Русское сообщество по скриптингу

[Модуль AMXX] Round Control

Файлы и модули, которые пригодятся при скриптинге для AMX Mod X или SourceMod.
Правила форума
1. Запрещено материться и оскорблять других участников форума.
2. Запрещен флуд, оффтоп, дабл постинг во всех разделах форума, кроме раздела "Болтовня".
3. Запрещено взламывать сайт/форум или наносить любой вред проекту.
4. Запрещено рекламировать другие ресурсы.
5. Запрещено создавать темы без информативного названия. Название темы должно отображать ее смысл.

В данном разделе форума разрешено выкладывать файлы или модули для AMXX/SM, которые пригодятся при программировании.

[Модуль AMXX] Round Control

Сообщение s1lent » 04 май 2014, 11:59

RoundControl


Автор: s1lent
Весрия: 2.2

Описание: В основном модуль предназначен для разработчиков, как отдельный инструмент для работы над раундами. Модуль умеет - блокировать полностью раунд, принудительно завершать раунд (Победа CT, T, НИЧЬЯ), блокировать конец раунда по собственному желанию в нужный момент.
Также снимает ограничение с CVAR mp_roundtime, можно ставить 500 минут, выше не советую - собьется HUD.

Поддерживаемые версии HLDS:
- Windows 5758,6027,6132
- Linux 5787,6027,6132

Установка:
roundcontrol_amxx.dll | roundcontrol_amxx_i386.so положить в папку /cstrike/amxmodx/modules/
и прописать roundcontrol модуль в /cstrike/amxmodx/configs/modules.ini

API:

Блокировка окончания раунда
Возможность заблокировать окончание раунда только в нужный момент используя совместно с плагином.

