搜索
查看: 2530|回复: 7

simple_team_balancer修改

[复制链接]
匿名  发表于 2003-5-9 08:16:09 |阅读模式 来自 Invalid
这个插件主要解决的是乱战服务器上局面不平衡的问题

这其实是很复杂的算法,olo也只是给出了0.5版
我在他的基础上修改了一些条件
比如他的每个人的分数使用frags来计算(这个东西我还真不知道是什么)
我改成了get_user_kills(使用get_user_stats可以得到这个数值,参看
stats.sma)
在交换人员的条件方面,我对他的算法没有太清楚,不过我加了几个条件
比如,ct(or t)比分差距为4或以上,然后本队的优秀选手(高过平均水平的)
多于对手,这个时候就该换人了,另外,人数多而且还是胜利的一方,也改换人了。
代码我明天看贴上来,因为修改的是服务器,我现在在公司呢,呵呵。

大家给提提意见。
发表于 2003-5-9 08:42:17 | 显示全部楼层 来自 中国–福建–厦门

我没有用过队伍平衡的东西

不过,记得还有一个PTB的,不知道跟OLO的这个东西有多少差别,只知道PTB是从adminmod的ptb插件转换过来的,好像OLO也参与了该工作,不知道那个会好一点,请用过的兄弟们发表一下使用经验吧?
回复

使用道具 举报

发表于 2003-5-9 11:27:18 | 显示全部楼层 来自 中国–湖北–武汉
frag是杀人的分数...
希望看到源代码
:):D
回复

使用道具 举报

匿名  发表于 2003-5-10 08:53:43 来自 Invalid
/* AMX Mod script.
*
* (c) Copyright 2002, OLO
* This file is provided as is (no warranties).
*
*/

#include <amxmod>
#include <csstats>

new bool:endscore = true
new blockjoining[2]
new scores[2]
new Float:ppower[33]
new Float:tpower[2]
new Float:tempf
new Float:avepower
new playersnum[2]


Float:maxf(Float:a,Float:b)
        return a < b ? b : a

Float:minf(Float:a,Float:b)
        return a < b ? a : b
       
absn(a)
        return a < 0 ? -a : a       
       
