Как лучше написать плагин?

Vladius

Участник
Сообщения
18
Реакции
0
Такая ситуация. Я ввожу команду, и на следующем раунде игроки спавнятся с калашами. Как лучше реализовать:
1) Хукнуть эвенты при загрузке плагина и в каждом евенте проверять переменную bool, которую команда будет ставить на true.
2) В команде хукать эвенты, а в конце раунда разхукивать.
Так:
C-подобный:
#include <sourcemod>
#include <sdktools>

new bool:round=false;

public void OnPluginStart()
{
    HookEvent("player_spawn", Event_PlayerSpawned);
    HookEvent("round_end", Event_RoundEnd);
}
public void Event_PlayerSpawned(Handle:event, const String:name[], bool:dontBroadcast)
{
    if(round)
    {
        int ent = GetPlayerWeaponSlot(GetClientOfUserId(GetEventInt(event,"userid")), 0);
        if(ent != -1)
        {
            RemovePlayerItem(GetClientOfUserId(GetEventInt(event,"userid")), ent);
            RemoveEdict(ent);       
        }
        GivePlayerItem(GetClientOfUserId(GetEventInt(event,"userid")), "weapon_ak47");
    }
}
public void Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
{
        if(round){
            round=false;
        }
}
public Action:SpecialRound(client, args)
{
    if (args != 1)
    {
        ReplyToCommand(client, "[SM] Usage: sm_specround <weapon>");
        return Plugin_Handled;
    }
    GetCmdArg(1, weapon, sizeof(weapon));
    round=true;
   
    return Plugin_Handled;
   
}
Или так:
C-подобный:
#include <sourcemod>
#include <sdktools>

public void OnPluginStart()
{
   
    HookEvent("round_start", Event_RoundStart);
    HookEvent("player_spawn", Event_PlayerSpawned);
    HookEvent("round_end", Event_RoundEnd);
   
}
public void Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
    HookEvent("round_end", Event_RoundEnd);
}
public void Event_PlayerSpawned(Handle:event, const String:name[], bool:dontBroadcast)
{
   
        int ent = GetPlayerWeaponSlot(GetClientOfUserId(GetEventInt(event,"userid")), 0);
        if(ent != -1)
        {
            RemovePlayerItem(GetClientOfUserId(GetEventInt(event,"userid")), ent);
            RemoveEdict(ent);       
        }
        GivePlayerItem(GetClientOfUserId(GetEventInt(event,"userid")), weapon);
   
}
public void Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
{
    UnhookEvent("round_start");
    UnhookEvent("player_spawn");
    UnhookEvent("round_end");
       
   
}
public Action:SpecialRound(client, args)
{
    if (args != 1)
    {
        ReplyToCommand(client, "[SM] Usage: sm_specround <weapon>");
        return Plugin_Handled;
    }
    GetCmdArg(1, weapon, sizeof(weapon));
    HookEvent("round_start", Event_RoundStart);
    HookEvent("player_spawn", Event_PlayerSpawned);
   
    return Plugin_Handled;
   
}
Надеюсь, что понятно объяснил.
 

DarklSide

Участник
Сообщения
931
Реакции
468
Если (ан)хукать события, то отказатся в использовании команды в первом раунде.

По идее сами события не часто исполняются, поэтому лучше их микс.

При вслучае с булевой: использовать команду можно, только на этапе (после конца раунда и до начала следующего). Поэтому убрать событие "round_end" и попытаться проверять булевую при старте раунда, и (ан)хукать событие спавн игрока, а если csgo то лучше событие "round_prestart").
Еще добавить булевую - на состояние собития спавна (есть его хук или нет).
 
Последнее редактирование:

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
попытаться проверять булевую при старте раунда, и (ан)хукать событие спавн игрока
В событии round_start? Бесполезная затея, событие спавна вызывается до начала раунда. Оффтоп
csgo то лучше событие "round_prestart"
Вот тут сработает верно. Оффтоп
Вообще, вместо события спавна лучше использовать хук "игрок взял/поднял оружие", так как оно может лежать на карте/выдаваться другими плагинами, да и покупать никто не запретил... Оффтоп
 
Последнее редактирование:

Vladius