Регистрируем форвард
Код: Выделить всё
public plugin_init()
{
        
RegisterControl(RC_CheckWinConditions,"fw_CheckWinConditions");


Уничтожение форварда
Код: Выделить всё
new RoundControlHook:g_pWinCondHook;
 
public 
plugin_init()
{
        
g_pWinCondHook RegisterControl(RC_CheckWinConditions,"fw_CheckWinConditions");
}
 
public 
removeHook()
{
        
UnregisterControl(RC_CheckWinConditions,g_pWinCondHook);


Функция CheckWinConditions, вызывается когда заканчивается раунд, игрок заходит в игру или меняет команду.

ROUND_CONTINUE - Продолжает выполнение функции, в нашем случае произойдет конец раунда.
ROUND_SUPERCEDE - Блокирует дальнейшее выполнение функции, окончание раунда будет заблокирован.

Код: Выделить всё
 
public fw_CheckWinConditions()
{
        
client_print(0,print_chat,"* Forward ^"CheckWinConditions^" called.");
        if(
g_pBlockEnd)// Предположим у нас свой мод и g_pBlockEnd == true, раунд не будет завершаться, пока g_pBlockEnd снова не станет false.
        
{
                return 
ROUND_SUPERCEDE;
        }
        return 
ROUND_CONTINUE;
}
  


roundcontrol.inc
Код: Выделить всё
#if defined _roundcontrol_included
   #endinput
#endif

#define _roundcontrol_included

#if AMXX_VERSION_NUM >= 175
   #pragma reqlib roundcontrol
   #if !defined AMXMODX_NOAUTOLOAD
      #pragma loadlib roundcontrol
   #endif
#else
   #pragma library roundcontrol
#endif

#define DONT_REG         -1
#define BLOCK_BOTH         0
#define BLOCK_ONLY_EXPIRED      1

#define FLAG_RETRACT_EXPIRED      (1<<0)                     /* Этот флаг убирает перехват функции HasRoundTimeExpired за ненадобностью. */

#define RC_NONE            0
#define RC_SOUND         (1<<0)                     /* Воспроизводить звук победы. */
#define RC_MESSAGE         (1<<1)                     /* Сообщение окончания раунда. ( Автоматически составляет сообщение по событии eventid ) */
#define RC_SCORE         (1<<2)                     /* Прибавлять команде победные очки. */

#define RC_ALL_AUTO         (RC_SOUND|RC_SCORE)
#define RC_ALL_CUSTOM         (RC_SOUND|RC_MESSAGE|RC_SCORE)

#define ROUND_CONTINUE         0                     /* Продолжает выполнение функции */
#define ROUND_SUPERCEDE         4                     /* Блокирует дальнейшее выполнение функции */

enum (+= 4)
{
   m_bFreezePeriod = 4,
   m_bBombDropped,

   m_flRestartRoundTime = 48,      // +4 float   | W.48 | L.40
   m_flCheckWinConditions,         // +4 float   | W.52 | L.44
   m_fRoundCount,            // +4 float   | W.56 | L.48
   m_iRoundTime,            // +4 int   | W.60 | L.52
   m_iRoundTimeSecs,         // +4 int   | W.64 | L.56
   m_iIntroRoundTime,         // +4 int   | W.68 | L.60
   m_fIntroRoundCount,         // +4 int   | W.72 | L.64
   m_iAccountTerrorist,         // +4 int   | W.76 | L.68
   m_iAccountCT,            // +4 int   | W.80 | L.68
   m_iNumTerrorist,         // +4 int   | W.84 | L.76
   m_iNumCT,            // +4 int   | W.88 | L.80
   m_iNumSpawnableTerrorist,      // +4 int   | W.92 | L.84
   m_iNumSpawnableCT,         // +4 int   | W.96 | L.88
   m_iSpawnPointCount_Terrorist,      // +4 int   | W.100 | L.92
   m_iSpawnPointCount_CT,         // +4 int   | W.104 | L.96
   m_iHostagesRescued,         // +4 int   | W.108 | L.100
   m_iHostagesTouched,         // +4 int   | W.112 | L.104
   m_iRoundWinStatus,         // +4 int   | W.116 | L.108
   m_iNumCTWins,            // +2 short   | W.120 | L.112
   m_iNumTerroristWins = 122,      // +2 short   | W.122 | L.114
   m_bTargetBombed = 124,         // +1 bool   | W.124 | L.116
   m_bBombDefused = 125,         // +1 bool   | W.125 | L.117
   m_bMapHasBombTarget = 126,      // +1 bool   | W.126 | L.118
   m_bMapHasBombZone = 127,      // +1 bool   | W.127 | L.119
   m_bMapHasBuyZone = 128,         // +1 bool   | W.128 | L.120
   m_bMapHasRescueZone = 129,      // +1 bool   | W.129 | L.121
   m_bMapHasEscapeZone = 130,      // +1 bool   | W.130 | L.122
   m_iMapHasVIPSafetyZone = 132,      // +4 int   | W.132 | L.124
   m_bMapHasCameras,         // +4 bool   | W.136 | L.128
   m_iC4Timer,            // +4 int   | W.140 | L.132
   m_iC4Guy,            // +4 int   | W.144 | L.136
   m_iLoserBonus,            // +4 int   | W.148 | L.140
   m_iNumConsecutiveCTLoses,      // +4 int   | W.152 | L.144
   m_iNumConsecutiveTerroristLoses,   // +4 int   | W.156 | L.148
   m_fMaxIdlePeriod,         // +4 int   | W.160 | L.152
   m_iLimitTeams,            // +4 int   | W.164 | L.156
   m_bLevelInitialized,         // +1 bool   | W.168 | L.160
   m_bRoundTerminating = 169,      // +1 bool   | W.169 | L.161
   m_bCompleteReset = 170,         // +1 bool   | W.170 | L.162
   m_flRequiredEscapeRatio = 172,      // +4 float   | W.172 | L.164
   m_iNumEscapers,            // +4 float   | W.176 | L.168
   m_iHaveEscaped,            // +4 float   | W.180 | L.172
   m_bCTCantBuy,            // +1 bool   | W.184 | L.176
   m_bTCantBuy = 185,         // +1 bool   | W.185 | L.177
   m_flBombRadius = 188,         // +4 float   | W.188 | L.180
   m_iConsecutiveVIP,         // +4 float   | W.192 | L.184
   m_iTotalGunCount,         // +4 int   | W.196 | L.188
   m_iTotalGrenadeCount,         // +4 int   | W.200 | L.192
   m_iTotalArmourCount,         // +4 int   | W.204 | L.196
   m_iUnBalancedRounds,         // +4 int   | W.208 | L.200
   m_iNumEscapeRounds,         // +4 int   | W.212 | L.204
   m_iMapVotes,            // +400 int   | W.216 | L.208
   m_iLastPick = 616,         // +4 int   | W.616 | L.608
   m_iMaxMapTime,            // +4 int   | W.620 | L.612
   m_iMaxRounds,            // +4 int   | W.624 | L.616
   m_iTotalRoundsPlayed,         // +4 int   | W.628 | L.620
   m_iMaxRoundsWon,         // +4 int   | W.632 | L.624
   m_iStoredSpectValue,         // +4 int   | W.636 | L.628
   m_flForceCameraValue,         // +4 float   | W.640 | L.632
   m_flForceChaseCamValue,         // +4 float   | W.644 | L.636
   m_flFadeToBlackValue,         // +4 float   | W.648 | L.640
   m_pVIP,               // +4 pvdata   | W.652 | L.644
   VIPQueue,            // +20 pvdata   | W.656 | L.648
   m_flIntermissionEndTime = 676,      // +4 pvdata   | W.676 | L.668
   m_flIntermissionStartTime,      // +4 float   | W.680 | L.672
   m_iEndIntermissionButtonHit,      // +4 int   | W.684 | L.676
   m_tmNextPeriodicThink,         // +4 float   | W.688 | L.680
   m_bFirstConnected,         // +1 bool   | W.692 | L.684
   m_bInCareerGame = 693,         // +1 bool   | W.693 | L.685
   m_fCareerRoundMenuTime = 696,      // +4 float   | W.696 | L.688
   m_iCareerMatchWins,         // +4 int   | W.700 | L.692
   m_iRoundWinDifference,         // +4 int   | W.704 | L.696
   m_fCareerMatchMenuTime,         // +4 float   | W.708 | L.700
   m_bSkipSpawn            // +1 bool   | W.712 | L.704
};

enum RoundEvent
{
   EventDefault = 0,
   TargetBombed,
   VIPEscaped,
   VIPAssassinated,
   TerroristEscaped,
   CTsPreventEscape,
   EscapingTerroristNeutralized,
   BombDefused,
   CTsWin,
   TerroristWin,
   RoundDraw,
   AllHostagesRescued,
   TargetSaved,
   HostagesNotRescued,
   TerroristNotEscaped,
   VIPNotEscaped,
   GameCommencing
};

enum RoundControlWin
{
   WINSTATUS_CT = 1,
   WINSTATUS_TERRORIST,
   WINSTATUS_DRAW
};

enum RoundControlFunc
{
   /*
   * void
   */
   RC_CheckWinConditions = 0,         // (void);

   /*
    * teamWins - какая команда побеждает.
    * numWins - победные очки.
    * eventRound - событие окончание раунда.
    * bHasExpired - раунд закончился по истечению времени.
   */
   RC_RoundEnd               // (RoundControlWin:teamWins,numWins,RoundEvent:eventRound,bool:bHasExpired)
};

/*
 * Регистрация форварда
 *
*/
native RoundControlHook:RegisterControl(RoundControlFunc:function,const callback[],Post = 0);

/*
 * Удаление форварда
 *
*/
native UnregisterControl(RoundControlFunc:function,RoundControlHook:hookid,Post = 0);

/*
 * Позволяет составить условие для постоянной блокировки
 *
*/
native RoundControlHook:SetBlockControl(RoundControlFunc:function,any:...);

/*
 * Удаляет блокировку
 *
*/
native RemoveBlockControl(RoundControlFunc:function,RoundControlHook:hookid);

/**
 * Возобновляет вызов форварда
 *
*/
native EnableControl(RoundControlHook:hookid,Post = 0);

/**
 * Приостанавливает вызов форварда
 *
*/
native DisableControl(RoundControlHook:hookid,Post = 0);

/*
 * Вызов функции из gamedll, в частности функцию CheckWinConditions
 * Вызов RoundEnd имитирует конце раунда
 *
*/
native ExecuteControl(RoundControlFunc:function,any:...);

/*
 * Действует только для RoundEnd и только в PRE
 * Дает возможность изменить параметры, которые передается в функции.
*/
native SetReturnParamControl(RoundControlFunc:function,any:...);

/*
 * Устанавливает особые флаги
 *
*/
native SetFlagsControl(const flags = FLAG_RETRACT_EXPIRED);

/*
 * Обновить табло счёта и установить/добавить очки команде.
 *
*/
native RoundUpdateScoreWins(ctsWins = 0,tsWins = 0,bool:bAdd = true);

/*
 * Принудительное окончание раунда.
 *
 * @param winStatus      Команда которая побеждает.
 * @param fDelay      Время (задержка), через которое наступит следующий раунд.
 * @param flags         Флаги RC_SOUND, RC_MESSAGE,RC_SCORE.
 * @param sentence      Своё сообщение о победе. (По умолчанию сообщение определяется по eventid)
 * @param eventid      Событие победы, "RoundEvent".
 * @param numScore      Сколько очков получает побежденная команда (По умолчанию +1)
 * @param bReset      Отбирать всю экипировку, фраги, смерти, победы в начале нового раунда. (Идентично sv_restart 1)
 *
 * @return         nothing
 */
native RoundEndForceControl(RoundControlWin:winStatus = WINSTATUS_CT,Float:fDelay = 5.0,flags = RC_ALL_CUSTOM,const sentence[] = "#Round_Draw",RoundEvent:eventid = EventDefault,numScore = 1,bool:bReset = false);

native set_pgame_int(_offset,_value,_linuxdiff = 8);

native get_pgame_int(_offset,_linuxdiff = 8);

native set_pgame_float(_offset,Float:_value,_linuxdiff = 8);

native Float:get_pgame_float(_offset,_linuxdiff = 8);

native set_pgame_short(_offset,Float:_value,_linuxdiff = 8);

native get_pgame_short(_offset,_linuxdiff = 8);

native set_pgame_bool(_offset,bool:_value,_linuxdiff = 8);

native bool:get_pgame_bool(_offset,_linuxdiff = 8);

native set_pgame_cbase(_Index_,_offset,_linuxdiff = 8);

native get_pgame_cbase(_offset,_linuxdiff = 8);

/*
* @return адрес указателя g_pGameRules
*/
native get_pgame_rules();

Принудительно завершить раунд
Код: Выделить всё
/*
 * Принудительное окончание раунда.
 *
 * @param winStatus             Команда которая побеждает.
 * @param fDelay                Время (задержка), через которое наступит следующий раунд.
 * @param flags                 Флаги RC_SOUND, RC_MESSAGE,RC_SCORE.
 * @param sentence              Своё сообщение о победе. (По умолчанию сообщение определяется по eventid)
 * @param eventid               Событие победы, "RoundEvent".
 * @param numScore              Сколько очков получает побежденная команда (По умолчанию +1)
 * @param bReset                Отбирать всю экипировку, фраги, смерти, победы в начале нового раунда. (Идентично sv_restart 1)
 *
 * @return                      nothing
 */
native RoundEndForceControl(RoundControlWin:winStatus WINSTATUS_CT,Float:fDelay 5.0,flags RC_ALL_CUSTOM,const sentence[] = "#Round_Draw",RoundEvent:eventid EventDefault,numScore 1,bool:bReset false); 


Принудительно завершить победный раунд в пользу CT.
Код: Выделить всё
 register_clcmd("say /ctwin","cmdCtwin");
 
public 
cmdCtwin(id)
{
        
RoundEndForceControl(WINSTATUS_CT);


Исходники:
Вы должны зарегистрироваться, чтобы видеть ссылки.
Последний раз редактировалось s1lent 01 ноя 2014, 00:28, всего редактировалось 14 раз(а).
Аватара пользователя
s1lent
Скриптер
 
Сообщения: 123
Зарегистрирован: 11 июл 2011, 20:02
Откуда: Северск
Благодарил (а): 32 раз.
Поблагодарили: 110 раз.

Re: [Модуль AMXX] Round Control

Сообщение Morning Rainbow » 22 авг 2014, 15:57

draft, судя по описанию колбэк Round_CheckWinConditions вообще не имеет параметров, а ты всунул какие-то)
Аватара пользователя
Morning Rainbow
 
Сообщения: 73
Зарегистрирован: 28 июл 2013, 00:35
Откуда: ??chan
Благодарил (а): 7 раз.
Поблагодарили: 50 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6

Re: [Модуль AMXX] Round Control

Сообщение Dmitry Beast » 22 авг 2014, 16:04

ё-маё, до меня только допёрло по какой я теме не попал :ROFL:
Аватара пользователя
Dmitry Beast
 
Сообщения: 1560
Зарегистрирован: 24 дек 2010, 10:35
Откуда: Египет
Благодарил (а): 440 раз.
Поблагодарили: 207 раз.
Опыт программирования: Больше трех лет
Языки программирования: All Languages

Re: [Модуль AMXX] Round Control

Сообщение draft » 22 авг 2014, 17:16

Morning Rainbow писал(а):draft, судя по описанию колбэк Round_CheckWinConditions вообще не имеет параметров, а ты всунул какие-то)

Да, увидел это и тогда снова возвращаемся к вопросу, как этим модулем перехватывать события RoundDraw / Game Commencing? По-моему, Round_CheckWinConditions без параметров выглядит немного бесполезной. В частности, я хочу запретить рестарт раунда при Game Commencing, когда идёт игра 1х1 и противник решил сделать реконнект, как мне это сделать без костылей?

Добавлено спустя 15 минут 6 секунд:
И ещё заметил баг, что событие Round_CheckWinConditions по истечении времени раунда не вызывается...
Аватара пользователя
draft
 
Сообщения: 10
Зарегистрирован: 05 фев 2010, 09:52
Благодарил (а): 2 раз.
Поблагодарили: 3 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6

Re: [Модуль AMXX] Round Control

Сообщение s1lent » 24 авг 2014, 18:26

draft писал(а):И ещё хотел задать вопрос. В коде модуля я нашёл функцию StartFrame и в ней в начале HasRoundTimeExpired - я правильно понял, что этот плагин проверяет события окончания времени раунда в каждом фрейме?


какой плагин обрабатывает события окончания раунда? что за чушь, модуль обрабатывает, а точнее эмитирует, как только окончание раунда происходит вызывает зарегистрированные форварды amxx плагинами.

Код: Выделить всё
void CHalfLifeMultiplay::Think(void)

тоже вызывает каждый фрейм в StartFrame, и что?

draft писал(а):И ещё заметил баг, что событие Round_CheckWinConditions по истечении времени раунда не вызывается...

какой еще баг? CheckWinConditions и не должен отвечать за истечении времени раунда, за это отвечает HasRoundTimeExpired, правда на винде ее нет, там заинлайнилась во внутрь CHalfLifeMultiplay::Think

draft писал(а):В частности, я хочу запретить рестарт раунда при Game Commencing, когда идёт игра 1х1 и противник решил сделать реконнект, как мне это сделать без костылей?


наверно так
[pawn]
  1.  

  2. public client_disconnect(id) {

  3.  

  4.         if(!get_pgame_int(m_iNumSpawnableTerrorist) || !get_pgame_int(m_iNumSpawnableCT))

  5.                 set_pgame_bool(m_bFirstConnected,true);

  6. }
[/pawn]

Добавлено спустя 1 минуту 22 секунды:
да и вообще идеально, нужно объединить три функции (Round_WinCounterTerrorist, Round_WinTerrorist, Round_HasRoundTimeExpired) в одну
[pawn]
  1. public RoundEnd(RoundControlWin:teamWins,numWins,RoundEvent:eventRound,bool:bHasExpired)
[/pawn]
Аватара пользователя
s1lent
Скриптер
 
Сообщения: 123
Зарегистрирован: 11 июл 2011, 20:02
Откуда: Северск
Благодарил (а): 32 раз.
Поблагодарили: 110 раз.

Re: [Модуль AMXX] Round Control

Сообщение draft » 25 авг 2014, 04:09

s1lent писал(а):
draft писал(а):И ещё хотел задать вопрос. В коде модуля я нашёл функцию StartFrame и в ней в начале HasRoundTimeExpired - я правильно понял, что этот плагин проверяет события окончания времени раунда в каждом фрейме?


какой плагин обрабатывает события окончания раунда? что за чушь, модуль обрабатывает, а точнее эмитирует, как только окончание раунда происходит вызывает зарегистрированные форварды amxx плагинами.

Да не надо так нервничать из-за опечатки, всем понятно, что в теме про модуль обсуждаем модуль.

Код: Выделить всё
void CHalfLifeMultiplay::Think(void)

тоже вызывает каждый фрейм в StartFrame, и что?

А я не говорил, что у Valve идеальный код, до сих пор эксплойты находят. А так, например, на счёт события установки бомбы было бы, я думаю, неплохо подумать, как оптимизировать: как вариант, это при первом получении, что бомба установлена запомнить это в переменную до конца раунда либо найти какие-то оффсеты, отвечающие событию установленной бомбы.
draft писал(а):И ещё заметил баг, что событие Round_CheckWinConditions по истечении времени раунда не вызывается...

какой еще баг? CheckWinConditions и не должен отвечать за истечении времени раунда, за это отвечает HasRoundTimeExpired, правда на винде ее нет, там заинлайнилась во внутрь CHalfLifeMultiplay::Think

А я откуда знаю, что должно или не должно отвечать? С учётом текущей документации по модулю для меня этот факт не был очевидным, потому что в твоих примерах блокировок конца раунда ни слова про то, что нужно блокировать отдельно RoundTimeExpired не увидел, поэтому и решил, что это баг.

draft писал(а):В частности, я хочу запретить рестарт раунда при Game Commencing, когда идёт игра 1х1 и противник решил сделать реконнект, как мне это сделать без костылей?


наверно так
[pawn]
  1.  

  2. public client_disconnect(id) {

  3.  

  4.         if(!get_pgame_int(m_iNumSpawnableTerrorist) || !get_pgame_int(m_iNumSpawnableCT))

  5.                 set_pgame_bool(m_bFirstConnected,true);

  6. }
[/pawn]

Опять же пример нерабочий, но спасибо за идею, я её доработал и реализовал.
Нерабочий он по двум причинам:
1) На событии client_disconnect оффсеты m_iNumSpawnableTerrorist и m_iNumSpawnableCT ещё не обнулены.
2) set_pgame_bool(m_bFirstConnected,true) - тоже не будет работать, потому что я попробовал так и при вызове CheckWinConditions это значение уже обнулено.
Эту штуку нужно ставить прямо внутрь хука CheckWinConditions, итого примерно такой код рабочий:
[pawn]
  1.   

  2. new RoundControlHook:fwdCheckWinCond

  3.  

  4. public plugin_init() {

  5. }

  6.  

  7. public updateTeamNum()

  8. {

  9.         g_iCTnum = get_pgame_int(m_iNumCT)

  10.         g_iTnum = get_pgame_int(m_iNumTerrorist)

  11. }

  12.  

  13. public client_disconnect(id)

  14. {

  15.         new team = get_user_team(id)

  16.         if(0 < team < 3)

  17.                 set_task(0.1, "check_blockGameCommence")

  18. }

  19.  

  20. public check_blockGameCommence()

  21. {

  22.         if(!get_pgame_int(m_iNumSpawnableTerrorist) || !get_pgame_int(m_iNumSpawnableCT))

  23.                         fwdCheckWinCond = RegisterControl(Round_CheckWinConditions,"forward_CheckWinConditions")

  24. }

  25.  

  26. public forward_CheckWinConditions()

  27. {

  28.                 set_pgame_bool(m_bFirstConnected,true)

  29.                 RemoveControl(Round_CheckWinConditions, fwdCheckWinCond)

  30. }

  31.  
