diff --git a/README.md b/README.md index 1bb82af..0385120 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,8 @@ A bunch of funmodes especially made for Zombie Escape - sm_funmodes_hud_channel - "The channel for the hud if using DynamicChannels" # Plugin Structure -- Each funmode will need to be included in Fun_Modes/Core.sp file, editing macros to include the funmode is required +- Each funmode will need to be included in Fun_Modes/Core/ModesInclude.sp file, The order matters. +- Each funmode will also need to be included in FunModes/Core/ModesDefinition for forwards. - You can remove any funmode you want from the Fun_Modes/ folder # Current FunModes Available diff --git a/addons/sourcemod/configs/FunModes/ConVars.cfg b/addons/sourcemod/configs/FunModes/ConVars.cfg new file mode 100644 index 0000000..66e5150 --- /dev/null +++ b/addons/sourcemod/configs/FunModes/ConVars.cfg @@ -0,0 +1,465 @@ +"FunModes_Cvars" +{ + "0" + { + "name" "sm_beacon_timer" + "Default" "20.000000" + "description" "The time that will start picking random players at round start" + } + "1" + { + "name" "sm_beacon_alert_timer" + "Default" "10.000000" + "description" "How much time in seconds the damage will start being applied from heal beacon as an alert for the other humans" + } + "2" + { + "name" "sm_beacon_damage" + "Default" "5.000000" + "description" "The damage that the heal beacon will give" + } + "3" + { + "name" "sm_beacon_heal" + "Default" "1" + "description" "How much heal beacon should heal the players in 1 second" + } + "4" + { + "name" "sm_healbeacon_randoms" + "Default" "2" + "description" "How many random players should get the heal beacon" + } + "5" + { + "name" "sm_healbeacon_distance" + "Default" "400.000000" + "description" "default distance of beacon to give" + } + "6" + { + "name" "sm_healbeacon_enable" + "Default" "1" + "description" "Enable/Disable HealBeacon mode." + } + "7" + { + "name" "sm_vipmode_timer" + "Default" "15" + "description" "After how many seconds from round start to pick VIP" + } + "8" + { + "name" "sm_vipmode_counter" + "Default" "3" + "description" "After how many seconds all the other humans will be slayed after the vip dies" + } + "9" + { + "name" "sm_vipmode_laser" + "Default" "1" + "description" "Don't Kill all humans when vip dies to a laser, 1 = Enabled, 0 = Disabled" + } + "10" + { + "name" "sm_vipmode_max_vips" + "Default" "1" + "description" "How many VIPs to be picked" + } + "11" + { + "name" "sm_vipmode_enable" + "Default" "1" + "description" "Enable/Disable the VIP Mode (This differes from turning it on/off)" + } + "12" + { + "name" "sm_fog_enable" + "Default" "1" + "description" "Enable/Disable Fog Mode (This differs from turning it on/off)" + } + "13" + { + "name" "sm_rlgl_time_between_damage" + "Default" "0.300000" + "description" "The timer interval for player to detect their movement" + } + "14" + { + "name" "sm_rlgl_freeze_time" + "Default" "5.000000" + "description" "How many seconds the movement detection should be disabled after" + } + "15" + { + "name" "sm_rlgl_time_between_redlights_min" + "Default" "20.000000" + "description" "After how many seconds to keep repeating the redlights (MIN VALUE)" + } + "16" + { + "name" "sm_rlgl_time_between_redlights_max" + "Default" "30.000000" + "description" "After how many seconds to keep repeating the redlights (MAX VALUE, SET TO 0 to disable min/max)" + } + "17" + { + "name" "sm_rlgl_damage" + "Default" "5.000000" + "description" "Damage to apply to the player that is moving while its a red light" + } + "18" + { + "name" "sm_rlgl_warning_time" + "Default" "8.000000" + "description" "Time in seconds to warn the players before red light is on" + } + "19" + { + "name" "sm_rlgl_zombies_speed" + "Default" "0.500000" + "description" "Zombies speed during red light, if set to 0 then it is disabled" + } + "20" + { + "name" "sm_rlgl_countdown_folder" + "Default" "zr/countdown/$.mp3" + "description" "Countdown folder and the files that can be used for sound" + } + "21" + { + "name" "sm_rlgl_enable" + "Default" "1" + "description" "Enable/Disable the RLGL Mode (This differes from turning it on/off)" + } + "22" + { + "name" "sm_doublejump_boost" + "Default" "260.000000" + "description" "The amount of vertical boost to apply to double jumps." + } + "23" + { + "name" "sm_doublejump_max_jumps" + "Default" "1" + "description" "How many re-jumps the player can do while he is in the air." + } + "24" + { + "name" "sm_doublejump_humans" + "Default" "1" + "description" "Enable/Disable Double jump for humans." + } + "25" + { + "name" "sm_doublejump_zombies" + "Default" "0" + "description" "Enable/Disable Double jump zombies." + } + "26" + { + "name" "sm_doublejump_enable" + "Default" "1" + "description" "Enable/Disable Double Jump mode" + } + "27" + { + "name" "sm_ic_enable" + "Default" "1" + "description" "Enable/Disable Inverted Controls mode." + } + "28" + { + "name" "sm_damagegame_time_interval" + "Default" "15.000000" + "description" "Damage Game Timer Interval" + } + "29" + { + "name" "sm_damagegame_damage" + "Default" "15.000000" + "description" "The amount of damage to apply to players who don't shoot zombies" + } + "30" + { + "name" "sm_damagegame_mode" + "Default" "0" + "description" "DamageGame Mode (0 = Worst defenders, 1 = Doesn't defend for x time, 2 = Both)" + } + "31" + { + "name" "sm_damagegame_enable" + "Default" "1" + "description" "Enable/Disable Damage Game" + } + "32" + { + "name" "sm_blindmode_time_interval" + "Default" "20.000000" + "description" "Every how many seconds to keep giving the zombies flashbang?" + } + "33" + { + "name" "sm_blindmode_percentage" + "Default" "33.000000" + "description" "Percentage value of zombies to give flashbang to" + } + "34" + { + "name" "sm_blindmode_max_distance" + "Default" "300.000000" + "description" "Max distance between humans and flashbang to apply blind in units" + } + "35" + { + "name" "sm_blindmode_blind_time" + "Default" "5" + "description" "How many seconds should the humans be blind for?" + } + "36" + { + "name" "sm_blindmode_enable" + "Default" "1" + "description" "Enable/Disable BlindMode Mode (This differs from turning it on/off)" + } + "37" + { + "name" "sm_slapmode_time_interval" + "Default" "20.000000" + "description" "Every how many seconds to keep slapping a random human?" + } + "38" + { + "name" "sm_slapmode_randoms_count" + "Default" "1" + "description" "How many random humans to keep slapping?" + } + "39" + { + "name" "sm_slapmode_enable" + "Default" "1" + "description" "Enable/Disable SlapMode Mode (This differs from turning it on/off)" + } + "40" + { + "name" "sm_chaosweapons_timer_interval" + "Default" "30.000000" + "description" "Every how many seconds to keep picking a random weapon?" + } + "41" + { + "name" "sm_chaosweapons_knockback" + "Default" "0.100000" + "description" "Knockback to set of other weapons" + } + "42" + { + "name" "sm_chaosweapons_countdown" + "Default" "10" + "description" "How many seconds for the countdown" + } + "43" + { + "name" "sm_chaosweapons_enable" + "Default" "1" + "description" "Enable/Disable ChaosWeapons Mode (This differs from turning it on/off)" + } + "44" + { + "name" "sm_gungame_pistols_damage" + "Default" "1200" + "description" "The required damage needed for pistols to upgrade" + } + "45" + { + "name" "sm_gungame_shotguns_damage" + "Default" "2200" + "description" "The required damage needed for shotguns to upgrade" + } + "46" + { + "name" "sm_gungame_smgs_damage" + "Default" "4200" + "description" "The required damage needed for smgs to upgrade" + } + "47" + { + "name" "sm_gungame_rifles_damage" + "Default" "3800" + "description" "The required damage needed for rifles to upgrade" + } + "48" + { + "name" "sm_gungame_m249_damage" + "Default" "8000" + "description" "The required damage needed for m249 to finish the gungame cycle" + } + "49" + { + "name" "sm_gungame_hegrenades_reward" + "Default" "2" + "description" "How many smokegrenades to give to the player when completing a cycle" + } + "50" + { + "name" "sm_gungame_speed_reward" + "Default" "100.000000" + "description" "How many seconds can the player keep their high speed hold" + } + "51" + { + "name" "sm_gungame_enable" + "Default" "1" + "description" "Enable/Disable GunGame Mode (This differs from turning it on/off)" + } + "52" + { + "name" "sm_mathgame_easy_time" + "Default" "15.000000" + "description" "The time needed to answer easy math questions" + } + "53" + { + "name" "sm_mathgame_medium_time" + "Default" "30.000000" + "description" "The time needed to answer medium math questions" + } + "54" + { + "name" "sm_mathgame_hard_time" + "Default" "60.000000" + "description" "The time needed to answer hard math questions" + } + "55" + { + "name" "sm_mathgame_easy_damage" + "Default" "50.000000" + "description" "The amount of damage to apply to those who can't answer easy questions" + } + "56" + { + "name" "sm_mathgame_medium_damage" + "Default" "35.000000" + "description" "The amount of damage to apply to those who can't answer medium questions" + } + "57" + { + "name" "sm_mathgame_hard_damage" + "Default" "20.000000" + "description" "The amount of damage to apply to those who can't answer hard questions" + } + "58" + { + "name" "sm_mathgame_include_zombies" + "Default" "0" + "description" "Include zombies to the math game (1 = Enabled, 0 = Disabled)" + } + "59" + { + "name" "sm_mathgame_max_tries" + "Default" "3" + "description" "How many failed tries for zombies to answer question until they can never respawn again?" + } + "60" + { + "name" "sm_mathgame_time_delay" + "Default" "15.000000" + "description" "The delayed time after each math question" + } + "61" + { + "name" "sm_mathgame_enable" + "Default" "1" + "description" "Enable/Disable MathGame Mode (This differs from turning it on/off)" + } + "62" + { + "name" "sm_crazyshop_damage" + "Default" "5000" + "description" "The needed damage for humans to be rewarded with credits" + } + "63" + { + "name" "sm_crazyshop_credits" + "Default" "1" + "description" "How many credits to reward the human when they reach the needed damage?" + } + "64" + { + "name" "sm_crazyshop_savecredits" + "Default" "1" + "description" "Save credits to a database or not" + } + "65" + { + "name" "sm_crazyshop_slowbeacon_radius" + "Default" "400.000000" + "description" "Slow Beacon Radius" + } + "66" + { + "name" "sm_crazyshop_disable_shop" + "Default" "0" + "description" "Enable/Disable the !crazyshop command" + } + "67" + { + "name" "sm_crazyshop_enable" + "Default" "1" + "description" "Enable/Disable CrazyShop Mode (This differs from turning it on/off)" + } + "68" + { + "name" "sm_realityshift_timer_interval" + "Default" "30.000000" + "description" "After how many seconds to keep swapping positions" + } + "69" + { + "name" "sm_realityshift_mode" + "Default" "0" + "description" "RealityShift Mode [0 = Random Swaps, 1 = Assigned Swaps [At round start]]" + } + "70" + { + "name" "sm_realityshift_enable" + "Default" "1" + "description" "Enable/Disable RealityShift Mode (This differs from turning it on/off)" + } + "71" + { + "name" "sm_pullgame_timer_interval" + "Default" "30.000000" + "description" "After how many seconds to keep giving pull access to a random zm?" + } + "72" + { + "name" "sm_pullgame_speed" + "Default" "300.000000" + "description" "Pulling Speed Value" + } + "73" + { + "name" "sm_pullgame_pull_time" + "Default" "15.000000" + "description" "Pulling Time" + } + "74" + { + "name" "sm_pullgame_humans_count" + "Default" "3" + "description" "How many humans to give pull access to?" + } + "75" + { + "name" "sm_pullgame_zombies_count" + "Default" "3" + "description" "How many zombies to give pull access to?" + } + "76" + { + "name" "sm_pullgame_enable" + "Default" "1" + "description" "Enable/Disable PullGame Mode (This differs from turning it on/off)" + } +} diff --git a/addons/sourcemod/configs/FM_CrazyShop.cfg b/addons/sourcemod/configs/FunModes/CrazyShop.cfg similarity index 100% rename from addons/sourcemod/configs/FM_CrazyShop.cfg rename to addons/sourcemod/configs/FunModes/CrazyShop.cfg diff --git a/addons/sourcemod/scripting/FunModes.sp b/addons/sourcemod/scripting/FunModes.sp index 67abb4a..aa7a3b6 100644 --- a/addons/sourcemod/scripting/FunModes.sp +++ b/addons/sourcemod/scripting/FunModes.sp @@ -19,14 +19,14 @@ #tryinclude #define REQUIRE_PLUGIN -#include "Fun_Modes/Core.sp" +#include "Fun_Modes/Core/Core.sp" public Plugin myinfo = { name = "FunModes", author = "Dolly", description = "bunch of fun modes for ze mode", - version = "2.1.0", + version = "2.5.0", url = "https://nide.gg" } @@ -35,7 +35,7 @@ public void OnPluginStart() /* TRANSLATIONS LAODS */ LoadTranslations("common.phrases"); LoadTranslations("FunModes.phrases"); - + /* HUD HANDLE */ g_hHudMsg = CreateHudSynchronizer(); @@ -43,24 +43,22 @@ public void OnPluginStart() DECLARE_FM_FORWARD(OnPluginStart); + DECLARE_FM_FORWARD(InitCvarsValues); + AutoExecConfig(); - for(int i = 1; i <= MaxClients; i++) - { - if (IsClientConnected(i)) - OnClientPutInServer(i); - } - static const char commands[][] = { "sm_fm_cvars", "sm_funmodes", "sm_funmode" }; for(int i = 0; i < sizeof(commands); i++) { RegAdminCmd(commands[i], Cmd_FunModes, ADMFLAG_CONVARS, "Show all available funmodes"); } - + + RegAdminCmd("sm_fmcvar", Cmd_FunModesCvars, ADMFLAG_CONVARS, "Change a FunModes cvar"); + g_iNetPropAmmoIndex = FindSendPropInfo("CBasePlayer", "m_iAmmo"); if (g_iNetPropAmmoIndex == -1) SetFailState("[FunModes] Could not find offset `CBasePlayer::m_iAmmo`"); - + GameData gd = new GameData("sdkhooks.games/engine.ep2v"); if (gd == null) LogError("[FunModes] Could not find \"sdkhooks.games/engine.ep2v.txt\" file."); @@ -69,10 +67,11 @@ public void OnPluginStart() int offset = gd.GetOffset("Weapon_Switch"); if (offset == -1) { + delete gd; LogError("[FunModes] Could not find the offset of \"Weapon_Switch\", some features may be neglected"); return; } - + StartPrepSDKCall(SDKCall_Player); PrepSDKCall_SetVirtual(offset); @@ -83,7 +82,7 @@ public void OnPluginStart() if (g_hSwitchSDKCall == null) LogError("[FunModes] Incorrect offset for \"Weapon_Switch\", Cannot get a good SDKCall Handle"); - + delete gd; } } @@ -94,7 +93,7 @@ public void OnPluginEnd() { if (!IsClientInGame(i) || IsFakeClient(i)) continue; - + OnClientDisconnect(i); } } @@ -104,7 +103,7 @@ public void OnMapStart() g_LaserSprite = PrecacheModel("sprites/laser.vmt"); g_HaloSprite = PrecacheModel("materials/sprites/halo.vtf"); g_iLaserBeam = PrecacheModel("materials/sprites/laserbeam.vmt"); - + PrecacheSound(Beacon_Sound, true); DECLARE_FM_FORWARD(OnMapStart); @@ -174,18 +173,18 @@ void OnTakeDamagePost(int victim, int attacker, int inflictor, float damage, int Action OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype) { Action result = Plugin_Continue; - + DECLARE_FM_FORWARD_PARAM4(OnTakeDamage, victim, attacker, damage, result); - + return result; } Action OnWeaponEquip(int client, int weapon) { Action result = Plugin_Continue; - + DECLARE_FM_FORWARD_PARAM3(OnWeaponEquip, client, weapon, result); - + return result; } @@ -206,10 +205,10 @@ void FunModes_RestartRound() { if (!IsClientInGame(i) || !IsPlayerAlive(i)) continue; - + ForcePlayerSuicide(i); } - + CS_TerminateRound(3.0, CSRoundEnd_Draw); } @@ -247,32 +246,32 @@ float GetDistanceBetween(int origin, int target, bool squarred = false) stock void BeaconPlayer(int client, int mode, float distance = 0.0, int color[4] = {0,0,0,0}) { - float fvec[3]; - GetClientAbsOrigin(client, fvec); - fvec[2] += 10; + float vec[3]; + GetClientAbsOrigin(client, vec); + vec[2] += 10; if (mode == 0) { - TE_SetupBeamRingPoint(fvec, (distance - 10.0), distance, g_LaserSprite, g_HaloSprite, 0, 15, 0.1, 10.0, 0.0, color, 10, 0); + TE_SetupBeamRingPoint(vec, (distance - 10.0), distance, g_LaserSprite, g_HaloSprite, 0, 15, 0.1, 10.0, 0.0, color, 10, 0); TE_SendToAll(); } - else if (mode == 1) + else { - TE_SetupBeamRingPoint(fvec, 10.0, 375.0, g_LaserSprite, g_HaloSprite, 0, 15, 0.5, 5.0, 0.0, g_ColorCyan, 10, 0); + TE_SetupBeamRingPoint(vec, 10.0, 375.0, g_LaserSprite, g_HaloSprite, 0, 15, 0.5, 5.0, 0.0, g_ColorCyan, 10, 0); TE_SendToAll(); int rainbowColor[4]; - float i = GetGameTime(); - float Frequency = 2.5; - rainbowColor[0] = RoundFloat(Sine(Frequency * i + 0.0) * 127.0 + 128.0); - rainbowColor[1] = RoundFloat(Sine(Frequency * i + 2.0943951) * 127.0 + 128.0); - rainbowColor[2] = RoundFloat(Sine(Frequency * i + 4.1887902) * 127.0 + 128.0); + float f = GetGameTime(); + float frequency = 2.5; + rainbowColor[0] = RoundFloat(Sine(frequency * f + 0.0) * 127.0 + 128.0); + rainbowColor[1] = RoundFloat(Sine(frequency * f + 2.0943951) * 127.0 + 128.0); + rainbowColor[2] = RoundFloat(Sine(frequency * f + 4.1887902) * 127.0 + 128.0); rainbowColor[3] = 255; - TE_SetupBeamRingPoint(fvec, 10.0, 375.0, g_LaserSprite, g_HaloSprite, 0, 10, 0.6, 10.0, 0.5, rainbowColor, 10, 0); + TE_SetupBeamRingPoint(vec, 10.0, 375.0, g_LaserSprite, g_HaloSprite, 0, 10, 0.6, 10.0, 0.5, rainbowColor, 10, 0); TE_SendToAll(); - EmitAmbientSound(Beacon_Sound, fvec, client, SNDLEVEL_RAIDSIREN); + EmitAmbientSound(Beacon_Sound, vec, client, SNDLEVEL_RAIDSIREN); } } @@ -305,9 +304,8 @@ int Menu_MainModes(Menu menu, MenuAction action, int param1, int param2) switch(action) { case MenuAction_End: - { delete menu; - } + case MenuAction_Select: { char index[3]; @@ -327,9 +325,11 @@ void DisplayModeInfo(int client, int modeIndex) ModeInfo info; info = g_ModesInfo[modeIndex]; - - bool enabled = info.cvarInfo[info.enableIndex].cvar.BoolValue; - + + FM_ConVar cvar; + cvar = info.cvars[info.enableIndex]; + bool enabled = FUNMODES_CVAR_GET_VALUE(cvar, Bool); + menu.SetTitle("%s - Mode Info\nStatus: %s - %s\n", info.name, enabled?"Enabled":"Disabled", info.isOn?"On":"Off"); menu.AddItem(info.name, "Toggle", enabled?ITEMDRAW_DEFAULT:ITEMDRAW_DISABLED); @@ -363,14 +363,14 @@ int Menu_DisplayConVars(Menu menu, MenuAction action, int param1, int param2) Function myFunction = GetFunctionByName(null, functionName); if (myFunction == INVALID_FUNCTION) return -1; - + Call_StartFunction(null, myFunction); Call_PushCell(param1); Call_PushCell(0); - + Call_Finish(); - + if (param2 == 0) DisplayModeInfo(param1, g_iPreviousModeIndex[param1]); } @@ -381,22 +381,23 @@ int Menu_DisplayConVars(Menu menu, MenuAction action, int param1, int param2) void ShowCvarsInfo(int client, ModeInfo info) { + g_iPreviousModeIndex[client] = info.index; + + info = g_ModesInfo[info.index]; + Menu menu = new Menu(Menu_CvarsInfo); menu.SetTitle("%s - ConVars List", info.name); - for (int i = 0; i < sizeof(ModeInfo::cvarInfo); i++) + for (int i = 0; i < sizeof(ModeInfo::cvars); i++) { - if (info.cvarInfo[i].cvar == null || info.cvarInfo[i].type[0] == '\0') + if (!FUNMODES_CVAR_ISVALID(info.cvars[i]) || info.cvars[i].type == CONVAR_STRING) continue; char index[3]; IntToString(i, index, sizeof(index)); - char cvarName[64]; - info.cvarInfo[i].cvar.GetName(cvarName, sizeof(cvarName)); - - menu.AddItem(index, cvarName); + menu.AddItem(index, info.cvars[i].name); } menu.ExitBackButton = true; @@ -409,7 +410,7 @@ int Menu_CvarsInfo(Menu menu, MenuAction action, int param1, int param2) { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) @@ -421,27 +422,21 @@ int Menu_CvarsInfo(Menu menu, MenuAction action, int param1, int param2) char indexStr[3]; menu.GetItem(param2, indexStr, sizeof(indexStr)); - ShowCvarInfo(param1, g_ModesInfo[g_iPreviousModeIndex[param1]].cvarInfo[StringToInt(indexStr)]); + ShowCvarInfo(param1, g_ModesInfo[g_iPreviousModeIndex[param1]].cvars[StringToInt(indexStr)]); } } - + return 0; } -void ShowCvarInfo(int client, ConVarInfo thisCvarInfo) +void ShowCvarInfo(int client, FM_ConVar thisCvarInfo) { + g_iPreviousModeIndex[client] = thisCvarInfo.modeIndex; + Menu menu = new Menu(Menu_ShowCvarInfo); - - char convarName[32]; - thisCvarInfo.cvar.GetName(convarName, sizeof(convarName)); - - char convarDescription[120]; - thisCvarInfo.cvar.GetDescription(convarDescription, sizeof(convarDescription)); - - char title[sizeof(convarName) + sizeof(convarDescription) + 2]; - FormatEx(title, sizeof(title), "%s\n%s", convarName, convarDescription); - menu.SetTitle(title); - + + menu.SetTitle("%s\n- %s", thisCvarInfo.name, thisCvarInfo.description); + int valsCount; for (int i = 0; i < sizeof(thisCvarInfo.values); i++) { @@ -450,32 +445,27 @@ void ShowCvarInfo(int client, ConVarInfo thisCvarInfo) } valsCount++; - + char[][] dataEx = new char[valsCount][8]; ExplodeString(thisCvarInfo.values, ",", dataEx, valsCount, 8); - - any currentVal = GetValFromCvar(thisCvarInfo.cvar, thisCvarInfo.type); + + any currentVal = GetValFromCvar(thisCvarInfo, thisCvarInfo.type); bool currentValExists = false; for (int i = 0; i < valsCount; i++) { - any val = GetValFromCvar(null, thisCvarInfo.type, dataEx[i]); - if (val == currentVal) { + any val = GetValFromCvar(_, thisCvarInfo.type, dataEx[i]); + if (val == currentVal) currentValExists = true; - } - - char data[100]; - FormatEx(data, sizeof(data), "%d|%s|%s|%s", view_as(thisCvarInfo.cvar), dataEx[i], thisCvarInfo.type, thisCvarInfo.values); - + + char data[22]; + FormatEx(data, sizeof(data), "%d|%d|%s", thisCvarInfo.modeIndex, thisCvarInfo.cvarIndex, dataEx[i]); + menu.AddItem(data, dataEx[i], val == currentVal ? ITEMDRAW_DISABLED : ITEMDRAW_DEFAULT); } - + if (!currentValExists) - { - char val[10]; - thisCvarInfo.cvar.GetString(val, sizeof(val)); - menu.AddItem(NULL_STRING, val, ITEMDRAW_DISABLED); - } + menu.AddItem(NULL_STRING, FUNMODES_CVAR_GET_VALUE(thisCvarInfo, String), ITEMDRAW_DISABLED); menu.ExitBackButton = true; menu.Display(client, MENU_TIME_FOREVER); @@ -487,95 +477,124 @@ int Menu_ShowCvarInfo(Menu menu, MenuAction action, int param1, int param2) { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) ShowCvarsInfo(param1, g_ModesInfo[g_iPreviousModeIndex[param1]]); } - + case MenuAction_Select: { char data[100]; menu.GetItem(param2, data, sizeof(data)); - - char dataEx[4][22]; - ExplodeString(data, "|", dataEx, 4, 22); - - ConVar cvar = view_as(StringToInt(dataEx[0])); - SetCvarVal(cvar, dataEx[2], dataEx[1]); - - char cvarName[32]; - cvar.GetName(cvarName, sizeof(cvarName)); - CPrintToChat(param1, "{gold}[FunModes]{lightgreen} You have changed {olive}%s {lightgreen}value to {olive}%s.", cvarName, dataEx[1]); - - ConVarInfo info; - info.cvar = cvar; - strcopy(info.values, sizeof(ConVarInfo::values), dataEx[3]); - strcopy(info.type, sizeof(ConVarInfo::type), dataEx[2]); - - ShowCvarInfo(param1, info); + + char dataEx[3][22]; + ExplodeString(data, "|", dataEx, sizeof(dataEx), sizeof(dataEx[])); + + int modeIndex = StringToInt(dataEx[0]); + int cvarIndex = StringToInt(dataEx[1]); + + FM_ConVar cvar; + cvar = g_ModesInfo[modeIndex].cvars[cvarIndex]; + FUNMODES_CVAR_SET_VALUE(cvar, String, dataEx[2]); + + // Just to avoid some random sourcemod bug... + strcopy(g_ModesInfo[modeIndex].cvars[cvarIndex].currentValue, sizeof(FM_ConVar::currentValue), dataEx[2]); + + CPrintToChat(param1, "{gold}[FunModes]{lightgreen} You have changed {olive}%s {lightgreen}value to {olive}%s.", cvar.name, dataEx[2]); + + ShowCvarInfo(param1, cvar); } } - + return 0; } -void SetCvarVal(ConVar cvar, const char[] type, const char[] valStr) +any GetValFromCvar(FM_ConVar cvar = {}, ConVarType type, const char[] valStr = "") { - if (strcmp(type, "int") == 0) - cvar.IntValue = StringToInt(valStr); - - else if (strcmp(type, "float") == 0) - cvar.FloatValue = StringToFloat(valStr); + switch (type) + { + case CONVAR_INT: return (FUNMODES_CVAR_ISVALID(cvar)) ? FUNMODES_CVAR_GET_VALUE(cvar, Int) : StringToInt(valStr); + case CONVAR_FLOAT: return (FUNMODES_CVAR_ISVALID(cvar)) ? FUNMODES_CVAR_GET_VALUE(cvar, Float) : StringToFloat(valStr); + case CONVAR_BOOL: return (FUNMODES_CVAR_ISVALID(cvar)) ? FUNMODES_CVAR_GET_VALUE(cvar, Bool) : view_as(StringToInt(valStr)); + } - else if (strcmp(type, "bool") == 0) - cvar.BoolValue = view_as(StringToInt(valStr)); + return 0; } -any GetValFromCvar(ConVar cvar = null, const char[] type, const char[] valStr = "") -{ - if (strcmp(type, "int") == 0) +Action Cmd_FunModesCvars(int client, int args) +{ + if (args < 1) { - if (cvar != null) - return cvar.IntValue; - else - return StringToInt(valStr); + CReplyToCommand(client, "[FunModes] Usage: sm_fmcvar "); + return Plugin_Handled; } - else if (strcmp(type, "float") == 0) + + char cvarName[sizeof(FM_ConVar::name)]; + GetCmdArg(1, cvarName, sizeof(cvarName)); + + bool exists; + FM_ConVar cvar; + for (int i = 0; i < g_iLastModeIndex; i++) { - if (cvar != null) - return cvar.FloatValue; - else - return StringToFloat(valStr); + if (exists) + break; + + for (int j = 0; j < sizeof(ModeInfo::cvars); j++) + { + cvar = g_ModesInfo[i].cvars[j]; + if (!FUNMODES_CVAR_ISVALID(cvar)) + continue; + + if (strcmp(cvar.name, cvarName, false) != 0) + continue; + + exists = true; + break; + } } - else if (strcmp(type, "bool") == 0) + if (!exists) { - if (cvar != null) - return cvar.BoolValue; - else - return view_as(StringToInt(valStr)); - } - - return 0; + CReplyToCommand(client, "{gold}[FunModes]{lightgreen} Cannot find the specified cvar."); + return Plugin_Handled; + } + + if (args < 2) + { + CReplyToCommand(client, "{gold}[FunModes]{lightgreen} %s value is: {olive}%s", cvar.name, cvar.currentValue); + return Plugin_Handled; + } + + char newValue[sizeof(FM_ConVar::defaultValue)]; + GetCmdArg(2, newValue, sizeof(newValue)); + + FUNMODES_CVAR_SET_VALUE(cvar, String, newValue); + int cvarIndex = cvar.cvarIndex; + int modeIndex = cvar.modeIndex; + + g_ModesInfo[modeIndex].cvars[cvarIndex] = cvar; + CReplyToCommand(client, "{gold}[FunModes]{lightgreen} changed %s value to: {olive}%s", cvar.name, cvar.currentValue); + + return Plugin_Handled; } -stock void SendHudText(int client, const char[] sMessage, bool isFar = false, int icolor = -1) +stock void SendHudText(int client, const char[] message, bool isFar = false, int color = -1) { - bool bDynamicAvailable = false; - int iHUDChannel = -1; + static bool dynamicAvailable; + int hudChannel = -1; - int iChannel = g_cvHUDChannel.IntValue; - if (iChannel < 0 || iChannel > 5) { - iChannel = 4; - } + if (!dynamicAvailable) + dynamicAvailable = g_bPlugin_DynamicChannels && GetFeatureStatus(FeatureType_Native, "GetDynamicChannel") == FeatureStatus_Available; - bDynamicAvailable = g_bPlugin_DynamicChannels && CanTestFeatures() && GetFeatureStatus(FeatureType_Native, "GetDynamicChannel") == FeatureStatus_Available; + int channel = g_cvHUDChannel.IntValue; + if (channel < 0 || channel > 5) + channel = 4; #if defined _DynamicChannels_included_ - if (bDynamicAvailable) - iHUDChannel = GetDynamicChannel(iChannel); + if (dynamicAvailable) + hudChannel = GetDynamicChannel(channel); #endif if (isFar) @@ -583,7 +602,7 @@ stock void SendHudText(int client, const char[] sMessage, bool isFar = false, in else SetHudTextParams(-1.0, 0.1, 2.0, 255, 36, 255, 13); - switch(icolor) + switch(color) { case 0: { @@ -599,13 +618,99 @@ stock void SendHudText(int client, const char[] sMessage, bool isFar = false, in } } - if (bDynamicAvailable) + if (dynamicAvailable) { - ShowHudText(client, iHUDChannel, "%s", sMessage); + ShowHudText(client, hudChannel, "%s", message); + return; } - else + + ClearSyncHud(client, g_hHudMsg); + ShowSyncHudText(client, g_hHudMsg, "%s", message); +} + +stock bool HasPlayerItem(int client, const char[] weapon) +{ + int max = GetEntPropArraySize(client, Prop_Send, "m_hMyWeapons"); + for (int i = 0; i < max; i++) + { + int ent = GetEntPropEnt(client, Prop_Send, "m_hMyWeapons", i); + if (ent == -1 || !IsValidEntity(ent)) + continue; + + char className[32]; + GetEntityClassname(ent, className, sizeof(className)); + if (strcmp(className, weapon, false) == 0) + return true; + } + + return false; +} + +public void OnConfigsExecuted() +{ + delete g_hKV; + g_hKV = new KeyValues("FunModes_Cvars"); + + if (!g_hKV.ImportFromFile(FUNMODES_CVAR_CONFIG)) + { + delete g_hKV; + return; + } + + if (!g_hKV.GotoFirstSubKey()) { - ClearSyncHud(client, g_hHudMsg); - ShowSyncHudText(client, g_hHudMsg, "%s", sMessage); + delete g_hKV; + return; } -} \ No newline at end of file + + int modeIndex = 0; + int cvarIndex = 0; + int maxCvars = g_ModesInfo[modeIndex].GetCvarsCount(); + int count = 0; + do + { + FM_ConVar cvar; + cvar = g_ModesInfo[modeIndex].cvars[cvarIndex]; + + char defaultValue[sizeof(FM_ConVar::defaultValue)]; + g_hKV.GetString("default", defaultValue, sizeof(defaultValue)); + if (!defaultValue[0]) + continue; + + cvar.defaultValue = defaultValue; + + cvar.autoChange = true; + + char currentValue[sizeof(FM_ConVar::currentValue)]; + g_hKV.GetString("currentvalue", currentValue, sizeof(currentValue)); + if (currentValue[0]) + FUNMODES_CVAR_SET_VALUE(cvar, String, currentValue); + else + FUNMODES_CVAR_SET_VALUE(cvar, String, defaultValue); + + cvar.autoChange = false; + + char description[sizeof(FM_ConVar::description)]; + g_hKV.GetString("description", description, sizeof(description)); + cvar.description = description; + + char values[sizeof(FM_ConVar::values)]; + g_hKV.GetString("values", values, sizeof(values)); + if (values[0]) + cvar.values = values; + + g_ModesInfo[modeIndex].cvars[cvarIndex] = cvar; + g_ModesInfo[modeIndex].cvars[cvarIndex].currentValue = cvar.currentValue; + if (++cvarIndex >= maxCvars) + { + if (++modeIndex >= g_iLastModeIndex) + break; + + cvarIndex = 0; + maxCvars = g_ModesInfo[modeIndex].GetCvarsCount(); + } + count++; + } while (g_hKV.GotoNextKey()); + + g_hKV.Rewind(); +} diff --git a/addons/sourcemod/scripting/Fun_Modes/BlindMode.sp b/addons/sourcemod/scripting/Fun_Modes/BlindMode.sp index f52d814..31fac5f 100644 --- a/addons/sourcemod/scripting/Fun_Modes/BlindMode.sp +++ b/addons/sourcemod/scripting/Fun_Modes/BlindMode.sp @@ -16,10 +16,13 @@ #pragma semicolon 1 #pragma newdecls required -ModeInfo g_BlindModeInfo; +static int g_iBlindModeIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iBlindModeIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_BlindModeInfo +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] #define BLINDMODE_CONVAR_TIMER_INTERVAL 0 #define BLINDMODE_CONVAR_PERCENTAGE 1 @@ -30,8 +33,20 @@ ModeInfo g_BlindModeInfo; Handle g_hBlindModeTimer; bool g_bHasFlash[MAXPLAYERS + 1]; +/* ConVars Values variables */ +float g_fBlindMode_TimerInterval; +float g_fBlindMode_Percentage; +float g_fBlindMode_MaxDistance; + +int g_iBlindMode_BlindTime; + +bool g_bBlindMode_Enabled; + stock void OnPluginStart_BlindMode() { + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + THIS_MODE_INFO.name = "BlindMode"; THIS_MODE_INFO.tag = "{gold}[FunModes-BlindMode]{lightgreen}"; @@ -39,53 +54,97 @@ stock void OnPluginStart_BlindMode() /* THESE ARE THE STANDARD COMMANDS THAT ALL MODES SHOULD HAVE */ RegAdminCmd("sm_fm_blindmode", Cmd_BlindModeToggle, ADMFLAG_CONVARS, "Turn BlindMode Mode On/Off"); RegAdminCmd("sm_blindmode_settings", Cmd_BlindModeSettings, ADMFLAG_CONVARS, "Open BlindMode Sttings Menu"); - + /* CONVARS */ DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, BLINDMODE_CONVAR_TIMER_INTERVAL, - "sm_blindmode_time_interval", "20.0", "Every how many seconds to keep giving the zombies flashbang?", - ("15.0,20.0,30.0,40.0,60.0"), "float" + BLINDMODE_CONVAR_TIMER_INTERVAL, "sm_blindmode_time_interval", + "20.0", "Every how many seconds to keep giving the zombies flashbang?", + ("15.0,20.0,30.0,40.0,60.0"), CONVAR_FLOAT ); - + + THIS_MODE_INFO.cvars[BLINDMODE_CONVAR_TIMER_INTERVAL].HookChange(BlindMode_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, BLINDMODE_CONVAR_PERCENTAGE, - "sm_blindmode_percentage", "33.0", "Percentage value of zombies to give flashbang to", - ("10.0,20.0,50.0,70.0,100.0"), "float" + BLINDMODE_CONVAR_PERCENTAGE, "sm_blindmode_percentage", + "33.0", "Percentage value of zombies to give flashbang to", + ("10.0,20.0,50.0,70.0,100.0"), CONVAR_FLOAT ); - - THIS_MODE_INFO.cvarInfo[BLINDMODE_CONVAR_PERCENTAGE].cvar.SetBounds(ConVarBound_Lower, false, 0.0); - THIS_MODE_INFO.cvarInfo[BLINDMODE_CONVAR_PERCENTAGE].cvar.SetBounds(ConVarBound_Upper, false, 100.0); - + + THIS_MODE_INFO.cvars[BLINDMODE_CONVAR_PERCENTAGE].HookChange(BlindMode_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, BLINDMODE_CONVAR_MAX_DISTANCE, - "sm_blindmode_max_distance", "300.0", "Max distance between humans and flashbang to apply blind in units", - ("200.0,300.0,500.0,700.0,1000.0"), "float" + BLINDMODE_CONVAR_MAX_DISTANCE, "sm_blindmode_max_distance", + "300.0", "Max distance between humans and flashbang to apply blind in units", + ("200.0,300.0,500.0,700.0,1000.0"), CONVAR_FLOAT ); - + + THIS_MODE_INFO.cvars[BLINDMODE_CONVAR_MAX_DISTANCE].HookChange(BlindMode_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, BLINDMODE_CONVAR_BLIND_TIME, - "sm_blindmode_blind_time", "5", "How many seconds should the humans be blind for?", - ("2,3,5,7,10"), "int" + BLINDMODE_CONVAR_BLIND_TIME,"sm_blindmode_blind_time", + "5", "How many seconds should the humans be blind for?", + ("2,3,5,7,10"), CONVAR_INT ); - + + THIS_MODE_INFO.cvars[BLINDMODE_CONVAR_BLIND_TIME].HookChange(BlindMode_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, BLINDMODE_CONVAR_TOGGLE, - "sm_blindmode_enable", "1", "Enable/Disable BlindMode Mode (This differs from turning it on/off)", - ("0,1"), "bool" + BLINDMODE_CONVAR_TOGGLE, "sm_blindmode_enable", + "1", "Enable/Disable BlindMode Mode (This differs from turning it on/off)", + ("0,1"), CONVAR_BOOL ); - + + THIS_MODE_INFO.cvars[BLINDMODE_CONVAR_TOGGLE].HookChange(BlindMode_OnConVarChange); + THIS_MODE_INFO.enableIndex = BLINDMODE_CONVAR_TOGGLE; - - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; - - THIS_MODE_INFO.cvarInfo[BLINDMODE_CONVAR_TOGGLE].cvar.AddChangeHook(OnBlindModeModeToggle); } -void OnBlindModeModeToggle(ConVar cvar, const char[] newValue, const char[] oldValue) +void InitCvarsValues_BlindMode() { - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + int modeIndex = THIS_MODE_INFO.index; + + g_fBlindMode_TimerInterval = _FUNMODES_CVAR_GET_VALUE(modeIndex, BLINDMODE_CONVAR_TIMER_INTERVAL, Float); + g_fBlindMode_Percentage = _FUNMODES_CVAR_GET_VALUE(modeIndex, BLINDMODE_CONVAR_PERCENTAGE, Float); + g_fBlindMode_MaxDistance = _FUNMODES_CVAR_GET_VALUE(modeIndex, BLINDMODE_CONVAR_MAX_DISTANCE, Float); + + g_iBlindMode_BlindTime = _FUNMODES_CVAR_GET_VALUE(modeIndex, BLINDMODE_CONVAR_BLIND_TIME, Int); + + g_bBlindMode_Enabled = _FUNMODES_CVAR_GET_VALUE(modeIndex, BLINDMODE_CONVAR_TOGGLE, Bool); +} + +void BlindMode_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) +{ + switch (cvarIndex) + { + case BLINDMODE_CONVAR_TIMER_INTERVAL: + { + g_fBlindMode_TimerInterval = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + } + + case BLINDMODE_CONVAR_PERCENTAGE: + { + g_fBlindMode_Percentage = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + } + + case BLINDMODE_CONVAR_MAX_DISTANCE: + { + g_fBlindMode_MaxDistance = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + } + + case BLINDMODE_CONVAR_BLIND_TIME: + { + g_iBlindMode_BlindTime = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + } + + case BLINDMODE_CONVAR_TOGGLE: + { + bool val = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bBlindMode_Enabled = val; + } + } } stock void OnMapStart_BlindMode() {} @@ -135,7 +194,7 @@ stock void Event_PlayerDeath_BlindMode(int client) public Action Cmd_BlindModeToggle(int client, int args) { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) + if (!g_bBlindMode_Enabled) { CReplyToCommand(client, "%s BlindMode Mode is currently Disabled", THIS_MODE_INFO.tag); return Plugin_Handled; @@ -143,29 +202,27 @@ public Action Cmd_BlindModeToggle(int client, int args) /* You can change whatever you want here */ CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, !THIS_MODE_INFO.isOn, THIS_MODE_INFO.index); - + CPrintToChatAll("%s BlindMode Mode is now %s!", THIS_MODE_INFO.tag, THIS_MODE_INFO.isOn ? "On" : "Off"); - + if (THIS_MODE_INFO.isOn) { FunModes_HookEvent(g_bEvent_RoundStart, "round_start", Event_RoundStart); FunModes_HookEvent(g_bEvent_RoundEnd, "round_end", Event_RoundEnd); - - float interval = THIS_MODE_INFO.cvarInfo[BLINDMODE_CONVAR_TIMER_INTERVAL].cvar.FloatValue; - + CPrintToChatAll("%s Zombies will get a {olive}flashbang {lightgreen}that can blind humans.", THIS_MODE_INFO.tag); - CPrintToChatAll("%s %d%% of the zombies team will get the {olive}flashbang {lightgreen}every %.2f seconds", THIS_MODE_INFO.tag, - THIS_MODE_INFO.cvarInfo[BLINDMODE_CONVAR_PERCENTAGE].cvar.IntValue, - interval + CPrintToChatAll("%s %.0f%% of the zombies team will get the {olive}flashbang {lightgreen}every %.2f seconds", THIS_MODE_INFO.tag, + g_fBlindMode_Percentage, + g_fBlindMode_TimerInterval ); - - g_hBlindModeTimer = CreateTimer(interval, Timer_BlindMode, _, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT); + + g_hBlindModeTimer = CreateTimer(g_fBlindMode_TimerInterval, Timer_BlindMode, _, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT); } else { delete g_hBlindModeTimer; } - + return Plugin_Handled; } @@ -174,7 +231,7 @@ public Action Cmd_BlindModeSettings(int client, int args) { if (!client) return Plugin_Handled; - + Menu menu = new Menu(Menu_BlindModeSettings); menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); @@ -183,7 +240,7 @@ public Action Cmd_BlindModeSettings(int client, int args) menu.ExitBackButton = true; menu.Display(client, MENU_TIME_FOREVER); - + return Plugin_Handled; } @@ -193,7 +250,7 @@ int Menu_BlindModeSettings(Menu menu, MenuAction action, int param1, int param2) { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) @@ -218,23 +275,21 @@ void ApplyBlind(int client) int clients[1]; clients[0] = client; - - int time = THIS_MODE_INFO.cvarInfo[BLINDMODE_CONVAR_BLIND_TIME].cvar.IntValue; - + Handle message = StartMessage("Fade", clients, 1, 1); if (GetUserMessageType() == UM_Protobuf) { Protobuf pb = UserMessageToProtobuf(message); - pb.SetInt("duration", time * 1000); - pb.SetInt("hold_time", time * 1000); + pb.SetInt("duration", g_iBlindMode_BlindTime * 1000); + pb.SetInt("hold_time", g_iBlindMode_BlindTime * 1000); pb.SetInt("flags", flags); pb.SetColor("clr", color); } else { BfWrite bf = UserMessageToBfWrite(message); - bf.WriteShort(time * 1000); - bf.WriteShort(time * 1000); + bf.WriteShort(g_iBlindMode_BlindTime * 1000); + bf.WriteShort(g_iBlindMode_BlindTime * 1000); bf.WriteShort(flags); bf.WriteByte(color[0]); bf.WriteByte(color[1]); @@ -269,9 +324,8 @@ Action Timer_BlindMode(Handle timer) if (zombiesCount == 0) return Plugin_Handled; - - float percentage = THIS_MODE_INFO.cvarInfo[BLINDMODE_CONVAR_PERCENTAGE].cvar.FloatValue; - int neededZombies = RoundToCeil(zombiesCount * (percentage / 100)); + + int neededZombies = RoundToCeil(zombiesCount * (g_fBlindMode_Percentage / 100)); int enough = 1; do @@ -281,9 +335,16 @@ Action Timer_BlindMode(Handle timer) zombie = zombies[GetRandomInt(0, zombiesCount - 1)]; g_bHasFlash[zombie] = true; - - int entity = GivePlayerItem(zombie, "weapon_flashbang"); - EquipPlayerWeapon(zombie, entity); + + if (!HasPlayerItem(zombie, "weapon_flashbang")) + { + int entity = GivePlayerItem(zombie, "weapon_flashbang"); + EquipPlayerWeapon(zombie, entity); + } + else + { + SET_GRENADES_COUNT(zombie, FLASHBANG, GET_GRENADES_COUNT(zombie, FLASHBANG) + 1); + } CPrintToChat(zombie, "%s You have been granted a FlashBang!!!\nBlind some humans.", THIS_MODE_INFO.tag); enough++; @@ -315,7 +376,7 @@ Action Timer_ApplyBlind(Handle timer, int ref) float origin[3]; GetEntPropVector(entity, Prop_Send, "m_vecOrigin", origin); - float maxDistance = THIS_MODE_INFO.cvarInfo[BLINDMODE_CONVAR_MAX_DISTANCE].cvar.FloatValue; + float maxDistance = g_fBlindMode_MaxDistance; maxDistance *= maxDistance; for (int i = 1; i <= MaxClients; i++) diff --git a/addons/sourcemod/scripting/Fun_Modes/ChaosWeapons.sp b/addons/sourcemod/scripting/Fun_Modes/ChaosWeapons.sp index 3e6c888..cfc720c 100644 --- a/addons/sourcemod/scripting/Fun_Modes/ChaosWeapons.sp +++ b/addons/sourcemod/scripting/Fun_Modes/ChaosWeapons.sp @@ -2,11 +2,10 @@ (). FunModes V2: @file ChaosWeapons.sp - @Usage Funcitons for the ChaosWeapons mode. - + @Usage Funcitons for the ChaosWeapons mode. */ -/* + /* Chaos Weapons: A mode where every 30 seconds or 1 minute, a global message says what weapon will be used like "Only the AK47 will push the zombies for the next 30 seconds!" and only the named weapon will have normal knockback, any other weapon will have 0.1 knockback (It wont push zombies) @@ -18,10 +17,13 @@ #pragma semicolon 1 #pragma newdecls required -ModeInfo g_ChaosWeaponsInfo; +static int g_iChaosWeaponsIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iChaosWeaponsIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_ChaosWeaponsInfo +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] #define CHAOSWEAPONS_CONVAR_TIMER_INTERVAL 0 #define CHAOSWEAPONS_CONVAR_KNOCKBACK 1 @@ -41,8 +43,19 @@ char g_ChaosWeaponsList[][] = float g_fOriginalWeaponsKB[sizeof(g_ChaosWeaponsList)]; +/* ConVars Values variables */ +float g_fChaosWeapons_TimerInterval; +float g_fChaosWeapons_Knockback; + +int g_iChaosWeapons_Countdown; + +bool g_bChaosWeapons_Enabled; + stock void OnPluginStart_ChaosWeapons() { + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + THIS_MODE_INFO.name = "ChaosWeapons"; THIS_MODE_INFO.tag = "{gold}[FunModes-ChaosWeapons]{lightgreen}"; @@ -53,48 +66,87 @@ stock void OnPluginStart_ChaosWeapons() /* CONVARS */ DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, CHAOSWEAPONS_CONVAR_TIMER_INTERVAL, - "sm_chaosweapons_timer_interval", "30.0", "Every how many seconds to keep picking a random weapon?", - ("10.0,15.0,20.0,30.0"), "float" + CHAOSWEAPONS_CONVAR_TIMER_INTERVAL, "sm_chaosweapons_timer_interval", + "30.0", "Every how many seconds to keep picking a random weapon?", + ("10.0,15.0,20.0,30.0"), CONVAR_FLOAT ); - + + THIS_MODE_INFO.cvars[CHAOSWEAPONS_CONVAR_TIMER_INTERVAL].HookChange(ChaosWeapons_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, CHAOSWEAPONS_CONVAR_KNOCKBACK, - "sm_chaosweapons_knockback", "0.1", "Knockback to set of other weapons", - ("0.1,0.2,0.5,1.0"), "float" + CHAOSWEAPONS_CONVAR_KNOCKBACK, "sm_chaosweapons_knockback", + "0.1", "Knockback to set of other weapons", + ("0.1,0.2,0.5,1.0"), CONVAR_FLOAT ); - + + THIS_MODE_INFO.cvars[CHAOSWEAPONS_CONVAR_KNOCKBACK].HookChange(ChaosWeapons_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, CHAOSWEAPONS_CONVAR_COUNTDOWN, - "sm_chaosweapons_countdown", "10", "How many seconds for the countdown", - ("5,10,15,20"), "int" + CHAOSWEAPONS_CONVAR_COUNTDOWN, "sm_chaosweapons_countdown", + "10", "How many seconds for the countdown", + ("5,10,15,20"), CONVAR_INT ); - + + THIS_MODE_INFO.cvars[CHAOSWEAPONS_CONVAR_COUNTDOWN].HookChange(ChaosWeapons_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, CHAOSWEAPONS_CONVAR_TOGGLE, - "sm_chaosweapons_enable", "1", "Enable/Disable ChaosWeapons Mode (This differs from turning it on/off)", - ("0,1"), "bool" + CHAOSWEAPONS_CONVAR_TOGGLE, "sm_chaosweapons_enable", + "1", "Enable/Disable ChaosWeapons Mode (This differs from turning it on/off)", + ("0,1"), CONVAR_BOOL ); - + + THIS_MODE_INFO.cvars[CHAOSWEAPONS_CONVAR_TOGGLE].HookChange(ChaosWeapons_OnConVarChange); + THIS_MODE_INFO.enableIndex = CHAOSWEAPONS_CONVAR_TOGGLE; - - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; - - THIS_MODE_INFO.cvarInfo[CHAOSWEAPONS_CONVAR_TOGGLE].cvar.AddChangeHook(OnChaosWeaponsModeToggle); } -void OnChaosWeaponsModeToggle(ConVar cvar, const char[] newValue, const char[] oldValue) +void InitCvarsValues_ChaosWeapons() { - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + int modeIndex = THIS_MODE_INFO.index; + + g_fChaosWeapons_TimerInterval = _FUNMODES_CVAR_GET_VALUE(modeIndex, CHAOSWEAPONS_CONVAR_TIMER_INTERVAL, Float); + g_fChaosWeapons_Knockback = _FUNMODES_CVAR_GET_VALUE(modeIndex, CHAOSWEAPONS_CONVAR_KNOCKBACK, Float); + + g_iChaosWeapons_Countdown = _FUNMODES_CVAR_GET_VALUE(modeIndex, CHAOSWEAPONS_CONVAR_COUNTDOWN, Int); + + g_bChaosWeapons_Enabled = _FUNMODES_CVAR_GET_VALUE(modeIndex, CHAOSWEAPONS_CONVAR_TOGGLE, Bool); +} + +void ChaosWeapons_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) +{ + switch (cvarIndex) + { + case CHAOSWEAPONS_CONVAR_TIMER_INTERVAL: + { + g_fChaosWeapons_TimerInterval = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + } + + case CHAOSWEAPONS_CONVAR_KNOCKBACK: + { + g_fChaosWeapons_Knockback = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + } + + case CHAOSWEAPONS_CONVAR_COUNTDOWN: + { + g_iChaosWeapons_Countdown = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + } + + case CHAOSWEAPONS_CONVAR_TOGGLE: + { + bool val = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bChaosWeapons_Enabled = val; + } + } } stock void OnMapStart_ChaosWeapons() {} stock void OnMapEnd_ChaosWeapons() { CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, false, THIS_MODE_INFO.index); - + g_hChaosWeaponsTimer = null; } @@ -132,26 +184,24 @@ stock void Event_PlayerDeath_ChaosWeapons(int client) public Action Cmd_ChaosWeaponsToggle(int client, int args) { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) + if (!g_bChaosWeapons_Enabled) { CReplyToCommand(client, "%s ChaosWeapons Mode is currently Disabled", THIS_MODE_INFO.tag); return Plugin_Handled; } - /* You can change whatever you want here */ CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, !THIS_MODE_INFO.isOn, THIS_MODE_INFO.index); - + CPrintToChatAll("%s ChaosWeapons Mode is now %s!", THIS_MODE_INFO.tag, THIS_MODE_INFO.isOn ? "On" : "Off"); - + if (THIS_MODE_INFO.isOn) { - float interval = THIS_MODE_INFO.cvarInfo[CHAOSWEAPONS_CONVAR_TIMER_INTERVAL].cvar.FloatValue; - g_hChaosWeaponsTimer = CreateTimer(interval, Timer_ChaosWeapons, _, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT); - - CPrintToChatAll("%s a Random weapon will get normal knockback and the others will get their knockback nerfed every %.2f seconds!", THIS_MODE_INFO.tag, interval); - - SetAllWeaponsKnockback(THIS_MODE_INFO.cvarInfo[CHAOSWEAPONS_CONVAR_KNOCKBACK].cvar.FloatValue, _, true); + g_hChaosWeaponsTimer = CreateTimer(g_fChaosWeapons_TimerInterval, Timer_ChaosWeapons, _, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT); + CPrintToChatAll("%s a Random weapon will get normal knockback and the others will get their knockback nerfed every %.2f seconds!", THIS_MODE_INFO.tag, g_fChaosWeapons_TimerInterval); + + SetAllWeaponsKnockback(g_fChaosWeapons_Knockback, _, true); + PickRandomWeapon(); } else @@ -159,7 +209,7 @@ public Action Cmd_ChaosWeaponsToggle(int client, int args) delete g_hChaosWeaponsTimer; SetAllWeaponsKnockback(_, _, _, true); } - + return Plugin_Handled; } @@ -168,7 +218,7 @@ public Action Cmd_ChaosWeaponsSettings(int client, int args) { if (!client) return Plugin_Handled; - + Menu menu = new Menu(Menu_ChaosWeaponsSettings); menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); @@ -177,7 +227,7 @@ public Action Cmd_ChaosWeaponsSettings(int client, int args) menu.ExitBackButton = true; menu.Display(client, MENU_TIME_FOREVER); - + return Plugin_Handled; } @@ -187,7 +237,7 @@ int Menu_ChaosWeaponsSettings(Menu menu, MenuAction action, int param1, int para { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) @@ -210,7 +260,7 @@ Action Timer_ChaosWeapons(Handle timer) g_hChaosWeaponsTimer = null; return Plugin_Handled; } - + CreateTimer(1.0, Timer_ChaosWeaponsRepeat, _, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT); return Plugin_Continue; } @@ -223,49 +273,52 @@ Action Timer_ChaosWeaponsRepeat(Handle timer) counter = 0; return Plugin_Stop; } - - int max = THIS_MODE_INFO.cvarInfo[CHAOSWEAPONS_CONVAR_COUNTDOWN].cvar.IntValue; - - if (++counter >= max) + + if (++counter >= g_iChaosWeapons_Countdown) { counter = 0; PickRandomWeapon(); return Plugin_Stop; } - + char msg[128]; FormatEx ( msg, sizeof(msg), "[ChaosWeapons] The weapon that pushes zombies will change in %d seconds!", - max - counter + g_iChaosWeapons_Countdown - counter ); - + for (int i = 1; i <= MaxClients; i++) { if (!IsClientInGame(i)) continue; - + SendHudText(i, msg, _, 1); } - + return Plugin_Continue; } void PickRandomWeapon() { int index = GetRandomInt(0, sizeof(g_ChaosWeaponsList) - 1); - + FormatEx(g_sChaosWeaponCurrent, sizeof(g_sChaosWeaponCurrent), "weapon_%s", g_ChaosWeaponsList[index]); - SetAllWeaponsKnockback(THIS_MODE_INFO.cvarInfo[CHAOSWEAPONS_CONVAR_KNOCKBACK].cvar.FloatValue, index); - + SetAllWeaponsKnockback(g_fChaosWeapons_Knockback, index); + char msg[255]; - FormatEx(msg, sizeof(msg), "Only the [%s] will push the zombies for the next %d seconds\nPress F to buy it!", StrToUpper(g_ChaosWeaponsList[index]), THIS_MODE_INFO.cvarInfo[CHAOSWEAPONS_CONVAR_TIMER_INTERVAL].cvar.IntValue); - + FormatEx( + msg, sizeof(msg), + "Only the [%s] will push the zombies for the next %.0f seconds\nPress F to buy it!", + StrToUpper(g_ChaosWeaponsList[index]), + g_fChaosWeapons_TimerInterval + ); + for (int i = 1; i <= MaxClients; i++) { if (!IsClientInGame(i)) continue; - + SendHudText(i, msg, _, 1); CPrintToChat(i, "%s %s", THIS_MODE_INFO.tag, msg); } @@ -275,16 +328,16 @@ stock char[] StrToUpper(const char[] buffer) { int len = strlen(buffer); char myChar[32]; - + for (int i = 0; i < len; i++) { char c = buffer[i]; if (c >= 'a' && c <= 'z') c &= ~0x20; - + myChar[i] = c; } - + return myChar; } @@ -297,10 +350,10 @@ void SetAllWeaponsKnockback(float kb = 0.0, int index = -1, bool firstTime = fal ZR_SetWeaponKnockback(g_ChaosWeaponsList[i], g_fOriginalWeaponsKB[i]); continue; } - + if (firstTime) g_fOriginalWeaponsKB[i] = ZR_GetWeaponKnockback(g_ChaosWeaponsList[i]); - + ZR_SetWeaponKnockback(g_ChaosWeaponsList[i], kb); } } @@ -308,53 +361,53 @@ void SetAllWeaponsKnockback(float kb = 0.0, int index = -1, bool firstTime = fal stock void OnPlayerRunCmdPost_ChaosWeapons(int client, int buttons, int impulse) { #pragma unused buttons - + if (!THIS_MODE_INFO.isOn) return; - + if (!IsPlayerAlive(client) || !ZR_IsClientHuman(client)) return; - + static float playersTime[MAXPLAYERS + 1]; - + float currentTime = GetGameTime(); if (currentTime <= playersTime[client]) return; - + // https://github.com/ValveSoftware/source-sdk-2013/blob/7191ecc418e28974de8be3a863eebb16b974a7ef/src/game/server/player.cpp#L6073 if (impulse == 100) { playersTime[client] = currentTime + 2.0; - + char curWeapon[sizeof(g_sChaosWeaponCurrent)]; strcopy(curWeapon, sizeof(curWeapon), g_sChaosWeaponCurrent); - + int weapon = 0; - + ReplaceString(curWeapon, sizeof(curWeapon), "weapon_", ""); int price = ZR_GetWeaponZMarketPrice(curWeapon); - + int cash = GetEntProp(client, Prop_Send, "m_iAccount"); if (cash < price) { CPrintToChat(client, "%s Insufficent fund", THIS_MODE_INFO.tag); return; } - + weapon = GetPlayerWeaponSlot(client, CS_SLOT_PRIMARY); if (IsValidEntity(weapon)) { SDKHooks_DropWeapon(client, weapon); RemoveEntity(weapon); } - + weapon = GivePlayerItem(client, g_sChaosWeaponCurrent); if (!IsValidEntity(weapon)) return; - + if (g_hSwitchSDKCall != null) SDKCall(g_hSwitchSDKCall, client, weapon, 0); - + SetEntProp(client, Prop_Send, "m_iAccount", cash - price); } -} \ No newline at end of file +} diff --git a/addons/sourcemod/scripting/Fun_Modes/Core.sp b/addons/sourcemod/scripting/Fun_Modes/Core.sp deleted file mode 100644 index 62d267f..0000000 --- a/addons/sourcemod/scripting/Fun_Modes/Core.sp +++ /dev/null @@ -1,228 +0,0 @@ -/* - (). FunModes V2: - - @file Core.sp - @Usage Global variables, and modes definition, add the mode names in the end of the file -*/ - -/* Important Variables */ - -/* Event Hooks Booleans */ -bool g_bEvent_RoundStart; -bool g_bEvent_RoundEnd; -bool g_bEvent_PlayerDeath; -bool g_bEvent_PlayerTeam; -bool g_bEvent_PlayerSpawn; -bool g_bEvent_WeaponFire; - -/* Client SDKHook Boolens */ -bool g_bSDKHook_OnTakeDamagePost[MAXPLAYERS + 1] = { false, ... }; -bool g_bSDKHook_WeaponEquip[MAXPLAYERS + 1] = { false, ... }; -bool g_bSDKHook_OnTakeDamage[MAXPLAYERS + 1] = { false, ... }; - -/* Round Checking Booleans */ -bool g_bRoundEnd; - -/* COLORS VARIABLES */ -int g_ColorCyan[4] = {0, 255, 255, 255}; // cyan -int g_ColorDefault[4] = {255, 215, 55, 255}; // default color - -/* Sprites Indexes Integers */ -int g_LaserSprite = -1; -int g_HaloSprite = -1; -int g_iLaserBeam = -1; - -/* Library Checking Booleans */ -bool g_bPlugin_DynamicChannels = false; -bool g_bMotherZombie = false; - -/* HUD HANDLER */ -Handle g_hHudMsg = null; - -/* NORMAL VARIABLES */ -int g_iCounter = 0; - -/* GLOBAL CONVARS */ -ConVar g_cvHUDChannel; -int g_iPreviousModeIndex[MAXPLAYERS+1]; -int g_iNetPropAmmoIndex = -1; - -/* SDKCall Handles */ -Handle g_hSwitchSDKCall; - -#define Beacon_Sound "buttons/blip1.wav" - -#define FFADE_IN (0x0001) // Fade in -#define FFADE_OUT (0x0002) // Fade out -#define FFADE_MODULATE (0x0004) // Modulate (Don't blend) -#define FFADE_STAYOUT (0x0008) // Ignores the duration, stays faded out until a new fade message is received -#define FFADE_PURGE (0x0010) // Purges all other fades, replacing them with this one - -/* Mode Management structs */ -#define MAX_MODES_NUM 32 -#define MAX_CVARS_NUM 10 - -enum struct ConVarInfo -{ - ConVar cvar; - char values[32]; - char type[10]; -} - -enum struct ModeInfo -{ - int index; - char name[32]; - char tag[64]; - ConVarInfo cvarInfo[MAX_CVARS_NUM]; - bool isOn; - int enableIndex; -} - -ModeInfo g_ModesInfo[MAX_MODES_NUM]; -int g_iLastModeIndex; - -enum struct FM_Color -{ - char name[10]; - char rgb[14]; -} - -FM_Color g_ColorsList[] = -{ - { "White", "255 255 255" }, - { "Red", "255 0 0" }, - { "Lime", "0 255 0" }, - { "Blue", "0 0 255" }, - { "Yellow", "255 255 0" }, - { "Cyan", "0 255 255" }, - { "Gold", "255 215 0" } -}; - -enum WeaponAmmoGrenadeType -{ - GrenadeType_HEGrenade = 11, /** CSS - HEGrenade slot */ - GrenadeType_Flashbang = 12, /** CSS - Flashbang slot. */ - GrenadeType_Smokegrenade = 13, /** CSS - Smokegrenade slot. */ -}; - -#define HEGRENADE 11 -#define FLASHBANG 12 -#define SMOKEGRENADE 13 - -#define GET_GRENADES_COUNT(%1,%2) GetEntData(%1, g_iNetPropAmmoIndex + (%2 * 4)) -#define SET_GRENADES_COUNT(%1,%2,%3) SetEntData(%1, g_iNetPropAmmoIndex + (%2 * 4), %3, _, true) - -/* -- New FunModes Update - * The plugin will now use macros to define the main functions and forwards - * Macros are the only way possible for this as sourcepawn is too weak - * Do not edit the macros unless you know what you are doing - -- Things that are useful by macros: - * Only add the mode inside the DECLARE_FM_FORWARD macro, and the mode wll be included - * The include files will still need to be included by a macro - * Flexibility and more funcitonality -*/ -/* Edit the macros when you add a new mode */ -#define CALL_MODE_FUNC(%1,%2) %1_%2() -#define DECLARE_FM_FORWARD(%1) \ - CALL_MODE_FUNC(%1, HealBeacon); \ - CALL_MODE_FUNC(%1, VIPMode); \ - CALL_MODE_FUNC(%1, IC); \ - CALL_MODE_FUNC(%1, Fog); \ - CALL_MODE_FUNC(%1, RLGL); \ - CALL_MODE_FUNC(%1, DoubleJump); \ - CALL_MODE_FUNC(%1, DamageGame); \ - CALL_MODE_FUNC(%1, BlindMode); \ - CALL_MODE_FUNC(%1, SlapMode); \ - CALL_MODE_FUNC(%1, ChaosWeapons); \ - CALL_MODE_FUNC(%1, GunGame); \ - CALL_MODE_FUNC(%1, MathGame); \ - CALL_MODE_FUNC(%1, CrazyShop); \ - CALL_MODE_FUNC(%1, RealityShift); \ - CALL_MODE_FUNC(%1, PullGame) - -#define DECLARE_FM_FORWARD_PARAM(%1,%2) \ - CALL_MODE_FUNC_PARAM(%1, HealBeacon, %2); \ - CALL_MODE_FUNC_PARAM(%1, VIPMode, %2); \ - CALL_MODE_FUNC_PARAM(%1, IC, %2); \ - CALL_MODE_FUNC_PARAM(%1, Fog, %2); \ - CALL_MODE_FUNC_PARAM(%1, RLGL, %2); \ - CALL_MODE_FUNC_PARAM(%1, DoubleJump, %2); \ - CALL_MODE_FUNC_PARAM(%1, DamageGame, %2); \ - CALL_MODE_FUNC_PARAM(%1, BlindMode, %2); \ - CALL_MODE_FUNC_PARAM(%1, GunGame, %2); \ - CALL_MODE_FUNC_PARAM(%1, CrazyShop, %2); \ - CALL_MODE_FUNC_PARAM(%1, RealityShift, %2); \ - CALL_MODE_FUNC_PARAM(%1, PullGame, %2) -#define CALL_MODE_FUNC_PARAM(%1,%2,%3) %1_%2(%3) - -/* -these commented macros are not used for now -#define CALL_MODE_FUNC_PARAM2(%1,%2,%3,%4) %1_%2(%3,%4) -#define DECLARE_FM_FORWARD_PARAM2(%1,%2,%3) \ - CALL_MODE_FUNC_PARAM2(%1, HealBeacon, %2, %3); \ - CALL_MODE_FUNC_PARAM2(%1, VIPMode, %2, %3); \ - CALL_MODE_FUNC_PARAM2(%1, RLGL, %2, %3); \ - CALL_MODE_FUNC_PARAM2(%1, IC, %2, %3); \ - CALL_MODE_FUNC_PARAM2(%1, Fog, %2, %3); \ - CALL_MODE_FUNC_PARAM2(%1, DoubleJump, %2, %3); \ - CALL_MODE_FUNC_PARAM2(%1, DamageGame, %2, %3) -*/ -/* for now there are only 4 modes that use 3 params functions */ -#define CALL_MODE_FUNC_PARAM3(%1,%2,%3,%4,%5) %1_%2(%3,%4,%5) -#define DECLARE_FM_FORWARD_PARAM3(%1,%2,%3,%4) \ - CALL_MODE_FUNC_PARAM3(%1, VIPMode, %2, %3, %4); \ - CALL_MODE_FUNC_PARAM3(%1, DamageGame, %2, %3, %4); \ - CALL_MODE_FUNC_PARAM3(%1, GunGame, %2, %3, %4); \ - CALL_MODE_FUNC_PARAM3(%1, CrazyShop, %2, %3, %4) - -/* For 4 params-functions, only crazyshop and vipmode use it for now */ -#define CALL_MODE_FUNC_PARAM4(%1,%2,%3,%4,%5,%6) %1_%2(%3,%4,%5,%6) -#define DECLARE_FM_FORWARD_PARAM4(%1,%2,%3,%4,%5) \ - CALL_MODE_FUNC_PARAM4(%1, VIPMode, %2, %3, %4, %5); \ - CALL_MODE_FUNC_PARAM4(%1, CrazyShop, %2, %3, %4, %5) - -/* OnPlayerRunCmdPost Calls (Since this is called every frame, we gotta watch out for performance :p) */ -#define DECLARE_ONPLAYERRUNCMD_POST(%1,%2,%3,%4) \ - CALL_MODE_FUNC_PARAM3(%1, DoubleJump, %2, %3, %4); \ - CALL_MODE_FUNC_PARAM3(%1, CrazyShop, %2, %3, %4); \ - CALL_MODE_FUNC_PARAM3(%1, PullGame, %2, %3, %4); \ - CALL_MODE_FUNC_PARAM3(%1, ChaosWeapons, %2, %3, %4) - -/* %0: ConVarInfo[], %1: index, %2: name, %3: default value, %4: description - %5: cvar values, %6: cvar value type -*/ -#define DECLARE_FM_CVAR(%1,%2,%3,%4,%5,%6,%7) \ - %1[%2].cvar = CreateConVar(%3, %4, %5); \ - %1[%2].values = %6; \ - %1[%2].type = %7 - -/* %1: mode struct, %2: variable, %3: value, %4: index */ -#define CHANGE_MODE_INFO(%1,%2,%3,%4) \ - %1.%2 = %3; \ - g_ModesInfo[%4] = %1 - -/* -#define FUNMODE_CONVAR(%1,%2) %1.cvarInfo[%2].cvar -*/ - -#define THIS_MODE_INFO - -/* Add the mode's include file here */ -#include "Fun_Modes/HealBeacon.sp" -#include "Fun_Modes/VIPMode.sp" -#include "Fun_Modes/Fog.sp" -#include "Fun_Modes/RedLightGreenLight.sp" -#include "Fun_Modes/DoubleJump.sp" -#include "Fun_Modes/InvertedControls.sp" -#include "Fun_Modes/DamageGame.sp" -#include "Fun_Modes/BlindMode.sp" -#include "Fun_Modes/SlapMode.sp" -#include "Fun_Modes/ChaosWeapons.sp" -#include "Fun_Modes/GunGame.sp" -#include "Fun_Modes/MathGame.sp" -#include "Fun_Modes/CrazyShop.sp" -#include "Fun_Modes/RealityShift.sp" -#include "Fun_Modes/PullGame.sp" \ No newline at end of file diff --git a/addons/sourcemod/scripting/Fun_Modes/Core/Core.sp b/addons/sourcemod/scripting/Fun_Modes/Core/Core.sp new file mode 100644 index 0000000..25281ba --- /dev/null +++ b/addons/sourcemod/scripting/Fun_Modes/Core/Core.sp @@ -0,0 +1,376 @@ +/* + (). FunModes V2: + + @file Core/Core.sp + @Usage Global variables, and modes definition, add the mode names in the end of the file +*/ + +/* Important Variables */ + +/* Event Hooks Booleans */ +bool g_bEvent_RoundStart; +bool g_bEvent_RoundEnd; +bool g_bEvent_PlayerDeath; +bool g_bEvent_PlayerTeam; +bool g_bEvent_PlayerSpawn; +bool g_bEvent_WeaponFire; + +/* Client SDKHook Boolens */ +bool g_bSDKHook_OnTakeDamagePost[MAXPLAYERS + 1] = { false, ... }; +bool g_bSDKHook_WeaponEquip[MAXPLAYERS + 1] = { false, ... }; +bool g_bSDKHook_OnTakeDamage[MAXPLAYERS + 1] = { false, ... }; + +/* Round Checking Booleans */ +bool g_bRoundEnd; + +/* COLORS VARIABLES */ +int g_ColorCyan[4] = {0, 255, 255, 255}; // cyan +int g_ColorDefault[4] = {255, 215, 55, 255}; // default color + +/* Sprites Indexes Integers */ +int g_LaserSprite = -1; +int g_HaloSprite = -1; +int g_iLaserBeam = -1; + +/* Library Checking Booleans */ +bool g_bPlugin_DynamicChannels = false; +bool g_bMotherZombie = false; + +/* HUD HANDLER */ +Handle g_hHudMsg = null; + +/* NORMAL VARIABLES */ +int g_iCounter = 0; + +/* GLOBAL CONVARS */ +ConVar g_cvHUDChannel; +int g_iPreviousModeIndex[MAXPLAYERS+1]; +int g_iNetPropAmmoIndex = -1; + +/* SDKCall Handles */ +Handle g_hSwitchSDKCall; + +#define Beacon_Sound "buttons/blip1.wav" + +#define FFADE_IN (0x0001) // Fade in +#define FFADE_OUT (0x0002) // Fade out +#define FFADE_MODULATE (0x0004) // Modulate (Don't blend) +#define FFADE_STAYOUT (0x0008) // Ignores the duration, stays faded out until a new fade message is received +#define FFADE_PURGE (0x0010) // Purges all other fades, replacing them with this one + +/* Mode Management structs */ +#define MAX_MODES_NUM 32 +#define MAX_CVARS_NUM 10 + +ModeInfo g_ModesInfo[MAX_MODES_NUM]; +int g_iLastModeIndex; + +/* ConVars Section */ +KeyValues g_hKV; + +#define FUNMODES_CVAR_CONFIG "addons/sourcemod/configs/FunModes/ConVars.cfg" + +enum ConVarType +{ + CONVAR_BOOL = 0, + CONVAR_INT, + CONVAR_FLOAT, + CONVAR_STRING, + CONVAR_NONE +}; + +void FunModes_CallCvarChange(DataPack pack) +{ + pack.Reset(); + + Function hookFunc = pack.ReadFunction(); + int modeIndex = pack.ReadCell(); + int cvarIndex = pack.ReadCell(); + + char oldVal[sizeof(FM_ConVar::currentValue)], currentValue[sizeof(FM_ConVar::currentValue)]; + pack.ReadString(oldVal, sizeof(oldVal)); + pack.ReadString(currentValue, sizeof(currentValue)); + + delete pack; + + Call_StartFunction(null, hookFunc); + + Call_PushCell(modeIndex); + Call_PushCell(cvarIndex); + Call_PushString(oldVal); + Call_PushString(currentValue); + + Call_Finish(); +} + +enum struct FM_ConVar +{ + int modeIndex; + int cvarIndex; + + char name[35]; + char defaultValue[128]; + char description[128]; + + char values[32]; + ConVarType type; + + char currentValue[128]; + + Function hookFunc; + + bool autoChange; + + void HookChange(Function func) + { + this.hookFunc = func; + } + + void OnChange(const char[] oldVal) + { + if (g_hKV && !this.autoChange) + { + char key[5]; + IntToString(this.GetPos(), key, sizeof(key)); + + if (g_hKV.JumpToKey(key)) + { + g_hKV.SetString("currentValue", this.currentValue); + g_hKV.Rewind(); + g_hKV.ExportToFile(FUNMODES_CVAR_CONFIG); + } + } + + if (this.hookFunc == INVALID_FUNCTION) + return; + + // We have to do a RequestFrame to avoid a weird sourcemod bug... + DataPack pack = new DataPack(); + pack.WriteFunction(this.hookFunc); + pack.WriteCell(this.modeIndex); + pack.WriteCell(this.cvarIndex); + pack.WriteString(oldVal); + pack.WriteString(this.currentValue); + + RequestFrame(FunModes_CallCvarChange, pack); + } + + int GetPos() + { + int pos = 0; + for (int i = this.modeIndex - 1; i >= 0; i--) + pos += g_ModesInfo[i].GetCvarsCount(); + + pos += this.cvarIndex; + return pos; + } + + void SetBool(bool val) + { + this.currentValue = ""; + this.currentValue[0] = val ? '1' : '0'; + } + + bool GetBool() + { + return this.type == CONVAR_BOOL && this.currentValue[0] == '1'; + } + + void SetInt(int val) + { + char oldVal[sizeof(FM_ConVar::currentValue)]; + oldVal = this.currentValue; + + IntToString(val, this.currentValue, sizeof(FM_ConVar::currentValue)); + + this.OnChange(oldVal); + } + + int GetInt() + { + if (view_as(this.type) > view_as(CONVAR_FLOAT)) + return -1; + + return StringToInt(this.currentValue); + } + + void SetFloat(float val) + { + char oldVal[sizeof(FM_ConVar::currentValue)]; + oldVal = this.currentValue; + + FloatToString(val, this.currentValue, sizeof(FM_ConVar::currentValue)); + + this.OnChange(oldVal); + } + + float GetFloat() + { + if (view_as(this.type) > view_as(CONVAR_FLOAT)) + return -1.0; + + return StringToFloat(this.currentValue); + } + + void SetString(const char str[sizeof(FM_ConVar::currentValue)]) + { + char oldVal[sizeof(FM_ConVar::currentValue)]; + oldVal = this.currentValue; + + this.currentValue = str; + this.OnChange(oldVal); + } + + char[] GetString() + { + return this.currentValue; + } +} + +enum struct ModeInfo +{ + int index; + char name[32]; + char tag[64]; + FM_ConVar cvars[MAX_CVARS_NUM]; + bool isOn; + int enableIndex; + + int GetCvarsCount() + { + int count; + for (int i = 0; i < sizeof(ModeInfo::cvars); i++) + { + if (this.cvars[i].name[0] == '\0') + continue; + + count++; + } + + return count; + } +} + +enum struct FM_Color +{ + char name[10]; + char rgb[14]; +} + +FM_Color g_ColorsList[] = +{ + { "White", "255 255 255" }, + { "Red", "255 0 0" }, + { "Lime", "0 255 0" }, + { "Blue", "0 0 255" }, + { "Yellow", "255 255 0" }, + { "Cyan", "0 255 255" }, + { "Gold", "255 215 0" } +}; + +enum WeaponAmmoGrenadeType +{ + GrenadeType_HEGrenade = 11, /** CSS - HEGrenade slot */ + GrenadeType_Flashbang = 12, /** CSS - Flashbang slot. */ + GrenadeType_Smokegrenade = 13, /** CSS - Smokegrenade slot. */ +}; + +#define HEGRENADE 11 +#define FLASHBANG 12 +#define SMOKEGRENADE 13 + +#define GET_GRENADES_COUNT(%1,%2) GetEntData(%1, g_iNetPropAmmoIndex + (%2 * 4)) +#define SET_GRENADES_COUNT(%1,%2,%3) SetEntData(%1, g_iNetPropAmmoIndex + (%2 * 4), %3, _, true) + +/* Modes Management Macros */ +#define THIS_MODE_INFO +#define NULL -1 + +/* +* Declares a FunModes cvar related to the current mode the compiler is reading. +* +* @param %1 Cvar index. +* @param %2 Cvar name. +* @param %3 Cvar's default value. +* @param %4 Cvar's description. +* @param %5 Cvar's accepted values. +* @param %6 Cvar's value type. +*/ +#define DECLARE_FM_CVAR(%1,%2,%3,%4,%5,%6) \ + THIS_MODE_INFO.cvars[%1].modeIndex = THIS_MODE_INDEX; \ + THIS_MODE_INFO.cvars[%1].cvarIndex = %1; \ + THIS_MODE_INFO.cvars[%1].name = %2; \ + THIS_MODE_INFO.cvars[%1].defaultValue = %3; \ + THIS_MODE_INFO.cvars[%1].currentValue = %3; \ + THIS_MODE_INFO.cvars[%1].description = %4; \ + THIS_MODE_INFO.cvars[%1].values = %5; \ + THIS_MODE_INFO.cvars[%1].type = %6 + +/* +* Changes the current mode the compiler is reading's info. +* +* @param %1 The mode's struct. +* @param %2 The variable to chnage. +* @param %3 The new value to assign to the variable. +* @param %4 The mode's index. (Unused) +*/ +#define CHANGE_MODE_INFO(%1,%2,%3,%4) \ + %1.%2 = %3 + +/* +* Retrieves a cvar's value. (Using the cvar's enum struct) +* +* @param %1 The cvar's enum struct. +* @param %2 The cvar's data type. +*/ +#define FUNMODES_CVAR_GET_VALUE(%1,%2) %1.Get%2() + +/* +* Sets a cvar's value to another one. (Using the cvar's enum struct) +* +* @param %1 The cvar's enum struct. +* @param %2 The cvar's data type. +* @param %3 The new value. +*/ +#define FUNMODES_CVAR_SET_VALUE(%1,%2,%3) %1.Set%2(%3) \ + + +/* +* Retrieves a cvar's value. (Using the cvar's mode and cvar indexes) +* +* @param %1 The cvar's mode index. +* @param %2 The cvar's index. +* @param %3 The cvar's data type. +*/ +#define _FUNMODES_CVAR_GET_VALUE(%1,%2,%3) g_ModesInfo[%1].cvars[%2].Get%3() + +/* +* Sets a cvar's value to another one. (Using the cvar's mode and cvar indexes) +* +* @param %1 The cvar's mode index. +* @param %2 The cvar's index. +* @param %3 The cvar's data type. +* @param %4 The new value. +*/ +#define _FUNMODES_CVAR_SET_VALUE(%1,%2,%3,%4) g_ModesInfo[%1].cvars[%2].Set%3(%4) + +/* +* Checks if the given cvar is a valid funmodes cvar. +* +* @param %1 The cvar's enum struct. +*/ +#define FUNMODES_CVAR_ISVALID(%1) !(%1.name[0] == '\0' || %1.type == CONVAR_NONE) + +/* +* Registers a FunMode and adds it to the modes array. +* +* @param %1 The name of the mode. +* @param %2 The tag of the mode. +* @param %3 The index of the enable/disable cvar relative to the mode. +*/ +#define FUNMODES_REGISTER_MODE() \ + THIS_MODE_INDEX = g_iLastModeIndex++; \ + THIS_MODE_INFO.index = THIS_MODE_INDEX + +#include "ModesInclude.sp" +#include "ModesDefinition.sp" diff --git a/addons/sourcemod/scripting/Fun_Modes/Core/ModesDefinition.sp b/addons/sourcemod/scripting/Fun_Modes/Core/ModesDefinition.sp new file mode 100644 index 0000000..3bf1ad4 --- /dev/null +++ b/addons/sourcemod/scripting/Fun_Modes/Core/ModesDefinition.sp @@ -0,0 +1,160 @@ +/* + (). FunModes V2: + + @file Core/ModesDefinition.sp + @Usage Modes definition, Any new mode that's added should also be declared and defined in this file. +*/ + +#pragma newdecls required +#pragma semicolon 1 + +/* +* Call specific mode functions with no param. +* +* @param %1 The name of the forward. +* @param %2 The name of the mode. +*/ +#define CALL_MODE_FUNC(%1,%2) %1_%2() + +/* +* Declares all available function calls for a forward with no param. +* +* @param %1 The name of the forward. +*/ +#define DECLARE_FM_FORWARD(%1) \ + CALL_MODE_FUNC(%1, HealBeacon); \ + CALL_MODE_FUNC(%1, VIPMode); \ + CALL_MODE_FUNC(%1, Fog); \ + CALL_MODE_FUNC(%1, RLGL); \ + CALL_MODE_FUNC(%1, DoubleJump); \ + CALL_MODE_FUNC(%1, IC); \ + CALL_MODE_FUNC(%1, DamageGame); \ + CALL_MODE_FUNC(%1, BlindMode); \ + CALL_MODE_FUNC(%1, SlapMode); \ + CALL_MODE_FUNC(%1, ChaosWeapons); \ + CALL_MODE_FUNC(%1, GunGame); \ + CALL_MODE_FUNC(%1, MathGame); \ + CALL_MODE_FUNC(%1, CrazyShop); \ + CALL_MODE_FUNC(%1, RealityShift); \ + CALL_MODE_FUNC(%1, PullGame) + +/* +* Call specific mode functions with 1 param. +* +* @param %1 The name of the forward. +* @param %2 The name of the mode. +* @param %3 The first param. +*/ +#define CALL_MODE_FUNC_PARAM(%1,%2,%3) %1_%2(%3) + +/* +* Declares all available function calls for a forward with 1 param. +* +* @param %1 The name of the forward. +* @param %2 The first param. +*/ +#define DECLARE_FM_FORWARD_PARAM(%1,%2) \ + CALL_MODE_FUNC_PARAM(%1, HealBeacon, %2); \ + CALL_MODE_FUNC_PARAM(%1, VIPMode, %2); \ + CALL_MODE_FUNC_PARAM(%1, IC, %2); \ + CALL_MODE_FUNC_PARAM(%1, Fog, %2); \ + CALL_MODE_FUNC_PARAM(%1, RLGL, %2); \ + CALL_MODE_FUNC_PARAM(%1, DoubleJump, %2); \ + CALL_MODE_FUNC_PARAM(%1, DamageGame, %2); \ + CALL_MODE_FUNC_PARAM(%1, BlindMode, %2); \ + CALL_MODE_FUNC_PARAM(%1, GunGame, %2); \ + CALL_MODE_FUNC_PARAM(%1, CrazyShop, %2); \ + CALL_MODE_FUNC_PARAM(%1, RealityShift, %2); \ + CALL_MODE_FUNC_PARAM(%1, PullGame, %2) + +/* +* Call specific mode functions with 2 params. +* +* @param %1 The name of the forward. +* @param %2 The name of the mode. +* @param %3 The first param. +* @param %4 The second param. +*/ +#define CALL_MODE_FUNC_PARAM2(%1,%2,%3,%4) %1_%2(%3,%4) + +/* +* Declares all available function calls for a forward with 2 params. (Not used for now) +* +* @param %1 The name of the forward. +* @param %2 The first param. +* @param %3 The second param. +*/ +/* +#define DECLARE_FM_FORWARD_PARAM2(%1,%2,%3) \ + CALL_MODE_FUNC_PARAM2(%1, HealBeacon, %2, %3); \ + CALL_MODE_FUNC_PARAM2(%1, VIPMode, %2, %3); \ + CALL_MODE_FUNC_PARAM2(%1, RLGL, %2, %3); \ + CALL_MODE_FUNC_PARAM2(%1, IC, %2, %3); \ + CALL_MODE_FUNC_PARAM2(%1, Fog, %2, %3); \ + CALL_MODE_FUNC_PARAM2(%1, DoubleJump, %2, %3); \ + CALL_MODE_FUNC_PARAM2(%1, DamageGame, %2, %3) +*/ + +/* +* Call specific mode functions with 3 params. +* +* @param %1 The name of the forward. +* @param %2 The name of the mode. +* @param %3 The first param. +* @param %4 The second param. +* @param %5 The third param. +*/ +#define CALL_MODE_FUNC_PARAM3(%1,%2,%3,%4,%5) %1_%2(%3,%4,%5) + +/* +* Declares all available function calls for a forward with 3 params. +* +* @param %1 The name of the forward. +* @param %2 The first param. +* @param %3 The second param. +* @param %4 The third param. +*/ +#define DECLARE_FM_FORWARD_PARAM3(%1,%2,%3,%4) \ + CALL_MODE_FUNC_PARAM3(%1, VIPMode, %2, %3, %4); \ + CALL_MODE_FUNC_PARAM3(%1, DamageGame, %2, %3, %4); \ + CALL_MODE_FUNC_PARAM3(%1, GunGame, %2, %3, %4); \ + CALL_MODE_FUNC_PARAM3(%1, CrazyShop, %2, %3, %4) + +/* +* Call specific mode functions with 4 params. +* +* @param %1 The name of the forward. +* @param %2 The name of the mode. +* @param %3 The first param. +* @param %4 The second param. +* @param %5 The third param. +* @param %6 The fourth param. +*/ +#define CALL_MODE_FUNC_PARAM4(%1,%2,%3,%4,%5,%6) %1_%2(%3,%4,%5,%6) + +/* +* Declares all available function calls for a forward with 4 params. +* +* @param %1 The name of the forward. +* @param %2 The first param. +* @param %3 The second param. +* @param %4 The third param. +* @param %5 The fourth param. +*/ +#define DECLARE_FM_FORWARD_PARAM4(%1,%2,%3,%4,%5) \ + CALL_MODE_FUNC_PARAM4(%1, VIPMode, %2, %3, %4, %5); \ + CALL_MODE_FUNC_PARAM4(%1, CrazyShop, %2, %3, %4, %5) + +/* +* Declares all available function calls for OnPlayerRunCmdPost. +* +* @param %1 The name of the forward. +* @param %2 The first param (client). +* @param %3 The second param (buttons). +* @param %4 The third param (impulse). +*/ +#define DECLARE_ONPLAYERRUNCMD_POST(%1,%2,%3,%4) \ + CALL_MODE_FUNC_PARAM3(%1, DoubleJump, %2, %3, %4); \ + CALL_MODE_FUNC_PARAM3(%1, CrazyShop, %2, %3, %4); \ + CALL_MODE_FUNC_PARAM3(%1, PullGame, %2, %3, %4); \ + CALL_MODE_FUNC_PARAM3(%1, ChaosWeapons, %2, %3, %4) diff --git a/addons/sourcemod/scripting/Fun_Modes/Core/ModesInclude.sp b/addons/sourcemod/scripting/Fun_Modes/Core/ModesInclude.sp new file mode 100644 index 0000000..687636a --- /dev/null +++ b/addons/sourcemod/scripting/Fun_Modes/Core/ModesInclude.sp @@ -0,0 +1,25 @@ +/* + (). FunModes V2: + + @file Core/ModesInclude.sp + @Usage Modes Include, Any new mode that's added should be included to the plugin by this file. +*/ + +#pragma newdecls required +#pragma semicolon 1 + +#include "../HealBeacon.sp" +#include "../VIPMode.sp" +#include "../Fog.sp" +#include "../RedLightGreenLight.sp" +#include "../DoubleJump.sp" +#include "../InvertedControls.sp" +#include "../DamageGame.sp" +#include "../BlindMode.sp" +#include "../SlapMode.sp" +#include "../ChaosWeapons.sp" +#include "../GunGame.sp" +#include "../MathGame.sp" +#include "../CrazyShop.sp" +#include "../RealityShift.sp" +#include "../PullGame.sp" diff --git a/addons/sourcemod/scripting/Fun_Modes/CrazyShop.sp b/addons/sourcemod/scripting/Fun_Modes/CrazyShop.sp index 738e881..145bca9 100644 --- a/addons/sourcemod/scripting/Fun_Modes/CrazyShop.sp +++ b/addons/sourcemod/scripting/Fun_Modes/CrazyShop.sp @@ -30,10 +30,13 @@ #pragma semicolon 1 #pragma newdecls required -ModeInfo g_CrazyShopInfo; +static int g_iCrazyShopIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iCrazyShopIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_CrazyShopInfo +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] #define CRAZYSHOP_CONVAR_DAMAGE 0 #define CRAZYSHOP_CONVAR_CREDITS 1 @@ -197,67 +200,118 @@ Database g_hCrazyShop_DB; /***************************************************************/ #define PROP_MODEL "models/props/cs_office/vending_machine.mdl" +int g_iCrazyShop_DamageRequired; +int g_iCrazyShop_CreditsReward; + +bool g_bCrazyShop_SaveCredits; +bool g_bCrazyShop_DisableShop; +bool g_bCrazyShop_Enabled; + +float g_fCrazyShop_SlowBeaconRadius; + stock void OnPluginStart_CrazyShop() { + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + THIS_MODE_INFO.name = "CrazyShop"; THIS_MODE_INFO.tag = "{gold}[FunModes-CrazyShop]{lightgreen}"; - + /* COMMANDS */ /* THESE ARE THE STANDARD COMMANDS THAT ALL MODES SHOULD HAVE */ RegAdminCmd("sm_fm_crazyshop", Cmd_CrazyShopToggle, ADMFLAG_CONVARS, "Turn CrazyShop Mode On/Off"); RegAdminCmd("sm_crazyshop_settings", Cmd_CrazyShopSettings, ADMFLAG_CONVARS, "Open CrazyShop Sttings Menu"); RegConsoleCmd("sm_crazyshop", Cmd_CrazyShopMenu, "Open the CrazyShop Menu"); RegConsoleCmd("sm_myitems", Cmd_CrazyShopMyItems, "Open the Available Items Menu"); - + /* CONVARS */ DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, CRAZYSHOP_CONVAR_DAMAGE, - "sm_crazyshop_damage", "5000", "The needed damage for humans to be rewarded with credits", - ("200,500,1000,1500,2000"), "int" + CRAZYSHOP_CONVAR_DAMAGE, "sm_crazyshop_damage", + "5000", "The needed damage for humans to be rewarded with credits", + ("200,500,1000,1500,2000"), CONVAR_INT ); - + THIS_MODE_INFO.cvars[CRAZYSHOP_CONVAR_DAMAGE].HookChange(CrazyShop_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, CRAZYSHOP_CONVAR_CREDITS, - "sm_crazyshop_credits", "1", "How many credits to reward the human when they reach the needed damage?", - ("1,2,3,4,5"), "int" + CRAZYSHOP_CONVAR_CREDITS, "sm_crazyshop_credits", + "1", "How many credits to reward the human when they reach the needed damage?", + ("1,2,3,4,5"), CONVAR_INT ); - + THIS_MODE_INFO.cvars[CRAZYSHOP_CONVAR_CREDITS].HookChange(CrazyShop_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, CRAZYSHOP_CONVAR_SAVECREDITS, - "sm_crazyshop_savecredits", "1", "Save credits to a database or not", - ("0,1"), "bool" + CRAZYSHOP_CONVAR_SAVECREDITS, "sm_crazyshop_savecredits", + "1", "Save credits to a database or not", + ("0,1"), CONVAR_BOOL ); - + THIS_MODE_INFO.cvars[CRAZYSHOP_CONVAR_SAVECREDITS].HookChange(CrazyShop_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, CRAZYSHOP_CONVAR_SLOWBEACON_RADIUS, - "sm_crazyshop_slowbeacon_radius", "400.0", "Slow Beacon Radius", - ("300.0,400.0,500.0,600.0,700.0"), "float" + CRAZYSHOP_CONVAR_SLOWBEACON_RADIUS, "sm_crazyshop_slowbeacon_radius", + "400.0", "Slow Beacon Radius", + ("300.0,400.0,500.0,600.0,700.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[CRAZYSHOP_CONVAR_SLOWBEACON_RADIUS].HookChange(CrazyShop_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, CRAZYSHOP_CONVAR_DISABLE_SHOP, - "sm_crazyshop_disable_shop", "0", "Enable/Disable the !crazyshop command", - ("0,1"), "bool" + CRAZYSHOP_CONVAR_DISABLE_SHOP, "sm_crazyshop_disable_shop", + "0", "Enable/Disable the !crazyshop command", + ("0,1"), CONVAR_BOOL ); - + THIS_MODE_INFO.cvars[CRAZYSHOP_CONVAR_DISABLE_SHOP].HookChange(CrazyShop_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, CRAZYSHOP_CONVAR_TOGGLE, - "sm_crazyshop_enable", "1", "Enable/Disable CrazyShop Mode (This differs from turning it on/off)", - ("0,1"), "bool" + CRAZYSHOP_CONVAR_TOGGLE, "sm_crazyshop_enable", + "1", "Enable/Disable CrazyShop Mode (This differs from turning it on/off)", + ("0,1"), CONVAR_BOOL ); - + THIS_MODE_INFO.cvars[CRAZYSHOP_CONVAR_TOGGLE].HookChange(CrazyShop_OnConVarChange); + THIS_MODE_INFO.enableIndex = CRAZYSHOP_CONVAR_TOGGLE; - - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; - - THIS_MODE_INFO.cvarInfo[CRAZYSHOP_CONVAR_TOGGLE].cvar.AddChangeHook(OnCrazyShopModeToggle); } -void OnCrazyShopModeToggle(ConVar cvar, const char[] newValue, const char[] oldValue) +void InitCvarsValues_CrazyShop() { - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + int modeIndex = THIS_MODE_INFO.index; + + g_iCrazyShop_DamageRequired = _FUNMODES_CVAR_GET_VALUE(modeIndex, CRAZYSHOP_CONVAR_DAMAGE, Int); + g_iCrazyShop_CreditsReward = _FUNMODES_CVAR_GET_VALUE(modeIndex, CRAZYSHOP_CONVAR_CREDITS, Int); + + g_bCrazyShop_SaveCredits = _FUNMODES_CVAR_GET_VALUE(modeIndex, CRAZYSHOP_CONVAR_SAVECREDITS, Bool); + g_fCrazyShop_SlowBeaconRadius = _FUNMODES_CVAR_GET_VALUE(modeIndex, CRAZYSHOP_CONVAR_SLOWBEACON_RADIUS, Float); + g_bCrazyShop_DisableShop = _FUNMODES_CVAR_GET_VALUE(modeIndex, CRAZYSHOP_CONVAR_DISABLE_SHOP, Bool); + + g_bCrazyShop_Enabled = _FUNMODES_CVAR_GET_VALUE(modeIndex, CRAZYSHOP_CONVAR_TOGGLE, Bool); +} + +void CrazyShop_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) +{ + switch (cvarIndex) + { + case CRAZYSHOP_CONVAR_DAMAGE: + g_iCrazyShop_DamageRequired = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + case CRAZYSHOP_CONVAR_CREDITS: + g_iCrazyShop_CreditsReward = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + case CRAZYSHOP_CONVAR_SAVECREDITS: + g_bCrazyShop_SaveCredits = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + + case CRAZYSHOP_CONVAR_SLOWBEACON_RADIUS: + g_fCrazyShop_SlowBeaconRadius = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case CRAZYSHOP_CONVAR_DISABLE_SHOP: + g_bCrazyShop_DisableShop = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + + case CRAZYSHOP_CONVAR_TOGGLE: + { + bool val = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bCrazyShop_Enabled = val; + } + } } stock void OnMapStart_CrazyShop() @@ -268,7 +322,7 @@ stock void OnMapStart_CrazyShop() stock void OnMapEnd_CrazyShop() { CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, false, THIS_MODE_INFO.index); - + g_iCrazyShopProps = 0; } @@ -276,13 +330,13 @@ stock void OnClientPutInServer_CrazyShop(int client) { if (!THIS_MODE_INFO.isOn) return; - + if (!g_bSDKHook_OnTakeDamagePost[client]) { SDKHook(client, SDKHook_OnTakeDamagePost, OnTakeDamagePost); g_bSDKHook_OnTakeDamagePost[client] = true; } - + if (!g_bSDKHook_OnTakeDamage[client]) { SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage); @@ -292,22 +346,25 @@ stock void OnClientPutInServer_CrazyShop(int client) stock void OnClientDisconnect_CrazyShop(int client) { + if (!THIS_MODE_INFO.isOn || THIS_MODE_DB == null) + return; + for (int i = 1; i <= MaxClients; i++) { if (PLAYER_TEMP_VAR(i, grabbedTarget) == client) PLAYER_TEMP_VAR(i, grabbedTarget) = -1; } - + if (!THIS_MODE_INFO.isOn || THIS_MODE_DB == null) return; - + if (!PLAYER_IN_DB(client)) CrazyShop_DB_AddPlayer(client); else CrazyShop_DB_SaveCredits(client); - + CrazyShop_DB_CheckItems(client); - + PLAYER_RESET(client); } @@ -319,12 +376,13 @@ stock void ZR_OnClientInfected_CrazyShop(int client) stock void Event_RoundStart_CrazyShop() { g_iCrazyShopProps = 0; - + for (int i = 1; i <= MaxClients; i++) PLAYER_RESET_TEMP_VARS(i); } stock void Event_RoundEnd_CrazyShop() {} + stock void Event_PlayerSpawn_CrazyShop(int client) { #pragma unused client @@ -345,32 +403,32 @@ stock void Event_WeaponFire_CrazyShop(Event event, const char[] name, bool dontB { if (!THIS_MODE_INFO.isOn) return; - + int client = GetClientOfUserId(event.GetInt("userid")); if (!PLAYER_TEMP_VAR(client, superWeapon) && !PLAYER_TEMP_VAR(client, unlimitedAmmo)) return; - + int weapon = GetEntPropEnt(client, Prop_Data, "m_hActiveWeapon"); if (!IsValidEntity(weapon)) return; - + if (weapon != GetPlayerWeaponSlot(client, CS_SLOT_PRIMARY) && weapon != GetPlayerWeaponSlot(client, CS_SLOT_SECONDARY)) return; - + int clip1 = GetEntProp(weapon, Prop_Send, "m_iClip1"); if (GetEntProp(weapon, Prop_Send, "m_iState", 4, 0) != 2 || !clip1) return; - + int toAdd = 1; char weaponClassname[32]; GetEntityClassname(weapon, weaponClassname, sizeof(weaponClassname)); - + if (strcmp(weaponClassname, "weapon_glock") == 0 || strcmp(weaponClassname, "weapon_famas") == 0) { if (GetEntProp(weapon, Prop_Send, "m_bBurstMode")) toAdd = clip1; } - + SetEntProp(weapon, Prop_Send, "m_iClip1", clip1 + toAdd); } @@ -378,23 +436,23 @@ stock void OnTakeDamagePost_CrazyShop(int victim, int attacker, float damage) { if (!THIS_MODE_INFO.isOn) return; - + if (!(1<=attacker<=MaxClients) || !IsPlayerAlive(victim) || !IsPlayerAlive(attacker) || !ZR_IsClientZombie(victim) || !ZR_IsClientHuman(attacker)) return; - + if (PLAYER_TEMP_VAR(attacker, superWeapon)) return; - + DAMAGE_DEALT(attacker) += RoundToNearest(damage); - - if (DAMAGE_DEALT(attacker) >= THIS_MODE_INFO.cvarInfo[CRAZYSHOP_CONVAR_DAMAGE].cvar.IntValue) + + if (DAMAGE_DEALT(attacker) >= g_iCrazyShop_DamageRequired) { - int credits = THIS_MODE_INFO.cvarInfo[CRAZYSHOP_CONVAR_CREDITS].cvar.IntValue; + int credits = g_iCrazyShop_CreditsReward; if (credits <= 0) return; - + CPrintToChat(attacker, "%s You have been given {olive}%d credits {lightgreen}for damaging the zombies!", THIS_MODE_INFO.tag, credits); - + PLAYER_CREDITS(attacker) += credits; DAMAGE_DEALT(attacker) = 0; } @@ -411,66 +469,66 @@ stock void OnTakeDamage_CrazyShop(int victim, int &attacker, float &damage, Acti { if (!THIS_MODE_INFO.isOn) return; - + bool isVictimAlive = IsPlayerAlive(victim); bool isAttackerAlive = (1 <= attacker <= MaxClients) && IsPlayerAlive(attacker); - + bool isVictimZombie = ZR_IsClientZombie(victim); bool isAttackerZombie = (1 <= attacker <= MaxClients) && ZR_IsClientZombie(attacker); - + // victim is for sure gonna be a real player, so no need to check - + // check if victim is a human and has laser protect if (PLAYER_TEMP_VAR(victim, laserProtect) && isVictimAlive && !isVictimZombie) { if (!IsValidEntity(attacker)) return; - + char classname[32]; if (!GetEntityClassname(attacker, classname, sizeof(classname))) return; - + /* if attacker entity is not trigger_hurt */ if (strcmp(classname, "trigger_hurt") != 0) return; - + /* we should now check if trigger_hurt is from a laser */ - int parent = GetEntPropEnt(attacker, Prop_Data, "m_hParent"); + int parent = GetEntPropEnt(attacker, Prop_Data, "m_hParent"); if (!IsValidEntity(parent)) return; - + bool isFromLaser = false; char parentClassName[64]; if (!GetEntityClassname(parent, parentClassName, sizeof(parentClassName))) return; - + if (strcmp(parentClassName, "func_movelinear") == 0 || strcmp(parentClassName, "func_door") == 0) isFromLaser = true; - + if (!isFromLaser) return; - + damage = 0.0; result = Plugin_Changed; return; } - + // check if victim is a zombie and attacker is human for ignite immunity and kb protection if ((PLAYER_TEMP_VAR(victim, igniteImmunity) || PLAYER_TEMP_VAR(victim, kbProtect)) && isVictimAlive && isVictimZombie) { if (isAttackerZombie) return; - + if (PLAYER_TEMP_VAR(victim, kbProtect)) { damage -= damage * g_CrazyShopItems[8].amount; result = Plugin_Changed; return; } - + RequestFrame(CrazyShop_CheckIgnite, GetClientUserId(victim)); } - + if (isAttackerAlive && !isAttackerZombie && PLAYER_TEMP_VAR(attacker, superWeapon)) { if (!isVictimAlive || !isVictimZombie) @@ -480,13 +538,13 @@ stock void OnTakeDamage_CrazyShop(int victim, int &attacker, float &damage, Acti GetClientWeapon(attacker, weaponName, sizeof(weaponName)); if (strcmp(weaponName, PLAYER_TEMP_VAR(attacker, superWeaponName)) != 0) return; - + damage *= g_CrazyShopItems[2].amount; int flags = GetEntityFlags(victim); - + if (!(flags & FL_ONFIRE)) IgniteEntity(victim, 5.0); - + result = Plugin_Changed; } } @@ -496,9 +554,9 @@ void CrazyShop_CheckIgnite(int userid) int victim = GetClientOfUserId(userid); if (!victim) return; - + int flags = GetEntityFlags(victim); - + if (flags & FL_ONFIRE) { flags &= ~FL_ONFIRE; @@ -507,7 +565,7 @@ void CrazyShop_CheckIgnite(int userid) { char className[12]; GetEntityClassname(effect, className, sizeof(className)); - + if (strcmp(className, "entityflame") == 0) RemoveEntity(effect); } @@ -517,22 +575,22 @@ void CrazyShop_CheckIgnite(int userid) stock void OnPlayerRunCmdPost_CrazyShop(int client, int buttons, int impulse) { #pragma unused buttons - + if (!THIS_MODE_INFO.isOn) return; - + if (!IsPlayerAlive(client)) return; - + float currentTime = GetGameTime(); if (currentTime <= PLAYER_TEMP_VAR(client, lastUse)) return; - + // https://github.com/ValveSoftware/source-sdk-2013/blob/7191ecc418e28974de8be3a863eebb16b974a7ef/src/game/server/player.cpp#L6073 if (impulse == 100) - { + { PLAYER_TEMP_VAR(client, lastUse) = currentTime + 2.0; - CrazyShop_OpenAvailableItems(client); + CrazyShop_OpenAvailableItems(client); } } @@ -542,10 +600,10 @@ public void OnClientPostAdminCheck(int client) { if (!THIS_MODE_INFO.isOn || THIS_MODE_DB == null) return; - + if (IsFakeClient(client)) return; - + CrazyShop_DB_GetData(client, CRAZYSHOP_DB_DATA_COLUMN, "credits"); CrazyShop_DB_GetData(client, CRAZYSHOP_DB_ITEMS_DATA_COLUMN, "item,count"); } @@ -558,10 +616,10 @@ void CrazyShop_DB_OnConnect(Database db, const char[] error, any data) LogError("[FM-%s] Couldn't connect to database, error: %s", THIS_MODE_INFO.name, error); return; } - + THIS_MODE_DB = db; THIS_MODE_DB.SetCharset("utf8mb4"); - + CrazyShop_DB_CreateTables(); } @@ -569,46 +627,46 @@ void CrazyShop_DB_CreateTables() { char driver[10]; THIS_MODE_DB.Driver.GetIdentifier(driver, sizeof(driver)); - + if (strcmp(driver, "sqlite", false) != 0) { delete THIS_MODE_DB; LogError("[FM-%s] Only SQLITE is supported", THIS_MODE_INFO.name); return; } - + Transaction tr = SQL_CreateTransaction(); char query[1024]; - THIS_MODE_DB.Format(query, sizeof(query), + THIS_MODE_DB.Format(query, sizeof(query), "CREATE TABLE IF NOT EXISTS `%s` (" ... "`client_steamid` INTEGER PRIMARY KEY NOT NULL," ... "`credits` INTEGER NOT NULL)", CRAZYSHOP_DB_DATA_COLUMN); - + tr.AddQuery(query); - + THIS_MODE_DB.Format(query, sizeof(query), "CREATE TABLE IF NOT EXISTS `%s` (" ... "`client_steamid` INTEGER NOT NULL," ... "`item` INTEGER NOT NULL," ... "`count` INTEGER NOT NULL," ... "UNIQUE(`client_steamid`, `item`))", CRAZYSHOP_DB_ITEMS_DATA_COLUMN); - + tr.AddQuery(query); - + THIS_MODE_DB.Execute(tr, DB_CrazyShop_TablesOnSuccess, DB_CrazyShop_TablesOnError, _, DBPrio_High); } void DB_CrazyShop_TablesOnSuccess(Database database, any data, int queries, Handle[] results, any[] queryData) { LogMessage("[FM-%s] Successfully created tables (SQLITE)", THIS_MODE_INFO.name); - + // here is where we get players' credits and items: for (int i = 1; i <= MaxClients; i++) { if (!IsClientInGame(i) || IsFakeClient(i)) continue; - + CrazyShop_DB_GetData(i, CRAZYSHOP_DB_DATA_COLUMN, "credits"); CrazyShop_DB_GetData(i, CRAZYSHOP_DB_ITEMS_DATA_COLUMN, "item,count"); } @@ -624,14 +682,14 @@ void CrazyShop_DB_GetData(int client, const char[] table, const char[] column) int steamID = GetSteamAccountID(client); if (!steamID) return; - + char query[1024]; THIS_MODE_DB.Format(query, sizeof(query), "SELECT %s FROM `%s` WHERE `client_steamid`=%d", column, table, steamID); - + DataPack pack = new DataPack(); pack.WriteCell(GetClientUserId(client)); pack.WriteCell(column[0]); - + THIS_MODE_DB.Query(DB_CrazyShop_OnGetData, query, pack, DBPrio_Normal); } @@ -643,28 +701,28 @@ void DB_CrazyShop_OnGetData(Database db, DBResultSet results, const char[] error delete pack; return; } - + if (results == null || !results.RowCount) { delete pack; return; } - + pack.Reset(); - + int client = GetClientOfUserId(pack.ReadCell()); if (!client) { delete pack; return; } - + bool isCredits = pack.ReadCell() == 'c'; delete pack; - + if (!results.FetchRow()) return; - + if (isCredits) { PLAYER_IN_DB(client) = true; @@ -678,7 +736,7 @@ void DB_CrazyShop_OnGetData(Database db, DBResultSet results, const char[] error { int item = results.FetchInt(0); int count = results.FetchInt(1); - + PLAYER_ITEM_COUNT(client, item) = count; PLAYER_ITEM_COUNT_OG(client, item) = count; } @@ -690,12 +748,12 @@ void CrazyShop_DB_AddPlayer(int client) int steamID = GetSteamAccountID(client); if (!steamID) return; - + char query[1024]; THIS_MODE_DB.Format(query, sizeof(query), "INSERT INTO `%s` (`client_steamid`, `credits`) VALUES (%d, %d) " ... "ON CONFLICT(`client_steamid`) DO UPDATE SET `credits`=excluded.credits", CRAZYSHOP_DB_DATA_COLUMN, steamID, PLAYER_CREDITS(client)); - + THIS_MODE_DB.Query(DB_CrazyShop_OnAddPlayer, query, _, DBPrio_High); } @@ -710,11 +768,11 @@ void CrazyShop_DB_SaveCredits(int client) int steamID = GetSteamAccountID(client); if (!steamID) return; - + char query[1024]; THIS_MODE_DB.Format(query, sizeof(query), "UPDATE `%s` SET `credits`=%d WHERE `client_steamid`=%d", CRAZYSHOP_DB_DATA_COLUMN, PLAYER_CREDITS(client), steamID); - + THIS_MODE_DB.Query(DB_CrazyShop_OnSaveCredits, query, _, DBPrio_High); } @@ -729,7 +787,7 @@ void CrazyShop_DB_CheckItems(int client) int steamID = GetSteamAccountID(client); if (!steamID) return; - + char query[1024]; bool hasItems = false; for (int i = 0; i < sizeof(CrazyShop_PlayerData::itemsCount); i++) @@ -740,12 +798,12 @@ void CrazyShop_DB_CheckItems(int client) break; } } - + if (!hasItems) { THIS_MODE_DB.Format(query, sizeof(query), "DELETE FROM `%s` WHERE `client_steamid`=%d", CRAZYSHOP_DB_ITEMS_DATA_COLUMN, steamID); - + THIS_MODE_DB.Query(DB_CrazyShop_OnCheckItems, query, _, DBPrio_High); } else @@ -756,7 +814,7 @@ void CrazyShop_DB_CheckItems(int client) ... "(%d, %d, %d) ON CONFLICT(`client_steamid`, `item`) DO UPDATE SET " ... "`count` = excluded.count WHERE `count` != excluded.count", CRAZYSHOP_DB_ITEMS_DATA_COLUMN, steamID, i, PLAYER_ITEM_COUNT(client, i)); - + THIS_MODE_DB.Query(DB_CrazyShop_OnCheckItems, query, _, DBPrio_High); } } @@ -770,47 +828,55 @@ void DB_CrazyShop_OnCheckItems(Database db, DBResultSet results, const char[] er public Action Cmd_CrazyShopToggle(int client, int args) { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) + if (!g_bCrazyShop_Enabled) { CReplyToCommand(client, "%s CrazyShop Mode is currently Disabled", THIS_MODE_INFO.tag); return Plugin_Handled; } - /* You can change whatever you want here */ CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, !THIS_MODE_INFO.isOn, THIS_MODE_INFO.index); - + CPrintToChatAll("%s CrazyShop Mode is now %s!", THIS_MODE_INFO.tag, THIS_MODE_INFO.isOn ? "On" : "Off"); - + if (THIS_MODE_INFO.isOn) { FunModes_HookEvent(g_bEvent_RoundStart, "round_start", Event_RoundStart); FunModes_HookEvent(g_bEvent_RoundEnd, "round_end", Event_RoundEnd); - + CPrintToChatAll("%s Earn credits by defending and shooting the zombies!", THIS_MODE_INFO.tag); CPrintToChatAll("%s Type {olive}!crazyshop {lightgreen}to open the Shop Menu and buy powerful items!", THIS_MODE_INFO.tag); - - if (THIS_MODE_INFO.cvarInfo[CRAZYSHOP_CONVAR_SAVECREDITS].cvar.BoolValue && THIS_MODE_DB == null) + + if (g_bCrazyShop_SaveCredits && THIS_MODE_DB == null) Database.Connect(CrazyShop_DB_OnConnect, CRAZYSHOP_DB_NAME); - + CrazyShop_GetItems(); - + for (int i = 1; i <= MaxClients; i++) { if (!IsClientInGame(i) || IsClientSourceTV(i)) continue; - + SDKHook(i, SDKHook_OnTakeDamage, OnTakeDamage); SDKHook(i, SDKHook_OnTakeDamagePost, OnTakeDamagePost); g_bSDKHook_OnTakeDamagePost[i] = true; g_bSDKHook_OnTakeDamage[i] = true; } - - // Restart the round + FunModes_RestartRound(); } else - delete THIS_MODE_DB; - + { + THIS_MODE_INFO.isOn = true; + for (int i = 1; i <= MaxClients; i++) + { + if (!IsClientInGame(i) || IsFakeClient(i)) + continue; + + OnClientDisconnect_CrazyShop(i); + } + THIS_MODE_INFO.isOn = false; + } + return Plugin_Handled; } @@ -818,32 +884,32 @@ public Action Cmd_CrazyShopToggle(int client, int args) void CrazyShop_GetItems() { char filePath[PLATFORM_MAX_PATH]; - BuildPath(Path_SM, filePath, sizeof(filePath), "configs/FM_CrazyShop.cfg"); - + BuildPath(Path_SM, filePath, sizeof(filePath), "configs/FunModes/CrazyShop.cfg"); + KeyValues kv = new KeyValues("Items"); - + if (!kv.ImportFromFile(filePath)) { delete kv; return; } - + if (!kv.GotoFirstSubKey()) { delete kv; return; } - + int i = 0; - do + do { char name[sizeof(CrazyShop_Item::name)]; - kv.GetString("name", name, sizeof(name)); - + kv.GetString("name", name, sizeof(name)); + int price = kv.GetNum("price"); g_CrazyShopItems[i].name = name; g_CrazyShopItems[i].price = price; - + CrazyShop_DataType type = view_as(kv.GetNum("type", g_CrazyShopItems[i].type)); switch (type) { @@ -855,27 +921,27 @@ void CrazyShop_GetItems() g_CrazyShopItems[i].time = kv.GetFloat("time", g_CrazyShopItems[i].time); } } - + i++; } while (kv.GotoNextKey()); - + delete kv; } void CrazyShop_AdminPanel(int client) { Menu menu = new Menu(Menu_CrazyShop_AdminPanel); - + menu.SetTitle("[CrazyShop] Admin Panel (The secret place, shhh!)"); - + for (int i = 0; i < sizeof(g_CrazyShopItems); i++) { char item[128]; FormatEx(item, sizeof(item), "%s - Edit", g_CrazyShopItems[i].name); - + menu.AddItem(NULL_STRING, item); } - + menu.ExitButton = true; menu.Display(client, MENU_TIME_FOREVER); } @@ -886,7 +952,7 @@ int Menu_CrazyShop_AdminPanel(Menu menu, MenuAction action, int param1, int para { case MenuAction_End: delete menu; - + case MenuAction_Select: CrazyShop_OpenItemSettings(param1, param2); } @@ -897,33 +963,33 @@ int Menu_CrazyShop_AdminPanel(Menu menu, MenuAction action, int param1, int para void CrazyShop_OpenItemSettings(int client, int item) { g_iCrazyShopPreviousItem[client] = item; - + Menu menu = new Menu(Menu_CrazyShop_ItemSettings); - + CrazyShop_DataType type = g_CrazyShopItems[item].type; - char valuesString[sizeof(CrazyShop_Item::amountName)+32]; + char valuesString[sizeof(CrazyShop_Item::amountName) + 32]; switch (type) { case DATATYPE_AMOUNT: FormatEx(valuesString, sizeof(valuesString), "%s: %.2f", g_CrazyShopItems[item].amountName, g_CrazyShopItems[item].amount); case DATATYPE_TIME: FormatEx(valuesString, sizeof(valuesString), "Time: %.2fs", g_CrazyShopItems[item].time); case DATATYPE_BOTH: FormatEx(valuesString, sizeof(valuesString), "%s: %.2f\nTime: %.2fs", g_CrazyShopItems[item].amountName, g_CrazyShopItems[item].amount, g_CrazyShopItems[item].time); } - + menu.SetTitle("[CrazyShop] %s - Settings\nPrice: %d\n%s", g_CrazyShopItems[item].name, g_CrazyShopItems[item].price, valuesString); - + menu.AddItem(NULL_STRING, "Change Price"); - + if (type == DATATYPE_AMOUNT || type == DATATYPE_BOTH) { char itemText[sizeof(CrazyShop_Item::amountName) + 20]; FormatEx(itemText, sizeof(itemText), "Change %s", g_CrazyShopItems[item].amountName); - + menu.AddItem(NULL_STRING, itemText); } - + if (type == DATATYPE_TIME || type == DATATYPE_BOTH) menu.AddItem(NULL_STRING, "Change Time"); - + menu.ExitButton = true; menu.Display(client, MENU_TIME_FOREVER); } @@ -934,13 +1000,13 @@ int Menu_CrazyShop_ItemSettings(Menu menu, MenuAction action, int param1, int pa { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) CrazyShop_AdminPanel(param1); } - + case MenuAction_Select: CrazyShop_OpenItemAction(param1, param2); } @@ -952,124 +1018,122 @@ void CrazyShop_OpenItemAction(int client, int action) { CrazyShop_Item item; item = g_CrazyShopItems[g_iCrazyShopPreviousItem[client]]; - - /* 0 = price, 1 = amount (if type is amount or all), time (if type is time), 2 = time (if found) */ + Menu menu = new Menu(Menu_CrazyShop_ItemAction); - + if (action == 0) { menu.SetTitle("[CrazyShop] %s - Price\nCurrent Price: %d", item.name, item.price); - + for (int i = item.price, count; i <= item.price * 2; i += item.price / 4) { if (count <= 1) i = item.price - item.price / 4; - + count++; - + if (i <= 0) { - i += 2*(item.price / 4); + i += 2 * (item.price / 4); count--; continue; } - + char thisVal[3]; IntToString(i, thisVal, sizeof(thisVal)); - + char data[sizeof(thisVal) + 2]; FormatEx(data, sizeof(data), "0|%s", thisVal); - + menu.AddItem(data, thisVal); } } - - /* this is 100% time */ + if (action == 2) { menu.SetTitle("[CrazyShop] %s - Time\nCurrent Time: %.2f", item.name, item.time); - + for (float f = item.time, count; f <= item.time * 2.0; f += item.time / 4.0) { if (count <= 1.0) f = item.time - (item.time / 4.0); - + count++; - + if (f <= 0.0) { - f += 2*(item.time / 4.0); + f += 2 * (item.time / 4.0); count--; continue; } - + char thisVal[6]; FloatToString(f, thisVal, sizeof(thisVal)); - + char data[sizeof(thisVal) + 2]; FormatEx(data, sizeof(data), "2|%s", thisVal); - + menu.AddItem(data, thisVal); } } - + if (action == 1) { if (item.type == DATATYPE_TIME) { menu.SetTitle("[CrazyShop] %s - Time\nCurrent Time: %.2f", item.name, item.time); - + for (float f = item.time, count; f <= item.time * 2.0; f += item.time / 4.0) { if (count <= 1.0) f = item.time - (item.time / 4.0); - + count++; - + if (f <= 0.0) { - f += 2*(item.time / 4.0); + f += 2 * (item.time / 4.0); count--; continue; } - + char thisVal[6]; FloatToString(f, thisVal, sizeof(thisVal)); - + char data[sizeof(thisVal) + 2]; FormatEx(data, sizeof(data), "2|%s", thisVal); - + menu.AddItem(data, thisVal); } } else { menu.SetTitle("[CrazyShop] %s - %s\nCurrent %s: %.2f", item.name, item.amountName, item.amountName, item.amount); - + for (float f = item.amount, count; f <= item.amount * 2; f += item.amount / 4.0) { if (count <= 1.0) f = item.amount - (item.amount / 4.0); - + if (f <= 0.0) { - f += 2*(item.amount / 4.0); + f += 2 * (item.amount / 4.0); count--; continue; } - + count++; char thisVal[6]; FloatToString(f, thisVal, sizeof(thisVal)); - + char data[sizeof(thisVal) + 2]; FormatEx(data, sizeof(data), "1|%s", thisVal); - + menu.AddItem(data, thisVal); } } } - + menu.ExitBackButton = true; menu.Display(client, MENU_TIME_FOREVER); } @@ -1080,23 +1144,23 @@ int Menu_CrazyShop_ItemAction(Menu menu, MenuAction action, int param1, int para { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) CrazyShop_OpenItemSettings(param1, g_iCrazyShopPreviousItem[param1]); } - + case MenuAction_Select: { char info[15]; menu.GetItem(param2, info, sizeof(info)); - + char data[2][10]; ExplodeString(info, "|", data, sizeof(data), sizeof(data[])); - + int itemAction = StringToInt(data[0]); - + switch (itemAction) { case 0: CrazyShop_UpdateItemData(param1, g_iCrazyShopPreviousItem[param1], "price", data[1]); @@ -1112,23 +1176,23 @@ int Menu_CrazyShop_ItemAction(Menu menu, MenuAction action, int param1, int para void CrazyShop_UpdateItemData(int client, int item, const char[] key, const char[] value) { char filePath[PLATFORM_MAX_PATH]; - BuildPath(Path_SM, filePath, sizeof(filePath), "configs/FM_CrazyShop.cfg"); - + BuildPath(Path_SM, filePath, sizeof(filePath), "configs/FunModes/CrazyShop.cfg"); + KeyValues kv = new KeyValues("Items"); - + if (!kv.ImportFromFile(filePath)) { CPrintToChat(client, "%s Sorry, no settings file was found, Changes will not be saved (Report this to the server manager).", THIS_MODE_INFO.tag); delete kv; } - + if (kv != null) { char keyNum[3]; IntToString(item, keyNum, sizeof(keyNum)); - + if (kv.JumpToKey(keyNum)) - { + { kv.SetString(key, value); kv.Rewind(); kv.ExportToFile(filePath); @@ -1136,14 +1200,14 @@ void CrazyShop_UpdateItemData(int client, int item, const char[] key, const char else CPrintToChat(client, "%s Sorry, the item is not in the settings file, changes will not be saved, (Report this to the server manager)", THIS_MODE_INFO.tag); } - + delete kv; - - if (key[0] == 'p') + + if (key[0] == 'p') g_CrazyShopItems[item].price = StringToInt(value); - else if (key[0] == 'a') + else if (key[0] == 'a') g_CrazyShopItems[item].amount = StringToFloat(value); - else + else g_CrazyShopItems[item].time = StringToFloat(value); CPrintToChat(client, "%s You have successfully changed {olive}%s {lightgreen}of %s {olive}to %s", THIS_MODE_INFO.tag, key, g_CrazyShopItems[item].name, value); @@ -1153,17 +1217,17 @@ public Action Cmd_CrazyShopSettings(int client, int args) { if (!client) return Plugin_Handled; - + Menu menu = new Menu(Menu_CrazyShopSettings); menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); menu.AddItem(NULL_STRING, "Show Cvars\n "); menu.AddItem(NULL_STRING, "Manage Shop Items"); - + menu.ExitBackButton = true; menu.Display(client, MENU_TIME_FOREVER); - + return Plugin_Handled; } @@ -1173,7 +1237,7 @@ int Menu_CrazyShopSettings(Menu menu, MenuAction action, int param1, int param2) { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) @@ -1199,16 +1263,16 @@ Action Cmd_CrazyShopMenu(int client, int args) CReplyToCommand(client, "%s The CrazyShop Mode is currently OFF!", THIS_MODE_INFO.tag); return Plugin_Handled; } - + if (!client) return Plugin_Handled; - - if (THIS_MODE_INFO.cvarInfo[CRAZYSHOP_CONVAR_DISABLE_SHOP].cvar.BoolValue) + + if (g_bCrazyShop_DisableShop) { CReplyToCommand(client, "%s The shop is currently disabled!", THIS_MODE_INFO.tag); return Plugin_Handled; } - + CrazyShop_OpenMenu(client); return Plugin_Handled; } @@ -1220,10 +1284,10 @@ Action Cmd_CrazyShopMyItems(int client, int args) CReplyToCommand(client, "%s The CrazyShop Mode is currently OFF!", THIS_MODE_INFO.tag); return Plugin_Handled; } - + if (!client) return Plugin_Handled; - + CrazyShop_OpenAvailableItems(client); return Plugin_Handled; } @@ -1232,24 +1296,24 @@ void CrazyShop_OpenMenu(int client) { if (!THIS_MODE_INFO.isOn) return; - + Menu menu = new Menu(Menu_CrazyShop); - + menu.SetTitle("[CrazyShop] Items List\nYour credits: %d$", PLAYER_CREDITS(client)); - + for (int i = 0; i < sizeof(g_CrazyShopItems); i++) { - char team[10]; + char team[10]; team = (g_CrazyShopItems[i].team == 0) ? "Zombies" : "Humans"; - + char[] item = new char[sizeof(CrazyShop_Item::name) + strlen(team)]; - FormatEx(item, sizeof(CrazyShop_Item::name) + strlen(team), "%s - %d$ [%s]%s", g_CrazyShopItems[i].name, g_CrazyShopItems[i].price, team, i == (sizeof(g_CrazyShopItems)-1) ? "\n ":""); - + FormatEx(item, sizeof(CrazyShop_Item::name) + strlen(team), "%s - %d$ [%s]%s", g_CrazyShopItems[i].name, g_CrazyShopItems[i].price, team, i == (sizeof(g_CrazyShopItems) - 1) ? "\n " : ""); + menu.AddItem(NULL_STRING, item, PLAYER_CREDITS(client) >= g_CrazyShopItems[i].price ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED); } - + menu.AddItem(NULL_STRING, "Gift 5 credits", PLAYER_CREDITS(client) >= 5 ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED); - + menu.ExitButton = true; menu.Display(client, MENU_TIME_FOREVER); } @@ -1260,25 +1324,24 @@ int Menu_CrazyShop(Menu menu, MenuAction action, int param1, int param2) { case MenuAction_End: delete menu; - + case MenuAction_Select: { if (!THIS_MODE_INFO.isOn) return -1; - - // Gift 5 credits + if (param2 == sizeof(g_CrazyShopItems)) { CrazyShop_OpenGiftMenu(param1); return -1; } - + if (PLAYER_CREDITS(param1) < g_CrazyShopItems[param2].price) { CPrintToChat(param1, "%s You have insufficent credits to buy this item.", THIS_MODE_INFO.tag); return -1; } - + PLAYER_CREDITS(param1) -= g_CrazyShopItems[param2].price; PLAYER_ITEM_COUNT(param1, param2) += 1; CPrintToChat(param1, "%s You have successfully bought {olive}%s, {lightgreen}Type !myitems to activate it!", THIS_MODE_INFO.tag, g_CrazyShopItems[param2].name); @@ -1286,30 +1349,30 @@ int Menu_CrazyShop(Menu menu, MenuAction action, int param1, int param2) CrazyShop_OpenMenu(param1); } } - + return -1; } void CrazyShop_OpenGiftMenu(int client) { Menu menu = new Menu(Menu_CrazyShop_Gift); - + menu.SetTitle("[CrazyShop] Select Player to gift 5 credits"); - + for (int i = 1; i <= MaxClients; i++) { if (!IsClientInGame(i) || IsFakeClient(i) || i == client) continue; - + char userId[10]; IntToString(GetClientUserId(i), userId, sizeof(userId)); - + char item[64]; FormatEx(item, sizeof(item), "%N - [%d$]", i, PLAYER_CREDITS(i)); - + menu.AddItem(userId, item); } - + menu.ExitBackButton = true; menu.Display(client, MENU_TIME_FOREVER); } @@ -1320,41 +1383,41 @@ int Menu_CrazyShop_Gift(Menu menu, MenuAction action, int param1, int param2) { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) CrazyShop_OpenMenu(param1); } - + case MenuAction_Select: { if (!THIS_MODE_INFO.isOn) return -1; - + if (PLAYER_CREDITS(param1) < 5) { CPrintToChat(param1, "%s You do not have 5 credits to gift.", THIS_MODE_INFO.tag); return -1; } - + char userId[10]; menu.GetItem(param2, userId, sizeof(userId)); - + int target = GetClientOfUserId(StringToInt(userId)); if (!target) { CPrintToChat(param1, "%s Player is no longer available!", THIS_MODE_INFO.tag); return -1; } - + PLAYER_CREDITS(target) += 5; PLAYER_CREDITS(param1) -= 5; CPrintToChat(param1, "%s You have gifted {olive}%N {lightgreen}5 credits, you are so generous!", THIS_MODE_INFO.tag, target); CPrintToChat(target, "%s %N {olive}has gifted you 5 credits! What a generous man!", THIS_MODE_INFO.tag, param1); } } - + return -1; } @@ -1362,48 +1425,47 @@ void CrazyShop_OpenAvailableItems(int client) { if (!g_bMotherZombie || g_bRoundEnd) return; - + bool found = false; - Menu menu; - + if (!IsPlayerAlive(client)) { CPrintToChat(client, "%s you have to be alive to use this command!", THIS_MODE_INFO.tag); return; } - + for (int i = 0; i < sizeof(CrazyShop_PlayerData::itemsCount); i++) { - if (((g_CrazyShopItems[i].team == 0 && ZR_IsClientZombie(client)) || - (g_CrazyShopItems[i].team == 1 && ZR_IsClientHuman(client))) && PLAYER_ITEM_COUNT(client, i)) + if (((g_CrazyShopItems[i].team == 0 && ZR_IsClientZombie(client)) + || (g_CrazyShopItems[i].team == 1 && ZR_IsClientHuman(client))) && PLAYER_ITEM_COUNT(client, i)) { found = true; - + if (menu == null) { menu = new Menu(Menu_AvailableItems); menu.SetTitle("[CrazyShop] Your Available Items!"); } - + if (menu) { char item[64]; FormatEx(item, sizeof(item), "%s - Activate", g_CrazyShopItems[i].name); - + char data[3]; IntToString(i, data, sizeof(data)); menu.AddItem(data, item); } } } - + if (!found) { CPrintToChat(client, "%s You have no available items!", THIS_MODE_INFO.tag); return; } - + menu.ExitButton = true; menu.Display(client, MENU_TIME_FOREVER); } @@ -1414,29 +1476,29 @@ int Menu_AvailableItems(Menu menu, MenuAction action, int param1, int param2) { case MenuAction_End: delete menu; - + case MenuAction_Select: { if (!THIS_MODE_INFO.isOn) return -1; - + char data[3]; menu.GetItem(param2, data, sizeof(data)); - + int itemNum = StringToInt(data); - + if (PLAYER_ITEM_COUNT(param1, itemNum) <= 0) { CPrintToChat(param1, "%s You do not have this item in your inventory", THIS_MODE_INFO.tag); return 0; } - + if (!IsPlayerAlive(param1)) { CPrintToChat(param1, "%s You have to be alive to activate items!", THIS_MODE_INFO.tag); return -1; } - + CrazyShop_Item item; item = g_CrazyShopItems[itemNum]; bool isZombie = ZR_IsClientZombie(param1); @@ -1445,18 +1507,18 @@ int Menu_AvailableItems(Menu menu, MenuAction action, int param1, int param2) CPrintToChat(param1, "%s This item is for zombies only!", THIS_MODE_INFO.tag); return -1; } - + if (item.team == 1 && isZombie) - { + { CPrintToChat(param1, "%s This item is for humans only!", THIS_MODE_INFO.tag); return -1; } - + CrazyShop_Activate(param1, itemNum); CrazyShop_OpenAvailableItems(param1); } } - + return -1; } @@ -1470,7 +1532,7 @@ void CrazyShop_Activate(int client, int itemNum) CPrintToChat(client, "%s You cannot activate the same item again unless the old ones' effect ended", THIS_MODE_INFO.tag); return; } - + switch (itemNum) { // HP - Humans @@ -1478,26 +1540,26 @@ void CrazyShop_Activate(int client, int itemNum) { int maxHealth = GetEntProp(client, Prop_Data, "m_iMaxHealth"); SetEntProp(client, Prop_Data, "m_iMaxHealth", maxHealth + RoundToNearest(item.amount)); - + int health = RoundToNearest(item.amount); SetEntityHealth(client, GetClientHealth(client) + health); - + CPrintToChat(client, "%s You have given yourself {olive}%d {lightgreen}more HP", THIS_MODE_INFO.tag, health); } - + // Infection Protection - Humans case 1: - { + { PLAYER_ITEM_ACTIVE(client, itemNum) = true; PLAYER_TEMP_VAR(client, infectionProtect) = true; - + DataPack pack = new DataPack(); pack.WriteCell(GetClientUserId(client)); pack.WriteCell(itemNum); - + CreateTimer(item.time, Timer_CrazyShop_InfectionProtection, pack, TIMER_FLAG_NO_MAPCHANGE); } - + // Super Weapon - Humans case 2: { @@ -1508,21 +1570,21 @@ void CrazyShop_Activate(int client, int itemNum) return; } #endif - + static const char weaponsList[][] = { "weapon_mac10", "weapon_tmp", "weapon_mp5navy", "weapon_ump45", "weapon_p90", "weapon_galil", "weapon_famas", "weapon_ak47", "weapon_m4a1", "weapon_sg552", "weapon_aug", "weapon_m249" }; - - strcopy(PLAYER_TEMP_VAR(client, superWeaponName), sizeof(CrazyShop_PlayerData::superWeaponName), + + strcopy(PLAYER_TEMP_VAR(client, superWeaponName), sizeof(CrazyShop_PlayerData::superWeaponName), weaponsList[GetRandomInt(0, sizeof(weaponsList) - 1)]); - + int wp = GetPlayerWeaponSlot(client, CS_SLOT_PRIMARY); if (IsValidEntity(wp)) GetEntityClassname(wp, PLAYER_TEMP_VAR(client, originalWeapon), sizeof(CrazyShop_PlayerData::originalWeapon)); - + if (strcmp(PLAYER_TEMP_VAR(client, originalWeapon), PLAYER_TEMP_VAR(client, superWeaponName)) == 0) PLAYER_TEMP_VAR(client, originalWeapon)[0] = '\0'; else @@ -1531,125 +1593,131 @@ void CrazyShop_Activate(int client, int itemNum) GunGame_EquipWeapon(client, PLAYER_TEMP_VAR(client, superWeaponName), true); #endif } - + FunModes_HookEvent(g_bEvent_WeaponFire, "weapon_fire", Event_WeaponFire_CrazyShop); - + PLAYER_ITEM_ACTIVE(client, itemNum) = true; PLAYER_TEMP_VAR(client, superWeapon) = true; - + DataPack pack = new DataPack(); pack.WriteCell(GetClientUserId(client)); pack.WriteCell(itemNum); - + CreateTimer(item.time, Timer_CrazyShop_SuperWeapon, pack, TIMER_FLAG_NO_MAPCHANGE); } - + // Laser Protection - Humans case 3: { PLAYER_ITEM_ACTIVE(client, itemNum) = true; PLAYER_TEMP_VAR(client, laserProtect) = true; - + DataPack pack = new DataPack(); pack.WriteCell(GetClientUserId(client)); pack.WriteCell(itemNum); - + CreateTimer(item.time, Timer_CrazyShop_LaserProtection, pack, TIMER_FLAG_NO_MAPCHANGE); } - + // Unlimited Ammo - Humans case 4: { PLAYER_ITEM_ACTIVE(client, itemNum) = true; - + PLAYER_TEMP_VAR(client, unlimitedAmmo) = true; - + FunModes_HookEvent(g_bEvent_WeaponFire, "weapon_fire", Event_WeaponFire_CrazyShop); - + DataPack pack = new DataPack(); - + pack.WriteCell(GetClientUserId(client)); pack.WriteCell(itemNum); - + CreateTimer(item.time, Timer_CrazyShop_UnlimitedAmmo, pack, TIMER_FLAG_NO_MAPCHANGE); - + CPrintToChat(client, "%s You have activated unlimited Ammo, Go Hunt the Zombies!", THIS_MODE_INFO.tag); } - + // Buy a smokegrenade case 5: { - SET_GRENADES_COUNT(client, SMOKEGRENADE, GET_GRENADES_COUNT(client, SMOKEGRENADE) + 1); - - int wp = GivePlayerItem(client, "weapon_smokegrenade"); - EquipPlayerWeapon(client, wp); - + bool given = false; + if (!HasPlayerItem(client, "weapon_smokegrenade")) + { + int wp = GivePlayerItem(client, "weapon_smokegrenade"); + EquipPlayerWeapon(client, wp); + given = true; + } + + int extra = given ? 0 : 1; + SET_GRENADES_COUNT(client, SMOKEGRENADE, GET_GRENADES_COUNT(client, SMOKEGRENADE) + extra); + CPrintToChat(client, "%s You have given yourself a smokegrenade! {olive}Freeze the zombies now!", THIS_MODE_INFO.tag); } - + // Slow Beacon case 6: { int userid = GetClientUserId(client); - + PLAYER_ITEM_ACTIVE(client, itemNum) = true; - + delete PLAYER_TEMP_VAR(client, slowBeaconTimer); PLAYER_TEMP_VAR(client, slowBeaconTimer) = CreateTimer(0.1, Timer_SlowBeaconRepeat, userid, TIMER_REPEAT); - + CreateTimer(item.time, Timer_CrazyShop_SlowBeacon, userid, TIMER_FLAG_NO_MAPCHANGE); - + CPrintToChat(client, "%s You have activated slow beacon, you can slow down the zombies if they got close to your beacon!", THIS_MODE_INFO.tag); } - + // More Speed - Zombies case 7: { PLAYER_ITEM_ACTIVE(client, itemNum) = true; - + float originalSpeed = GetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue"); - + SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", originalSpeed + item.amount); - + DataPack pack = new DataPack(); pack.WriteCell(GetClientUserId(client)); pack.WriteCell(itemNum); pack.WriteFloat(originalSpeed); - + CreateTimer(item.time, Timer_CrazyShop_MoreSpeed, pack, TIMER_FLAG_NO_MAPCHANGE); } - + // KB Protection - Zombies case 8: { PLAYER_TEMP_VAR(client, kbProtect) = true; PLAYER_ITEM_ACTIVE(client, itemNum) = true; - + DataPack pack = new DataPack(); pack.WriteCell(GetClientUserId(client)); pack.WriteCell(itemNum); - + CreateTimer(item.time, Timer_CrazyShop_KBProtection, pack, TIMER_FLAG_NO_MAPCHANGE); - + CPrintToChat(client, "%s You have activated KB protection, your knockback will be much less now!", THIS_MODE_INFO.tag); } - + // Lower Gravity - Zombies case 9: { PLAYER_ITEM_ACTIVE(client, itemNum) = true; - + SetEntityGravity(client, 1.0 + item.amount); - + DataPack pack = new DataPack(); pack.WriteCell(GetClientUserId(client)); pack.WriteCell(itemNum); - + CreateTimer(item.time, Timer_CrazyShop_LowerGravity, pack, TIMER_FLAG_NO_MAPCHANGE); - + CPrintToChat(client, "%s You have been given lower gravity, use it wisely!", THIS_MODE_INFO.tag); } - + // Hurting Machine - Zombies case 10: { @@ -1658,7 +1726,7 @@ void CrazyShop_Activate(int client, int itemNum) CPrintToChat(client, "%s Please wait until the older hurting machines die!", THIS_MODE_INFO.tag); return; } - + int userid = GetClientOfUserId(client); char propName[64]; FormatEx(propName, sizeof(propName), "%d_FM_PROP_%d_%d", RoundToNearest(item.amount), userid, GetGameTime()); @@ -1669,49 +1737,49 @@ void CrazyShop_Activate(int client, int itemNum) CPrintToChat(client, "%s Failed to activate this item, try again later", THIS_MODE_INFO.tag); return; } - + CrazyShop_ThrowProp(client, prop); - + DataPack pack = new DataPack(); pack.WriteCell(userid); pack.WriteCell(EntIndexToEntRef(prop)); - + CreateTimer(item.time, Timer_CrazyShop_HurtingMachine, pack, TIMER_FLAG_NO_MAPCHANGE); } - + // Ignite Immunity - Zombies case 11: { PLAYER_ITEM_ACTIVE(client, itemNum) = true; PLAYER_TEMP_VAR(client, igniteImmunity) = true; - + DataPack pack = new DataPack(); pack.WriteCell(GetClientUserId(client)); pack.WriteCell(itemNum); - + CreateTimer(item.time, Timer_CrazyShop_IgniteImmunity, pack, TIMER_FLAG_NO_MAPCHANGE); - + CPrintToChat(client, "%s You have activated ignite immunity, you won't be on fire for now!", THIS_MODE_INFO.tag); } - + // Invisibility - Zombies case 12: { PLAYER_ITEM_ACTIVE(client, itemNum) = true; - + int nodraw = 0x20; - + SetEntProp(client, Prop_Send, "m_fEffects", GetEntProp(client, Prop_Send, "m_fEffects") | nodraw); - + DataPack pack = new DataPack(); pack.WriteCell(GetClientUserId(client)); pack.WriteCell(itemNum); - + CreateTimer(item.time, Timer_CrazyShop_Invisibility, pack, TIMER_FLAG_NO_MAPCHANGE); - + CPrintToChat(client, "%s You are invisibile now, shhh!", THIS_MODE_INFO.tag); } - + // Human Pull - Zombies case 13: { @@ -1721,44 +1789,44 @@ void CrazyShop_Activate(int client, int itemNum) CPrintToChat(client, "%s Canceling the activation of this item, please aim at a human!", THIS_MODE_INFO.tag); return; } - + PLAYER_ITEM_ACTIVE(client, itemNum) = true; - + CrazyShop_StartGrab(client, target); - + DataPack pack = new DataPack(); pack.WriteCell(GetClientUserId(client)); pack.WriteCell(itemNum); - + CreateTimer(item.time, Timer_CrazyShop_Pull, pack, TIMER_FLAG_NO_MAPCHANGE); - + CPrintToChat(client, "%s You are now pulling a human xD", THIS_MODE_INFO.tag); } } - + if (item.time > 0.0) { SetEntPropFloat(client, Prop_Send, "m_flProgressBarStartTime", GetGameTime()); SetEntProp(client, Prop_Send, "m_iProgressBarDuration", RoundToNearest(item.time)); } - + PLAYER_ITEM_COUNT(client, itemNum)--; } Action Timer_CrazyShop_InfectionProtection(Handle timer, DataPack pack) { pack.Reset(); - + int client = GetClientOfUserId(pack.ReadCell()); if (!client) { delete pack; return Plugin_Stop; } - + int itemNum = pack.ReadCell(); delete pack; - + PLAYER_TEMP_VAR(client, infectionProtect) = false; PLAYER_ITEM_ACTIVE(client, itemNum) = false; SetEntProp(client, Prop_Send, "m_iProgressBarDuration", 0); @@ -1768,31 +1836,31 @@ Action Timer_CrazyShop_InfectionProtection(Handle timer, DataPack pack) Action Timer_CrazyShop_SuperWeapon(Handle timer, DataPack pack) { pack.Reset(); - + int client = GetClientOfUserId(pack.ReadCell()); if (!client) { delete pack; return Plugin_Stop; } - + int itemNum = pack.ReadCell(); delete pack; - + PLAYER_TEMP_VAR(client, superWeaponName)[0] = '\0'; PLAYER_TEMP_VAR(client, superWeapon) = false; PLAYER_ITEM_ACTIVE(client, itemNum) = false; SetEntProp(client, Prop_Send, "m_iProgressBarDuration", 0); - + if (!THIS_MODE_INFO.isOn || g_bRoundEnd) return Plugin_Stop; - + if (IsPlayerAlive(client) && ZR_IsClientHuman(client) && PLAYER_TEMP_VAR(client, originalWeapon)[0]) { #if defined _FM_GunGame GunGame_EquipWeapon(client, PLAYER_TEMP_VAR(client, originalWeapon), true); #endif - + PLAYER_TEMP_VAR(client, originalWeapon)[0] = '\0'; } @@ -1802,18 +1870,18 @@ Action Timer_CrazyShop_SuperWeapon(Handle timer, DataPack pack) Action Timer_CrazyShop_LaserProtection(Handle timer, DataPack pack) { pack.Reset(); - + int client = GetClientOfUserId(pack.ReadCell()); if (!client) { delete pack; return Plugin_Stop; } - + int itemNum = pack.ReadCell(); delete pack; PLAYER_ITEM_ACTIVE(client, itemNum) = false; - + PLAYER_TEMP_VAR(client, laserProtect) = false; SetEntProp(client, Prop_Send, "m_iProgressBarDuration", 0); return Plugin_Stop; @@ -1822,17 +1890,17 @@ Action Timer_CrazyShop_LaserProtection(Handle timer, DataPack pack) Action Timer_CrazyShop_UnlimitedAmmo(Handle timer, DataPack pack) { pack.Reset(); - + int client = GetClientOfUserId(pack.ReadCell()); if (!client) { delete pack; return Plugin_Stop; } - + int itemNum = pack.ReadCell(); delete pack; - + PLAYER_ITEM_ACTIVE(client, itemNum) = false; PLAYER_TEMP_VAR(client, unlimitedAmmo) = false; SetEntProp(client, Prop_Send, "m_iProgressBarDuration", 0); @@ -1840,14 +1908,14 @@ Action Timer_CrazyShop_UnlimitedAmmo(Handle timer, DataPack pack) } Action Timer_CrazyShop_SlowBeacon(Handle timer, int userid) -{ +{ int client = GetClientOfUserId(userid); if (!client) { CrazyShop_ResetSpeed(); return Plugin_Stop; } - + PLAYER_TEMP_VAR(client, slowBeaconTimer) = null; PLAYER_ITEM_ACTIVE(client, 6) = false; SetEntProp(client, Prop_Send, "m_iProgressBarDuration", 0); @@ -1862,9 +1930,9 @@ Action Timer_SlowBeaconRepeat(Handle timer, int userid) CrazyShop_ResetSpeed(); return Plugin_Stop; } - + int itemNum = 6; - + if (!THIS_MODE_INFO.isOn || g_bRoundEnd) { PLAYER_ITEM_ACTIVE(client, itemNum) = false; @@ -1872,7 +1940,7 @@ Action Timer_SlowBeaconRepeat(Handle timer, int userid) PLAYER_TEMP_VAR(client, slowBeaconTimer) = null; return Plugin_Stop; } - + if (!IsPlayerAlive(client) || ZR_IsClientZombie(client)) { PLAYER_ITEM_ACTIVE(client, itemNum) = false; @@ -1880,25 +1948,25 @@ Action Timer_SlowBeaconRepeat(Handle timer, int userid) PLAYER_TEMP_VAR(client, slowBeaconTimer) = null; return Plugin_Stop; } - + if (!PLAYER_ITEM_ACTIVE(client, itemNum)) { CrazyShop_ResetSpeed(); PLAYER_TEMP_VAR(client, slowBeaconTimer) = null; return Plugin_Stop; } - - float beaconRadius = THIS_MODE_INFO.cvarInfo[CRAZYSHOP_CONVAR_SLOWBEACON_RADIUS].cvar.FloatValue; - BeaconPlayer(client, 0, beaconRadius, { 255, 255, 255, 255 } ); - + + float beaconRadius = g_fCrazyShop_SlowBeaconRadius; + BeaconPlayer(client, 0, beaconRadius, { 255, 255, 255, 255 }); + // check for distance for (int i = 1; i <= MaxClients; i++) { if (!IsClientInGame(i) || !IsPlayerAlive(i) || !ZR_IsClientZombie(i)) continue; - + float squarredDistance = GetDistanceBetween(client, i, true); - if (!PLAYER_TEMP_VAR(i, gotSlowed) && squarredDistance <= ((beaconRadius/2.0)*(beaconRadius/2.0))) + if (!PLAYER_TEMP_VAR(i, gotSlowed) && squarredDistance <= ((beaconRadius / 2.0) * (beaconRadius / 2.0))) { PLAYER_TEMP_VAR(i, gotSlowed) = true; PLAYER_TEMP_VAR(i, originalSpeed) = GetEntPropFloat(i, Prop_Data, "m_flLaggedMovementValue"); @@ -1911,13 +1979,13 @@ Action Timer_SlowBeaconRepeat(Handle timer, int userid) // More Speed - 4 if (PLAYER_ITEM_ACTIVE(i, 4)) continue; - + PLAYER_TEMP_VAR(i, gotSlowed) = false; SetEntPropFloat(i, Prop_Data, "m_flLaggedMovementValue", PLAYER_TEMP_VAR(i, originalSpeed)); } } } - + return Plugin_Continue; } @@ -1930,7 +1998,7 @@ void CrazyShop_ResetSpeed() // More Speed - 4 if (PLAYER_ITEM_ACTIVE(i, 4)) continue; - + PLAYER_TEMP_VAR(i, gotSlowed) = false; SetEntPropFloat(i, Prop_Data, "m_flLaggedMovementValue", PLAYER_TEMP_VAR(i, originalSpeed)); } @@ -1938,27 +2006,27 @@ void CrazyShop_ResetSpeed() } Action Timer_CrazyShop_MoreSpeed(Handle timer, DataPack pack) -{ +{ pack.Reset(); - + int client = GetClientOfUserId(pack.ReadCell()); if (!client) { delete pack; return Plugin_Stop; } - + int itemNum = pack.ReadCell(); float speed = pack.ReadFloat(); - + PLAYER_ITEM_ACTIVE(client, itemNum) = false; SetEntProp(client, Prop_Send, "m_iProgressBarDuration", 0); - + delete pack; - + if (!THIS_MODE_INFO.isOn || g_bRoundEnd) return Plugin_Stop; - + SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", speed); return Plugin_Stop; } @@ -1966,17 +2034,17 @@ Action Timer_CrazyShop_MoreSpeed(Handle timer, DataPack pack) Action Timer_CrazyShop_KBProtection(Handle timer, DataPack pack) { pack.Reset(); - + int client = GetClientOfUserId(pack.ReadCell()); if (!client) { delete pack; return Plugin_Stop; } - + int itemNum = pack.ReadCell(); delete pack; - + PLAYER_TEMP_VAR(client, kbProtect) = false; PLAYER_ITEM_ACTIVE(client, itemNum) = false; SetEntProp(client, Prop_Send, "m_iProgressBarDuration", 0); @@ -1986,17 +2054,17 @@ Action Timer_CrazyShop_KBProtection(Handle timer, DataPack pack) Action Timer_CrazyShop_LowerGravity(Handle timer, DataPack pack) { pack.Reset(); - + int client = GetClientOfUserId(pack.ReadCell()); if (!client) { delete pack; return Plugin_Stop; } - + int itemNum = pack.ReadCell(); delete pack; - + SetEntityGravity(client, 1.0); PLAYER_ITEM_ACTIVE(client, itemNum) = false; SetEntProp(client, Prop_Send, "m_iProgressBarDuration", 0); @@ -2006,17 +2074,17 @@ Action Timer_CrazyShop_LowerGravity(Handle timer, DataPack pack) Action Timer_CrazyShop_IgniteImmunity(Handle timer, DataPack pack) { pack.Reset(); - + int client = GetClientOfUserId(pack.ReadCell()); if (!client) { delete pack; return Plugin_Stop; } - + int itemNum = pack.ReadCell(); delete pack; - + PLAYER_ITEM_ACTIVE(client, itemNum) = false; PLAYER_TEMP_VAR(client, igniteImmunity) = false; SetEntProp(client, Prop_Send, "m_iProgressBarDuration", 0); @@ -2026,19 +2094,19 @@ Action Timer_CrazyShop_IgniteImmunity(Handle timer, DataPack pack) Action Timer_CrazyShop_Invisibility(Handle timer, DataPack pack) { pack.Reset(); - + int client = GetClientOfUserId(pack.ReadCell()); if (!client) { delete pack; return Plugin_Stop; } - + int itemNum = pack.ReadCell(); delete pack; - + PLAYER_ITEM_ACTIVE(client, itemNum) = false; - + int nodraw = 0x20; SetEntProp(client, Prop_Send, "m_fEffects", GetEntProp(client, Prop_Send, "m_fEffects") & ~nodraw); SetEntProp(client, Prop_Send, "m_iProgressBarDuration", 0); @@ -2054,24 +2122,24 @@ Action Timer_CrazyShop_Pull(Handle timer, DataPack pack) delete pack; return Plugin_Stop; } - + int itemNum = pack.ReadCell(); delete pack; - + PLAYER_ITEM_ACTIVE(client, itemNum) = false; int target = PLAYER_TEMP_VAR(client, grabbedTarget); SetEntProp(client, Prop_Send, "m_iProgressBarDuration", 0); - + if (target == -1) return Plugin_Stop; - + PLAYER_TEMP_VAR(client, grabbedTarget) = -1; - + PLAYER_ITEM_ACTIVE(target, 1) = false; PLAYER_TEMP_VAR(target, infectionProtect) = false; - + SetEntPropFloat(target, Prop_Send, "m_flMaxspeed", PLAYER_TEMP_VAR(client, originalTargetMaxSpeed)); - + return Plugin_Stop; } @@ -2079,12 +2147,12 @@ void CrazyShop_StartGrab(int client, int target) { PLAYER_ITEM_ACTIVE(target, 1) = true; PLAYER_TEMP_VAR(target, infectionProtect) = true; - + PLAYER_TEMP_VAR(client, grabbedTarget) = target; - + PLAYER_TEMP_VAR(client, originalTargetMaxSpeed) = GetEntPropFloat(target, Prop_Send, "m_flMaxspeed"); SetEntPropFloat(target, Prop_Send, "m_flMaxspeed", 0.01); - + CreateTimer(0.05, CrazyShop_Timer_Grabbing, client, TIMER_REPEAT); } @@ -2093,15 +2161,15 @@ Action CrazyShop_Timer_Grabbing(Handle timer, int client) int itemNum = 13; if (!PLAYER_ITEM_ACTIVE(client, itemNum)) return Plugin_Stop; - + int target = PLAYER_TEMP_VAR(client, grabbedTarget); if (target == -1 || !IsPlayerAlive(target) || !ZR_IsClientHuman(target) || !IsPlayerAlive(client) || ZR_IsClientHuman(client)) return Plugin_Stop; - + float clientEyePos[3], targetEyePos[3]; GetClientEyePosition(client, clientEyePos); GetClientEyePosition(target, targetEyePos); - + float distance = GetVectorDistance(clientEyePos, targetEyePos, true); if (distance > 40000.0) { @@ -2111,10 +2179,10 @@ Action CrazyShop_Timer_Grabbing(Handle timer, int client) ScaleVector(velocity, 300.0); TeleportEntity(target, _, _, velocity); } - + TE_SetupBeamPoints(clientEyePos, targetEyePos, g_iLaserBeam, 0, 0, 66, 0.2, 1.0, 10.0, 0, 0.0, {255,255,255,255}, 0); TE_SendToAll(); - + return Plugin_Continue; } @@ -2123,7 +2191,7 @@ stock bool TraceRayTryToHit(int entity, int mask) #pragma unused mask if (entity > 0 && entity <= MaxClients) return false; - + return true; } @@ -2131,22 +2199,22 @@ stock bool TraceRayTryToHit(int entity, int mask) Action Timer_CrazyShop_HurtingMachine(Handle timer, DataPack pack) { pack.Reset(); - + int client = GetClientOfUserId(pack.ReadCell()); int prop = EntRefToEntIndex(pack.ReadCell()); - + delete pack; - + g_iCrazyShopProps--; - + if (prop == INVALID_ENT_REFERENCE) return Plugin_Stop; - + RemoveEntity(prop); - + if (!client) return Plugin_Stop; - + SetEntProp(client, Prop_Send, "m_iProgressBarDuration", 0); return Plugin_Stop; } @@ -2155,39 +2223,39 @@ void CrazyShop_ThrowProp(int client, int prop) { float vecEyeAngles[3]; float vecEyePos[3]; - + GetClientEyeAngles(client, vecEyeAngles); GetClientEyePosition(client, vecEyePos); - + float vecForward[3]; GetAngleVectors(vecEyeAngles, vecForward, NULL_VECTOR, NULL_VECTOR); - + ScaleVector(vecForward, 100.0); - + float spawnOrigin[3]; AddVectors(vecEyePos, vecForward, spawnOrigin); TeleportEntity(prop, spawnOrigin, vecEyeAngles, vecEyeAngles); - + DispatchSpawn(prop); - + g_iCrazyShopProps++; } stock int CrazyShop_CreateProp(const char[] name) { - int ent = CreateEntityByName("prop_physics_override"); + int ent = CreateEntityByName("prop_physics_override"); if (ent == -1) return -1; - + DispatchKeyValue(ent, "targetname", name); DispatchKeyValue(ent, "solid", "0"); DispatchKeyValue(ent, "model", PROP_MODEL); DispatchKeyValue(ent, "disableshadows", "1"); DispatchKeyValue(ent, "disablereceiveshadows", "1"); - + SDKHook(ent, SDKHook_SpawnPost, Prop_Spawn); - + return ent; } @@ -2203,35 +2271,35 @@ public Action Hook_PropDamage(int entity, int& attacker, int& inflictor, float& } Action Hook_PropHit(int entity, int other) -{ +{ if (!(1<=other<=MaxClients)) return Plugin_Continue; - + if (!IsPlayerAlive(other) || ZR_IsClientZombie(other)) return Plugin_Continue; - + if (PLAYER_TEMP_VAR(other, protectLaser)) return Plugin_Continue; - + char name[64]; GetEntPropString(entity, Prop_Data, "m_iName", name, sizeof(name)); - + char vals[5][10]; ExplodeString(name, "_", vals, sizeof(vals), sizeof(vals[])); - + int damage = StringToInt(vals[0]); if (damage == 0) return Plugin_Continue; - + // Decide what to do: if (damage > 100) { ForcePlayerSuicide(other); return Plugin_Continue; } - + SDKHooks_TakeDamage(other, 0, 0, float(damage)); - + return Plugin_Continue; } @@ -2241,10 +2309,10 @@ public Action ZR_OnClientInfect(int &client, int &attacker, bool &motherInfect) { if (!THIS_MODE_INFO.isOn) return Plugin_Continue; - + if (!PLAYER_TEMP_VAR(client, infectionProtect)) return Plugin_Continue; - + return Plugin_Handled; } diff --git a/addons/sourcemod/scripting/Fun_Modes/DamageGame.sp b/addons/sourcemod/scripting/Fun_Modes/DamageGame.sp index 433a38e..a03555c 100644 --- a/addons/sourcemod/scripting/Fun_Modes/DamageGame.sp +++ b/addons/sourcemod/scripting/Fun_Modes/DamageGame.sp @@ -1,10 +1,13 @@ #pragma semicolon 1 #pragma newdecls required -ModeInfo g_DamageGameInfo; +static int g_iDamageGameIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iDamageGameIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_DamageGameInfo +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] int g_iDealtDamage[MAXPLAYERS + 1] = {-1, ...}; Handle g_hDamageGameTimer; @@ -15,9 +18,19 @@ bool g_bDamageGameDisable; #define DAMAGEGAME_CONVAR_MODE 2 #define DAMAGEGAME_CONVAR_TOGGLE 3 +float g_fDamageGame_TimeInterval; +float g_fDamageGame_Damage; + +int g_iDamageGame_Mode; + +bool g_bDamageGame_Enabled; + /* CALLED on Plugin Start */ stock void OnPluginStart_DamageGame() { + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + THIS_MODE_INFO.name = "DamageGame"; THIS_MODE_INFO.tag = "{gold}[FunModes-DamageGame]{lightgreen}"; @@ -25,54 +38,92 @@ stock void OnPluginStart_DamageGame() RegAdminCmd("sm_fm_damage", Cmd_DamageGameToggle, ADMFLAG_CONVARS, "Enable/Disable Damage Game mode."); RegAdminCmd("sm_fm_damagegame", Cmd_DamageGameToggle, ADMFLAG_CONVARS, "Enable/Disable Damage Game mode."); RegAdminCmd("sm_fm_dg", Cmd_DamageGameToggle, ADMFLAG_CONVARS, "Enable/Disable Damage Game mode."); - + /* CONVARS */ DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, DAMAGEGAME_CONVAR_TIME_INTERVAL, - "sm_damagegame_time_interval", "15.0", "Damage Game Timer Interval", - ("15.0,20.0,30.0,40.0"), "float" + DAMAGEGAME_CONVAR_TIME_INTERVAL, "sm_damagegame_time_interval", + "15.0", "Damage Game Timer Interval", + ("15.0,20.0,30.0,40.0"), CONVAR_FLOAT ); + THIS_MODE_INFO.cvars[DAMAGEGAME_CONVAR_TIME_INTERVAL].HookChange(DamageGame_OnConVarChange); DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, DAMAGEGAME_CONVAR_DAMAGE, - "sm_damagegame_damage", "15.0", "The amount of damage to apply to players who don't shoot zombies", - ("5.0,10.0,15.0,20.0"), "float" + DAMAGEGAME_CONVAR_DAMAGE, "sm_damagegame_damage", + "15.0", "The amount of damage to apply to players who don't shoot zombies", + ("5.0,10.0,15.0,20.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[DAMAGEGAME_CONVAR_DAMAGE].HookChange(DamageGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, DAMAGEGAME_CONVAR_MODE, - "sm_damagegame_mode", "0", "DamageGame Mode (0 = Worst defenders, 1 = Doesn't defend for x time, 2 = Both)", - ("0,1,2"), "int" + DAMAGEGAME_CONVAR_MODE, "sm_damagegame_mode", + "0", "DamageGame Mode (0 = Worst defenders, 1 = Doesn't defend for x time, 2 = Both)", + ("0,1,2"), CONVAR_INT ); - + THIS_MODE_INFO.cvars[DAMAGEGAME_CONVAR_MODE].HookChange(DamageGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, DAMAGEGAME_CONVAR_TOGGLE, - "sm_damagegame_enable", "1", "Enable/Disable Damage Game", - ("0,1"), "bool" + DAMAGEGAME_CONVAR_TOGGLE, "sm_damagegame_enable", + "1", "Enable/Disable Damage Game", + ("0,1"), CONVAR_BOOL ); - - THIS_MODE_INFO.enableIndex = DAMAGEGAME_CONVAR_TOGGLE; - - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; + THIS_MODE_INFO.cvars[DAMAGEGAME_CONVAR_TOGGLE].HookChange(DamageGame_OnConVarChange); - THIS_MODE_INFO.cvarInfo[DAMAGEGAME_CONVAR_TOGGLE].cvar.AddChangeHook(OnDamageGameModeToggle); - - THIS_MODE_INFO.cvarInfo[DAMAGEGAME_CONVAR_MODE].cvar.AddChangeHook(OnDamageGameModeChange); + THIS_MODE_INFO.enableIndex = DAMAGEGAME_CONVAR_TOGGLE; } -void OnDamageGameModeToggle(ConVar cvar, const char[] oldValue, const char[] newValue) +void InitCvarsValues_DamageGame() { - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + int modeIndex = THIS_MODE_INFO.index; + + g_fDamageGame_TimeInterval = _FUNMODES_CVAR_GET_VALUE(modeIndex, DAMAGEGAME_CONVAR_TIME_INTERVAL, Float); + g_fDamageGame_Damage = _FUNMODES_CVAR_GET_VALUE(modeIndex, DAMAGEGAME_CONVAR_DAMAGE, Float); + + g_iDamageGame_Mode = _FUNMODES_CVAR_GET_VALUE(modeIndex, DAMAGEGAME_CONVAR_MODE, Int); + + g_bDamageGame_Enabled = _FUNMODES_CVAR_GET_VALUE(modeIndex, DAMAGEGAME_CONVAR_TOGGLE, Bool); } -void OnDamageGameModeChange(ConVar cvar, const char[] oldValue, const char[] newValue) +void DamageGame_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) { - for (int i = 1; i <= MaxClients; i++) - g_iDealtDamage[i] = -1; - - DamageGame_StartTimers(); + switch (cvarIndex) + { + case DAMAGEGAME_CONVAR_TIME_INTERVAL: + { + g_fDamageGame_TimeInterval = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + if (!THIS_MODE_INFO.isOn) + return; + + DamageGame_StartTimers(); + } + + case DAMAGEGAME_CONVAR_DAMAGE: + { + g_fDamageGame_Damage = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + } + + case DAMAGEGAME_CONVAR_MODE: + { + g_iDamageGame_Mode = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + if (!THIS_MODE_INFO.isOn) + return; + + for (int i = 1; i <= MaxClients; i++) + g_iDealtDamage[i] = -1; + + DamageGame_StartTimers(); + } + + case DAMAGEGAME_CONVAR_TOGGLE: + { + bool val = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bDamageGame_Enabled = val; + } + } } stock void OnMapStart_DamageGame() {} @@ -87,7 +138,7 @@ stock void OnClientPutInServer_DamageGame(int client) { if (g_bSDKHook_OnTakeDamagePost[client]) return; - + SDKHook(client, SDKHook_OnTakeDamagePost, OnTakeDamagePost); g_bSDKHook_OnTakeDamagePost[client] = true; } @@ -96,7 +147,7 @@ stock void OnClientDisconnect_DamageGame(int client) { if (!THIS_MODE_INFO.isOn) return; - + g_iDealtDamage[client] = -1; } @@ -105,19 +156,19 @@ stock void ZR_OnClientInfected_DamageGame(int client) #pragma unused client if (!THIS_MODE_INFO.isOn) return; - + if (!g_bMotherZombie && g_hDamageGameTimer == null) - DamageGame_StartTimers(); + DamageGame_StartTimers(); } stock void Event_RoundStart_DamageGame() { if (!THIS_MODE_INFO.isOn) return; - + for (int i = 1; i <= MaxClients; i++) g_iDealtDamage[i] = -1; - + delete g_hDamageGameTimer; } @@ -136,7 +187,7 @@ stock void Event_PlayerDeath_DamageGame(int client) { if (!THIS_MODE_INFO.isOn) return; - + g_iDealtDamage[client] = -1; } @@ -144,13 +195,13 @@ stock void OnTakeDamagePost_DamageGame(int victim, int attacker, float damage) { if (!THIS_MODE_INFO.isOn) return; - + if (!(IsPlayerAlive(victim) && ZR_IsClientZombie(victim))) return; - + if (!(0 < attacker <= MaxClients && IsPlayerAlive(attacker) && ZR_IsClientHuman(attacker))) return; - + g_iDealtDamage[attacker] += RoundToNearest(damage); } @@ -163,7 +214,7 @@ stock void OnWeaponEquip_DamageGame(int client, int weapon, Action &result) public Action Cmd_DamageGameToggle(int client, int args) { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) + if (!g_bDamageGame_Enabled) { CReplyToCommand(client, "%s Damage Game mode is currently disabled!", THIS_MODE_INFO.tag); return Plugin_Handled; @@ -179,34 +230,34 @@ public Action Cmd_DamageGameToggle(int client, int args) FunModes_HookEvent(g_bEvent_RoundStart, "round_start", Event_RoundStart); FunModes_HookEvent(g_bEvent_RoundEnd, "round_end", Event_RoundEnd); FunModes_HookEvent(g_bEvent_PlayerDeath, "player_death", Event_PlayerDeath); - + for (int i = 1; i <= MaxClients; i++) { g_iDealtDamage[i] = -1; - + if (!IsClientInGame(i)) continue; - + OnClientPutInServer_DamageGame(i); } - + FunModes_RestartRound(); } else { delete g_hDamageGameTimer; } - + return Plugin_Handled; } void DamageGame_StartTimers() { - int interval = THIS_MODE_INFO.cvarInfo[DAMAGEGAME_CONVAR_TIME_INTERVAL].cvar.IntValue; - + int interval = RoundToNearest(g_fDamageGame_TimeInterval); + delete g_hDamageGameTimer; - g_hDamageGameTimer = CreateTimer(float(interval), Timer_DamageGame, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); - switch (THIS_MODE_INFO.cvarInfo[DAMAGEGAME_CONVAR_MODE].cvar.IntValue) + g_hDamageGameTimer = CreateTimer(g_fDamageGame_TimeInterval, Timer_DamageGame, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); + switch (g_iDamageGame_Mode) { case 0: CPrintToChatAll("%s Humans with lowest damage dealt to zombies will get damaged every %d seconds!", THIS_MODE_INFO.tag, interval); case 1: CPrintToChatAll("%s Humans who don't shoot zombies for {olive}%d seconds {lightgreen}(repeated) will be damaged", THIS_MODE_INFO.tag, interval); @@ -225,17 +276,17 @@ Action Timer_DamageGame(Handle timer) g_hDamageGameTimer = null; return Plugin_Stop; } - + if (g_bDamageGameDisable) return Plugin_Handled; - + if (!g_bMotherZombie || g_bRoundEnd) return Plugin_Handled; - + int lowestDamage = 999999, count, clients[MAXPLAYERS + 1]; - - int mode = THIS_MODE_INFO.cvarInfo[DAMAGEGAME_CONVAR_MODE].cvar.IntValue; - + + int mode = g_iDamageGame_Mode; + for (int i = 1; i <= MaxClients; i++) { int thisDamage = 0; @@ -246,27 +297,27 @@ Action Timer_DamageGame(Handle timer) g_iDealtDamage[i] = -1; continue; } - + g_iDealtDamage[i] = 0; } else { thisDamage = g_iDealtDamage[i]; } - + if ((mode > 0 && thisDamage == 0) || (mode != 1 && (thisDamage == 0 || thisDamage < lowestDamage))) { clients[count++] = i; lowestDamage = thisDamage; } } - + if (mode == 0 && lowestDamage == 999999) return Plugin_Continue; - + if (!count) return Plugin_Continue; - + /* Depending on the damagegame mode, we will specify which clients to damage */ for (int i = 0; i < count; i++) { @@ -278,13 +329,13 @@ Action Timer_DamageGame(Handle timer) if (lowestDamage == g_iDealtDamage[client]) DamageGame_DamagePlayer(client); } - + case 1: { if (g_iDealtDamage[client] == 0) DamageGame_DamagePlayer(client); } - + default: { if (g_iDealtDamage[client] == 0 || (lowestDamage != 0 && lowestDamage == g_iDealtDamage[client])) @@ -292,25 +343,25 @@ Action Timer_DamageGame(Handle timer) } } } - + if (mode > 0) { for (int i = 1; i <= MaxClients; i++) g_iDealtDamage[i] = -1; } - + return Plugin_Continue; } void DamageGame_DamagePlayer(int client) { int health = GetClientHealth(client); - int newHealth = health - THIS_MODE_INFO.cvarInfo[DAMAGEGAME_CONVAR_DAMAGE].cvar.IntValue; + int newHealth = health - RoundToNearest(g_fDamageGame_Damage); if (newHealth <= 0) ForcePlayerSuicide(client); - else + else SetEntityHealth(client, newHealth); - + CPrintToChat(client, "%s You have been damaged for being a bad defender", THIS_MODE_INFO.tag); CPrintToChatAll("%s %N {olive}got damaged for being a bad defender!", THIS_MODE_INFO.tag, client); } @@ -323,11 +374,11 @@ public void Cmd_DamageGameSettings(int client) menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); menu.AddItem(NULL_STRING, "Show Cvars\n "); - + char item[20]; FormatEx(item, sizeof(item), "%s Damage", g_bDamageGameDisable ? "Enable" : "Disable"); menu.AddItem(NULL_STRING, item); - + menu.ExitBackButton = true; menu.Display(client, MENU_TIME_FOREVER); } @@ -338,7 +389,7 @@ int Menu_DamageGameSettings(Menu menu, MenuAction action, int param1, int param2 { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) @@ -358,4 +409,4 @@ int Menu_DamageGameSettings(Menu menu, MenuAction action, int param1, int param2 } return 0; -} \ No newline at end of file +} diff --git a/addons/sourcemod/scripting/Fun_Modes/DoubleJump.sp b/addons/sourcemod/scripting/Fun_Modes/DoubleJump.sp index 44e73f8..0ad2cee 100644 --- a/addons/sourcemod/scripting/Fun_Modes/DoubleJump.sp +++ b/addons/sourcemod/scripting/Fun_Modes/DoubleJump.sp @@ -1,77 +1,128 @@ -/* - (). FunModes V2: - - @file DoubleJump.sp - @Usage Functions for the DoubleJump mode. -*/ #pragma semicolon 1 #pragma newdecls required -ModeInfo g_DoubleJumpInfo; +static int g_iDoubleJumpIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iDoubleJumpIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_DoubleJumpInfo +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] + +#define DOUBLEJUMP_CONVAR_BOOST 0 +#define DOUBLEJUMP_CONVAR_MAX_JUMPS 1 +#define DOUBLEJUMP_CONVAR_HUMANS 2 +#define DOUBLEJUMP_CONVAR_ZOMBIES 3 +#define DOUBLEJUMP_CONVAR_TOGGLE 4 + +float g_fDoubleJump_Boost; +int g_iDoubleJump_MaxJumps; -#define DOUBLEJUMP_CONVAR_BOOST 0 -#define DOUBLEJUMP_CONVAR_MAX_JUMPS 1 -#define DOUBLEJUMP_CONVAR_HUMANS 2 -#define DOUBLEJUMP_CONVAR_ZOMBIES 3 -#define DOUBLEJUMP_CONVAR_TOGGLE 4 +bool g_bDoubleJump_Humans; +bool g_bDoubleJump_Zombies; +bool g_bDoubleJump_Enabled; -/* CALLED on Plugin Start */ stock void OnPluginStart_DoubleJump() { + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + THIS_MODE_INFO.name = "DoubleJump"; THIS_MODE_INFO.tag = "{gold}[FunModes-DoubleJump]{lightgreen}"; - /* ADMIN COMMANDS */ - RegAdminCmd("sm_fm_doublejump", Cmd_DoubleJumpToggle, ADMFLAG_CONVARS, "Enable/Disable Double Jump mode."); - RegAdminCmd("sm_doublejump_settings", Cmd_DoubleJumpSettings, ADMFLAG_CONFIG, "Open DoubleJump Settings Menu"); - - /* CONVARS */ + RegAdminCmd("sm_fm_doublejump", Cmd_DoubleJumpToggle, ADMFLAG_CONVARS); + RegAdminCmd("sm_doublejump_settings", Cmd_DoubleJumpSettings, ADMFLAG_CONFIG); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, DOUBLEJUMP_CONVAR_BOOST, - "sm_doublejump_boost", "260.0", "The amount of vertical boost to apply to double jumps.", - ("150.0,260.0,300.0,320.0"), "float" + DOUBLEJUMP_CONVAR_BOOST, "sm_doublejump_boost", + "260.0", "Vertical boost applied to double jump", + ("150.0,260.0,300.0,320.0"), CONVAR_FLOAT ); + THIS_MODE_INFO.cvars[DOUBLEJUMP_CONVAR_BOOST].HookChange(DoubleJump_OnConVarChange); DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, DOUBLEJUMP_CONVAR_MAX_JUMPS, - "sm_doublejump_max_jumps", "1", "How many re-jumps the player can do while he is in the air.", - ("1,2,3,4,5"), "int" + DOUBLEJUMP_CONVAR_MAX_JUMPS, "sm_doublejump_max_jumps", + "1", "Number of mid-air jumps", + ("1,2,3,4,5"), CONVAR_INT ); + THIS_MODE_INFO.cvars[DOUBLEJUMP_CONVAR_MAX_JUMPS].HookChange(DoubleJump_OnConVarChange); DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, DOUBLEJUMP_CONVAR_HUMANS, - "sm_doublejump_humans", "1", "Enable/Disable Double jump for humans.", - ("0,1"), "bool" + DOUBLEJUMP_CONVAR_HUMANS, "sm_doublejump_humans", + "1", "Enable for humans", + ("0,1"), CONVAR_BOOL ); + THIS_MODE_INFO.cvars[DOUBLEJUMP_CONVAR_HUMANS].HookChange(DoubleJump_OnConVarChange); DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, DOUBLEJUMP_CONVAR_ZOMBIES, - "sm_doublejump_zombies", "0", "Enable/Disable Double jump zombies.", - ("0,1"), "bool" + DOUBLEJUMP_CONVAR_ZOMBIES, "sm_doublejump_zombies", + "0", "Enable for zombies", + ("0,1"), CONVAR_BOOL ); + THIS_MODE_INFO.cvars[DOUBLEJUMP_CONVAR_ZOMBIES].HookChange(DoubleJump_OnConVarChange); DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, DOUBLEJUMP_CONVAR_TOGGLE, - "sm_doublejump_enable", "1", "Enable/Disable Double Jump mode", - ("0,1"), "bool" + DOUBLEJUMP_CONVAR_TOGGLE, "sm_doublejump_enable", + "1", "Enable DoubleJump", + ("0,1"), CONVAR_BOOL ); + THIS_MODE_INFO.cvars[DOUBLEJUMP_CONVAR_TOGGLE].HookChange(DoubleJump_OnConVarChange); THIS_MODE_INFO.enableIndex = DOUBLEJUMP_CONVAR_TOGGLE; - - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; +} + +void InitCvarsValues_DoubleJump() +{ + int modeIndex = THIS_MODE_INFO.index; + + g_fDoubleJump_Boost = + _FUNMODES_CVAR_GET_VALUE(modeIndex, DOUBLEJUMP_CONVAR_BOOST, Float); + + g_iDoubleJump_MaxJumps = + _FUNMODES_CVAR_GET_VALUE(modeIndex, DOUBLEJUMP_CONVAR_MAX_JUMPS, Int); - THIS_MODE_INFO.cvarInfo[DOUBLEJUMP_CONVAR_TOGGLE].cvar.AddChangeHook(OnDoubleJumpModeToggle); + g_bDoubleJump_Humans = + _FUNMODES_CVAR_GET_VALUE(modeIndex, DOUBLEJUMP_CONVAR_HUMANS, Bool); + + g_bDoubleJump_Zombies = + _FUNMODES_CVAR_GET_VALUE(modeIndex, DOUBLEJUMP_CONVAR_ZOMBIES, Bool); + + g_bDoubleJump_Enabled = + _FUNMODES_CVAR_GET_VALUE(modeIndex, DOUBLEJUMP_CONVAR_TOGGLE, Bool); } -void OnDoubleJumpModeToggle(ConVar cvar, const char[] newValue, const char[] oldValue) +void DoubleJump_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) { - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + switch (cvarIndex) + { + case DOUBLEJUMP_CONVAR_BOOST: + g_fDoubleJump_Boost = + _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case DOUBLEJUMP_CONVAR_MAX_JUMPS: + g_iDoubleJump_MaxJumps = + _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + case DOUBLEJUMP_CONVAR_HUMANS: + g_bDoubleJump_Humans = + _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + + case DOUBLEJUMP_CONVAR_ZOMBIES: + g_bDoubleJump_Zombies = + _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + + case DOUBLEJUMP_CONVAR_TOGGLE: + { + bool val = + _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bDoubleJump_Enabled = val; + } + } } stock void OnMapStart_DoubleJump() {} @@ -114,89 +165,87 @@ stock void Event_PlayerDeath_DoubleJump(int client) public Action Cmd_DoubleJumpToggle(int client, int args) { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) + if (!g_bDoubleJump_Enabled) { - CReplyToCommand(client, "%s Double Jump mode is currently disabled!", THIS_MODE_INFO.tag); + CReplyToCommand(client, "%s DoubleJump disabled", THIS_MODE_INFO.tag); return Plugin_Handled; } CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, !THIS_MODE_INFO.isOn, THIS_MODE_INFO.index); - CPrintToChatAll("%s Double Jump is now {olive}%s. %s", THIS_MODE_INFO.tag, (THIS_MODE_INFO.isOn) ? "Enabled" : "Disabled", - (THIS_MODE_INFO.isOn) ? "You can re-jump while you are in the air." : ""); + CPrintToChatAll( + "%s DoubleJump is now %s", + THIS_MODE_INFO.tag, + THIS_MODE_INFO.isOn ? "Enabled" : "Disabled" + ); if (THIS_MODE_INFO.isOn) { - CPrintToChatAll("%s Humans Double Jump: {olive}%s\n%s Zombies Double Jump: {olive}%s.", - THIS_MODE_INFO.tag, (THIS_MODE_INFO.cvarInfo[DOUBLEJUMP_CONVAR_HUMANS].cvar.BoolValue) ? "Enabled" : "Disabled", - THIS_MODE_INFO.tag, (THIS_MODE_INFO.cvarInfo[DOUBLEJUMP_CONVAR_ZOMBIES].cvar.BoolValue) ? "Enabled" : "Disabled"); + CPrintToChatAll( + "%s Humans: %s | Zombies: %s", + THIS_MODE_INFO.tag, + g_bDoubleJump_Humans ? "Enabled" : "Disabled", + g_bDoubleJump_Zombies ? "Enabled" : "Disabled" + ); } - + return Plugin_Handled; } -/* SM DOUBLEJUMP 1.1.0, ALL CREDITS GO TO - https://forums.alliedmods.net/showpost.php?p=2759524&postcount=37 */ void OnPlayerRunCmdPost_DoubleJump(int client, int buttons, int impulse) { - #pragma unused buttons #pragma unused impulse - - if (!THIS_MODE_INFO.isOn || !IsClientInGame(client) || !IsPlayerAlive(client)) + + if (!THIS_MODE_INFO.isOn || !IsPlayerAlive(client)) return; - if ((!THIS_MODE_INFO.cvarInfo[DOUBLEJUMP_CONVAR_HUMANS].cvar.BoolValue && GetClientTeam(client) == CS_TEAM_CT) || (!THIS_MODE_INFO.cvarInfo[DOUBLEJUMP_CONVAR_ZOMBIES].cvar.BoolValue && GetClientTeam(client) == CS_TEAM_T)) + bool isHuman = GetClientTeam(client) == CS_TEAM_CT; + bool isZombie = GetClientTeam(client) == CS_TEAM_T; + + if ((isHuman && !g_bDoubleJump_Humans) + || (isZombie && !g_bDoubleJump_Zombies)) return; - static bool inGround; - static bool inJump; - static bool wasJump[MAXPLAYERS + 1]; - static bool landed[MAXPLAYERS + 1]; + static bool wasJump[MAXPLAYERS+1]; + static int jumps[MAXPLAYERS+1]; - inGround = !!(GetEntityFlags(client) & FL_ONGROUND); - inJump = !!(GetClientButtons(client) & IN_JUMP); + bool onGround = !!(GetEntityFlags(client) & FL_ONGROUND); + bool pressingJump = !!(buttons & IN_JUMP); - if (!landed[client]) - { - if (THIS_MODE_INFO.cvarInfo[DOUBLEJUMP_CONVAR_MAX_JUMPS].cvar.IntValue) - { - static int jumps[MAXPLAYERS+1]; - if (inGround) - jumps[client] = 0; - else if (!wasJump[client] && inJump && jumps[client]++ <= THIS_MODE_INFO.cvarInfo[DOUBLEJUMP_CONVAR_MAX_JUMPS].cvar.IntValue) - ApplyNewJump(client); - } - else if (!inGround && !wasJump[client] && inJump) - { - ApplyNewJump(client); - } - } + if (onGround) + jumps[client] = 0; - landed[client] = inGround; - wasJump[client] = inJump; + else if (!wasJump[client] + && pressingJump + && jumps[client]++ <= g_iDoubleJump_MaxJumps) + ApplyNewJump(client); - return; + wasJump[client] = pressingJump; } stock void ApplyNewJump(int client) { - static float vel[3]; + float vel[3]; + GetEntPropVector(client, Prop_Data, "m_vecVelocity", vel); - vel[2] = THIS_MODE_INFO.cvarInfo[DOUBLEJUMP_CONVAR_BOOST].cvar.FloatValue; + + vel[2] = g_fDoubleJump_Boost; TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, vel); } -/* DoubleJump Settings */ public Action Cmd_DoubleJumpSettings(int client, int args) { Menu menu = new Menu(Menu_DoubleJumpSettings); - menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); + menu.SetTitle("%s Settings", THIS_MODE_INFO.name); - menu.AddItem(NULL_STRING, "Show Cvars\n"); + menu.AddItem(NULL_STRING, "Show Cvars"); menu.ExitBackButton = true; + menu.Display(client, MENU_TIME_FOREVER); + return Plugin_Handled; } @@ -206,7 +255,7 @@ int Menu_DoubleJumpSettings(Menu menu, MenuAction action, int param1, int param2 { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) @@ -214,10 +263,8 @@ int Menu_DoubleJumpSettings(Menu menu, MenuAction action, int param1, int param2 } case MenuAction_Select: - { ShowCvarsInfo(param1, THIS_MODE_INFO); - } } return 0; -} \ No newline at end of file +} diff --git a/addons/sourcemod/scripting/Fun_Modes/Fog.sp b/addons/sourcemod/scripting/Fun_Modes/Fog.sp index 42dd4cf..442c5d0 100644 --- a/addons/sourcemod/scripting/Fun_Modes/Fog.sp +++ b/addons/sourcemod/scripting/Fun_Modes/Fog.sp @@ -1,31 +1,30 @@ -/* - (). FunModes V2: - - @file Fog.sp - @Usage Functions for the Fog mode. -*/ #pragma semicolon 1 #pragma newdecls required -ModeInfo g_FogInfo; +static int g_iFogIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iFogIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_FogInfo +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] -#define FOGInput_Color 0 -#define FOGInput_Start 1 -#define FOGInput_End 2 +#define FOGInput_Color 0 +#define FOGInput_Start 1 +#define FOGInput_End 2 #define FOGInput_Toggle 3 -#define FOG_NAME "fog_mode_aaa34124n" +#define FOG_NAME "fog_mode_aaa34124n" + +#define FOG_CONVAR_TOGGLE 0 enum struct fogData { float fogStart; float fogEnd; int fogColor[4]; - + void SetColor(int setColor[4]) { this.fogColor[0] = setColor[0]; @@ -39,37 +38,55 @@ fogData g_FogData; int g_iFogEntity = -1; -#define FOG_CONVAR_TOGGLE 0 +bool g_bFog_Enabled; -/* CALLED ON PLUGIN START */ stock void OnPluginStart_Fog() { + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + THIS_MODE_INFO.name = "Fog"; THIS_MODE_INFO.tag = "{gold}[FunModes-FOG]{lightgreen}"; - RegAdminCmd("sm_fm_fog", Cmd_FogToggle, ADMFLAG_CONVARS, "Toggle fog on/off"); - RegAdminCmd("sm_fogmode", Cmd_FogSettings, ADMFLAG_CONVARS, "Fog Settings"); - RegAdminCmd("sm_fog_start", Cmd_FogStart, ADMFLAG_CONVARS, "Fog Start"); - RegAdminCmd("sm_fog_end", Cmd_FogEnd, ADMFLAG_CONVARS, "Fog End"); + RegAdminCmd("sm_fm_fog", Cmd_FogToggle, ADMFLAG_CONVARS); + RegAdminCmd("sm_fogmode", Cmd_FogSettings, ADMFLAG_CONVARS); + RegAdminCmd("sm_fog_start", Cmd_FogStart, ADMFLAG_CONVARS); + RegAdminCmd("sm_fog_end", Cmd_FogEnd, ADMFLAG_CONVARS); DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, FOG_CONVAR_TOGGLE, - "sm_fog_enable", "1", "Enable/Disable Fog Mode (This differs from turning it on/off)", - ("0,1"), "bool" + FOG_CONVAR_TOGGLE, "sm_fog_enable", + "1", "Enable Fog mode", + ("0,1"), CONVAR_BOOL ); + THIS_MODE_INFO.cvars[FOG_CONVAR_TOGGLE].HookChange(Fog_OnConVarChange); + THIS_MODE_INFO.enableIndex = FOG_CONVAR_TOGGLE; - - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; +} - THIS_MODE_INFO.cvarInfo[FOG_CONVAR_TOGGLE].cvar.AddChangeHook(OnFogModeToggle); +void InitCvarsValues_Fog() +{ + int modeIndex = THIS_MODE_INFO.index; + + g_bFog_Enabled = + _FUNMODES_CVAR_GET_VALUE(modeIndex, FOG_CONVAR_TOGGLE, Bool); } -void OnFogModeToggle(ConVar cvar, const char[] newValue, const char[] oldValue) +void Fog_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) { - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + switch (cvarIndex) + { + case FOG_CONVAR_TOGGLE: + { + bool val = + _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bFog_Enabled = val; + } + } } stock void OnMapStart_Fog() @@ -271,20 +288,7 @@ public int FogSettings_Handler(Menu menu, MenuAction action, int param1, int par } case 1: { - bool isOn = THIS_MODE_INFO.isOn; - if (isOn) - { - CPrintToChat(param1, "%s %T", THIS_MODE_INFO.tag, "Fog_Disabled", param1); - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, false, THIS_MODE_INFO.index); - } - else - { - CPrintToChat(param1, "%s %T", THIS_MODE_INFO.tag, "Fog_Enabled", param1); - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, true, THIS_MODE_INFO.index); - } - - AcceptFogInput(FOGInput_Toggle); - Fog_DisplaySettingsMenu(param1); + Cmd_FogToggle(param1, 0); } } } @@ -391,7 +395,7 @@ public int FogColorsMenu_Handler(Menu menu, MenuAction action, int param1, int p public Action Cmd_FogToggle(int client, int args) { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) + if (!g_bFog_Enabled) { CReplyToCommand(client, "%s Fog mode is currently disabled!", THIS_MODE_INFO.tag); return Plugin_Handled; @@ -416,7 +420,7 @@ public Action Cmd_FogToggle(int client, int args) } } -Action Cmd_FogSettings(int client, int args) +public Action Cmd_FogSettings(int client, int args) { if (!client) return Plugin_Handled; @@ -489,4 +493,4 @@ Action Cmd_FogEnd(int client, int args) AcceptFogInput(FOGInput_End); CReplyToCommand(client, "%s You have changed FOG End Distance to %d", THIS_MODE_INFO.tag, distance); return Plugin_Handled; -} \ No newline at end of file +} diff --git a/addons/sourcemod/scripting/Fun_Modes/GunGame.sp b/addons/sourcemod/scripting/Fun_Modes/GunGame.sp index addd243..2c2ac23 100644 --- a/addons/sourcemod/scripting/Fun_Modes/GunGame.sp +++ b/addons/sourcemod/scripting/Fun_Modes/GunGame.sp @@ -1,18 +1,17 @@ /* (). FunModes V2: - + @file GunGame.sp - @Usage Functions for the GunGame Mode. - + @Usage Functions for the GunGame Mode. */ /* - GunGame Escape: Humans start with pistols like in a gg game, and every 1 thousand damage, - the gun automatically upgrades to the next one, making it into pistols, smgs, rifles and ending in m249. - After 1 complete cycle (If the map is long enough to cycle), - the human will get a random advantage such as 3 extra grenades, more speed, more grav... etc - - By @kiku-san + GunGame Escape: Humans start with pistols like in a gg game, and every 1 thousand damage, + the gun automatically upgrades to the next one, making it into pistols, smgs, rifles and ending in m249. + After 1 complete cycle (If the map is long enough to cycle), + the human will get a random advantage such as 3 extra grenades, more speed, more grav... etc + + By @kiku-san */ #pragma semicolon 1 @@ -22,656 +21,715 @@ #define _FM_GunGame -ModeInfo g_GunGameInfo; +static int g_iGunGameIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iGunGameIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_GunGameInfo +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] -#define GUNGAME_CONVAR_PISTOLS_DAMAGE 0 -#define GUNGAME_CONVAR_SHOTGUNS_DAMAGE 1 -#define GUNGAME_CONVAR_SMGS_DAMAGE 2 -#define GUNGAME_CONVAR_RIFLES_DAMAGE 3 -#define GUNGAME_CONVAR_M249_DAMAGE 4 -#define GUNGAME_CONVAR_SMOKEGRENADES_COUNT 5 -#define GUNGAME_CONVAR_REWARD_SPEED 6 -#define GUNGAME_CONVAR_TOGGLE 7 +#define GUNGAME_CONVAR_PISTOLS_DAMAGE 0 +#define GUNGAME_CONVAR_SHOTGUNS_DAMAGE 1 +#define GUNGAME_CONVAR_SMGS_DAMAGE 2 +#define GUNGAME_CONVAR_RIFLES_DAMAGE 3 +#define GUNGAME_CONVAR_M249_DAMAGE 4 +#define GUNGAME_CONVAR_SMOKEGRENADES_COUNT 5 +#define GUNGAME_CONVAR_REWARD_SPEED 6 +#define GUNGAME_CONVAR_TOGGLE 7 static const char g_GunGameWeaponsList[][][] = { - { "weapon_glock", "weapon_usp", "weapon_p228", "weapon_deagle", "weapon_elite", "weapon_fiveseven" }, /* Pistols */ - { "weapon_m3", "weapon_xm1014", "", "", "", "" }, /* Shotguns */ - { "weapon_mac10", "weapon_ump45", "weapon_tmp", "weapon_mp5navy", "weapon_p90", "" }, /* SMGs */ - { "weapon_galil", "weapon_famas", "weapon_sg552", "weapon_aug", "weapon_ak47", "weapon_m4a1" }, /* Rifles */ - { "weapon_m249", "", "", "", "", "" } /* The one and only :) */ + { "weapon_glock", "weapon_usp", "weapon_p228", "weapon_deagle", "weapon_elite", "weapon_fiveseven" }, + { "weapon_m3", "weapon_xm1014", "", "", "", "" }, + { "weapon_mac10", "weapon_ump45", "weapon_tmp", "weapon_mp5navy", "weapon_p90", "" }, + { "weapon_galil", "weapon_famas", "weapon_sg552", "weapon_aug", "weapon_ak47", "weapon_m4a1" }, + { "weapon_m249", "", "", "", "", "" } }; enum GunGame_Reward { - REWARD_SPEED = 0, - REWARD_SMOKEGRENADES, - REWARD_NONE + REWARD_SPEED = 0, + REWARD_SMOKEGRENADES, + REWARD_NONE }; enum struct GunGame_Data { - int level[2]; // [0] = weapon type, [1] = weapon index - int dealtDamage; - - bool completedCycle; - bool allowEquip; - - float originalSpeed; - - GunGame_Reward reward; - Handle rewardTimer; - - void ResetLevel() - { - this.level[0] = 0; - this.level[1] = 0; - } + int level[2]; + int dealtDamage; + + bool completedCycle; + bool allowEquip; + + float originalSpeed; + + GunGame_Reward reward; + Handle rewardTimer; + + void ResetLevel() + { + this.level[0] = 0; + this.level[1] = 0; + } } GunGame_Data g_GunGameData[MAXPLAYERS + 1]; +int g_iGunGame_DamageRequired[5]; +int g_iGunGame_SmokeGrenadesCount; + +float g_fGunGame_RewardSpeed; + +bool g_bGunGame_Enabled; + stock void OnPluginStart_GunGame() { - THIS_MODE_INFO.name = "GunGame"; - THIS_MODE_INFO.tag = "{gold}[FunModes-GunGame]{lightgreen}"; - - /* COMMANDS */ - /* THESE ARE THE STANDARD COMMANDS THAT ALL MODES SHOULD HAVE */ - RegAdminCmd("sm_fm_gungame", Cmd_GunGameToggle, ADMFLAG_CONVARS, "Turn GunGame Mode On/Off"); - RegAdminCmd("sm_gungame_settings", Cmd_GunGameSettings, ADMFLAG_CONVARS, "Open GunGame Sttings Menu"); - - RegConsoleCmd("sm_gungame", Cmd_GunGame, "Get your original weapons"); - - /* CONVARS */ - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, GUNGAME_CONVAR_PISTOLS_DAMAGE, - "sm_gungame_pistols_damage", "1200", "The required damage needed for pistols to upgrade", - ("800,1000,1500,2000,2500"), "int" - ); - - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, GUNGAME_CONVAR_SHOTGUNS_DAMAGE, - "sm_gungame_shotguns_damage", "2200", "The required damage needed for shotguns to upgrade", - ("800,1000,1500,2000,2500"), "int" - ); - - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, GUNGAME_CONVAR_SMGS_DAMAGE, - "sm_gungame_smgs_damage", "4200", "The required damage needed for smgs to upgrade", - ("800,1000,1500,2000,2500"), "int" - ); - - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, GUNGAME_CONVAR_RIFLES_DAMAGE, - "sm_gungame_rifles_damage", "3800", "The required damage needed for rifles to upgrade", - ("800,1000,1500,2000,2500"), "int" - ); - - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, GUNGAME_CONVAR_M249_DAMAGE, - "sm_gungame_m249_damage", "8000", "The required damage needed for m249 to finish the gungame cycle", - ("800,1000,1500,2000,2500"), "int" - ); - - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, GUNGAME_CONVAR_SMOKEGRENADES_COUNT, - "sm_gungame_hegrenades_reward", "2", "How many smokegrenades to give to the player when completing a cycle", - ("1,3,5,10,15"), "int" - ); - - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, GUNGAME_CONVAR_REWARD_SPEED, - "sm_gungame_speed_reward", "100.0", "How many seconds can the player keep their high speed hold", - ("20.0,30.0,40.0,60.0,80.0,100.0"), "float" - ); - - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, GUNGAME_CONVAR_TOGGLE, - "sm_gungame_enable", "1", "Enable/Disable GunGame Mode (This differs from turning it on/off)", - ("0,1"), "bool" - ); - - THIS_MODE_INFO.enableIndex = GUNGAME_CONVAR_TOGGLE; - - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; - - THIS_MODE_INFO.cvarInfo[GUNGAME_CONVAR_TOGGLE].cvar.AddChangeHook(OnGunGameModeToggle); + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + + THIS_MODE_INFO.name = "GunGame"; + THIS_MODE_INFO.tag = "{gold}[FunModes-GunGame]{lightgreen}"; + + RegAdminCmd("sm_fm_gungame", Cmd_GunGameToggle, ADMFLAG_CONVARS, "Turn GunGame Mode On/Off"); + RegAdminCmd("sm_gungame_settings", Cmd_GunGameSettings, ADMFLAG_CONVARS, "Open GunGame Sttings Menu"); + + RegConsoleCmd("sm_gungame", Cmd_GunGame, "Get your original weapons"); + + DECLARE_FM_CVAR( + GUNGAME_CONVAR_PISTOLS_DAMAGE, "sm_gungame_pistols_damage", + "1200", "The required damage needed for pistols to upgrade", + ("800,1000,1500,2000,2500"), CONVAR_INT + ); + THIS_MODE_INFO.cvars[GUNGAME_CONVAR_PISTOLS_DAMAGE].HookChange(GunGame_OnConVarChange); + + DECLARE_FM_CVAR( + GUNGAME_CONVAR_SHOTGUNS_DAMAGE, "sm_gungame_shotguns_damage", + "2200", "The required damage needed for shotguns to upgrade", + ("800,1000,1500,2000,2500"), CONVAR_INT + ); + THIS_MODE_INFO.cvars[GUNGAME_CONVAR_SHOTGUNS_DAMAGE].HookChange(GunGame_OnConVarChange); + + DECLARE_FM_CVAR( + GUNGAME_CONVAR_SMGS_DAMAGE, "sm_gungame_smgs_damage", + "4200", "The required damage needed for smgs to upgrade", + ("800,1000,1500,2000,2500"), CONVAR_INT + ); + THIS_MODE_INFO.cvars[GUNGAME_CONVAR_SMGS_DAMAGE].HookChange(GunGame_OnConVarChange); + + DECLARE_FM_CVAR( + GUNGAME_CONVAR_RIFLES_DAMAGE, "sm_gungame_rifles_damage", + "3800", "The required damage needed for rifles to upgrade", + ("800,1000,1500,2000,2500"), CONVAR_INT + ); + THIS_MODE_INFO.cvars[GUNGAME_CONVAR_RIFLES_DAMAGE].HookChange(GunGame_OnConVarChange); + + DECLARE_FM_CVAR( + GUNGAME_CONVAR_M249_DAMAGE, "sm_gungame_m249_damage", + "8000", "The required damage needed for m249 to finish the gungame cycle", + ("800,1000,1500,2000,2500"), CONVAR_INT + ); + THIS_MODE_INFO.cvars[GUNGAME_CONVAR_M249_DAMAGE].HookChange(GunGame_OnConVarChange); + + DECLARE_FM_CVAR( + GUNGAME_CONVAR_SMOKEGRENADES_COUNT, "sm_gungame_hegrenades_reward", + "2", "How many smokegrenades to give to the player when completing a cycle", + ("1,3,5,10,15"), CONVAR_INT + ); + THIS_MODE_INFO.cvars[GUNGAME_CONVAR_SMOKEGRENADES_COUNT].HookChange(GunGame_OnConVarChange); + + DECLARE_FM_CVAR( + GUNGAME_CONVAR_REWARD_SPEED, "sm_gungame_speed_reward", + "100.0", "How many seconds can the player keep their high speed hold", + ("20.0,30.0,40.0,60.0,80.0,100.0"), CONVAR_FLOAT + ); + THIS_MODE_INFO.cvars[GUNGAME_CONVAR_REWARD_SPEED].HookChange(GunGame_OnConVarChange); + + DECLARE_FM_CVAR( + GUNGAME_CONVAR_TOGGLE, "sm_gungame_enable", + "1", "Enable/Disable GunGame Mode (This differs from turning it on/off)", + ("0,1"), CONVAR_BOOL + ); + THIS_MODE_INFO.cvars[GUNGAME_CONVAR_TOGGLE].HookChange(GunGame_OnConVarChange); + + THIS_MODE_INFO.enableIndex = GUNGAME_CONVAR_TOGGLE; } -void OnGunGameModeToggle(ConVar cvar, const char[] newValue, const char[] oldValue) +void InitCvarsValues_GunGame() { - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + int modeIndex = THIS_MODE_INFO.index; + + g_iGunGame_DamageRequired[0] = _FUNMODES_CVAR_GET_VALUE(modeIndex, GUNGAME_CONVAR_PISTOLS_DAMAGE, Int); + g_iGunGame_DamageRequired[1] = _FUNMODES_CVAR_GET_VALUE(modeIndex, GUNGAME_CONVAR_SHOTGUNS_DAMAGE, Int); + g_iGunGame_DamageRequired[2] = _FUNMODES_CVAR_GET_VALUE(modeIndex, GUNGAME_CONVAR_SMGS_DAMAGE, Int); + g_iGunGame_DamageRequired[3] = _FUNMODES_CVAR_GET_VALUE(modeIndex, GUNGAME_CONVAR_RIFLES_DAMAGE, Int); + g_iGunGame_DamageRequired[4] = _FUNMODES_CVAR_GET_VALUE(modeIndex, GUNGAME_CONVAR_M249_DAMAGE, Int); + + g_iGunGame_SmokeGrenadesCount = _FUNMODES_CVAR_GET_VALUE(modeIndex, GUNGAME_CONVAR_SMOKEGRENADES_COUNT, Int); + g_fGunGame_RewardSpeed = _FUNMODES_CVAR_GET_VALUE(modeIndex, GUNGAME_CONVAR_REWARD_SPEED, Float); + + g_bGunGame_Enabled = _FUNMODES_CVAR_GET_VALUE(modeIndex, GUNGAME_CONVAR_TOGGLE, Bool); +} + +void GunGame_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) +{ + switch (cvarIndex) + { + case GUNGAME_CONVAR_PISTOLS_DAMAGE: + { + g_iGunGame_DamageRequired[0] = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + } + + case GUNGAME_CONVAR_SHOTGUNS_DAMAGE: + g_iGunGame_DamageRequired[1] = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + case GUNGAME_CONVAR_SMGS_DAMAGE: + g_iGunGame_DamageRequired[2] = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + case GUNGAME_CONVAR_RIFLES_DAMAGE: + g_iGunGame_DamageRequired[3] = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + case GUNGAME_CONVAR_M249_DAMAGE: + g_iGunGame_DamageRequired[4] = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + case GUNGAME_CONVAR_SMOKEGRENADES_COUNT: + g_iGunGame_SmokeGrenadesCount = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + case GUNGAME_CONVAR_REWARD_SPEED: + g_fGunGame_RewardSpeed = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case GUNGAME_CONVAR_TOGGLE: + { + bool val = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bGunGame_Enabled = val; + } + } } stock void OnMapStart_GunGame() {} + stock void OnMapEnd_GunGame() { - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, false, THIS_MODE_INFO.index); - - for (int i = 1; i <= MaxClients; i++) - g_GunGameData[i].rewardTimer = null; + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, false, THIS_MODE_INFO.index); + + for (int i = 1; i <= MaxClients; i++) + g_GunGameData[i].rewardTimer = null; } stock void OnClientPutInServer_GunGame(int client) { - if (!THIS_MODE_INFO.isOn) - return; - - g_GunGameData[client].allowEquip = true; - g_GunGameData[client].ResetLevel(); - - if (!g_bSDKHook_WeaponEquip[client]) - { - SDKHook(client, SDKHook_WeaponEquip, OnWeaponEquip); - g_bSDKHook_WeaponEquip[client] = true; - } - - if (!g_bSDKHook_OnTakeDamagePost[client]) - { - SDKHook(client, SDKHook_OnTakeDamagePost, OnTakeDamagePost); - g_bSDKHook_OnTakeDamagePost[client] = true; - } + if (!THIS_MODE_INFO.isOn) + return; + + g_GunGameData[client].allowEquip = true; + g_GunGameData[client].ResetLevel(); + + if (!g_bSDKHook_WeaponEquip[client]) + { + SDKHook(client, SDKHook_WeaponEquip, OnWeaponEquip); + g_bSDKHook_WeaponEquip[client] = true; + } + + if (!g_bSDKHook_OnTakeDamagePost[client]) + { + SDKHook(client, SDKHook_OnTakeDamagePost, OnTakeDamagePost); + g_bSDKHook_OnTakeDamagePost[client] = true; + } } stock void OnClientDisconnect_GunGame(int client) { - delete g_GunGameData[client].rewardTimer; + delete g_GunGameData[client].rewardTimer; } stock void ZR_OnClientInfected_GunGame(int client) { - #pragma unused client - if (!THIS_MODE_INFO.isOn) - return; - - if (!g_bMotherZombie) - { - for (int i = 1; i <= MaxClients; i++) - { - if (!IsClientInGame(i) || !IsPlayerAlive(i) || !ZR_IsClientHuman(i)) - continue; - - if (EntWatch_HasSpecialItem(i)) - continue; - - GunGame_ResetHuman(i); - } - - CPrintToChatAll("%s Your weapon will be upgraded when you reach the required damage for each weapon type!", THIS_MODE_INFO.tag); - CPrintToChatAll("%s Type {olive}!gungame {lightgreen}if you lost your weapons!", THIS_MODE_INFO.tag); - } + #pragma unused client + if (!THIS_MODE_INFO.isOn) + return; + + if (!g_bMotherZombie) + { + for (int i = 1; i <= MaxClients; i++) + { + if (!IsClientInGame(i) || !IsPlayerAlive(i) || !ZR_IsClientHuman(i)) + continue; + + if (EntWatch_HasSpecialItem(i)) + continue; + + GunGame_ResetHuman(i); + } + + CPrintToChatAll("%s Your weapon will be upgraded when you reach the required damage for each weapon type!", THIS_MODE_INFO.tag); + CPrintToChatAll("%s Type {olive}!gungame {lightgreen}if you lost your weapons!", THIS_MODE_INFO.tag); + } } stock void Event_RoundStart_GunGame() {} + stock void Event_RoundEnd_GunGame() { - for (int i = 1; i <= MaxClients; i++) - g_GunGameData[i].allowEquip = true; + for (int i = 1; i <= MaxClients; i++) + g_GunGameData[i].allowEquip = true; } stock void Event_PlayerSpawn_GunGame(int client) { - if (!THIS_MODE_INFO.isOn || !g_bMotherZombie) - return; - - CreateTimer(2.0, Timer_GunGame_CheckPlayerSpawn, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE); + if (!THIS_MODE_INFO.isOn || !g_bMotherZombie) + return; + + CreateTimer(2.0, Timer_GunGame_CheckPlayerSpawn, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE); } Action Timer_GunGame_CheckPlayerSpawn(Handle timer, int userid) { - int client = GetClientOfUserId(userid); - if (!client) - return Plugin_Stop; - - if (!IsPlayerAlive(client) || !ZR_IsClientHuman(client)) - return Plugin_Stop; - - GunGame_ResetHuman(client); - return Plugin_Stop; + int client = GetClientOfUserId(userid); + if (!client) + return Plugin_Stop; + + if (!IsPlayerAlive(client) || !ZR_IsClientHuman(client)) + return Plugin_Stop; + + GunGame_ResetHuman(client); + return Plugin_Stop; } stock void Event_PlayerTeam_GunGame(Event event) { - #pragma unused event + #pragma unused event } stock void Event_PlayerDeath_GunGame(int client) { - if (!THIS_MODE_INFO.isOn) - return; - - GunGame_GiveReward(client, REWARD_NONE); + if (!THIS_MODE_INFO.isOn) + return; + + GunGame_GiveReward(client, REWARD_NONE); } stock void OnTakeDamagePost_GunGame(int victim, int attacker, float damage) { - if (!THIS_MODE_INFO.isOn) - return; - - if (!(1<=attacker<=MaxClients) || !IsPlayerAlive(attacker) || !IsPlayerAlive(victim) || !ZR_IsClientZombie(victim) || !ZR_IsClientHuman(attacker)) - return; - - if (EntWatch_HasSpecialItem(attacker)) - return; - - int neededDamage = THIS_MODE_INFO.cvarInfo[g_GunGameData[attacker].level[0]].cvar.IntValue; - - if (g_GunGameData[attacker].dealtDamage >= neededDamage) - { - g_GunGameData[attacker].dealtDamage = 0; - GunGame_GiveWeapon(attacker); - return; - } - - g_GunGameData[attacker].dealtDamage += RoundToNearest(damage); + if (!THIS_MODE_INFO.isOn) + return; + + if (!(1<=attacker<=MaxClients) || !IsPlayerAlive(attacker) || !IsPlayerAlive(victim) || !ZR_IsClientZombie(victim) || !ZR_IsClientHuman(attacker)) + return; + + if (EntWatch_HasSpecialItem(attacker)) + return; + + int neededDamage = g_iGunGame_DamageRequired[g_GunGameData[attacker].level[0]]; + + if (g_GunGameData[attacker].dealtDamage >= neededDamage) + { + g_GunGameData[attacker].dealtDamage = 0; + GunGame_GiveWeapon(attacker); + return; + } + + g_GunGameData[attacker].dealtDamage += RoundToNearest(damage); } stock void OnWeaponEquip_GunGame(int client, int weapon, Action &result) { - if (!THIS_MODE_INFO.isOn) - return; - - if (!IsPlayerAlive(client) || ZR_IsClientZombie(client)) - return; - - char className[32]; - GetEntityClassname(weapon, className, sizeof(className)); + if (!THIS_MODE_INFO.isOn) + return; - // kevlar, hegrenades and smokegrenades: - if (StrContains(className, "item_", false) != -1 || StrContains(className, "grenade", false) != -1) - return; - - // flashbang - if (className[7] == 'f' && className[8] == 'l') - return; + if (!IsPlayerAlive(client) || ZR_IsClientZombie(client)) + return; - if (EntWatch_IsSpecialItem(weapon)) - return; + char className[32]; + GetEntityClassname(weapon, className, sizeof(className)); - if (!g_GunGameData[client].allowEquip) - { - result = Plugin_Handled; - return; - } + if (StrContains(className, "item_", false) != -1 || StrContains(className, "grenade", false) != -1) + return; + + if (className[7] == 'f' && className[8] == 'l') + return; + + if (EntWatch_IsSpecialItem(weapon)) + return; + + if (!g_GunGameData[client].allowEquip) + { + result = Plugin_Handled; + return; + } } public Action CS_OnBuyCommand(int client, const char[] weapon) { - if (!THIS_MODE_INFO.isOn) - return Plugin_Continue; - - if (EntWatch_HasSpecialItem(client)) - return Plugin_Continue; + #pragma unused weapon + if (!THIS_MODE_INFO.isOn) + return Plugin_Continue; - if (!g_GunGameData[client].allowEquip) - { - CPrintToChat(client, "%s You cannot buy/equip weapons during GunGame Escape Mode", THIS_MODE_INFO.tag); - return Plugin_Stop; - } - - return Plugin_Continue; + if (EntWatch_HasSpecialItem(client)) + return Plugin_Continue; + + if (!g_GunGameData[client].allowEquip) + { + CPrintToChat(client, "%s You cannot buy/equip weapons during GunGame Escape Mode", THIS_MODE_INFO.tag); + return Plugin_Stop; + } + + return Plugin_Continue; } stock void GunGame_ResetHuman(int client) { - GunGame_GiveReward(client, REWARD_NONE); - g_GunGameData[client].ResetLevel(); - g_GunGameData[client].completedCycle = false; - - GunGame_EquipWeapon(client, g_GunGameWeaponsList[0][GetRandomInt(0, 1)]); + GunGame_GiveReward(client, REWARD_NONE); + g_GunGameData[client].ResetLevel(); + g_GunGameData[client].completedCycle = false; + + GunGame_EquipWeapon(client, g_GunGameWeaponsList[0][GetRandomInt(0, 1)]); } public Action Cmd_GunGameToggle(int client, int args) { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) - { - CReplyToCommand(client, "%s GunGame Mode is currently Disabled", THIS_MODE_INFO.tag); - return Plugin_Handled; - } - - /* You can change whatever you want here */ - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, !THIS_MODE_INFO.isOn, THIS_MODE_INFO.index); - - CPrintToChatAll("%s GunGame Mode is now %s!", THIS_MODE_INFO.tag, THIS_MODE_INFO.isOn ? "On" : "Off"); - - static bool cvarsValues[2]; - - if (THIS_MODE_INFO.isOn) - { - FunModes_HookEvent(g_bEvent_RoundStart, "round_start", Event_RoundStart); - FunModes_HookEvent(g_bEvent_RoundEnd, "round_end", Event_RoundEnd); - FunModes_HookEvent(g_bEvent_PlayerSpawn, "player_spawn", Event_PlayerSpawn); - FunModes_HookEvent(g_bEvent_PlayerDeath, "player_death", Event_PlayerDeath); - - for (int i = 1; i <= MaxClients; i++) - { - if (!IsClientInGame(i)) - continue; - - OnClientPutInServer_GunGame(i); - if (view_as(g_GunGameData[i].reward) < view_as(REWARD_SMOKEGRENADES)) - GunGame_GiveReward(i, REWARD_NONE); - } - - FunModes_RestartRound(); - - ConVar cvar = FindConVar("zr_weapons_zmarket_rebuy"); - if (cvar != null) - { - cvarsValues[0] = cvar.BoolValue; - cvar.BoolValue = false; - delete cvar; - } - - cvar = FindConVar("zr_weapons_zmarket"); - if (cvar != null) - { - cvarsValues[1] = cvar.BoolValue; - cvar.BoolValue = false; - delete cvar; - } - } - else - { - ConVar cvar = FindConVar("zr_weapons_zmarket_rebuy"); - if (cvar != null) - { - cvar.BoolValue = cvarsValues[0]; - delete cvar; - } - - cvar = FindConVar("zr_weapons_zmarket"); - if (cvar != null) - { - cvar.BoolValue = cvarsValues[1]; - delete cvar; - } - } - - return Plugin_Handled; + if (!g_bGunGame_Enabled) + { + CReplyToCommand(client, "%s GunGame Mode is currently Disabled", THIS_MODE_INFO.tag); + return Plugin_Handled; + } + + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, !THIS_MODE_INFO.isOn, THIS_MODE_INFO.index); + + CPrintToChatAll("%s GunGame Mode is now %s!", THIS_MODE_INFO.tag, THIS_MODE_INFO.isOn ? "On" : "Off"); + + static bool cvarsValues[2]; + + if (THIS_MODE_INFO.isOn) + { + FunModes_HookEvent(g_bEvent_RoundStart, "round_start", Event_RoundStart); + FunModes_HookEvent(g_bEvent_RoundEnd, "round_end", Event_RoundEnd); + FunModes_HookEvent(g_bEvent_PlayerSpawn, "player_spawn", Event_PlayerSpawn); + FunModes_HookEvent(g_bEvent_PlayerDeath, "player_death", Event_PlayerDeath); + + for (int i = 1; i <= MaxClients; i++) + { + if (!IsClientInGame(i)) + continue; + + OnClientPutInServer_GunGame(i); + if (view_as(g_GunGameData[i].reward) < view_as(REWARD_SMOKEGRENADES)) + GunGame_GiveReward(i, REWARD_NONE); + } + + FunModes_RestartRound(); + + ConVar cvar = FindConVar("zr_weapons_zmarket_rebuy"); + if (cvar != null) + { + cvarsValues[0] = cvar.BoolValue; + cvar.BoolValue = false; + delete cvar; + } + + cvar = FindConVar("zr_weapons_zmarket"); + if (cvar != null) + { + cvarsValues[1] = cvar.BoolValue; + cvar.BoolValue = false; + delete cvar; + } + } + else + { + ConVar cvar = FindConVar("zr_weapons_zmarket_rebuy"); + if (cvar != null) + { + cvar.BoolValue = cvarsValues[0]; + delete cvar; + } + + cvar = FindConVar("zr_weapons_zmarket"); + if (cvar != null) + { + cvar.BoolValue = cvarsValues[1]; + delete cvar; + } + } + + return Plugin_Handled; } -/* GunGame Settings */ public Action Cmd_GunGameSettings(int client, int args) { - if (!client) - return Plugin_Handled; - - Menu menu = new Menu(Menu_GunGameSettings); + if (!client) + return Plugin_Handled; + + Menu menu = new Menu(Menu_GunGameSettings); - menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); + menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); + menu.AddItem(NULL_STRING, "Show Cvars\n"); - menu.AddItem(NULL_STRING, "Show Cvars\n"); + menu.ExitBackButton = true; + menu.Display(client, MENU_TIME_FOREVER); - menu.ExitBackButton = true; - menu.Display(client, MENU_TIME_FOREVER); - - return Plugin_Handled; + return Plugin_Handled; } int Menu_GunGameSettings(Menu menu, MenuAction action, int param1, int param2) { - switch (action) - { - case MenuAction_End: - delete menu; - - case MenuAction_Cancel: - { - if (param2 == MenuCancel_ExitBack) - DisplayModeInfo(param1, g_iPreviousModeIndex[param1]); - } - - case MenuAction_Select: - { - ShowCvarsInfo(param1, THIS_MODE_INFO); - } - } - - return 0; + switch (action) + { + case MenuAction_End: + delete menu; + + case MenuAction_Cancel: + { + if (param2 == MenuCancel_ExitBack) + DisplayModeInfo(param1, g_iPreviousModeIndex[param1]); + } + + case MenuAction_Select: + { + ShowCvarsInfo(param1, THIS_MODE_INFO); + } + } + + return 0; } Action Cmd_GunGame(int client, int args) { - if (!client) - return Plugin_Handled; - - if (!THIS_MODE_INFO.isOn) - { - CReplyToCommand(client, "%s GunGame is currently Off!", THIS_MODE_INFO.tag); - return Plugin_Handled; - } - - if (!IsPlayerAlive(client) || !ZR_IsClientHuman(client)) - { - CReplyToCommand(client, "%s You have to be an alive human to use this command!", THIS_MODE_INFO.tag); - return Plugin_Handled; - } - - if (EntWatch_HasSpecialItem(client)) - { - static const char weapons[][] = { "weapon_p90", "weapon_tmp", "weapon_ak47", "weapon_m4a1" }; - GunGame_EquipWeapon(client, weapons[GetRandomInt(0, sizeof(weapons)-1)], true); - return Plugin_Handled; - } - - int weaponType = g_GunGameData[client].level[0]; - int weaponIndex = g_GunGameData[client].level[1]; - if (weaponType > 0) - { - if (GetPlayerWeaponSlot(client, CS_SLOT_SECONDARY) == -1) - GunGame_EquipWeapon(client, g_GunGameWeaponsList[0][0], true); - } - - GunGame_EquipWeapon(client, g_GunGameWeaponsList[weaponType][weaponIndex], true); - - return Plugin_Handled; + if (!client) + return Plugin_Handled; + + if (!THIS_MODE_INFO.isOn) + { + CReplyToCommand(client, "%s GunGame is currently Off!", THIS_MODE_INFO.tag); + return Plugin_Handled; + } + + if (!IsPlayerAlive(client) || !ZR_IsClientHuman(client)) + { + CReplyToCommand(client, "%s You have to be an alive human to use this command!", THIS_MODE_INFO.tag); + return Plugin_Handled; + } + + if (EntWatch_HasSpecialItem(client)) + { + static const char weapons[][] = { "weapon_p90", "weapon_tmp", "weapon_ak47", "weapon_m4a1" }; + GunGame_EquipWeapon(client, weapons[GetRandomInt(0, sizeof(weapons)-1)], true); + return Plugin_Handled; + } + + int weaponType = g_GunGameData[client].level[0]; + int weaponIndex = g_GunGameData[client].level[1]; + if (weaponType > 0) + { + if (GetPlayerWeaponSlot(client, CS_SLOT_SECONDARY) == -1) + GunGame_EquipWeapon(client, g_GunGameWeaponsList[0][0], true); + } + + GunGame_EquipWeapon(client, g_GunGameWeaponsList[weaponType][weaponIndex], true); + + return Plugin_Handled; } void GunGame_GiveWeapon(int client) { - int weaponType = g_GunGameData[client].level[0]; - int weaponIndex = g_GunGameData[client].level[1]; - - /* If weapon type is still pistols */ - if (weaponType == 0) - { - int secondary = GetPlayerWeaponSlot(client, CS_SLOT_SECONDARY); - if (!IsValidEntity(secondary)) - { - GunGame_EquipWeapon(client, g_GunGameWeaponsList[0][0]); - g_GunGameData[client].level[0] = 0; g_GunGameData[client].level[1] = 0; - return; - } - - char weaponName[32]; - GetEntityClassname(secondary, weaponName, sizeof(weaponName)); - - bool hasGlock = !strcmp(weaponName, "weapon_glock"); - - if (hasGlock || strcmp(weaponName, "weapon_usp") == 0) - { - if (weaponIndex == 0) - { - GunGame_EquipWeapon(client, hasGlock ? "weapon_usp" : "weapon_glock"); - g_GunGameData[client].level[1] = 1; - return; - } - } - } - - if (weaponType == sizeof(g_GunGameWeaponsList) - 1) - { - weaponType = 0; - weaponIndex = 0; - - /* Reward player with shits */ - g_GunGameData[client].completedCycle = true; - GunGame_ShowRewardsMenu(client); - } - else if (++weaponIndex >= sizeof(g_GunGameWeaponsList[]) || g_GunGameWeaponsList[weaponType][weaponIndex][0] == '\0') - { - weaponType++; - weaponIndex = 0; - } - - g_GunGameData[client].level[0] = weaponType; - g_GunGameData[client].level[1] = weaponIndex; - - GunGame_EquipWeapon(client, g_GunGameWeaponsList[weaponType][weaponIndex], weaponType > 0); + int weaponType = g_GunGameData[client].level[0]; + int weaponIndex = g_GunGameData[client].level[1]; + + if (weaponType == 0) + { + int secondary = GetPlayerWeaponSlot(client, CS_SLOT_SECONDARY); + if (!IsValidEntity(secondary)) + { + GunGame_EquipWeapon(client, g_GunGameWeaponsList[0][0]); + g_GunGameData[client].level[0] = 0; + g_GunGameData[client].level[1] = 0; + return; + } + + char weaponName[32]; + GetEntityClassname(secondary, weaponName, sizeof(weaponName)); + + bool hasGlock = !strcmp(weaponName, "weapon_glock"); + + if (hasGlock || strcmp(weaponName, "weapon_usp") == 0) + { + if (weaponIndex == 0) + { + GunGame_EquipWeapon(client, hasGlock ? "weapon_usp" : "weapon_glock"); + g_GunGameData[client].level[1] = 1; + return; + } + } + } + + if (weaponType == sizeof(g_GunGameWeaponsList) - 1) + { + weaponType = 0; + weaponIndex = 0; + + g_GunGameData[client].completedCycle = true; + GunGame_ShowRewardsMenu(client); + } + else if (++weaponIndex >= sizeof(g_GunGameWeaponsList[]) || g_GunGameWeaponsList[weaponType][weaponIndex][0] == '\0') + { + weaponType++; + weaponIndex = 0; + } + + g_GunGameData[client].level[0] = weaponType; + g_GunGameData[client].level[1] = weaponIndex; + + GunGame_EquipWeapon(client, g_GunGameWeaponsList[weaponType][weaponIndex], weaponType > 0); } void GunGame_EquipWeapon(int client, const char[] weaponName, bool keepSecondary = false) { + GunGame_StripPlayer(client, keepSecondary); + + g_GunGameData[client].allowEquip = true; + int weapon = GivePlayerItem(client, weaponName); - if (!IsValidEntity(weapon)) - return; - - GunGame_StripPlayer(client, keepSecondary); - - g_GunGameData[client].allowEquip = true; - EquipPlayerWeapon(client, weapon); + if (!IsValidEntity(weapon)) + return; - if (g_hSwitchSDKCall != null) - SDKCall(g_hSwitchSDKCall, client, weapon, 0); + if (g_hSwitchSDKCall != null) + SDKCall(g_hSwitchSDKCall, client, weapon, 0); - g_GunGameData[client].allowEquip = false; + g_GunGameData[client].allowEquip = false; } void GunGame_StripPlayer(int client, bool keepSecondary = false, bool giveSecondary = false) { - for (int i = 0; i <= 5; i++) + int weapon = GetPlayerWeaponSlot(client, CS_SLOT_PRIMARY); + if (weapon != -1) { - if (i != CS_SLOT_SECONDARY && i != CS_SLOT_PRIMARY) - continue; - - if (keepSecondary && i == CS_SLOT_SECONDARY) - continue; - - int wp = GetPlayerWeaponSlot(client, i); - if (!IsValidEntity(wp)) - { - if (i == CS_SLOT_SECONDARY && giveSecondary) - GunGame_EquipWeapon(client, g_GunGameWeaponsList[0][0], true); - - continue; - } - - SDKHooks_DropWeapon(client, wp); - RemoveEntity(wp); + RemovePlayerItem(client, weapon); + RemoveEntity(weapon); + } + + if (keepSecondary) + return; + + weapon = GetPlayerWeaponSlot(client, CS_SLOT_SECONDARY); + if (weapon != -1) + { + RemovePlayerItem(client, weapon); + RemoveEntity(weapon); } + + if (!giveSecondary) + return; + + GunGame_EquipWeapon(client, g_GunGameWeaponsList[0][0], true); } void GunGame_ShowRewardsMenu(int client) { - GunGame_GiveReward(client, REWARD_SPEED); - - Menu menu = new Menu(Menu_GunGame_ShowRewards); - menu.SetTitle("[GunGame Escape] You have completed a gungame cycle! Choose your reward!\nYou only have 60s to switch your rewards"); - - menu.AddItem("0", "More Speed", g_GunGameData[client].reward == REWARD_SPEED ? ITEMDRAW_DISABLED : ITEMDRAW_DEFAULT); - menu.AddItem("2", "Smokegrenades (Freeze)", g_GunGameData[client].reward == REWARD_SMOKEGRENADES ? ITEMDRAW_DISABLED : ITEMDRAW_DEFAULT); - - menu.ExitBackButton = true; - menu.Display(client, 60); + GunGame_GiveReward(client, REWARD_SPEED); + + Menu menu = new Menu(Menu_GunGame_ShowRewards); + menu.SetTitle("[GunGame Escape] You have completed a gungame cycle! Choose your reward!\nYou only have 60s to switch your rewards"); + + menu.AddItem("0", "More Speed", g_GunGameData[client].reward == REWARD_SPEED ? ITEMDRAW_DISABLED : ITEMDRAW_DEFAULT); + menu.AddItem("1", "Smokegrenades (Freeze)", g_GunGameData[client].reward == REWARD_SMOKEGRENADES ? ITEMDRAW_DISABLED : ITEMDRAW_DEFAULT); + + menu.ExitBackButton = true; + menu.Display(client, 60); } int Menu_GunGame_ShowRewards(Menu menu, MenuAction action, int param1, int param2) { - switch (action) - { - case MenuAction_End: - delete menu; - - case MenuAction_Select: - { - if (!g_GunGameData[param1].completedCycle) - { - CPrintToChat(param1, "%s You cannot pick a reward right now, Sorry :p", THIS_MODE_INFO.tag); - return 0; - } - - char data[3]; - menu.GetItem(param2, data, sizeof(data)); - - GunGame_Reward reward = view_as(StringToInt(data)); - GunGame_GiveReward(param1, reward); - } - } - - return 0; + switch (action) + { + case MenuAction_End: + delete menu; + + case MenuAction_Select: + { + if (!g_GunGameData[param1].completedCycle) + { + CPrintToChat(param1, "%s You cannot pick a reward right now, Sorry :p", THIS_MODE_INFO.tag); + return 0; + } + + char data[3]; + menu.GetItem(param2, data, sizeof(data)); + + GunGame_Reward reward = view_as(StringToInt(data)); + GunGame_GiveReward(param1, reward); + } + } + + return 0; } void GunGame_GiveReward(int client, GunGame_Reward reward) { - g_GunGameData[client].reward = reward; - - /* Delete Timer */ - delete g_GunGameData[client].rewardTimer; - - switch (reward) - { - case REWARD_SPEED: - { - if (!IsPlayerAlive(client) || !ZR_IsClientHuman(client)) - return; - - g_GunGameData[client].originalSpeed = GetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue"); - SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", g_GunGameData[client].originalSpeed + 0.3); - - CPrintToChat(client, "%s You have been granted an extra speed for finishing a gungame cycle!", THIS_MODE_INFO.tag); - - delete g_GunGameData[client].rewardTimer; - g_GunGameData[client].rewardTimer = CreateTimer(THIS_MODE_INFO.cvarInfo[GUNGAME_CONVAR_REWARD_SPEED].cvar.FloatValue, Timer_GunGameReward, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE); - } - - case REWARD_SMOKEGRENADES: - { - /* Reset Speed */ - if (g_GunGameData[client].originalSpeed != 0.0) - { - SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", g_GunGameData[client].originalSpeed); - g_GunGameData[client].originalSpeed = 0.0; - } - - if (!IsPlayerAlive(client) || !ZR_IsClientHuman(client)) - return; - - int smoke = GivePlayerItem(client, "weapon_smokegrenade"); - EquipPlayerWeapon(client, smoke); - int count = THIS_MODE_INFO.cvarInfo[GUNGAME_CONVAR_SMOKEGRENADES_COUNT].cvar.IntValue; - SET_GRENADES_COUNT(client, SMOKEGRENADE, GET_GRENADES_COUNT(client, SMOKEGRENADE)+count-1); - - CPrintToChat(client, "%s You have been granted {olive}%d extra SMOKEGRENADES {lightgreen}for finishing a gungame cycle!", THIS_MODE_INFO.tag, count); - } - - default: - { - /* Reset Speed */ - if (g_GunGameData[client].originalSpeed != 0.0) + g_GunGameData[client].reward = reward; + + delete g_GunGameData[client].rewardTimer; + + switch (reward) + { + case REWARD_SPEED: + { + if (!IsPlayerAlive(client) || !ZR_IsClientHuman(client)) + return; + + g_GunGameData[client].originalSpeed = GetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue"); + SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", g_GunGameData[client].originalSpeed + 0.3); + + CPrintToChat(client, "%s You have been granted an extra speed for finishing a gungame cycle!", THIS_MODE_INFO.tag); + + delete g_GunGameData[client].rewardTimer; + g_GunGameData[client].rewardTimer = CreateTimer(g_fGunGame_RewardSpeed, Timer_GunGameReward, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE); + } + + case REWARD_SMOKEGRENADES: + { + if (g_GunGameData[client].originalSpeed != 0.0) + { + SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", g_GunGameData[client].originalSpeed); + g_GunGameData[client].originalSpeed = 0.0; + } + + if (!IsPlayerAlive(client) || !ZR_IsClientHuman(client)) + return; + + if (!HasPlayerItem(client, "weapon_smokegrenade")) { - SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", g_GunGameData[client].originalSpeed); - g_GunGameData[client].originalSpeed = 0.0; - } - } - } + int wp = GivePlayerItem(client, "weapon_smokegrenade"); + EquipPlayerWeapon(client, wp); + } + + int count = g_iGunGame_SmokeGrenadesCount; + SET_GRENADES_COUNT(client, SMOKEGRENADE, GET_GRENADES_COUNT(client, SMOKEGRENADE) + count); + + CPrintToChat(client, "%s You have been granted {olive}%d extra SMOKEGRENADES {lightgreen}for finishing a gungame cycle!", THIS_MODE_INFO.tag, count); + } + + default: + { + if (g_GunGameData[client].originalSpeed != 0.0) + { + SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", g_GunGameData[client].originalSpeed); + g_GunGameData[client].originalSpeed = 0.0; + } + } + } } Action Timer_GunGameReward(Handle timer, int userid) { - int client = GetClientOfUserId(userid); - if (!client) - return Plugin_Stop; - - g_GunGameData[client].rewardTimer = null; - - CPrintToChat(client, "%s Sorry, your reward has ended!", THIS_MODE_INFO.tag); - GunGame_GiveReward(client, REWARD_NONE); - return Plugin_Stop; + int client = GetClientOfUserId(userid); + if (!client) + return Plugin_Stop; + + g_GunGameData[client].rewardTimer = null; + + CPrintToChat(client, "%s Sorry, your reward has ended!", THIS_MODE_INFO.tag); + GunGame_GiveReward(client, REWARD_NONE); + return Plugin_Stop; } diff --git a/addons/sourcemod/scripting/Fun_Modes/HealBeacon.sp b/addons/sourcemod/scripting/Fun_Modes/HealBeacon.sp index a7c6abc..38ac04e 100644 --- a/addons/sourcemod/scripting/Fun_Modes/HealBeacon.sp +++ b/addons/sourcemod/scripting/Fun_Modes/HealBeacon.sp @@ -1,6 +1,6 @@ /* (). FunModes V2: - + @file HealBeacon.sp @Usage Functions for the HealBeacon mode. */ @@ -8,10 +8,15 @@ #pragma semicolon 1 #pragma newdecls required -ModeInfo g_HBInfo; +// This must be static (To avoid confusion between other modes), +// but since HealBeacon requires a menus include file, we can make it as instance. +int g_iHealBeaconIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iHealBeaconIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_HBInfo +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] bool g_bIsBetterDamageModeOn; @@ -24,45 +29,55 @@ Handle g_hDamageTimer = null; Handle g_hHealTimer = null; Handle g_hBeaconTimer[MAXPLAYERS + 1] = { null, ... }; -#define HB_CONVAR_BEACON_TIMER 0 -#define HB_CONVAR_ALERT_TIMER 1 -#define HB_CONVAR_BEACON_DAMAGE 2 -#define HB_CONVAR_BEACON_HEAL 3 -#define HB_CONVAR_RANDOMS 4 -#define HB_CONVAR_DEFAULT_DISTANCE 5 -#define HB_CONVAR_TOGGLE 6 +#define HB_CONVAR_BEACON_TIMER 0 +#define HB_CONVAR_ALERT_TIMER 1 +#define HB_CONVAR_BEACON_DAMAGE 2 +#define HB_CONVAR_BEACON_HEAL 3 +#define HB_CONVAR_RANDOMS 4 +#define HB_CONVAR_DEFAULT_DISTANCE 5 +#define HB_CONVAR_TOGGLE 6 + +float g_fHB_BeaconTimer; +float g_fHB_AlertTimer; +float g_fHB_BeaconDamage; +float g_fHB_DefaultDistance; + +int g_iHB_BeaconHeal; +int g_iHB_RandomPlayers; + +bool g_bHealBeacon_Enabled; enum struct BeaconPlayers { - bool hasHealBeacon; - bool hasNeon; - int color[4]; - float distance; - int neonEntity; - - void SetColor(int setColor[4]) - { - this.color[0] = setColor[0]; - this.color[1] = setColor[1]; - this.color[2] = setColor[2]; - this.color[3] = setColor[3]; - } - - void ResetColor() - { - this.color[0] = g_ColorDefault[0]; - this.color[1] = g_ColorDefault[1]; - this.color[2] = g_ColorDefault[2]; - this.color[3] = g_ColorDefault[3]; - } - - void ResetValues() - { - this.hasHealBeacon = false; - this.ResetColor(); - this.distance = THIS_MODE_INFO.cvarInfo[HB_CONVAR_DEFAULT_DISTANCE].cvar.FloatValue; - this.neonEntity = -1; - } + bool hasHealBeacon; + bool hasNeon; + int color[4]; + float distance; + int neonEntity; + + void SetColor(int setColor[4]) + { + this.color[0] = setColor[0]; + this.color[1] = setColor[1]; + this.color[2] = setColor[2]; + this.color[3] = setColor[3]; + } + + void ResetColor() + { + this.color[0] = g_ColorDefault[0]; + this.color[1] = g_ColorDefault[1]; + this.color[2] = g_ColorDefault[2]; + this.color[3] = g_ColorDefault[3]; + } + + void ResetValues() + { + this.hasHealBeacon = false; + this.ResetColor(); + this.distance = g_fHB_DefaultDistance; + this.neonEntity = -1; + } } BeaconPlayers g_BeaconPlayersData[MAXPLAYERS + 1]; @@ -70,592 +85,591 @@ BeaconPlayers g_BeaconPlayersData[MAXPLAYERS + 1]; /* Called in OnPluginStart */ stock void OnPluginStart_HealBeacon() { - THIS_MODE_INFO.name = "HealBeacon"; - THIS_MODE_INFO.tag = "{gold}[FunModes-HealBeacon]{lightgreen}"; - - /* ADMIN COMMANDS */ - RegAdminCmd("sm_fm_healbeacon", Cmd_HealBeaconToggle, ADMFLAG_CONVARS, "Enable/Disable Healbeacon"); - RegAdminCmd("sm_healbeacon", Cmd_HealBeaconSettings, ADMFLAG_CONVARS, "Shows healbeacon menu"); - RegAdminCmd("sm_beacon_distance", Cmd_HealBeaconDistance, ADMFLAG_CONVARS, "Change beacon distance"); - RegAdminCmd("sm_replacebeacon", Cmd_HealBeaconReplace, ADMFLAG_BAN, "Replace an already heal beaconed player with another one"); - RegAdminCmd("sm_addnewbeacon", Cmd_HealBeaconAddNew, ADMFLAG_BAN, "Add a new heal beaconed player"); - RegAdminCmd("sm_removebeacon", Cmd_HealBeaconRemove, ADMFLAG_BAN, "Remove heal beacon player"); - RegConsoleCmd("sm_checkdistance", Cmd_HealBeaconCheckDistance, "..."); - - /* CONVARS */ - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, HB_CONVAR_BEACON_TIMER, - "sm_beacon_timer", "20.0", "The time that will start picking random players at round start", - ("20.0,30.0,40.0,60.0"), "float" - ); - - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, HB_CONVAR_ALERT_TIMER, - "sm_beacon_alert_timer", "10.0", "How much time in seconds the damage will start being applied from heal beacon as an alert for the other humans", - ("5.0,8.0,10.0,15.0"), "float" - ); - - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, HB_CONVAR_BEACON_DAMAGE, - "sm_beacon_damage", "5.0", "The damage that the heal beacon will give", - ("2.0,5.0,8.0,10.0,15.0"), "float" - ); - - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, HB_CONVAR_BEACON_HEAL, - "sm_beacon_heal", "1", "How much heal beacon should heal the players in 1 second", - ("1,2,3,4,5,10"), "int" - ); - - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, HB_CONVAR_RANDOMS, - "sm_healbeacon_randoms", "2", "How many random players should get the heal beacon", - ("1,2,3,4,5,10"), "int" - ); - - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, HB_CONVAR_DEFAULT_DISTANCE, - "sm_healbeacon_distance", "400.0", "Default distance of beacon to give", - ("100.0,200.0,400.0,500.0"), "float" - ); - - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, HB_CONVAR_TOGGLE, - "sm_healbeacon_enable", "1", "Enable/Disable HealBeacon mode.", - ("0,1"), "bool" - ); - - THIS_MODE_INFO.enableIndex = HB_CONVAR_TOGGLE; - - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; - - THIS_MODE_INFO.cvarInfo[HB_CONVAR_TOGGLE].cvar.AddChangeHook(OnHBModeToggle); -} - -void OnHBModeToggle(ConVar cvar, const char[] newValue, const char[] oldValue) -{ - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + + THIS_MODE_INFO.name = "HealBeacon"; + THIS_MODE_INFO.tag = "{gold}[FunModes-HealBeacon]{lightgreen}"; + + /* ADMIN COMMANDS */ + RegAdminCmd("sm_fm_healbeacon", Cmd_HealBeaconToggle, ADMFLAG_CONVARS, "Enable/Disable Healbeacon"); + RegAdminCmd("sm_healbeacon", Cmd_HealBeaconSettings, ADMFLAG_CONVARS, "Shows healbeacon menu"); + RegAdminCmd("sm_beacon_distance", Cmd_HealBeaconDistance, ADMFLAG_CONVARS, "Change beacon distance"); + RegAdminCmd("sm_replacebeacon", Cmd_HealBeaconReplace, ADMFLAG_BAN, "Replace an already heal beaconed player with another one"); + RegAdminCmd("sm_addnewbeacon", Cmd_HealBeaconAddNew, ADMFLAG_BAN, "Add a new heal beaconed player"); + RegAdminCmd("sm_removebeacon", Cmd_HealBeaconRemove, ADMFLAG_BAN, "Remove heal beacon player"); + RegConsoleCmd("sm_checkdistance", Cmd_HealBeaconCheckDistance, "..."); + + /* CONVARS */ + DECLARE_FM_CVAR( + HB_CONVAR_BEACON_TIMER, "sm_beacon_timer", + "20.0", "The time that will start picking random players at round start", + ("20.0,30.0,40.0,60.0"), CONVAR_FLOAT + ); + THIS_MODE_INFO.cvars[HB_CONVAR_BEACON_TIMER].HookChange(HealBeacon_OnConVarChange); + + DECLARE_FM_CVAR( + HB_CONVAR_ALERT_TIMER, "sm_beacon_alert_timer", + "10.0", "How much time in seconds the damage will start being applied from heal beacon as an alert for the other humans", + ("5.0,8.0,10.0,15.0"), CONVAR_FLOAT + ); + THIS_MODE_INFO.cvars[HB_CONVAR_ALERT_TIMER].HookChange(HealBeacon_OnConVarChange); + + DECLARE_FM_CVAR( + HB_CONVAR_BEACON_DAMAGE, "sm_beacon_damage", + "5.0", "The damage that the heal beacon will give", + ("2.0,5.0,8.0,10.0,15.0"), CONVAR_FLOAT + ); + THIS_MODE_INFO.cvars[HB_CONVAR_BEACON_DAMAGE].HookChange(HealBeacon_OnConVarChange); + + DECLARE_FM_CVAR( + HB_CONVAR_BEACON_HEAL, "sm_beacon_heal", + "1", "How much heal beacon should heal the players in 1 second", + ("1,2,3,4,5,10"), CONVAR_INT + ); + THIS_MODE_INFO.cvars[HB_CONVAR_BEACON_HEAL].HookChange(HealBeacon_OnConVarChange); + + DECLARE_FM_CVAR( + HB_CONVAR_RANDOMS, "sm_healbeacon_randoms", + "2", "How many random players should get the heal beacon", + ("1,2,3,4,5,10"), CONVAR_INT + ); + THIS_MODE_INFO.cvars[HB_CONVAR_RANDOMS].HookChange(HealBeacon_OnConVarChange); + + DECLARE_FM_CVAR( + HB_CONVAR_DEFAULT_DISTANCE, "sm_healbeacon_distance", + "400.0", "Default distance of beacon to give", + ("100.0,200.0,400.0,500.0"), CONVAR_FLOAT + ); + THIS_MODE_INFO.cvars[HB_CONVAR_DEFAULT_DISTANCE].HookChange(HealBeacon_OnConVarChange); + + DECLARE_FM_CVAR( + HB_CONVAR_TOGGLE, "sm_healbeacon_enable", + "1", "Enable/Disable HealBeacon mode.", + ("0,1"), CONVAR_BOOL + ); + THIS_MODE_INFO.cvars[HB_CONVAR_TOGGLE].HookChange(HealBeacon_OnConVarChange); + + THIS_MODE_INFO.enableIndex = HB_CONVAR_TOGGLE; +} + +void InitCvarsValues_HealBeacon() +{ + int modeIndex = THIS_MODE_INFO.index; + + g_fHB_BeaconTimer = _FUNMODES_CVAR_GET_VALUE(modeIndex, HB_CONVAR_BEACON_TIMER, Float); + g_fHB_AlertTimer = _FUNMODES_CVAR_GET_VALUE(modeIndex, HB_CONVAR_ALERT_TIMER, Float); + g_fHB_BeaconDamage = _FUNMODES_CVAR_GET_VALUE(modeIndex, HB_CONVAR_BEACON_DAMAGE, Float); + g_iHB_BeaconHeal = _FUNMODES_CVAR_GET_VALUE(modeIndex, HB_CONVAR_BEACON_HEAL, Int); + g_iHB_RandomPlayers = _FUNMODES_CVAR_GET_VALUE(modeIndex, HB_CONVAR_RANDOMS, Int); + g_fHB_DefaultDistance = _FUNMODES_CVAR_GET_VALUE(modeIndex, HB_CONVAR_DEFAULT_DISTANCE, Float); + + g_bHealBeacon_Enabled = _FUNMODES_CVAR_GET_VALUE(modeIndex, HB_CONVAR_TOGGLE, Bool); +} + +void HealBeacon_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) +{ + switch (cvarIndex) + { + case HB_CONVAR_BEACON_TIMER: + g_fHB_BeaconTimer = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case HB_CONVAR_ALERT_TIMER: + g_fHB_AlertTimer = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case HB_CONVAR_BEACON_DAMAGE: + g_fHB_BeaconDamage = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case HB_CONVAR_BEACON_HEAL: + g_iHB_BeaconHeal = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + case HB_CONVAR_RANDOMS: + g_iHB_RandomPlayers = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + case HB_CONVAR_DEFAULT_DISTANCE: + g_fHB_DefaultDistance = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case HB_CONVAR_TOGGLE: + { + bool val = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bHealBeacon_Enabled = val; + } + } } stock void OnMapStart_HealBeacon() {} + stock void OnMapEnd_HealBeacon() { - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, false, THIS_MODE_INFO.index); + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, false, THIS_MODE_INFO.index); - for (int i = 1; i <= MaxClients; i++) - { - g_hBeaconTimer[i] = null; - } - g_hRoundStart_Timer[0] = null; - g_hRoundStart_Timer[1] = null; - g_hDamageTimer = null; - g_hHealTimer = null; + for (int i = 1; i <= MaxClients; i++) + g_hBeaconTimer[i] = null; + + g_hRoundStart_Timer[0] = null; + g_hRoundStart_Timer[1] = null; + g_hDamageTimer = null; + g_hHealTimer = null; } stock void OnClientPutInServer_HealBeacon(int client) { - #pragma unused client + #pragma unused client } stock void OnClientDisconnect_HealBeacon(int client) { - if (!THIS_MODE_INFO.isOn) - return; - - if (!g_BeaconPlayersData[client].hasHealBeacon) - { - delete g_hBeaconTimer[client]; - g_BeaconPlayersData[client].ResetValues(); - return; - } + if (!THIS_MODE_INFO.isOn) + return; + + if (!g_BeaconPlayersData[client].hasHealBeacon) + { + delete g_hBeaconTimer[client]; + g_BeaconPlayersData[client].ResetValues(); + return; + } - RemoveBeacon(-1, client); - CPrintToChatAll("%s {olive}%N {lightgreen}disconnected with HealBeacon.", THIS_MODE_INFO.tag, client); + RemoveBeacon(-1, client); + CPrintToChatAll("%s {olive}%N {lightgreen}disconnected with HealBeacon.", THIS_MODE_INFO.tag, client); } stock void ZR_OnClientInfected_HealBeacon(int client) { - #pragma unused client + #pragma unused client } stock void Event_RoundStart_HealBeacon() { - /* DELETE TIMER HANDLES SO WE DONT GET ERRORS */ - HealBeacon_DeleteAllTimers(); + HealBeacon_DeleteAllTimers(); - /* CHECK IF ARRAYLIST IS NOT NULL AND THEN ERASE ALL CLIENTS INDEXES IN ARRAYLIST */ - if (g_aHBPlayers == null) - return; + if (g_aHBPlayers == null) + return; - g_aHBPlayers.Clear(); + g_aHBPlayers.Clear(); - if (!THIS_MODE_INFO.isOn) - return; + if (!THIS_MODE_INFO.isOn) + return; - /* RESET COUNTER */ - g_iCounter = 0; + g_iCounter = 0; - /* LETS CREATE THE FIRST ROUND START TIMER */ - g_hRoundStart_Timer[0] = CreateTimer(THIS_MODE_INFO.cvarInfo[HB_CONVAR_BEACON_TIMER].cvar.FloatValue, RoundStart_Timer, _, TIMER_FLAG_NO_MAPCHANGE); + g_hRoundStart_Timer[0] = CreateTimer(g_fHB_BeaconTimer, RoundStart_Timer, _, TIMER_FLAG_NO_MAPCHANGE); } stock void Event_RoundEnd_HealBeacon() {} + stock void Event_PlayerSpawn_HealBeacon(int client) { - #pragma unused client + #pragma unused client } stock void Event_PlayerDeath_HealBeacon(int client) { - if (!THIS_MODE_INFO.isOn || !g_BeaconPlayersData[client].hasHealBeacon) - return; + if (!THIS_MODE_INFO.isOn || !g_BeaconPlayersData[client].hasHealBeacon) + return; - RemoveBeacon(-1, client); - CPrintToChatAll("%s {olive}%N {lightgreen}died with HealBeacon.", THIS_MODE_INFO.tag, client); + RemoveBeacon(-1, client); + CPrintToChatAll("%s {olive}%N {lightgreen}died with HealBeacon.", THIS_MODE_INFO.tag, client); } stock void Event_PlayerTeam_HealBeacon(Event event) { - if (!THIS_MODE_INFO.isOn) - return; - - int client = GetClientOfUserId(event.GetInt("userid")); - if (!client || !g_BeaconPlayersData[client].hasHealBeacon) - return; + if (!THIS_MODE_INFO.isOn) + return; + + int client = GetClientOfUserId(event.GetInt("userid")); + if (!client || !g_BeaconPlayersData[client].hasHealBeacon) + return; - int team = event.GetInt("team"); - if (team == CS_TEAM_SPECTATOR || team == CS_TEAM_NONE) - { - RemoveBeacon(-1, client); - CPrintToChatAll("%s {olive}%N {lightgreen}moved to spectator team with HealBeacon.", THIS_MODE_INFO.tag, client); - } + int team = event.GetInt("team"); + if (team == CS_TEAM_SPECTATOR || team == CS_TEAM_NONE) + { + RemoveBeacon(-1, client); + CPrintToChatAll("%s {olive}%N {lightgreen}moved to spectator team with HealBeacon.", THIS_MODE_INFO.tag, client); + } } Action RoundStart_Timer(Handle timer) { - g_hRoundStart_Timer[0] = null; - - if (!THIS_MODE_INFO.isOn) - return Plugin_Stop; - - /* Let's now pick the random players */ - for (int i = 0; i < THIS_MODE_INFO.cvarInfo[HB_CONVAR_RANDOMS].cvar.IntValue; i++) - { - GetRandomPlayer(); - } + g_hRoundStart_Timer[0] = null; + + if (!THIS_MODE_INFO.isOn) + return Plugin_Stop; + + for (int i = 0; i < g_iHB_RandomPlayers; i++) + GetRandomPlayer(); - /* Delete the previous timer handler if found so we dont assign a new CreateTimer over the old one */ - delete g_hRoundStart_Timer[1]; - g_hRoundStart_Timer[1] = CreateTimer(1.0, RoundStart_CountTimer, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); - return Plugin_Stop; + delete g_hRoundStart_Timer[1]; + g_hRoundStart_Timer[1] = CreateTimer(1.0, RoundStart_CountTimer, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); + return Plugin_Stop; } Action RoundStart_CountTimer(Handle timer) { - if (!THIS_MODE_INFO.isOn) - { - g_hRoundStart_Timer[1] = null; - return Plugin_Stop; - } - - int alertTime = THIS_MODE_INFO.cvarInfo[HB_CONVAR_ALERT_TIMER].cvar.IntValue; + if (!THIS_MODE_INFO.isOn) + { + g_hRoundStart_Timer[1] = null; + return Plugin_Stop; + } - if (g_iCounter >= alertTime) - { - HealBeacon_Setup(); - g_hRoundStart_Timer[1] = null; - return Plugin_Stop; - } + int alertTime = RoundToNearest(g_fHB_AlertTimer); - /* Lets send the hud message to all clients */ - for (int i = 1; i <= MaxClients; i++) - { - if (!IsClientInGame(i)) - continue; + if (g_iCounter >= alertTime) + { + HealBeacon_Setup(); + g_hRoundStart_Timer[1] = null; + return Plugin_Stop; + } - char message[256]; - FormatEx(message, sizeof(message), "%T", "HealBeacon_Alert", i, (alertTime - g_iCounter)); - SendHudText(i, message); - } + for (int i = 1; i <= MaxClients; i++) + { + if (!IsClientInGame(i)) + continue; - g_iCounter++; - return Plugin_Continue; + char message[256]; + FormatEx(message, sizeof(message), "%T", "HealBeacon_Alert", i, (alertTime - g_iCounter)); + SendHudText(i, message); + } + + g_iCounter++; + return Plugin_Continue; } stock void GetRandomPlayer() { - int clientsCount[MAXPLAYERS + 1]; - int humansCount; + int clientsCount[MAXPLAYERS + 1]; + int humansCount; - for (int i = 1; i <= MaxClients; i++) - { - if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) - continue; + for (int i = 1; i <= MaxClients; i++) + { + if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) + continue; - /* if client is already heal beaconed then dont include them in */ - if (g_BeaconPlayersData[i].hasHealBeacon) - continue; + if (g_BeaconPlayersData[i].hasHealBeacon) + continue; - clientsCount[humansCount++] = i; - } + clientsCount[humansCount++] = i; + } - if (humansCount <= 0 || humansCount < THIS_MODE_INFO.cvarInfo[HB_CONVAR_RANDOMS].cvar.IntValue) - return; + if (humansCount <= 0 || humansCount < g_iHB_RandomPlayers) + return; - int random = clientsCount[GetRandomInt(0, (humansCount - 1))]; - if (random < 1) - return; + int random = clientsCount[GetRandomInt(0, (humansCount - 1))]; + if (random < 1) + return; - /* Lets now apply healbeacon to the choosen one */ - SetHealBeaconToClient(random); - CPrintToChatAll("%s %T", THIS_MODE_INFO.tag, "HealBeacon_AddAnnounce", random, random); + SetHealBeaconToClient(random); + CPrintToChatAll("%s %T", THIS_MODE_INFO.tag, "HealBeacon_AddAnnounce", random, random); } stock void SetHealBeaconToClient(int client) { - /* Lets save the healbeacon player data they are needed */ - g_BeaconPlayersData[client].hasHealBeacon = true; - g_BeaconPlayersData[client].distance = THIS_MODE_INFO.cvarInfo[HB_CONVAR_DEFAULT_DISTANCE].cvar.FloatValue; - g_BeaconPlayersData[client].ResetColor(); + g_BeaconPlayersData[client].hasHealBeacon = true; + g_BeaconPlayersData[client].distance = g_fHB_DefaultDistance; + g_BeaconPlayersData[client].ResetColor(); - /* BEACON THE PLAYER */ - delete g_hBeaconTimer[client]; - g_hBeaconTimer[client] = CreateTimer(0.1, HealBeacon_BeaconTimer, GetClientUserId(client), TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); + delete g_hBeaconTimer[client]; + g_hBeaconTimer[client] = CreateTimer(0.1, HealBeacon_BeaconTimer, GetClientUserId(client), TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); - /* Lets now push client indexes to the arraylist */ - g_aHBPlayers.Push(client); + g_aHBPlayers.Push(client); } stock void HealBeacon_Setup() { - /* Lets create the damage timer and delete the handle first so we dont get problems */ - delete g_hDamageTimer; - g_hDamageTimer = CreateTimer(0.7, HealBeacon_DamageTimer, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); + delete g_hDamageTimer; + g_hDamageTimer = CreateTimer(0.7, HealBeacon_DamageTimer, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); - /* Lets create the heal timer and delete the handle first so we dont get problems */ - delete g_hHealTimer; - g_hHealTimer = CreateTimer(1.0, HealBeacon_HealTimer, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); + delete g_hHealTimer; + g_hHealTimer = CreateTimer(1.0, HealBeacon_HealTimer, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); } Action HealBeacon_BeaconTimer(Handle timer, int userid) { - int client = GetClientOfUserId(userid); - if (!client) - { - return Plugin_Stop; - } - - if (!THIS_MODE_INFO.isOn) - { - g_hBeaconTimer[client] = null; - return Plugin_Stop; - } - - if (!IsPlayerAlive(client) || GetClientTeam(client) != CS_TEAM_CT || !g_BeaconPlayersData[client].hasHealBeacon) - { - g_hBeaconTimer[client] = null; - return Plugin_Stop; - } - - BeaconPlayer(client, 0, g_BeaconPlayersData[client].distance, g_BeaconPlayersData[client].color); - return Plugin_Continue; + int client = GetClientOfUserId(userid); + if (!client) + return Plugin_Stop; + + if (!THIS_MODE_INFO.isOn) + { + g_hBeaconTimer[client] = null; + return Plugin_Stop; + } + + if (!IsPlayerAlive(client) || GetClientTeam(client) != CS_TEAM_CT || !g_BeaconPlayersData[client].hasHealBeacon) + { + g_hBeaconTimer[client] = null; + return Plugin_Stop; + } + + BeaconPlayer(client, 0, g_BeaconPlayersData[client].distance, g_BeaconPlayersData[client].color); + return Plugin_Continue; } Action HealBeacon_DamageTimer(Handle timer) { - if (!THIS_MODE_INFO.isOn) - { - g_hDamageTimer = null; - return Plugin_Stop; - } - - /* if round is ending */ - if (g_bRoundEnd) - return Plugin_Handled; - - /* if all healbeacon players died */ - if (g_aHBPlayers.Length == 0) - { - for (int i = 1; i <= MaxClients; i++) - { - if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) - continue; - - SDKHooks_TakeDamage(i, 0, 0, THIS_MODE_INFO.cvarInfo[HB_CONVAR_BEACON_DAMAGE].cvar.FloatValue); - } - - return Plugin_Handled; - } - - for (int i = 1; i <= MaxClients; i++) - { - if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) - continue; - - /* if client is healbeaconed then continue the loop and ignore that client */ - if (g_BeaconPlayersData[i].hasHealBeacon) - continue; - - HealBeacon_DealDamage(i); - } - - return Plugin_Continue; + if (!THIS_MODE_INFO.isOn) + { + g_hDamageTimer = null; + return Plugin_Stop; + } + + if (g_bRoundEnd) + return Plugin_Handled; + + if (g_aHBPlayers.Length == 0) + { + for (int i = 1; i <= MaxClients; i++) + { + if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) + continue; + + SDKHooks_TakeDamage(i, 0, 0, g_fHB_BeaconDamage); + } + + return Plugin_Handled; + } + + for (int i = 1; i <= MaxClients; i++) + { + if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) + continue; + + if (g_BeaconPlayersData[i].hasHealBeacon) + continue; + + HealBeacon_DealDamage(i); + } + + return Plugin_Continue; } stock void HealBeacon_DealDamage(int client) { - bool isFar = false; - - for (int i = 0; i < g_aHBPlayers.Length; i++) - { - int random = g_aHBPlayers.Get(i); - - // squarred distance, better for performance - float distance = GetDistanceBetween(random, client, true); - - /* if player is not far from any heal beacon player then we need to stop the loop */ - float beaconRadiusHalf = g_BeaconPlayersData[random].distance / 2.0; - if (distance < (beaconRadiusHalf * beaconRadiusHalf)) - { - isFar = false; - break; - } - - /* else */ - isFar = true; - } - - /* if player is far then do damage and warn them */ - if (isFar) - { - SDKHooks_TakeDamage(client, 0, 0, THIS_MODE_INFO.cvarInfo[HB_CONVAR_BEACON_DAMAGE].cvar.FloatValue); - char sMessage[256]; - FormatEx(sMessage, sizeof(sMessage), "%T", "HealBeacon_Damage", client); - SendHudText(client, sMessage, true); - } + bool isFar = false; + + for (int i = 0; i < g_aHBPlayers.Length; i++) + { + int random = g_aHBPlayers.Get(i); + + float distance = GetDistanceBetween(random, client, true); + + float beaconRadiusHalf = g_BeaconPlayersData[random].distance / 2.0; + if (distance < (beaconRadiusHalf * beaconRadiusHalf)) + { + isFar = false; + break; + } + + isFar = true; + } + + if (isFar) + { + SDKHooks_TakeDamage(client, 0, 0, g_fHB_BeaconDamage); + + char sMessage[256]; + FormatEx(sMessage, sizeof(sMessage), "%T", "HealBeacon_Damage", client); + SendHudText(client, sMessage, true); + } } Action HealBeacon_HealTimer(Handle timer) { - if (!THIS_MODE_INFO.isOn) - { - g_hHealTimer = null; - return Plugin_Stop; - } - - /* IF BETTER DAMAGE MODE IS ON THEN stop the timer for a while until its off */ - /* BETTER DAMAGE mode means that the players will get hurt but they wont get heal */ - if (g_bIsBetterDamageModeOn) - return Plugin_Handled; + if (!THIS_MODE_INFO.isOn) + { + g_hHealTimer = null; + return Plugin_Stop; + } + + if (g_bIsBetterDamageModeOn) + return Plugin_Handled; - for (int i = 1; i <= MaxClients; i++) - { - if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) - continue; + for (int i = 1; i <= MaxClients; i++) + { + if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) + continue; - HealBeacon_DealHeal(i); - } + HealBeacon_DealHeal(i); + } - return Plugin_Continue; + return Plugin_Continue; } stock void HealBeacon_DealHeal(int client) { - /* if client has healbeacon then give heal to them */ - if (g_BeaconPlayersData[client].hasHealBeacon) - { - int health = GetEntProp(client, Prop_Send, "m_iHealth"); - int maxHealth = GetEntProp(client, Prop_Data, "m_iMaxHealth"); - - /* WE SHOULD ALWAYS CHECK IF MAXHEALTH IS MORE THAN PLAYERS HEALTH summing with the extra health */ - if ((health) < maxHealth) - { - int newHealth = (health + THIS_MODE_INFO.cvarInfo[HB_CONVAR_BEACON_HEAL].cvar.IntValue); - - if (newHealth == maxHealth) - newHealth = maxHealth; - else if (newHealth > maxHealth) - newHealth = (health + 1); - - SetEntProp(client, Prop_Data, "m_iHealth", newHealth); - } - - return; - } - - for (int i = 0; i < g_aHBPlayers.Length; i++) - { - int random = g_aHBPlayers.Get(i); - float distance = GetDistanceBetween(random, client); - - /* if distance between both of them is less than or equal the healbeacon distance */ - if (distance <= (g_BeaconPlayersData[random].distance / 2.0)) - { - int health = GetEntProp(client, Prop_Send, "m_iHealth"); - int maxHealth = GetEntProp(client, Prop_Data, "m_iMaxHealth"); - - /* WE SHOULD ALWAYS CHECK IF MAXHEALTH IS MORE THAN PLAYERS HEALTH summing with the extra health */ - if ((health) < maxHealth) - { - int newHealth = (health + THIS_MODE_INFO.cvarInfo[HB_CONVAR_BEACON_HEAL].cvar.IntValue); - - if (newHealth == maxHealth) - newHealth = maxHealth; - else if (newHealth > maxHealth) - newHealth = (health + 1); - - SetEntProp(client, Prop_Data, "m_iHealth", newHealth); - } - - break; - } - } + if (g_BeaconPlayersData[client].hasHealBeacon) + { + int health = GetEntProp(client, Prop_Send, "m_iHealth"); + int maxHealth = GetEntProp(client, Prop_Data, "m_iMaxHealth"); + + if (health < maxHealth) + { + int newHealth = health + g_iHB_BeaconHeal; + + if (newHealth == maxHealth) + newHealth = maxHealth; + else if (newHealth > maxHealth) + newHealth = health + 1; + + SetEntProp(client, Prop_Data, "m_iHealth", newHealth); + } + + return; + } + + for (int i = 0; i < g_aHBPlayers.Length; i++) + { + int random = g_aHBPlayers.Get(i); + float distance = GetDistanceBetween(random, client); + + if (distance <= (g_BeaconPlayersData[random].distance / 2.0)) + { + int health = GetEntProp(client, Prop_Send, "m_iHealth"); + int maxHealth = GetEntProp(client, Prop_Data, "m_iMaxHealth"); + + if (health < maxHealth) + { + int newHealth = health + g_iHB_BeaconHeal; + + if (newHealth == maxHealth) + newHealth = maxHealth; + else if (newHealth > maxHealth) + newHealth = health + 1; + + SetEntProp(client, Prop_Data, "m_iHealth", newHealth); + } + + break; + } + } } stock void HealBeacon_DeleteAllTimers() { - for (int i = 0; i <= 1; i++) { - delete g_hRoundStart_Timer[i]; - } + for (int i = 0; i <= 1; i++) + delete g_hRoundStart_Timer[i]; - delete g_hDamageTimer; - delete g_hHealTimer; + delete g_hDamageTimer; + delete g_hHealTimer; - for (int i = 1; i <= MaxClients; i++) - { - delete g_hBeaconTimer[i]; - } + for (int i = 1; i <= MaxClients; i++) + delete g_hBeaconTimer[i]; } stock void SetClientNeon(int client) { - RemoveNeon(client); + RemoveNeon(client); - int entity = CreateEntityByName("light_dynamic"); + int entity = CreateEntityByName("light_dynamic"); + if (!IsValidEntity(entity)) + return; - if (!IsValidEntity(entity)) - return; + g_BeaconPlayersData[client].hasNeon = true; + g_BeaconPlayersData[client].neonEntity = entity; - g_BeaconPlayersData[client].hasNeon = true; - g_BeaconPlayersData[client].neonEntity = entity; + float fOrigin[3]; + GetClientAbsOrigin(client, fOrigin); + fOrigin[2] += 5.0; - float fOrigin[3]; - GetClientAbsOrigin(client, fOrigin); - fOrigin[2] += 5; + int color[4]; + color[0] = g_BeaconPlayersData[client].color[0]; + color[1] = g_BeaconPlayersData[client].color[1]; + color[2] = g_BeaconPlayersData[client].color[2]; + color[3] = g_BeaconPlayersData[client].color[3]; - int color[4]; - color[0] = g_BeaconPlayersData[client].color[0]; - color[1] = g_BeaconPlayersData[client].color[1]; - color[2] = g_BeaconPlayersData[client].color[2]; - color[3] = g_BeaconPlayersData[client].color[3]; + char sColor[64]; + Format(sColor, sizeof(sColor), "%i %i %i %i", color[0], color[1], color[2], color[3]); - char sColor[64]; - Format(sColor, sizeof(sColor), "%i %i %i %i", color[0], color[1], color[2], color[3]); + DispatchKeyValue(entity, "_light", sColor); + DispatchKeyValue(entity, "brightness", "5"); + DispatchKeyValue(entity, "distance", "150"); + DispatchKeyValue(entity, "spotlight_radius", "50"); + DispatchKeyValue(entity, "style", "0"); + DispatchSpawn(entity); + AcceptEntityInput(entity, "TurnOn"); - DispatchKeyValue(entity, "_light", sColor); - DispatchKeyValue(entity, "brightness", "5"); - DispatchKeyValue(entity, "distance", "150"); - DispatchKeyValue(entity, "spotlight_radius", "50"); - DispatchKeyValue(entity, "style", "0"); - DispatchSpawn(entity); - AcceptEntityInput(entity, "TurnOn"); + TeleportEntity(entity, fOrigin, NULL_VECTOR, NULL_VECTOR); - TeleportEntity(entity, fOrigin, NULL_VECTOR, NULL_VECTOR); - - SetVariantString("!activator"); - AcceptEntityInput(entity, "SetParent", client); + SetVariantString("!activator"); + AcceptEntityInput(entity, "SetParent", client); } stock void RemoveNeon(int client) { - if (g_BeaconPlayersData[client].neonEntity && IsValidEntity(g_BeaconPlayersData[client].neonEntity)) - AcceptEntityInput(g_BeaconPlayersData[client].neonEntity, "KillHierarchy"); + if (g_BeaconPlayersData[client].neonEntity && IsValidEntity(g_BeaconPlayersData[client].neonEntity)) + AcceptEntityInput(g_BeaconPlayersData[client].neonEntity, "KillHierarchy"); - g_BeaconPlayersData[client].hasNeon = false; - g_BeaconPlayersData[client].neonEntity = -1; + g_BeaconPlayersData[client].hasNeon = false; + g_BeaconPlayersData[client].neonEntity = -1; } stock void AddNewBeacon(int client, int target) { - SetHealBeaconToClient(target); - - /* ANNOUNCE THAT THIS TARGET IS NOW A HEALBEACON! */ - CPrintToChatAll("%s %T", THIS_MODE_INFO.tag, "HealBeacon_AddAnnounce", client, target); + SetHealBeaconToClient(target); + CPrintToChatAll("%s %T", THIS_MODE_INFO.tag, "HealBeacon_AddAnnounce", client, target); } stock void RemoveBeacon(int client, int target) { - /* REMOVE NEON */ - RemoveNeon(target); + RemoveNeon(target); - /* SAVE HEAL BEACON PLAYER DATA */ - g_BeaconPlayersData[target].ResetValues(); + g_BeaconPlayersData[target].ResetValues(); - /* ERASE THE TARGET INDEX FROM ARRAYLIST */ - for (int i = 0; i < g_aHBPlayers.Length; i++) - { - int random = g_aHBPlayers.Get(i); - if (random == target) - { - g_aHBPlayers.Erase(i); - break; - } - } + for (int i = 0; i < g_aHBPlayers.Length; i++) + { + int random = g_aHBPlayers.Get(i); + if (random == target) + { + g_aHBPlayers.Erase(i); + break; + } + } - /* DELETE BEACON TIMER */ - delete g_hBeaconTimer[target]; + delete g_hBeaconTimer[target]; - /* ANNOUNCE THAT THIS DUDE HEALBEACON IS REMOVED */ - if (client > 0) - { - CPrintToChatAll("%s %T", THIS_MODE_INFO.tag, "HealBeacon_RemoveAnnounce", client, client, target); - LogAction(client, target, "[FunModes-HealBeacon] \"%L\" removed HealBeacon from \"%L\"", client, target); - } + if (client > 0) + { + CPrintToChatAll("%s %T", THIS_MODE_INFO.tag, "HealBeacon_RemoveAnnounce", client, client, target); + LogAction(client, target, "[FunModes-HealBeacon] \"%L\" removed HealBeacon from \"%L\"", client, target); + } } stock void ReplaceBeacon(int client, int random, int target) { - /* if is Repick */ - if (target == -1) - { - /* WE GOTTA REPICK a RANDOM HUMAN FOR HEALBEACON */ - int clientsCount[MAXPLAYERS + 1]; - int humansCount; - - for (int i = 1; i <= MaxClients; i++) - { - if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) - continue; + if (target == -1) + { + int clientsCount[MAXPLAYERS + 1]; + int humansCount; + + for (int i = 1; i <= MaxClients; i++) + { + if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) + continue; + + if (g_BeaconPlayersData[i].hasHealBeacon) + continue; - if (g_BeaconPlayersData[i].hasHealBeacon) - continue; + clientsCount[humansCount++] = i; + } - clientsCount[humansCount++] = i; - } - - if (humansCount <= 0) - return; + if (humansCount <= 0) + return; - /* REMOVE BEACON FROM PREVIOUS HEALBEACON */ - RemoveBeacon(-1, random); + RemoveBeacon(-1, random); - /* WE CAN FINALLY GET THE NEW HEALBEACON */ - int newRandom = clientsCount[GetRandomInt(0, humansCount - 1)]; - SetHealBeaconToClient(newRandom); + int newRandom = clientsCount[GetRandomInt(0, humansCount - 1)]; + SetHealBeaconToClient(newRandom); - /* ANNOUNCE THAT THIS DUDE IS A HEALBEACON */ - CPrintToChatAll("%s %T", THIS_MODE_INFO.tag, "HealBeacon_RepickAnnounce", client, client, newRandom, random); - return; - } + CPrintToChatAll("%s %T", THIS_MODE_INFO.tag, "HealBeacon_RepickAnnounce", client, client, newRandom, random); + return; + } - /* if is a normal replace */ - RemoveBeacon(-1, random); - SetHealBeaconToClient(target); + RemoveBeacon(-1, random); + SetHealBeaconToClient(target); - /* ANNOUNCE THAT THIS DUDE IS A HEALBEACON */ - CPrintToChatAll("%s %T", THIS_MODE_INFO.tag, "HealBeacon_ReplaceAnnounce", client, client, target, random); + CPrintToChatAll("%s %T", THIS_MODE_INFO.tag, "HealBeacon_ReplaceAnnounce", client, client, target, random); } /*---------------------*/ @@ -664,248 +678,240 @@ stock void ReplaceBeacon(int client, int random, int target) public Action Cmd_HealBeaconToggle(int client, int args) { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) - { - CReplyToCommand(client, "%s Healbeacon is currently disabled!", THIS_MODE_INFO.tag); - return Plugin_Handled; - } - - if (THIS_MODE_INFO.isOn) - { - delete g_aHBPlayers; - - HealBeacon_DeleteAllTimers(); - - if (!client) - ReplyToCommand(client, "%s HealBeacon Mode is now OFF!", THIS_MODE_INFO.tag); - else - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_Disabled", client); - } - else - { - /* Event hooks */ - FunModes_HookEvent(g_bEvent_RoundStart, "round_start", Event_RoundStart); - FunModes_HookEvent(g_bEvent_RoundEnd, "round_end", Event_RoundEnd); - FunModes_HookEvent(g_bEvent_PlayerTeam, "player_team", Event_PlayerTeam); - FunModes_HookEvent(g_bEvent_PlayerDeath, "player_death", Event_PlayerDeath); - - delete g_aHBPlayers; - g_aHBPlayers = new ArrayList(ByteCountToCells(32)); - if (!client) - ReplyToCommand(client, "%s HealBeacon Mode is now ON!", THIS_MODE_INFO.tag); - else - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_Enabled", client); - - FunModes_RestartRound(); - } - - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, !THIS_MODE_INFO.isOn, THIS_MODE_INFO.index); - return Plugin_Handled; + if (!g_bHealBeacon_Enabled) + { + CReplyToCommand(client, "%s Healbeacon is currently disabled!", THIS_MODE_INFO.tag); + return Plugin_Handled; + } + + if (THIS_MODE_INFO.isOn) + { + delete g_aHBPlayers; + + HealBeacon_DeleteAllTimers(); + + if (!client) + ReplyToCommand(client, "%s HealBeacon Mode is now OFF!", THIS_MODE_INFO.tag); + else + CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_Disabled", client); + } + else + { + FunModes_HookEvent(g_bEvent_RoundStart, "round_start", Event_RoundStart); + FunModes_HookEvent(g_bEvent_RoundEnd, "round_end", Event_RoundEnd); + FunModes_HookEvent(g_bEvent_PlayerTeam, "player_team", Event_PlayerTeam); + FunModes_HookEvent(g_bEvent_PlayerDeath, "player_death", Event_PlayerDeath); + + delete g_aHBPlayers; + g_aHBPlayers = new ArrayList(ByteCountToCells(32)); + + if (!client) + ReplyToCommand(client, "%s HealBeacon Mode is now ON!", THIS_MODE_INFO.tag); + else + CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_Enabled", client); + + FunModes_RestartRound(); + } + + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, !THIS_MODE_INFO.isOn, THIS_MODE_INFO.index); + return Plugin_Handled; } public Action Cmd_HealBeaconSettings(int client, int args) { - if (!client) - return Plugin_Handled; - - if (!THIS_MODE_INFO.isOn) - { - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_Disabled", client); - return Plugin_Handled; - } + if (!client) + return Plugin_Handled; - HealBeacon_DisplayMainMenu(client); - return Plugin_Handled; + HealBeacon_DisplayMainMenu(client); + return Plugin_Handled; } Action Cmd_HealBeaconDistance(int client, int args) { - if (!THIS_MODE_INFO.isOn) - { - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_Disabled", client); - return Plugin_Handled; - } - - if (args < 2) - { - CReplyToCommand(client, "%s Usage: sm_beacon_distance ", THIS_MODE_INFO.tag); - return Plugin_Handled; - } - - char arg1[65], arg2[65]; - GetCmdArg(1, arg1, sizeof(arg1)); - GetCmdArg(2, arg2, sizeof(arg2)); - - int target = FindTarget(client, arg1, false, false); - if (target < 1) - { - ReplyToTargetError(client, COMMAND_TARGET_NOT_IN_GAME); - return Plugin_Handled; - } - - if (!g_BeaconPlayersData[target].hasHealBeacon) - { - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_PlayerIsNot", client); - return Plugin_Handled; - } - - float distance; - if (!StringToFloatEx(arg2, distance)) - { - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_InvalidDistnace", client); - return Plugin_Handled; - } - - g_BeaconPlayersData[target].distance = distance; - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_DistanceChange", client, target, distance); - LogAction(client, target, "[FunModes-HealBeacon] \"%L\" changed Beacon Distance of \"%L\" to \"%d\"", client, target, distance); - return Plugin_Handled; + if (!THIS_MODE_INFO.isOn) + { + CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_Disabled", client); + return Plugin_Handled; + } + + if (args < 2) + { + CReplyToCommand(client, "%s Usage: sm_beacon_distance ", THIS_MODE_INFO.tag); + return Plugin_Handled; + } + + char arg1[65], arg2[65]; + GetCmdArg(1, arg1, sizeof(arg1)); + GetCmdArg(2, arg2, sizeof(arg2)); + + int target = FindTarget(client, arg1, false, false); + if (target < 1) + { + ReplyToTargetError(client, COMMAND_TARGET_NOT_IN_GAME); + return Plugin_Handled; + } + + if (!g_BeaconPlayersData[target].hasHealBeacon) + { + CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_PlayerIsNot", client); + return Plugin_Handled; + } + + float distance; + if (!StringToFloatEx(arg2, distance)) + { + CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_InvalidDistnace", client); + return Plugin_Handled; + } + + g_BeaconPlayersData[target].distance = distance; + CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_DistanceChange", client, target, distance); + LogAction(client, target, "[FunModes-HealBeacon] \"%L\" changed Beacon Distance of \"%L\" to \"%d\"", client, target, distance); + return Plugin_Handled; } Action Cmd_HealBeaconReplace(int client, int args) { - if (!THIS_MODE_INFO.isOn) - { - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_Disabled", client); - return Plugin_Handled; - } + if (!THIS_MODE_INFO.isOn) + { + CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_Disabled", client); + return Plugin_Handled; + } - if (args < 2) - { - CReplyToCommand(client, "%s Usage: sm_replacebeacon ", THIS_MODE_INFO.tag); - return Plugin_Handled; - } + if (args < 2) + { + CReplyToCommand(client, "%s Usage: sm_replacebeacon ", THIS_MODE_INFO.tag); + return Plugin_Handled; + } - char arg1[65], arg2[65]; - GetCmdArg(1, arg1, sizeof(arg1)); - GetCmdArg(2, arg2, sizeof(arg2)); + char arg1[65], arg2[65]; + GetCmdArg(1, arg1, sizeof(arg1)); + GetCmdArg(2, arg2, sizeof(arg2)); - int healBeaconTarget = FindTarget(client, arg1, false, false); - int target = FindTarget(client, arg2, false, false); + int healBeaconTarget = FindTarget(client, arg1, false, false); + int target = FindTarget(client, arg2, false, false); - if (healBeaconTarget < 1 || target < 1) - { - ReplyToTargetError(client, COMMAND_TARGET_NOT_IN_GAME); - return Plugin_Handled; - } + if (healBeaconTarget < 1 || target < 1) + { + ReplyToTargetError(client, COMMAND_TARGET_NOT_IN_GAME); + return Plugin_Handled; + } - if (!g_BeaconPlayersData[healBeaconTarget].hasHealBeacon) - { - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_PlayerIsNot", client); - return Plugin_Handled; - } + if (!g_BeaconPlayersData[healBeaconTarget].hasHealBeacon) + { + CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_PlayerIsNot", client); + return Plugin_Handled; + } - if (g_BeaconPlayersData[target].hasHealBeacon) - { - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_PlayerIs", client); - return Plugin_Handled; - } + if (g_BeaconPlayersData[target].hasHealBeacon) + { + CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_PlayerIs", client); + return Plugin_Handled; + } - ReplaceBeacon(client, healBeaconTarget, target); - return Plugin_Handled; + ReplaceBeacon(client, healBeaconTarget, target); + return Plugin_Handled; } Action Cmd_HealBeaconAddNew(int client, int args) { - if (!THIS_MODE_INFO.isOn) - { - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_Disabled", client); - return Plugin_Handled; - } + if (!THIS_MODE_INFO.isOn) + { + CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_Disabled", client); + return Plugin_Handled; + } - if (args < 1) - { - CReplyToCommand(client, "%s Usage: sm_addnewbeacon ", THIS_MODE_INFO.tag); - return Plugin_Handled; - } + if (args < 1) + { + CReplyToCommand(client, "%s Usage: sm_addnewbeacon ", THIS_MODE_INFO.tag); + return Plugin_Handled; + } - char arg[65]; - GetCmdArg(1, arg, sizeof(arg)); + char arg[65]; + GetCmdArg(1, arg, sizeof(arg)); - int target = FindTarget(client, arg, false, false); - if (target < 1) - { - ReplyToTargetError(client, COMMAND_TARGET_NOT_IN_GAME); - return Plugin_Handled; - } + int target = FindTarget(client, arg, false, false); + if (target < 1) + { + ReplyToTargetError(client, COMMAND_TARGET_NOT_IN_GAME); + return Plugin_Handled; + } - if (g_BeaconPlayersData[target].hasHealBeacon) - { - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_PlayerIs", client); - return Plugin_Handled; - } + if (g_BeaconPlayersData[target].hasHealBeacon) + { + CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_PlayerIs", client); + return Plugin_Handled; + } - AddNewBeacon(client, target); - LogAction(client, target, "[FunModes-HealBeacon] \"%L\" added \"%L\" with a HealBeacon.", client, target); - return Plugin_Handled; + AddNewBeacon(client, target); + LogAction(client, target, "[FunModes-HealBeacon] \"%L\" added \"%L\" with a HealBeacon.", client, target); + return Plugin_Handled; } Action Cmd_HealBeaconRemove(int client, int args) { - if (!THIS_MODE_INFO.isOn) - { - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_Disabled", client); - return Plugin_Handled; - } + if (!THIS_MODE_INFO.isOn) + { + CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_Disabled", client); + return Plugin_Handled; + } - if (args < 1) - { - CReplyToCommand(client, "%s Usage: sm_removebeacon ", THIS_MODE_INFO.tag); - return Plugin_Handled; - } + if (args < 1) + { + CReplyToCommand(client, "%s Usage: sm_removebeacon ", THIS_MODE_INFO.tag); + return Plugin_Handled; + } - char arg[65]; - GetCmdArg(1, arg, sizeof(arg)); + char arg[65]; + GetCmdArg(1, arg, sizeof(arg)); - int target = FindTarget(client, arg, false, false); - if (target < 1) - { - ReplyToTargetError(client, COMMAND_TARGET_NOT_IN_GAME); - return Plugin_Handled; - } + int target = FindTarget(client, arg, false, false); + if (target < 1) + { + ReplyToTargetError(client, COMMAND_TARGET_NOT_IN_GAME); + return Plugin_Handled; + } - if (!g_BeaconPlayersData[target].hasHealBeacon) - { - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_PlayerIsNot", client); - return Plugin_Handled; - } + if (!g_BeaconPlayersData[target].hasHealBeacon) + { + CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_PlayerIsNot", client); + return Plugin_Handled; + } - RemoveBeacon(client, target); - return Plugin_Handled; + RemoveBeacon(client, target); + return Plugin_Handled; } Action Cmd_HealBeaconCheckDistance(int client, int args) { - if (!client) - { - return Plugin_Handled; - } + if (!client) + return Plugin_Handled; - if (args < 1) - { - CReplyToCommand(client, "%s Usage: sm_checkdistance ", THIS_MODE_INFO.tag); - return Plugin_Handled; - } + if (args < 1) + { + CReplyToCommand(client, "%s Usage: sm_checkdistance ", THIS_MODE_INFO.tag); + return Plugin_Handled; + } - char arg[65]; - GetCmdArg(1, arg, sizeof(arg)); + char arg[65]; + GetCmdArg(1, arg, sizeof(arg)); - int target = FindTarget(client, arg, false, false); - if (target < 1) - { - ReplyToTargetError(client, COMMAND_TARGET_NOT_IN_GAME); - return Plugin_Handled; - } + int target = FindTarget(client, arg, false, false); + if (target < 1) + { + ReplyToTargetError(client, COMMAND_TARGET_NOT_IN_GAME); + return Plugin_Handled; + } - if (!IsPlayerAlive(target)) - { - ReplyToTargetError(client, COMMAND_TARGET_NOT_ALIVE); - return Plugin_Handled; - } + if (!IsPlayerAlive(target)) + { + ReplyToTargetError(client, COMMAND_TARGET_NOT_ALIVE); + return Plugin_Handled; + } - float distance = GetDistanceBetween(client, target); - CReplyToCommand(client, "%s Distance between you and %N is: {olive}%.2f.", THIS_MODE_INFO.tag, target, distance); - return Plugin_Handled; + float distance = GetDistanceBetween(client, target); + CReplyToCommand(client, "%s Distance between you and %N is: {olive}%.2f.", THIS_MODE_INFO.tag, target, distance); + return Plugin_Handled; } -#include "Fun_Modes/HealBeacon_Menus.sp" \ No newline at end of file +#include "HealBeacon_Menus.sp" diff --git a/addons/sourcemod/scripting/Fun_Modes/HealBeacon_Menus.sp b/addons/sourcemod/scripting/Fun_Modes/HealBeacon_Menus.sp index cfbd41a..41912c2 100644 --- a/addons/sourcemod/scripting/Fun_Modes/HealBeacon_Menus.sp +++ b/addons/sourcemod/scripting/Fun_Modes/HealBeacon_Menus.sp @@ -1,6 +1,6 @@ /* (). FunModes V2: - + @file HealBeacon_Menus.sp @Usage Menu Functions for the HealBeacon mode. */ @@ -13,27 +13,31 @@ int g_iClientMenuUserId[MAXPLAYERS + 1] = { -1, ... }; stock void HealBeacon_DisplayMainMenu(int client) { Menu menu = new Menu(MainMenu_Handler); - menu.SetTitle("Do Actions on the heal beaconed players"); + menu.SetTitle("HealBeacon Settings"); - int count = 0; - for (int i = 0; i < g_aHBPlayers.Length; i++) + if (g_aHBPlayers) { - int random = g_aHBPlayers.Get(i); - if (!IsClientInGame(random) || !IsPlayerAlive(random)) - continue; - - char info[32], buffer[64]; - Format(info, sizeof(info), "%d", GetClientUserId(random)); - Format(buffer, sizeof(buffer), "%N", random); - - menu.AddItem(info, buffer); - count++; + int count = 0; + for (int i = 0; i < g_aHBPlayers.Length; i++) + { + int random = g_aHBPlayers.Get(i); + if (!IsClientInGame(random) || !IsPlayerAlive(random)) + continue; + + char info[32], buffer[64]; + Format(info, sizeof(info), "%d", GetClientUserId(random)); + Format(buffer, sizeof(buffer), "%N", random); + + menu.AddItem(info, buffer); + count++; + } + + if (count <= 0) + menu.AddItem("", "None", ITEMDRAW_DISABLED); } - if (count <= 0) - menu.AddItem("", "None", ITEMDRAW_DISABLED); - menu.AddItem("option2", "Change Heal Beacon Settings"); + menu.AddItem("option3", "Show Cvars"); menu.Display(client, MENU_TIME_FOREVER); menu.ExitButton = true; @@ -56,6 +60,11 @@ public int MainMenu_Handler(Menu menu, MenuAction action, int param1, int param2 HealBeacon_DisplaySettingsMenu(param1); return 0; } + else if (strcmp(buffer, "option3") == 0) + { + ShowCvarsInfo(param1, THIS_MODE_INFO); + return 0; + } int userid = StringToInt(buffer); int random = GetClientOfUserId(userid); @@ -71,7 +80,6 @@ public int MainMenu_Handler(Menu menu, MenuAction action, int param1, int param2 return 0; } - /* save the heal beacon player's userid in the param1 variable so we can get it for later */ HealBeacon_DisplayActionsMenu(param1, random); } } @@ -156,7 +164,7 @@ stock void HealBeacon_DisplayBeaconDamageMenu(int client) { Menu menu = new Menu(BeaconDamageMenu_Handler); char title[256]; - Format(title, sizeof(title), "Change Heal Beacon Damage\nYou can also change the cvar sm_beacon_damage\nincase you didnt find the good\ndamage in the list\nCurrent HealBeacon Damage: %.2f", THIS_MODE_INFO.cvarInfo[HB_CONVAR_BEACON_DAMAGE].cvar.FloatValue); + Format(title, sizeof(title), "Change Heal Beacon Damage\nYou can also change the cvar sm_beacon_damage\nincase you didnt find the good\ndamage in the list\nCurrent HealBeacon Damage: %.2f", g_fHB_BeaconDamage); menu.SetTitle(title); menu.AddItem("1", "1"); @@ -189,7 +197,8 @@ public int BeaconDamageMenu_Handler(Menu menu, MenuAction action, int param1, in menu.GetItem(param2, buffer, sizeof(buffer)); int num = StringToInt(buffer); - THIS_MODE_INFO.cvarInfo[HB_CONVAR_BEACON_DAMAGE].cvar.FloatValue = float(num); + _FUNMODES_CVAR_SET_VALUE(THIS_MODE_INFO.index, HB_CONVAR_BEACON_DAMAGE, Float, float(num)); + CPrintToChat(param1, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_DamageChange", param1, num); HealBeacon_DisplayBeaconDamageMenu(param1); } @@ -203,7 +212,7 @@ stock void HealBeacon_DisplayBeaconHealMenu(int client) { Menu menu = new Menu(BeaconHealMenu_Handler); char title[256]; - Format(title, sizeof(title), "Change Heal Beacon Heal per second\nYou can also change the cvar sm_beacon_heal\nincase you didnt find the good\nheal in the list\nCurrent HealBeacon Heal: %d", THIS_MODE_INFO.cvarInfo[HB_CONVAR_BEACON_HEAL].cvar.IntValue); + Format(title, sizeof(title), "Change Heal Beacon Heal per second\nYou can also change the cvar sm_beacon_heal\nincase you didnt find the good\nheal in the list\nCurrent HealBeacon Heal: %d", g_iHB_BeaconHeal); menu.SetTitle(title); for (int i = 1; i <= 7; i++) @@ -235,8 +244,9 @@ public int BeaconHealMenu_Handler(Menu menu, MenuAction action, int param1, int char buffer[32]; menu.GetItem(param2, buffer, sizeof(buffer)); int num = StringToInt(buffer); - - THIS_MODE_INFO.cvarInfo[HB_CONVAR_BEACON_HEAL].cvar.IntValue = num; + + _FUNMODES_CVAR_SET_VALUE(THIS_MODE_INFO.index, HB_CONVAR_BEACON_HEAL, Int, num); + CPrintToChat(param1, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_HealChange", param1, num); HealBeacon_DisplayBeaconHealMenu(param1); } @@ -283,7 +293,8 @@ public int BeaconTimerMenu_Handler(Menu menu, MenuAction action, int param1, int menu.GetItem(param2, buffer, sizeof(buffer)); int num = StringToInt(buffer); - THIS_MODE_INFO.cvarInfo[HB_CONVAR_BEACON_TIMER].cvar.FloatValue = float(num); + _FUNMODES_CVAR_SET_VALUE(THIS_MODE_INFO.index, HB_CONVAR_BEACON_TIMER, Float, float(num)); + CPrintToChat(param1, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_TimerChange", param1, num); HealBeacon_DisplaySettingsMenu(param1); } @@ -342,14 +353,14 @@ public int BeaconDefaultColorMenu_Handler(Menu menu, MenuAction action, int para { char info[128]; menu.GetItem(param2, info, sizeof(info)); - + int index = StringToInt(info); FM_Color myColor; myColor = g_ColorsList[index]; - + char buffers[3][5]; // the splitted buffers from menu item ExplodeString(myColor.rgb, " ", buffers, 3, sizeof(buffers[])); - + g_ColorDefault[0] = StringToInt(buffers[0]); g_ColorDefault[1] = StringToInt(buffers[1]); g_ColorDefault[2] = StringToInt(buffers[2]); @@ -380,7 +391,7 @@ stock void HealBeacon_DisplayActionsMenu(int client, int random) menu.AddItem("", "Change beacon radius and distance"); char light[32]; - g_BeaconPlayersData[random].hasNeon ? Format(light, sizeof(light), "Disable Light on the player") : Format(light, sizeof(light), "Enable Light on the player"); + g_BeaconPlayersData[random].hasNeon ? Format(light, sizeof(light), "Disable Light on the player") : Format(light, sizeof(light), "Enable Light on the player"); menu.AddItem("", light); menu.AddItem("", "Teleport to player"); @@ -421,19 +432,19 @@ public int ActionsMenu_Handler(Menu menu, MenuAction action, int param1, int par HealBeacon_DisplayMainMenu(param1); return 0; } - + switch(param2) { - case 0: // Repick + case 0: { ReplaceBeacon(param1, random, -1); HealBeacon_DisplayMainMenu(param1); } - case 1: // Colors Menu + case 1: { HealBeacon_DisplayColorsMenu(param1); } - case 2: // Beacon Distance Menu + case 2: { HealBeacon_DisplayBeaconDistanceMenu(param1); } @@ -452,7 +463,7 @@ public int ActionsMenu_Handler(Menu menu, MenuAction action, int param1, int par HealBeacon_DisplayActionsMenu(param1, random); } - case 4: // Teleport To Player + case 4: { float fOrigin[3], fAngles[3]; GetClientAbsOrigin(random, fOrigin); @@ -462,8 +473,8 @@ public int ActionsMenu_Handler(Menu menu, MenuAction action, int param1, int par LogAction(param1, random, "[FunModes-HealBeacon] \"%L\" teleported to \"%L\"(HealBeacon Player)", param1, random); HealBeacon_DisplayActionsMenu(param1, random); } - - case 5:// Bring player + + case 5: { float fOrigin[3], fAngles[3]; GetClientAbsOrigin(param1, fOrigin); @@ -546,25 +557,24 @@ public int ColorsMenu_Handler(Menu menu, MenuAction action, int param1, int para return 0; } - char info[3]; // The menu item + char info[3]; menu.GetItem(param2, info, sizeof(info)); - + int index = StringToInt(info); FM_Color myColor; myColor = g_ColorsList[index]; - - char buffers[3][5]; // the splitted buffers from menu item + + char buffers[3][5]; ExplodeString(myColor.rgb, " ", buffers, 3, sizeof(buffers[])); - + int color[4]; color[0] = StringToInt(buffers[0]); color[1] = StringToInt(buffers[1]); color[2] = StringToInt(buffers[2]); color[3] = 255; - g_BeaconPlayersData[random].SetColor(color); // we gotta save the new color in the enum struct + g_BeaconPlayersData[random].SetColor(color); - /* TELL THE CLIENT THAT THIS CHANGE IS APPLIED */ CPrintToChat(param1, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_ColorChange", param1, random, myColor.name, myColor.name); LogAction(param1, random, "[FunModes-HealBeacon] \"%L\" changed Beacon and Neon colors of \"%L\" to \"%s\"", param1, random, myColor.name); HealBeacon_DisplayColorsMenu(param1); @@ -631,13 +641,12 @@ public int BeaconDistanceMenu_Handler(Menu menu, MenuAction action, int param1, return 0; } - char info[128]; // The menu item + char info[128]; menu.GetItem(param2, info, sizeof(info)); int distance = StringToInt(info); g_BeaconPlayersData[random].distance = float(distance); - /* TELL THE CLIENT THAT THIS CHANGE IS APPLIED */ CPrintToChat(param1, "%s %T", THIS_MODE_INFO.tag, "HealBeacon_DistanceChange", param1, random, distance); LogAction(param1, random, "[FunModes-HealBeacon] \"%L\" changed Beacon Distance of \"%L\" to \"%d\"", param1, random, distance); HealBeacon_DisplayBeaconDistanceMenu(param1); @@ -645,4 +654,4 @@ public int BeaconDistanceMenu_Handler(Menu menu, MenuAction action, int param1, } return 0; -} \ No newline at end of file +} diff --git a/addons/sourcemod/scripting/Fun_Modes/InvertedControls.sp b/addons/sourcemod/scripting/Fun_Modes/InvertedControls.sp index 7e5f9d8..9062877 100644 --- a/addons/sourcemod/scripting/Fun_Modes/InvertedControls.sp +++ b/addons/sourcemod/scripting/Fun_Modes/InvertedControls.sp @@ -1,6 +1,6 @@ /* (). FunModes V2: - + @file InvertedControls.sp @Usage Functions for the IC mode. */ @@ -8,16 +8,24 @@ #pragma semicolon 1 #pragma newdecls required -ModeInfo g_ICInfo; +static int g_iICIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iICIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_ICInfo +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] #define IC_CONVAR_TOGGLE 0 +bool g_bIC_Enabled; + /* CALLED ON PLUGIN START */ stock void OnPluginStart_IC() { + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + THIS_MODE_INFO.name = "IC"; THIS_MODE_INFO.tag = "{gold}[FunModes-InvertedControls]{lightgreen}"; @@ -29,36 +37,50 @@ stock void OnPluginStart_IC() "sm_invertedcontrols", "sm_fm_ic" }; - + for (int i = 0; i < sizeof(commands); i++) { RegAdminCmd(commands[i], Cmd_ICToggle, ADMFLAG_CONVARS, "Enable/Disable Inverted controls"); } - + RegAdminCmd("sm_ic_settings", Cmd_ICSettings, ADMFLAG_CONVARS, "Open IC Settings Menu"); - + /* CONVARS */ DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, IC_CONVAR_TOGGLE, - "sm_ic_enable", "1", "Enable/Disable Inverted Controls mode.", - ("0,1"), "bool" + IC_CONVAR_TOGGLE, "sm_ic_enable", + "1", "Enable/Disable Inverted Controls mode.", + ("0,1"), CONVAR_BOOL ); + THIS_MODE_INFO.cvars[IC_CONVAR_TOGGLE].HookChange(IC_OnConVarChange); + THIS_MODE_INFO.enableIndex = IC_CONVAR_TOGGLE; +} - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; +void InitCvarsValues_IC() +{ + int modeIndex = THIS_MODE_INFO.index; - THIS_MODE_INFO.cvarInfo[IC_CONVAR_TOGGLE].cvar.AddChangeHook(OnICModeToggle); + g_bIC_Enabled = _FUNMODES_CVAR_GET_VALUE(modeIndex, IC_CONVAR_TOGGLE, Bool); } -void OnICModeToggle(ConVar cvar, const char[] newValue, const char[] oldValue) +void IC_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) { - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + switch (cvarIndex) + { + case IC_CONVAR_TOGGLE: + { + bool val = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bIC_Enabled = val; + } + } } stock void OnMapStart_IC() {} + stock void OnMapEnd_IC() { CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, false, THIS_MODE_INFO.index); @@ -80,7 +102,9 @@ stock void ZR_OnClientInfected_IC(int client) } stock void Event_RoundStart_IC() {} + stock void Event_RoundEnd_IC() {} + stock void Event_PlayerSpawn_IC(int client) { #pragma unused client @@ -98,7 +122,7 @@ stock void Event_PlayerDeath_IC(int client) public Action Cmd_ICToggle(int client, int args) { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) + if (!g_bIC_Enabled) { CReplyToCommand(client, "%s Inverted Controls is currently Disabled", THIS_MODE_INFO.tag); return Plugin_Handled; @@ -107,10 +131,9 @@ public Action Cmd_ICToggle(int client, int args) ConVar cvar = FindConVar("sv_accelerate"); if (cvar == null) { - // it should never happen though return Plugin_Handled; } - + if (cvar.IntValue == -5) { CPrintToChatAll("%s Inverted Controls is now {olive}Off!", THIS_MODE_INFO.tag); @@ -118,7 +141,7 @@ public Action Cmd_ICToggle(int client, int args) delete cvar; return Plugin_Handled; } - + CPrintToChatAll("%s Inverted Controls is now {olive}On!", THIS_MODE_INFO.tag); cvar.IntValue = -5; delete cvar; @@ -130,7 +153,7 @@ public Action Cmd_ICSettings(int client, int args) { if (!client) return Plugin_Handled; - + Menu menu = new Menu(Menu_ICSettings); menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); @@ -139,7 +162,7 @@ public Action Cmd_ICSettings(int client, int args) menu.ExitBackButton = true; menu.Display(client, MENU_TIME_FOREVER); - + return Plugin_Handled; } @@ -149,7 +172,7 @@ int Menu_ICSettings(Menu menu, MenuAction action, int param1, int param2) { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) @@ -163,4 +186,4 @@ int Menu_ICSettings(Menu menu, MenuAction action, int param1, int param2) } return 0; -} \ No newline at end of file +} diff --git a/addons/sourcemod/scripting/Fun_Modes/MathGame.sp b/addons/sourcemod/scripting/Fun_Modes/MathGame.sp index 0e2f597..2edb73f 100644 --- a/addons/sourcemod/scripting/Fun_Modes/MathGame.sp +++ b/addons/sourcemod/scripting/Fun_Modes/MathGame.sp @@ -1,29 +1,31 @@ /* (). FunModes V2: - + @file MathGame.sp - @Usage Functions for the MathGame Mode. - + @Usage Functions for the MathGame Mode. */ #pragma semicolon 1 #pragma newdecls required -ModeInfo g_MathGameInfo; +static int g_iMathGameIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iMathGameIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_MathGameInfo - -#define MATHGAME_CONVAR_TIMER_INTERVAL_EASY 0 -#define MATHGAME_CONVAR_TIMER_INTERVAL_MEDIUM 1 -#define MATHGAME_CONVAR_TIMER_INTERVAL_HARD 2 -#define MATHGAME_CONVAR_EASY_DAMAGE 3 -#define MATHGAME_CONVAR_MEDIUM_DAMAGE 4 -#define MATHGAME_CONVAR_HARD_DAMAGE 5 -#define MATHGAME_CONVAR_INCLUDE_ZOMBIE 6 -#define MATHGAME_CONVAR_MAX_TRIES 7 -#define MATHGAME_CONVAR_TIME_DELAY 8 -#define MATHGAME_CONVAR_TOGGLE 9 +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] + +#define MATHGAME_CONVAR_TIMER_INTERVAL_EASY 0 +#define MATHGAME_CONVAR_TIMER_INTERVAL_MEDIUM 1 +#define MATHGAME_CONVAR_TIMER_INTERVAL_HARD 2 +#define MATHGAME_CONVAR_EASY_DAMAGE 3 +#define MATHGAME_CONVAR_MEDIUM_DAMAGE 4 +#define MATHGAME_CONVAR_HARD_DAMAGE 5 +#define MATHGAME_CONVAR_INCLUDE_ZOMBIE 6 +#define MATHGAME_CONVAR_MAX_TRIES 7 +#define MATHGAME_CONVAR_TIME_DELAY 8 +#define MATHGAME_CONVAR_TOGGLE 9 Handle g_hMathGameTimer; Handle g_hMathGameTimerRepeat; @@ -36,98 +38,166 @@ bool g_bMathGameDisableRespawn[MAXPLAYERS + 1]; char g_sMathGameQuestion[MAXPLAYERS + 1][32]; int g_iMathGameTime; +float g_fMathGame_TimerIntervals[3]; +float g_fMathGame_Damages[3]; +bool g_bMathGame_IncludeZombies; +int g_iMathGame_MaxTries; +float g_fMathGame_TimeDelay; +bool g_bMathGame_Enabled; + stock void OnPluginStart_MathGame() { + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + THIS_MODE_INFO.name = "MathGame"; THIS_MODE_INFO.tag = "{gold}[FunModes-MathGame]{lightgreen}"; - - /* COMMANDS */ - /* THESE ARE THE STANDARD COMMANDS THAT ALL MODES SHOULD HAVE */ + RegAdminCmd("sm_fm_mathgame", Cmd_MathGameToggle, ADMFLAG_CONVARS, "Turn MathGame Mode On/Off"); RegAdminCmd("sm_mathgame_settings", Cmd_MathGameSettings, ADMFLAG_CONVARS, "Open MathGame Sttings Menu"); - - /* CONVARS */ + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, MATHGAME_CONVAR_TIMER_INTERVAL_EASY, - "sm_mathgame_easy_time", "15.0", "The time needed to answer easy math questions", - ("20.0,30.0,50.0,60.0"), "float" + MATHGAME_CONVAR_TIMER_INTERVAL_EASY, "sm_mathgame_easy_time", + "15.0", "The time needed to answer easy math questions", + ("20.0,30.0,50.0,60.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[MATHGAME_CONVAR_TIMER_INTERVAL_EASY].HookChange(MathGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, MATHGAME_CONVAR_TIMER_INTERVAL_MEDIUM, - "sm_mathgame_medium_time", "30.0", "The time needed to answer medium math questions", - ("20.0,30.0,50.0,60.0"), "float" + MATHGAME_CONVAR_TIMER_INTERVAL_MEDIUM, "sm_mathgame_medium_time", + "30.0", "The time needed to answer medium math questions", + ("20.0,30.0,50.0,60.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[MATHGAME_CONVAR_TIMER_INTERVAL_MEDIUM].HookChange(MathGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, MATHGAME_CONVAR_TIMER_INTERVAL_HARD, - "sm_mathgame_hard_time", "60.0", "The time needed to answer hard math questions", - ("20.0,30.0,50.0,60.0"), "float" + MATHGAME_CONVAR_TIMER_INTERVAL_HARD, "sm_mathgame_hard_time", + "60.0", "The time needed to answer hard math questions", + ("20.0,30.0,50.0,60.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[MATHGAME_CONVAR_TIMER_INTERVAL_HARD].HookChange(MathGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, MATHGAME_CONVAR_EASY_DAMAGE, - "sm_mathgame_easy_damage", "50.0", "The amount of damage to apply to those who can't answer easy questions", - ("10.0,20.0,25.0,35.0,50.0"), "float" + MATHGAME_CONVAR_EASY_DAMAGE, "sm_mathgame_easy_damage", + "50.0", "The amount of damage to apply to those who can't answer easy questions", + ("10.0,20.0,25.0,35.0,50.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[MATHGAME_CONVAR_EASY_DAMAGE].HookChange(MathGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, MATHGAME_CONVAR_MEDIUM_DAMAGE, - "sm_mathgame_medium_damage", "35.0", "The amount of damage to apply to those who can't answer medium questions", - ("10.0,20.0,25.0,35.0,50.0"), "float" + MATHGAME_CONVAR_MEDIUM_DAMAGE, "sm_mathgame_medium_damage", + "35.0", "The amount of damage to apply to those who can't answer medium questions", + ("10.0,20.0,25.0,35.0,50.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[MATHGAME_CONVAR_MEDIUM_DAMAGE].HookChange(MathGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, MATHGAME_CONVAR_HARD_DAMAGE, - "sm_mathgame_hard_damage", "20.0", "The amount of damage to apply to those who can't answer hard questions", - ("10.0,20.0,25.0,35.0,50.0"), "float" + MATHGAME_CONVAR_HARD_DAMAGE, "sm_mathgame_hard_damage", + "20.0", "The amount of damage to apply to those who can't answer hard questions", + ("10.0,20.0,25.0,35.0,50.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[MATHGAME_CONVAR_HARD_DAMAGE].HookChange(MathGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, MATHGAME_CONVAR_INCLUDE_ZOMBIE, - "sm_mathgame_include_zombies", "0", "Include zombies to the math game (1 = Enabled, 0 = Disabled)", - ("0,1"), "bool" + MATHGAME_CONVAR_INCLUDE_ZOMBIE, "sm_mathgame_include_zombies", + "0", "Include zombies to the math game (1 = Enabled, 0 = Disabled)", + ("0,1"), CONVAR_BOOL ); - + THIS_MODE_INFO.cvars[MATHGAME_CONVAR_INCLUDE_ZOMBIE].HookChange(MathGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, MATHGAME_CONVAR_MAX_TRIES, - "sm_mathgame_max_tries", "3", "How many failed tries for zombies to answer question until they can never respawn again?", - ("1,2,3,4,5"), "int" + MATHGAME_CONVAR_MAX_TRIES, "sm_mathgame_max_tries", + "3", "How many failed tries for zombies to answer question until they can never respawn again?", + ("1,2,3,4,5"), CONVAR_INT ); - + THIS_MODE_INFO.cvars[MATHGAME_CONVAR_MAX_TRIES].HookChange(MathGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, MATHGAME_CONVAR_TIME_DELAY, - "sm_mathgame_time_delay", "15.0", "The delayed time after each math question", - ("15.0,20.0,30.0,35.0"), "float" + MATHGAME_CONVAR_TIME_DELAY, "sm_mathgame_time_delay", + "15.0", "The delayed time after each math question", + ("15.0,20.0,30.0,35.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[MATHGAME_CONVAR_TIME_DELAY].HookChange(MathGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, MATHGAME_CONVAR_TOGGLE, - "sm_mathgame_enable", "1", "Enable/Disable MathGame Mode (This differs from turning it on/off)", - ("0,1"), "bool" + MATHGAME_CONVAR_TOGGLE, "sm_mathgame_enable", + "1", "Enable/Disable MathGame Mode (This differs from turning it on/off)", + ("0,1"), CONVAR_BOOL ); - + THIS_MODE_INFO.cvars[MATHGAME_CONVAR_TOGGLE].HookChange(MathGame_OnConVarChange); + THIS_MODE_INFO.enableIndex = MATHGAME_CONVAR_TOGGLE; - - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; - - THIS_MODE_INFO.cvarInfo[MATHGAME_CONVAR_TOGGLE].cvar.AddChangeHook(OnMathGameModeToggle); } -void OnMathGameModeToggle(ConVar cvar, const char[] newValue, const char[] oldValue) +void InitCvarsValues_MathGame() { - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + int modeIndex = THIS_MODE_INFO.index; + + g_fMathGame_TimerIntervals[0] = _FUNMODES_CVAR_GET_VALUE(modeIndex, MATHGAME_CONVAR_TIMER_INTERVAL_EASY, Float); + g_fMathGame_TimerIntervals[1] = _FUNMODES_CVAR_GET_VALUE(modeIndex, MATHGAME_CONVAR_TIMER_INTERVAL_MEDIUM, Float); + g_fMathGame_TimerIntervals[2] = _FUNMODES_CVAR_GET_VALUE(modeIndex, MATHGAME_CONVAR_TIMER_INTERVAL_HARD, Float); + + g_fMathGame_Damages[0] = _FUNMODES_CVAR_GET_VALUE(modeIndex, MATHGAME_CONVAR_EASY_DAMAGE, Float); + g_fMathGame_Damages[1] = _FUNMODES_CVAR_GET_VALUE(modeIndex, MATHGAME_CONVAR_MEDIUM_DAMAGE, Float); + g_fMathGame_Damages[2] = _FUNMODES_CVAR_GET_VALUE(modeIndex, MATHGAME_CONVAR_HARD_DAMAGE, Float); + + g_bMathGame_IncludeZombies = _FUNMODES_CVAR_GET_VALUE(modeIndex, MATHGAME_CONVAR_INCLUDE_ZOMBIE, Bool); + g_iMathGame_MaxTries = _FUNMODES_CVAR_GET_VALUE(modeIndex, MATHGAME_CONVAR_MAX_TRIES, Int); + g_fMathGame_TimeDelay = _FUNMODES_CVAR_GET_VALUE(modeIndex, MATHGAME_CONVAR_TIME_DELAY, Float); + g_bMathGame_Enabled = _FUNMODES_CVAR_GET_VALUE(modeIndex, MATHGAME_CONVAR_TOGGLE, Bool); +} + +void MathGame_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) +{ + switch (cvarIndex) + { + case MATHGAME_CONVAR_TIMER_INTERVAL_EASY: + g_fMathGame_TimerIntervals[0] = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case MATHGAME_CONVAR_TIMER_INTERVAL_MEDIUM: + g_fMathGame_TimerIntervals[1] = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case MATHGAME_CONVAR_TIMER_INTERVAL_HARD: + g_fMathGame_TimerIntervals[2] = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case MATHGAME_CONVAR_EASY_DAMAGE: + g_fMathGame_Damages[0] = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case MATHGAME_CONVAR_MEDIUM_DAMAGE: + g_fMathGame_Damages[1] = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case MATHGAME_CONVAR_HARD_DAMAGE: + g_fMathGame_Damages[2] = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case MATHGAME_CONVAR_INCLUDE_ZOMBIE: + g_bMathGame_IncludeZombies = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + + case MATHGAME_CONVAR_MAX_TRIES: + g_iMathGame_MaxTries = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + case MATHGAME_CONVAR_TIME_DELAY: + g_fMathGame_TimeDelay = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case MATHGAME_CONVAR_TOGGLE: + { + bool val = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bMathGame_Enabled = val; + } + } } stock void OnMapStart_MathGame() {} + stock void OnMapEnd_MathGame() { CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, false, THIS_MODE_INFO.index); - + g_hMathGameTimer = null; g_hMathGameTimerRepeat = null; + g_hMathGameTimerDelay = null; } stock void OnClientPutInServer_MathGame(int client) @@ -151,11 +221,11 @@ stock void Event_RoundStart_MathGame() { if (!THIS_MODE_INFO.isOn) return; - + delete g_hMathGameTimer; delete g_hMathGameTimerRepeat; delete g_hMathGameTimerDelay; - + MathGame_ResetPlayers(); CreateTimer(30.0, Timer_StartMathGame, _, TIMER_FLAG_NO_MAPCHANGE); } @@ -164,12 +234,13 @@ Action Timer_StartMathGame(Handle timer) { if (!THIS_MODE_INFO.isOn) return Plugin_Stop; - + MathGame_Ask(); return Plugin_Stop; } stock void Event_RoundEnd_MathGame() {} + stock void Event_PlayerSpawn_MathGame(int client) { #pragma unused client @@ -189,29 +260,28 @@ public Action ZR_OnClientRespawn(int &client, ZR_RespawnCondition &condition) { if (!THIS_MODE_INFO.isOn) return Plugin_Continue; - + if (condition != ZR_Respawn_Zombie) return Plugin_Continue; - + if (!g_bMathGameDisableRespawn[client]) return Plugin_Continue; - + return Plugin_Handled; } public Action Cmd_MathGameToggle(int client, int args) { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) + if (!g_bMathGame_Enabled) { CReplyToCommand(client, "%s MathGame Mode is currently Disabled", THIS_MODE_INFO.tag); return Plugin_Handled; } - /* You can change whatever you want here */ CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, !THIS_MODE_INFO.isOn, THIS_MODE_INFO.index); - + CPrintToChatAll("%s MathGame Mode is now %s!", THIS_MODE_INFO.tag, THIS_MODE_INFO.isOn ? "On" : "Off"); - + if (THIS_MODE_INFO.isOn) { MathGame_ResetPlayers(); @@ -226,25 +296,26 @@ public Action Cmd_MathGameToggle(int client, int args) delete g_hMathGameTimerRepeat; delete g_hMathGameTimerDelay; } - + return Plugin_Handled; } public Action OnClientSayCommand(int client, const char[] command, const char[] args) { + #pragma unused command if (!THIS_MODE_INFO.isOn) return Plugin_Continue; - + if (!g_bMathGameHasQuestion[client]) return Plugin_Continue; - + if (!IsCharNumeric(args[0]) && args[0] != '-' && args[0] != '+') return Plugin_Continue; - + int num; if (!StringToIntEx(args, num)) return Plugin_Continue; - + if (num == g_iMathGameAnswer[client]) { CPrintToChat(client, "%s Congratuations, you have answered the math question, nothing bad will hurt you now!", THIS_MODE_INFO.tag); @@ -253,40 +324,37 @@ public Action OnClientSayCommand(int client, const char[] command, const char[] g_iMathGameAnswer[client] = 0; return Plugin_Stop; } - + return Plugin_Continue; } void MathGame_Ask() { int level = GetRandomInt(0, 2); - - static const char levels[][] = { "Easy", "Medium", "Hard" }; - - int time = THIS_MODE_INFO.cvarInfo[level].cvar.IntValue; + + static const char levels[][] = { "Easy", "Medium", "Hard" }; + + int time = RoundToNearest(g_fMathGame_TimerIntervals[level]); CPrintToChatAll("%s Alright gentlemen, Each player will now receive a math question to answer, You have got only {olive}%d seconds", THIS_MODE_INFO.tag, time); CPrintToChatAll("%s Question Level: {olive}%s", THIS_MODE_INFO.tag, levels[level]); - - bool includeZombies = THIS_MODE_INFO.cvarInfo[MATHGAME_CONVAR_INCLUDE_ZOMBIE].cvar.BoolValue; - int maxTries = THIS_MODE_INFO.cvarInfo[MATHGAME_CONVAR_MAX_TRIES].cvar.IntValue; - - if (includeZombies) - CPrintToChatAll("%s Zombies will have {olive}%d maximum tries {lightgreen}to survive or they will be stuck on spec!", THIS_MODE_INFO.tag, maxTries); - + + if (g_bMathGame_IncludeZombies) + CPrintToChatAll("%s Zombies will have {olive}%d maximum tries {lightgreen}to survive or they will be stuck on spec!", THIS_MODE_INFO.tag, g_iMathGame_MaxTries); + for (int i = 1; i <= MaxClients; i++) { if (!IsClientInGame(i) || IsFakeClient(i) || !IsPlayerAlive(i)) continue; - - if (ZR_IsClientHuman(i) || (includeZombies && ZR_IsClientZombie(i))) + + if (ZR_IsClientHuman(i) || (g_bMathGame_IncludeZombies && ZR_IsClientZombie(i))) MathGame_SendQuestion(i, level); } - + delete g_hMathGameTimer; g_hMathGameTimer = CreateTimer(float(time), MathGame_Timer, level, TIMER_FLAG_NO_MAPCHANGE); - + g_iMathGameTime = 0; - + delete g_hMathGameTimerRepeat; g_hMathGameTimerRepeat = CreateTimer(1.0, MathGame_TimerRepeat, time, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT); } @@ -294,18 +362,18 @@ void MathGame_Ask() void MathGame_SendQuestion(int client, int level) { g_bMathGameHasQuestion[client] = true; - + char oper[2]; int numbers[2]; - + int min, max; - + if (level == 0 || level == 1) { min = 1; max = (level == 0) ? 99 : 299; - oper = (GetRandomInt(0,1) == 0)?"+":"-"; - + oper = (GetRandomInt(0, 1) == 0) ? "+" : "-"; + numbers[0] = GetRandomInt(min, max); numbers[1] = GetRandomInt(min, max); } @@ -315,7 +383,7 @@ void MathGame_SendQuestion(int client, int level) numbers[1] = GetRandomInt(0, 9); oper = "*"; } - + int answer; switch (oper[0]) { @@ -323,31 +391,29 @@ void MathGame_SendQuestion(int client, int level) case '-': answer = numbers[0] - numbers[1]; default: answer = numbers[0] * numbers[1]; } - + g_iMathGameAnswer[client] = answer; FormatEx(g_sMathGameQuestion[client], sizeof(g_sMathGameQuestion[]), "%d %s %d", numbers[0], oper, numbers[1]); - + CPrintToChat(client, "%s What is [ {white}%d {olive}%s {white}%d {lightgreen}]?", THIS_MODE_INFO.tag, numbers[0], oper, numbers[1]); } Action MathGame_Timer(Handle timer, int level) { g_hMathGameTimer = null; - + if (!THIS_MODE_INFO.isOn) { delete g_hMathGameTimerRepeat; return Plugin_Stop; } - + delete g_hMathGameTimerRepeat; CPrintToChatAll("%s Time is Up! Players who failed to answer will now be punished!", THIS_MODE_INFO.tag); - - float damage = THIS_MODE_INFO.cvarInfo[level + 3].cvar.FloatValue; - bool includeZombies = THIS_MODE_INFO.cvarInfo[MATHGAME_CONVAR_INCLUDE_ZOMBIE].cvar.BoolValue; - int maxTries = THIS_MODE_INFO.cvarInfo[MATHGAME_CONVAR_MAX_TRIES].cvar.IntValue; - + + float damage = g_fMathGame_Damages[level]; + for (int i = 1; i <= MaxClients; i++) { if (g_bMathGameHasQuestion[i]) @@ -359,35 +425,35 @@ Action MathGame_Timer(Handle timer, int level) } else { - if (!includeZombies) + if (!g_bMathGame_IncludeZombies) continue; - + g_iMathGameFailedAnswers[i]++; - if (g_iMathGameFailedAnswers[i] >= maxTries) + if (g_iMathGameFailedAnswers[i] >= g_iMathGame_MaxTries) { ForcePlayerSuicide(i); - CPrintToChat(i, "%s You will not be able to respawn for failing to answer math questions {olive}%d in a row", THIS_MODE_INFO.tag, maxTries); + CPrintToChat(i, "%s You will not be able to respawn for failing to answer math questions {olive}%d in a row", THIS_MODE_INFO.tag, g_iMathGame_MaxTries); g_bMathGameDisableRespawn[i] = true; g_iMathGameFailedAnswers[i] = 0; - } + } } } } - + MathGame_ResetPlayers(); - + delete g_hMathGameTimerDelay; - g_hMathGameTimerDelay = CreateTimer(THIS_MODE_INFO.cvarInfo[MATHGAME_CONVAR_TIME_DELAY].cvar.FloatValue, MathGame_TimerDelay, _, TIMER_FLAG_NO_MAPCHANGE); + g_hMathGameTimerDelay = CreateTimer(g_fMathGame_TimeDelay, MathGame_TimerDelay, _, TIMER_FLAG_NO_MAPCHANGE); return Plugin_Stop; } Action MathGame_TimerDelay(Handle timer) { g_hMathGameTimerDelay = null; - + if (!THIS_MODE_INFO.isOn) return Plugin_Stop; - + MathGame_Ask(); return Plugin_Continue; } @@ -396,31 +462,30 @@ Action MathGame_TimerRepeat(Handle timer, int time) { char message[128]; FormatEx(message, sizeof(message), "[MathGame] Time Left: %ds\n", time - g_iMathGameTime - 2); - + for (int i = 1; i <= MaxClients; i++) { if (!IsClientInGame(i) || IsFakeClient(i)) continue; - + char thisMsg[256]; strcopy(thisMsg, sizeof(thisMsg), message); - + if (g_bMathGameHasQuestion[i]) FormatEx(thisMsg, sizeof(thisMsg), "%s\n[ %s ]", thisMsg, g_sMathGameQuestion[i]); - + SendHudText(i, thisMsg); } - + g_iMathGameTime++; return Plugin_Continue; } -/* MathGame Settings */ public Action Cmd_MathGameSettings(int client, int args) { if (!client) return Plugin_Handled; - + Menu menu = new Menu(Menu_MathGameSettings); menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); @@ -429,7 +494,7 @@ public Action Cmd_MathGameSettings(int client, int args) menu.ExitBackButton = true; menu.Display(client, MENU_TIME_FOREVER); - + return Plugin_Handled; } @@ -439,7 +504,7 @@ int Menu_MathGameSettings(Menu menu, MenuAction action, int param1, int param2) { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) @@ -464,4 +529,4 @@ void MathGame_ResetPlayers() g_iMathGameFailedAnswers[i] = 0; g_bMathGameDisableRespawn[i] = false; } -} \ No newline at end of file +} diff --git a/addons/sourcemod/scripting/Fun_Modes/PullGame.sp b/addons/sourcemod/scripting/Fun_Modes/PullGame.sp index 9d2ad21..34836de 100644 --- a/addons/sourcemod/scripting/Fun_Modes/PullGame.sp +++ b/addons/sourcemod/scripting/Fun_Modes/PullGame.sp @@ -1,25 +1,27 @@ /* (). FunModes V2: - + @file PullGame.sp - @Usage Functions for the PullGame Mode. - + @Usage Functions for the PullGame Mode. */ #pragma semicolon 1 #pragma newdecls required -ModeInfo g_PullGameInfo; +static int g_iPullGameIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iPullGameIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_PullGameInfo +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] -#define PULLGAME_CONVAR_TIMER_INTERVAL 0 -#define PULLGAME_CONVAR_SPEED 1 -#define PULLGAME_CONVAR_PULL_TIME 2 -#define PULLGAME_CONVAR_RANDOMS_ZOMBIES 3 -#define PULLGAME_CONVAR_RANDOMS_HUMANS 4 -#define PULLGAME_CONVAR_TOGGLE 5 +#define PULLGAME_CONVAR_TIMER_INTERVAL 0 +#define PULLGAME_CONVAR_SPEED 1 +#define PULLGAME_CONVAR_PULL_TIME 2 +#define PULLGAME_CONVAR_RANDOMS_ZOMBIES 3 +#define PULLGAME_CONVAR_RANDOMS_HUMANS 4 +#define PULLGAME_CONVAR_TOGGLE 5 float g_fPullLastUseTime[MAXPLAYERS + 1]; bool g_bPullState[MAXPLAYERS + 1]; @@ -28,80 +30,115 @@ float g_fPullOriginalDistance[MAXPLAYERS + 1]; int g_iPullClientTarget[MAXPLAYERS + 1]; bool g_bPullGameHas[MAXPLAYERS + 1]; -float g_fPullGameSpeed; +float g_fPullGame_TimerInterval; +float g_fPullGame_Speed; +float g_fPullGame_PullTime; +int g_iPullGame_RandomsZombies; +int g_iPullGame_RandomsHumans; +bool g_bPullGame_Enabled; Handle g_hPullGameTimer; stock void OnPluginStart_PullGame() { + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + THIS_MODE_INFO.name = "PullGame"; THIS_MODE_INFO.tag = "{gold}[FunModes-PullGame]{lightgreen}"; - - /* COMMANDS */ - /* THESE ARE THE STANDARD COMMANDS THAT ALL MODES SHOULD HAVE */ + RegAdminCmd("sm_fm_pullgame", Cmd_PullGameToggle, ADMFLAG_CONVARS, "Turn PullGame Mode On/Off"); RegAdminCmd("sm_pullgame_settings", Cmd_PullGameSettings, ADMFLAG_CONVARS, "Open PullGame Sttings Menu"); - /* CONVARS */ DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, PULLGAME_CONVAR_TIMER_INTERVAL, - "sm_pullgame_timer_interval", "30.0", "After how many seconds to keep giving pull access to a random zm?", - ("15.0,30.0,40.0,60.0"), "float" + PULLGAME_CONVAR_TIMER_INTERVAL, "sm_pullgame_timer_interval", + "30.0", "After how many seconds to keep giving pull access to a random zm?", + ("15.0,30.0,40.0,60.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[PULLGAME_CONVAR_TIMER_INTERVAL].HookChange(PullGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, PULLGAME_CONVAR_SPEED, - "sm_pullgame_speed", "300.0", "Pulling Speed Value", - ("100.0,300.0,500.0,700.0,1000.0"), "float" + PULLGAME_CONVAR_SPEED, "sm_pullgame_speed", + "300.0", "Pulling Speed Value", + ("100.0,300.0,500.0,700.0,1000.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[PULLGAME_CONVAR_SPEED].HookChange(PullGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, PULLGAME_CONVAR_PULL_TIME, - "sm_pullgame_pull_time", "15.0", "Pulling Time", - ("10.0,15.0,30.0,40.0,55.0"), "float" + PULLGAME_CONVAR_PULL_TIME, "sm_pullgame_pull_time", + "15.0", "Pulling Time", + ("10.0,15.0,30.0,40.0,55.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[PULLGAME_CONVAR_PULL_TIME].HookChange(PullGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, PULLGAME_CONVAR_RANDOMS_HUMANS, - "sm_pullgame_humans_count", "3", "Pulling Time", - ("1,2,3,4,5,6,7"), "int" + PULLGAME_CONVAR_RANDOMS_HUMANS, "sm_pullgame_humans_count", + "3", "How many humans to give pull access to?", + ("1,2,3,4,5,6,7"), CONVAR_INT ); - + THIS_MODE_INFO.cvars[PULLGAME_CONVAR_RANDOMS_HUMANS].HookChange(PullGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, PULLGAME_CONVAR_RANDOMS_ZOMBIES, - "sm_pullgame_zombies_count", "3", "Pulling Time", - ("1,2,3,4,5,6,7"), "int" + PULLGAME_CONVAR_RANDOMS_ZOMBIES, "sm_pullgame_zombies_count", + "3", "How many zombies to give pull access to?", + ("1,2,3,4,5,6,7"), CONVAR_INT ); - + THIS_MODE_INFO.cvars[PULLGAME_CONVAR_RANDOMS_ZOMBIES].HookChange(PullGame_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, PULLGAME_CONVAR_TOGGLE, - "sm_pullgame_enable", "1", "Enable/Disable PullGame Mode (This differs from turning it on/off)", - ("0,1"), "bool" + PULLGAME_CONVAR_TOGGLE, "sm_pullgame_enable", + "1", "Enable/Disable PullGame Mode (This differs from turning it on/off)", + ("0,1"), CONVAR_BOOL ); - + THIS_MODE_INFO.cvars[PULLGAME_CONVAR_TOGGLE].HookChange(PullGame_OnConVarChange); + THIS_MODE_INFO.enableIndex = PULLGAME_CONVAR_TOGGLE; - - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; - - THIS_MODE_INFO.cvarInfo[PULLGAME_CONVAR_TOGGLE].cvar.AddChangeHook(OnPullGameModeToggle); - - g_fPullGameSpeed = THIS_MODE_INFO.cvarInfo[PULLGAME_CONVAR_SPEED].cvar.FloatValue; - THIS_MODE_INFO.cvarInfo[PULLGAME_CONVAR_SPEED].cvar.AddChangeHook(OnPullGameSpeedChange); } -void OnPullGameModeToggle(ConVar cvar, const char[] oldValue, const char[] newValue) +void InitCvarsValues_PullGame() { - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + int modeIndex = THIS_MODE_INFO.index; + + g_fPullGame_TimerInterval = _FUNMODES_CVAR_GET_VALUE(modeIndex, PULLGAME_CONVAR_TIMER_INTERVAL, Float); + g_fPullGame_Speed = _FUNMODES_CVAR_GET_VALUE(modeIndex, PULLGAME_CONVAR_SPEED, Float); + g_fPullGame_PullTime = _FUNMODES_CVAR_GET_VALUE(modeIndex, PULLGAME_CONVAR_PULL_TIME, Float); + g_iPullGame_RandomsZombies = _FUNMODES_CVAR_GET_VALUE(modeIndex, PULLGAME_CONVAR_RANDOMS_ZOMBIES, Int); + g_iPullGame_RandomsHumans = _FUNMODES_CVAR_GET_VALUE(modeIndex, PULLGAME_CONVAR_RANDOMS_HUMANS, Int); + g_bPullGame_Enabled = _FUNMODES_CVAR_GET_VALUE(modeIndex, PULLGAME_CONVAR_TOGGLE, Bool); } -void OnPullGameSpeedChange(ConVar cvar, const char[] oldValue, const char[] newValue) +void PullGame_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) { - g_fPullGameSpeed = cvar.FloatValue; + switch (cvarIndex) + { + case PULLGAME_CONVAR_TIMER_INTERVAL: + g_fPullGame_TimerInterval = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case PULLGAME_CONVAR_SPEED: + g_fPullGame_Speed = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case PULLGAME_CONVAR_PULL_TIME: + g_fPullGame_PullTime = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case PULLGAME_CONVAR_RANDOMS_ZOMBIES: + g_iPullGame_RandomsZombies = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + case PULLGAME_CONVAR_RANDOMS_HUMANS: + g_iPullGame_RandomsHumans = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + case PULLGAME_CONVAR_TOGGLE: + { + bool val = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bPullGame_Enabled = val; + } + } } stock void OnMapStart_PullGame() {} + stock void OnMapEnd_PullGame() { CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, false, THIS_MODE_INFO.index); @@ -119,17 +156,17 @@ stock void OnClientDisconnect_PullGame(int client) if (g_iPullClientTarget[i] == client) g_iPullClientTarget[i] = -1; } - + PullGame_ResetVariablesClient(client); } stock void ZR_OnClientInfected_PullGame(int client) { #pragma unused client - + if (!THIS_MODE_INFO.isOn) return; - + if (!g_bMotherZombie) PullGame_ToggleTimer(true); } @@ -140,6 +177,7 @@ stock void Event_RoundStart_PullGame() } stock void Event_RoundEnd_PullGame() {} + stock void Event_PlayerSpawn_PullGame(int client) { #pragma unused client @@ -157,35 +195,36 @@ stock void Event_PlayerDeath_PullGame(int client) public Action Cmd_PullGameToggle(int client, int args) { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) + if (!g_bPullGame_Enabled) { CReplyToCommand(client, "%s PullGame Mode is currently Disabled", THIS_MODE_INFO.tag); return Plugin_Handled; } - /* You can change whatever you want here */ CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, !THIS_MODE_INFO.isOn, THIS_MODE_INFO.index); - + CPrintToChatAll("%s PullGame Mode is now %s!", THIS_MODE_INFO.tag, THIS_MODE_INFO.isOn ? "On" : "Off"); - + if (THIS_MODE_INFO.isOn) { FunModes_HookEvent(g_bEvent_RoundStart, "round_start", Event_RoundStart); FunModes_HookEvent(g_bEvent_RoundEnd, "round_end", Event_RoundEnd); - + CPrintToChatAll("%s Press (F) {olive} | Flashlight {lightgreen}to use pull, only when you get selected!", THIS_MODE_INFO.tag); - - int humansCount = THIS_MODE_INFO.cvarInfo[PULLGAME_CONVAR_RANDOMS_HUMANS].cvar.IntValue; - int zombiesCount = THIS_MODE_INFO.cvarInfo[PULLGAME_CONVAR_RANDOMS_ZOMBIES].cvar.IntValue; - int interval = THIS_MODE_INFO.cvarInfo[PULLGAME_CONVAR_TIMER_INTERVAL].cvar.IntValue; - + + int humansCount = g_iPullGame_RandomsHumans; + int zombiesCount = g_iPullGame_RandomsZombies; + int interval = RoundToNearest(g_fPullGame_TimerInterval); + CPrintToChatAll("%s {olive}%d Random Humans {lightgreen}and {olive}%d Random Zombies {lightgreen}will be selected for the pullgame every %d seconds", THIS_MODE_INFO.tag, humansCount, zombiesCount, interval); - + FunModes_RestartRound(); } else + { PullGame_ToggleTimer(false); - + } + return Plugin_Handled; } @@ -194,7 +233,7 @@ public Action Cmd_PullGameSettings(int client, int args) { if (!client) return Plugin_Handled; - + Menu menu = new Menu(Menu_PullGameSettings); menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); @@ -203,7 +242,7 @@ public Action Cmd_PullGameSettings(int client, int args) menu.ExitBackButton = true; menu.Display(client, MENU_TIME_FOREVER); - + return Plugin_Handled; } @@ -213,7 +252,7 @@ int Menu_PullGameSettings(Menu menu, MenuAction action, int param1, int param2) { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) @@ -248,11 +287,11 @@ void PullGame_ResetVariables() void PullGame_ToggleTimer(bool toggle) { PullGame_ResetVariables(); - + delete g_hPullGameTimer; - + if (toggle) - g_hPullGameTimer = CreateTimer(THIS_MODE_INFO.cvarInfo[PULLGAME_CONVAR_TIMER_INTERVAL].cvar.FloatValue, Timer_PullGame, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); + g_hPullGameTimer = CreateTimer(g_fPullGame_TimerInterval, Timer_PullGame, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); } Action Timer_PullGame(Handle timer) @@ -262,32 +301,32 @@ Action Timer_PullGame(Handle timer) g_hPullGameTimer = null; return Plugin_Stop; } - - int humansMaxCount = THIS_MODE_INFO.cvarInfo[PULLGAME_CONVAR_RANDOMS_HUMANS].cvar.IntValue; - int zombiesMaxCount = THIS_MODE_INFO.cvarInfo[PULLGAME_CONVAR_RANDOMS_ZOMBIES].cvar.IntValue; - + + int humansMaxCount = g_iPullGame_RandomsHumans; + int zombiesMaxCount = g_iPullGame_RandomsZombies; + int zombies[MAXPLAYERS + 1]; int humans[MAXPLAYERS + 1]; - + int zombiesCount, humansCount; - + for (int i = 1; i <= MaxClients; i++) { if (!IsClientInGame(i) || !IsPlayerAlive(i)) continue; - + if (ZR_IsClientZombie(i)) zombies[zombiesCount++] = i; else humans[humansCount++] = i; } - + if (zombiesCount) PullGame_PickTeamRandoms(zombies, zombiesCount, 0, zombiesMaxCount); - + if (humansCount) PullGame_PickTeamRandoms(humans, humansCount, 0, humansMaxCount); - + return Plugin_Continue; } @@ -301,15 +340,15 @@ void PullGame_PickTeamRandoms(int[] arr, int len, int min, int max) { if (++min > max) break; - + int random; int index = PullGame_GetRandomFromArray(arr, len, random); if (index == -1) continue; - + arr[index] = 0; g_bPullGameHas[random] = true; - + CPrintToChat(random, "%s You have been selected to use pull! Press FlashLight button (F) Now!", THIS_MODE_INFO.tag); SendHudText(random, "[FunModes-PullGame] You have been selected to use pull! Press FlashLight button (F) Now!"); } @@ -320,21 +359,21 @@ int PullGame_GetRandomFromArray(int[] arr, int len, int &client) { int count; int[] newArr = new int[len]; - + for (int i = 0; i < len; i++) { if (arr[i] == 0) continue; - + if (g_bPullGameHas[arr[i]]) continue; - + newArr[count++] = arr[i]; } - + if (!count) return -1; - + int index = GetRandomInt(0, count - 1); client = newArr[index]; return index; @@ -345,11 +384,11 @@ stock void OnPlayerRunCmdPost_PullGame(int client, int buttons, int impulse) #pragma unused buttons if (!THIS_MODE_INFO.isOn) return; - + float time = GetGameTime(); if (g_fPullLastUseTime[client] > time) return; - + if (impulse == 100) { Cmd_Pull(client); @@ -364,29 +403,29 @@ void Cmd_Pull(int client) CPrintToChat(client, "%s You cannot use this command unless you were randomly chosen for it!", THIS_MODE_INFO.tag); return; } - + if (!IsPlayerAlive(client)) { CPrintToChat(client, "%s You have to be alive to use this command.", THIS_MODE_INFO.tag); return; } - + if (g_iPullClientTarget[client] != -1) { CPrintToChat(client, "%s You cannot use this command more than once while you are activating it.", THIS_MODE_INFO.tag); return; } - + int target = GetClientAimTarget(client); if (target == -1) { CPrintToChat(client, "%s You have to aim at a player!", THIS_MODE_INFO.tag); return; } - + bool isClientHuman = ZR_IsClientHuman(client); bool isTargetHuman = ZR_IsClientHuman(target); - + if (isClientHuman) { if (!isTargetHuman) @@ -394,29 +433,29 @@ void Cmd_Pull(int client) CPrintToChat(client, "%s You cannot target a zombie!", THIS_MODE_INFO.tag); return; } - + if (!g_bPullState[target]) { CPrintToChat(client, "%s You cannot pull a human that's not being pulled from the zombies!", THIS_MODE_INFO.tag); return; } } - + PullGame_StartGrab(client, target); } void PullGame_StartGrab(int client, int target) { g_iPullClientTarget[client] = target; - + if (!g_bPullState[target]) { g_bPullState[target] = true; g_fPullOriginalSpeed[target] = GetEntPropFloat(target, Prop_Send, "m_flMaxspeed"); SetEntPropFloat(target, Prop_Send, "m_flMaxspeed", 0.01); } - - CreateTimer(THIS_MODE_INFO.cvarInfo[PULLGAME_CONVAR_PULL_TIME].cvar.FloatValue, Timer_PullGameFinish, client, TIMER_FLAG_NO_MAPCHANGE); + + CreateTimer(g_fPullGame_PullTime, Timer_PullGameFinish, client, TIMER_FLAG_NO_MAPCHANGE); CreateTimer(0.05, PullGame_Pull_Timer, client, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); } @@ -425,26 +464,26 @@ Action Timer_PullGameFinish(Handle timer, int client) int target = g_iPullClientTarget[client]; if (target == -1) return Plugin_Stop; - + bool reset = true; for (int i = 1; i <= MaxClients; i++) { if (i == client || !IsClientInGame(i) || !IsPlayerAlive(i) || !ZR_IsClientHuman(i)) continue; - + if (g_iPullClientTarget[i] == target) { reset = false; break; } } - + if (reset) { SetEntPropFloat(target, Prop_Send, "m_flMaxspeed", g_fPullOriginalSpeed[target]); g_bPullState[target] = false; } - + g_iPullClientTarget[client] = -1; g_bPullGameHas[client] = false; return Plugin_Stop; @@ -455,23 +494,23 @@ Action PullGame_Pull_Timer(Handle timer, int client) int target = g_iPullClientTarget[client]; if (target == -1 || !IsPlayerAlive(target) || !IsPlayerAlive(client)) return Plugin_Stop; - + float clientEyePos[3], targetEyePos[3]; GetClientEyePosition(client, clientEyePos); GetClientEyePosition(target, targetEyePos); - + float distance = GetVectorDistance(clientEyePos, targetEyePos, true); if (distance > 40000.0) { float velocity[3]; SubtractVectors(clientEyePos, targetEyePos, velocity); NormalizeVector(velocity, velocity); - ScaleVector(velocity, g_fPullGameSpeed); + ScaleVector(velocity, g_fPullGame_Speed); TeleportEntity(target, _, _, velocity); } - + TE_SetupBeamPoints(clientEyePos, targetEyePos, g_iLaserBeam, 0, 0, 66, 0.2, 1.0, 10.0, 0, 0.0, {255,255,255,255}, 0); TE_SendToAll(); - + return Plugin_Continue; -} \ No newline at end of file +} diff --git a/addons/sourcemod/scripting/Fun_Modes/RealityShift.sp b/addons/sourcemod/scripting/Fun_Modes/RealityShift.sp index 61cfede..c00e562 100644 --- a/addons/sourcemod/scripting/Fun_Modes/RealityShift.sp +++ b/addons/sourcemod/scripting/Fun_Modes/RealityShift.sp @@ -1,121 +1,153 @@ + /* (). FunModes V2: - + @file RealityShift.sp - @Usage Functions for the RealityShift Mode. - + @Usage Functions for the RealityShift Mode. */ #pragma semicolon 1 #pragma newdecls required -ModeInfo g_RealityShiftInfo; +static int g_iRealityShiftIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iRealityShiftIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_RealityShiftInfo +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] -#define REALITYSHIFT_CONVAR_TIMER_INTERVAL 0 -#define REALITYSHIFT_CONVAR_MODE 1 -#define REALITYSHIFT_CONVAR_TOGGLE 2 +#define REALITYSHIFT_CONVAR_TIMER_INTERVAL 0 +#define REALITYSHIFT_CONVAR_MODE 1 +#define REALITYSHIFT_CONVAR_TOGGLE 2 Handle g_hRealityShiftTimer; int g_iRealityShiftAssigned[MAXPLAYERS + 1]; bool g_bRealityShiftSwapped[MAXPLAYERS + 1]; +float g_fRealityShift_TimerInterval; +int g_iRealityShift_Mode; +bool g_bRealityShift_Enabled; + stock void OnPluginStart_RealityShift() { - THIS_MODE_INFO.name = "RealityShift"; - THIS_MODE_INFO.tag = "{gold}[FunModes-RealityShift]{lightgreen}"; - - /* COMMANDS */ - /* THESE ARE THE STANDARD COMMANDS THAT ALL MODES SHOULD HAVE */ - RegAdminCmd("sm_fm_rs", Cmd_RealityShiftToggle, ADMFLAG_CONVARS, "Turn RealityShift Mode On/Off"); - RegAdminCmd("sm_realityshift_settings", Cmd_RealityShiftSettings, ADMFLAG_CONVARS, "Open RealityShift Sttings Menu"); - - /* CONVARS */ - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, REALITYSHIFT_CONVAR_TIMER_INTERVAL, - "sm_realityshift_timer_interval", "30.0", "After how many seconds to keep swapping positions", - ("15.0,30.0,45.0,60.0"), "float" - ); - - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, REALITYSHIFT_CONVAR_MODE, - "sm_realityshift_mode", "0", ("RealityShift Mode [0 = Random Swaps, 1 = Assigned Swaps [At round start]]"), - ("0,1"), "int" - ); - - DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, REALITYSHIFT_CONVAR_TOGGLE, - "sm_realityshift_enable", "1", "Enable/Disable RealityShift Mode (This differs from turning it on/off)", - ("0,1"), "bool" - ); - - THIS_MODE_INFO.enableIndex = REALITYSHIFT_CONVAR_TOGGLE; - - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; - - THIS_MODE_INFO.cvarInfo[REALITYSHIFT_CONVAR_TOGGLE].cvar.AddChangeHook(OnRealityShiftModeToggle); - - THIS_MODE_INFO.cvarInfo[REALITYSHIFT_CONVAR_TIMER_INTERVAL].cvar.AddChangeHook(OnRealityShiftConVarChange); - THIS_MODE_INFO.cvarInfo[REALITYSHIFT_CONVAR_MODE].cvar.AddChangeHook(OnRealityShiftConVarChange); + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + + THIS_MODE_INFO.name = "RealityShift"; + THIS_MODE_INFO.tag = "{gold}[FunModes-RealityShift]{lightgreen}"; + + RegAdminCmd("sm_fm_rs", Cmd_RealityShiftToggle, ADMFLAG_CONVARS, "Turn RealityShift Mode On/Off"); + RegAdminCmd("sm_realityshift_settings", Cmd_RealityShiftSettings, ADMFLAG_CONVARS, "Open RealityShift Sttings Menu"); + + DECLARE_FM_CVAR( + REALITYSHIFT_CONVAR_TIMER_INTERVAL, "sm_realityshift_timer_interval", + "30.0", "After how many seconds to keep swapping positions", + ("15.0,30.0,45.0,60.0"), CONVAR_FLOAT + ); + THIS_MODE_INFO.cvars[REALITYSHIFT_CONVAR_TIMER_INTERVAL].HookChange(RealityShift_OnConVarChange); + + DECLARE_FM_CVAR( + REALITYSHIFT_CONVAR_MODE, "sm_realityshift_mode", + "0", "RealityShift Mode [0 = Random Swaps 1 = Assigned Swaps [At round start]]", + ("0,1"), CONVAR_INT + ); + THIS_MODE_INFO.cvars[REALITYSHIFT_CONVAR_MODE].HookChange(RealityShift_OnConVarChange); + + DECLARE_FM_CVAR( + REALITYSHIFT_CONVAR_TOGGLE, "sm_realityshift_enable", + "1", "Enable/Disable RealityShift Mode (This differs from turning it on/off)", + ("0,1"), CONVAR_BOOL + ); + THIS_MODE_INFO.cvars[REALITYSHIFT_CONVAR_TOGGLE].HookChange(RealityShift_OnConVarChange); + + THIS_MODE_INFO.enableIndex = REALITYSHIFT_CONVAR_TOGGLE; } -void OnRealityShiftModeToggle(ConVar cvar, const char[] oldValue, const char[] newValue) +void InitCvarsValues_RealityShift() { - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + int modeIndex = THIS_MODE_INFO.index; + + g_fRealityShift_TimerInterval = + _FUNMODES_CVAR_GET_VALUE(modeIndex, REALITYSHIFT_CONVAR_TIMER_INTERVAL, Float); + + g_iRealityShift_Mode = + _FUNMODES_CVAR_GET_VALUE(modeIndex, REALITYSHIFT_CONVAR_MODE, Int); + + g_bRealityShift_Enabled = + _FUNMODES_CVAR_GET_VALUE(modeIndex, REALITYSHIFT_CONVAR_TOGGLE, Bool); } -void OnRealityShiftConVarChange(ConVar cvar, const char[] oldValue, const char[] newValue) +void RealityShift_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) { - if (!THIS_MODE_INFO.isOn) - return; - - if (cvar == THIS_MODE_INFO.cvarInfo[REALITYSHIFT_CONVAR_TIMER_INTERVAL].cvar) - { - RealityShift_StartTimer(cvar.FloatValue); - return; - } - - if (cvar.IntValue == 1) - RealityShift_AssignPlayers(true); + switch (cvarIndex) + { + case REALITYSHIFT_CONVAR_TIMER_INTERVAL: + { + g_fRealityShift_TimerInterval = + _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + if (THIS_MODE_INFO.isOn) + RealityShift_StartTimer(g_fRealityShift_TimerInterval); + } + + case REALITYSHIFT_CONVAR_MODE: + { + g_iRealityShift_Mode = + _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + if (THIS_MODE_INFO.isOn && g_iRealityShift_Mode == 1) + RealityShift_AssignPlayers(true); + } + + case REALITYSHIFT_CONVAR_TOGGLE: + { + bool val = + _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bRealityShift_Enabled = val; + } + } } stock void OnMapStart_RealityShift() {} + stock void OnMapEnd_RealityShift() { - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, false, THIS_MODE_INFO.index); - - g_hRealityShiftTimer = null; + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, false, THIS_MODE_INFO.index); + g_hRealityShiftTimer = null; } stock void OnClientPutInServer_RealityShift(int client) { - g_iRealityShiftAssigned[client] = 0; - g_bRealityShiftSwapped[client] = false; + g_iRealityShiftAssigned[client] = 0; + g_bRealityShiftSwapped[client] = false; } stock void OnClientDisconnect_RealityShift(int client) { - g_iRealityShiftAssigned[client] = 0; - g_bRealityShiftSwapped[client] = false; + g_iRealityShiftAssigned[client] = 0; + g_bRealityShiftSwapped[client] = false; } stock void ZR_OnClientInfected_RealityShift(int client) { - #pragma unused client - if (!THIS_MODE_INFO.isOn) - return; - - if (!g_bMotherZombie && g_hRealityShiftTimer == null) - { - RealityShift_StartTimer(THIS_MODE_INFO.cvarInfo[REALITYSHIFT_CONVAR_TIMER_INTERVAL].cvar.FloatValue); - if (THIS_MODE_INFO.cvarInfo[REALITYSHIFT_CONVAR_MODE].cvar.IntValue == 1) - RealityShift_AssignPlayers(true); - } + #pragma unused client + + if (!THIS_MODE_INFO.isOn) + return; + + if (!g_bMotherZombie && g_hRealityShiftTimer == null) + { + RealityShift_StartTimer(g_fRealityShift_TimerInterval); + + if (g_iRealityShift_Mode == 1) + RealityShift_AssignPlayers(true); + } } stock void Event_RoundStart_RealityShift() {} @@ -137,215 +169,318 @@ stock void Event_PlayerDeath_RealityShift(int client) public Action Cmd_RealityShiftToggle(int client, int args) { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) - { - CReplyToCommand(client, "%s RealityShift Mode is currently Disabled", THIS_MODE_INFO.tag); - return Plugin_Handled; - } - - /* You can change whatever you want here */ - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, !THIS_MODE_INFO.isOn, THIS_MODE_INFO.index); - - CPrintToChatAll("%s RealityShift Mode is now %s!", THIS_MODE_INFO.tag, THIS_MODE_INFO.isOn ? "On" : "Off"); - - if (THIS_MODE_INFO.isOn) - { - FunModes_HookEvent(g_bEvent_RoundStart, "round_start", Event_RoundStart); - FunModes_HookEvent(g_bEvent_RoundEnd, "round_end", Event_RoundEnd); - - CPrintToChatAll("%s Each human will be swappaed their position with another one!", THIS_MODE_INFO.tag); - - int mode = THIS_MODE_INFO.cvarInfo[REALITYSHIFT_CONVAR_MODE].cvar.IntValue; - if (mode == 0) - CPrintToChatAll("%s The positions will be swapped randomly.", THIS_MODE_INFO.tag); - - int interval = THIS_MODE_INFO.cvarInfo[REALITYSHIFT_CONVAR_TIMER_INTERVAL].cvar.IntValue; - CPrintToChatAll("%s Positions will be swapped every {olive}%d seconds!", THIS_MODE_INFO.tag, interval); - - FunModes_RestartRound(); - } - else - delete g_hRealityShiftTimer; - - return Plugin_Handled; + if (!g_bRealityShift_Enabled) + { + CReplyToCommand(client, "%s RealityShift Mode is currently Disabled", THIS_MODE_INFO.tag); + return Plugin_Handled; + } + + CHANGE_MODE_INFO( + THIS_MODE_INFO, + isOn, + !THIS_MODE_INFO.isOn, + THIS_MODE_INFO.index + ); + + CPrintToChatAll( + "%s RealityShift Mode is now %s!", + THIS_MODE_INFO.tag, + THIS_MODE_INFO.isOn ? "On" : "Off" + ); + + if (THIS_MODE_INFO.isOn) + { + FunModes_HookEvent( + g_bEvent_RoundStart, + "round_start", + Event_RoundStart + ); + + FunModes_HookEvent( + g_bEvent_RoundEnd, + "round_end", + Event_RoundEnd + ); + + CPrintToChatAll( + "%s Each human will be swapped with another one!", + THIS_MODE_INFO.tag + ); + + if (g_iRealityShift_Mode == 0) + { + CPrintToChatAll( + "%s The positions will be swapped randomly.", + THIS_MODE_INFO.tag + ); + } + + int interval = RoundToNearest(g_fRealityShift_TimerInterval); + + CPrintToChatAll( + "%s Positions will be swapped every {olive}%d seconds!", + THIS_MODE_INFO.tag, + interval + ); + + FunModes_RestartRound(); + } + else + { + delete g_hRealityShiftTimer; + } + + return Plugin_Handled; } -/* RealityShift Settings */ public Action Cmd_RealityShiftSettings(int client, int args) { - if (!client) - return Plugin_Handled; - - Menu menu = new Menu(Menu_RealityShiftSettings); + if (!client) + return Plugin_Handled; + + Menu menu = new Menu(Menu_RealityShiftSettings); + + menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); - menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); + menu.AddItem(NULL_STRING, "Show Cvars\n"); - menu.AddItem(NULL_STRING, "Show Cvars\n"); + menu.ExitBackButton = true; - menu.ExitBackButton = true; - menu.Display(client, MENU_TIME_FOREVER); - - return Plugin_Handled; + menu.Display(client, MENU_TIME_FOREVER); + + return Plugin_Handled; } int Menu_RealityShiftSettings(Menu menu, MenuAction action, int param1, int param2) { - switch (action) - { - case MenuAction_End: - delete menu; - - case MenuAction_Cancel: - { - if (param2 == MenuCancel_ExitBack) - DisplayModeInfo(param1, g_iPreviousModeIndex[param1]); - } - - case MenuAction_Select: - { - ShowCvarsInfo(param1, THIS_MODE_INFO); - } - } - - return 0; + switch (action) + { + case MenuAction_End: + delete menu; + + case MenuAction_Cancel: + { + if (param2 == MenuCancel_ExitBack) + DisplayModeInfo(param1, g_iPreviousModeIndex[param1]); + } + + case MenuAction_Select: + { + ShowCvarsInfo(param1, THIS_MODE_INFO); + } + } + + return 0; } void RealityShift_StartTimer(float interval) { - for (int i = 1; i <= MaxClients; i++) - g_iRealityShiftAssigned[i] = 0; - - delete g_hRealityShiftTimer; - g_hRealityShiftTimer = CreateTimer(interval, RealityShift_Timer, _, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT); + for (int i = 1; i <= MaxClients; i++) + g_iRealityShiftAssigned[i] = 0; + + delete g_hRealityShiftTimer; + + g_hRealityShiftTimer = + CreateTimer( + interval, + RealityShift_Timer, + _, + TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT + ); } Action RealityShift_Timer(Handle timer) { - if (g_bRoundEnd || !g_bMotherZombie) - { - g_hRealityShiftTimer = null; - return Plugin_Stop; - } - - int mode = THIS_MODE_INFO.cvarInfo[REALITYSHIFT_CONVAR_MODE].cvar.IntValue; - RealityShift_AssignPlayers(_, mode == 0); - - return Plugin_Continue; + if (g_bRoundEnd || !g_bMotherZombie) + { + g_hRealityShiftTimer = null; + return Plugin_Stop; + } + + RealityShift_AssignPlayers(_, g_iRealityShift_Mode == 0); + + return Plugin_Continue; } int GetRandomClientFromArray(int[] arr, int len, int &client) { - int count; - int[] newArr = new int[len]; - - for (int i = 0; i < len; i++) - { - if (arr[i] == 0) - continue; - - if (g_bRealityShiftSwapped[arr[i]]) - continue; - - newArr[count++] = arr[i]; - } - - if (!count) - return -1; - - int index = GetRandomInt(0, count - 1); - client = newArr[index]; - return index; + int count; + + int[] newArr = new int[len]; + + for (int i = 0; i < len; i++) + { + if (arr[i] == 0) + continue; + + if (g_bRealityShiftSwapped[arr[i]]) + continue; + + newArr[count++] = arr[i]; + } + + if (!count) + return -1; + + int index = GetRandomInt(0, count - 1); + + client = newArr[index]; + + return index; } void RealityShift_AssignPlayers(bool saveOnly = false, bool random = true) { - int clients[MAXPLAYERS + 1], count; - - for (int i = 1; i <= MaxClients; i++) - { - if (!IsClientInGame(i) || !IsPlayerAlive(i) || !ZR_IsClientHuman(i)) - continue; - - g_bRealityShiftSwapped[i] = false; - clients[count++] = i; - - if (!random) - { - int assignedTo = GetClientOfUserId(g_iRealityShiftAssigned[i]); - if (!assignedTo || !IsClientInGame(assignedTo) || !IsPlayerAlive(assignedTo) || !ZR_IsClientHuman(assignedTo)) - { - g_bRealityShiftSwapped[i] = false; - g_iRealityShiftAssigned[i] = 0; - continue; - } - - RealityShift_SwapPositions(i, assignedTo); - } - } - - if (!saveOnly && !random) - return; - - int assignmentsCount = count / 2; - if (assignmentsCount <= 1) - return; - - for (int i = 0; i < assignmentsCount; i++) - { - int client, assignedTo; - - int index = GetRandomClientFromArray(clients, count, client); - if (index == -1) - continue; - - clients[index] = 0; - - index = GetRandomClientFromArray(clients, count, assignedTo); - if (index == -1) - continue; - - clients[index] = 0; - - if (saveOnly) - { - g_iRealityShiftAssigned[client] = GetClientUserId(assignedTo); - g_iRealityShiftAssigned[assignedTo] = GetClientUserId(client); - CPrintToChat(client, "%s You will be swapping positions with {olive}%N {lightgreen}the whole round!", THIS_MODE_INFO.tag, assignedTo); - CPrintToChat(assignedTo, "%s You will be swapping positions with {olive}%N {lightgreen}the whole round!", THIS_MODE_INFO.tag, client); - } - else - { - if (!random) - continue; - - if (g_bRealityShiftSwapped[client] || g_bRealityShiftSwapped[assignedTo]) - continue; - - RealityShift_SwapPositions(client, assignedTo); - } - } + int clients[MAXPLAYERS + 1]; + + int count; + + for (int i = 1; i <= MaxClients; i++) + { + if (!IsClientInGame(i) + || !IsPlayerAlive(i) + || !ZR_IsClientHuman(i)) + continue; + + g_bRealityShiftSwapped[i] = false; + + clients[count++] = i; + + if (!random) + { + int assignedTo = + GetClientOfUserId(g_iRealityShiftAssigned[i]); + + if (!assignedTo + || !IsClientInGame(assignedTo) + || !IsPlayerAlive(assignedTo) + || !ZR_IsClientHuman(assignedTo)) + { + g_bRealityShiftSwapped[i] = false; + + g_iRealityShiftAssigned[i] = 0; + + continue; + } + + RealityShift_SwapPositions(i, assignedTo); + } + } + + if (!saveOnly && !random) + return; + + int assignmentsCount = count / 2; + + if (assignmentsCount <= 1) + return; + + for (int i = 0; i < assignmentsCount; i++) + { + int client, assignedTo; + + int index = + GetRandomClientFromArray(clients, count, client); + + if (index == -1) + continue; + + clients[index] = 0; + + index = + GetRandomClientFromArray(clients, count, assignedTo); + + if (index == -1) + continue; + + clients[index] = 0; + + if (saveOnly) + { + g_iRealityShiftAssigned[client] = + GetClientUserId(assignedTo); + + g_iRealityShiftAssigned[assignedTo] = + GetClientUserId(client); + + CPrintToChat( + client, + "%s You will swap with {olive}%N {lightgreen} all round!", + THIS_MODE_INFO.tag, + assignedTo + ); + + CPrintToChat( + assignedTo, + "%s You will swap with {olive}%N {lightgreen} all round!", + THIS_MODE_INFO.tag, + client + ); + } + else + { + if (!random) + continue; + + if (g_bRealityShiftSwapped[client] + || g_bRealityShiftSwapped[assignedTo]) + continue; + + RealityShift_SwapPositions( + client, + assignedTo + ); + } + } } void RealityShift_SwapPositions(int client, int assignedTo) { - if (client == assignedTo) - return; - - if (g_bRealityShiftSwapped[client] || g_bRealityShiftSwapped[assignedTo]) - return; - - float clientOrigin[3], assignedToOrigin[3], clientEyeAngles[3], assignedToEyeAngles[3]; - GetClientAbsOrigin(client, clientOrigin); - GetClientAbsOrigin(assignedTo, assignedToOrigin); - GetClientEyeAngles(client, clientEyeAngles); - GetClientEyeAngles(assignedTo, assignedToEyeAngles); - - TeleportEntity(client, assignedToOrigin, assignedToEyeAngles); - TeleportEntity(assignedTo, clientOrigin, clientEyeAngles); - - CPrintToChat(client, "%s You have swapped positions with {olive}%N", THIS_MODE_INFO.tag, assignedTo); - CPrintToChat(assignedTo, "%s You have swapped position with {olive}%N", THIS_MODE_INFO.tag, client); - - g_bRealityShiftSwapped[client] = true; - g_bRealityShiftSwapped[assignedTo] = true; -} \ No newline at end of file + if (client == assignedTo) + return; + + if (g_bRealityShiftSwapped[client] + || g_bRealityShiftSwapped[assignedTo]) + return; + + float clientOrigin[3]; + float assignedToOrigin[3]; + + float clientEyeAngles[3]; + float assignedToEyeAngles[3]; + + GetClientAbsOrigin(client, clientOrigin); + GetClientAbsOrigin(assignedTo, assignedToOrigin); + + GetClientEyeAngles(client, clientEyeAngles); + GetClientEyeAngles(assignedTo, assignedToEyeAngles); + + TeleportEntity( + client, + assignedToOrigin, + assignedToEyeAngles + ); + + TeleportEntity( + assignedTo, + clientOrigin, + clientEyeAngles + ); + + CPrintToChat( + client, + "%s You swapped positions with {olive}%N", + THIS_MODE_INFO.tag, + assignedTo + ); + + CPrintToChat( + assignedTo, + "%s You swapped positions with {olive}%N", + THIS_MODE_INFO.tag, + client + ); + + g_bRealityShiftSwapped[client] = true; + g_bRealityShiftSwapped[assignedTo] = true; +} diff --git a/addons/sourcemod/scripting/Fun_Modes/RedLightGreenLight.sp b/addons/sourcemod/scripting/Fun_Modes/RedLightGreenLight.sp index 8bdd109..fd1029e 100644 --- a/addons/sourcemod/scripting/Fun_Modes/RedLightGreenLight.sp +++ b/addons/sourcemod/scripting/Fun_Modes/RedLightGreenLight.sp @@ -1,10 +1,20 @@ +/* + (). FunModes V2: + + @file RLGL.sp + @Usage Functions for the RedLightGreenLight Mode. +*/ + #pragma semicolon 1 #pragma newdecls required -ModeInfo g_RLGLInfo; +static int g_iRLGLIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iRLGLIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_RLGLInfo +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] bool g_bEnableDetecting; @@ -17,108 +27,170 @@ Handle g_hRLGLTimer; Handle g_hRLGLDetectTimer; Handle g_hRLGLWarningTimer; -#define RLGL_CONVAR_TIME_BETWEEN_DAMAGE 0 -#define RLGL_CONVAR_FREEZE_TIME 1 -#define RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MIN 2 -#define RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MAX 3 -#define RLGL_CONVAR_DAMAGE 4 -#define RLGL_CONVAR_WARNING_TIME 5 -#define RLGL_CONVAR_ZOMBIES_SPEED 6 -#define RLGL_CONVAR_COUNTDOWN_FOLDER 7 -#define RLGL_CONVAR_TOGGLE 8 - -/* CALLED on Plugin Start */ +#define RLGL_CONVAR_TIME_BETWEEN_DAMAGE 0 +#define RLGL_CONVAR_FREEZE_TIME 1 +#define RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MIN 2 +#define RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MAX 3 +#define RLGL_CONVAR_DAMAGE 4 +#define RLGL_CONVAR_WARNING_TIME 5 +#define RLGL_CONVAR_ZOMBIES_SPEED 6 +#define RLGL_CONVAR_COUNTDOWN_FOLDER 7 +#define RLGL_CONVAR_TOGGLE 8 + +float g_fRLGL_TimeBetweenDamage; +float g_fRLGL_FreezeTime; +float g_fRLGL_RedMin; +float g_fRLGL_RedMax; +float g_fRLGL_Damage; +float g_fRLGL_WarningTime; +float g_fRLGL_ZombieSpeed; +bool g_bRLGL_Enabled; + stock void OnPluginStart_RLGL() { + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + THIS_MODE_INFO.name = "RLGL"; THIS_MODE_INFO.tag = "{gold}[FunModes-RedLightGreenLight]{lightgreen}"; - /* ADMIN COMMANDS */ RegAdminCmd("sm_fm_rlgl", Cmd_RLGLToggle, ADMFLAG_CONVARS, "Enable/Disable RedLightGreenLight mode."); RegAdminCmd("sm_rlgl_settings", Cmd_RLGLSettings, ADMFLAG_CONVARS, "Open RLGL Settings Menu"); - - /* CONVARS */ + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, RLGL_CONVAR_TIME_BETWEEN_DAMAGE, - "sm_rlgl_time_between_damage", "0.1", "The timer interval for player to detect their movement", - ("0.1,0.3,0.5,0.8"), "float" + RLGL_CONVAR_TIME_BETWEEN_DAMAGE, "sm_rlgl_time_between_damage", + "0.1", "The timer interval for player to detect their movement", + ("0.1,0.3,0.5,0.8"), CONVAR_FLOAT ); + THIS_MODE_INFO.cvars[RLGL_CONVAR_TIME_BETWEEN_DAMAGE].HookChange(RLGL_OnConVarChange); DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, RLGL_CONVAR_FREEZE_TIME, - "sm_rlgl_freeze_time", "5.0", "How many seconds the movement detection should be disabled after", - ("2.0,5.0,10.0,15.0"), "float" + RLGL_CONVAR_FREEZE_TIME, "sm_rlgl_freeze_time", + "5.0", "How many seconds the movement detection should be disabled after", + ("2.0,5.0,10.0,15.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[RLGL_CONVAR_FREEZE_TIME].HookChange(RLGL_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MIN, - "sm_rlgl_time_between_redlights_min", "20.0", "After how many seconds to keep repeating the redlights (MIN VALUE)", - ("20.0,30.0,40.0,60.0"), "float" + RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MIN, "sm_rlgl_time_between_redlights_min", + "20.0", "After how many seconds to keep repeating the redlights (MIN VALUE)", + ("20.0,30.0,40.0,60.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MIN].HookChange(RLGL_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MAX, - "sm_rlgl_time_between_redlights_max", "30.0", "After how many seconds to keep repeating the redlights (MAX VALUE, SET TO 0 to disable min/max)", - ("25.0,35.0,45.0,65.0"), "float" + RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MAX, "sm_rlgl_time_between_redlights_max", + "30.0", "After how many seconds to keep repeating the redlights (MAX VALUE, SET TO 0 to disable min/max)", + ("25.0,35.0,45.0,65.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MAX].HookChange(RLGL_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, RLGL_CONVAR_DAMAGE, - "sm_rlgl_damage", "5.0", "Damage to apply to the player that is moving while its a red light", - ("1.0,2.0,3.0,4.0,5.0"), "float" + RLGL_CONVAR_DAMAGE, "sm_rlgl_damage", + "5.0", "Damage to apply to the player that is moving while its a red light", + ("1.0,2.0,3.0,4.0,5.0"), CONVAR_FLOAT ); + THIS_MODE_INFO.cvars[RLGL_CONVAR_DAMAGE].HookChange(RLGL_OnConVarChange); DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, RLGL_CONVAR_WARNING_TIME, - "sm_rlgl_warning_time", "8.0", "Time in seconds to warn the players before red light is on", - ("5.0,8.0,10.0,15.0,20.0"), "float" + RLGL_CONVAR_WARNING_TIME, "sm_rlgl_warning_time", + "8.0", "Time in seconds to warn the players before red light is on", + ("5.0,8.0,10.0,15.0,20.0"), CONVAR_FLOAT ); + THIS_MODE_INFO.cvars[RLGL_CONVAR_WARNING_TIME].HookChange(RLGL_OnConVarChange); DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, RLGL_CONVAR_ZOMBIES_SPEED, - "sm_rlgl_zombies_speed", "0.5", ("Zombies speed during red light, if set to 0 then it is disabled"), - ("0.0,0.2,0.5,0.8,1.5,2.0"), "float" + RLGL_CONVAR_ZOMBIES_SPEED, "sm_rlgl_zombies_speed", + "0.5", "Zombies speed during red light if set to 0 then it is disabled", + ("0.0,0.2,0.5,0.8,1.5,2.0"), CONVAR_FLOAT ); + THIS_MODE_INFO.cvars[RLGL_CONVAR_ZOMBIES_SPEED].HookChange(RLGL_OnConVarChange); DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, RLGL_CONVAR_COUNTDOWN_FOLDER, - "sm_rlgl_countdown_folder", "zr/countdown/$.mp3", "Countdown folder and the files that can be used for sound", - "", "" + RLGL_CONVAR_COUNTDOWN_FOLDER, "sm_rlgl_countdown_folder", + "zr/countdown/$.mp3", "Countdown folder and the files that can be used for sound", + "", CONVAR_STRING ); + THIS_MODE_INFO.cvars[RLGL_CONVAR_COUNTDOWN_FOLDER].HookChange(RLGL_OnConVarChange); DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, RLGL_CONVAR_TOGGLE, - "sm_rlgl_enable", "1", "Enable/Disable the RLGL Mode (This differes from turning it on/off)", - ("0,1"), "bool" + RLGL_CONVAR_TOGGLE, "sm_rlgl_enable", + "1", "Enable/Disable the RLGL Mode (This differs from turning it on/off)", + ("0,1"), CONVAR_BOOL ); - - THIS_MODE_INFO.enableIndex = RLGL_CONVAR_TOGGLE; + THIS_MODE_INFO.cvars[RLGL_CONVAR_TOGGLE].HookChange(RLGL_OnConVarChange); - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; + THIS_MODE_INFO.enableIndex = RLGL_CONVAR_TOGGLE; +} - THIS_MODE_INFO.cvarInfo[RLGL_CONVAR_TOGGLE].cvar.AddChangeHook(OnRLGLModeToggle); +void InitCvarsValues_RLGL() +{ + int modeIndex = THIS_MODE_INFO.index; + + g_fRLGL_TimeBetweenDamage = _FUNMODES_CVAR_GET_VALUE(modeIndex, RLGL_CONVAR_TIME_BETWEEN_DAMAGE, Float); + g_fRLGL_FreezeTime = _FUNMODES_CVAR_GET_VALUE(modeIndex, RLGL_CONVAR_FREEZE_TIME, Float); + g_fRLGL_RedMin = _FUNMODES_CVAR_GET_VALUE(modeIndex, RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MIN, Float); + g_fRLGL_RedMax = _FUNMODES_CVAR_GET_VALUE(modeIndex, RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MAX, Float); + g_fRLGL_Damage = _FUNMODES_CVAR_GET_VALUE(modeIndex, RLGL_CONVAR_DAMAGE, Float); + g_fRLGL_WarningTime = _FUNMODES_CVAR_GET_VALUE(modeIndex, RLGL_CONVAR_WARNING_TIME, Float); + g_fRLGL_ZombieSpeed = _FUNMODES_CVAR_GET_VALUE(modeIndex, RLGL_CONVAR_ZOMBIES_SPEED, Float); + g_bRLGL_Enabled = _FUNMODES_CVAR_GET_VALUE(modeIndex, RLGL_CONVAR_TOGGLE, Bool); + + countDownPath = _FUNMODES_CVAR_GET_VALUE(modeIndex, RLGL_CONVAR_COUNTDOWN_FOLDER, String); } -void OnRLGLModeToggle(ConVar cvar, const char[] newValue, const char[] oldValue) +void RLGL_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) { - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + switch (cvarIndex) + { + case RLGL_CONVAR_TIME_BETWEEN_DAMAGE: + g_fRLGL_TimeBetweenDamage = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case RLGL_CONVAR_FREEZE_TIME: + g_fRLGL_FreezeTime = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MIN: + g_fRLGL_RedMin = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MAX: + g_fRLGL_RedMax = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case RLGL_CONVAR_DAMAGE: + g_fRLGL_Damage = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case RLGL_CONVAR_WARNING_TIME: + g_fRLGL_WarningTime = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case RLGL_CONVAR_ZOMBIES_SPEED: + g_fRLGL_ZombieSpeed = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case RLGL_CONVAR_COUNTDOWN_FOLDER: + countDownPath = _FUNMODES_CVAR_GET_VALUE(modeIndex, RLGL_CONVAR_COUNTDOWN_FOLDER, String); + + case RLGL_CONVAR_TOGGLE: + { + bool val = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bRLGL_Enabled = val; + } + } } -stock void OnMapStart_RLGL() +stock void OnMapStart_RLGL() { - THIS_MODE_INFO.cvarInfo[RLGL_CONVAR_COUNTDOWN_FOLDER].cvar.GetString(countDownPath, sizeof(countDownPath)); - - for (int i = 1; i <= THIS_MODE_INFO.cvarInfo[RLGL_CONVAR_WARNING_TIME].cvar.IntValue; i++) + countDownPath = _FUNMODES_CVAR_GET_VALUE(THIS_MODE_INFO.index, RLGL_CONVAR_COUNTDOWN_FOLDER, String); + PrintToChatAll("countdown path: %s", countDownPath); + for (int i = 1; i <= RoundToNearest(g_fRLGL_WarningTime); i++) { char sndPath[PLATFORM_MAX_PATH]; strcopy(sndPath, sizeof(sndPath), countDownPath); - + char numStr[3]; IntToString(i, numStr, sizeof(numStr)); ReplaceString(sndPath, sizeof(sndPath), "$", numStr); - + PrecacheSound(sndPath); FormatEx(sndPath, sizeof(sndPath), "sound/%s", sndPath); AddFileToDownloadsTable(sndPath); @@ -149,12 +221,11 @@ stock void ZR_OnClientInfected_RLGL(int client) if (!(THIS_MODE_INFO.isOn && g_bEnableDetecting)) return; - float speed = THIS_MODE_INFO.cvarInfo[RLGL_CONVAR_ZOMBIES_SPEED].cvar.FloatValue; - if (speed <= 0.0) + if (g_fRLGL_ZombieSpeed <= 0.0) return; g_fOriginalSpeed[client] = GetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue"); - SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", speed); + SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", g_fRLGL_ZombieSpeed); } stock void Event_RoundStart_RLGL() @@ -162,12 +233,13 @@ stock void Event_RoundStart_RLGL() delete g_hRLGLWarningTimer; delete g_hRLGLTimer; delete g_hRLGLDetectTimer; - + if (THIS_MODE_INFO.isOn) StartRLGLTimer(); } stock void Event_RoundEnd_RLGL() {} + stock void Event_PlayerSpawn_RLGL(int client) { #pragma unused client @@ -231,7 +303,7 @@ void ApplyFade(const char[] sColor) BfWrite bf = UserMessageToBfWrite(message); bf.WriteShort(500); bf.WriteShort(500); - bf.WriteShort(flags); + bf.WriteShort(flags); bf.WriteByte(color[0]); bf.WriteByte(color[1]); bf.WriteByte(color[2]); @@ -243,23 +315,31 @@ void ApplyFade(const char[] sColor) public Action Cmd_RLGLToggle(int client, int args) { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) + #pragma unused args + + if (!g_bRLGL_Enabled) { CReplyToCommand(client, "%s RLGL mode is currently disabled!", THIS_MODE_INFO.tag); return Plugin_Handled; } CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, !THIS_MODE_INFO.isOn, THIS_MODE_INFO.index); - CPrintToChatAll("%s Red Light Green Light is now {olive}%s{lightgreen}.", THIS_MODE_INFO.tag, (THIS_MODE_INFO.isOn) ? "Enabled" : "Disabled"); + CPrintToChatAll("%s Red Light Green Light is now {olive}%s{lightgreen}.", THIS_MODE_INFO.tag, THIS_MODE_INFO.isOn ? "Enabled" : "Disabled"); delete g_hRLGLTimer; delete g_hRLGLDetectTimer; + delete g_hRLGLWarningTimer; if (THIS_MODE_INFO.isOn) { FunModes_HookEvent(g_bEvent_RoundStart, "round_start", Event_RoundStart); StartRLGLTimer(); } + else + { + g_bEnableDetecting = false; + SetZombiesSpeed(1.0); + } return Plugin_Handled; } @@ -267,15 +347,15 @@ public Action Cmd_RLGLToggle(int client, int args) Action RLGL_Timer(Handle timer) { g_hRLGLTimer = null; - + if (!THIS_MODE_INFO.isOn) return Plugin_Stop; delete g_hRLGLWarningTimer; g_hRLGLWarningTimer = CreateTimer(1.0, RLGL_Warning_Timer, _, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT); - + StartRLGLTimer(); - + return Plugin_Stop; } @@ -288,52 +368,50 @@ Action RLGL_Warning_Timer(Handle timer) } static int timePassed; + char sMessage[256]; - FormatEx(sMessage, sizeof(sMessage), "Warning: Red Light is coming in %d seconds, Do not move after that", (THIS_MODE_INFO.cvarInfo[RLGL_CONVAR_WARNING_TIME].cvar.IntValue - timePassed)); - - int warningTime = THIS_MODE_INFO.cvarInfo[RLGL_CONVAR_WARNING_TIME].cvar.IntValue; + FormatEx(sMessage, sizeof(sMessage), "Warning: Red Light is coming in %d seconds, Do not move after that", (RoundToNearest(g_fRLGL_WarningTime) - timePassed)); char numStr[3]; - IntToString(warningTime - timePassed, numStr, sizeof(numStr)); - + IntToString(RoundToNearest(g_fRLGL_WarningTime) - timePassed, numStr, sizeof(numStr)); + char sndPath[PLATFORM_MAX_PATH]; strcopy(sndPath, sizeof(sndPath), countDownPath); ReplaceString(sndPath, sizeof(sndPath), "$", numStr); - + char sndPath2[PLATFORM_MAX_PATH]; FormatEx(sndPath2, sizeof(sndPath2), "sound/%s", sndPath); bool playSnd = FileExists(sndPath2); sndPath2[0] = '\0'; - + for (int i = 1; i <= MaxClients; i++) { if (!IsClientInGame(i)) continue; SendHudText(i, sMessage, _, 0); - if (playSnd) { + if (playSnd) EmitSoundToClient(i, sndPath); - } } timePassed++; - if (timePassed > warningTime) + if (timePassed > RoundToNearest(g_fRLGL_WarningTime)) { ApplyFade("Red"); g_bEnableDetecting = true; - float speed = THIS_MODE_INFO.cvarInfo[RLGL_CONVAR_ZOMBIES_SPEED].cvar.FloatValue; - if (speed > 0.0) { - SetZombiesSpeed(speed); - } - - CreateTimer(THIS_MODE_INFO.cvarInfo[RLGL_CONVAR_FREEZE_TIME].cvar.FloatValue, RLGL_Detect_Time_Timer, _, TIMER_FLAG_NO_MAPCHANGE); + + if (g_fRLGL_ZombieSpeed > 0.0) + SetZombiesSpeed(g_fRLGL_ZombieSpeed); + + CreateTimer(g_fRLGL_FreezeTime, RLGL_Detect_Time_Timer, _, TIMER_FLAG_NO_MAPCHANGE); + timePassed = 0; g_hRLGLWarningTimer = null; - + delete g_hRLGLDetectTimer; - g_hRLGLDetectTimer = CreateTimer(THIS_MODE_INFO.cvarInfo[RLGL_CONVAR_TIME_BETWEEN_DAMAGE].cvar.FloatValue, RLGL_Detect_Timer, _, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT); - + g_hRLGLDetectTimer = CreateTimer(g_fRLGL_TimeBetweenDamage, RLGL_Detect_Timer, _, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT); + return Plugin_Stop; } @@ -348,7 +426,6 @@ Action RLGL_Detect_Timer(Handle timer) return Plugin_Stop; } - float damage = THIS_MODE_INFO.cvarInfo[RLGL_CONVAR_DAMAGE].cvar.FloatValue; for (int i = 1; i <= MaxClients; i++) { if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) @@ -361,11 +438,9 @@ Action RLGL_Detect_Timer(Handle timer) int buttons = GetClientButtons(i); if (buttons & (IN_WALK | IN_BACK | IN_FORWARD | IN_RIGHT | IN_LEFT | IN_JUMP)) { - SDKHooks_TakeDamage(i, 0, 0, damage); + SDKHooks_TakeDamage(i, 0, 0, g_fRLGL_Damage); SendHudText(i, "STOP MOVING ITS A RED LIGHT!!!", _, 1); } - - continue; } return Plugin_Continue; @@ -379,9 +454,9 @@ Action RLGL_Detect_Time_Timer(Handle timer) ApplyFade("Green"); g_bEnableDetecting = false; SetZombiesSpeed(1.0); - + delete g_hRLGLDetectTimer; - + for (int i = 1; i <= MaxClients; i++) { if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) @@ -393,20 +468,21 @@ Action RLGL_Detect_Time_Timer(Handle timer) return Plugin_Continue; } -stock void SetZombiesSpeed(float val) { - for (int i = 1; i <= MaxClients; i++) +stock void SetZombiesSpeed(float val) +{ + for (int i = 1; i <= MaxClients; i++) { - if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_T) + if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_T) continue; - + g_fOriginalSpeed[i] = (val == 1.0) ? 0.0 : GetEntPropFloat(i, Prop_Data, "m_flLaggedMovementValue"); float thisVal = (val == 1.0) ? g_fOriginalSpeed[i] : val; if (thisVal == 0.0) thisVal = 1.0; - SetEntPropFloat(i, Prop_Data, "m_flLaggedMovementValue", thisVal); - CPrintToChat(i, "%s Your speed has been changed to {olive}%.2f", THIS_MODE_INFO.tag, thisVal); + SetEntPropFloat(i, Prop_Data, "m_flLaggedMovementValue", thisVal); + CPrintToChat(i, "%s Your speed has been changed to {olive}%.2f", THIS_MODE_INFO.tag, thisVal); CPrintToChat(i, "%s This is a part of {olive}Red Light Green Light.{white} An admin decided to have this kicker.", THIS_MODE_INFO.tag); } } @@ -414,22 +490,22 @@ stock void SetZombiesSpeed(float val) { stock void StartRLGLTimer() { float time = 10.0; - float timeMax = THIS_MODE_INFO.cvarInfo[RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MAX].cvar.FloatValue; - float timeMin = THIS_MODE_INFO.cvarInfo[RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MIN].cvar.FloatValue; - if (timeMax <= 0.0) - time = timeMin; + + if (g_fRLGL_RedMax <= 0.0) + time = g_fRLGL_RedMin; else - time = GetRandomFloat(timeMin, timeMax); - + time = GetRandomFloat(g_fRLGL_RedMin, g_fRLGL_RedMax); + g_hRLGLTimer = CreateTimer(time, RLGL_Timer, _, TIMER_FLAG_NO_MAPCHANGE); } -/* RLGL Settings */ public Action Cmd_RLGLSettings(int client, int args) { + #pragma unused args + if (!client) return Plugin_Handled; - + Menu menu = new Menu(Menu_RLGLSettings); menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); @@ -447,7 +523,7 @@ int Menu_RLGLSettings(Menu menu, MenuAction action, int param1, int param2) { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) @@ -461,4 +537,4 @@ int Menu_RLGLSettings(Menu menu, MenuAction action, int param1, int param2) } return 0; -} \ No newline at end of file +} diff --git a/addons/sourcemod/scripting/Fun_Modes/Sample.sp b/addons/sourcemod/scripting/Fun_Modes/Sample.sp index d0c4a2d..642f056 100644 --- a/addons/sourcemod/scripting/Fun_Modes/Sample.sp +++ b/addons/sourcemod/scripting/Fun_Modes/Sample.sp @@ -1,50 +1,70 @@ /* (). FunModes V2: - + @file Sample.sp - @Usage Functions for the Sample Mode. - + @Usage Functions for the Sample Mode. */ #pragma semicolon 1 #pragma newdecls required -ModeInfo g_SampleInfo; +static int g_iSampleIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iSampleIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_SampleInfo +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] #define SAMPLE_CONVAR_TOGGLE 0 +bool g_bSample_Enabled; + stock void OnPluginStart_Sample() { + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + THIS_MODE_INFO.name = "Sample"; THIS_MODE_INFO.tag = "{gold}[FunModes-Sample]{lightgreen}"; - + /* COMMANDS */ /* THESE ARE THE STANDARD COMMANDS THAT ALL MODES SHOULD HAVE */ RegAdminCmd("sm_fm_sample", Cmd_SampleToggle, ADMFLAG_CONVARS, "Turn Sample Mode On/Off"); RegAdminCmd("sm_sample_settings", Cmd_SampleSettings, ADMFLAG_CONVARS, "Open Sample Sttings Menu"); - + /* CONVARS */ DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, SAMPLE_CONVAR_TOGGLE, - "sm_sample_enable", "1", "Enable/Disable Sample Mode (This differs from turning it on/off)", - ("0,1"), "bool" + SAMPLE_CONVAR_TOGGLE, "sm_sample_enable", + "1", "Enable/Disable Sample Mode (This differs from turning it on/off)", + ("0,1"), CONVAR_BOOL ); - + + THIS_MODE_INFO.cvars[SAMPLE_CONVAR_TOGGLE].HookChange(Sample_OnConVarChange); + THIS_MODE_INFO.enableIndex = SAMPLE_CONVAR_TOGGLE; - - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; - - THIS_MODE_INFO.cvarInfo[SAMPLE_CONVAR_TOGGLE].cvar.AddChangeHook(OnSampleModeToggle); } -void OnSampleModeToggle(ConVar cvar, const char[] newValue, const char[] oldValue) +void InitCvarsValues_Sample() { - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + int modeIndex = THIS_MODE_INFO.index; + + g_bSample_Enabled = _FUNMODES_CVAR_GET_VALUE(modeIndex, SAMPLE_CONVAR_TOGGLE, Bool); +} + +void Sample_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) +{ + switch (cvarIndex) + { + case SAMPLE_CONVAR_TOGGLE: + { + bool val = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bSample_Enabled = val; + } + } } stock void OnMapStart_Sample() {} @@ -87,17 +107,16 @@ stock void Event_PlayerDeath_Sample(int client) public Action Cmd_SampleToggle(int client, int args) { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) + if (!g_bSample_Enabled) { CReplyToCommand(client, "%s Sample Mode is currently Disabled", THIS_MODE_INFO.tag); return Plugin_Handled; } - /* You can change whatever you want here */ CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, !THIS_MODE_INFO.isOn, THIS_MODE_INFO.index); - + CPrintToChatAll("%s Sample Mode is now %s!", THIS_MODE_INFO.tag, THIS_MODE_INFO.isOn ? "On" : "Off"); - + return Plugin_Handled; } @@ -106,7 +125,7 @@ public Action Cmd_SampleSettings(int client, int args) { if (!client) return Plugin_Handled; - + Menu menu = new Menu(Menu_SampleSettings); menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); @@ -115,7 +134,7 @@ public Action Cmd_SampleSettings(int client, int args) menu.ExitBackButton = true; menu.Display(client, MENU_TIME_FOREVER); - + return Plugin_Handled; } @@ -125,7 +144,7 @@ int Menu_SampleSettings(Menu menu, MenuAction action, int param1, int param2) { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) @@ -139,4 +158,4 @@ int Menu_SampleSettings(Menu menu, MenuAction action, int param1, int param2) } return 0; -} \ No newline at end of file +} diff --git a/addons/sourcemod/scripting/Fun_Modes/SlapMode.sp b/addons/sourcemod/scripting/Fun_Modes/SlapMode.sp index 9a3a5bd..5828f7b 100644 --- a/addons/sourcemod/scripting/Fun_Modes/SlapMode.sp +++ b/addons/sourcemod/scripting/Fun_Modes/SlapMode.sp @@ -1,80 +1,102 @@ /* (). FunModes V2: - - @file SlapMode.sp - @Usage Functions for the Slap mode. - -*/ -/* - Slapmode : - Like all 3 or 5 seconds (not sure about the time) a random ct gets slapped, i think it can make certain maps really fun - - By @Kamisama Kaneki + @file SlapMode.sp + @Usage Functions for the SlapMode Mode. */ #pragma semicolon 1 #pragma newdecls required -ModeInfo g_SlapModeInfo; +static int g_iSlapModeIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iSlapModeIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_SlapModeInfo +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] -#define SLAPMODE_CONVAR_TIMER_INTERVAL 0 -#define SLAPMODE_CONVAR_RANDOMS_COUNT 1 -#define SLAPMODE_CONVAR_TOGGLE 2 +#define SLAPMODE_CONVAR_TIMER_INTERVAL 0 +#define SLAPMODE_CONVAR_RANDOMS_COUNT 1 +#define SLAPMODE_CONVAR_TOGGLE 2 Handle g_hSlapModeTimer; +float g_fSlapModeInterval; +int g_iSlapModeCount; +bool g_bSlapModeEnabled; + stock void OnPluginStart_SlapMode() { + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + THIS_MODE_INFO.name = "SlapMode"; THIS_MODE_INFO.tag = "{gold}[FunModes-SlapMode]{lightgreen}"; - - /* COMMANDS */ - /* THESE ARE THE STANDARD COMMANDS THAT ALL MODES SHOULD HAVE */ - RegAdminCmd("sm_fm_slapmode", Cmd_SlapModeToggle, ADMFLAG_CONVARS, "Turn SlapMode Mode On/Off"); - RegAdminCmd("sm_slapmode_settings", Cmd_SlapModeSettings, ADMFLAG_CONVARS, "Open SlapMode Sttings Menu"); - - /* CONVARS */ + + RegAdminCmd("sm_fm_slapmode", Cmd_SlapModeToggle, ADMFLAG_CONVARS, "Turn SlapMode On/Off"); + RegAdminCmd("sm_slapmode_settings", Cmd_SlapModeSettings, ADMFLAG_CONVARS, "Open SlapMode Settings Menu"); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, SLAPMODE_CONVAR_TIMER_INTERVAL, - "sm_slapmode_time_interval", "20.0", "Every how many seconds to keep slapping a random human?", - ("15.0,20.0,30.0,40.0,60.0"), "float" + SLAPMODE_CONVAR_TIMER_INTERVAL, "sm_slapmode_time_interval", + "20.0", "The time interval between each slap round", + ("15.0,20.0,30.0,40.0,60.0"), CONVAR_FLOAT ); - + THIS_MODE_INFO.cvars[SLAPMODE_CONVAR_TIMER_INTERVAL].HookChange(SlapMode_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, SLAPMODE_CONVAR_RANDOMS_COUNT, - "sm_slapmode_randoms_count", "1", "How many random humans to keep slapping?", - ("1,2,3,4,5"), "int" + SLAPMODE_CONVAR_RANDOMS_COUNT, "sm_slapmode_randoms_count", + "1", "How many random CTs should be slapped each round", + ("1,2,3,4,5"), CONVAR_INT ); - + THIS_MODE_INFO.cvars[SLAPMODE_CONVAR_RANDOMS_COUNT].HookChange(SlapMode_OnConVarChange); + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, SLAPMODE_CONVAR_TOGGLE, - "sm_slapmode_enable", "1", "Enable/Disable SlapMode Mode (This differs from turning it on/off)", - ("0,1"), "bool" + SLAPMODE_CONVAR_TOGGLE, "sm_slapmode_enable", + "1", "Enable/Disable SlapMode (This differs from turning it on/off)", + ("0,1"), CONVAR_BOOL ); - + THIS_MODE_INFO.cvars[SLAPMODE_CONVAR_TOGGLE].HookChange(SlapMode_OnConVarChange); + THIS_MODE_INFO.enableIndex = SLAPMODE_CONVAR_TOGGLE; - - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; - - THIS_MODE_INFO.cvarInfo[SLAPMODE_CONVAR_TOGGLE].cvar.AddChangeHook(OnSlapModeModeToggle); } -void OnSlapModeModeToggle(ConVar cvar, const char[] newValue, const char[] oldValue) +void InitCvarsValues_SlapMode() { - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + int modeIndex = THIS_MODE_INFO.index; + + g_fSlapModeInterval = _FUNMODES_CVAR_GET_VALUE(modeIndex, SLAPMODE_CONVAR_TIMER_INTERVAL, Float); + g_iSlapModeCount = _FUNMODES_CVAR_GET_VALUE(modeIndex, SLAPMODE_CONVAR_RANDOMS_COUNT, Int); + g_bSlapModeEnabled = _FUNMODES_CVAR_GET_VALUE(modeIndex, SLAPMODE_CONVAR_TOGGLE, Bool); +} + +void SlapMode_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) +{ + switch (cvarIndex) + { + case SLAPMODE_CONVAR_TIMER_INTERVAL: + g_fSlapModeInterval = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case SLAPMODE_CONVAR_RANDOMS_COUNT: + g_iSlapModeCount = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + case SLAPMODE_CONVAR_TOGGLE: + { + bool val = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bSlapModeEnabled = val; + } + } } stock void OnMapStart_SlapMode() {} + stock void OnMapEnd_SlapMode() { CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, false, THIS_MODE_INFO.index); - g_hSlapModeTimer = null; } @@ -95,6 +117,7 @@ stock void ZR_OnClientInfected_SlapMode(int client) stock void Event_RoundStart_SlapMode() {} stock void Event_RoundEnd_SlapMode() {} + stock void Event_PlayerSpawn_SlapMode(int client) { #pragma unused client @@ -112,47 +135,82 @@ stock void Event_PlayerDeath_SlapMode(int client) public Action Cmd_SlapModeToggle(int client, int args) { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) + if (!g_bSlapModeEnabled) { - CReplyToCommand(client, "%s SlapMode Mode is currently Disabled", THIS_MODE_INFO.tag); + CReplyToCommand(client, "%s SlapMode is currently Disabled", THIS_MODE_INFO.tag); return Plugin_Handled; } - /* You can change whatever you want here */ CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, !THIS_MODE_INFO.isOn, THIS_MODE_INFO.index); - - CPrintToChatAll("%s SlapMode Mode is now %s!", THIS_MODE_INFO.tag, THIS_MODE_INFO.isOn ? "On" : "Off"); - + + CPrintToChatAll("%s SlapMode is now %s!", THIS_MODE_INFO.tag, THIS_MODE_INFO.isOn ? "On" : "Off"); + if (THIS_MODE_INFO.isOn) { - float interval = THIS_MODE_INFO.cvarInfo[SLAPMODE_CONVAR_TIMER_INTERVAL].cvar.FloatValue; - - CPrintToChatAll("%s A random human will get slapped every %.2f seconds", THIS_MODE_INFO.tag, interval); - g_hSlapModeTimer = CreateTimer(interval, Timer_SlapMode, _, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT); + CPrintToChatAll("%s Random CTs will be slapped every %.2f seconds", THIS_MODE_INFO.tag, g_fSlapModeInterval); + + delete g_hSlapModeTimer; + g_hSlapModeTimer = CreateTimer( + g_fSlapModeInterval, + Timer_SlapMode, + _, + TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE + ); } else { delete g_hSlapModeTimer; } - + return Plugin_Handled; } -/* SlapMode Settings */ +Action Timer_SlapMode(Handle timer) +{ + if (!THIS_MODE_INFO.isOn) + return Plugin_Stop; + + int players[MAXPLAYERS + 1]; + int count; + + for (int i = 1; i <= MaxClients; i++) + { + if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) + continue; + + players[count] = i; + count++; + } + + if (!count) + return Plugin_Continue; + + for (int i = 0; i < g_iSlapModeCount; i++) + { + int client = players[GetRandomInt(0, count - 1)]; + + SlapPlayer(client); + SlapPlayer(client); + + CPrintToChatAll("%s %N has been slapped", THIS_MODE_INFO.tag, client); + } + + return Plugin_Continue; +} + public Action Cmd_SlapModeSettings(int client, int args) { if (!client) return Plugin_Handled; - + Menu menu = new Menu(Menu_SlapModeSettings); menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); - menu.AddItem(NULL_STRING, "Show Cvars\n"); menu.ExitBackButton = true; menu.Display(client, MENU_TIME_FOREVER); - + return Plugin_Handled; } @@ -162,7 +220,7 @@ int Menu_SlapModeSettings(Menu menu, MenuAction action, int param1, int param2) { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) @@ -177,39 +235,3 @@ int Menu_SlapModeSettings(Menu menu, MenuAction action, int param1, int param2) return 0; } - -Action Timer_SlapMode(Handle timer) -{ - if (!THIS_MODE_INFO.isOn) - { - g_hBlindModeTimer = null; - return Plugin_Stop; - } - - int humansCount = 0; - int humans[MAXPLAYERS + 1]; - - for (int i = 1; i <= MaxClients; i++) - { - if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) - continue; - - humans[humansCount++] = i; - } - - if (humansCount == 0) - return Plugin_Handled; - - int neededHumans = THIS_MODE_INFO.cvarInfo[SLAPMODE_CONVAR_RANDOMS_COUNT].cvar.IntValue; - int enough = 1; - do - { - int human = humans[GetRandomInt(0, humansCount - 1)]; - SlapPlayer(human); - SlapPlayer(human); - CPrintToChatAll("%s %N {olive}has been slapped for being a bad boy (Bruh, It's totally random...)", THIS_MODE_INFO.tag, human); - enough++; - } while (enough <= neededHumans); - - return Plugin_Continue; -} \ No newline at end of file diff --git a/addons/sourcemod/scripting/Fun_Modes/VIPMode.sp b/addons/sourcemod/scripting/Fun_Modes/VIPMode.sp index 05a7bb7..8966217 100644 --- a/addons/sourcemod/scripting/Fun_Modes/VIPMode.sp +++ b/addons/sourcemod/scripting/Fun_Modes/VIPMode.sp @@ -1,87 +1,127 @@ /* (). FunModes V2: - + @file VIPMode.sp - @Usage Functions for the VIP mode. + @Usage Functions for the VIPMode Mode. */ #pragma semicolon 1 #pragma newdecls required -ModeInfo g_VIPModeInfo; +static int g_iVIPModeIndex = -1; + +#undef THIS_MODE_INDEX +#define THIS_MODE_INDEX g_iVIPModeIndex #undef THIS_MODE_INFO -#define THIS_MODE_INFO g_VIPModeInfo +#define THIS_MODE_INFO g_ModesInfo[THIS_MODE_INDEX] -#define VIPMODE_CONVAR_TIMER 0 -#define VIPMODE_CONVAR_COUNT 1 -#define VIPMODE_CONVAR_LASER 2 -#define VIPMODE_CONVAR_VIP_MAX 3 -#define VIPMODE_CONVAR_TOGGLE 4 +#define VIPMODE_CONVAR_TIMER 0 +#define VIPMODE_CONVAR_COUNT 1 +#define VIPMODE_CONVAR_LASER 2 +#define VIPMODE_CONVAR_VIP_MAX 3 +#define VIPMODE_CONVAR_TOGGLE 4 -bool g_bDiedFromLaser[MAXPLAYERS+1]; +bool g_bDiedFromLaser[MAXPLAYERS + 1]; bool g_bIsVIP[MAXPLAYERS + 1]; -/* Timers */ Handle g_hKillAllTimer = null; Handle g_hVIPRoundStartTimer = null; Handle g_hVIPBeaconTimer[MAXPLAYERS + 1] = { null, ... }; -/* CALLED ON PLUGIN START */ +float g_fVIP_Timer; +float g_fVIP_KillDelay; +bool g_bVIP_LaserException; +int g_iVIP_Max; +bool g_bVIP_Enabled; + stock void OnPluginStart_VIPMode() { + // Important, this must be first before filling any other mode info! + FUNMODES_REGISTER_MODE(); + THIS_MODE_INFO.name = "VIPMode"; THIS_MODE_INFO.tag = "{gold}[FunModes-VIPMode]{lightgreen}"; - /* Commands */ - RegAdminCmd("sm_fm_vipmode", Cmd_VIPModeToggle, ADMFLAG_CONVARS, "Enable/Disable VIP Mode"); - RegAdminCmd("sm_vipmode_setvip", Cmd_SetVIP, ADMFLAG_CONVARS); + RegAdminCmd("sm_fm_vipmode", Cmd_VIPModeToggle, ADMFLAG_CONVARS, "Turn VIPMode On/Off"); + RegAdminCmd("sm_vipmode_setvip", Cmd_SetVIP, ADMFLAG_CONVARS, "Set a player as VIP"); RegConsoleCmd("sm_checkvip", Cmd_CheckVIP); RegAdminCmd("sm_vipmode_settings", Cmd_VIPModeSettings, ADMFLAG_CONVARS, "Open VIPMode Settings Menu"); - - /* CONVARS */ + DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, VIPMODE_CONVAR_TIMER, - "sm_vipmode_timer", "15", "After how many seconds from round start to pick VIP", - ("15.0,25.0,40.0,60.0"), "float" + VIPMODE_CONVAR_TIMER, "sm_vipmode_timer", + "15", "How many seconds after round start before choosing the VIPs", + ("15,25,40,60"), CONVAR_FLOAT ); + THIS_MODE_INFO.cvars[VIPMODE_CONVAR_TIMER].HookChange(VIPMode_OnConVarChange); DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, VIPMODE_CONVAR_COUNT, - "sm_vipmode_counter", "3", "After how many seconds all the other humans will be slayed after the vip dies", - ("2.0,3.0,5.0,10.0"), "float" + VIPMODE_CONVAR_COUNT, "sm_vipmode_counter", + "3", "How many seconds to wait before killing all CTs when all VIPs die", + ("2,3,5,10"), CONVAR_FLOAT ); + THIS_MODE_INFO.cvars[VIPMODE_CONVAR_COUNT].HookChange(VIPMode_OnConVarChange); DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, VIPMODE_CONVAR_LASER, - "sm_vipmode_laser", "1", ("Don't Kill all humans when vip dies to a laser, 1 = Enabled, 0 = Disabled"), - ("0,1"), "bool" + VIPMODE_CONVAR_LASER, "sm_vipmode_laser", + "1", "Whether laser deaths should be ignored as a VIP death exception", + ("0,1"), CONVAR_BOOL ); + THIS_MODE_INFO.cvars[VIPMODE_CONVAR_LASER].HookChange(VIPMode_OnConVarChange); DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, VIPMODE_CONVAR_VIP_MAX, - "sm_vipmode_max_vips", "1", "How many VIPs to be picked", - ("1,2,3,4,5"), "int" + VIPMODE_CONVAR_VIP_MAX, "sm_vipmode_max_vips", + "1", "Maximum number of VIPs to pick each round", + ("1,2,3,4,5"), CONVAR_INT ); + THIS_MODE_INFO.cvars[VIPMODE_CONVAR_VIP_MAX].HookChange(VIPMode_OnConVarChange); DECLARE_FM_CVAR( - THIS_MODE_INFO.cvarInfo, VIPMODE_CONVAR_TOGGLE, - "sm_vipmode_enable", "1", "Enable/Disable the VIP Mode (This differes from turning it on/off)", - ("0,1"), "bool" + VIPMODE_CONVAR_TOGGLE, "sm_vipmode_enable", + "1", "Enable/Disable VIPMode (This differs from turning it on/off)", + ("0,1"), CONVAR_BOOL ); + THIS_MODE_INFO.cvars[VIPMODE_CONVAR_TOGGLE].HookChange(VIPMode_OnConVarChange); THIS_MODE_INFO.enableIndex = VIPMODE_CONVAR_TOGGLE; +} - THIS_MODE_INFO.index = g_iLastModeIndex++; - g_ModesInfo[THIS_MODE_INFO.index] = THIS_MODE_INFO; +void InitCvarsValues_VIPMode() +{ + int modeIndex = THIS_MODE_INFO.index; - THIS_MODE_INFO.cvarInfo[VIPMODE_CONVAR_TOGGLE].cvar.AddChangeHook(OnVIPModeToggle); + g_fVIP_Timer = _FUNMODES_CVAR_GET_VALUE(modeIndex, VIPMODE_CONVAR_TIMER, Float); + g_fVIP_KillDelay = _FUNMODES_CVAR_GET_VALUE(modeIndex, VIPMODE_CONVAR_COUNT, Float); + g_bVIP_LaserException = _FUNMODES_CVAR_GET_VALUE(modeIndex, VIPMODE_CONVAR_LASER, Bool); + g_iVIP_Max = _FUNMODES_CVAR_GET_VALUE(modeIndex, VIPMODE_CONVAR_VIP_MAX, Int); + g_bVIP_Enabled = _FUNMODES_CVAR_GET_VALUE(modeIndex, VIPMODE_CONVAR_TOGGLE, Bool); } -void OnVIPModeToggle(ConVar cvar, const char[] newValue, const char[] oldValue) +void VIPMode_OnConVarChange(int modeIndex, int cvarIndex, const char[] oldValue, const char[] newValue) { - if (THIS_MODE_INFO.isOn) - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, cvar.BoolValue, THIS_MODE_INFO.index); + switch (cvarIndex) + { + case VIPMODE_CONVAR_TIMER: + g_fVIP_Timer = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case VIPMODE_CONVAR_COUNT: + g_fVIP_KillDelay = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Float); + + case VIPMODE_CONVAR_LASER: + g_bVIP_LaserException = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + + case VIPMODE_CONVAR_VIP_MAX: + g_iVIP_Max = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Int); + + case VIPMODE_CONVAR_TOGGLE: + { + bool val = _FUNMODES_CVAR_GET_VALUE(modeIndex, cvarIndex, Bool); + if (THIS_MODE_INFO.isOn) + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, val, THIS_MODE_INFO.index); + + g_bVIP_Enabled = val; + } + } } stock void OnMapStart_VIPMode() {} @@ -100,6 +140,9 @@ stock void OnMapEnd_VIPMode() stock void OnClientPutInServer_VIPMode(int client) { + if (!THIS_MODE_INFO.isOn) + return; + if (g_bSDKHook_OnTakeDamage[client]) return; @@ -141,7 +184,7 @@ stock void Event_RoundStart_VIPMode() } delete g_hVIPRoundStartTimer; - g_hVIPRoundStartTimer = CreateTimer(THIS_MODE_INFO.cvarInfo[VIPMODE_CONVAR_TIMER].cvar.FloatValue, VIPRoundStart_Timer, _, TIMER_FLAG_NO_MAPCHANGE); + g_hVIPRoundStartTimer = CreateTimer(g_fVIP_Timer, VIPRoundStart_Timer, _, TIMER_FLAG_NO_MAPCHANGE); } stock void Event_RoundEnd_VIPMode() {} @@ -152,7 +195,7 @@ stock void Event_PlayerSpawn_VIPMode(int client) stock void Event_PlayerTeam_VIPMode(Event event) { - if (!!THIS_MODE_INFO.isOn) + if (!THIS_MODE_INFO.isOn) return; int client = GetClientOfUserId(event.GetInt("userid")); @@ -193,10 +236,10 @@ stock void OnTakeDamagePost_VIPMode(int victim, int attacker, float damage) stock void OnTakeDamage_VIPMode(int victim, int attacker, float damage, Action &result) { #pragma unused result - - if (!THIS_MODE_INFO.cvarInfo[VIPMODE_CONVAR_LASER].cvar.BoolValue) + + if (!THIS_MODE_INFO.isOn || !g_bVIP_LaserException) return; - + if (!g_bIsVIP[victim]) return; @@ -223,10 +266,10 @@ stock void OnTakeDamage_VIPMode(int victim, int attacker, float damage, Action & if (strcmp(parentClassName, "func_movelinear") == 0 || strcmp(parentClassName, "func_door") == 0) isFromLaser = true; - + if (!isFromLaser) return; - + g_bDiedFromLaser[victim] = false; if (damage > GetClientHealth(victim)) g_bDiedFromLaser[victim] = true; @@ -239,275 +282,207 @@ stock void OnWeaponEquip_VIPMode(int client, int weapon, Action &result) #pragma unused result } -Action VIPMode_KillAllTimer(Handle timer) +public Action Cmd_VIPModeToggle(int client, int args) { - g_hKillAllTimer = null; + if (!g_bVIP_Enabled) + { + CReplyToCommand(client, "%s VIPMode is currently Disabled", THIS_MODE_INFO.tag); + return Plugin_Handled; + } - if (!THIS_MODE_INFO.isOn) - return Plugin_Stop; + CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, !THIS_MODE_INFO.isOn, THIS_MODE_INFO.index); - if (GetCurrentVIPsCount() > 0) + CPrintToChatAll("%s VIPMode is now %s!", THIS_MODE_INFO.tag, THIS_MODE_INFO.isOn ? "On" : "Off"); + + if (THIS_MODE_INFO.isOn) { - CPrintToChatAll("%s Found a VIP player, {olive}Cancelling The kills...", THIS_MODE_INFO.tag); - return Plugin_Stop; + FunModes_HookEvent(g_bEvent_RoundStart, "round_start", Event_RoundStart); + FunModes_HookEvent(g_bEvent_PlayerDeath, "player_death", Event_PlayerDeath); } - + + delete g_hKillAllTimer; + delete g_hVIPRoundStartTimer; + for (int i = 1; i <= MaxClients; i++) { - if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) - continue; + if (THIS_MODE_INFO.isOn && IsClientInGame(i)) + OnClientPutInServer_VIPMode(i); - ForcePlayerSuicide(i); + g_bIsVIP[i] = false; + g_bDiedFromLaser[i] = false; + delete g_hVIPBeaconTimer[i]; } - return Plugin_Continue; + return Plugin_Handled; } Action VIPRoundStart_Timer(Handle timer) { g_hVIPRoundStartTimer = null; - if (THIS_MODE_INFO.isOn) - return Plugin_Stop; - - /* CHECK IF THERE IS ALREADY VIP SET BY ADMIN */ - if (GetCurrentVIPsCount() > 0) + if (!THIS_MODE_INFO.isOn) return Plugin_Stop; - /* Lets pick a random human */ - for (int i = 0; i < THIS_MODE_INFO.cvarInfo[VIPMODE_CONVAR_VIP_MAX].cvar.IntValue; i++) + for (int i = 0; i < g_iVIP_Max; i++) VIP_PickRandom(); - + return Plugin_Stop; } -Action VIP_BeaconTimer(Handle timer, int userid) +stock void RemoveClientVIP(int client, bool kill, const char[] translation = "") { - int client = GetClientOfUserId(userid); - if (!client) - { - return Plugin_Stop; - } - - if (!THIS_MODE_INFO.isOn) - { - g_hVIPBeaconTimer[client] = null; - return Plugin_Stop; - } - - if (!IsPlayerAlive(client) || GetClientTeam(client) != CS_TEAM_CT) + g_bIsVIP[client] = false; + delete g_hVIPBeaconTimer[client]; + + CPrintToChatAll("%s %t", THIS_MODE_INFO.tag, translation, client); + + if (kill && GetCurrentVIPsCount() == 0) { - g_hVIPBeaconTimer[client] = null; - return Plugin_Stop; - } + CPrintToChatAll("%s %t", THIS_MODE_INFO.tag, "VIPMode_KillAll", RoundToNearest(g_fVIP_KillDelay)); - if (g_bRoundEnd) - { - g_hVIPBeaconTimer[client] = null; - return Plugin_Stop; + delete g_hKillAllTimer; + g_hKillAllTimer = CreateTimer(g_fVIP_KillDelay, VIPMode_KillAllTimer, _, TIMER_FLAG_NO_MAPCHANGE); } - - BeaconPlayer(client, 1); - return Plugin_Continue; } -public Action Cmd_VIPModeToggle(int client, int args) +stock void VIP_PickRandom() { - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) - { - CReplyToCommand(client, "%s VIPmode is currently disabled!", THIS_MODE_INFO.tag); - return Plugin_Handled; - } + int players[MAXPLAYERS + 1]; + int count; - bool isOn = THIS_MODE_INFO.isOn; - if (isOn) - { - isOn = false; - if (!client) - CReplyToCommand(client, "%s VIP Mode is now OFF!", THIS_MODE_INFO.tag); - else - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "VIPMode_Disabled", client); - - for (int i = 1; i <= MaxClients; i++) - { - g_bIsVIP[i] = false; - delete g_hVIPBeaconTimer[i]; - } - } - else + for (int i = 1; i <= MaxClients; i++) { - isOn = true; - - /* Events Hooks */ - FunModes_HookEvent(g_bEvent_RoundStart, "round_start", Event_RoundStart); - FunModes_HookEvent(g_bEvent_RoundEnd, "round_end", Event_RoundEnd); - FunModes_HookEvent(g_bEvent_PlayerTeam, "player_team", Event_PlayerTeam); - FunModes_HookEvent(g_bEvent_PlayerDeath, "player_death", Event_PlayerDeath); - - if (!client) - CReplyToCommand(client, "%s VIP Mode is now ON!", THIS_MODE_INFO.tag); - else - CReplyToCommand(client, "%s %T", THIS_MODE_INFO.tag, "VIPMode_Enabled", client); - - for (int i = 1; i <= MaxClients; i++) - { - if (!IsClientInGame(i) || IsFakeClient(i)) - continue; + if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT || g_bIsVIP[i]) + continue; - SDKHook(i, SDKHook_OnTakeDamage, OnTakeDamage); - } + players[count] = i; + count++; } - CHANGE_MODE_INFO(THIS_MODE_INFO, isOn, isOn, THIS_MODE_INFO.index); - return Plugin_Handled; -} + if (!count) + return; -Action Cmd_SetVIP(int client, int args) -{ - if (!THIS_MODE_INFO.isOn) - { - CReplyToCommand(client, "%s VIP Mode is currently OFF!", THIS_MODE_INFO.tag); - return Plugin_Handled; - } + int client = players[GetRandomInt(0, count - 1)]; - if (args < 1) - { - CReplyToCommand(client, "%s Usage: sm_vipmode_setvip ", THIS_MODE_INFO.tag); - return Plugin_Handled; - } + g_bIsVIP[client] = true; - char arg[65]; - GetCmdArg(1, arg, sizeof(arg)); - int target = FindTarget(client, arg, false, false); + delete g_hVIPBeaconTimer[client]; + g_hVIPBeaconTimer[client] = CreateTimer( + 1.0, + VIP_BeaconTimer, + GetClientUserId(client), + TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE + ); - if (target < 1) - { - ReplyToTargetError(client, COMMAND_TARGET_NOT_IN_GAME); - return Plugin_Handled; - } + CPrintToChatAll("%s %N is VIP!", THIS_MODE_INFO.tag, client); +} - if (g_bIsVIP[target]) - { - CReplyToCommand(client, "%s The specified target is already VIP!", THIS_MODE_INFO.tag); - return Plugin_Handled; - } +Action VIP_BeaconTimer(Handle timer, int userid) +{ + int client = GetClientOfUserId(userid); - if (!IsPlayerAlive(target) || GetClientTeam(target) != CS_TEAM_CT) - { - CReplyToCommand(client, "%s Cannot set VIP to a player that is not human.", THIS_MODE_INFO.tag); - return Plugin_Handled; - } - - g_bIsVIP[target] = true; - CPrintToChatAll("%s {olive}%N {lightgreen}is a VIP!", THIS_MODE_INFO.tag, target); + if (!client || !IsPlayerAlive(client) || !THIS_MODE_INFO.isOn) + return Plugin_Stop; - delete g_hVIPBeaconTimer[target]; - g_hVIPBeaconTimer[target] = CreateTimer(1.0, VIP_BeaconTimer, GetClientUserId(target), TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); - return Plugin_Handled; + BeaconPlayer(client, 1); + + return Plugin_Continue; } -Action Cmd_CheckVIP(int client, int args) +Action VIPMode_KillAllTimer(Handle timer) { + g_hKillAllTimer = null; + if (!THIS_MODE_INFO.isOn) - { - CReplyToCommand(client, "%s VIP Mode is currently OFF", THIS_MODE_INFO.tag); - return Plugin_Handled; - } - - if (GetCurrentVIPsCount() == 0) - { - CReplyToCommand(client, "%s No VIP was found!", THIS_MODE_INFO.tag); - return Plugin_Handled; - } - - char vipPlayers[200]; + return Plugin_Stop; + for (int i = 1; i <= MaxClients; i++) { - if (!g_bIsVIP[i]) + if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT) continue; - - Format(vipPlayers, sizeof(vipPlayers), "%s%N, ", vipPlayers, i); + + ForcePlayerSuicide(i); } - - CReplyToCommand(client, "%s The current {purple}VIPs {olive}are: {purple}%s", THIS_MODE_INFO.tag, vipPlayers); - return Plugin_Handled; + + return Plugin_Stop; } stock int GetCurrentVIPsCount() { int count; + for (int i = 1; i <= MaxClients; i++) { - if (!g_bIsVIP[i]) - continue; - - count++; + if (g_bIsVIP[i]) + count++; } - + return count; } -stock void RemoveClientVIP(int client, bool kill, const char[] translation = "") +public Action Cmd_SetVIP(int client, int args) { - g_bIsVIP[client] = false; - delete g_hVIPBeaconTimer[client]; - - CPrintToChatAll("%s %t", THIS_MODE_INFO.tag, translation, client); - - if (kill && GetCurrentVIPsCount() == 0) - { - int counter = THIS_MODE_INFO.cvarInfo[VIPMODE_CONVAR_COUNT].cvar.IntValue; - CPrintToChatAll("%s %t", THIS_MODE_INFO.tag, "VIPMode_KillAll", counter); + if (!THIS_MODE_INFO.isOn) + return Plugin_Handled; - delete g_hKillAllTimer; - g_hKillAllTimer = CreateTimer(float(counter), VIPMode_KillAllTimer, _, TIMER_FLAG_NO_MAPCHANGE); - } + if (args < 1) + return Plugin_Handled; + + char arg[64]; + GetCmdArg(1, arg, sizeof(arg)); + + int target = FindTarget(client, arg, false, false); + + if (target < 1 || !IsPlayerAlive(target) || ZR_IsClientZombie(target)) + return Plugin_Handled; + + g_bIsVIP[target] = true; + + delete g_hVIPBeaconTimer[target]; + g_hVIPBeaconTimer[target] = CreateTimer( + 1.0, + VIP_BeaconTimer, + GetClientUserId(target), + TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE + ); + + CPrintToChatAll("%s %N has been set as VIP!", THIS_MODE_INFO.tag, target); + + return Plugin_Handled; } -stock void VIP_PickRandom() +public Action Cmd_CheckVIP(int client, int args) { - /* Lets pick a random human */ - int clientsCount[MAXPLAYERS + 1]; - int humansCount; + bool found; for (int i = 1; i <= MaxClients; i++) { - if (!IsClientInGame(i) || !IsPlayerAlive(i) || GetClientTeam(i) != CS_TEAM_CT || g_bIsVIP[i]) + if (!g_bIsVIP[i]) continue; - clientsCount[humansCount++] = i; + CReplyToCommand(client, "%s VIP: %N", THIS_MODE_INFO.tag, i); + found = true; } - if (humansCount <= 0) - return; - - int random = clientsCount[GetRandomInt(0, (humansCount - 1))]; - if (random < 1) - return; - - g_bIsVIP[random] = true; - CPrintToChatAll("%s {olive}%N {lightgreen}is a VIP!", THIS_MODE_INFO.tag, random); + if (!found) + CReplyToCommand(client, "%s no VIP", THIS_MODE_INFO.tag); - delete g_hVIPBeaconTimer[random]; - g_hVIPBeaconTimer[random] = CreateTimer(1.0, VIP_BeaconTimer, GetClientUserId(random), TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); + return Plugin_Handled; } -/* VIPMode Settings */ public Action Cmd_VIPModeSettings(int client, int args) { if (!client) return Plugin_Handled; - + Menu menu = new Menu(Menu_VIPModeSettings); menu.SetTitle("%s - Settings", THIS_MODE_INFO.name); - menu.AddItem(NULL_STRING, "Show Cvars\n"); - menu.AddItem(NULL_STRING, "Check current VIPs", THIS_MODE_INFO.isOn ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED); - menu.AddItem(NULL_STRING, "Set Player VIP", THIS_MODE_INFO.isOn ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED); menu.ExitBackButton = true; menu.Display(client, MENU_TIME_FOREVER); + return Plugin_Handled; } @@ -517,7 +492,7 @@ int Menu_VIPModeSettings(Menu menu, MenuAction action, int param1, int param2) { case MenuAction_End: delete menu; - + case MenuAction_Cancel: { if (param2 == MenuCancel_ExitBack) @@ -526,179 +501,9 @@ int Menu_VIPModeSettings(Menu menu, MenuAction action, int param1, int param2) case MenuAction_Select: { - switch (param2) - { - case 0: - { - ShowCvarsInfo(param1, THIS_MODE_INFO); - } - - case 1: - { - ShowCurrentVIPs(param1); - } - - case 2: - { - ShowSetPlayerVIP(param1); - } - } - } - } - - return 0; -} - -void ShowCurrentVIPs(int client) -{ - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) - return; - - Menu menu = new Menu(Menu_VIPCurrentVIPs); - - menu.SetTitle("%s - Current VIPs List", THIS_MODE_INFO.name); - - if (!THIS_MODE_INFO.isOn) - menu.AddItem(NULL_STRING, "The VIPMode is currently Off!", ITEMDRAW_DISABLED); - else - { - bool found = false; - for (int i = 1; i <= MaxClients; i++) - { - if (!g_bIsVIP[i]) - continue; - - found = true; - int userid = GetClientUserId(i); - - char useridStr[10]; - IntToString(userid, useridStr, sizeof(useridStr)); - - char menuItem[70]; - FormatEx(menuItem, sizeof(menuItem), "[#%d] %N - Remove", userid, i); - - menu.AddItem(useridStr, menuItem); + ShowCvarsInfo(param1, THIS_MODE_INFO); } - - if (!found) - menu.AddItem(NULL_STRING, "There's no VIP player yet!", ITEMDRAW_DISABLED); } - menu.Display(client, MENU_TIME_FOREVER); -} - -int Menu_VIPCurrentVIPs(Menu menu, MenuAction action, int param1, int param2) -{ - switch (action) - { - case MenuAction_End: - delete menu; - - case MenuAction_Cancel: - { - if (param2 == MenuCancel_ExitBack) - Cmd_VIPModeSettings(param1, 0); - } - - case MenuAction_Select: - { - char useridStr[10]; - menu.GetItem(param2, useridStr, sizeof(useridStr)); - - int userid = StringToInt(useridStr); - int client = GetClientOfUserId(userid); - if (!client || !g_bIsVIP[client]) - { - CPrintToChat(param1, "%s The selected player either left or is no longer {purple]VIP!", THIS_MODE_INFO.tag); - ShowCurrentVIPs(param1); - return 0; - } - - RemoveClientVIP(client, false, "VIPMode_AdminRemove"); - ShowCurrentVIPs(param1); - } - } - return 0; } - -void ShowSetPlayerVIP(int client) -{ - if (!THIS_MODE_INFO.cvarInfo[THIS_MODE_INFO.enableIndex].cvar.BoolValue) - return; - - Menu menu = new Menu(Menu_VIPSetPlayerVIP); - - menu.SetTitle("%s - Players List - Select a player to set them to a VIP", THIS_MODE_INFO.name); - - if (!THIS_MODE_INFO.isOn) - menu.AddItem(NULL_STRING, "The VIPMode is currently Off!", ITEMDRAW_DISABLED); - else - { - bool found = false; - for (int i = 1; i <= MaxClients; i++) - { - if (g_bIsVIP[i] || !IsClientInGame(i) || IsFakeClient(i) || !IsPlayerAlive(i)) - continue; - - if (ZR_IsClientZombie(i)) - continue; - - found = true; - int userid = GetClientUserId(i); - - char useridStr[10]; - IntToString(userid, useridStr, sizeof(useridStr)); - - char menuItem[70]; - FormatEx(menuItem, sizeof(menuItem), "[#%d] %N - Set VIP", userid, i); - - menu.AddItem(useridStr, menuItem); - } - - if (!found) - menu.AddItem(NULL_STRING, "No player was found!", ITEMDRAW_DISABLED); - } - - menu.Display(client, MENU_TIME_FOREVER); -} - -int Menu_VIPSetPlayerVIP(Menu menu, MenuAction action, int param1, int param2) -{ - switch (action) - { - case MenuAction_End: - delete menu; - - case MenuAction_Cancel: - { - if (param2 == MenuCancel_ExitBack) - Cmd_VIPModeSettings(param1, 0); - } - - case MenuAction_Select: - { - char useridStr[10]; - menu.GetItem(param2, useridStr, sizeof(useridStr)); - - int userid = StringToInt(useridStr); - int client = GetClientOfUserId(userid); - if (!client || g_bIsVIP[client] || ZR_IsClientZombie(client)) - { - CPrintToChat(param1, "%s The selected player either left, died or is currently a {purple]VIP!", THIS_MODE_INFO.tag); - ShowCurrentVIPs(param1); - return 0; - } - - g_bIsVIP[client] = true; - CPrintToChatAll("%s {olive}%N {lightgreen}is a VIP!", THIS_MODE_INFO.tag, client); - - delete g_hVIPBeaconTimer[client]; - g_hVIPBeaconTimer[client] = CreateTimer(1.0, VIP_BeaconTimer, userid, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE); - - ShowCurrentVIPs(param1); - } - } - - return 0; -} \ No newline at end of file