Участник
Сообщения
18
Реакции
0
В событии round_start? Бесполезная затея, событие спавна вызывается до начала раунда. Оффтоп
Вот тут сработает верно. Оффтоп
Вообще, вместо события спавна лучше использовать хук "игрок взял/поднял оружие", так как оно может лежать на карте/выдаваться другими плагинами, да и покупать никто не запретил... Оффтоп
Я для своего авп сервера делаю, так что на карте точно ничего не валяется.

Если (ан)хукать события, то отказатся в использовании команды в первом раунде.

По идее сами события не часто исполняются, поэтому лучше их микс.

При вслучае с булевой: использовать команду можно, только на этапе (после конца раунда и до начала следующего). Поэтому убрать событие "round_end" и попытаться проверять булевую при старте раунда, и (ан)хукать событие спавн игрока, а если csgo то лучше событие "round_prestart").
Еще добавить булевую - на состояние собития спавна (есть его хук или нет).

Если дописать 1 код, то можно будет использовать и в середине раунда, я пока так и делаю. Можете пояснить, что такое микс?
 

DarklSide

Участник
Сообщения
931
Реакции
468
Можете пояснить, что такое микс?
Их сочетание:
PHP:
#include <sdktools>
#pragma newdecls required
bool round = false;
bool spawn = false;
char weapon[20];
public void OnPluginStart()
{
   HookEvent("round_prestart", Event_RoundStart);
   RegAdminCmd("sm_specround", SpecialRound, ADMFLAG_GENERIC, "sm_specround ak47");
}
public void Event_RoundStart(Event event, const char[] name, bool dontBroadcast)
{
   if (round)
   {
     HookEvent("player_spawn", Event_PlayerSpawned);
     round = false;
     spawn = true;
   }
   else if (spawn)
   {
     UnhookEvent("player_spawn", Event_PlayerSpawned);
     spawn = round;
   }
}
public void Event_PlayerSpawned(Event event, const char[] name, bool dontBroadcast)
{
   int client = GetClientOfUserId(event.GetInt("userid"));
   int ent = GetPlayerWeaponSlot(client, 0);
   if (ent != -1)
   {
     RemovePlayerItem(client, ent);
     RemoveEdict(ent);
   }
   GivePlayerItem(client, weapon);
}
public Action SpecialRound(int client, int args)
{
   if (args != 1)ReplyToCommand(client, "[SM] Usage: sm_specround <weapon>");
   else
   {
     GetCmdArgString(weapon, sizeof(weapon));
     Format(weapon, sizeof(weapon), "weapon_%s", weapon);
     round = true;
   }
   return Plugin_Handled;
}
public Action CS_OnBuyCommand(int client, const char[] weapons)
{
   if (spawn)
   {
     printCl(client);
     return Plugin_Handled;
   }
   return Plugin_Continue;
}
void printCl(int client)
{
   PrintToChat(client, "Раунд на выданное оружие");
}
public Action CS_OnCSWeaponDrop(int client, int weaponIndex)
{
   if (spawn && !GetEntityClassname(weaponIndex, weapon, sizeof(weapon))) // && GetEntityClassname... - не разрешить дроп на выданное оружие.
   {
     printCl(client);
     return Plugin_Handled;
   }
   return Plugin_Continue;
}
 
Последнее редактирование:

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
Ничего не забыто? Нет логики.
Format(weapon, sizeof(weapon), "weapon_%s", GetCmdArg(1, weapon, sizeof(weapon)));
Забавно даже) Пытаемся форматировать строку для оружия из количества записанных символов)
На
Обычно нет зон покупок, как я понимаю - не требуется.
Сейчас никуда не ведёт... Оффтоп
 
Последнее редактирование:

Monomizer

Держу JDW в бане.
Сообщения
1,947
  • Команда форума
  • #8
Ничего не забыто? Нет логики.
Забавно даже) Пытаемся форматировать строку для оружия из количества записанных символов)
На
Обычно нет зон покупок, как я понимаю - не требуется.
Сейчас никуда не ведёт... Оффтоп
Оффтоп
 

DarklSide