[/pawn]

да и вообще идеально, нужно объединить три функции (Round_WinCounterTerrorist, Round_WinTerrorist, Round_HasRoundTimeExpired) в одну
[pawn]
  1. public RoundEnd(RoundControlWin:teamWins,numWins,RoundEvent:eventRound,bool:bHasExpired)
[/pawn]

Плюсую.
Последний раз редактировалось draft 25 авг 2014, 16:13, всего редактировалось 6 раз(а).
Аватара пользователя
draft
 
Сообщения: 10
Зарегистрирован: 05 фев 2010, 09:52
Благодарил (а): 2 раз.
Поблагодарили: 3 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6

Re: [Модуль AMXX] Round Control

Сообщение s1lent » 25 авг 2014, 10:53

draft писал(а):А я не говорил, что у Valve идеальный код, до сих пор эксплойты находят. А так, например, на счёт события установки бомбы было бы, я думаю, неплохо подумать, как оптимизировать: как вариант, это при первом получении, что бомба установлена запомнить это в переменную до конца раунда либо найти какие-то оффсеты, отвечающие событию установленной бомбы.


я тебя не понимаю.
IsBombPlanted вызывается один раз, как время подошло к концу, какая еще тут может быть оптимизация? хукать кучу месседжев ради перехвата сообщения о установленной бомбы? это не вариант.

