Implemented delayed infection mode. Fixed immunity_cooldown attribute not loaded properly.
This commit is contained in:
parent
e31d867c57
commit
666ac57836
@ -37,13 +37,15 @@
|
||||
// (Not implemented) "full" - Completely immune. Humans can't be infected, zombies don't receive damage or knock back. Careful with this, it might not be that fun.
|
||||
// "infect" - Humans are immune to infections until HP go below a threshold. Threshold at zero enable stabbing to death.
|
||||
// (Not implemented) "damage" - Zombies are immune to damage from humans/grenades, but still vulnerable to knock back.
|
||||
// (Not implemented) "delay" - Delay infection for a certain number of seconds.
|
||||
// "delay" - Delay infection for a certain number of seconds.
|
||||
// (Not implemented) "shield" - Shield against infections (humans) or knock back (zombies) for a certain amount of seconds (similar to TF2's übercharge).
|
||||
// immunity_amount number Immunity data value (humans only). Depends on the immunity mode above:
|
||||
// "infect" - HP threshold. Infection will be allowed when HP go below this value. Zero will enable stabbing to death.
|
||||
// (Not implemented) "delay" - Number of seconds the infection is delayed since first hit by a zombie.
|
||||
// (Not implemented) "shield" - Number of seconds the shield is active.
|
||||
// immunity_cooldown number (Not implemented) Number of seconds of cooldown for temporary immunity effects (currently just shield mode).
|
||||
// immunity_cooldown number Number of seconds of cooldown for temporary immunity effects, depending on mode.
|
||||
// "shield" - Number of seconds the player has to wait before the shield can be used again.
|
||||
// "delay" - Number of seconds the delay is reduced every time a zombie attack, while a delayed infection is in progress.
|
||||
// no_fall_damage on/off Disables fall damage.
|
||||
// health number How many health points to give.
|
||||
// health_regen_interval decimal Sets the regeneration interval. 0 to disable.
|
||||
@ -501,9 +503,9 @@
|
||||
"napalm_time" "0.0"
|
||||
|
||||
// Player behavior
|
||||
"immunity_mode" "none"
|
||||
"immunity_amount" "1"
|
||||
"immunity_cooldown" "60"
|
||||
"immunity_mode" "delay" // Delay infection
|
||||
"immunity_amount" "10" // 10 seconds.
|
||||
"immunity_cooldown" "2" // Reduce delay 2 seconds every subsequent attack (infect faster).
|
||||
"no_fall_damage" "0"
|
||||
|
||||
"health" "100"
|
||||
|
@ -55,6 +55,8 @@ new PlayerImmunityLastUse[MAXPLAYERS + 1] = {0, ...};
|
||||
*/
|
||||
new bool:PlayerImmunityThresholdPassed[MAXPLAYERS + 1] = {false, ...};
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Handles immunity when a client is about to be infected. This function may
|
||||
* delay or block infection according to the immunity mode class settings.
|
||||
@ -103,6 +105,8 @@ bool:ImmunityOnClientInfect(client, attacker)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* TraceAttack hook.
|
||||
*
|
||||
@ -150,35 +154,12 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag
|
||||
// Check if damage give HP below the infection threshold.
|
||||
if (ImmunityBelowInfectThreshold(client, damage))
|
||||
{
|
||||
//PrintToChatAll("ImmunityOnClientTraceAttack - Threshold passed");
|
||||
PlayerImmunityThresholdPassed[client] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayerImmunityThresholdPassed[client] = false;
|
||||
}
|
||||
|
||||
/*new threshold = ClassGetImmunityAmount(client);
|
||||
new clientHP = GetClientHealth(client);
|
||||
new dmg = RoundToNearest(damage);
|
||||
PrintToChatAll("threshold=%d, clientHp=%d", threshold, clientHP);
|
||||
|
||||
// Prevent humans with low HP from dying when a zombie is
|
||||
// attacking, and stab to death is disabled (threshold above zero).
|
||||
if (clientHP - dmg <= 0.0 && threshold > 0)
|
||||
{
|
||||
// Client is about to be infected. Remove damage, but don't
|
||||
// block the damage event. The infect module need it to detect
|
||||
// zombie attack.
|
||||
damage = 0.0;
|
||||
|
||||
// Client is about to be infected, re-add HP so they aren't
|
||||
// killed by knife. Don't block the damage, the infect
|
||||
// module need the damage event.
|
||||
//PrintToChatAll("Re-add HP.");
|
||||
//SetEntityHealth(client, clientHP + dmg);
|
||||
return false;
|
||||
}*/
|
||||
}
|
||||
case Immunity_Damage:
|
||||
{
|
||||
@ -209,22 +190,12 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag
|
||||
// Block damage from attacker.
|
||||
return true;
|
||||
}
|
||||
case Immunity_Delay:
|
||||
{
|
||||
// Client must be human.
|
||||
if (InfectIsClientInfected(client))
|
||||
{
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Block damage if there's an infection in progress.
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//PrintToChatAll("Allow damage.");
|
||||
return false;
|
||||
}
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* TakeDamage hook.
|
||||
@ -239,8 +210,6 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag
|
||||
*/
|
||||
bool:ImmunityOnClientDamage(client, attacker, &Float:damage)
|
||||
{
|
||||
//PrintToChatAll("ImmunityOnClientDamage(client=%d, attacker=%d, damage=%f)", client, attacker, damage);
|
||||
|
||||
// Check if there is no attacker (world damage).
|
||||
if (!ZRIsClientValid(attacker))
|
||||
{
|
||||
@ -259,11 +228,6 @@ bool:ImmunityOnClientDamage(client, attacker, &Float:damage)
|
||||
// attacking, and stab to death is disabled (threshold above zero).
|
||||
if (ImmunityBelowInfectThreshold(client, damage))
|
||||
{
|
||||
//PrintToChatAll("ImmunityOnClientDamage - Below threshold, removing damage.");
|
||||
// Client is about to be infected. Remove damage so the client
|
||||
// won't die.
|
||||
//damage = 0.0;
|
||||
|
||||
// Fake hurt event because it's not triggered when the damage
|
||||
// was removed (because no one is actually hurt).
|
||||
InfectOnClientHurt(client, attacker, "knife");
|
||||
@ -272,12 +236,25 @@ bool:ImmunityOnClientDamage(client, attacker, &Float:damage)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
case Immunity_Delay:
|
||||
{
|
||||
// Fake hurt event because it's not triggered when the damage
|
||||
// was removed (because no one is actually hurt). This event must
|
||||
// still be triggered so that subsequent attacks are registered,
|
||||
// without dealing any damage.
|
||||
InfectOnClientHurt(client, attacker, "knife");
|
||||
|
||||
// Block damage to prevent player from dying.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow damage.
|
||||
return false;
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Client is about to receive knock back (zombie).
|
||||
*
|
||||
@ -289,6 +266,8 @@ bool:ImmunityOnClientDamage(client, attacker, &Float:damage)
|
||||
{
|
||||
}*/
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Handles infect mode immunity.
|
||||
*
|
||||
@ -303,20 +282,15 @@ bool:ImmunityOnClientDamage(client, attacker, &Float:damage)
|
||||
*/
|
||||
bool:ImmunityInfectModeHandler(client)
|
||||
{
|
||||
//PrintToChatAll("ImmunityInfectModeHandler(client=%d, attacker=%d)", client, attacker);
|
||||
|
||||
// Note: ImmunityOnClientDamage and ImmunityOnClientTraceAttack hook into
|
||||
// the damage module to prevent humans with low HP from dying when
|
||||
// they're not supposed to.
|
||||
|
||||
new threshold = ClassGetImmunityAmount(client);
|
||||
//PrintToChatAll("threshold=%d", threshold);
|
||||
|
||||
// Check if infection is disabled.
|
||||
if (threshold == 0)
|
||||
{
|
||||
// Infection is handled here: blocked.
|
||||
//PrintToChatAll("Infection disabled, block infection.");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -326,10 +300,11 @@ bool:ImmunityInfectModeHandler(client)
|
||||
return false;
|
||||
}
|
||||
|
||||
//PrintToChatAll("Above threshold, block infection.");
|
||||
return true;
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Handles delayed infections.
|
||||
*
|
||||
@ -346,27 +321,46 @@ bool:ImmunityDelayModeHandler(client, attacker)
|
||||
// Additional attacks while a delayed infection is in progress will
|
||||
// speedup the infection.
|
||||
|
||||
// Trigger timer event to reduce duration.
|
||||
// Get reduction amount for subsequent zombie attack.
|
||||
new reduction = ClassGetImmunityCooldown(client);
|
||||
if (reduction > 0)
|
||||
{
|
||||
// Reduce duration. Add one because the timer handler itself reduce
|
||||
// duration by one.
|
||||
PlayerImmunityDuration[client] -= reduction + 1;
|
||||
|
||||
// Note: This feature can be used to trigger an instant infection
|
||||
// when a human receive a second attack, by setting the
|
||||
// reduction value high enough.
|
||||
|
||||
// Trigger timer event to reduce delay and infect faster.
|
||||
ImmunityDelayTimerHandler(PlayerImmunityTimer[client], client);
|
||||
}
|
||||
|
||||
// Block infection.
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Start a delayed infection. Initialize duration and attacker.
|
||||
PlayerImmunityDuration[client] = ClassGetImmunityAmount(client);
|
||||
PlayerImmunityAttacker[client] = attacker;
|
||||
|
||||
// Create repated 1-second timer.
|
||||
// Create repated 1-second timer for handling the countdown.
|
||||
PlayerImmunityTimer[client] = CreateTimer(1.0, ImmunityDelayTimerHandler, client, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT);
|
||||
|
||||
// Block infection.
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Delayed infection timer handler. Handles countdown and infection when time
|
||||
* is up.
|
||||
*/
|
||||
public Action:ImmunityDelayTimerHandler(Handle:timer, any:client)
|
||||
{
|
||||
// Verify that client is connected and alive.
|
||||
// Verify that client is still connected and alive.
|
||||
if (!IsClientInGame(client) || !IsPlayerAlive(client))
|
||||
{
|
||||
// Client disconnected or died. Abort immunity action.
|
||||
@ -375,19 +369,16 @@ public Action:ImmunityDelayTimerHandler(Handle:timer, any:client)
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
// TODO: Read cvar for reduction amount.
|
||||
new reduction = 2;
|
||||
|
||||
// Reduce duration.
|
||||
PlayerImmunityDuration[client] -= reduction;
|
||||
PlayerImmunityDuration[client] -= 1;
|
||||
|
||||
// Check if time is up.
|
||||
if (PlayerImmunityDuration[client] <= 0)
|
||||
{
|
||||
// Time is up. Reset data.
|
||||
PlayerImmunityDuration[client] = 0;
|
||||
PlayerImmunityTimer[client] = INVALID_HANDLE;
|
||||
ZREndTimer(PlayerImmunityTimer[client]);
|
||||
//PlayerImmunityTimer[client] = INVALID_HANDLE;
|
||||
ImmunityAbortHandler(client);
|
||||
|
||||
// Infect client.
|
||||
InfectHumanToZombie(client, PlayerImmunityAttacker[client]);
|
||||
@ -398,6 +389,8 @@ public Action:ImmunityDelayTimerHandler(Handle:timer, any:client)
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Handles shield mode immunity.
|
||||
*
|
||||
@ -427,6 +420,8 @@ bool:ImmunityShieldModeHandler(client, bool:asZombie = true)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Aborts any immunity mode in action (shields, delays, etc.). Resets values.
|
||||
*
|
||||
@ -449,6 +444,8 @@ ImmunityAbortHandler(client, bool:resetLastUse = true)
|
||||
}
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Aborts all immunity modes in action.
|
||||
*
|
||||
@ -462,26 +459,63 @@ ImmunityAbortAll(bool:resetLastUse = true)
|
||||
}
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Client was infected.
|
||||
*/
|
||||
ImmunityOnClientInfected(client)
|
||||
{
|
||||
// In case client was infected through an admin command or mother zombie
|
||||
// selection, abort other actions in progress.
|
||||
ImmunityAbortHandler(client);
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Client was turned back into a human.
|
||||
*/
|
||||
ImmunityOnClientHuman(client)
|
||||
{
|
||||
ImmunityAbortHandler(client);
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Client died.
|
||||
*/
|
||||
ImmunityOnClientDeath(client)
|
||||
{
|
||||
ImmunityAbortHandler(client, false);
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Client connected to the server.
|
||||
*/
|
||||
ImmunityClientInit(client)
|
||||
{
|
||||
ImmunityAbortHandler(client);
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Client spawned.
|
||||
*/
|
||||
ImmunityClientSpawn(client)
|
||||
{
|
||||
ImmunityAbortHandler(client, false);
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Client disconnected.
|
||||
*/
|
||||
ImmunityOnClientDisconnect(client)
|
||||
{
|
||||
ImmunityAbortHandler(client);
|
||||
@ -498,29 +532,54 @@ ImmunityOnClientDisconnect(client)
|
||||
}
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Client changed team.
|
||||
*/
|
||||
ImmunityOnClientTeam(client)
|
||||
{
|
||||
ImmunityAbortHandler(client);
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Round ended.
|
||||
*/
|
||||
ImmunityOnRoundEnd()
|
||||
{
|
||||
ImmunityAbortAll();
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Map ended.
|
||||
*/
|
||||
ImmunityOnMapEnd()
|
||||
{
|
||||
ImmunityAbortAll();
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Returns whether the specified damage will take a client's HP below the
|
||||
* infection threshold. Only used by "infect" immunity mode.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param damage Damage applied to client.
|
||||
*
|
||||
* @return True if client HP go below threshold (immunity_amount) when
|
||||
* applying damage, false otherwise.
|
||||
*/
|
||||
bool:ImmunityBelowInfectThreshold(client, Float:damage)
|
||||
{
|
||||
new threshold = ClassGetImmunityAmount(client);
|
||||
new clientHP = GetClientHealth(client);
|
||||
new dmg = RoundToNearest(damage);
|
||||
|
||||
//PrintToChatAll("threshold=%d, clientHp=%d", threshold, clientHP);
|
||||
|
||||
// Check if the damage go below the HP threshold.
|
||||
if (clientHP - dmg <= 0.0 && threshold > 0)
|
||||
{
|
||||
@ -530,6 +589,8 @@ bool:ImmunityBelowInfectThreshold(client, Float:damage)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Converts a string to an immunity mode.
|
||||
*
|
||||
@ -572,6 +633,8 @@ ImmunityMode:ImmunityStringToMode(const String:mode[])
|
||||
return Immunity_Invalid;
|
||||
}
|
||||
|
||||
/*____________________________________________________________________________*/
|
||||
|
||||
/**
|
||||
* Converts an immunity mode to a string.
|
||||
*
|
||||
|
@ -751,6 +751,7 @@ InfectHumanToZombie(client, attacker = -1, bool:motherinfect = false, bool:respa
|
||||
ZTeleOnClientInfected(client);
|
||||
ZHPOnClientInfected(client);
|
||||
APIOnClientInfected(client, attacker, motherinfect, respawnoverride, respawn);
|
||||
ImmunityOnClientInfected(client);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -615,6 +615,7 @@ ClassLoad()
|
||||
KvGetString(kvClassData, "immunity_mode", immunity_mode, sizeof(immunity_mode), ZR_CLASS_DEFAULT_IMMUNITY_MODE);
|
||||
ClassData[ClassCount][Class_ImmunityMode] = ImmunityStringToMode(immunity_mode);
|
||||
ClassData[ClassCount][Class_ImmunityAmount] = KvGetNum(kvClassData, "immunity_amount", ZR_CLASS_DEFAULT_IMMUNITY_AMOUNT);
|
||||
ClassData[ClassCount][Class_ImmunityCooldown] = KvGetNum(kvClassData, "immunity_cooldown", ZR_CLASS_DEFAULT_IMMUNITY_COOLDOWN);
|
||||
ClassData[ClassCount][Class_NoFallDamage] = ConfigKvGetStringBool(kvClassData, "no_fall_damage", ZR_CLASS_DEFAULT_NO_FALL_DAMAGE);
|
||||
|
||||
ClassData[ClassCount][Class_Health] = KvGetNum(kvClassData, "health", ZR_CLASS_DEFAULT_HEALTH);
|
||||
@ -756,9 +757,10 @@ bool:ClassReloadDataCache()
|
||||
ClassDataCache[classindex][Class_HasNapalm] = ClassData[classindex][Class_HasNapalm];
|
||||
ClassDataCache[classindex][Class_NapalmTime] = ClassData[classindex][Class_NapalmTime];
|
||||
|
||||
/* Player behaviour */
|
||||
/* Player behavior */
|
||||
ClassDataCache[classindex][Class_ImmunityMode] = ClassData[classindex][Class_ImmunityMode];
|
||||
ClassDataCache[classindex][Class_ImmunityAmount] = ClassData[classindex][Class_ImmunityAmount];
|
||||
ClassDataCache[classindex][Class_ImmunityCooldown] = ClassData[classindex][Class_ImmunityCooldown];
|
||||
ClassDataCache[classindex][Class_NoFallDamage] = ClassData[classindex][Class_NoFallDamage];
|
||||
ClassDataCache[classindex][Class_Health] = ClassData[classindex][Class_Health];
|
||||
ClassDataCache[classindex][Class_HealthRegenInterval] = ClassData[classindex][Class_HealthRegenInterval];
|
||||
@ -821,9 +823,10 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF
|
||||
ClassPlayerCache[client][Class_HasNapalm] = ClassData[classindex][Class_HasNapalm];
|
||||
ClassPlayerCache[client][Class_NapalmTime] = ClassData[classindex][Class_NapalmTime];
|
||||
|
||||
/* Player behaviour */
|
||||
/* Player behavior */
|
||||
ClassPlayerCache[client][Class_ImmunityMode] = ClassData[classindex][Class_ImmunityMode];
|
||||
ClassPlayerCache[client][Class_ImmunityAmount] = ClassData[classindex][Class_ImmunityAmount];
|
||||
ClassPlayerCache[client][Class_ImmunityCooldown] = ClassData[classindex][Class_ImmunityCooldown];
|
||||
ClassPlayerCache[client][Class_NoFallDamage] = ClassData[classindex][Class_NoFallDamage];
|
||||
ClassPlayerCache[client][Class_Health] = ClassData[classindex][Class_Health];
|
||||
ClassPlayerCache[client][Class_HealthRegenInterval] = ClassData[classindex][Class_HealthRegenInterval];
|
||||
@ -861,9 +864,10 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF
|
||||
ClassPlayerCache[client][Class_HasNapalm] = ClassDataCache[classindex][Class_HasNapalm];
|
||||
ClassPlayerCache[client][Class_NapalmTime] = ClassDataCache[classindex][Class_NapalmTime];
|
||||
|
||||
/* Player behaviour */
|
||||
/* Player behavior */
|
||||
ClassPlayerCache[client][Class_ImmunityMode] = ClassDataCache[classindex][Class_ImmunityMode];
|
||||
ClassPlayerCache[client][Class_ImmunityAmount] = ClassDataCache[classindex][Class_ImmunityAmount];
|
||||
ClassPlayerCache[client][Class_ImmunityCooldown] = ClassDataCache[classindex][Class_ImmunityCooldown];
|
||||
ClassPlayerCache[client][Class_NoFallDamage] = ClassDataCache[classindex][Class_NoFallDamage];
|
||||
ClassPlayerCache[client][Class_Health] = ClassDataCache[classindex][Class_Health];
|
||||
ClassPlayerCache[client][Class_HealthRegenInterval] = ClassDataCache[classindex][Class_HealthRegenInterval];
|
||||
@ -1376,10 +1380,14 @@ ClassDumpData(index, cachetype, String:buffer[], maxlen)
|
||||
Format(attribute, sizeof(attribute), "napalm_time: \"%f\"\n", ClassGetNapalmTime(index, cachetype));
|
||||
cellcount += StrCat(buffer, maxlen, attribute);
|
||||
|
||||
Format(attribute, sizeof(attribute), "immunity_mode: \"%d\"\n", ClassGetImmunityMode(index, cachetype));
|
||||
ImmunityModeToString(ClassGetImmunityMode(index, cachetype), format_buffer, sizeof(format_buffer));
|
||||
Format(attribute, sizeof(attribute), "immunity_mode: \"%s\"\n", format_buffer);
|
||||
cellcount += StrCat(buffer, maxlen, attribute);
|
||||
|
||||
Format(attribute, sizeof(attribute), "immunity_amount: \"%f\"\n", ClassGetImmunityAmount(index, cachetype));
|
||||
Format(attribute, sizeof(attribute), "immunity_amount: \"%d\"\n", ClassGetImmunityAmount(index, cachetype));
|
||||
cellcount += StrCat(buffer, maxlen, attribute);
|
||||
|
||||
Format(attribute, sizeof(attribute), "immunity_cooldown: \"%d\"\n", ClassGetImmunityCooldown(index, cachetype));
|
||||
cellcount += StrCat(buffer, maxlen, attribute);
|
||||
|
||||
Format(attribute, sizeof(attribute), "no_fall_damage: \"%d\"\n", ClassGetNoFallDamage(index, cachetype));
|
||||
|
Loading…
Reference in New Issue
Block a user