Added antistick system, removed zstuck, and removed redundant check in zombie.inc

This commit is contained in:
Greyscale 2009-04-05 23:20:35 +02:00
parent 1cbce4de6d
commit fd3739b53a
8 changed files with 220 additions and 91 deletions

View File

@ -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
View 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;
}

View File

@ -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)");

View File

@ -34,6 +34,7 @@ public Action:RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
ChangeLightStyle();
AmbienceRestartAll();
AntiStickRestart();
RefreshList();
if (tRound != INVALID_HANDLE)

View File

@ -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);

View File

@ -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);

View File

@ -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))

View File

@ -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;