да я и не нервничаю, просто у тебя должны бы обоснованные сообщения, почему это вдруг понадобилась оптимизация. сервер лагает?
Аватара пользователя
s1lent
Скриптер
 
Сообщения: 123
Зарегистрирован: 11 июл 2011, 20:02
Откуда: Северск
Благодарил (а): 32 раз.
Поблагодарили: 110 раз.

Re: [Модуль AMXX] Round Control

Сообщение draft » 25 авг 2014, 15:10

Код: Выделить всё

bool HasRoundTimeExpired()
{
// Вызывается в каждом стартфрейме
   if(TimeRemaining() > 0 || *(int *)((char *)g_pGameRules + OFFSET_GAME_ROUND_WIN_INT))
      return FALSE;
// Если таймер обнулился и нет команды-победителя , проверяем событие установленной бомбы.
   return IsBombPlanted() != true;
// Соответственно, если бомба установлена, то функция проверит true != true и вернёт false в HasRoundTimeExpired и дальше в следующем StartFrame эта же проверка произойдёт заново.
}

bool IsBombPlanted()
{
   if(*(bool *)((char *)g_pGameRules + OFFSET_GAME_HAS_TARGTER_BOMB_BOOL)) {
      edict_t *pGrenade = NULL;
      while((pGrenade = findEntityByClassname(pGrenade,"grenade")) != NULL) {
         if(*(bool *)((char *)pGrenade->pvPrivateData + OFFSET_IS_C4)) {
            return true;
         }
      }
   }
   return false;
}

