Added antistick system, removed zstuck, and removed redundant check in zombie.inc
This commit is contained in:
parent
1cbce4de6d
commit
fd3739b53a
@ -27,6 +27,7 @@
|
||||
#include "zr/models"
|
||||
#include "zr/overlays"
|
||||
#include "zr/playerclasses"
|
||||
#include "zr/antistick"
|
||||
#include "zr/anticamp"
|
||||
#include "zr/teleport"
|
||||
#include "zr/zombie"
|
||||
@ -205,6 +206,7 @@ MapChangeCleanup()
|
||||
tRound = INVALID_HANDLE;
|
||||
tInfect = INVALID_HANDLE;
|
||||
AmbienceStopAll();
|
||||
AntiStickReset();
|
||||
|
||||
for (new client = 1; client <= maxclients; client++)
|
||||
{
|
||||
|
200
src/zr/antistick.inc
Normal file
200
src/zr/antistick.inc
Normal file
@ -0,0 +1,200 @@
|
||||
/**
|
||||
* ====================
|
||||
* Zombie:Reloaded
|
||||
* File: antistick.inc
|
||||
* Author: Greyscale
|
||||
* ====================
|
||||
*/
|
||||
|
||||
/**
|
||||
* @section Offsets relating to player hull dimensions.
|
||||
*/
|
||||
#define PLAYER_HULL_XY_OFFSET 32
|
||||
#define PLAYER_HULL_Z_OFFSET 12
|
||||
#define PLAYER_HULL_STACK_OFFSET 14
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handle to keep track of AntiStickTimer
|
||||
*/
|
||||
new Handle:tAntiStick = INVALID_HANDLE;
|
||||
|
||||
/**
|
||||
* Restarts the AntiStickTimer function.
|
||||
*/
|
||||
AntiStickRestart()
|
||||
{
|
||||
if (tAntiStick != INVALID_HANDLE)
|
||||
{
|
||||
KillTimer(tAntiStick);
|
||||
}
|
||||
|
||||
new bool:antistick = GetConVarBool(gCvars[CVAR_ANTISTICK]);
|
||||
if (antistick)
|
||||
{
|
||||
new Float:interval = GetConVarFloat(gCvars[CVAR_ANTISTICK_INTERVAL]);
|
||||
tAntiStick = CreateTimer(interval, AntiStickTimer, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the handle that keeps track of the AntiStickTimer function.
|
||||
*/
|
||||
AntiStickReset()
|
||||
{
|
||||
tAntiStick = INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes a player away from another to prevent sticking. (Used on infect)
|
||||
*
|
||||
* @param attacker The player to push away.
|
||||
* @param client The client to push player away from.
|
||||
*/
|
||||
AntiStick(attacker, client)
|
||||
{
|
||||
// Validate player is valid client and in-game
|
||||
if (!attacker || !IsClientInGame(attacker))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve cvar value for force of the push, if 0 is returned, stop function
|
||||
new Float:force = GetConVarFloat(gCvars[CVAR_INFECT_ANTISTICK_FORCE]);
|
||||
if (force == 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
new Float:vector[3];
|
||||
|
||||
new Float:attackerloc[3];
|
||||
new Float:clientloc[3];
|
||||
|
||||
GetClientAbsOrigin(attacker, attackerloc);
|
||||
GetClientAbsOrigin(client, clientloc);
|
||||
|
||||
MakeVectorFromPoints(attackerloc, clientloc, vector);
|
||||
|
||||
NormalizeVector(vector, vector);
|
||||
ScaleVector(vector, force);
|
||||
|
||||
// Push player
|
||||
TeleportEntity(attacker, NULL_VECTOR, NULL_VECTOR, vector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player is currently stuck within another player
|
||||
*
|
||||
* @param client The client index.
|
||||
* @return The client index of the other stuck player, -1 when
|
||||
* player is not stuck.
|
||||
*/
|
||||
AntiStickIsStuck(client)
|
||||
{
|
||||
new Float:clientloc[3];
|
||||
new Float:stuckloc[3];
|
||||
|
||||
GetClientAbsOrigin(client, clientloc);
|
||||
|
||||
// x = client index
|
||||
new maxplayers = GetMaxClients();
|
||||
for (new x = 1; x <= maxplayers; x++)
|
||||
{
|
||||
// Validate player is in-game, alive, and isn't the player being checked ('client')
|
||||
if (!IsClientInGame(x) || !IsPlayerAlive(x) || x == client)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
GetClientAbsOrigin(x, stuckloc);
|
||||
|
||||
// x-y plane distance formula: sqrt((x2-x1)^2 + (y2-y1)^2)
|
||||
new Float:xydistance = SquareRoot(Pow(stuckloc[0] - clientloc[0], 2.0) + Pow(stuckloc[1] - clientloc[1], 2.0));
|
||||
if (xydistance < PLAYER_HULL_XY_OFFSET)
|
||||
{
|
||||
if (clientloc[2] <= stuckloc[2])
|
||||
{
|
||||
new Float:eyeloc[3];
|
||||
GetPlayerEyePosition(client, eyeloc);
|
||||
|
||||
// Get the distance between the eyes and feet and subtract the stack "view crush"
|
||||
new Float:eyedistance = FloatAbs(eyeloc[2] - clientloc[2]) - PLAYER_HULL_STACK_OFFSET;
|
||||
new Float:zdistance = FloatAbs(stuckloc[2] - clientloc[2]);
|
||||
|
||||
if (zdistance <= eyedistance + PLAYER_HULL_Z_OFFSET)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeated timer function.
|
||||
* Automatically unsticks players that are stuck together.
|
||||
*/
|
||||
public Action:AntiStickTimer(Handle:timer)
|
||||
{
|
||||
// x = client index
|
||||
new maxplayers = GetMaxClients();
|
||||
for (new x = 1; x <= maxplayers; x++)
|
||||
{
|
||||
// Validate player is in-game and alive
|
||||
if (!IsClientInGame(x) || !IsPlayerAlive(x))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Stop if the player isn't stuck
|
||||
new stuckindex = AntiStickIsStuck(x);
|
||||
if (stuckindex == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CanCollide(x))
|
||||
{
|
||||
NoCollide(x, true);
|
||||
CreateTimer(0.5, AntiStickSolidify, x, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
|
||||
if (CanCollide(stuckindex))
|
||||
{
|
||||
NoCollide(stuckindex, true);
|
||||
CreateTimer(0.5, AntiStickSolidify, stuckindex, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeated timer function.
|
||||
* Re-solidifies a player being unstuck.
|
||||
*
|
||||
* @param index The client index.
|
||||
*/
|
||||
public Action:AntiStickSolidify(Handle:timer, any:index)
|
||||
{
|
||||
// Validate player is in-game, alive, and is being unstuck
|
||||
if (!IsClientInGame(index) || !IsPlayerAlive(index) || CanCollide(index))
|
||||
{
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
// Stop if the player is still stuck
|
||||
if (AntiStickIsStuck(index) > -1)
|
||||
{
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
NoCollide(index, false);
|
||||
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,8 @@ enum ZRSettings
|
||||
Handle:CVAR_SUICIDE_WORLD_DAMAGE,
|
||||
Handle:CVAR_SPAWN_MIN,
|
||||
Handle:CVAR_SPAWN_MAX,
|
||||
Handle:CVAR_ANTISTICK,
|
||||
Handle:CVAR_ANTISTICK_INTERVAL,
|
||||
Handle:CVAR_PROTECT,
|
||||
Handle:CVAR_CONSECUTIVE_INFECT,
|
||||
Handle:CVAR_OVERLAYS,
|
||||
@ -72,7 +74,6 @@ enum ZRSettings
|
||||
Handle:CVAR_ZTELE_ZOMBIE_DELAY,
|
||||
Handle:CVAR_ZTELE_ZOMBIE_LIMIT,
|
||||
Handle:CVAR_ZTELE_RESET_BUFFERS,
|
||||
Handle:CVAR_ZSTUCK,
|
||||
Handle:CVAR_ZHP,
|
||||
Handle:CVAR_ZHP_DEFAULT,
|
||||
Handle:CVAR_CASHFILL,
|
||||
@ -144,6 +145,8 @@ CreateCvars()
|
||||
gCvars[CVAR_SUICIDE_WORLD_DAMAGE] = CreateConVar("zr_suicide_world_damage", "1", "Respawn zombies as zombies if they were killed by the world, like elevators, doors and lasers. (0: Disable)");
|
||||
gCvars[CVAR_SPAWN_MIN] = CreateConVar("zr_spawn_min", "30", "Minimum time a player is picked to be zombie after the round starts, in seconds");
|
||||
gCvars[CVAR_SPAWN_MAX] = CreateConVar("zr_spawn_max", "50", "Maximum time a player is picked to be zombie after the round starts, in seconds");
|
||||
gCvars[CVAR_ANTISTICK] = CreateConVar("zr_antistick", "1", "Enable the anti-stick module, which will automatically unstick players stuck within each other. (0:Disable)");
|
||||
gCvars[CVAR_ANTISTICK_INTERVAL] = CreateConVar("zr_antistick_interval", "1.0", "How often, in seconds, the anti-stick module checks each player for being stuck. (1.0: Default)");
|
||||
gCvars[CVAR_PROTECT] = CreateConVar("zr_protect", "10", "Players that join late will be protected for this long, in seconds (0: Disable)");
|
||||
gCvars[CVAR_CONSECUTIVE_INFECT] = CreateConVar("zr_consecutive_infect", "0", "Allow player to be randomly chosen twice in a row to be a mother zombie (0: Disable)");
|
||||
gCvars[CVAR_OVERLAYS] = CreateConVar("zr_overlays", "1", "Will show overlays that tell who the winner of the round was (0: Disable)");
|
||||
@ -159,7 +162,6 @@ CreateCvars()
|
||||
gCvars[CVAR_ZTELE_ZOMBIE_DELAY] = CreateConVar("zr_tele_zombie_delay", "0", "Teleport delay for zombies. (0: No delay)");
|
||||
gCvars[CVAR_ZTELE_ZOMBIE_LIMIT] = CreateConVar("zr_tele_zombie_limit", "8", "Maximum number of teleports zombies can do. (0: Zombies can't use the teleporter. -1: Unlimited)");
|
||||
gCvars[CVAR_ZTELE_RESET_BUFFERS] = CreateConVar("zr_tele_reset_buffers", "1", "Reset custom saved teleport locations on each round start. (0: Disable)");
|
||||
gCvars[CVAR_ZSTUCK] = CreateConVar("zr_zstuck", "1", "Allow players that are stuck together to get unstuck (0: Disable)");
|
||||
gCvars[CVAR_ZHP] = CreateConVar("zr_zhp", "1", "Allows clients to enable/disable zombie health display (1: On, 0: Off)");
|
||||
gCvars[CVAR_ZHP_DEFAULT] = CreateConVar("zr_zhp_default", "1", "The default value of zombie health display to new clients (1: On, 0: Off)");
|
||||
gCvars[CVAR_CASHFILL] = CreateConVar("zr_cashfill", "1", "Enable the mod to set the players cash to zr_cashamount (0: Disabled)");
|
||||
|
@ -34,6 +34,7 @@ public Action:RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
|
||||
{
|
||||
ChangeLightStyle();
|
||||
AmbienceRestartAll();
|
||||
AntiStickRestart();
|
||||
RefreshList();
|
||||
|
||||
if (tRound != INVALID_HANDLE)
|
||||
|
@ -20,7 +20,6 @@ MainMenu(client)
|
||||
decl String:zmarket[128];
|
||||
decl String:zspawn[128];
|
||||
decl String:ztele[128];
|
||||
decl String:zstuck[128];
|
||||
decl String:zhp[128];
|
||||
|
||||
Format(zmenu, sizeof(zmenu), "%t", "!zmenu menu");
|
||||
@ -29,7 +28,6 @@ MainMenu(client)
|
||||
Format(zmarket, sizeof(zmarket), "%t", "!zmenu market");
|
||||
Format(zspawn, sizeof(zspawn), "%t", "!zmenu spawn");
|
||||
Format(ztele, sizeof(ztele), "%t", "!zmenu tele");
|
||||
Format(zstuck, sizeof(zstuck), "%t", "!zmenu stuck");
|
||||
Format(zhp, sizeof(zhp), "%t (%d HP)", "!zmenu hp", GetClientHealth(client));
|
||||
|
||||
AddMenuItem(menu_main, "zmenu", zmenu, ITEMDRAW_DISABLED);
|
||||
@ -56,7 +54,6 @@ MainMenu(client)
|
||||
|
||||
AddMenuItem(menu_main, "zspawn", zspawn);
|
||||
AddMenuItem(menu_main, "ztele", ztele);
|
||||
AddMenuItem(menu_main, "zstuck", zstuck);
|
||||
AddMenuItem(menu_main, "zhp", zhp);
|
||||
|
||||
DisplayMenu(menu_main, client, MENU_TIME_FOREVER);
|
||||
@ -101,11 +98,6 @@ public MainMenuHandle(Handle:menu_main, MenuAction:action, client, slot)
|
||||
}
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
ZStuck(client);
|
||||
MainMenu(client);
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
ZHP(client);
|
||||
MainMenu(client);
|
||||
|
@ -175,6 +175,18 @@ NoCollide(client, bool:nocollide)
|
||||
}
|
||||
}
|
||||
|
||||
bool:CanCollide(client)
|
||||
{
|
||||
new collisionstate = GetEntData(client, offsCollision, 1);
|
||||
|
||||
if (collisionstate == 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SetPlayerMoney(client, amount)
|
||||
{
|
||||
SetEntData(client, offsMoney, amount, 4, true);
|
||||
|
@ -63,11 +63,6 @@ public Action:SayCommand(client, argc)
|
||||
AbortTeleport(client, false);
|
||||
}
|
||||
|
||||
else if (StrEqual(args, "!zstuck", false))
|
||||
{
|
||||
ZStuck(client);
|
||||
}
|
||||
|
||||
else if (StrEqual(args, "!zhp", false))
|
||||
{
|
||||
ZHP(client);
|
||||
@ -230,52 +225,6 @@ ZSpawn(client)
|
||||
AddPlayerToList(client);
|
||||
}
|
||||
|
||||
ZStuck(client)
|
||||
{
|
||||
new bool:stuck = GetConVarBool(gCvars[CVAR_ZSTUCK]);
|
||||
if (!stuck)
|
||||
{
|
||||
ZR_PrintToChat(client, "Feature is disabled");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsPlayerAlive(client))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
new Float:clientloc[3];
|
||||
new Float:stuckloc[3];
|
||||
|
||||
GetClientAbsOrigin(client, clientloc);
|
||||
new maxplayers = GetMaxClients();
|
||||
for (new x = 1; x <= maxplayers; x++)
|
||||
{
|
||||
if (!IsClientInGame(x) || !IsPlayerAlive(x))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
GetClientAbsOrigin(x, stuckloc);
|
||||
if (GetVectorDistance(clientloc, stuckloc) <= 60)
|
||||
{
|
||||
NoCollide(x, true);
|
||||
CreateTimer(0.5, CollisionOn, x, TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
new Float:x = GetRandomFloat(-150.0, 150.0);
|
||||
new Float:y = GetRandomFloat(-150.0, 150.0);
|
||||
|
||||
new Float:nudge[3];
|
||||
|
||||
nudge[0] = x;
|
||||
nudge[1] = y;
|
||||
|
||||
SetPlayerVelocity(client, nudge, true);
|
||||
}
|
||||
|
||||
public Action:CollisionOn(Handle:timer, any:index)
|
||||
{
|
||||
if (!IsClientInGame(index))
|
||||
|
@ -650,35 +650,6 @@ RemoveObjectives()
|
||||
}
|
||||
}
|
||||
|
||||
AntiStick(attacker, client)
|
||||
{
|
||||
if (!attacker || !IsClientInGame(attacker))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
new Float:force = GetConVarFloat(gCvars[CVAR_INFECT_ANTISTICK_FORCE]);
|
||||
if (force == 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
new Float:vector[3];
|
||||
|
||||
new Float:attackerloc[3];
|
||||
new Float:clientloc[3];
|
||||
|
||||
GetClientAbsOrigin(attacker, attackerloc);
|
||||
GetClientAbsOrigin(client, clientloc);
|
||||
|
||||
MakeVectorFromPoints(attackerloc, clientloc, vector);
|
||||
|
||||
NormalizeVector(vector, vector);
|
||||
ScaleVector(vector, force);
|
||||
|
||||
TeleportEntity(attacker, NULL_VECTOR, NULL_VECTOR, vector);
|
||||
}
|
||||
|
||||
ZVisionPreCheck(client)
|
||||
{
|
||||
if (IsFakeClient(client))
|
||||
@ -901,7 +872,7 @@ RespawnPlayer(client)
|
||||
return;
|
||||
}
|
||||
|
||||
if (zombieSpawned && GetConVarBool(gCvars[CVAR_SUICIDE_WORLD_DAMAGE]) && gKilledByWorld[client])
|
||||
if (GetConVarBool(gCvars[CVAR_SUICIDE_WORLD_DAMAGE]) && gKilledByWorld[client])
|
||||
{
|
||||
Zombify(client, 0);
|
||||
gKilledByWorld[client] = false;
|
||||
|
Loading…
Reference in New Issue
Block a user