From d666fbf7ce5eeead6d0c3a283f6d2928c3f6fd16 Mon Sep 17 00:00:00 2001 From: richard Date: Thu, 16 Jul 2009 10:05:40 +0200 Subject: [PATCH 1/3] More work on volfeatures. See details. Finished base event handler for volfeatures. Finished zr_voladd, zr_vol_remove, zr_vol_list and zr_vol_dumpstates console commands. Removed unused function call in class module. Fixed minior bugs in parameter parser (paramtools.inc). Made a debug tools module with console commands for directly testing certain functions. --- .../translations/zombiereloaded.phrases.txt | 12 +- src/zombiereloaded.sp | 2 + src/zr/commands.inc | 2 + src/zr/cvars.inc | 4 +- src/zr/debugtools.inc | 105 +++ src/zr/paramtools.inc | 54 +- src/zr/playerclasses/filtertools.inc | 2 +- src/zr/translation.inc | 1 + src/zr/volfeatures/volanticamp.inc | 817 +++++++++++++++++- src/zr/volfeatures/volcommands.inc | 555 +++++++++++- src/zr/volfeatures/volevents.inc | 41 +- src/zr/volfeatures/volfeatures.inc | 330 +++++-- src/zr/volfeatures/volgenericattributes.inc | 112 ++- 13 files changed, 1861 insertions(+), 176 deletions(-) create mode 100644 src/zr/debugtools.inc diff --git a/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt b/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt index 79871d0..a94bc35 100644 --- a/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt +++ b/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt @@ -932,17 +932,19 @@ "ru" "Здоровье: {1}" } + // =========================== + // Volumetric features (module) + // =========================== - - "Unfair camping" + "Vol Anticamp Message" { - "en" "An admin has marked this area as unfair, please move along, or die." + "en" "This area is restricted, please move along." } - "Unfair camper slayed" + "Vol Slay" { "#format" "{1:s},{2:d}" - "en" "Player {1} has been slayed for camping in a restricted area. (ID: {2})" + "en" "Player \"{1}\" has been slayed for camping in a restricted area (ID: {2})." } // =========================== diff --git a/src/zombiereloaded.sp b/src/zombiereloaded.sp index 5e923d9..aa8f4f0 100644 --- a/src/zombiereloaded.sp +++ b/src/zombiereloaded.sp @@ -80,6 +80,7 @@ #include "zr/zcookies" #include "zr/jumpboost" #include "zr/volfeatures/volfeatures" +#include "zr/debugtools" /** * Record plugin info. @@ -137,6 +138,7 @@ public OnMapStart() SEffectsOnMapStart(); AntiStickOnMapStart(); ZSpawnOnMapStart(); + } /** diff --git a/src/zr/commands.inc b/src/zr/commands.inc index 6f343e8..4dcb552 100644 --- a/src/zr/commands.inc +++ b/src/zr/commands.inc @@ -45,6 +45,8 @@ CommandsInit() ZHPOnCommandsCreate(); VolOnCommandsCreate(); + DebugOnCommandsCreate(); + // Forward event to modules. (hook commands) ClassOnCommandsHook(); DamageOnCommandsHook(); diff --git a/src/zr/cvars.inc b/src/zr/cvars.inc index 99b14de..4efcc38 100644 --- a/src/zr/cvars.inc +++ b/src/zr/cvars.inc @@ -423,8 +423,8 @@ CvarsCreate() // Volumetric Features (module) // =========================== g_hCvarsList[CVAR_VOL] = CreateConVar("zr_vol", "1", "Enables volumetric features."); - g_hCvarsList[CVAR_VOL_UPDATE_INTERVAL] = CreateConVar("zr_vol_update_interval", "1.0", "How often to update player positions and trigger events, in seconds."); - g_hCvarsList[CVAR_VOL_TRIGGER_INTERVAL] = CreateConVar("zr_vol_trigger_interval", "1.0", "How often to check for delayed events, in seconds. Use lower values for more precise delays."); + g_hCvarsList[CVAR_VOL_UPDATE_INTERVAL] = CreateConVar("zr_vol_update_interval", "0.5", "How often to update player positions and trigger events, in seconds."); + g_hCvarsList[CVAR_VOL_TRIGGER_INTERVAL] = CreateConVar("zr_vol_trigger_interval", "0.5", "How often to check for delayed events, in seconds. Use lower values for more precise delays."); // =========================== diff --git a/src/zr/debugtools.inc b/src/zr/debugtools.inc new file mode 100644 index 0000000..e8082ae --- /dev/null +++ b/src/zr/debugtools.inc @@ -0,0 +1,105 @@ +/* + * ============================================================================ + * + * Zombie:Reloaded + * + * File: debugtools.inc + * Type: Core + * Description: Place to put custom functions and test stuff. + * + * Copyright (C) 2009 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 . + * + * ============================================================================ + */ + +DebugOnCommandsCreate() +{ + // Custom test commands: + RegConsoleCmd("zr_getparametercount", Command_GetParameterCount, "Test GetParameterCount function in paramtools.inc. Usage: zr_getparametercount "); + RegConsoleCmd("zr_getparametervalue", Command_GetParameterValue, "Test GetParameterValue function in paramtools.inc. Usage: zr_getparametervalue "); +} + +public Action:Command_GetParameterCount(client, argc) +{ + if (argc < 1) + { + ReplyToCommand(client, "No parameter string passed. Usage: zr_getparametercount "); + return Plugin_Handled; + } + + decl String:argbuffer[256]; + decl String:paramstring[256]; + + paramstring[0] = 0; + + // Join the last parameters in a string. + for (new arg = 1; arg <= argc; arg++) + { + GetCmdArg(arg, argbuffer, sizeof(argbuffer)); + StrCat(paramstring, sizeof(paramstring), argbuffer); + + // Add space, except on the last parameter. + if (arg < argc) + { + StrCat(paramstring, sizeof(paramstring), " "); + } + } + + ReplyToCommand(client, "Parameter string: \"%s\"", paramstring); + new paramcount = GetParameterCount(paramstring); + ReplyToCommand(client, "Parameter count: %d", paramcount); + + return Plugin_Handled; +} + +public Action:Command_GetParameterValue(client, argc) +{ + if (argc < 2) + { + ReplyToCommand(client, "Missing parameters. Usage: zr_getparametervalue "); + return Plugin_Handled; + } + + decl String:paramname[256]; + decl String:paramstring[256]; + + decl String:valuebuffer[64]; + decl String:argbuffer[256]; + + paramstring[0] = 0; + valuebuffer[0] = 0; + + GetCmdArg(1, paramname, sizeof(paramname)); + + // Join the last parameters in a string. + for (new arg = 2; arg <= argc; arg++) + { + GetCmdArg(arg, argbuffer, sizeof(argbuffer)); + StrCat(paramstring, sizeof(paramstring), argbuffer); + + // Add space, except on the last parameter. + if (arg < argc) + { + StrCat(paramstring, sizeof(paramstring), " "); + } + } + + new retval = GetParameterValue(valuebuffer, sizeof(valuebuffer), paramstring, paramname); + + ReplyToCommand(client, "Return value: %d\nParameter string: \"%s\"\nParameter value: \"%s\"", retval, paramstring, valuebuffer); + + return Plugin_Handled; +} \ No newline at end of file diff --git a/src/zr/paramtools.inc b/src/zr/paramtools.inc index cb61b20..701ab7a 100644 --- a/src/zr/paramtools.inc +++ b/src/zr/paramtools.inc @@ -8,6 +8,8 @@ * Description: Provides functions for parsing strings with parameters in * key=value format. * + * Note: Does not support spaces or quoted strings. + * * Copyright (C) 2009 Greyscale, Richard Helgeby * * This program is free software: you can redistribute it and/or modify @@ -34,6 +36,8 @@ stock GetParameterCount(const String:rawString[]) { new lenRawString = strlen(rawString); new paramCount; + new searchPos; + new splitPos; // Check if the raw string is empty. if (lenRawString == 0) @@ -42,20 +46,26 @@ stock GetParameterCount(const String:rawString[]) } // Count number of "=". - for (new searchPos = 0; searchPos < lenRawString; searchPos++) + for (splitPos = 0; splitPos < lenRawString; splitPos++) { - // Set searchPos and check if "=" was found. - searchPos = StrContains(rawString[searchPos], "="); - if (searchPos) + // Find next "=". + searchPos = StrContains(rawString[splitPos], "=", false); + + // Note: searchPos is an offset from rawString[splitPos]. If searchPos + // is 0, then the real position is splitPos. + + // Check if "=" was found. + if (searchPos >= 0) { + // Parameter found. paramCount++; - // Increment one position so we dont find the same "=" again. - searchPos++; + // Update split position. + splitPos += searchPos; } else { - // Exit loop. + // No need to continue. "=" not found. break; } } @@ -86,9 +96,11 @@ stock GetParameterValue(String:buffer[], maxlen, const String:rawString[], const new valuePos; new valueLen; new nextPos; + new splitPos; // Get the position of parameter. paramPos = StrContains(rawString, parameter, false); + splitPos = paramPos; // Check if found. if (paramPos >= 0) @@ -96,8 +108,8 @@ stock GetParameterValue(String:buffer[], maxlen, const String:rawString[], const // Get parameter length. paramLen = strlen(parameter); - // Get the position of the next parameter. - nextPos = StrContains(rawString[paramPos + 1], " "); + // Get the position of the next parameter by finding the next space. + nextPos = StrContains(rawString[splitPos], " "); // Check if the next parameter was found. if (nextPos >= 0) @@ -105,8 +117,9 @@ stock GetParameterValue(String:buffer[], maxlen, const String:rawString[], const // Calculate value starting position. valuePos = paramPos + paramLen + 1; - // Calculate value length. - valueLen = nextPos - valuePos; + // Calculate value length. Note: Adding 1 for space to the null + // terminator. + valueLen = nextPos + splitPos - valuePos + 1; // Check if value length is longer than buffer size. if (valueLen > maxlen) @@ -145,6 +158,7 @@ stock GetParameterName(String:buffer[], maxlen, const String:rawString[], parame new paramPos; new valuePos; new nextValuePos; + new splitPos; // Check if the raw string is empty. if (strlen(rawString) == 0) @@ -157,22 +171,26 @@ stock GetParameterName(String:buffer[], maxlen, const String:rawString[], parame // Get the value starting position for the previous index. for (new index = 0; index < parameterIndex - 1; index++) { - valuePos = StrContains(rawString[valuePos], "="); + valuePos = StrContains(rawString[splitPos], "="); + splitPos += valuePos; } - // Find the next space from valuePos where the specified parameter + // Find the next space from splitPos where the specified parameter // starts. - paramPos = StrContains(rawString[valuePos], " ") + 1; + paramPos = StrContains(rawString[splitPos], " ") + splitPos + 1; - // Find the next value position from paramPos to get the end position + // Update split position. + splitPos += paramPos; + + // Find the next value position from splitPos to get the end position // of the parameter name. - nextValuePos = StrContains(rawString[paramPos], "="); + nextValuePos = StrContains(rawString[splitPos], "=") + splitPos; // Check if a value is specified. if (nextValuePos > 0) { // Return the parameter name between paramPos and nextValuePos. - return strcopy(buffer, nextValuePos - paramPos, rawString[paramPos]); + return strcopy(buffer, nextValuePos - paramPos + 1, rawString[paramPos]); // + 1 to include null terminator. } else { @@ -189,7 +207,7 @@ stock GetParameterName(String:buffer[], maxlen, const String:rawString[], parame if (valuePos > 0) { // Return the parameter name. - return strcopy(buffer, valuePos, rawString); + return strcopy(buffer, valuePos + 1, rawString); // + 1 to include null terminator. } else { diff --git a/src/zr/playerclasses/filtertools.inc b/src/zr/playerclasses/filtertools.inc index aa86c85..d63ca73 100644 --- a/src/zr/playerclasses/filtertools.inc +++ b/src/zr/playerclasses/filtertools.inc @@ -384,7 +384,7 @@ stock ClassGetIndex(const String:name[], cachetype = ZR_CLASS_CACHE_MODIFIED) */ stock ClassGetActiveIndex(client) { - new teamid = GetClientTeam(client); + new teamid; if (!ZRIsClientOnTeam(client)) { diff --git a/src/zr/translation.inc b/src/zr/translation.inc index f2ae06e..1b8ccfa 100644 --- a/src/zr/translation.inc +++ b/src/zr/translation.inc @@ -61,6 +61,7 @@ TranslationInit() { // Load translations phrases used by plugin. LoadTranslations("common.phrases.txt"); + LoadTranslations("core.phrases.txt"); LoadTranslations("zombiereloaded.phrases.txt"); } diff --git a/src/zr/volfeatures/volanticamp.inc b/src/zr/volfeatures/volanticamp.inc index bc314c1..d99fe98 100644 --- a/src/zr/volfeatures/volanticamp.inc +++ b/src/zr/volfeatures/volanticamp.inc @@ -25,31 +25,16 @@ * ============================================================================ */ -/** - * Data structure for a anti-camp volume. - */ -enum VolTypeAnticamp -{ - Float:anticamp_interval, /** How often to trigger an action. */ - Handle:anticamp_timer, /** Action timer handle. */ - - VolAnticampAction:anticamp_action, /** What to do with players in anti-camp volumes */ - Float:anticamp_amount, /** Amount depending on action type. Usually time in seconds or damage amount. */ - - VolAnticampeWarningType:anticamp_warning, /** How to warn the player. */ - String:anticamp_message[256] /** Override warning message. Max 256 characters. */ -} - /** * Actions to do with players in anti-camp volumes. */ enum VolAnticampAction { - anticamp_no_action, /** Do nothing but give a warning. */ - anticamp_damage, /** Give damage to player. */ - anticamp_slay, /** Slay player. */ - anticamp_drug, /** Drug player. */ - anticamp_fire /** Ignite player. */ + Anticamp_NoAction, /** Do nothing but give a warning. */ + Anticamp_Damage, /** Give damage to player. */ + Anticamp_Slay, /** Slay player. */ + Anticamp_Drug, /** Drug player. */ + Anticamp_Ignite /** Ignite player. */ } /** @@ -57,13 +42,797 @@ enum VolAnticampAction */ enum VolAnticampeWarningType { - anticamp_no_warning, /** No warning messages. */ - anticamp_chat, /** Print warning in chat area. */ - anticamp_center, /** Print centered warning message. */ - anticamp_menu /** Print a menu-like warning message with close option. */ + Anticamp_NoWarning, /** No warning messages. */ + Anticamp_Chat, /** Print warning in chat area. */ + Anticamp_Center, /** Print centered warning message. */ + Anticamp_Menu /** Print a menu-like warning message with close option. */ +} + +/** + * Data structure for a anti-camp volume. + */ +enum VolTypeAnticamp +{ + bool:Anticamp_InUse, /** Specifies if the data index is used or not. */ + Float:Anticamp_Interval, /** How often to trigger an action. */ + Handle:Anticamp_Timer, /** Action timer handle. */ + + VolAnticampAction:Anticamp_Action, /** What to do with players in anti-camp volumes */ + Float:Anticamp_Amount, /** Amount depending on action type. Usually time in seconds or damage amount. */ + + VolAnticampeWarningType:Anticamp_Warning, /** How to warn the player. */ + String:Anticamp_Message[256] /** Override warning message. Max 256 characters. */ } /** * Anti-camp data. */ new AnticampData[ZR_VOLUMES_MAX][VolTypeAnticamp]; + +/** + * Event callback. Enables a anticamp volume. + * + * @param volumeIndex The volume index. + */ +VolAnticampEnable(volumeIndex) +{ + new Float:interval; + + // Validate index. + if (!VolIsValidIndex(volumeIndex)) + { + return; + } + + // Get data index. + new dataindex = Volumes[volumeIndex][Vol_DataIndex]; + + // Validate data index. + if (!VolAnticampValidateIndex(dataindex)) + { + return; + } + + // Check if in use. + if (AnticampData[dataindex][Anticamp_InUse]) + { + // Start timer if not running. + if (AnticampData[dataindex][Anticamp_Timer] == INVALID_HANDLE) + { + // Get interval. + interval = AnticampData[dataindex][Anticamp_Interval]; + + // Validate interval. + if (interval > 0.0) + { + AnticampData[dataindex][Anticamp_Timer] = CreateTimer(interval, Event_VolAnticampTrigger, _, TIMER_REPEAT); + } + } + + LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Vol state", "Enabled anticamp volume %d.", volumeIndex); + } +} + +/** + * Starts all existing anticamp timers. + */ +stock VolAnticampEnableAll() +{ + new Float:interval; + + // Loop through all volumes. + for (new dataindex = 0; dataindex < ZR_VOLUMES_MAX; dataindex++) + { + // Check if in use. + if (AnticampData[dataindex][Anticamp_InUse]) + { + // Start timer if not running. + if (AnticampData[dataindex][Anticamp_Timer] == INVALID_HANDLE) + { + // Get interval. + interval = AnticampData[dataindex][Anticamp_Interval]; + + // Validate interval. + if (interval > 0.0) + { + AnticampData[dataindex][Anticamp_Timer] = CreateTimer(interval, Event_VolAnticampTrigger, _, TIMER_REPEAT); + } + } + } + } +} + +/** + * Event callback. Stops existing anticamp timer on a volume. + */ +VolAnticampDisable(volumeIndex) +{ + new Handle:timerbuffer; + + // Validate index. + if (!VolIsValidIndex(volumeIndex)) + { + return; + } + + // Get data index. + new dataindex = Volumes[volumeIndex][Vol_DataIndex]; + + // Validate data index. + if (!VolAnticampValidateIndex(dataindex)) + { + return; + } + + // Check if in use. + if (AnticampData[dataindex][Anticamp_InUse]) + { + // Stop timer. + timerbuffer = AnticampData[dataindex][Anticamp_Timer]; + if (timerbuffer != INVALID_HANDLE) + { + KillTimer(timerbuffer); + AnticampData[dataindex][Anticamp_Timer] = INVALID_HANDLE; + } + + LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Vol state", "Disabled anticamp volume %d.", volumeIndex); + } + +} + +/** + * Stops all existing anticamp timers. + */ +stock VolAnticampDisableAll() +{ + new Handle:timerbuffer; + + // Loop through all volumes. + for (new dataindex = 0; dataindex < ZR_VOLUMES_MAX; dataindex++) + { + // Check if in use. + if (AnticampData[dataindex][Anticamp_InUse]) + { + // Stop timer. + timerbuffer = AnticampData[dataindex][Anticamp_Timer]; + if (timerbuffer != INVALID_HANDLE) + { + KillTimer(timerbuffer); + AnticampData[dataindex][Anticamp_Timer] = INVALID_HANDLE; + } + } + } +} + +/** + * Disables feature and resets data to defaults at the specified index. + * + * @param dataIndex Local data index. + */ +VolAnticampReset(dataIndex) +{ + AnticampData[dataIndex][Anticamp_InUse] = false; + + AnticampData[dataIndex][Anticamp_Interval] = 1.0; + if (AnticampData[dataIndex][Anticamp_Timer] != INVALID_HANDLE) + { + KillTimer(AnticampData[dataIndex][Anticamp_Timer]); + AnticampData[dataIndex][Anticamp_Timer] = INVALID_HANDLE; + } + + AnticampData[dataIndex][Anticamp_Action] = Anticamp_Damage; + AnticampData[dataIndex][Anticamp_Amount] = 5.0; + + AnticampData[dataIndex][Anticamp_Warning] = Anticamp_Chat; + Format(String:AnticampData[dataIndex][Anticamp_Message], 256, ""); +} + +/** + * Initialization event for anticamp feature. + */ +VolAnticampInit() +{ + // Set default attributes. + for (new dataindex = 0; dataindex < ZR_VOLUMES_MAX; dataindex++) + { + VolAnticampReset(dataindex); + } +} + +/** + * Timer callback for anticamp volumes. Applies actions on players in volumes. + */ +public Action:Event_VolAnticampTrigger(Handle:timer) +{ + // Loop through all players. + for (new client = 1; client <= MaxClients; client++) + { + // Loop through all volumes. + for (new volumeindex = 0; volumeindex < ZR_VOLUMES_MAX; volumeindex++) + { + // Check if the volume is enabled and in use. + if (VolIsEnabled(volumeindex) && VolInUse(volumeindex)) + { + // Check if player is in a anticamp volume. + if (VolPlayerInVolume[client][volumeindex] && Volumes[volumeindex][Vol_Type] == VolFeature_Anticamp) + { + // Apply action. + VolAnticampApplyAction(client, Volumes[volumeindex][Vol_DataIndex], volumeindex); + } + } + } + } +} + +/** + * Applies action on a client for the specified volume. + * + * @param client The client index. + * @param dataIndex Local data index. + * @param volumeIndex The volume index. + */ +VolAnticampApplyAction(client, dataIndex, volumeIndex) +{ + new Float:amount = AnticampData[dataIndex][Anticamp_Amount]; + + // Send warning message. + VolAnticampWarnPlayer(client, dataIndex); + + switch (AnticampData[dataIndex][Anticamp_Action]) + { + case Anticamp_NoAction: + { + // Do nothing. + } + case Anticamp_Damage: + { + // Give damage to player. Kill if zero HP. + new damage = RoundToNearest(amount); + new health = GetClientHealth(client) - damage; + decl String:name[64]; + decl String:buffer[256]; + + if (health > 0) + { + SetEntityHealth(client, health); + } + else + { + // Health is zero or below. Kill player. + ForcePlayerSuicide(client); + + // Log event. + GetClientName(client, name, sizeof(name)); + SetGlobalTransTarget(client); + Format(buffer, sizeof(buffer), "%t", "Vol Slay", name, volumeIndex); + + /*if (LogFlagCheck(LOG_GAME_EVENTS, LOG_MODULE_ANTICAMP)) ZR_LogMessageFormatted(client, "anticamp", "kill", "%s", true, buffer); + if (anticamp_echo) + { + FormatTextString(buffer, sizeof(buffer)); + ZR_PrintToAdminChat(buffer); + }*/ + } + } + case Anticamp_Slay: + { + + } + case Anticamp_Drug: + { + + } + case Anticamp_Ignite: + { + + } + } +} + +/** + * Gives a warning to the specified player for the specified volume. + * + * @param client The client index. + * @param dataIndex Local data index. + */ +VolAnticampWarnPlayer(client, dataIndex) +{ + decl String:buffer[256]; + new bool:custommessage = (strlen(AnticampData[dataIndex][Anticamp_Message]) > 0) ? true : false; + + // Set language. + SetGlobalTransTarget(client); + + // Format message. + if (custommessage) + { + // Use custom message. + strcopy(buffer, sizeof(buffer), AnticampData[dataIndex][Anticamp_Message]); + } + else + { + // Use message in translations file. + Format(buffer, sizeof(buffer), "%t", "Vol Anticamp Message"); + } + + switch (AnticampData[dataIndex][Anticamp_Warning]) + { + case Anticamp_NoWarning: + { + // Do nothing. + } + case Anticamp_Chat: + { + // Apply ZR formatting and print chat message. + TranslationPluginFormatString(buffer, sizeof(buffer)); + PrintToChat(client, buffer); + } + case Anticamp_Center: + { + // Print centered message. + PrintCenterText(client, buffer); + } + case Anticamp_Menu: + { + // Display the message in a menu panel. + new Handle:panel = CreatePanel(); + + SetPanelTitle(panel, "Zombie:Reloaded"); + DrawPanelItem(panel, "", ITEMDRAW_SPACER); + DrawPanelItem(panel, buffer); + DrawPanelItem(panel, "", ITEMDRAW_SPACER); + + SetPanelCurrentKey(panel, 10); + + Format(buffer, sizeof(buffer), "%t", "Exit"); + DrawPanelItem(panel, buffer, ITEMDRAW_CONTROL); + + SendPanelToClient(panel, client, Handler_AnitcampDummy, 10); + CloseHandle(panel); + } + } +} + +/** + * Dummy handler for panel messages. + */ +public Handler_AnitcampDummy(Handle:menu, MenuAction:action, param1, param2) +{ + // Do nothing. +} + +/** + * Gets the first free anticamp data index. + * + * @return The first free anticamp data index if successful, or -1 if + * there are no free volumes. + */ +VolAnticampGetFreeIndex() +{ + // Loop through all indexes. + for (new dataindex = 0; dataindex < ZR_VOLUMES_MAX; dataindex++) + { + // Check if it's free. + if (!AnticampData[dataindex][Anticamp_InUse]) + { + return dataindex; + } + } + + // No free index found. + return -1; +} + +/** + * Validates local data index. + * + * @param dataIndex Index to validate. + * @return True if valid, false otherwise. + */ +bool:VolAnticampValidateIndex(dataIndex) +{ + if (dataIndex >= 0 && dataIndex < ZR_VOLUMES_MAX) + { + return true; + } + else + { + return false; + } +} + +/** + * Dumps data to be used by zr_vol_list command. + * + * @param dataIndex Index in anticamp data array. + * @param buffer Destination string buffer. + * @param maxlen Size of destination buffer. + * @return Number of cells written. + */ +VolAnticampDumpData(dataIndex, String:buffer[], maxlen) +{ + decl String:linebuffer[128]; + decl String:valuebuffer[256]; + new anticampcache[VolTypeAnticamp]; + new cellswritten; + + // Validate index. + if (!VolAnticampValidateIndex(dataIndex)) + { + return 0; + } + + // Initialize and clear buffer. + buffer[0] = 0; + + // Cache data. + anticampcache = AnticampData[dataIndex]; + + Format(linebuffer, sizeof(linebuffer), "Interval: %.2f\n", anticampcache[Anticamp_Interval]); + cellswritten += StrCat(buffer, maxlen, linebuffer); + + VolAnticampActionToString(anticampcache[Anticamp_Action], valuebuffer, sizeof(valuebuffer)); + Format(linebuffer, sizeof(linebuffer), "Action: %s\n", valuebuffer); + cellswritten += StrCat(buffer, maxlen, linebuffer); + + Format(linebuffer, sizeof(linebuffer), "Action amount: %.2f\n", anticampcache[Anticamp_Amount]); + cellswritten += StrCat(buffer, maxlen, linebuffer); + + VolAnticampWarningToString(anticampcache[Anticamp_Warning], valuebuffer, sizeof(valuebuffer)); + Format(linebuffer, sizeof(linebuffer), "Warning type: %s\n", valuebuffer); + cellswritten += StrCat(buffer, maxlen, linebuffer); + + strcopy(valuebuffer, sizeof(valuebuffer), anticampcache[Anticamp_Message]); + Format(linebuffer, sizeof(linebuffer), "Warning message: \"%s\"\n", valuebuffer); + cellswritten += StrCat(buffer, maxlen, linebuffer); + + return cellswritten; +} + + +/************************************** + * * + * CONVERTING FUNCTIONS * + * * + **************************************/ + +/** + * Converts a action type to a string. + * + * @param actionType Action type to convert. + * @param buffer Destination string buffer. + * @param maxlen Size of destination buffer. + * @param shortName Optional. Write short name or human readable name. + * Default is human readable (false). + * @return Number of cells written. + */ +VolAnticampActionToString(VolAnticampAction:actionType, String:buffer[], maxlen, bool:shortName = false) +{ + switch (actionType) + { + case Anticamp_NoAction: + { + return shortName ? strcopy(buffer, maxlen, "none") : strcopy(buffer, maxlen, "No action"); + } + case Anticamp_Damage: + { + return shortName ? strcopy(buffer, maxlen, "damage") : strcopy(buffer, maxlen, "Damage player"); + } + case Anticamp_Drug: + { + return shortName ? strcopy(buffer, maxlen, "drug") : strcopy(buffer, maxlen, "Drug player "); + } + case Anticamp_Ignite: + { + return shortName ? strcopy(buffer, maxlen, "ignite") : strcopy(buffer, maxlen, "Ignite player"); + } + } + + return 0; +} + +/** + * Converts a action string type to a action type. + * + * @param action Action string type to convert. + * @return Action type or Anticamp_NoAction if failed. + */ +stock VolAnticampAction:VolAnticampStringToAction(const String:action[]) +{ + // Check if empty. + if (strlen(action) == 0) + { + return Anticamp_NoAction; + } + + if (StrEqual(action, "none", false)) + { + return Anticamp_NoWarning; + } + else if (StrEqual(action, "damage", false)) + { + return Anticamp_Damage; + } + else if (StrEqual(action, "drug", false)) + { + return Anticamp_Drug; + } + else if (StrEqual(action, "ignite", false)) + { + return Anticamp_Ignite; + } + + // No match. + return Anticamp_NoAction; +} + +/** + * Converts a warning type to a string. + * + * @param warningType Warning type to convert. + * @param buffer Destination string buffer. + * @param maxlen Size of destination buffer. + * @param shortName Optional. Write short name or human readable name. + * Default is human readable (false). + * @return Number of cells written. + */ +VolAnticampWarningToString(VolAnticampeWarningType:warningType, String:buffer[], maxlen, bool:shortName = false) +{ + switch (warningType) + { + case Anticamp_NoWarning: + { + return shortName ? strcopy(buffer, maxlen, "none") : strcopy(buffer, maxlen, "No warning"); + } + case Anticamp_Chat: + { + return shortName ? strcopy(buffer, maxlen, "chat") : strcopy(buffer, maxlen, "Chat area"); + } + case Anticamp_Center: + { + return shortName ? strcopy(buffer, maxlen, "center") : strcopy(buffer, maxlen, "Centered message"); + } + case Anticamp_Menu: + { + return shortName ? strcopy(buffer, maxlen, "meny") : strcopy(buffer, maxlen, "Message in menu panel"); + } + } + + return 0; +} + +/** + * Converts a warning string type to a warning type. + * + * @param warning Warning string type to convert. + * @return Warning type, or Anticamp_NoWarning if failed. + */ +stock VolAnticampeWarningType:VolAnticampStringToWarning(const String:warning[]) +{ + // Check if empty. + if (strlen(warning) == 0) + { + return Anticamp_NoWarning; + } + + if (StrEqual(warning, "none", false)) + { + return Anticamp_NoWarning; + } + else if (StrEqual(warning, "chat", false)) + { + return Anticamp_Chat; + } + else if (StrEqual(warning, "center", false)) + { + return Anticamp_Center; + } + else if (StrEqual(warning, "menu", false)) + { + return Anticamp_Menu; + } + + // No match. + return Anticamp_NoWarning; +} + + +/************************************** + * * + * ATTRIBUTE FUNCTIONS * + * * + **************************************/ + +/** + * Sets anticamp spesific attributes on a anticamp volume. + * + * @param dataIndex Local data index. + * @param attribName Attribute to modify. + * @param attribVlue Attribute value to set. + * @return True if successfully set, false otherwise. + */ +bool:VolAnticampSetAttribute(dataIndex, const String:attribName[], const String:attribValue[]) +{ + // Validate data index. + if (!VolAnticampValidateIndex(dataIndex)) + { + return false; + } + + // Check attribute names. + if (StrEqual(attribName, "interval", false)) + { + if (VolAnticampSetIntervalString(dataIndex, attribValue)) + { + return true; + } + } + else if (StrEqual(attribName, "action", false)) + { + if (VolAnticampSetActionString(dataIndex, attribValue)) + { + return true; + } + } + else if (StrEqual(attribName, "amount", false)) + { + if (VolAnticampSetAmountString(dataIndex, attribValue)) + { + return true; + } + } + else if (StrEqual(attribName, "warning", false)) + { + if (VolAnticampSetWarningString(dataIndex, attribValue)) + { + return true; + } + } + else if (StrEqual(attribName, "message", false)) + { + // Unsupported because of technical limits in command parser. Spaces + // and quoted strings aren't supported yet. + } + + return false; +} + +/** + * Parses a interval string value and applies it to the specified volume. + * + * @param dataIndex Local data index. + * @param interval Interval to set. A floating point number formatted as a + * string. + * @return True if successfully set, false otherwise. + */ +bool:VolAnticampSetIntervalString(dataIndex, const String:interval[]) +{ + new Float:anticampinterval; + + // Check if string value is empty. + if (strlen(interval) == 0) + { + return false; + } + + // Convert value. + anticampinterval = StringToFloat(interval); + + // Apply value. + AnticampData[dataIndex][Anticamp_Interval] = anticampinterval; + return true; +} + +/** + * Parses a action type string value and applies it to the specified volume. + * + * @param dataIndex Local data index. + * @param action Action type to set. + * @return True if successfully set, false otherwise. + */ +bool:VolAnticampSetActionString(dataIndex, const String:action[]) +{ + // Check if string value is empty. + if (strlen(action) == 0) + { + return false; + } + + // Check effect string values and apply them to the volume. + if (StrEqual(action, "none", false)) + { + AnticampData[dataIndex][Anticamp_Action] = Anticamp_NoAction; + return true; + } + else if (StrEqual(action, "damage", false)) + { + AnticampData[dataIndex][Anticamp_Action] = Anticamp_Damage; + return true; + } + else if (StrEqual(action, "slay", false)) + { + AnticampData[dataIndex][Anticamp_Action] = Anticamp_Slay; + return true; + } + else if (StrEqual(action, "drug", false)) + { + AnticampData[dataIndex][Anticamp_Action] = Anticamp_Drug; + return true; + } + else if (StrEqual(action, "ignite", false)) + { + AnticampData[dataIndex][Anticamp_Action] = Anticamp_Ignite; + return true; + } + + // The string value didn't match any valid action types. + return false; +} + +/** + * Parses a action amount string value and applies it to the specified volume. + * + * @param dataIndex Local data index. + * @param amount Amount to set. A floating point number formatted as a + * string. + * @return True if successfully set, false otherwise. + */ +bool:VolAnticampSetAmountString(dataIndex, const String:amount[]) +{ + new Float:actionamount; + + // Check if string value is empty. + if (strlen(amount) == 0) + { + return false; + } + + // Convert value. + actionamount = StringToFloat(amount); + + // Apply value. + AnticampData[dataIndex][Anticamp_Amount] = actionamount; + return true; +} + +/** + * Parses a warning type string value and applies it to the specified volume. + * + * @param dataIndex Local data index. + * @param warning warning type to set. + * @return True if successfully set, false otherwise. + */ +bool:VolAnticampSetWarningString(dataIndex, const String:warning[]) +{ + + // Check if string value is empty. + if (strlen(warning) == 0) + { + return false; + } + + // Check effect string values and apply them to the volume. + if (StrEqual(warning, "none", false)) + { + AnticampData[dataIndex][Anticamp_Warning] = Anticamp_NoWarning; + return true; + } + else if (StrEqual(warning, "chat", false)) + { + AnticampData[dataIndex][Anticamp_Warning] = Anticamp_Chat; + return true; + } + else if (StrEqual(warning, "center", false)) + { + AnticampData[dataIndex][Anticamp_Warning] = Anticamp_Center; + return true; + } + else if (StrEqual(warning, "menu", false)) + { + AnticampData[dataIndex][Anticamp_Warning] = Anticamp_Menu; + return true; + } + + // The string value didn't match any valid action types. + return false; +} diff --git a/src/zr/volfeatures/volcommands.inc b/src/zr/volfeatures/volcommands.inc index de40f3d..4488ba8 100644 --- a/src/zr/volfeatures/volcommands.inc +++ b/src/zr/volfeatures/volcommands.inc @@ -49,9 +49,433 @@ Example: zr_vol_add 0 0 0 100 200 300 anticamp team=humans delay=5 effect=wireframe effect_color=255,0,0 */ + +/** + * Creates commands for managing volumes. + */ +VolOnCommandsCreate() +{ + RegAdminCmd("zr_vol_add", VolAddVolumeCommand, ADMFLAG_CONFIG, "Creates a rectangular volume in the map. Usage: zr_vol_add [params]"); + RegAdminCmd("zr_vol_remove", VolRemoveVolumeCommand, ADMFLAG_CONFIG, "Removes an existing volume in the map. Usage: zr_vol_remove "); + RegConsoleCmd("zr_vol_list", VolListCommand, "Lists existing volumes in the map, or dumps detail data to the specified volume. Usage: zr_vol_list [volume index]"); + RegConsoleCmd("zr_vol_dumpstates", VolDumpStatesCommand, "Dumps volume states for the specified player. Usage: zr_vol_dumpstates "); +} + +/** + * Command callback for creating a new volume. + */ public Action:VolAddVolumeCommand(client, argc) { + decl String:buffer[640]; + buffer[0] = 0; + if (argc < 7) + { + // Write syntax info. + StrCat(buffer, sizeof(buffer), "Creates a rectangular volume in the map. Usage: zr_vol_add [params]\n\n"); + StrCat(buffer, sizeof(buffer), "Parameters:\n"); + StrCat(buffer, sizeof(buffer), "x1, y1, z1 Coordinates to first corner (any corner)\n"); + StrCat(buffer, sizeof(buffer), "x2, y2, z2 Coordinates to oposite corner (diagonally to oposite height)\n"); + StrCat(buffer, sizeof(buffer), "type Volumetric feature type:\n"); + StrCat(buffer, sizeof(buffer), " anticamp\n"); + StrCat(buffer, sizeof(buffer), "params Parameter string with additional volume data. Generic parameters:\n"); + StrCat(buffer, sizeof(buffer), " teamfilter=all|humans|zombies\n"); + StrCat(buffer, sizeof(buffer), " delay=0\n"); + StrCat(buffer, sizeof(buffer), " effect=none|wireframe|smoke\n"); + StrCat(buffer, sizeof(buffer), " effect_color=0,0,0\n"); + StrCat(buffer, sizeof(buffer), " enabled=1"); + + ReplyToCommand(client, buffer); + return Plugin_Handled; + } + + new Float:x1; + new Float:y1; + new Float:z1; + new Float:x2; + new Float:y2; + new Float:z2; + new Float:min[3]; + new Float:max[3]; + new VolumeFeatureTypes:voltype; + new Float:floatbuffer; + new volindex; + new dataindex; + new paramcount; + + decl String:params[256]; + decl String:argbuffer[256]; + + params[0] = 0; + + // Get a free volume index. + volindex = VolGetFreeVolume(); + + // Validate index. + if (!VolIsValidIndex(volindex)) + { + ReplyToCommand(client, "Cannot add volume. Maximum number of volumes reached."); + return Plugin_Handled; + } + + // Get positions. + GetCmdArg(1, argbuffer, sizeof(argbuffer)); + x1 = StringToFloat(argbuffer); + + GetCmdArg(2, argbuffer, sizeof(argbuffer)); + y1 = StringToFloat(argbuffer); + + GetCmdArg(3, argbuffer, sizeof(argbuffer)); + z1 = StringToFloat(argbuffer); + + GetCmdArg(4, argbuffer, sizeof(argbuffer)); + x2 = StringToFloat(argbuffer); + + GetCmdArg(5, argbuffer, sizeof(argbuffer)); + y2 = StringToFloat(argbuffer); + + GetCmdArg(6, argbuffer, sizeof(argbuffer)); + z2 = StringToFloat(argbuffer); + + // Check if both locations are equal. + if (FloatCompare(x1, x2) == 0) + { + if (FloatCompare(y1, y2) == 0) + { + if (FloatCompare(z1, z2) == 0) + { + ReplyToCommand(client, "Cannot add volume. Both locations are equal."); + return Plugin_Handled; + } + } + } + + // Sort out max and min values so 1-values are smaller. + if (FloatCompare(x1, x2) == 1) + { + // x1 is bigger than x2. Swap values. + floatbuffer = x1; + x1 = x2; + x2 = floatbuffer; + } + if (FloatCompare(y1, y2) == 1) + { + // y1 is bigger than y2. Swap values. + floatbuffer = y1; + y1 = y2; + y2 = floatbuffer; + } + if (FloatCompare(z1, z2) == 1) + { + // z1 is bigger than z2. Swap values. + floatbuffer = z1; + z1 = z2; + z2 = floatbuffer; + } + + // Copy coordinates to location vectors. + min[0] = x1; + min[1] = y1; + min[2] = z1; + max[0] = x2; + max[1] = y2; + max[2] = z2; + + // Get volume type. + GetCmdArg(7, argbuffer, sizeof(argbuffer)); + voltype = VolGetTypeFromString(argbuffer); + + // Validate volume type. + if (voltype == VolFeature_Invalid) + { + ReplyToCommand(client, "Cannot add volume. Invalid volume type: %s", argbuffer); + return Plugin_Handled; + } + + // Get free data index for the specified type. + dataindex = VolGetFreeDataIndex(voltype); + + // Validate data index. + if (dataindex < 0) + { + ReplyToCommand(client, "Cannot add volume. Out of free data indexes for type \"%s\"", argbuffer); + return Plugin_Handled; + } + + // Add volume. + volindex = VolAdd(volindex, min, max, voltype, dataindex); + + // Get additional parameters if they exist. + if (argc >= 8) + { + // Join the last parameters in a string. + for (new arg = 8; arg <= argc; arg++) + { + GetCmdArg(arg, argbuffer, sizeof(argbuffer)); + StrCat(params, sizeof(params), argbuffer); + + // Add space, except on the last parameter. + if (arg < argc) + { + StrCat(params, sizeof(params), " "); + } + } + + // Set attributes. + paramcount = VolSetAttributes(volindex, params); + LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Add volume", "Parsing parameter string. Param count = \"%d\". String = \"%s\"", paramcount, params); + } + else + { + // No attributes set. + paramcount = 0; + } + + if (paramcount < 1) + { + Format(buffer, sizeof(buffer), "No additional attributes set."); + } + else + { + Format(buffer, sizeof(buffer), "Additional attributes set: %d", paramcount); + } + + ReplyToCommand(client, "Added volume at index %d. %s", volindex, buffer); + return Plugin_Handled; +} + +/** + * Command callback for removing a volume. + */ +public Action:VolRemoveVolumeCommand(client, argc) +{ + decl String:arg[16]; + new volindex; + + if (argc < 1) + { + // Write syntax info. + ReplyToCommand(client, "Removes an existing volume in the map. Usage: zr_vol_remove "); + return Plugin_Handled; + } + + // Get volume index. + GetCmdArg(1, arg, sizeof(arg)); + volindex = StringToInt(arg); + + // Validate index. + if (!VolIsValidIndex(volindex)) + { + ReplyToCommand(client, "Invalid volume index."); + return Plugin_Handled; + } + + // Check if volume exist. + if (!Volumes[volindex][Vol_InUse]) + { + ReplyToCommand(client, "Volume %d doesn't exist.", volindex); + return Plugin_Handled; + } + + // Remove volume. + VolRemove(volindex); + + ReplyToCommand(client, "Successfully disabled and removed volume %d.", volindex); + return Plugin_Handled; +} + +/** + * Command callback for listing volumes or dumping data. + */ +public Action:VolListCommand(client, argc) +{ + decl String:buffer[1022]; // Two chars reserved for newline and null terminator. + decl String:linebuffer[128]; + decl String:valuebuffer[32]; + decl String:arg[16]; + + buffer[0] = 0; + linebuffer[0] = 0; + + new volindex; + new volcount; + new volcache[VolumeAttributes]; + + if (argc < 1) + { + // No volume specified. Display syntax and list volumes. + StrCat(buffer, sizeof(buffer), "Lists existing volumes in the map, or dumps detail data to the specified volume. Usage: zr_vol_list [volume index]\n\n"); + StrCat(buffer, sizeof(buffer), "ID: Type: Min loc: Max loc:\n"); + StrCat(buffer, sizeof(buffer), "--------------------------------------------------------------------------------"); + ReplyToCommand(client, buffer); + + // Loop through all indexes. + for (volindex = 0; volindex < ZR_VOLUMES_MAX; volindex++) + { + // Check if in use. + if (Volumes[volindex][Vol_InUse]) + { + // Cache volume data. + volcache = Volumes[volindex]; + + // Add to list. + VolTypeToString(volcache[Vol_Type], valuebuffer, sizeof(valuebuffer), true); + Format(linebuffer, sizeof(linebuffer), "%-4d %-15s %-8.2f %-8.2f %-8.2f %-8.2f %-8.2f %-8.2f", + volindex, + valuebuffer, + volcache[Vol_xMin], + volcache[Vol_yMin], + volcache[Vol_zMin], + volcache[Vol_xMax], + volcache[Vol_yMax], + volcache[Vol_zMax]); + + ReplyToCommand(client, linebuffer); + volcount++; + } + } + + Format(linebuffer, sizeof(linebuffer), "\nTotal volumes: %d", volcount); + ReplyToCommand(client, linebuffer); + return Plugin_Handled; + } + else + { + // Dump data for the specified volume. + + // Get volume index. + GetCmdArg(1, arg, sizeof(arg)); + volindex = StringToInt(arg); + + // Validate index. + if (!VolIsValidIndex(volindex)) + { + ReplyToCommand(client, "The specified volume index is invalid: %d", volindex); + return Plugin_Handled; + } + + // Check if unused. + if (!VolInUse(volindex)) + { + ReplyToCommand(client, "The specified volume doesn't exist: %d.", volindex); + return Plugin_Handled; + } + + // Cache volume data. + volcache = Volumes[volindex]; + + // Dump generic volume data. + Format(linebuffer, sizeof(linebuffer), "Volume data at index %d:\n", volindex); + StrCat(buffer, sizeof(buffer), linebuffer); + StrCat(buffer, sizeof(buffer), "--------------------------------------------------------------------------------"); + ReplyToCommand(client, buffer); + + // Clear buffer. + buffer[0] = 0; + + Format(linebuffer, sizeof(linebuffer), "ID: %d\n", volindex); + StrCat(buffer, sizeof(buffer), linebuffer); + + Format(linebuffer, sizeof(linebuffer), "Enabled: %d\n", volcache[Vol_Enabled]); + StrCat(buffer, sizeof(buffer), linebuffer); + + VolTypeToString(volcache[Vol_Type], valuebuffer, sizeof(valuebuffer)); + Format(linebuffer, sizeof(linebuffer), "Type: %s\n", valuebuffer); + StrCat(buffer, sizeof(buffer), linebuffer); + + Format(linebuffer, sizeof(linebuffer), "Min loc: %-8.2f %-8.2f %-8.2f\n", volcache[Vol_xMin], volcache[Vol_yMin], volcache[Vol_zMin]); + StrCat(buffer, sizeof(buffer), linebuffer); + + Format(linebuffer, sizeof(linebuffer), "Max loc: %-8.2f %-8.2f %-8.2f\n", volcache[Vol_xMax], volcache[Vol_yMax], volcache[Vol_zMax]); + StrCat(buffer, sizeof(buffer), linebuffer); + + VolEffectToString(volcache[Vol_Effect], valuebuffer, sizeof(valuebuffer)); + Format(linebuffer, sizeof(linebuffer), "Effect: %s\n", valuebuffer); + StrCat(buffer, sizeof(buffer), linebuffer); + + Format(linebuffer, sizeof(linebuffer), "Effect color: %d, %d, %d\n", volcache[Vol_EffectColor][0], volcache[Vol_EffectColor][1], volcache[Vol_EffectColor][2]); + StrCat(buffer, sizeof(buffer), linebuffer); + + VolTeamToString(volcache[Vol_TeamFilter], valuebuffer, sizeof(valuebuffer)); + Format(linebuffer, sizeof(linebuffer), "Team filter: %s\n", valuebuffer); + StrCat(buffer, sizeof(buffer), linebuffer); + + Format(linebuffer, sizeof(linebuffer), "Trigger delay: %.2f", volcache[Vol_TriggerDelay]); + StrCat(buffer, sizeof(buffer), linebuffer); + + // Print generic attributes. + ReplyToCommand(client, buffer); + + // Clear buffer. + buffer[0] = 0; + + // Get type spesific attributes. + switch (volcache[Vol_Type]) + { + case VolFeature_Anticamp: + { + VolAnticampDumpData(volcache[Vol_DataIndex], buffer, sizeof(buffer)); + } + case VolFeature_Knockback: + { + + } + } + + // Print type spesific attributes if any. + if (strlen(buffer) > 0) + { + ReplyToCommand(client, buffer); + } + + return Plugin_Handled; + } +} + +public Action:VolDumpStatesCommand(client, argc) +{ + decl String:target[64]; + new targetclient; + + if (argc < 1) + { + ReplyToCommand(client, "Dumps volume states for the specified player. Usage: zr_vol_dumpstates "); + return Plugin_Handled; + } + + // Get target. + GetCmdArg(1, target, sizeof(target)); + targetclient = FindTarget(client, target); + + // Validate target. + if (targetclient <= 0) + { + // Note: FindTarget automatically print error messages. + return Plugin_Handled; + } + + // Print header. + ReplyToCommand(client, "Volume ID: Player in volume:\n----------------------------------------"); + + // Get player states. + new bool:statebuffer[ZR_VOLUMES_MAX]; + VolGetPlayerStates(targetclient, statebuffer, sizeof(statebuffer)); + + // Set language. + SetGlobalTransTarget(client); + + // Loop through each volume. + for (new volumeindex = 0; volumeindex < ZR_VOLUMES_MAX; volumeindex++) + { + // Check if volume is in use. + if (VolInUse(volumeindex)) + { + // Dump state. + ReplyToCommand(client, "%-11d %t", volumeindex, statebuffer[volumeindex] ? "Yes" : "No"); + } + } + + return Plugin_Handled; } /** @@ -59,6 +483,7 @@ public Action:VolAddVolumeCommand(client, argc) * * Note: Extra volume attributes must be set using VolSetAttributes. * + * @param index Optional. Add volume at the specified index. * @param locMin Minimum x, y and z values. * @param locMax Maximum x, y and z values. * @param volumeType Specifies the volumetric feature type. @@ -66,39 +491,43 @@ public Action:VolAddVolumeCommand(client, argc) * * @return The new volume index, or -1 if failed. */ -VolAdd(Float:locMin[3], Float:locMax[3], VolumeFeatureTypes:volumeType, dataIndex) +VolAdd(volumeIndex = -1, Float:locMin[3], Float:locMax[3], VolumeFeatureTypes:volumeType, dataIndex) { - new volumeIndex; - - // Get a free volume index. - volumeIndex = VolGetFreeVolume(); + if (volumeIndex < 0) + { + // Get a free volume index. + volumeIndex = VolGetFreeVolume(); + } // Validate index. - if (volumeIndex >= 0) + if (VolIsValidIndex(volumeIndex)) { // Mark volume as enabled and in use. - Volumes[volumeIndex][vol_enabled] = true; - Volumes[volumeIndex][vol_in_use] = true; + Volumes[volumeIndex][Vol_Enabled] = true; + Volumes[volumeIndex][Vol_InUse] = true; // Set location data. - Volumes[volumeIndex][vol_x_min] = locMin[0]; - Volumes[volumeIndex][vol_y_min] = locMin[1]; - Volumes[volumeIndex][vol_z_min] = locMin[2]; + Volumes[volumeIndex][Vol_xMin] = locMin[0]; + Volumes[volumeIndex][Vol_yMin] = locMin[1]; + Volumes[volumeIndex][Vol_zMin] = locMin[2]; - Volumes[volumeIndex][vol_x_max] = locMax[0]; - Volumes[volumeIndex][vol_y_max] = locMax[1]; - Volumes[volumeIndex][vol_z_max] = locMax[2]; + Volumes[volumeIndex][Vol_xMax] = locMax[0]; + Volumes[volumeIndex][Vol_yMax] = locMax[1]; + Volumes[volumeIndex][Vol_zMax] = locMax[2]; // Set type. - Volumes[volumeIndex][vol_type] = volumeType; - Volumes[volumeIndex][vol_data_index] = dataIndex; + Volumes[volumeIndex][Vol_Type] = volumeType; + Volumes[volumeIndex][Vol_DataIndex] = dataIndex; + + // Update number of volumes. + VolumeCount++; // Return the new index. return volumeIndex; } else { - // No free volumes. + // No free volumes or invalid index. return -1; } } @@ -112,14 +541,22 @@ VolAdd(Float:locMin[3], Float:locMax[3], VolumeFeatureTypes:volumeType, dataInde bool:VolRemove(volumeIndex) { // Validate index. - if (volumeIndex >= 0) + if (VolIsValidIndex(volumeIndex)) { - // Trigger event. - VolOnVolumeDisabled(volumeIndex); + // Trigger event to clean up data and stop timers. + VolOnDisabled(volumeIndex); - // Mark volume as disabled and unused. - Volumes[volumeIndex][vol_enabled] = false; - Volumes[volumeIndex][vol_in_use] = false; + // Clear feature data. + switch (Volumes[volumeIndex][Vol_Type]) + { + case VolFeature_Anticamp: + { + VolAnticampReset(Volumes[volumeIndex][Vol_DataIndex]); + } + } + + // Clear volume data. + VolClear(volumeIndex); return true; } @@ -130,6 +567,31 @@ bool:VolRemove(volumeIndex) } } +/** + * Clears volume data at the specified index. + * + * @param volumeIndex The volume index. + */ +VolClear(volumeIndex) +{ + Volumes[volumeIndex][Vol_Enabled] = false; + Volumes[volumeIndex][Vol_InUse] = false; + + Volumes[volumeIndex][Vol_xMin] = 0.0; + Volumes[volumeIndex][Vol_yMin] = 0.0; + Volumes[volumeIndex][Vol_zMin] = 0.0; + + Volumes[volumeIndex][Vol_xMax] = 0.0; + Volumes[volumeIndex][Vol_yMax] = 0.0; + Volumes[volumeIndex][Vol_zMax] = 0.0; + + Volumes[volumeIndex][Vol_Type] = VolFeature_Invalid; + Volumes[volumeIndex][Vol_DataIndex] = -1; + + Volumes[volumeIndex][Vol_TeamFilter] = VolTeam_All; + Volumes[volumeIndex][Vol_TriggerDelay] = 0.0; +} + /** * Sets extra attributes on a volume. * @@ -142,6 +604,8 @@ VolSetAttributes(volumeIndex, const String:attributes[]) { new attribCount; new successfulCount; + new VolumeFeatureTypes:voltype; + new dataindex; decl String:attribName[64]; decl String:attribValue[256]; @@ -160,8 +624,14 @@ VolSetAttributes(volumeIndex, const String:attributes[]) return -1; } + // Get volumetric feature type. + voltype = Volumes[volumeIndex][Vol_Type]; + + // Get feature data index. + dataindex = Volumes[volumeIndex][Vol_DataIndex]; + // Loop through all attributes. - for (new attrib = 0; attrib > attribCount; attrib++) + for (new attrib = 0; attrib < attribCount; attrib++) { // Get attribute name. GetParameterName(attribName, sizeof(attribName), attributes, attrib); @@ -169,8 +639,10 @@ VolSetAttributes(volumeIndex, const String:attributes[]) // Get attribute value. GetParameterValue(attribValue, sizeof(attribValue), attributes, attribName); - // Check names and set volume attributes. - if (strcmp(attribName, "team", false)) + LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Set attribute", "Got parameter: \"%s\" = \"%s\"", attribName, attribValue); + + // Check generic attributes. + if (StrEqual(attribName, "teamfilter", false)) { // Parse team string value. if (VolSetTeamString(volumeIndex, attribValue)) @@ -178,7 +650,7 @@ VolSetAttributes(volumeIndex, const String:attributes[]) successfulCount++; } } - else if (strcmp(attribName, "delay", false)) + else if (StrEqual(attribName, "delay", false)) { // Parse delay string value. if (VolSetDelayString(volumeIndex, attribValue)) @@ -186,7 +658,7 @@ VolSetAttributes(volumeIndex, const String:attributes[]) successfulCount++; } } - else if (strcmp(attribName, "effect", false)) + else if (StrEqual(attribName, "effect", false)) { // Parse effect string value. if (VolSetEffectString(volumeIndex, attribValue)) @@ -194,7 +666,7 @@ VolSetAttributes(volumeIndex, const String:attributes[]) successfulCount++; } } - else if (strcmp(attribName, "effect_color", false)) + else if (StrEqual(attribName, "effect_color", false)) { // Parse effect color string value. if (VolSetEffectColorString(volumeIndex, attribValue)) @@ -202,7 +674,7 @@ VolSetAttributes(volumeIndex, const String:attributes[]) successfulCount++; } } - else if (strcmp(attribName, "enabled", false)) + else if (StrEqual(attribName, "enabled", false)) { // Parse enabled string value. if (VolSetEnabledString(volumeIndex, attribValue)) @@ -210,16 +682,23 @@ VolSetAttributes(volumeIndex, const String:attributes[]) successfulCount++; } } + + // Pass attribute onto the volumetric feature attribute handler. + else + { + switch (voltype) + { + case VolFeature_Anticamp: + { + if (VolAnticampSetAttribute(dataindex, attribName, attribValue)) + { + successfulCount++; + } + } + } + } } // Return number of successfully attributes set. return successfulCount; } - -/** - * Creates commands for managing volumes. - */ -VolOnCommandsCreate() -{ - RegAdminCmd("zr_vol_add", VolAddVolumeCommand, ADMFLAG_GENERIC, "Adds a new volume. Usage: zr_vol_add [params]"); -} diff --git a/src/zr/volfeatures/volevents.inc b/src/zr/volfeatures/volevents.inc index 3531c3d..33f1398 100644 --- a/src/zr/volfeatures/volevents.inc +++ b/src/zr/volfeatures/volevents.inc @@ -39,9 +39,11 @@ VolOnPlayerEnter(client, volumeIndex) // Volumetric features disabled. return; } - + + LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Event", "Player %N entered volume %d.", client, volumeIndex); + // Forward event to features. - // VolAnticampStart(client, volume); + } /** @@ -59,8 +61,10 @@ VolOnPlayerLeave(client, volumeIndex) return; } + LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Event", "Player %N left volume %d.", client, volumeIndex); + // Forward event to features. - // VolAnticampStop(client, volume); + } /** @@ -106,6 +110,9 @@ VolOnRoundStart() // Start main timer. VolStartUpdateTimer(); + + // Start volumes. + VolEnableVolumes(); } /** @@ -116,26 +123,42 @@ VolOnRoundEnd() // Stop main timer. VolStopUpdateTimer(); - // Forward stop event to features. - // VolAnticampStop(); + // Stop volumes. + VolDisableVolumes(); } /** * Called when a volume is disabled. * @param volumeIndex The volume index. */ -VolOnVolumeDisabled(volumeIndex) +VolOnDisabled(volumeIndex) { - // Forward stop event to features. + new VolumeFeatureTypes:voltype = Volumes[volumeIndex][Vol_Type]; + // Forward stop event to features. + switch (voltype) + { + case VolFeature_Anticamp: + { + VolAnticampDisable(volumeIndex); + } + } } /** * Called when a volume is enabled. * @param volumeIndex The volume index. */ -VolOnVolumeEnabled(volumeIndex) +VolOnEnabled(volumeIndex) { - // Forward start event to features. + new VolumeFeatureTypes:voltype = Volumes[volumeIndex][Vol_Type]; + // Forward stop event to features. + switch (voltype) + { + case VolFeature_Anticamp: + { + VolAnticampEnable(volumeIndex); + } + } } diff --git a/src/zr/volfeatures/volfeatures.inc b/src/zr/volfeatures/volfeatures.inc index f0192d7..1f67dfd 100644 --- a/src/zr/volfeatures/volfeatures.inc +++ b/src/zr/volfeatures/volfeatures.inc @@ -36,30 +36,30 @@ enum VolumeAttributes { /* General */ - bool:vol_enabled, /** Volume state. */ - bool:vol_in_use, /** Marks if the volume is used. */ + bool:Vol_Enabled, /** Volume state. */ + bool:Vol_InUse, /** Marks if the volume is used. */ /* Location */ - Float:vol_x_min, /** Minimum x position. */ - Float:vol_x_max, /** Maximum x position. */ + Float:Vol_xMin, /** Minimum x position. */ + Float:Vol_xMax, /** Maximum x position. */ - Float:vol_y_min, /** Minimum y position. */ - Float:vol_y_max, /** Maximum y position. */ + Float:Vol_yMin, /** Minimum y position. */ + Float:Vol_yMax, /** Maximum y position. */ - Float:vol_z_min, /** Minimum z position. */ - Float:vol_z_max, /** Maximum z position. */ + Float:Vol_zMin, /** Minimum z position. */ + Float:Vol_zMax, /** Maximum z position. */ /* Style */ - VolumeEffects:vol_effect, /** Visual effect to apply on the volume. */ - vol_effect_color[3], /** Render color of the effect. RGB colors. */ + VolumeEffects:Vol_Effect, /** Visual effect to apply on the volume. */ + Vol_EffectColor[3], /** Render color of the effect. RGB colors. */ /* Data */ - VolumeFeatureTypes:vol_type, /** The volumetric feature type. */ - vol_data_index, /** Index in remote feature array. */ + VolumeFeatureTypes:Vol_Type, /** The volumetric feature type. */ + Vol_DataIndex, /** Index in remote feature array. */ /* Behaviour */ - VolumeTeamFilters:vol_team_filter, /** Team filtering. Trigger by certain teams, or all. */ - Float:vol_trigger_delay /** Trigger delay. How many seconds players have to stay to trigger volume events. */ + VolumeTeamFilters:Vol_TeamFilter, /** Team filtering. Trigger by certain teams, or all. */ + Float:Vol_TriggerDelay /** Trigger delay. How many seconds players have to stay to trigger volume events. */ } /** @@ -67,7 +67,8 @@ enum VolumeAttributes */ enum VolumeFeatureTypes { - VolFeature_Anticamp = 0, + VolFeature_Invalid = 0, + VolFeature_Anticamp, VolFeature_Knockback } @@ -106,6 +107,11 @@ new VolumeCount; */ new Float:VolPlayerLoc[MAXPLAYERS + 1][3]; +/** + * Cache that specifies if a player is in a volume or not. + */ +new bool:VolPlayerInVolume[MAXPLAYERS + 1][ZR_VOLUMES_MAX]; + /** * Specifies whether the volumetric features module is enabled or not. Synced * with zr_vol CVAR. @@ -121,7 +127,7 @@ new Float:VolPlayerCountDown[MAXPLAYERS + 1][ZR_VOLUMES_MAX]; * The handle for a timer that updates player locations. This is the main timer * and any feature events can't be updated faster than this interval. * - * Note: Some features may have its own timer. + * Note: Some features may have its own timer for actions on players. */ new Handle:hVolUpdateTimer; @@ -138,6 +144,8 @@ new Float:VolTriggerInterval; #include "zr/volfeatures/volevents" #include "zr/volfeatures/volgenericattributes" #include "zr/volfeatures/volcommands" + +// Sub features. #include "zr/volfeatures/volanticamp" @@ -148,6 +156,9 @@ VolLoad() { // Cache CVAR value. VolEnabled = GetConVarBool(g_hCvarsList[CVAR_VOL]); + + // Initialize sub features. + VolAnticampInit(); } /** @@ -157,8 +168,51 @@ VolDisable() { VolEnabled = false; VolStopUpdateTimer(); + VolDisableVolumes(); - // TODO: Send disable/stop event to volumes with their own timers. + LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Disabled", "Volfeatures disabled."); +} + +/** + * Function alias for starting volumetric features. + */ +VolEnable() +{ + VolEnabled = true; + VolStartUpdateTimer(); + VolEnableVolumes(); + + LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Enabled", "Volfeatures enabled."); +} + +/** + * Disables all enabled volumes. + */ +VolDisableVolumes() +{ + // Trigger disable event on all enabled volumes in use. + for (new volindex = 0; volindex < ZR_VOLUMES_MAX; volindex++) + { + if (Volumes[volindex][Vol_InUse] && Volumes[volindex][Vol_Enabled]) + { + VolOnDisabled(volindex); + } + } +} + +/** + * Enables all disabled volumes. + */ +VolEnableVolumes() +{ + // Trigger enable event on all volumes in use. + for (new volindex = 0; volindex < ZR_VOLUMES_MAX; volindex++) + { + if (Volumes[volindex][Vol_InUse] && !Volumes[volindex][Vol_Enabled]) + { + VolOnEnabled(volindex); + } + } } /** @@ -195,7 +249,8 @@ bool:VolStartUpdateTimer() } else { - // Volumetric features disabled. + // Volumetric features disabled. + LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Volfeatures, "Config Validation", "Warning: Console variable \"zr_vol_update_interval\" is set to zero or negative. Must be positive."); return false; } } @@ -236,7 +291,7 @@ bool:VolStartTriggerTimer() if (VolTriggerInterval > 0.0) { // Start the timer. - hVolTriggerTimer = CreateTimer(VolTriggerInterval, Event_VolUpdateTimer, _, TIMER_REPEAT); + hVolTriggerTimer = CreateTimer(VolTriggerInterval, Event_VolTriggerTimer, _, TIMER_REPEAT); // Trigger timer started. return true; @@ -244,6 +299,7 @@ bool:VolStartTriggerTimer() else { // Trigger timer not running. Either disabled or invalid interval. + LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Volfeatures, "Config Validation", "Warning: Console variable \"zr_vol_trigger_interval\" is set to zero or negative. Must be positive."); return false; } } @@ -302,7 +358,7 @@ VolResetCountDown(client = -1) */ VolUpdatePlayerLocation(client = -1) { - if (client <= 0) + if (client > 0) { // Assume the client is valid and save location in array. GetClientAbsOrigin(client, VolPlayerLoc[client]); @@ -343,10 +399,11 @@ VolUpdatePlayerChanges() // Check if client is in game and alive. if (!IsClientConnected(client) || !IsClientInGame(client) || !IsPlayerAlive(client)) { - return; + // Skip client. + continue; } - // Get the current volume states. + // Get the current volume states based on player location cache. VolGetPlayerStates(client, volumeStates, sizeof(volumeStates)); // Update player location cache. @@ -356,23 +413,37 @@ VolUpdatePlayerChanges() VolGetPlayerStates(client, volumeNewStates, sizeof(volumeNewStates)); // Loop through each volume and compare states. - for (new volumeIndex = 0; volumeIndex < VolumeCount; volumeIndex++) + for (new volumeIndex = 0; volumeIndex < ZR_VOLUMES_MAX; volumeIndex++) { + // Check if the volume is disabled and unused. + if (!VolInUse(volumeIndex) || !VolIsEnabled(volumeIndex)) + { + // Skip volume. + continue; + } + + // Check team filtering on the volume. + if (!VolTeamFilterMatch(client, volumeIndex)) + { + // Team filter mismatch. + continue; + } + newState = volumeNewStates[volumeIndex]; oldState = volumeStates[volumeIndex]; - // Compare new states with old states. + // Check for no change. if (newState == oldState) { // No change. Skip to next volume. - break; + continue; } // Check if client entered the volume. - else if (!newState && oldState) + if (newState && !oldState) { // Get trigger delay value. - trigger_delay = Volumes[volumeIndex][vol_trigger_delay]; + trigger_delay = Volumes[volumeIndex][Vol_TriggerDelay]; // Check if the volume has a trigger delay. if (trigger_delay > 0.0) @@ -382,17 +453,23 @@ VolUpdatePlayerChanges() } else { + // Update cache. + VolPlayerInVolume[client][volumeIndex] = true; + // No trigger delay, trigger event instantly. VolOnPlayerEnter(client, volumeIndex); } } // Check if client left the volume. - else if (newState && !oldState) + else if (!newState && oldState) { // Make sure count down value is reset. VolPlayerCountDown[client][volumeIndex] = -1.0; + // Update cache. + VolPlayerInVolume[client][volumeIndex] = false; + // Trigger event. VolOnPlayerLeave(client, volumeIndex); } @@ -401,20 +478,20 @@ VolUpdatePlayerChanges() } /** - * Returns wether a position is within a certain location. + * Returns wether a point is within a certain location. * - * @param loc The position to check. + * @param point The point to check. * @param min Minimum x, y and z values of the location. * @param max Maximum x, y and z values of the location. * @return True if the position is within min and max values. False * otherwise. */ -bool:IsPositionInLocation(Float:pos[3], Float:min[3], Float:max[3]) +bool:IsPointInLocation(Float:point[3], Float:min[3], Float:max[3]) { - // Cache location to avoid re-indexing arrays. - new Float:posX = pos[0]; - new Float:posY = pos[1]; - new Float:posZ = pos[2]; + // Cache to avoid re-indexing arrays. + new Float:posX = point[0]; + new Float:posY = point[1]; + new Float:posZ = point[2]; // Check if within x boundaries. if ((posX >= min[0]) && (posX <= max[0])) @@ -425,13 +502,13 @@ bool:IsPositionInLocation(Float:pos[3], Float:min[3], Float:max[3]) // Check if within x boundaries. if ((posZ >= min[2]) && (posZ <= max[2])) { - // The player is within the location boundaries. + // The point is within the location boundaries. return true; } } } - // The player is outside the location boundaries. + // The point is outside the location boundaries. return false; } @@ -443,9 +520,22 @@ bool:IsPositionInLocation(Float:pos[3], Float:min[3], Float:max[3]) * @param volumeIndex The volume index. * @return True if in use, false otherwise. */ -bool:VolIsInUse(volumeIndex) +bool:VolInUse(volumeIndex) { - return Volumes[volumeIndex][vol_in_use]; + return Volumes[volumeIndex][Vol_InUse]; +} + +/** + * Returns wether a volume is enabled or not. + * + * Note: Does not validate index. + * + * @param volumeIndex The volume index. + * @return True if enabled, false otherwise. + */ +bool:VolIsEnabled(volumeIndex) +{ + return Volumes[volumeIndex][Vol_Enabled]; } /** @@ -478,7 +568,7 @@ VolGetFreeVolume() for (new volumeIndex = 0; volumeIndex < ZR_VOLUMES_MAX; volumeIndex++) { // Check if it's free. - if (!VolIsInUse(volumeIndex)) + if (!VolInUse(volumeIndex)) { return volumeIndex; } @@ -488,6 +578,69 @@ VolGetFreeVolume() return -1; } +/** + * Gets a free index in the data array for the specified volume type. + * + * @param volumeType Volumetric feature type. + * @return Data index, or -1 on error. + */ +VolGetFreeDataIndex(VolumeFeatureTypes:volumeType) +{ + switch (volumeType) + { + case VolFeature_Anticamp: + { + return VolAnticampGetFreeIndex(); + } + case VolFeature_Knockback: + { + // TOTO: Finish incomplete feature. + return -1; + } + } + + // No match. + return -1; +} + +/** + * Checks if the specified client match the team filtering for the specified + * volume. + * + * @param client The client index. + * @param volumeIndex The volume to check team filtering on. + * @return True if client pass the team filtering, false otherwise. + */ +bool:VolTeamFilterMatch(client, volumeIndex) +{ + new VolumeTeamFilters:filter; + + // Chache filter value. + filter = Volumes[volumeIndex][Vol_TeamFilter]; + + switch (filter) + { + case VolTeam_All: + { + // All maches everyone. + return true; + } + case VolTeam_Humans: + { + // Check if client is a human. + return InfectIsClientHuman(client); + } + case VolTeam_Zombies: + { + // Check if client is a zombie. + return InfectIsClientInfected(client); + } + } + + // Invalid filter value. + return false; +} + /** * Gets wether a client is within volumes or not. Result is stored in a boolean * array. @@ -506,25 +659,25 @@ VolGetPlayerStates(client, bool:buffer[], maxlen) new Float:volMaxBuffer[3]; // Loop through all available volumes. - for (new volumeIndex = 0; volumeIndex < VolumeCount && volumeIndex < maxlen; volumeIndex++) + for (new volumeIndex = 0; volumeIndex < ZR_VOLUMES_MAX && volumeIndex < maxlen; volumeIndex++) { - if (VolIsInUse(volumeIndex)) + if (VolInUse(volumeIndex)) { // Chache volume to avoid re-indexing. volumeBuffer = Volumes[volumeIndex]; // Get min positions. - volMinBuffer[0] = volumeBuffer[vol_x_min]; - volMinBuffer[1] = volumeBuffer[vol_y_min]; - volMinBuffer[2] = volumeBuffer[vol_z_min]; + volMinBuffer[0] = volumeBuffer[Vol_xMin]; + volMinBuffer[1] = volumeBuffer[Vol_yMin]; + volMinBuffer[2] = volumeBuffer[Vol_zMin]; // Get max positions. - volMaxBuffer[0] = volumeBuffer[vol_x_min]; - volMaxBuffer[1] = volumeBuffer[vol_y_min]; - volMaxBuffer[2] = volumeBuffer[vol_z_min]; + volMaxBuffer[0] = volumeBuffer[Vol_xMax]; + volMaxBuffer[1] = volumeBuffer[Vol_yMax]; + volMaxBuffer[2] = volumeBuffer[Vol_zMax]; // Check the cached player location. - if (IsPositionInLocation(VolPlayerLoc[client], volMinBuffer, volMaxBuffer)) + if (IsPointInLocation(VolPlayerLoc[client], volMinBuffer, volMaxBuffer)) { // Mark player as in volume. buffer[volumeIndex] = true; @@ -541,6 +694,65 @@ VolGetPlayerStates(client, bool:buffer[], maxlen) return volCount; } +/** + * Converts a string into a volumetric feature type. + * + * @param volType String to convert. Name of type. + * @return Volumetric feature type or VolFeature_Invalid on error. + */ +VolumeFeatureTypes:VolGetTypeFromString(const String:volType[]) +{ + // Check if empty. + if (strlen(volType) == 0) + { + return VolFeature_Invalid; + } + + // Match types. + if (StrEqual(volType, "anticamp", false)) + { + return VolFeature_Anticamp; + } + else if (StrEqual(volType, "knockback", false)) + { + return VolFeature_Knockback; + } + + // No match. + return VolFeature_Invalid; +} + +/** + * Converts a volume type to a string. + * + * @param volType Volume type to convert. + * @param buffer Destination string buffer. + * @param maxlen Size of destination buffer. + * @param shortName Optional. Write short name or human readable name. + * Default is human readable (false). + * @return Number of cells written. + */ +VolTypeToString(VolumeFeatureTypes:volType, String:buffer[], maxlen, bool:shortName = false) +{ + switch (volType) + { + case VolFeature_Invalid: + { + return shortName ? strcopy(buffer, maxlen, "") : strcopy(buffer, maxlen, "(none)"); + } + case VolFeature_Anticamp: + { + return shortName ? strcopy(buffer, maxlen, "anticamp") : strcopy(buffer, maxlen, "Anti camp"); + } + case VolFeature_Knockback: + { + return shortName ? strcopy(buffer, maxlen, "knockback") : strcopy(buffer, maxlen, "Knock back modifier"); + } + } + + return 0; +} + /** * Callback for update timer. This is the main timer in volumetric features. */ @@ -562,6 +774,13 @@ public Action:Event_VolTriggerTimer(Handle:timer) // Loop through all volumes. for (new volumeIndex = 0; volumeIndex < ZR_VOLUMES_MAX; volumeIndex++) { + // Check if volume is in use and enabled. + if (!VolInUse(volumeIndex) || !VolIsEnabled(volumeIndex)) + { + // Not in use or enabled, skip volume. + continue; + } + // Get count down value. countDown = VolPlayerCountDown[client][volumeIndex]; @@ -571,15 +790,21 @@ public Action:Event_VolTriggerTimer(Handle:timer) // Substract by trigger interval. countDown -= VolTriggerInterval; - // Check if zero or below. + // Check if time is up. if (countDown <= 0.0) { + // Update cache. + VolPlayerInVolume[client][volumeIndex] = true; + // Trigger volume enter event. VolOnPlayerEnter(client, volumeIndex); // Reset count down value. VolPlayerCountDown[client][volumeIndex] = -1.0; } + + // Update count down value and continue. + VolPlayerCountDown[client][volumeIndex] = countDown; } } } @@ -595,10 +820,7 @@ public VolEnabledChanged(Handle:cvar, const String:oldvalue[], const String:newv if (isEnabled) { // Volumetric features is enabled. - VolEnabled = true; - - // Start timers. - VolStartUpdateTimer(); + VolEnable(); } else { diff --git a/src/zr/volfeatures/volgenericattributes.inc b/src/zr/volfeatures/volgenericattributes.inc index 461665a..3632b1d 100644 --- a/src/zr/volfeatures/volgenericattributes.inc +++ b/src/zr/volfeatures/volgenericattributes.inc @@ -44,21 +44,21 @@ stock bool:VolSetTeamString(volumeIndex, const String:team[]) } // Convert value. - if (strcmp(team, "all", false)) + if (StrEqual(team, "all", false)) { teamfilter = VolTeam_All; } - else if (strcmp(team, "humans", false)) + else if (StrEqual(team, "humans", false)) { teamfilter = VolTeam_Humans; } - else if (strcmp(team, "zombies", false)) + else if (StrEqual(team, "zombies", false)) { teamfilter = VolTeam_Zombies; } // Apply value. - Volumes[volumeIndex][vol_team_filter] = teamfilter; + Volumes[volumeIndex][Vol_TeamFilter] = teamfilter; return true; } @@ -71,7 +71,38 @@ stock bool:VolSetTeamString(volumeIndex, const String:team[]) */ stock VolSetTeam(volumeIndex, VolumeTeamFilters:team[]) { - Volumes[volumeIndex][vol_team_filter] = team; + Volumes[volumeIndex][Vol_TeamFilter] = team; +} + +/** + * Converts a team name type to a string. + * + * @param team Team type to convert. + * @param buffer Destination string buffer. + * @param maxlen Size of destination buffer. + * @param shortName Optional. Write short name or human readable name. + * Default is human readable (false). + * @return Number of cells written. + */ +stock VolTeamToString(VolumeTeamFilters:team, String:buffer[], maxlen, bool:shortName = false) +{ + switch (team) + { + case VolTeam_All: + { + return shortName ? strcopy(buffer, maxlen, "all") : strcopy(buffer, maxlen, "All"); + } + case VolTeam_Humans: + { + return shortName ? strcopy(buffer, maxlen, "humans") : strcopy(buffer, maxlen, "Humans"); + } + case VolTeam_Zombies: + { + return shortName ? strcopy(buffer, maxlen, "zombies") : strcopy(buffer, maxlen, "Zombies"); + } + } + + return 0; } /** @@ -96,7 +127,7 @@ stock bool:VolSetDelayString(volumeIndex, const String:delay[]) triggerdelay = StringToFloat(delay); // Apply value. - Volumes[volumeIndex][vol_trigger_delay] = triggerdelay; + Volumes[volumeIndex][Vol_TriggerDelay] = triggerdelay; return true; } @@ -108,7 +139,7 @@ stock bool:VolSetDelayString(volumeIndex, const String:delay[]) */ stock VolSetDelay(volumeIndex, Float:delay) { - Volumes[volumeIndex][vol_trigger_delay] = delay; + Volumes[volumeIndex][Vol_TriggerDelay] = delay; } /** @@ -128,19 +159,19 @@ stock bool:VolSetEffectString(volumeIndex, const String:effect[]) } // Check effect string values and apply them to the volume. - if (strcmp(effect, "none", false)) + if (StrEqual(effect, "none", false)) { - Volumes[volumeIndex][vol_effect] = VolEffect_None; + Volumes[volumeIndex][Vol_Effect] = VolEffect_None; return true; } - else if (strcmp(effect, "wireframe", false)) + else if (StrEqual(effect, "wireframe", false)) { - Volumes[volumeIndex][vol_effect] = VolEffect_Wireframe; + Volumes[volumeIndex][Vol_Effect] = VolEffect_Wireframe; return true; } - else if (strcmp(effect, "smoke", false)) + else if (StrEqual(effect, "smoke", false)) { - Volumes[volumeIndex][vol_effect] = VolEffect_Smoke; + Volumes[volumeIndex][Vol_Effect] = VolEffect_Smoke; return true; } @@ -156,7 +187,38 @@ stock bool:VolSetEffectString(volumeIndex, const String:effect[]) */ stock VolSetEffect(volumeIndex, VolumeEffects:effect) { - Volumes[volumeIndex][vol_effect] = effect; + Volumes[volumeIndex][Vol_Effect] = effect; +} + +/** + * Converts a volume effect type to a string. + * + * @param effect Effect type to convert. + * @param buffer Destination string buffer. + * @param maxlen Size of destination buffer. + * @param shortName Optional. Write short name or human readable name. + * Default is human readable (false). + * @return Number of cells written. + */ +stock VolEffectToString(VolumeEffects:effect, String:buffer[], maxlen, bool:shortName = false) +{ + switch (effect) + { + case VolEffect_None: + { + return shortName ? strcopy(buffer, maxlen, "none") : strcopy(buffer, maxlen, "No effect"); + } + case VolEffect_Wireframe: + { + return shortName ? strcopy(buffer, maxlen, "wireframe") : strcopy(buffer, maxlen, "Wire frame"); + } + case VolEffect_Smoke: + { + return shortName ? strcopy(buffer, maxlen, "smoke") : strcopy(buffer, maxlen, "Smoke"); + } + } + + return 0; } /** @@ -187,9 +249,9 @@ stock bool:VolSetEffectColorString(volumeIndex, const String:effect_color[]) blue = StringToInt(colors[2]); // Apply values. - Volumes[volumeIndex][vol_effect_color][0] = red; - Volumes[volumeIndex][vol_effect_color][1] = green; - Volumes[volumeIndex][vol_effect_color][2] = blue; + Volumes[volumeIndex][Vol_EffectColor][0] = red; + Volumes[volumeIndex][Vol_EffectColor][1] = green; + Volumes[volumeIndex][Vol_EffectColor][2] = blue; return true; } @@ -227,31 +289,31 @@ stock bool:VolSetEnabledString(volumeIndex, const String:enabled[]) new bool:val = bool:StringToInt(enabled); // Check yes or no values first. - if (strcmp(enabled, "yes", false) == 0) + if (StrEqual(enabled, "yes", false)) { val = true; } - else if (strcmp(enabled, "no", false) == 0) + else if (StrEqual(enabled, "no", false)) { val = false; } // Check if the new value is different from the current. - if (Volumes[volumeIndex][vol_enabled] != val) + if (Volumes[volumeIndex][Vol_Enabled] != val) { // Forward event. if (val) { - VolOnVolumeEnabled(volumeIndex); + VolOnEnabled(volumeIndex); } else { - VolOnVolumeDisabled(volumeIndex); + VolOnDisabled(volumeIndex); } } // Apply converted value. - Volumes[volumeIndex][vol_enabled] = val; + Volumes[volumeIndex][Vol_Enabled] = val; return true; } @@ -264,7 +326,7 @@ stock bool:VolSetEnabledString(volumeIndex, const String:enabled[]) stock VolSetEnabled(volumeIndex, bool:enabled) { // Check if the new value is different from the current. - if (Volumes[volumeIndex][vol_enabled] != enabled) + if (Volumes[volumeIndex][Vol_Enabled] != enabled) { // Forward event. if (enabled) @@ -277,5 +339,5 @@ stock VolSetEnabled(volumeIndex, bool:enabled) } } - Volumes[volumeIndex][vol_enabled] = enabled; + Volumes[volumeIndex][Vol_Enabled] = enabled; } From 8127a29235ca9e711c21205732af79f015176ecf Mon Sep 17 00:00:00 2001 From: richard Date: Thu, 16 Jul 2009 10:16:58 +0200 Subject: [PATCH 2/3] Updated compiler and SourceMod include files to version 1.2.1. --- bin/spcomp | Bin 357128 -> 357192 bytes src/include/clients.inc | 4 ++++ src/include/console.inc | 10 +++++----- src/include/menus.inc | 16 +++++++++++----- src/include/tf2.inc | 8 ++++++++ src/include/version.inc | 4 ++-- 6 files changed, 30 insertions(+), 12 deletions(-) diff --git a/bin/spcomp b/bin/spcomp index f52b14d7d05d01d9571658f88676f128181ab02a..904911d0c46b7319a5fa4e235b49dd00eb3fdbfe 100755 GIT binary patch delta 101192 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

@1%#^CW=-Mm;>iz^5q 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 delta 101223 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 Date: Fri, 17 Jul 2009 00:20:09 +0200 Subject: [PATCH 3/3] Fixed typo in docs. --- docs/zr_3.0_release_notes.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zr_3.0_release_notes.txt b/docs/zr_3.0_release_notes.txt index 97771e5..acd7ab8 100644 --- a/docs/zr_3.0_release_notes.txt +++ b/docs/zr_3.0_release_notes.txt @@ -80,7 +80,7 @@ warning is logged in the SourceMod error logs. The validation prevents unexpected or invalid behaviour in the plugin. Dealing with errors or warnings in error logs helps a lot troubleshooting eventual -eventual issues in the plugin caused by incorrect configurations. +issues in the plugin caused by incorrect configurations. It's also possible to specify the path of configuration files. This can be used in combination with map configs, so it's possible to have different