void StartFrame()
{
   if(!HasRoundTimeExpired()) {
      RETURN_META(MRES_IGNORED);
   }
//...
}


Я привёл комментарии, как я понял код. Исходя из этого можно уточнить, точно ли IsBombPlanted вызывается один раз в момент установки бомбы, а не все 35 секунд * кол-во стартфреймов, пока она стоит + также возможна ситуация, где другими модулями / плагинами заблокировано окончание раунда по истечении времени и тогда эта проверка будет тоже?
Аватара пользователя
draft
 
Сообщения: 10
Зарегистрирован: 05 фев 2010, 09:52
Благодарил (а): 2 раз.
Поблагодарили: 3 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6

Re: [Модуль AMXX] Round Control

Сообщение s1lent » 25 авг 2014, 15:26

не будет заново потому, что TimeRemaining() уже будет > 0
Аватара пользователя
s1lent
Скриптер
 
Сообщения: 123
Зарегистрирован: 11 июл 2011, 20:02
Откуда: Северск
Благодарил (а): 32 раз.
Поблагодарили: 110 раз.

Re: [Модуль AMXX] Round Control

Сообщение s1lent » 25 авг 2014, 16:22

draft писал(а):Я привёл комментарии, как я понял код. Исходя из этого можно уточнить, точно ли IsBombPlanted вызывается один раз в момент установки бомбы, а не все 35 секунд * кол-во стартфреймов, пока она стоит