public calculate_power(){
        new teams[33], ppl[32], ippl
        new a, b, c , d, e
        new Float:frags
        new Float:deaths
        new transfer = -1
        new name[32], stats[8], body[8]
       
       
        playersnum[0] = playersnum[1] = 0 // reset player num
        tpower[0] = tpower[1] = 0.0 // reset teams power
        avepower = 0.0 // reset averange skill
        blockjoining[ 0 ] = blockjoining[ 1 ] = PLUGIN_CONTINUE // reset blocking
       
        get_players(ppl,ippl)        // get all players in game
       
        /* Get avarange efficiency, player efficiency and team efficiency. */
        for(a=0;a<ippl;++a){ // calculate efficiency for each player
                b = ppl[a]
                c = get_user_team(b) - 1 // in CS the T team has id #1 and CT has id #2
                teams = c // save what index of team the player has               
                if (c!=0&&c!=1) continue                // Spectator

                get_user_wstats(b,0,stats,body)

                frags = float(stats[0])
                deaths = float(stats[1])
                tempf = (frags / (deaths ? deaths : 1.0)) + (frags * 0.15)
                ppower = tempf
                avepower += tempf // add to sum of all efficiencies for avarange calculation
                playersnum[c]++ // increase number of player in that team
                tpower[c] += tempf        // add the player efficiency to team efficiency
        }
        avepower /= float(playersnum[0] + playersnum[1]) // averange efficiency
               
        /* Get best players. */
        new goodlist[2][32]        // array for list of good players
        new goodnum[2] // how many good player the team has
        goodnum[0] = goodnum[1] = 0
        for(a=0;a<ippl;++a){ // sum eff. for each team
                b = ppl[a]
                c = teams
                if (c!=0&&c!=1) continue                // Spectator
                if ( ppower > avepower ){ // if better than avarange then save him to list
                        goodlist[c][goodnum[c]] = b
                        goodnum[c]++
                }
        }
               
        /* Display score. */
        new Float: cscore = tpower[1]
        new Float: tscore = tpower[0]
        client_print(0,print_chat,"CT %d (%.2f) -- TERRORIST %d (%.2f)",scores[1],cscore,scores[0],tscore)
       
        /* Try to estimate which team is better and announce about it. */
        new Float: winner = maxf(cscore,tscore)
        new Float: looser = minf(cscore,tscore)
        new Float: compratio = winner / looser
               
        /* Determine index of better team (with higher skill ratio). */
        e = (cscore > tscore) ? 1 : 0
       
        if ( compratio >= 5 ){
                blockjoining[ e ] = PLUGIN_HANDLED /* Block joining to the better team. */
                transfer = 1 /* Save index of better them to switch from. */
                client_print(0,print_chat,"%s team beats %s", e ? "Ct" : "Terrorist", e ? "Terrorists" : "Cts" )
        }
        else if ( compratio >= 3 ){
                blockjoining[ e ] = PLUGIN_HANDLED /* Block joining to the better team. */
                transfer = 1        /* Save index of better them to switch from. */       
                client_print(0,print_chat,"%s team seems to be more powerful",e ? "Ct" : "Terrorist" )
        }
        else if ( compratio >= 1.5 ){
                blockjoining[ e ] = PLUGIN_HANDLED        /* Block joining to the better team. */               
                client_print(0,print_chat,"%s team is slightly better",e ? "Ct" : "Terrorist" )
        }
        else{
                /*Sometimes there is a situation that team is balanced but there are different
                         numbers of players in each team. If the difference is higher then 1 then transfer someone.
                         NOTE: That this condition will be never true for mp_limitteams 2.0 (this is now, however
                         we will leave it for possibly future modifications.)
                        
                         e.g, T 6 -- CT 2, the difference is 4 then get the best from T and worst from CT
                         and transfor them. Yes it won't balance them but make one team a bit better than
                         second, ppl tend to switch the team following with the best. If team is to
                         powerful they won't unbalance team more due to team switching block :)                        
                */
                if (  absn(playersnum[0] - playersnum[1]) > 1 )
                        transfer = (playersnum[0] > playersnum[1]) ? 0 : 1
                client_print(0,print_chat,"Teams balanced. T have %d and Cts %d good player(s)",goodnum[0],goodnum[1])
        }
       
        /* Build list of best players for each team and display them. */
        new list[256]
        c = goodnum[0]
        b = 0
        for(a=0;a<c;++a)        { // TERRORIST
                d = goodlist[0][a]
                get_user_name(d,name,31)
                b += format(list,255-b,"%s, ",name )
        }
        if (c) {
                list[b-2] = 0 // remove ", " from after last name
                client_print(0,print_chat,"In Terrorists good %s: %s",(c==1)?"is":"are",list)
        }
        c = goodnum[1]
        b = 0
        for(a=0;a<c;++a)        { // CT
                d = goodlist[1][a]
                get_user_name(d,name,31)
                b += format(list,255-b,"%s, ",name )
        }
        if (c) {
                list[b-2] = 0
                client_print(0,print_chat,"In Cts good %s: %s",(c==1)?"is":"are",list)
        }
       

        if ( (goodnum[1]-goodnum[0])>=4 && ( (scores[1] - scores[0]) >= 3 )  )       
        {
                transfer = 1
        }
        else if( (goodnum[0]-goodnum[1])>=4 && ( (scores[0] - scores[1]) >= 3)  )
        {
                transfer = 0
        }
        else if ( ( (scores[0] - scores[1]) >=4 ) && (playersnum[0] > playersnum[1])  )
        {
                transfer = 0
        }
        else if ( ( (scores[1] - scores[0]) >=4 ) && (playersnum[1] > playersnum[0]) )
        {
                transfer = 1
        }
        else
        {
                transfer = -1
        }       
        client_print(0,print_chat,"transfer is %i",transfer)       
        if (transfer != -1)
        {
                new baplayer[2], woplayer[2]
                new Float:bestalive[2]
                new Float:worstalive[2]
                baplayer[0] = baplayer[1] = 0
                woplayer[0] = woplayer[1] = 0       
                bestalive[0] = bestalive[1] = 0.0
                worstalive[0] = worstalive[1] = 100.0
                for(a=0;a<ippl;++a)
                { /* For each player. */
                        b = ppl[a]
                        c = teams /* The team index will put results to proper place. */
                        if (c!=0&&c!=1) continue                // Spectator
                        if (is_user_alive(b)) continue
                        if (bestalive[c] < ppower){ // Get best dead player
                                bestalive[c] = ppower
                                baplayer[c] = b
                               
                        }
                        if (worstalive[c] > ppower){ // Get worst dead player
                                worstalive[c] = ppower
                                woplayer[c] = b
                               
                        }
                }

                new optransfer = transfer ? 0 : 1

                if (baplayer[transfer] && woplayer[optransfer] ){
                        client_print(0,print_chat,"transfer best %i",baplayer[transfer])
                        client_print(0,print_chat,"transfer worst %i",woplayer[optransfer])
                        if (playersnum[transfer] > 1) // if has more than 1 player then you may transfer him
                                transfer_player(baplayer[transfer],transfer ? "1" : "2" )
                        if (playersnum[optransfer] > 1) // if has more than 1 player then you may transfer him
                                transfer_player(woplayer[optransfer], optransfer ? "1" : "2" )

                }
        }
}

