Imported some API-features from zr-dev. Added API test plugins in testsuite.

This commit is contained in:
Richard Helgeby 2010-11-14 15:17:19 +01:00
parent 772ed77beb
commit e7478e0a05
15 changed files with 1179 additions and 25 deletions

View File

@ -7,7 +7,7 @@ SPCOMP=env/linux/bin/spcomp-1.3.4
VERSIONDUMP=./updateversion.sh
vpath %.sp $(SOURCEDIR)
vpath %.inc $(SOURCEDIR)/include
vpath %.inc $(SOURCEDIR)/zr
vpath %.smx $(BUILDDIR)
SOURCEFILES=$(SOURCEDIR)/*.sp
@ -19,7 +19,7 @@ prepare: prepare_newlines prepare_builddir
prepare_newlines:
@echo "Removing windows newlines"
@find $(SOURCEDIR) -name \*.inc -exec dos2unix -p '{}' \;
@find $(SOURCEDIR)/zr -name \*.inc -exec dos2unix -p '{}' \;
@find $(SOURCEDIR) -name \*.sp -exec dos2unix -p '{}' \;
prepare_builddir:

12
buildtests.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/sh
BUILD_DIR=build
SRC=src/testsuite/zr
SM_INCLUDE=env/include
ZR_INCLUDE=src/include
SPCOMP=env/linux/bin/spcomp-1.3.4
mkdir -p $BUILD_DIR
$SPCOMP -i$SM_INCLUDE -i$ZR_INCLUDE -o$BUILD_DIR/respawnapitest.smx $SRC/respawnapitest.sp
$SPCOMP -i$SM_INCLUDE -i$ZR_INCLUDE -o$BUILD_DIR/infectapitest.smx $SRC/infectapitest.sp

View File

@ -0,0 +1,35 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: zombiereloaded.inc
* Type: Include
* Description: Main API include file.
* Notes: Include this file to include the whole ZR API.
*
* Copyright (C) 2009-2010 Greyscale, Richard Helgeby
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ============================================================================
*/
#if defined _zr_included
#endinput
#endif
#define _zr_included
#include <zr/infect.zr>
#include <zr/respawn.zr>

View File

@ -0,0 +1,123 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: infect.zr.inc
* Type: Include
* Description: Infect-related natives/forwards.
*
* Copyright (C) 2009-2010 Greyscale, Richard Helgeby
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ============================================================================
*/
/**
* Returns true if the player is a zombie, false if not.
*
* @param client The client index.
*
* @return True if zombie, false if not.
* @error Invalid client index, not connected or not alive.
*/
native bool:ZR_IsClientZombie(client);
/**
* Returns true if the player is a human, false if not.
*
* @param client The client index.
*
* @return True if human, false if not.
* @error Invalid client index, not connected or not alive.
*/
native bool:ZR_IsClientHuman(client);
/**
* Infects a player.
*
* Note: If the player already is a zombie, the player will be re-infected.
*
* @param client The client to infect.
* @param attacker (Optional) The attacker who did the infect.
* @param motherInfect (Optional) Infect as a mother zombie.
* @param respawnOverride (Optional) Set to true to override respawn cvar.
* @param respawn (Optional) Value to override with.
*
* @error Invalid client index, not connected or not alive.
*/
native ZR_InfectClient(client, attacker = -1, bool:motherInfect = false, bool:respawnOverride = false, bool:respawn = false);
/**
* Turns a zombie back into a human.
*
* Note: If the player already is a human, this code will still run as the
* player was a zombie.
*
* @param client The client to make human.
* @param respawn Teleport client back to spawn.
* @param protect Start spawn protection on client.
*
* @error Invalid client index, not connected or not alive.
*/
native ZR_HumanClient(client, bool:respawn = false, bool:protect = false);
/**
* Called when a player is about to become a zombie.
* Here you can modify any variable or block the infection entirely.
*
* @param client The client index.
* @param attacker The the infecter. (-1 if there is no infecter)
* @param motherInfect If the client is becoming a mother zombie.
* @param respawnOverride True if the respawn cvar is being overridden.
* @param respawn The value that respawn is being overridden with.
*
* @return Plugin_Handled to block infection. Anything else
* (like Plugin_Continue) to allow infection.
*/
forward Action:ZR_OnClientInfect(&client, &attacker, &bool:motherInfect, &bool:respawnOverride, &bool:respawn);
/**
* Called after a player has become a zombie.
*
* @param client The client that was infected.
* @param attacker The the infecter. (-1 if there is no infecter)
* @param motherInfect If the client is a mother zombie.
* @param respawnOverride True if the respawn cvar was overridden.
* @param respawn The value that respawn was overridden with.
*/
forward ZR_OnClientInfected(client, attacker, bool:motherInfect, bool:respawnOverride, bool:respawn);
/**
* Called when a player is about to become a human. (Through an admin command).
* Here you can modify any variable or block the action entirely.
*
* @param client The client index.
* @param respawn True if the client was respawned, false if not.
* @param protect True if the client spawn protected, false if not.
*
* @return Plugin_Handled to block infection. Anything else
* (like Plugin_Continue) to allow acion.
*/
forward Action:ZR_OnClientHuman(&client, &bool:respawn, &bool:protect);
/**
* Called after a player has become a human. (Through an admin command.)
*
* @param client The client index.
* @param respawn Whether the client was respawned.
* @param protect Whether the client has spawn protection.
*/
forward ZR_OnClientHumanPost(client, bool:respawn, bool:protect);

View File

@ -0,0 +1,95 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: respawn.zr.inc
* Type: Include
* Description: Infect-related natives/forwards.
*
* Copyright (C) 2009-2010 Greyscale, Richard Helgeby
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ============================================================================
*/
/**
* Conditions for respawning players.
*/
enum ZR_RespawnCondition
{
ZR_Repsawn_Default = -1, /** Let ZR decide according to its settings. */
ZR_Respawn_Human = 0, /** Respawn as a human. */
ZR_Respawn_Zombie, /** Respawn as a zombie. */
ZR_Respawn_ZombieIfSuicide /** Respawn as a zombie if killed by world damage. */
}
/**
* Spawns a player into the round.
*
* @param client The client index.
* @param condition Optional. Set respawn condition, defaults to current
* ZR settings. See ZR_RespawnCondition for details.
* @error Invalid client index, not connected or already alive.
*/
native ZR_RespawnClient(client, ZR_RespawnCondition:condition = ZR_Repsawn_Default);
/**
* Called right before ZR is about to respawn a player.
* Here you can modify any variable or stop the action entirely.
*
* @param client The client index.
* @param condition Respawn condition. See ZR_RespawnCondition for
* details.
*
* @return Plugin_Handled to block respawn.
*/
forward Action:ZR_OnClientRespawn(&client, &ZR_RespawnCondition:condition);
/**
* Called after ZR respawned a player.
*
* @param client The client index.
* @param condition Current condition of the respawned player. See
* ZR_RespawnCondition for details.
*/
forward ZR_OnClientRespawned(client, ZR_RespawnCondition:condition);
/**
* Set if a player died by a suicide or world damage.
* Note: This will change the respawn condition.
* Note: This value is reset to default by ZR when a zombie player dies.
*
* @param client The client index.
* @param suicide True to say the player suicided, false if killed by another
* player.
*
* @error Invalid client index or not connected.
*/
native ZR_SetKilledByWorld(client, bool:suicide);
/**
* Get whether the player died by a suicide or world damage.
*
* Note: This value is only valid after death event, and before respawn.
*
* @param client The client index.
*
* @return True if the player died by suicide, false if killed by
* another player.
* @error Invalid client index or not connected.
*/
native bool:ZR_GetKilledByWorld(client);

View File

@ -0,0 +1,176 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: respawnapi.sp
* Type: Test plugin
* Description: Tests the infection API.
*
* Copyright (C) 2009-2010 Greyscale, Richard Helgeby
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ============================================================================
*/
#pragma semicolon 1
#include <sourcemod>
#include <zombiereloaded>
public Plugin:myinfo =
{
name = "Zombie:Reloaded Infection API Test",
author = "Greyscale | Richard Helgeby",
description = "Tests the infection API for ZR",
version = "1.0.0",
url = "http://code.google.com/p/zombiereloaded/"
};
new Handle:cvarBlockInfect;
new Handle:cvarBlockHuman;
public OnPluginStart()
{
LoadTranslations("common.phrases");
RegConsoleCmd("zrtest_iszombie", IsZombieCommand, "Returns whether a player is a zombie or not. Usage: zrtest_iszombie <target>");
RegConsoleCmd("zrtest_ishuman", IsHumanCommand, "Returns whether a player is a human or not. Usage: zrtest_ishuman <target>");
RegConsoleCmd("zrtest_infect", InfectClientCommand, "Infects a player. Usage: zrtest_infect <target>");
RegConsoleCmd("zrtest_human", HumanClientCommand, "Turns a player back into a human. Usage: zrtest_human <target>");
cvarBlockInfect = CreateConVar("zrtest_block_infect", "0", "Block infection.");
cvarBlockHuman = CreateConVar("zrtest_block_human", "0", "Block turning players back into humans.");
}
public Action:IsZombieCommand(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
target = FindTarget(client, valueString);
}
else
{
ReplyToCommand(client, "Returns whether a player is a zombie or not. Usage: zrtest_iszombie <target>");
return Plugin_Handled;
}
ReplyToCommand(client, "Client %d is a zombie: %d", client, ZR_IsClientZombie(target));
return Plugin_Handled;
}
public Action:IsHumanCommand(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
target = FindTarget(client, valueString);
}
else
{
ReplyToCommand(client, "Returns whether a player is a human or not. Usage: zrtest_ishuman <target>");
return Plugin_Handled;
}
ReplyToCommand(client, "Client %d is a human: %d", client, ZR_IsClientHuman(target));
return Plugin_Handled;
}
public Action:InfectClientCommand(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
target = FindTarget(client, valueString);
}
if (target < 0)
{
ReplyToCommand(client, "Infects a player. Usage: zrtest_infect <target>");
return Plugin_Handled;
}
ZR_InfectClient(target);
return Plugin_Handled;
}
public Action:HumanClientCommand(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
target = FindTarget(client, valueString);
}
if (target < 0)
{
ReplyToCommand(client, "Turns a player back into a human. Usage: zrtest_human <target>");
return Plugin_Handled;
}
ZR_HumanClient(target);
return Plugin_Handled;
}
public Action:ZR_OnClientInfect(&client, &attacker, &bool:motherInfect, &bool:respawnOverride, &bool:respawn)
{
if (GetConVarBool(cvarBlockInfect))
{
PrintToChatAll("Infection blocked on client %d.", client);
return Plugin_Handled;
}
PrintToChatAll("Client %d is about to be infected. Attacker: %d, Mother zombie: %d, Respawn override: %d, Respawn: %d.", client, attacker, motherInfect, respawnOverride, respawn);
return Plugin_Continue;
}
public ZR_OnClientInfected(client, attacker, bool:motherInfect, bool:respawnOverride, bool:respawn)
{
PrintToChatAll("Client %d was infected. Attacker: %d, Mother zombie: %d, Respawn override: %d, Respawn: %d.", client, attacker, motherInfect, respawnOverride, respawn);
}
public Action:ZR_OnClientHuman(&client, &bool:respawn, &bool:protect)
{
if (GetConVarBool(cvarBlockHuman))
{
PrintToChatAll("Turning human blocked on client %d.", client);
return Plugin_Handled;
}
PrintToChatAll("Client %d is about to become a human. Respawn: %d, Spawn protect: %d", client, respawn, protect);
return Plugin_Continue;
}
public ZR_OnClientHumanPost(client, bool:respawn, bool:protect)
{
PrintToChatAll("Client %d turned a human. Respawn: %d, Spawn protect: %d", client, respawn, protect);
}

View File

@ -0,0 +1,132 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: respawnapi.sp
* Type: Test plugin
* Description: Tests the respawn API.
*
* Copyright (C) 2009-2010 Greyscale, Richard Helgeby
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ============================================================================
*/
#pragma semicolon 1
#include <sourcemod>
#include <zombiereloaded>
public Plugin:myinfo =
{
name = "Zombie:Reloaded Respawn API Test",
author = "Greyscale | Richard Helgeby",
description = "Tests the respawn API for ZR",
version = "1.0.0",
url = "http://code.google.com/p/zombiereloaded/"
};
new Handle:cvarBlockRespawn;
new Handle:cvarAllSuicide;
public OnPluginStart()
{
LoadTranslations("common.phrases");
RegConsoleCmd("zrtest_killed_by_world", KilledByWorldCommand, "Gets or sets the killed by world value. Usage: zrtest_killed_by_world <target> [1|0]");
RegConsoleCmd("zrtest_respawn", RespawnClientCommand, "Respawn a player. Usage: zrtest_respawn <target>");
cvarBlockRespawn = CreateConVar("zrtest_block_respawn", "0", "Block respawning.");
cvarAllSuicide = CreateConVar("zrtest_all_suicide", "0", "Treat all deaths as suicide.");
}
public Action:KilledByWorldCommand(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
target = FindTarget(client, valueString);
}
if (target <= 0)
{
ReplyToCommand(client, "Gets or sets the killed by world value. Usage: zrtest_killed_by_world <target> [value]");
return Plugin_Handled;
}
if (argc > 1)
{
// Set value.
GetCmdArg(2, valueString, sizeof(valueString));
ZR_SetKilledByWorld(target, bool:StringToInt(valueString));
}
else
{
// Print value.
ReplyToCommand(client, "Killed by world: %d", ZR_GetKilledByWorld(target));
}
return Plugin_Handled;
}
public Action:RespawnClientCommand(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
target = FindTarget(client, valueString);
}
if (target < 0)
{
ReplyToCommand(client, "Respawn a player. Usage: zrtest_respawn <target>");
return Plugin_Handled;
}
ZR_RespawnClient(target, ZR_Repsawn_Default);
return Plugin_Handled;
}
public Action:ZR_OnClientRespawn(&client, &ZR_RespawnCondition:condition)
{
if (GetConVarBool(cvarBlockRespawn))
{
PrintToChatAll("Respawn blocked on client %d.", client);
return Plugin_Handled;
}
PrintToChatAll("Client %d is about to respawn. Condition: %d", client, condition);
if (GetConVarBool(cvarAllSuicide))
{
// Set client suicide.
ZR_SetKilledByWorld(client, true);
PrintToChatAll("Client %d is marked as suicide victim.");
}
return Plugin_Continue;
}
public ZR_OnClientRespawned(client, ZR_RespawnCondition:condition)
{
PrintToChatAll("Client %d respawned.", client);
}

View File

@ -113,6 +113,8 @@
#include "zr/volfeatures/volfeatures"
#include "zr/debugtools"
#include "zr/api/api"
/**
* Record plugin info.
*/
@ -137,7 +139,8 @@ public Plugin:myinfo =
*/
public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
{
// TODO: EXTERNAL API
// Load API.
APIInit();
// Let plugin load.
return APLRes_Success;

92
src/zr/api/api.inc Normal file
View File

@ -0,0 +1,92 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: api.inc
* Type: Core
* Description: Native handlers for the ZR API.
*
* Copyright (C) 2009-2010 Greyscale, Richard Helgeby
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ============================================================================
*/
/**
* Application Programming Interface (API)
*
* To allow other plugins or extensions to interact directly with Zombie:Reloaded we need to implement
* an API. SourceMod allows us to do this by creating global "natives" or "forwards."
*
* Natives are basically functions that can be called from any plugin that includes its definition.
* Forwards are functions that are called on a given event. (Such as OnClientPutInServer)
* ZR's API files are located in sourcemod/scripting/include/zr/category.zr.inc. We chose to create multiple
* files simply for organization. Including zr.inc will automatically include the rest of the files as well.
*
* To better understand how natives and forwards are created, go here:
* http://wiki.alliedmods.net/Creating_Natives_(SourceMod_Scripting)
* http://wiki.alliedmods.net/Function_Calling_API_(SourceMod_Scripting)
*/
#include "zr/api/infect.api"
#include "zr/api/respawn.api"
/**
* Initializes all main natives and forwards.
*/
APIInit()
{
// Forward event to sub-modules.
APIInfectInit();
APIRespawnInit();
}
/**
* Validates a client index and when it fails, an error is thrown.
*
* @param client The client index to validate.
* @param alive Set to true to validate that the client is alive, false to ignore.
*
* @error Throws an error when the client isn't valid.
*/
stock APIValidateClientIndex(client, EligibleCondition:alive = Condition_Either)
{
// Verify client index.
if (client < 1 || client > MaxClients)
{
ThrowNativeError(SP_ERROR_NATIVE, "Invalid client index. (%d)", client);
}
// Verify that the client is connected.
if (!IsClientConnected(client))
{
ThrowNativeError(SP_ERROR_NATIVE, "Client %d is not connected.", client);
}
// Check if the player must be dead or alive.
new bool:bAlive = bool:alive;
if (alive != Condition_Either)
{
if (bAlive && !IsPlayerAlive(client))
{
ThrowNativeError(SP_ERROR_NATIVE, "Client %d must be alive.", client);
}
else if (!bAlive && IsPlayerAlive(client))
{
ThrowNativeError(SP_ERROR_NATIVE, "Client %d must be dead.", client);
}
}
}

229
src/zr/api/infect.api.inc Normal file
View File

@ -0,0 +1,229 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: infect.api.inc
* Type: Core
* Description: Native handlers for the ZR API. (Infect module)
*
* Copyright (C) 2009-2010 Greyscale, Richard Helgeby
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ============================================================================
*/
/**
* @section Global forward handles.
*/
new Handle:g_hAPIFwdOnClientInfect = INVALID_HANDLE;
new Handle:g_hAPIFwdOnClientInfected = INVALID_HANDLE;
new Handle:g_hAPIFwdOnClientHuman = INVALID_HANDLE;
new Handle:g_hAPIFwdOnClientHumanPost = INVALID_HANDLE;
/**
* @endsection
*/
/**
* Initializes all natives and forwards related to infection.
*/
APIInfectInit()
{
// Infect module natives/forwards (infect.zr.inc)
// Natives
CreateNative("ZR_IsClientZombie", APIIsClientZombie);
CreateNative("ZR_IsClientHuman", APIIsClientHuman);
CreateNative("ZR_InfectClient", APIInfectClient);
CreateNative("ZR_HumanClient", APIHumanClient);
// Forwards
g_hAPIFwdOnClientInfect = CreateGlobalForward("ZR_OnClientInfect", ET_Hook, Param_CellByRef, Param_CellByRef, Param_CellByRef, Param_CellByRef, Param_CellByRef);
g_hAPIFwdOnClientInfected = CreateGlobalForward("ZR_OnClientInfected", ET_Ignore, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
g_hAPIFwdOnClientHuman = CreateGlobalForward("ZR_OnClientHuman", ET_Hook, Param_CellByRef, Param_CellByRef, Param_CellByRef);
g_hAPIFwdOnClientHumanPost = CreateGlobalForward("ZR_OnClientHumanPost", ET_Ignore, Param_Cell, Param_Cell, Param_Cell);
}
/**
* Native call function (ZR_IsClientInfected)
* Returns true if the client is a zombie, false if not.
*/
public APIIsClientZombie(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
// Validate the client index.
APIValidateClientIndex(client, Condition_True);
return InfectIsClientInfected(client);
}
/**
* Native call function (ZR_IsClientHuman)
* Returns true if the client is a human, false if not.
*
* bool:InfectIsClientHuman(client)
*/
public APIIsClientHuman(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
// Validate the client index.
APIValidateClientIndex(client, Condition_True);
return InfectIsClientHuman(client);
}
/**
* Native call function (ZR_InfectClient)
* Infects a client.
*
* native ZR_InfectClient(client, attacker = -1, bool:motherInfect = false, bool:respawnOverride = false, bool:respawn = false);
*/
public APIInfectClient(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
new attacker = GetNativeCell(2);
new bool:motherInfect = bool:GetNativeCell(3);
new bool:respawnOverride = bool:GetNativeCell(4);
new bool:respawn = bool:GetNativeCell(5);
// Validate the client index.
APIValidateClientIndex(client, Condition_True);
InfectHumanToZombie(client, attacker, motherInfect, respawnOverride, respawn);
}
/**
* Native call function (ZR_HumanClient)
* Turns a zombie back into a human.
*
* native ZR_HumanClient(client, bool:respawn = false, bool:protect = false);
*/
public APIHumanClient(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
new bool:respawn = bool:GetNativeCell(2);
new bool:protect = bool:GetNativeCell(2);
// Validate the client index.
APIValidateClientIndex(client, Condition_True);
InfectZombieToHuman(client, respawn, protect);
}
/**
* Called when a client is about to become a zombie.
*
* @param client The client to infect.
* @param attacker The attacker who did the infect.
* @param motherinfect Indicates a mother zombie infect.
* @param respawnoverride Set to true to override respawn cvar.
* @param respawn Value to override with.
*
* InfectHumanToZombie(client, attacker = -1, bool:motherinfect = false, bool:respawnoverride = false, bool:respawn = false)
*/
Action:APIOnClientInfect(&client, &attacker, &bool:motherinfect, &bool:respawnoverride, &bool:respawn)
{
// Start forward call.
Call_StartForward(g_hAPIFwdOnClientInfect);
// Push the parameters.
Call_PushCellRef(client);
Call_PushCellRef(attacker);
Call_PushCellRef(motherinfect);
Call_PushCellRef(respawnoverride);
Call_PushCellRef(respawn);
// Get what they returned.
new Action:result;
Call_Finish(result);
return result;
}
/**
* Called after a client has become a zombie.
*
* @param client The client to infect.
* @param attacker The attacker who did the infect.
* @param motherinfect Indicates a mother zombie infect.
* @param respawnoverride Set to true to override respawn cvar.
* @param respawn Value to override with.
*
* InfectHumanToZombie(client, attacker = -1, bool:motherinfect = false, bool:respawnoverride = false, bool:respawn = false)
*/
APIOnClientInfected(client, attacker, bool:motherinfect, bool:respawnoverride, bool:respawn)
{
// Start forward call.
Call_StartForward(g_hAPIFwdOnClientInfected);
// Push the parameters.
Call_PushCell(client);
Call_PushCell(attacker);
Call_PushCell(motherinfect);
Call_PushCell(respawnoverride);
Call_PushCell(respawn);
// Finish the call.
Call_Finish();
}
/**
* Called when a client is about to become a human. (Through either zr_human or admin menu)
*
* @param client The client index.
* @param respawn True if the client was respawned, false if not.
* @param protect True if the client spawn protected, false if not.
*
* InfectZombieToHuman(client, bool:respawn = false, bool:protect = false)
*/
Action:APIOnClientHuman(&client, &bool:respawn, &bool:protect)
{
// Start forward call.
Call_StartForward(g_hAPIFwdOnClientHuman);
// Push the parameters.
Call_PushCellRef(client);
Call_PushCellRef(respawn);
Call_PushCellRef(protect);
// Get what they returned.
new Action:result;
Call_Finish(result);
return result;
}
/**
* Called after a client has become a human. (Through either zr_human or admin menu)
*
* @param client The client index.
* @param respawn True if the client was respawned, false if not.
* @param protect True if the client spawn protected, false if not.
*
* InfectZombieToHuman(client, bool:respawn = false, bool:protect = false)
*/
APIOnClientHumanPost(client, bool:respawn, bool:protect)
{
// Start forward call.
Call_StartForward(g_hAPIFwdOnClientHumanPost);
// Push the parameters.
Call_PushCell(client);
Call_PushCell(respawn);
Call_PushCell(protect);
// Finish the call.
Call_Finish();
}

149
src/zr/api/respawn.api.inc Normal file
View File

@ -0,0 +1,149 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: respawn.api.inc
* Type: Core
* Description: Native handlers for the ZR API. (Respawn module)
*
* Copyright (C) 2009-2010 Greyscale, Richard Helgeby
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ============================================================================
*/
/**
* @section Global forward handles.
*/
new Handle:g_hAPIFwdOnClientRespawn = INVALID_HANDLE;
new Handle:g_hAPIFwdOnClientRespawned = INVALID_HANDLE;
/**
* @endsection
*/
/**
* Initializes all natives and forwards related to respawn.
*/
APIRespawnInit()
{
// Respawn module natives/forwards (respawn.zr.inc)
// Natives
CreateNative("ZR_RespawnClient", APIRespawnClient);
CreateNative("ZR_SetKilledByWorld", APISetKilledByWorld);
CreateNative("ZR_GetKilledByWorld", APIGetKilledByWorld);
// Forwards
g_hAPIFwdOnClientRespawn = CreateGlobalForward("ZR_OnClientRespawn", ET_Hook, Param_CellByRef, Param_CellByRef);
g_hAPIFwdOnClientRespawned = CreateGlobalForward("ZR_OnClientRespawned", ET_Ignore, Param_Cell, Param_Cell);
}
/**
* Native call function (ZR_RespawnClient)
* Spawns a player into the round following rules set by cvars.
*
* RespawnSpawnClient(client, bool:zombie = false, bool:zombie_if_suicide = false)
*/
public APIRespawnClient(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
// Validate index and that player isn't alive.
APIValidateClientIndex(client, Condition_False);
// Restore respawn condition.
new RespawnCondition:condition = RespawnCondition:GetNativeCell(2);
new bool:zombie;
new bool:zombieIfSuicide;
RespawnRestoreCondition(condition, zombie, zombieIfSuicide);
// Respawn the client.
RespawnSpawnClient(client, zombie, zombieIfSuicide);
}
/**
* Called right before ZR is about to respawn a player.
*
* @param client The client index.
* @param condition Respawn condition. See RespawnCondition for
* details.
*/
Action:APIOnClientRespawn(&client, &RespawnCondition:condition)
{
// Start forward call.
Call_StartForward(g_hAPIFwdOnClientRespawn);
// Push the parameters.
Call_PushCellRef(client);
Call_PushCellRef(condition);
// Get what they returned.
new Action:result;
Call_Finish(result);
return result;
}
/**
* Called after a player was respawned.
*
* @param client The client index.
* @param condition Current condition of the respawned player. See
* RespawnCondition for details.
*/
Action:APIOnClientRespawned(client, RespawnCondition:condition)
{
// Start forward call.
Call_StartForward(g_hAPIFwdOnClientRespawned);
// Push the parameters.
Call_PushCell(client);
Call_PushCell(condition);
// Finish the call.
Call_Finish();
}
/**
* Native call function (ZR_SetKilledByWorld)
* Override if the client died by a suicide.
*/
public APISetKilledByWorld(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
// Validate the client index.
APIValidateClientIndex(client, Condition_Either);
new bool:suicide = bool:GetNativeCell(2);
// Override the old value.
bKilledByWorld[client] = suicide;
}
/**
* Native call function (ZR_GetKilledByWorld)
* Read the value of if the client died by a suicide.
*/
public APIGetKilledByWorld(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
// Validate the client index.
APIValidateClientIndex(client, Condition_Either);
// Return the value.
return _:bKilledByWorld[client];
}

View File

@ -563,6 +563,15 @@ public Action:InfectMotherZombie(Handle:timer)
*/
InfectHumanToZombie(client, attacker = -1, bool:motherinfect = false, bool:respawnoverride = false, bool:respawn = false)
{
// Forward pre-event to modules.
new Action:result = APIOnClientInfect(client, attacker, motherinfect, respawnoverride, respawn);
// Check if infection should be blocked.
if (result == Plugin_Handled)
{
return;
}
// Mark player as zombie.
bZombie[client] = true;
@ -650,6 +659,7 @@ InfectHumanToZombie(client, attacker = -1, bool:motherinfect = false, bool:respa
SEffectsOnClientInfected(client);
ZTeleOnClientInfected(client);
ZHPOnClientInfected(client);
APIOnClientInfected(client, attacker, motherinfect, respawnoverride, respawn);
}
/**
@ -662,6 +672,15 @@ InfectHumanToZombie(client, attacker = -1, bool:motherinfect = false, bool:respa
*/
InfectZombieToHuman(client, bool:respawn = false, bool:protect = false)
{
// Forward pre-event to modules.
new Action:result = APIOnClientHuman(client, respawn, protect);
// Check if action should be blocked.
if (result == Plugin_Handled)
{
return;
}
// Mark player as human.
bZombie[client] = false;
@ -702,6 +721,7 @@ InfectZombieToHuman(client, bool:respawn = false, bool:protect = false)
// Forward event to modules.
SEffectsOnClientHuman(client);
APIOnClientHumanPost(client, respawn, protect);
}
/**

View File

@ -25,6 +25,17 @@
* ============================================================================
*/
/**
* Conditions for respawning players.
*/
enum RespawnCondition
{
Repsawn_Default = -1, /** Let ZR decide according to its settings. */
Respawn_Human = 0, /** Respawn as a human. */
Respawn_Zombie, /** Respawn as a zombie. */
Respawn_ZombieIfSuicide /** Respawn as a zombie if killed by world damage. */
}
/**
* Array for storing respawn timer handles per client.
*/
@ -133,37 +144,59 @@ RespawnOnRoundEnd()
/**
* Spawns a player into the round.
*
* @param client The client index.
* @param client The client index.
* @param zombie Respawn as zombie.
* @param zombieIfSuicide Respawn as zombie if killed by world damage.
*
* @return True if the player was spawned, false otherwise.
*/
RespawnSpawnClient(client, bool:zombie = false)
bool:RespawnSpawnClient(client, bool:zombie = false, bool:zombieIfSuicide = false)
{
// If client isn't in-game, then stop.
if (!IsClientInGame(client))
{
return;
return false;
}
// Get respawn condition.
//new bool:zombieIfSuicide = GetConVarBool(g_hCvarsList[CVAR_RESPAWN_TEAM_ZOMBIE_WORLD]);
new RespawnCondition:condition = RespawnToContition(zombie, zombieIfSuicide);
// Trigger API forward.
new Action:result = APIOnClientRespawn(client, condition);
// Check if respawn should be stopped.
if (result == Plugin_Handled)
{
return false;
}
// Restore respawn condition.
RespawnRestoreCondition(condition, zombie, zombieIfSuicide);
// Spawn player.
CS_RespawnPlayer(client);
// Stop here if the first zombie hasn't spawned yet.
if (!g_bZombieSpawned)
// Check if first zombie has spawned.
if (g_bZombieSpawned)
{
return;
// Infect if player should spawn as zombie.
if (zombie)
{
InfectHumanToZombie(client);
}
// Infect if player committed suicide by world damage.
else if (zombieIfSuicide && bKilledByWorld[client])
{
InfectHumanToZombie(client);
bKilledByWorld[client] = false;
}
}
// Infect if zombie is true.
if (zombie)
{
InfectHumanToZombie(client);
return;
}
// Forward event to modules.
APIOnClientRespawned(client, condition);
if (GetConVarBool(g_hCvarsList[CVAR_RESPAWN_TEAM_ZOMBIE_WORLD]) && bKilledByWorld[client])
{
InfectHumanToZombie(client);
bKilledByWorld[client] = false;
}
return true;
}
/**
@ -183,7 +216,7 @@ public Action:RespawnTimer(Handle:timer, any:client)
return;
}
// If player isn't alive, then stop.
// If player already is alive, then stop.
if (IsPlayerAlive(client))
{
return;
@ -202,5 +235,52 @@ public Action:RespawnTimer(Handle:timer, any:client)
new bool:respawn_zombie = GetConVarBool(g_hCvarsList[CVAR_RESPAWN_TEAM_ZOMBIE]);
// Spawn player.
RespawnSpawnClient(client, respawn_zombie);
RespawnSpawnClient(client, respawn_zombie, true);
}
/**
* Converts separate conditions into a single condition value.
*/
RespawnCondition:RespawnToContition(bool:zombie, bool:zombieIfSuicide)
{
if (zombieIfSuicide)
{
return Respawn_ZombieIfSuicide;
}
else if (zombie)
{
return Respawn_Zombie;
}
return Respawn_Human;
}
/**
* Restores respawn condition to individual variables. If the condition invalid,
* nothing will be changed.
*
* @param condition Condition to restore.
* @param zombie Output.
* @param zombieIfSucidie Output.
*/
RespawnRestoreCondition(RespawnCondition:condition, &bool:zombie, &bool:zombieIfSuicide)
{
switch (condition)
{
case Respawn_Human:
{
zombie = false;
zombieIfSuicide = false;
}
case Respawn_Zombie:
{
zombie = true;
zombieIfSuicide = false;
}
case Respawn_ZombieIfSuicide:
{
zombie = false;
zombieIfSuicide = true;
}
}
}

View File

@ -39,6 +39,16 @@
* @endsection
*/
/**
* Options that a condition must pass to be eligible.
*/
enum EligibleCondition
{
Condition_False = 0, /** Condition must be false. */
Condition_True = 1, /** Condition must be true. */
Condition_Either = -1 /** Condition can be either true or false. */
}
/**
* Global variable set to true when the first zombie(s) is/are spawned.
*/

View File

@ -263,9 +263,7 @@ bool:ZSpawnClient(client, bool:force = false, bool:zombie = false)
}
// Tell respawn module to respawn client.
RespawnSpawnClient(client, teamzombie);
return true;
return RespawnSpawnClient(client, teamzombie, false);
}
/**