Поторопился с выводом, верно, после истечении времени каждый фрейм проверяется на присутствии триггер зоны для установки бомбы и присутствии самой бомбы на карте.

draft писал(а):также возможна ситуация, где другими модулями / плагинами заблокировано окончание раунда по истечении времени и тогда эта проверка будет тоже?

будет тоже.

если плагинами с roundcontrol, то там проверит сначала есть ли окончание раунда, а потом уже блокировка, так что в любом случае проверка выполнится.

оптимальный способ без дополнительных хуков не сделать, чего как раз не хочется и
никаких оффсетов на это события тоже нет и т.п
Аватара пользователя
s1lent
Скриптер
 
Сообщения: 123
Зарегистрирован: 11 июл 2011, 20:02
Откуда: Северск
Благодарил (а): 32 раз.
Поблагодарили: 110 раз.

Re: [Модуль AMXX] Round Control

Сообщение draft » 26 авг 2014, 04:34

Ещё один баг заметил - не получается снять хук Round_HasRoundTimeExpired:

[pawn]
  1.  

  2. new RoundControlHook:fwdHasRoundTimeExpired

  3.  

  4. public plugin_init()

  5. {

  6.         fwdHasRoundTimeExpired = RegisterControl(Round_HasRoundTimeExpired, "forward_RTE")

  7. }

  8.  

  9. public forward_RTE()

  10. {

  11.         server_print("remove forward RTE")

  12.         client_print(0, print_chat, "remove forward RTE")

  13.         RemoveControl(Round_HasRoundTimeExpired, fwdHasRoundTimeExpired)

  14. }

  15.  
[/pawn]

Всё равно каждый раунд вижу "remove forward RTE"
Аватара пользователя
draft
 
Сообщения: 10
Зарегистрирован: 05 фев 2010, 09:52
Благодарил (а): 2 раз.
Поблагодарили: 3 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6

Пред.След.

Вернуться в Файлы и модули

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8