Пользователь
- Сообщения
- 76
- Реакции
- 3
- Помог
- 1 раз(а)
Как сделать так чтобы живых игроков данный дм не переводил, а только тех кто умер. Потому что если у игрока есть к примеру турели, то его данный дм переводить за другую команду.
Код:
/*****=====--------
Привіт, ви намагаєтеся прочитати мій код... добре
DM balance - вас дратують ігри Deathmatch без Rond-less,
де жоден із модулів балансу команд не працює?
Я сподіваюся, що так.. Гаразд, десь є балансир CSDM, але, чесно кажучи, наскільки я знаю, він трохи кульгавий,
оскільки він працює на рахунок смертей...
Цей плагін перевіряє команди, коли гравець відключається,
або коли гравець набирає "/balance" у чаті, тож нікому не потрібно змінювати команду
вручну, АБО коли почнеться новий раунд...
--Чому метод виявлення відключення кращий?
На мій погляд, різниця в командах насправді створюється тим, що гравець роз'єднується,
тому - коли гравець від'єднується, гравців стає менше
і тому команди втрачають рівновагу... добре, звучить тупо :D Сподіваюся, ви зрозуміли (:
--Як це працює?
Алгоритм
1. Гравець роз'єднується або йде командою глядачів / починає раунд / "/баланс"
2. Спрацьовує лічильник гравців
3. Під час підрахунку гравців підраховуються результати, щоб побачити, чи варто когось передавати
4. Якщо варто когось перевести, то вибирають випадкового гравця з найсильнішої команди
5. Якщо випадковий гравець не з потрібної команди або є інша проблема, це повторюється
6. Коли нарешті знайдено, він передає його, показує оголошення чату...
7.* Якщо гравець підключається, він змушений приєднатися до найслабшої команди... (якщо ввімкнено)
--Кредити
* Більшість зроблено мною (Chill it BanG) "більшість" становить приблизно 97%, якщо вам подобається математика
* Більшість коду, який використовується в частині обмеження команди, взято з ConnorMcLeod,
з теми - https://forums.alliedmods.net/showthread.php?t=63818
--Завдяки...
* DonKisgot (https://forums.alliedmods.net/member.php?u=100584) за чудові ідеї та відгуки
--ChangeLog
v1.43 -
* Виправлено повідомлення ML "U_R_CT".
* Невелика оптимізація.
v1.41 -
* Додано підтримку ML, тепер ви можете перекладати повідомлення на свою мову та перемикати їх за допомогою amx_langmenu!
v1.4 -
* Знову ж таки, виправлено помилки в частині teamlimit
* Додано звук при передачі для перенесеного гравця (dmb_playsound)
* Додано прозоре згасання екрану під час переходу для переведеного гравця в колір його/її нової команди (dmb_fadescreen)
* Додано сповіщення про команду «say /balance»: «[DMB] У команді суперників більше гравців, ніж у вашій? Введіть «/balance» у чаті, щоб виправити це!»
(dmb_infodelay). ПРИМІТКА: якщо менше 20, він вимкнений, і ні, це не пов’язано з «dmb_printinchat»
* Все ще є деякі проблеми, коли команди погано збалансовані. Це помилка get_players з прапорцем "e"?
v1.35 -
* Зроблено код легшим для читання (код був трохи переплутаний з "indenter")
* Виправлено деякі помилки, пов’язані з teamlimit
* Виправлена власна помилка виконання для "cs_get_user_team"
* Спосіб пошуку випадкового гравця тепер швидший!
v1.3 -
* Додано dmb_respawn cvar, тому гравці після переходу можуть бути відроджені до своїх нових команд (може бути корисним у таких модах, як CTF та GG)
(сподіваюся, це виправить помилку в CTF, коли гравці після передачі не могли відродитися)
* Додано dmb_printincons cvar, оскільки код стає більшим і стає досить важко побачити, що відбувається.
Здебільшого для налагодження це має бути встановлено на 0;)
* Додано команди, які перевіряють, чи входить хтось до команди глядачів.
* Виправлено деякі невеликі помилки, коли іноді балансир зупинявся на пошуку випадкового гравця, але
пам’ятайте, якщо ваш сервер досить заповнений, пошук гравця може зайняти до 10 секунд.
* Позбудьтеся деяких непотрібних змінних.
v1.21 -
* Знайдено помилку, яка «вимкнула» плагін балансу, якщо було ввімкнено teamlimit, але нікого не примушували до найслабшої команди.
* Зроблено легше читати тести "якщо" в деяких частинах коду.
v1.2 -
* Додано teamlimit, який змушує приєднатися до найслабшої команди (dmb_teamlimit) (Примітка: подивіться на кредити)
* Додано cvar для контролю часу після початку раунду, коли перевіряється баланс
* Додано CVAR для ввімкнення/вимкнення сповіщень чату
* Невелика оптимізація коду
* Видалено ColorChat, оскільки client_print_color недоступний у amxx 1.8.2
* Покращена система ідентифікації коду, я відчуваю, що мені це погано :D
v1.1 -
* Виправлена помилка виконання (іноді він намагався перенести відключеного гравця, лол)
* Виправлена проблема, коли випадковий гравець вибирався з найслабшої команди
* Додано cvars, команди чату та консолі
* Додано більш складні обчислення, щоб переконатися, що баланс необхідний
v1.0 -
* Найперша версія, без CVAR і команд
--Команди
*Чат
/balance - запускає алгоритм перевірки команд
*Консоль
dmb_balance - Те саме, що "/balance", лише доступне для адміністратора з "ADMIN_KICK"
--Cvars
dmb_saybalance - (1) вмикає / (0) вимикає команду "say /balance" (за замовчуванням 1)
dmb_minplayers - Гравці, необхідні для початку балансу (за замовчуванням 2)
dmb_roundstarttime - час (у секундах) після початку раунду, коли можна перевірити баланс команди (за замовчуванням 10)
dmb_printinchat - (1) вмикає / (0) вимикає повідомлення чату (за замовчуванням 1)
dmb_printincenter - (1) вмикає / (0) вимикає повідомлення центру екрана (за замовчуванням 1)
dmb_printincons - (1) вмикає / (0) вимикає інформацію про налагодження консоліm не слід використовувати, якщо плагін, оскільки він містить купу повідомлень (за замовчуванням 0)
dmb_teamlimit - (1) вмикає / (0) вимикає ліміт команди. Це змушує гравця приєднатися до найслабшої команди
dmb_respawn - (1) вмикає / (0) вимикає відродження після передачі - тому гравці не будуть хапати прапор колишньої команди (CTF) або наносити удари колишніх товаришів по команді (GG) (за замовчуванням 0)
dmb_infodelay - Час у секундах. Як часто буває «[DMB] Команда суперників має більше гравців, ніж ваша? Введіть «/balance» у чаті, щоб виправити це!» показало повідомлення. Якщо менше 20 або "dmb_saybalance 0" - вимкнено (за замовчуванням 120)
dmb_playsound - (1) включає / (0) вимикає звук при передачі. Звук схожий на "біп" (за замовчуванням 1)
dmb_fadescreen - (1) вмикає / (0) вимикає прозоре затухання екрана в новій команді гравців. Лише для переведеного гравця (за замовчуванням 1)
dmb_version - показує версію плагіна, не торкайтеся цього...
-----======*******/
#include <amxmodx>
#include <amxmisc>
#include <cstrike>
#include <hamsandwich>
#define PLUGIN "DM balance"
#define VERSION "1.43"
#define AUTHOR "Chill it BanG"
// variables for cvars...
new c_dmb_saybalance
new c_dmb_minplayers
new c_dmb_printinchat
new c_dmb_printincenter
new c_dmb_teamlimit
new c_dmb_roundstarttime
new c_dmb_respawn
new c_dmb_printincons
new c_dmb_infodelay
new c_dmb_playsound
new c_dmb_fadescreen
//some variables
new countCT,countTS,countALL //player count
new randPid //random player id
new randPnick[32] //random player nick
new CTList[32] // list of CT`s
new TSList[32] // list of T`s
public plugin_init() {
//plugin info..
register_plugin(PLUGIN, VERSION, AUTHOR)
//lang file
register_dictionary("DM_balance.txt")
//commands
register_concmd("dmb_balance","counter",ADMIN_KICK,"Looks if balance is needed")
register_clcmd("say /balance","get_pcount_say",_,"Looks if balance is needed")
//cvars
c_dmb_saybalance = register_cvar("dmb_saybalance", "1") //controls "say /balance"
c_dmb_minplayers = register_cvar("dmb_minplayers", "4") //players needed to plugin to work
c_dmb_roundstarttime = register_cvar("dmb_roundstarttime", "20") //time after round start when balance checks teams
c_dmb_printinchat = register_cvar("dmb_printinchat", "0") //controls chat messages
c_dmb_printincenter = register_cvar("dmb_printincenter", "0") //controls center announcments
c_dmb_printincons = register_cvar("dmb_printincons", "0")//announcments in console, should be 0, since it is more for debugging
c_dmb_teamlimit = register_cvar("dmb_teamlimit", "1") //controls team limit,
c_dmb_respawn = register_cvar("dmb_respawn", "0") //respawn or not to respawn player when player is transfered
c_dmb_infodelay = register_cvar("dmb_infodelay", "120")//time, how often msg with "/balance" should appears, must be grater than "20"
c_dmb_playsound = register_cvar("dmb_playsound", "0")//play or not to play sound to player when transfered
c_dmb_fadescreen = register_cvar("dmb_fadescreen", "1")//fade screen for a little when transfered?
register_cvar("dmb_version", "1.43", FCVAR_SERVER | FCVAR_SPONLY) //version, seems legit
//events
register_logevent( "Event_RoundStart", 2, "0=World triggered", "1=Round_Start" ) //Round start
register_logevent("team_join",3,"1=joined team") //joined team
if(get_pcvar_num(c_dmb_saybalance) == 1 && get_pcvar_num(c_dmb_infodelay) > 20){
set_task(get_pcvar_float(c_dmb_infodelay), "SayBalanceInfo",_,_,_,"b")
} //spam info about "say /balance command"
}
/***
Triggers - turn balance on
***/
//Player disconnect
public client_disconnect(player){
set_task(1.0,"counter")
//check if chat massages are allowed (dmb_printinchat)
if(get_pcvar_num(c_dmb_printinchat) == 1 && countALL >= get_pcvar_num(c_dmb_minplayers)){
//print what is happening..
client_print(0,print_chat,"%L",LANG_PLAYER, "IS_NEEDED")
}
}
//if round starts - possible there is 1 vs "more than 1" game ;)
public Event_RoundStart() {
set_task (get_pcvar_float(c_dmb_roundstarttime), "counter")
//check if chat massages are allowed (dmb_printinchat)
if(get_pcvar_num(c_dmb_printinchat) == 1 && countALL >= get_pcvar_num(c_dmb_minplayers)){
//print what is happening..
client_print(0,print_chat,"%L",LANG_PLAYER, "IS_NEEDED")
}
}
//say comand
public get_pcount_say(player) {
new balancer[32]
get_user_name(player, balancer,31)
if(get_pcvar_num(c_dmb_printincons) == 1){
client_print(0,print_console,"[DMB] %s used /balance", balancer) //just for testing
}
if (get_pcvar_num(c_dmb_saybalance) == 1){
counter()
//check if chat massages are allowed (dmb_printinchat)
if(get_pcvar_num(c_dmb_printinchat) == 1 && countALL >= get_pcvar_num(c_dmb_minplayers)){
//print what is happening..
new used_bal[64]
formatex(used_bal,63,"%L", LANG_PLAYER, "USED_BAL", balancer)
client_print(0,print_chat,used_bal)
}
}
}
/***
Here the fun starts (:
***/
//Just counting players and going to next step
public counter(){
new printcons = get_pcvar_num(c_dmb_printincons)
get_players(CTList, countCT, "e", "CT") //Gets count of CT`s
get_players(TSList, countTS, "e", "TERRORIST") //Gets count of T`s
countALL = countCT + countTS //gets everyone counted
//check if console commands are allowed
if(printcons){
client_print(0,print_console,"[DMB] Counting") //just for testing
}
if(countALL >= get_pcvar_num(c_dmb_minplayers)){
set_task (1.0,"balance_calc")
if(printcons){
client_print(0,print_console,"[DMB]CT`s:%d, TS: %d ALL: %d /// Enough players",countCT,countTS,countALL) //just for testing
}
}
else {
if(printcons){
client_print(0,print_console,"[DMB]CT`s:%d, TS: %d ALL: %d /// Not enough players",countCT,countTS,countALL) //just for testing
}
}
}//end of counter
//Just counting... used in teamlimit part, in this case it won`t go to the next step
public get_pcount() {
get_players(CTList, countCT, "e", "CT") //Gets count of CT`s
get_players(TSList, countTS, "e", "TERRORIST") //Gets count of T`s
countALL = countCT + countTS //gets everyone counted
//check if console commands are allowed
if(get_pcvar_num(c_dmb_printincons) == 1){
client_print(0,print_console,"[DMB] Counting, because of join_team") //just for testing
client_print(0,print_console,"[DMB]CT`s:%d, TS: %d ALL: %d",countCT,countTS,countALL) //just for testing
}
}//end of get_pcount
//check if balance is needed
public balance_calc() {
new printcons = get_pcvar_num(c_dmb_printincons)
//test #1 and 2 - it would be useless to do something if teams are well balanced or there ar not enough players
if(countCT != countTS && countALL >= get_pcvar_num(c_dmb_minplayers)){
if(printcons){
client_print(0,print_console,"[DMB] Test #1 and #2 are true") //just for testing
}
//test #3 - it would be useless to do something if the difference is just 1 player
if (countCT +1 != countTS && countCT != countTS +1){
if(printcons){
client_print(0,print_console,"[DMB] Test #3 is true!") //just for testing
}
//ok, if it gets there it seems to be legit, to transfer player!
//choosing the strongest team
if(countCT > countTS){ //if CT`s ar more than T`s
if(printcons){
client_print(0,print_console,"[DMB] Going to transfer CT") //just for testing
}
trans_randomCT()
}
if(countTS > countCT) // if T`s ...
{
if(printcons){
client_print(0,print_console,"[DMB] Going to transfer TS") //just for testing
}
trans_randomTS()
}
if(countCT == countTS){
//how dafaq this could happen? :D
//be cool, just do nothing. -.-
if(printcons){
client_print(0,print_console,"[DMB] This message should never appear (CT=TS)") //just for testing
}
}
}//end of test#3
}//end of test#2 and #1
} //end of balance_calc
//And finaly, moment of transfer (:
//If CT needs to be transfered... find random CT
public trans_randomCT(){
new printcons = get_pcvar_num(c_dmb_printincons)
if(printcons){
client_print(0,print_console,"[DMB] Searching for random CT") //just for testing
}
new CT[32] = "CT"
new randomCT
new teamCT[32]
//so random player
randomCT = random_num(0, countCT -1)
randPid = CTList[randomCT]
//Check if player really comes from right team... shit may happen :D
// ... AND if player is in server, do the thing, if not, repeat!
if (is_user_connected(randPid)){
get_user_team(randPid,teamCT,31)
//if random player is CT
if(equali(teamCT,CT)){
cs_set_user_team(randPid,CS_TEAM_T,CS_T_TERROR)
if(printcons){
client_print(0,print_console,"[DMB] Found the winner! with id: %d",randPid) //just for testing
}
//Lets say that someone is transfered, so people would know that :D
//Check if print messages are enabled (dmb_printinchat)
if(get_pcvar_num(c_dmb_printinchat) == 1){
get_user_name(randPid,randPnick,31)
new is_now_ter[64]
formatex(is_now_ter, 63, "%L",LANG_PLAYER,"IS_NOW_T", randPnick)
client_print(0,print_chat,is_now_ter)
}
//Print message in center of screen, to our conest winner.. lol
//Check if center messages ar allowed (dmb_printincenter)
if(get_pcvar_num(c_dmb_printincenter) == 1){
client_print(randPid,print_center,"%L", LANG_PLAYER, "U_R_T")
}
//play "beep" sound, if allowed
if(get_pcvar_num(c_dmb_playsound)){
client_cmd(randPid, "spk buttons/blip2")
}
//fade screen red, if allowed
if(get_pcvar_num(c_dmb_fadescreen)){
message_begin(MSG_ONE, get_user_msgid("ScreenFade"), {0,0,0}, randPid)
write_short(1<<10)
write_short(1<<10)
write_short(0x0000)
write_byte(255)
write_byte(0)
write_byte(0)
write_byte(75)
message_end()
}
//if respawn is enabled, respawn to new spawn
if(get_pcvar_num(c_dmb_respawn) == 1){
//ExecuteHamB(Ham_CS_RoundRespawn, randPid)
set_task(0.5,"spawner")
if(printcons){
client_print(0,print_console,"[DMB] Prepearing to spawn a player!") //just for testing
}
}
}
else {
//if player is not CT O_O, count again
set_task (0.1,"counter")
}
}
else {
//If random player is not connected count again, maybe now player counts are better
set_task (0.1,"counter")
if(printcons){
client_print(0,print_console,"[DMB] Something went wrong, randPid is not connected. (ID:%d)", randPid) //just for testing
}
}
}
//If TS needs to be transfered ... find random TS
public trans_randomTS(){
new printcons = get_pcvar_num(c_dmb_printincons)
if(printcons){
client_print(0,print_console,"[DMB] Searching for random TS") //just for testing
}
new TERRORIST[32] = "TERRORIST"
new randomTS
new teamTS[32]
//so random player
randomTS = random_num(0, countTS -1)
randPid = TSList[randomTS]
//Check if player really comes from right team... shit may happen :D
if (is_user_connected(randPid)){
get_user_team(randPid,teamTS,31)
//check if random player comes from T team
if(equali(teamTS,TERRORIST)){
cs_set_user_team(randPid,CS_TEAM_CT,CS_CT_SAS)
if(printcons){
client_print(0,print_console,"[DMB] Found the winner! with id: %d",randPid) //just for testing
}
//lets say that someone is transfered, so people would know that :D
//check if allowed to print...
if(get_pcvar_num(c_dmb_printinchat) == 1){
get_user_name(randPid,randPnick,31)
new is_now_ct[64]
formatex(is_now_ct, 63, "%L",LANG_PLAYER,"IS_NOW_CT", randPnick)
client_print(0,print_chat,is_now_ct)
}
//Print msg in center + check if allowed
if(get_pcvar_num(c_dmb_printincenter) == 1){
client_print(randPid,print_center,"%L", LANG_PLAYER, "U_R_CT")
}
//play "beep" sound, if allowed
if(get_pcvar_num(c_dmb_playsound)){
client_cmd(randPid, "spk buttons/blip2")
}
//fade screen blue, if allowed
if(get_pcvar_num(c_dmb_fadescreen)){
message_begin(MSG_ONE, get_user_msgid("ScreenFade"), {0,0,0}, randPid)
write_short(1<<10)
write_short(1<<10)
write_short(0x0000)
write_byte(0)
write_byte(0)
write_byte(255)
write_byte(75)
message_end()
}
//if respawn is enabled, respawn to new spawn
if(get_pcvar_num(c_dmb_respawn) == 1){
//ExecuteHamB(Ham_CS_RoundRespawn, randPid)
set_task(0.5,"spawner")
}
}
else {
//if player has been disconnected, count again, maybe now player counts are better
set_task (0.5,"counter")
}
}
else {
set_task (0.5,"counter")
if(printcons){
client_print(0,print_console,"[DMB] Something went wrong, random player is not connected") //just for testing
}
}
}
//The respawner.. lol, if it is enabled
public spawner(){
ExecuteHamB(Ham_CS_RoundRespawn, randPid)
if(get_pcvar_num(c_dmb_printincons) == 1){
client_print(0,print_console,"[DMB] Player %s respawned after transfer",randPnick) //just for testing
}
}
public SayBalanceInfo(){
client_print(0,print_chat,"%L", LANG_PLAYER, "SAY_CMD_AD")
}
///////////
// Start of teams limiter, that does not allow to join to the strongest team
// Actually, it allows, but quickly transfers to the weakest team
//////////
/// code taken from ConnorMcLeod (https://forums.alliedmods.net/member.php?u=18946)
/// from thread - https://forums.alliedmods.net/showthread.php?t=63818
/// just edited to fit for limit teams, since I am beginner at coding :D
/////////
public team_join() {
if(get_pcvar_num(c_dmb_teamlimit) == 1){
//get count of players at first
get_pcount()
new loguser[80], name[32]
new temp[2]
read_logargv(0, loguser, 79)
parse_loguser(loguser, name, 31)
new id = get_user_index(name)
if(is_user_bot(id))
return
read_logargv(2, temp, 1)
switch(temp[0])
{
case 'T' :
{
if(countTS -1> countCT && is_user_connected(id)){
cs_set_user_team(id,CS_TEAM_CT,CS_CT_SAS)
if(get_pcvar_num(c_dmb_printincons) == 1){
client_print(0,print_console,"[DMB] Forced player to join CT. CT`s: %d T`s: %d ALL: %d", countCT,countTS,countALL) //just for testing
}
}
}
case 'C' :
{
if(countCT -1 > countTS && is_user_connected(id)){
cs_set_user_team(id,CS_TEAM_T,CS_T_TERROR)
if(get_pcvar_num(c_dmb_printincons) == 1){
client_print(0,print_console,"[DMB] Forced player to join TS. CT`s: %d T`s: %d ALL: %d", countCT,countTS,countALL) //just for testing
}
}
}
case 'S' :
{
set_task(0.5, "counter")
if(get_pcvar_num(c_dmb_printincons) == 1){
client_print(0,print_console,"[DMB] Player joined Spectator. CT`s: %d T`s: %d ALL: %d", countCT,countTS,countALL) //just for testing
}
}
}
}
}//end of team_join
//end of whole code (: