Objective reset problem

Сообщения
86
Реакции
2
Предупреждения
1
Ошибка
L 05/19/2022 - 12:40:23: -------- Mapchange to de_dust2 --------
L 05/19/2022 - 12:40:23: [ORPHEU] Function "InstallGameRules" not found
L 05/19/2022 - 12:40:23: [AMXX] Displaying debug trace (plugin "objective.amxx", version "unknown")
L 05/19/2022 - 12:40:23: [AMXX] Run time error 10: native error (native "OrpheuGetFunction")
L 05/19/2022 - 12:40:23: [AMXX] [0] objective.sma::plugin_precache (line 114)

L 05/19/2022 - 12:40:25: [ORPHEU] Function "CHostage::RePosition" not found
L 05/19/2022 - 12:40:25: [AMXX] Displaying debug trace (plugin "objective.amxx", version "unknown")
L 05/19/2022 - 12:40:25: [AMXX] Run time error 10: native error (native "OrpheuGetFunction")
L 05/19/2022 - 12:40:25: [AMXX] [0] objective.sma::plugin_init (line 214)
ОС
Windows
Amx Mod X
AMX Mod X 1.9.0.5294 (http://www.amxmodx.org)
Authors:
David "BAILOPAN" Anderson, Pavol "PM OnoTo" Marko
Felix "SniperBeamer" Geyer, Jonny "Got His Gun" Bergstrom
Lukasz "SidLuke" Wlasinski, Christian "Basic-Master" Hammacher
Borja "faluco" Ferrer, Scott "DS" Ehlert
Compiled: Dec 3 2021 22:52:28
Built from: https://github.com/alliedmodders/amxmodx/commit/363871a8
Build ID: 5294:363871a8
Core mode: JIT+ASM32
Билд
Protocol version 48
Exe version 1.1.2.7/Stdio (cstrike)
ReHLDS version: 3.11.0.776-dev
Build date: 19:38:11 Apr 20 2022 (2930)
Build from: https://github.com/dreamstalker/rehlds/commit/3dc9f8c
ReGamedll
ReGameDLL version: 5.21.0.573-dev
Build date: 15:52:15 Mar 11 2022
Build from: https://github.com/s1lentq/ReGameDLL_CS/commit/0b08d9c
Версия Metamod
Metamod-r v1.3.0.128, API (5:13)
Metamod-r build: 15:47:38 Aug 24 2018
Metamod-r from: https://github.com/theAsmodai/metamod-r/commit/0cf2f70
Список метамодулей
[ 1] AMX Mod X     RUN   -    amxmodx_mm.dll        v1.9.0.5294      ini  Start ANY
[ 2] HitBox Fix RUN - hitbox_fix_mm.dll v1.0.10 ini Start ANY
[ 3] YaPB RUN - yapb.dll v4.2.671 ini Chlvl ANY
[ 4] MySQL RUN - mysql_amxx.dll v1.9.0.5294 pl1 ANY ANY
[ 5] SQLite RUN - sqlite_amxx.dll v1.9.0.5294 pl1 ANY ANY
[ 6] Fun RUN - fun_amxx.dll v1.9.0.5294 pl1 ANY ANY
[ 7] Engine RUN - engine_amxx.dll v1.9.0.5294 pl1 ANY ANY
[ 8] FakeMeta RUN - fakemeta_amxx.dll v1.9.0.5294 pl1 ANY ANY
[ 9] CStrike RUN - cstrike_amxx.dll v1.9.0.5294 pl1 ANY ANY
[10] Ham Sandwich RUN - hamsandwich_amxx.dll v1.9.0.5294 pl1 ANY ANY
[11] ReAPI RUN - reapi_amxx.dll v5.21.0.248-dev pl1 ANY Never
[12] CSX RUN - csx_amxx.dll v1.9.0.5294 pl1 ANY ANY
[13] Orpheu RUN - orpheu_amxx.dll v2.6.3 pl1 ANY ANY
Список плагинов
[  1] Admin Chat              1.9.0.5273  AMXX Dev Team     adminchat.amxx   running
[ 2] MIX SYSTEM 1.0 stanciu mix.amxx debug
[ 3] Advanced Bullet Damage 1.0 Sn!ff3r abd.amxx running
[ 4] Advanced Bans 0.8 Exolent advanced_bans_s running
[ 5] CSStatsX SQL 0.7.4+2 serfreeman1337 points_test.amx running
[ 6] AES: StatsX 0.5+1 serfreeman1337 spoints.amxx running
[ 7] Reset Objective 0.1 HamletEagle objective.amxx debug
[ 8] Admin Base (SQL) 1.9.0.5263 AMXX Dev Team admins.amxx running
[ 9] Admin Commands 1.9.0.5263 AMXX Dev Team admincmd.amxx debug
[ 10] Restrict Weapons 1.9.0.5271 AMXX Dev Team restmenu.amxx running
Автор плагина
HamletEagle
Версия плагина
0.1
Исходный код
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <engine>
#include <hamsandwich>
#include <cstrike>
#include <orpheu>
#include <orpheu_memory>
#include <objective_reset>

#if !defined _orpheu_included
#assert "orpheu.inc library required ! Get it from https://forums.alliedmods.net/showthread.php?t=116393"
#endif

#if !defined _orpheu_memory_included
#assert "orpheu_memory.inc library required ! Get it from https://forums.alliedmods.net/showthread.php?t=116393"
#endif

#if !defined _objective_reset_included
#assert "objective_reset.inc library required ! Get it from https://forums.alliedmods.net/showthread.php?t=234986"
#endif

#define PluginName "Reset Objective"
#define PluginVersion "0.1"
#define PluginAuthor "HamletEagle"

//Alter GameRules offsets
#define get_gamerules_data(%0) OrpheuMemoryGetAtAddress(g_pGameRules, %0)
#define set_gamerules_data(%0,%1) OrpheuMemorySetAtAddress(g_pGameRules, %0, 1, %1)

#if AMXX_VERSION_NUM < 183
const INT_BYTES = 4
const BYTE_BITS = 8

stock bool:get_pdata_bool(ent, charbased_offset, intbase_linuxdiff = 5)
{
return !!(get_pdata_int(ent, charbased_offset / INT_BYTES, intbase_linuxdiff) & (0xFF<<((charbased_offset % INT_BYTES) * BYTE_BITS)))
}

stock set_pdata_bool(ent, charbased_offset, _:value, intbase_linuxdiff = 5)
{
value &= 0xFF
new int_offset_value = get_pdata_int(ent, charbased_offset / INT_BYTES, intbase_linuxdiff)
new bit_decal = (charbased_offset % INT_BYTES) * BYTE_BITS
int_offset_value &= ~(0xFF<<bit_decal) // clear byte
int_offset_value |= value<<bit_decal
set_pdata_int(ent, charbased_offset / INT_BYTES, int_offset_value, intbase_linuxdiff)
}
#endif

enum CustomForwards
{
ObjectiveResetted,
RoundTimeChanged
}

enum _:OrpheuFunctions
{
OrpheuFunction:InstallGameRules,
OrpheuFunction:PickNextVip, //CHalfLifeMultiplay
OrpheuFunction:RePosition, //CHostage
OrpheuFunction:GiveC4, //CHalfLifeMultiplay
OrpheuFunction:CheckWinConditions, //CHalfLifeMultiplay
OrpheuFunction:ResetMaxSpeed, //CBasePlayer
}

new OrpheuFunction:HandleHooks[OrpheuFunctions]
new HandleCForwards[CustomForwards]

new const ObjectiveNames[][] =
{
"",
"Timer",
"Bomb",
"Vip Assasination",
"Hostages Rescue",
"Escape"
}

new const ClassName [] = "classname"
new const HostageClassName[] = "hostage_entity"
new const GrenadeClassName[] = "grenade"

//This are full offsets, except the last one
const m_bEscaped = 836 //Player offset, used in both as and es maps. It is set to true for the player that escape
const m_bStartDefuse = 384 //Player offset
const m_bIsDefusing = 929 //Player offset
const m_bJustBlew = 432 //Grenade offset
const m_bIsC4 = 385 //Grenade offset
const m_pBombDefuser = 388 //Grenade offset
const m_flDefuseCountDown = 99 //Grenade offset

new gmsgRoundTime
new gmsgBombPickup
new gmsgShowTimer
new gmsgScoreAttrib
new gmsgBarTime

new CvarMpRoundTime
new CvarMpFreezeTime
new CvarSendHookableCalls
new CvarSendReliableMessages
new CvarShowChatMessage

new g_pGameRules
new MaxPlayers

new bool:InFreezeTime = true
new bool:SendReliableMessages = true
new bool:SendHookableCalls = false

public plugin_precache()
{
OrpheuRegisterHook(OrpheuGetFunction("InstallGameRules"), "OnInstallGameRules", OrpheuHookPost)
}

public OnInstallGameRules()
{
g_pGameRules = OrpheuGetReturn()
}

public plugin_init()
{
register_plugin
(
.plugin_name = PluginName,
.version = PluginVersion,
.author = PluginAuthor
)

register_concmd("SetRoundTime" , "ClientCommand_SetRoundTime" , ADMIN_RCON, "Set round time to a specific value")
register_concmd("GetRoundTime" , "ClientCommand_GetRoundTime" , ADMIN_RCON, "Get current round time in seconds")
register_concmd("ResetObjective", "ClientCommand_ResetObjective", ADMIN_RCON, "Reset current objective as it was at the beginning of the round")

register_event("HLTV", "OnNewRound_Event", "a", "1=0", "2=0")
register_logevent("OnRoundStart_Event", 2, "1=Round_Start")

CvarMpRoundTime = get_cvar_pointer("mp_roundtime" )
CvarMpFreezeTime = get_cvar_pointer("mp_freezetime" )
CvarSendHookableCalls = register_cvar("OR_SendHookableCalls" , "0")
CvarShowChatMessage = register_cvar("OR_ShowChatMessage" , "1")
CvarSendReliableMessages = register_cvar("OR_SendReliableMessages", "1")

gmsgBombPickup = get_user_msgid("BombPickup")
gmsgShowTimer = get_user_msgid("ShowTimer")
gmsgRoundTime = get_user_msgid("RoundTime")
gmsgScoreAttrib = get_user_msgid("ScoreAttrib")
gmsgBarTime = get_user_msgid("BarTime")

/**
* Send when an objective was resetted
*
* @param Objective The objective to restart.
* @return Forward does not care about the return value
*/

HandleCForwards[ObjectiveResetted] = CreateMultiForward("OnObjectiveReset" , ET_IGNORE, FP_CELL)

/**
* Send when time is changed.
*
* @param TimeType 1 if in freezetime, 0 otherwise
* @param OldRoundTime The round time before change occured.
* @param NewRoundTime The round time after change occured.
* @param RemainedTime The remained time from the round.
* @return Forward does not care about the return value
*/

HandleCForwards[RoundTimeChanged ] = CreateMultiForward("OnRoundTimeChanged", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL)

if(HandleCForwards[ObjectiveResetted] < 0)
{
log_error(AMX_ERR_NATIVE, "Reset objective forward failed to create")
}

if(HandleCForwards[RoundTimeChanged] < 0)
{
log_error(AMX_ERR_NATIVE, "Round time changed forward failed to create")
}

MaxPlayers = get_maxplayers()

/*
* RePosition
| Called from CHalfLifeMultiplay::RestartRound for resetting hostages to their old position.
| This handle all cases in which a hostage is not at his spawn place:
→ Rescued
→ Killed
→ Moved by a CT somewhere in the map
| Hostages are not respawned every round, they are resetted to their old positions.

* PickNextVip
| Called from CHalfLifeMultiplay::RestartRound for removing the old vip and choosing a new one, if needed.
| This functions free vip queue and check if the current vip was vip for more than two times in a row.
| If above is true, it calls ResetCurrentVIP and MakeVip to reset and make a new vip.
| If not, it checks if in the server is a valid vip(with m_pVIP offset). If no, one is choosed.

* GiveC4
| Called from CHalfLifeMultiplay::RestartRound and CBasePlayer::JoiningThink.
| If a bomber is not found, this function give C4 to a random player.

* CheckWinConditions
| Called from several places, this function decide which team will win.
| It decides based on the objective(fullfiled or no) or team extermination.
| This function does not deal with round time, this is done inside CHalfLifeMultiplay::Think

* ResetMaxSpeed
| When you stop defusing, this function is called in order to reset your speed to default one.
| It is called from more places, but here is the case in which we are interested.

*/

HandleHooks[RePosition] = OrpheuGetFunction("RePosition" , "CHostage" )
HandleHooks[PickNextVip] = OrpheuGetFunction("PickNextVip" , "CHalfLifeMultiplay")
HandleHooks[GiveC4] = OrpheuGetFunctionFromObject(g_pGameRules, "GiveC4" , "CGameRules" )
HandleHooks[CheckWinConditions] = OrpheuGetFunctionFromObject(g_pGameRules, "CheckWinConditions", "CGameRules" )
HandleHooks[ResetMaxSpeed] = OrpheuGetFunctionFromClass("player" , "ResetMaxSpeed" , "CBasePlayer" )
}

public plugin_cfg()
{
//Default cfg files should be loaded now and any change will be taken into account. Cache right now, this is not something which should be changed too often
SendHookableCalls = !!clamp(get_pcvar_num(CvarSendHookableCalls) , 0, 1)
SendReliableMessages = !!clamp(get_pcvar_num(CvarSendReliableMessages), 0, 1)
}

public plugin_end()
{
/*
| AMXX should free all handles by default.
| But, doing it manually is good practice and also avoid memory leacks
*/

new Size = sizeof HandleCForwards
for(new i; i < Size; i++)
{
if(HandleCForwards[CustomForwards:i] > 0)
{
DestroyForward(HandleCForwards[CustomForwards:i])
}
}
}

public plugin_natives()
{
register_library("objective_reset")
register_native("ResetObjective", "OnObjectiveReset_Native", false)
register_native("SetRoundTime" , "OnSetRoundTime_Native" , false)
register_native("GetRoundTime" , "OnGetRoundTime_Native" , false)
}

/**
* Reset the current objective.
*
* @param Objective The objective to restart.
* @return 1 if operation was succesfull, 0 otherwise
*/
public OnObjectiveReset_Native(const PluginIndex, const PluginParams)
{
if(PluginParams != 1)
{
log_error(AMX_ERR_NATIVE, "Invalid param count. Expected 1, got: %i", PluginParams)
return PLUGIN_CONTINUE
}

new ObjectiveToReset = get_param(1)

if(Obj_ResetTimer <= ObjectiveToReset <= Obj_DetectObjective)
{
ResetCurrentObjective(0, ObjectiveToReset)
return PLUGIN_HANDLED
}
else
{
log_error(AMX_ERR_NATIVE, "Native called with unknown objective %i. See the enum from include file for valid ones", ObjectiveToReset)
return PLUGIN_CONTINUE
}

return PLUGIN_CONTINUE
}

/**
* Alter the round time value.
*
* @param Time The time that will be used.
* @param Add If 1 the time will be added to current time, 0 means set.
* @return 1 if operation was succesfull, 0 otherwise
*/
public OnSetRoundTime_Native(const PluginIndex, const PluginParams)
{
if(PluginParams != 2)
{
log_error(AMX_ERR_NATIVE, "Invalid param count. Expected 2, got: %i", PluginParams)
return PLUGIN_CONTINUE
}

enum
{
Param_Id,
Param_Time,
Param_Add
}

SetNewRoundTime(Param_Id, get_param(Param_Time), clamp(get_param(Param_Add), 0, 1))
return PLUGIN_HANDLED
}

/**
* Return the value of round time/freeze time in seconds
*
* @param No params
* @return Round time in seconds or -1 on failure
*/
public OnGetRoundTime_Native(const PluginIndex, const PluginParams)
{
if(PluginParams)
{
log_error(AMX_ERR_NATIVE, "Invalid param count. Expected 0, got: %i", PluginParams)
return -1
}

new Float:RoundStartTime = Float:get_gamerules_data("m_fRoundCount")
return floatround(get_gamerules_data("m_iRoundTimeSecs") - get_gametime() + RoundStartTime)
}

public ClientCommand_SetRoundTime(id, level, cid)
{
if(!cmd_access(id, level, cid, 3))
{
return PLUGIN_HANDLED
}

enum CommandData {Time, Type}

new CommandArguments[CommandData][10]
read_argv(1, CommandArguments[Time], charsmax(CommandArguments[]))
read_argv(2, CommandArguments[Type], charsmax(CommandArguments[]))

SetNewRoundTime(id, str_to_num(CommandArguments[Time]), clamp(str_to_num(CommandArguments[Type]), 0, 1))

return PLUGIN_HANDLED
}

SetNewRoundTime(id, NewTime, Add)
{
new Float:RoundStartTime = Float:get_gamerules_data("m_fRoundCount")
new Float:CurrentGameTime = get_gametime()
new RoundTime = get_gamerules_data("m_iRoundTimeSecs"), RemainedTime

if(NewTime > 546 * 60)
{
if(id)
{
//This message should be send only if a player altered the round time
console_print(id, "You set a value bigger than 546 minutes, the timer will display 00:00")
}
}

/*
| Time is calculated by CHalfLifeMultiplay::Think with the fallowing formula:
| m_iRoundTimeSecs - gpGlobals->time + m_fRoundCount
| m_iRoundTimeSecs holds the total seconds in a round ; gpGlobals->time retrieve the time in seconds since map start; m_fRoundCount is the time when the round begun
| To vizualize better, it can be rewritten to: m_iRoundTimeSecs -(gpGlobals->time - m_fRoundCount)
| So, from the total ammount of seconds it substracts the played ones.

*/

if(Add)
{
//Time should be added, to increase it is enough to modify m_iRoundTimeSecs offset
new FullTime = RoundTime + NewTime
set_gamerules_data("m_iRoundTimeSecs", FullTime)

RemainedTime = floatround(FullTime - CurrentGameTime + RoundStartTime)
console_print(id, "You have %s %i seconds to %s", NewTime >= 0 ? "added" : "substracted", NewTime, InFreezeTime ? "freeze time" : "round time")
}
else
{
/*
| When setting, only positive time is allowed. Also, the timer doesn't like when you directly pass 0, so we force it to 1.
| I guess this is because it thinks that the new round already started, but didn't check in deep.
| We need to know what is the theoretical value of m_iRoundTimeSecs for which the round time is equal to the wanted time.
| m_iRoundTimeSecs - gpGlobals->time + m_fRoundCount = NewTime => m_iRoundTimeSecs = NewTime - m_fRoundCount + gpGlobals->time
*/

if(NewTime <= 0)
{
NewTime = 1
}
set_gamerules_data("m_iRoundTimeSecs", floatround(NewTime + CurrentGameTime - RoundStartTime))

RemainedTime = NewTime
console_print(id, "You have set %s to %i seconds", InFreezeTime ? "freeze time" : "round time", NewTime)
}

SendRoundTimeMessage .Time = RemainedTime, .Reliable = SendReliableMessages

if(HandleCForwards[RoundTimeChanged] > 0)
{
new ReturnType
ExecuteForward(HandleCForwards[RoundTimeChanged], ReturnType, InFreezeTime, RoundTime, get_gamerules_data("m_iRoundTimeSecs"), RemainedTime)
}
}

public ClientCommand_GetRoundTime(id, level, cid)
{
if(!cmd_access(id, level, cid, 1))
{
return PLUGIN_HANDLED
}

new Float:RoundStartTime = Float:get_gamerules_data("m_fRoundCount")
console_print(id, "Remained time(in seconds): %i from %s", floatround(get_gamerules_data("m_iRoundTimeSecs") - get_gametime() + RoundStartTime), InFreezeTime ? "freeze time" : "round time")

return PLUGIN_HANDLED
}

public ClientCommand_ResetObjective(id, level, cid)
{
if(!cmd_access(id, level, cid, 2))
{
return PLUGIN_HANDLED
}

new ObjectiveToReset[10], ResetType
read_argv(1, ObjectiveToReset, charsmax(ObjectiveToReset))

switch(ObjectiveToReset[0])
{
case 't', 'T', '1' : ResetType = Obj_ResetTimer
case 'b', 'B', '2' : ResetType = Obj_ResetBomb
case 'v', 'V', '3' : ResetType = Obj_ResetVip
case 'h', 'H', '4' : ResetType = Obj_ResetHostages
case 'e', 'E', '5' : ResetType = Obj_ResetEscape
case 'd', 'D', '6' : ResetType = Obj_DetectObjective
default : ResetType = Obj_InvalidObjective
}

if(ResetType != Obj_InvalidObjective)
{
ResetCurrentObjective(id, ResetType)
}
else
{
console_print(id, "Invalid objective specified^nValid types are:")
console_print(id, "^t[timer/Timer/1]^n^t[bomb/Bomb/2]^n^t[vip/Vip/3]^n^t[hostages/Hostages/4]^n^t[escape/Escape/5]^n^t[detect/Detect/6]")
}
return PLUGIN_HANDLED
}

ResetCurrentObjective(id, ResetType)
{
new bool:SuccesfullReset

switch(ResetType)
{
case Obj_ResetTimer:
{
/*
| This also work with freezetime, we just need to know if players are in freezetime or not
| Setting m_fRoundCount to current time will result in round being resetted
| m_iRoundTimeSecs - get_gametime + get_gametime = m_iRoundTimeSecs
| m_iRoundTimeSecs is set to default round time.
*/

new RoundTime
if(InFreezeTime)
{
RoundTime = get_pcvar_num(CvarMpFreezeTime)
console_print(id, "You have just reset freeze time to %i seconds", RoundTime)
}
else
{
RoundTime = get_pcvar_num(CvarMpRoundTime) * 60
console_print(id, "You have just reset round time to %i seconds", RoundTime)
}

set_gamerules_data("m_fRoundCount", get_gametime())
set_gamerules_data("m_iRoundTimeSecs", RoundTime)

SendRoundTimeMessage .Time = RoundTime, .Reliable = true

SuccesfullReset = true
}
case Obj_ResetBomb:
{
new GrenadeEntity = FM_NULLENT

while((GrenadeEntity = engfunc(EngFunc_FindEntityByString, GrenadeEntity, ClassName, GrenadeClassName)))
{
if(pev_valid(GrenadeEntity) && get_pdata_bool(GrenadeEntity, m_bIsC4))
{
if(!get_pdata_bool(GrenadeEntity, m_bJustBlew))
{
new DefuserIndex
if(1 <= (DefuserIndex = get_pdata_ent(GrenadeEntity, m_pBombDefuser)) <= MaxPlayers)
{
SendHookableCalls ?
OrpheuCallSuper(HandleHooks[ResetMaxSpeed], DefuserIndex) :
OrpheuCall(HandleHooks[ResetMaxSpeed], DefuserIndex)

set_pdata_bool(DefuserIndex, m_bIsDefusing, false)
set_pdata_bool(DefuserIndex, m_bStartDefuse, false)
set_pdata_float(GrenadeEntity, m_flDefuseCountDown, 0.0)

message_begin(SendReliableMessages ? MSG_ONE : MSG_ONE_UNRELIABLE, gmsgBarTime, _, DefuserIndex)
{
write_short(0)
message_end()
}
}

engfunc(EngFunc_RemoveEntity, GrenadeEntity)

SendHookableCalls ?
OrpheuCallSuper(HandleHooks[GiveC4], g_pGameRules) :
OrpheuCall(HandleHooks[GiveC4], g_pGameRules)

message_begin(SendReliableMessages ? MSG_ALL : MSG_BROADCAST, gmsgBombPickup)
{
message_end()
}

message_begin(SendReliableMessages ? MSG_ALL : MSG_BROADCAST, gmsgShowTimer)
{
message_end()
}

SuccesfullReset = true
}
break
}
}
}
case Obj_ResetHostages:
{
new HostageEnt = FM_NULLENT

while((HostageEnt = engfunc(EngFunc_FindEntityByString, HostageEnt, ClassName, HostageClassName)))
{
if(pev_valid(HostageEnt))
{
if(!SuccesfullReset)
{
SuccesfullReset = true
}

SendHookableCalls ?
OrpheuCallSuper(HandleHooks[RePosition], HostageEnt) :
OrpheuCall(HandleHooks[RePosition], HostageEnt)
}
}

if(SuccesfullReset)
{
set_gamerules_data("m_iHostagesRescued", 0)
set_gamerules_data("m_iHostagesTouched", 0)
}
}
case Obj_ResetVip:
{
new Players[32], Num
get_players(Players, Num, "ae", "CT")

if(Num > 1)
{
new OldVip = get_gamerules_data("m_pVIP")

if(is_user_alive(OldVip) && !get_pdata_bool(OldVip, m_bEscaped))
{
//RemoveCurrentVIP does not fix the score attrib and armor
message_begin(SendReliableMessages ? MSG_ALL : MSG_BROADCAST, gmsgScoreAttrib)
{
write_byte(OldVip)
write_byte(0)
message_end()
}

cs_set_user_armor(OldVip, 100, CS_ARMOR_KEVLAR)
cs_set_user_bpammo(OldVip, CSW_USP, 24)
cs_set_weapon_ammo(find_ent_by_owner(-1, "weapon_usp", OldVip), 12)

/*
| The function will choose the next vip and reset the current one if this offset is above 2.
| We force that by altering the offset.
| I don't like much that, but there is no other way. Also, I believe it won't fuck up something
| The offset is immediately resetted to 0 and increased. This is default game behaviour.
*/

set_gamerules_data("m_iConsecutiveVip", 3)

SendHookableCalls ?
OrpheuCallSuper(HandleHooks[PickNextVip], g_pGameRules) :
OrpheuCall(HandleHooks[PickNextVip], g_pGameRules)

set_gamerules_data("m_iConsecutiveVip", get_gamerules_data("m_iConsecutiveVip") + 1)

new NewVip = get_gamerules_data("m_pVIP")

if(1 <= NewVip <= MaxPlayers)
{
SendHookableCalls ?
ExecuteHamB(Ham_CS_RoundRespawn, NewVip) :
ExecuteHam(Ham_CS_RoundRespawn, NewVip)

SuccesfullReset = true
}
}
}
}
case Obj_ResetEscape:
{
new Escapers = get_gamerules_data("m_iHaveEscaped")

if(Escapers > 0)
{
new Float:RequieredEscapeRation = Float:get_gamerules_data("m_flRequiredEscapeRatio")

if(Escapers / float(get_gamerules_data("m_iNumEscapers")) < RequieredEscapeRation)
{
new Players[32], Num, index
get_players(Players, Num, "ae", "TERRORIST")

for(new i; i < Num; i++)
{
index = Players[i]
if(get_pdata_bool(index, m_bEscaped))
{
set_pdata_bool(index, m_bEscaped, false)

SendHookableCalls ?
ExecuteHamB(Ham_CS_RoundRespawn, index) :
ExecuteHam(Ham_CS_RoundRespawn, index)
}
}

set_gamerules_data("m_iHaveEscaped", 0)
SuccesfullReset = true
}
}
}
case Obj_DetectObjective:
{
static Objective
static bool:AlreadyDetected

if(!AlreadyDetected)
{
//The first found objective will be returned, for map with more objectives write manually the identifier
if(get_gamerules_data("m_bMapHasBombTarget"))
{
Objective = Obj_ResetBomb
}
else if(get_gamerules_data("m_bMapHasRescueZone"))
{
Objective = Obj_ResetHostages
}
else if(get_gamerules_data("m_iMapHasVIPSafetyZone") == 1) //Game sets this offset to 1 if safety zone is found and to 2 if not
{
Objective = Obj_ResetVip
}
else if(get_gamerules_data("m_bMapHasEscapeZone"))
{
Objective = Obj_ResetEscape
}
else
{
Objective = Obj_ResetTimer
}

AlreadyDetected = true
console_print(id, "Objective %s was auto-detected.", ObjectiveNames[Objective])
}

ResetCurrentObjective(id, Objective)
}
}

if(SuccesfullReset)
{
if(ResetType != Obj_ResetTimer)
{
console_print(id, "You have just reset the %s objective", ObjectiveNames[ResetType])
}
if(get_pcvar_num(CvarShowChatMessage))
{
client_print(0, print_chat, "Objective %s was resetted.", ObjectiveNames[ResetType])
}

if(HandleCForwards[ObjectiveResetted] > 0)
{
new ReturnType
ExecuteForward(HandleCForwards[ObjectiveResetted], ReturnType, ResetType)
}

//Recheck everything or bugs could appear
SendHookableCalls ?
OrpheuCallSuper(HandleHooks[CheckWinConditions], g_pGameRules) :
OrpheuCall(HandleHooks[CheckWinConditions], g_pGameRules)

}
}

public OnNewRound_Event()
{
InFreezeTime = true
}

public OnRoundStart_Event()
{
InFreezeTime = false
}

SendRoundTimeMessage(Time, bool:Reliable)
{
message_begin(Reliable ? MSG_ALL : MSG_BROADCAST, gmsgRoundTime)
{
write_short(Time)
message_end()
}
}
Hi. I put this module ( orpheus ) on the server, it works, but when I want to use this plugin I get these errors. ( Helping for a pause plugin )

The archive is taken directly from the forum. I have copied everything in the archive as required. Here is the InstallGameRules file
Код:
\cstrike\addons\amxmodx\configs\orpheu\functions
Here's the signature
Код:
{
    "name" : "InstallGameRules",
    "library" : "mod",
    "return" :
    {
        "type" : "CGameRules *"
    },
    "identifiers":
    [
        {
            "os" : "windows",
            "mod" : "cstrike",
            "value" : [0x68,"*","*","*","*",0xFF,"*","*","*","*","*",0x83,"*","*",0xFF,"*","*","*","*","*",0xA1,"*","*","*","*",0xD9,"*","*",0xD8,"*","*","*","*","*",0xDF]
        },
        {
            "os" : "linux",
            "mod" : "cstrike",
            "value" : "_Z16InstallGameRulesv"
        }
    ]
}
 

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу