[CSGO] Несколько вопросов по написанию плагинов от новичка.
| |
Black_Hawk1451
|
Дата: Среда, 09.03.2016, 15:50:22 | Сообщение # 1 |
|
Сообщений: 11
Репутация: 0 [ +/- ]
|
|
Всем привет! Только начинаю разбираться во внутренностях сурсмода и языка SourcePawn и поэтому хотел бы попросить Вас помочь мне разобраться с некоторыми непонятностями:
Итак, первым делом я решил переписать для себя SoccerMod-плагин(https://forums.alliedmods.net/showthread.php?p=1732360 - оригинал). Кусок кода будет ниже. Хочу немного апгрейднуть функцию, которая определяет кто нанес последний удар по мячу. Объясню подробнее: У меня есть своя собственная футбол-карта, на которой после попадания мяча в ворота всю проигравшую команду убивает. По замыслу плагина, последний игрок, который сделал удар по мячу(по сути, забил гол) получает 1 фраг в свою статистику. Соответственно, всем убитым(проигравшим) засчитывается -1 в колонку фрагов, что не есть хорошо. Вот кусок плагина, отвечающего за определение игрока, который нанес последний удар:
Код new String:LastAttacker[512]; new LastAttackerUser;
public OnEntityCreated(edict, const String:classname[]) { SDKHook(edict, SDKHook_OnTakeDamage, OnEntityTakeDamage); } // +----------------------------------------------------------------------------------+ public Action:OnEntityTakeDamage(edict, &inflictor, &attacker, &Float:damage, &damagetype) { decl String:classname[512]; GetEdictClassname(edict, classname, sizeof(classname)); if ( IsValidEdict(edict) && IsValidEntity(edict) ) { decl String:aName[64]; GetClientName(attacker, aName, sizeof(aName)); LastAttacker = aName; LastAttackerUser = attacker; } }
Во-первых, хочу сделать так, чтобы в начале раунда всем убитым в прошлом давало по 1 очку в колонку фрагов. Таким образом, если кто-то из проигравших забивал гол ранее, то его гол(+фраг) никуда не пропадет и сам игрок не уйдет в минус фраги. Во-вторых, исключить возможность получения фрага за гол в собственные ворота. Для определения команды игрока я нашел функцию "GetClientTeam", но как ее верно использовать в данной функции, пока не понимаю. В плагине эта функция реализована вот так:
Код HookEvent("round_end", Event_MixRoundEnd); stock SetclientFrags(client, frags) { SetEntProp(client, Prop_Data, "m_iFrags", frags); return 1; }
public Event_MixRoundEnd(Handle:event, const String:name[], bool:dontBroadcast) { // Add frag to the winner new cFrags = GetClientFrags(LastAttackerUser); new nFrags = cFrags + 1; SetclientFrags(LastAttackerUser, nFrags); if ( LastAttackerUser != -1 ) { PrintToChatAll("\x04Soccer\x05 |\x03 Player\x04 %s\x05 Scored\x03 on this round\x04!", LastAttacker); } LastAttackerUser = -1;
Кстати, что подразумевается под условием "LastAttackerUser != -1"?
Также, я подготовил собственные решения для своих же вопросов, но полностью в своей правоте не уверен. 1. Вот такой вот вариант:
Код HookEvent("player_hurt", Event_MixRoundEnd) new FragsForDead = GetClientFrags(***); new nFragsForDead = FragsForDead + 1; SetclientFrags(LastAttackerUser, nFrags);
Так как на моей карте всех проигравших убивает только trigger_hurt, то с помощью этой команды можно будет проще отследить всех умерших игроков(я это к тому, что команду kill никто не отменял и она может хреново работать с этим плагином, если поставить "player_death"). Вопрос только в том, что мне поставить на месте "***"? Сделать еще одну отдельную функцию по подобию с "LastAttackerUser"? В общем, тут у меня проблемы, выручайте)
2. А чтобы дополнить эту функцию и не давать фраг за гол в свои ворота, я решил сделать так:
Код HookEvent("player_hurt", Event_MixRoundEnd) new FragsForDead = GetClientFrags(***); new nFragsForDead = FragsForDead + 1; SetclientFrags(LastAttackerUser, nFragsForDead); if( LastAttackerUser = мертв) // я хз как правильно тут прописать условие { FragsForDead = GetClientFrags (LastAttackerUser) nFragsForDead = FragsForDead - 2; // отнимает помимо нечестного полученного фрага еще один сверху, т.е получает в итоге -1 к своей статистике по фрагам SetclientFrags(LastAttackerUser, nFragsForDead); }
Я в итоге решил, что GetClientTeam и не нужен тут, но я не знаю как сделать проверку на то, что игрок, ударивший мяч последним, после события "player_hurt" является мертвым. Также прошу вашей помощи.
На этом пока что всё, надеюсь на Вашу и помощь и прошу меня ссаными тряпками сильно не бить c:
Ах да, чуть не забыл: как узнать будет ли этот мой плагин поддерживаться в CS:GO? Только методом тыка на рабочий сервер или есть другие методы?
Сообщение отредактировал Black_Hawk1451 - Среда, 09.03.2016, 22:34:30 |
|
| |
BarD
|
Дата: Пятница, 11.03.2016, 10:10:13 | Сообщение # 2 |
|
Сообщений: 943
Репутация: 137 [ +/- ]
|
|
Доброго дня! Не проще ли сделать добавление фрага сразу после смерти? Все равно же умирают они от "рук" карты. А забившему добавлять фраг, когда он забивает.
Код public OnPluginStart() { HookEvent("player_death", Death); }
public Action:Death(Handle:event, const String:name[], bool:db) { new client = GetClientOfUserId(GetEventInt(event, "userid")); if (client) { SetEntProp(client, Prop_Data, "m_iFrags", GetEntProp(client, Prop_Data, "m_iFrags") + 1); // даем ему фраг, чтобы не уходил в минус } }
Цитата Black_Hawk1451 ( ) Кстати, что подразумевается под условием "LastAttackerUser != -1"? Это проверка, что такой игрок существует. Он мог выйти или умереть по дороге. Всего кода не видел, поэтому сказать точно не могу.
Цитата Black_Hawk1451 ( ) Ах да, чуть не забыл: как узнать будет ли этот мой плагин поддерживаться в CS:GO? Только методом тыка на рабочий сервер или есть другие методы? Если сможешь скомпилить, то тестируй на сервере. А так, по коду можно сказать, будет ли он работать в CSGO, если знаешь отличия CSGO от CSS.
P.S. Для ответа на остальные вопросы мне нужно знать особенности твоей карты. Как она работает, как определяет победителя и т.д.
Сообщение отредактировал BarD - Пятница, 11.03.2016, 10:11:23 |
|
| |
Black_Hawk1451
|
Дата: Пятница, 11.03.2016, 21:56:15 | Сообщение # 3 |
|
Сообщений: 11
Репутация: 0 [ +/- ]
|
|
Цитата BarD ( ) Доброго дня! Не проще ли сделать добавление фрага сразу после смерти? Все равно же умирают они от "рук" карты. А забившему добавлять фраг, когда он забивает.
Ну я вот сижу и думаю, если ты просто прописал kill в консоли, то у тебя же по-любому отнимают очко, так? Значит даже в случае, если ты захочешь перейти в другую команду по ходу игры, то ты не потеряешь свою статистику фрагов, я верно мыслю? Просто изначально мне казалось, что с помощью kill'a можно накидывать себе лишние фраги.
Цитата BarD ( ) Это проверка, что такой игрок существует. Он мог выйти или умереть по дороге. Всего кода не видел, поэтому сказать точно не могу.
https://forums.alliedmods.net/attachment.php?attachmentid=105290&d=1340202578 - весь код тут, если что.
Цитата BarD ( ) P.S. Для ответа на остальные вопросы мне нужно знать особенности твоей карты. Как она работает, как определяет победителя и т.д.
Сейчас объясню как работает моя карта, но если что снизу прикрепил ссылку на нее(запускать только в cs:s, csgo версия пока не готова) Есть мяч и есть ворота. У мяча как entity есть свое имя(возможно, это можно использовать в плагине) и у ворот тоже есть имя. Точнее говоря, в воротах стоит триггер-коробка, при попадании в которую мяча он(триггер) активирует trigger_hurt, который моментально убивает проигравшую команду. Мяч после попадания в ворота сразу исчезает(на карте пока не реализовано, но так будет в релизе).
Если ты хорошо разбираешься в маппинге, то могу тебе и .vmf-файл скинуть, если остались вопросы. https://www.dropbox.com/s/rtpim7utvcyi6an/mg_football_evo_v3.rar?dl=0 - ссылка на карту(CS:S)
Сообщение отредактировал Black_Hawk1451 - Пятница, 11.03.2016, 22:39:14 |
|
| |
Scarface_slv
|
Дата: Суббота, 12.03.2016, 22:31:21 | Сообщение # 4 |
|
Сообщений: 737
Репутация: 61 [ +/- ]
|
|
Я столько пишу и до сих пор плохо разбираюсь в этих энтити и обьектах. =) Попробуй так, если отобразит игрока который забил в чат, то я возможно смогу помочь)
Гости не могут скачивать файлы
|
|
|
| |
Black_Hawk1451
|
Дата: Воскресенье, 13.03.2016, 22:35:42 | Сообщение # 5 |
|
Сообщений: 11
Репутация: 0 [ +/- ]
|
|
Цитата Scarface_slv ( ) Я столько пишу и до сих пор плохо разбираюсь в этих энтити и обьектах. =) Попробуй так, если отобразит игрока который забил в чат, то я возможно смогу помочь)
Спасибо, но проверить пока не смогу. Решил на время заняться другой идеей и другой картой соответственно. Однако в планах разместить и футбол тоже на карте, которой я сейчас занимаюсь, так что к этому плагину я обязательно вернусь c:
|
|
| |
RunCrafting
|
Дата: Понедельник, 14.03.2016, 21:15:54 | Сообщение # 6 |
|
Сообщений: 52
Репутация: 0 [ +/- ]
|
|
Насчет уменьшения фрага, если убийца и есть жертва...
Код public OnPluginStart() { HookEvent("player_death", Event_Death); }
public Event_Death(Handle event, char[] name, bool dbc) { int client = GetClientOfUserId(GetEventInt(event, "userid")) int attacker = GetClientOfUserId(GetEventInt(event, "attacker")) if(attacker==client) SetEntProp(client, Prop_Data, "m_iFrags", GetEntProp(client, Prop_Data, "m_iFrags")+1); }
Добавлено (14.03.2016, 21:08:33) --------------------------------------------- Зачем делать триггер на карте и пытаться узнать, кто забил, когда можно создать свою зону в воротах (по типу плагина Zones)
Добавлено (14.03.2016, 21:11:27) ---------------------------------------------
Цитата Black_Hawk1451 ( ) 2. А чтобы дополнить эту функцию и не давать фраг за гол в свои ворота, я решил сделать так: Код if( LastAttackerUser = мертв) // я хз как правильно тут прописать условие
Код if(!IsPlayerAlive(LastAttackerUser))
и еще, если просто LastAttackerUser = значение, то он ставит значение и не возвращает true или false, что требует if, для этого нужно использовать 2 знака Пример: Код if( LastAttackerUser == значение ) , Код new bool:thebool = LastAttackerUser == значение
Добавлено (14.03.2016, 21:15:54) ---------------------------------------------
Цитата Black_Hawk1451 ( ) Также, я подготовил собственные решения для своих же вопросов, но полностью в своей правоте не уверен. 1. Вот такой вот вариант: Код
HookEvent("player_hurt", Event_MixRoundEnd) new FragsForDead = GetClientFrags(***); new nFragsForDead = FragsForDead + 1; SetclientFrags(LastAttackerUser, nFrags);
Зачем делать лишние переменные, если можно напрямую отправить значение?
Код HookEvent("player_hurt", Event_MixRoundEnd) SetclientFrags(LastAttackerUser, GetClientFrags(***) + 1);
и кстати нету функции SetClientFrags (или GetClientFrags.. Не помню), так-что придется напрямую через SetEntProp
Код SetEntProp(client, Prop_Data, "m_iFrags", GetEntProp(client, Prop_Data, "m_iFrags")+1)
Сообщение отредактировал RunCrafting - Понедельник, 14.03.2016, 21:16:44 |
|
| |
Black_Hawk1451
|
Дата: Вторник, 15.03.2016, 01:11:08 | Сообщение # 7 |
|
Сообщений: 11
Репутация: 0 [ +/- ]
|
|
Цитата RunCrafting ( ) Зачем делать триггер на карте и пытаться узнать, кто забил, когда можно создать свою зону в воротах (по типу плагина Zones)
Мне так намного удобнее. Все же лучше использовать всего 1 плагин для карты, нежели подключать еще какие-то.
Цитата RunCrafting ( ) и кстати нету функции SetClientFrags (или GetClientFrags.. Не помню), так-что придется напрямую через SetEntProp
Она есть в самом плагине, просто я ее не копипастил в эту тему:
Код stock SetclientFrags(client, frags) { SetEntProp(client, Prop_Data, "m_iFrags", frags); return 1; }
|
|
| |
RunCrafting
|
Дата: Вторник, 15.03.2016, 20:31:32 | Сообщение # 8 |
|
Сообщений: 52
Репутация: 0 [ +/- ]
|
|
Цитата Black_Hawk1451 ( ) Цитата RunCrafting писал(а): и кстати нету функции SetClientFrags (или GetClientFrags.. Не помню), так-что придется напрямую через SetEntProp
Она есть в самом плагине, просто я ее не копипастил в эту тему: Код stock SetclientFrags(client, frags) { SetEntProp(client, Prop_Data, "m_iFrags", frags); return 1; }
Извини, не знал что там есть отдельной функцией
|
|
| |
|