Участник
Сообщения
931
Реакции
468
Есть.
Забавно даже) Пытаемся форматировать строку для оружия из количества записанных символов)
Забавно.
P.S.: если сначала не идет получение any.
На awp Обычно нет зон покупок, как я понимаю - не требуется.
Сейчас никуда не ведёт...
Некоторое мульти (без использования pickup'a и получения тайма времени).
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
@Monomizer, Оффтоп
{UnhookEvent("player_spawn", Event_PlayerSpawned);
spawn = round;
}}
Наконец заметил фигурную скобочку... Ты бы ещё 2 стиля написания впихнул)
Некоторое мульти (без использования pickup'a и получения тайма времени)
Ну какая нам разница, удалось получить classname оружия или нет? Вот если бы его после сравнить... Тогда получим фильтр:
не разрешить дроп на выданное оружие
 
Последнее редактирование:

DarklSide

Участник
Сообщения
931
Реакции
468
PHP:
public void Event_RoundStart(Event event, const char[] name, bool dontBroadcast)
{
   if (round)
   {
     HookEvent("player_spawn", Event_PlayerSpawned);
     round = false;
   }
   else if (spawn){UnhookEvent("player_spawn", Event_PlayerSpawned);
   spawn = round;
}}

P.S.: при вставке сообщения удалил блок, после парсинга TextFX'ом.
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
Оффтоп
Format(weapon, sizeof(weapon), "weapon_%s", GetCmdArg(1, weapon, sizeof(weapon)));
Не будет работать из-за этого, не выдаст ничего. Количество символов, полученное от 1 аргумента здесь пытаемся вставить в строку строкой.
 

DarklSide

Участник
Сообщения
931
Реакции
468
PHP:
public Action SpecialRound(int client, int args)
{
    if (args != 1)ReplyToCommand(client, "[SM] Usage: sm_specround <weapon>");
    else
    {
        GetCmdArgString(weapon, sizeof(weapon));
        Format(weapon, sizeof(weapon), "weapon_%s", weapon);
        spawn = true;
        round = true;
    }
    return Plugin_Handled;
}
В этом случае лучше получать все строку, раз она задана.
 
Последнее редактирование:

Vladius

Участник
Сообщения
18
Реакции
0
Честно говоря, я так до конца и не уяснил ответ на свой вопрос.
 

inklesspen

Не пишу модули под LSD :с
Сообщения
1,775
Реакции
966
Возможно это не то, что вам нужно, но времени у меня щас не особо много, а помочь хочу:)
 

Вложения

  • respawnwithkalash.sp
    650 байт · Просмотры: 19

Vladius

Участник
Сообщения
18
Реакции
0
Возможно это не то, что вам нужно, но времени у меня щас не особо много, а помочь хочу:)
Спасибо, но дело в том, что у меня уже есть рабочий плагин, просто хотел оптимизировать. Сейчас у меня уже другая проблема. После последнего обновления на карте awp_lego_2 если был установлен раунд на калашх, то в следующем раунде у выживших игроков калаши не пропадут, как раньше. То есть нужно самому удалять у них калаши. А как это сделать я не знаю.
 

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
Спасибо, но дело в том, что у меня уже есть рабочий плагин, просто хотел оптимизировать. Сейчас у меня уже другая проблема. После последнего обновления на карте awp_lego_2 если был установлен раунд на калашх, то в следующем раунде у выживших игроков калаши не пропадут, как раньше. То есть нужно самому удалять у них калаши. А как это сделать я не знаю.
Получаешь слот оружия GetPlayerWeaponSlot и делаешь цикл по всем слотам оружия и удаляешь.
Цикл: for (int i = 0; i < 5; ++i)
 

Vladius

Участник
Сообщения
18
Реакции
0
Получаешь слот оружия GetPlayerWeaponSlot и делаешь цикл по всем слотам оружия и удаляешь.
Цикл: for (int i = 0; i < 5; ++i)
Так не получится, потому что умершие игроки останутся без оружия. Я пока жду фикса, но вот уже 4 обновления ничего не решают.
 

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
Так не получится, потому что умершие игроки останутся без оружия. Я пока жду фикса, но вот уже 4 обновления ничего не решают.
А зачем тебе умершим оружие? что за бред.
 
Сверху Снизу