transfer_player(id,key[]){
        new oldone[2]
        oldone[0] = blockjoining[ 0 ]
        oldone[1] = blockjoining[ 1 ]
        blockjoining[ 0 ] = blockjoining[ 1 ] = PLUGIN_CONTINUE
        //set_cvar_float("mp_limitteams",0.0)
        engclient_cmd(id,"chooseteam")
        engclient_cmd(id,"menuselect",key)
        engclient_cmd(id,"menuselect","5")
        client_print(id,print_center,"You have been moved to another team.")
        client_cmd(id,"slot10")
        //set_cvar_float("mp_limitteams",2.0)
        blockjoining[ 0 ] = oldone[0]
        blockjoining[ 1 ] = oldone[1]
}

public team_score() {
        new tid[2]
        read_data(1,tid,1)

        scores[(tid[0]=='C') ? 1 : 0 ] = read_data(2)
        if ((endscore = !endscore))// Round end
                set_task(1.0,"calculate_power")
}

public team_select(id, key){

        return PLUGIN_CONTINUE
}

public plugin_init() {
        register_plugin("Simple Team Balancer","0.5","default")
        register_event("TeamScore","team_score","a")
        register_menucmd(register_menuid("Team_Select"),(1<<0)|(1<<1),"team_select")
        register_menucmd(-2,(1<<0)|(1<<1),"team_select")        // VGUI menu
        return PLUGIN_CONTINUE
}
发表于 2003-5-10 10:57:45 | 显示全部楼层 来自 中国–湖北–襄阳

请问有谁用了效果如何?

请问有谁用了效果如何?
回复

使用道具 举报

发表于 2003-5-10 12:33:13 | 显示全部楼层 来自 中国–湖北–武汉
很不错的说..:D...
建议有基础的朋友都可以像sunwell一样研究一下amx插件的源代码...嘿嘿...
先下来用用看....:)感谢sunwell.
回复

使用道具 举报

匿名  发表于 2003-5-12 08:02:12 来自 Invalid
这里面很多调试性的代码
其实我觉得这些源代码最好玩的就是你能了解一些功能是如何实现的

在这里面也有一个事件的概念,某个事件发生了,插件就产生相应的响应行为
发表于 2003-5-12 09:40:57 | 显示全部楼层 来自 中国–湖北–武汉
amx得插件都是用基于c#得small语言写的,偶是不懂计算机语言..没办法,所以现在水平只停在修改部分插件上,建议有条件的朋友都像sunwell一样可以研究一下源代码的说..^_^..给大家写出好插件来....
回复

使用道具 举报

游客
回复
您需要登录后才可以回帖 登录 | 注个册吧

快速回复 返回顶部 返回列表