#pragma semicolon 1 #define PLUGIN_AUTHOR "jenz, https://steamcommunity.com/id/type_moon/" #define PLUGIN_VERSION "1.3" #define g_dIndexes 128 #define g_dLength 256 #define CSGO_KNOCKBACK_BOOST 251.0 #define CSGO_KNOCKBACK_BOOST_MAX 350.0 #define HEGrenadeOffset 11 // (11 * 4) #define FlashbangOffset 12 // (12 * 4) #define SmokegrenadeOffset 13 // (13 * 4) #include #include #include #include #include #include #include //smrpg not letting health be overwritten by zr classes #tryinclude #pragma newdecls required //#pragma dynamic 131072 char g_cDaysTitles[100][512]; static char g_cPathsClassHuman[PLATFORM_MAX_PATH]; static char g_cPathsClassZM[PLATFORM_MAX_PATH]; static char g_cPathsDownload[PLATFORM_MAX_PATH]; static char g_cPathsWaveSettings[PLATFORM_MAX_PATH]; static char g_cPathsWeapons[PLATFORM_MAX_PATH]; static char g_cPathsExtra[PLATFORM_MAX_PATH]; char g_cUniqueName[g_dIndexes][g_dLength]; char g_cZMRoundClasses[g_dIndexes][g_dLength]; char g_cHumanClasses[g_dIndexes][g_dLength]; char g_cTeam[g_dIndexes][g_dLength]; char g_cGroup[g_dIndexes][g_dLength]; char g_cSMFLAGS[g_dIndexes][g_dLength]; char g_cModelPath[g_dIndexes][g_dLength]; char g_cNoFallDmg[g_dIndexes][g_dLength]; char g_cHealth[g_dIndexes][g_dLength]; char g_cSpeed[g_dIndexes][g_dLength]; char g_cKnockback[g_dIndexes][g_dLength]; char g_cJumpHeight[g_dIndexes][g_dLength]; char g_cJumpDistance[g_dIndexes][g_dLength]; char g_cDamageMultiplier[g_dIndexes][g_dLength]; char g_cAdminGroups[g_dIndexes][g_dIndexes][g_dLength]; char g_cZMSounds[g_dIndexes][g_dLength]; char g_cWeaponEntity[g_dIndexes][g_dLength]; char g_cWeaponNames[g_dIndexes][g_dLength]; char g_cWeaponCommand[g_dIndexes][g_dLength]; char g_cBossSound[512]; char g_cAmbientSOund[64][512]; float g_fAmbientSoundLoopDuration; float g_fBossSoundLoopDuration; int g_iLength = g_dLength - 1; int g_iWave; int g_iSpeedDelayClient[MAXPLAYERS + 1]; float g_iZMScaleability; int g_iZMCount; int g_iToolsVelocity; //from zombie reloaded int g_iClientZMClasses[g_dIndexes]; int g_iClientHumanClasses[g_dIndexes]; int g_iClientRespawnCount[g_dIndexes]; int g_iWeaponSlot[g_dIndexes]; int g_iWeaponPrice[g_dIndexes]; int g_iBotStuckindex[g_dIndexes]; int g_iClientRespawnCountNum; int g_iZMBeginindex; int g_iSoundIndexes; int g_iWeaponIndex; int g_iBotStuckCounts; int g_iLoadClassesIndex; int g_iHumanCount; int g_iZombieCount; int g_iZombieBossIndex[g_dIndexes]; int g_iBossBotCount; float g_fKnockBackIndex[g_dIndexes + 1]; float g_fJumpHeightIndex[g_dIndexes + 1]; float g_fJumpDistanceIndex[g_dIndexes + 1]; float g_fDamageMultiplier[g_dIndexes + 1]; float g_fSwitchingTimer; float g_fZMSpawnProtection; float g_fHumanSpawnProtection; float g_fZMHealthScaleability; float g_fRespawnTimer; float g_fZMSounds; float g_fBotStuckPush; bool g_bSwitchingIndex; bool g_bRoundInProgress; bool g_bFallDamage[g_dIndexes]; bool g_bClientProtection[g_dIndexes]; bool g_bIsBossRound; bool g_bClientIsBoss[MAXPLAYERS + 1]; Handle g_hClientZMCookie; Handle g_hClientHumanCookie; Handle g_hCheckBotStuck = null; Handle g_hZombieSounds = null; Handle g_hFixKNife = null; Handle g_hAmbient = null; //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Plugin myinfo = { name = "Unloze Zombie Riot", author = PLUGIN_AUTHOR, description = "Zombie Riot mod. originally for csgo but remade for css", version = PLUGIN_VERSION, url = "www.unloze.com" }; public void loadDays() { char localPath[256]; BuildPath(Path_SM, localPath, sizeof(localPath), "configs/unloze_zr/daystitle.txt"); Handle fileHandle = OpenFile(localPath, "r"); char lineBuffer[512]; int count = 0; while( !IsEndOfFile( fileHandle ) && ReadFileLine( fileHandle, lineBuffer, sizeof( lineBuffer ) ) ) { TrimString( lineBuffer ); Format(g_cDaysTitles[count], sizeof(g_cDaysTitles[]), lineBuffer); count++; } CloseHandle( fileHandle ); } public void OnPluginStart() { //processstring LoadTranslations("common.phrases.txt"); //cookies if (g_hClientZMCookie == null) g_hClientZMCookie = RegClientCookie("unloze_zr_classprefZM", "Cookie for ZM classes", CookieAccess_Protected); if (g_hClientHumanCookie == null) g_hClientHumanCookie = RegClientCookie("unloze_zr_classprefHuman", "Cookie for Human classes", CookieAccess_Protected); BuildPath(Path_SM, g_cPathsClassZM, sizeof(g_cPathsClassZM), "configs/unloze_zr/classeszm.txt"); BuildPath(Path_SM, g_cPathsClassHuman, sizeof(g_cPathsClassHuman), "configs/unloze_zr/classeshuman.txt"); BuildPath(Path_SM, g_cPathsExtra, sizeof(g_cPathsExtra), "configs/unloze_zr/extra.txt"); BuildPath(Path_SM, g_cPathsDownload, sizeof(g_cPathsDownload), "configs/unloze_zr/download.txt"); BuildPath(Path_SM, g_cPathsWaveSettings, sizeof(g_cPathsWaveSettings), "configs/unloze_zr/wavesettings.txt"); BuildPath(Path_SM, g_cPathsWeapons, sizeof(g_cPathsWeapons), "configs/unloze_zr/weapons.txt"); //hooks HookEvent("player_spawn", ApplySettings, EventHookMode_Post); HookEvent("round_start", Event_roundStart, EventHookMode_Post); HookEvent("player_death", Event_OnPlayerDeath, EventHookMode_Post); HookEvent("player_hurt", EventPlayerHurt, EventHookMode_Pre); HookEvent("player_jump", EventPlayerJump, EventHookMode_Post); HookEvent("player_team", EventPlayerTeam, EventHookMode_Post); //commands RegConsoleCmd("say", Cmd_Say); RegConsoleCmd("sm_zclass", Cmd_Zclass, "Class Prefferences"); //named like zombiereloaded for ease of use RegConsoleCmd("sm_zmarket", Cmd_zmarket, "weapon Prefferences"); //named like zombiereloaded for ease of use RegConsoleCmd("sm_market", Cmd_zmarket, "weapon Prefferences"); //named like zombiereloaded for ease of use RegConsoleCmd("sm_buy", Cmd_zmarket, "weapon Prefferences"); //named like zombiereloaded for ease of use RegAdminCmd("sm_LoadClasses", Cmd_LoadManually, ADMFLAG_RCON); RegAdminCmd("sm_wave", Cmd_ChangeWave, ADMFLAG_RCON); RegAdminCmd("sm_human", Cmd_Humanize, ADMFLAG_BAN); RegAdminCmd("sm_infect", Cmd_Zombienize, ADMFLAG_BAN); g_hCheckBotStuck = CreateTimer(2.0, Timer_CheckIfBotsStuck, INVALID_HANDLE, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE); g_hZombieSounds = CreateTimer(g_fZMSounds, Timer_zombieSounds, INVALID_HANDLE, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE); g_hFixKNife = CreateTimer(2.0, Timer_FixKNife, INVALID_HANDLE, TIMER_REPEAT); for (int i = 1; i < MaxClients; i++) { if (IsValidClient(i)) { OnClientPostAdminCheck(i); } } } public void OnPluginEnd() { if (g_hCheckBotStuck != null) delete g_hCheckBotStuck; if (g_hZombieSounds != null) delete g_hZombieSounds; if (g_hFixKNife != null) delete g_hFixKNife; if (g_hAmbient != null) delete g_hAmbient; } public Action CheckPlayerTeam(Handle timer, any userid) { int client = GetClientOfUserId(userid); if (client == 0) return Plugin_Continue; checkIfRestartNeeded(); if (!IsValidClient(client) || IsPlayerAlive(client) || (GetClientTeam(client) != CS_TEAM_T && GetClientTeam(client) != CS_TEAM_CT) || IsFakeClient(client)) { return Plugin_Continue; } if (g_iClientRespawnCount[client] > 0) { ChangeClientTeam(client, CS_TEAM_CT); //default putting humans to CT team PrintToChat(client, "You have %i respawns left as human. You will respawn in %f seconds.", g_iClientRespawnCount[client], g_fRespawnTimer); CreateTimer(g_fRespawnTimer, Timer_Respawn, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE); } else { ChangeClientTeam(client, CS_TEAM_T); //default putting humans to ZM PrintToChat(client, "You will respawn as a zombie in %f seconds.", g_fRespawnTimer); CreateTimer(g_fRespawnTimer, Timer_Respawn, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE); } return Plugin_Handled; } public Action EventPlayerTeam(Event event, const char[] name, bool dontBroadcast) { int client = GetClientOfUserId(event.GetInt("userid")); CreateTimer(1.0, CheckPlayerTeam, GetClientUserId(client)); return Plugin_Handled; } public Action Timer_CheckIfRestartNeeded(Handle timer, any userid) { //the bots dont spawn right away. therefore we have the 6 seconds delay for them to actually spawn in. int activeBots = 0; for (int i = 1; i < MaxClients; i++) { if (IsValidClient(i) && IsFakeClient(i) && !IsClientSourceTV(i)) { activeBots++; } if (activeBots > 0) { break; } } if (activeBots == 0) { //bots did still not spawn. we need the restart to spawn them in. PrintToChatAll("First Player joining. Restarting the round..."); CS_TerminateRound(4.0, CSRoundEnd_Draw, true); } return Plugin_Handled; } public void checkIfRestartNeeded() { int activeBots = 0; int activePlayers = 0; for (int i = 1; i < MaxClients; i++) { //if a guy sits in spec it does not restart the round. needed IsPlayerAlive. if (!IsValidClient(i) || IsClientSourceTV(i) || !IsPlayerAlive(i)) { continue; } if (IsFakeClient(i)) { activeBots++; } else { activePlayers++; } if (activeBots > 0 && activePlayers > 0) { break; } } if (activeBots == 0 && activePlayers == 1) { CreateTimer(10.0, Timer_CheckIfRestartNeeded); //if only one guy is on a team we force a restart to spawn the bots. } } public Action ApplySettings(Event event, const char[] name, bool dontBroadcast) { checkIfRestartNeeded(); int client = GetClientOfUserId(event.GetInt("userid")); if (!IsValidClient(client) || !IsPlayerAlive(client) || IsClientSourceTV(client)) { return Plugin_Handled; } //when zombies spawn remove every weapon they have except of knife. When their spawn protection runs out we also check if they have a knife. int l_iWeapon; if (GetClientTeam(client) == CS_TEAM_T) { for (int i = 0; i < 5; i++) { l_iWeapon = GetPlayerWeaponSlot(client, i); if (l_iWeapon != -1 && i != 2) { RemovePlayerItem(client, l_iWeapon); } } } //removing guns from zombies when they spawn. if (!IsFakeClient(client) && g_iClientRespawnCount[client] < 1) //player ran out of human respawns and will be zm instead. { SelectWaveBasedZM(client, 1); } else if (IsFakeClient(client)) //bot getting respawned as zm { CreateTimer(0.3, Timer_delayedSelectWaveBasedZM, GetClientUserId(client)); } else { SelectWavebasedHuman(client); //player getting respawned as human } return Plugin_Handled; } public Action Timer_delayedSelectWaveBasedZM(Handle timer, any userid) { int client = GetClientOfUserId(userid); if (!IsValidClient(client)) { return Plugin_Handled; } SelectWaveBasedZM(client, 0); return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Cmd_LoadManually(int client, int args) { AddDownloadContent(); return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Cmd_zmarket(int client, int args) { Zmarket(client); return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Cmd_Humanize(int client, int args) { InfectionSlashHumanHandling(client, args, 0); return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Cmd_Zombienize(int client, int args) { InfectionSlashHumanHandling(client, args, 1); return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Cmd_Zclass(int client, int args) { Zclass(client); return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Cmd_ChangeWave(int client, int args) { char l_cChangeWave[4]; int l_iWave; GetCmdArg(1, l_cChangeWave, sizeof(l_cChangeWave)); l_iWave = StringToInt(l_cChangeWave); if (l_iWave > 0) { g_iWave = l_iWave; PrintToChatAll("Admin %N Changing to Day %i: %s", client, g_iWave, g_cDaysTitles[g_iWave - 1]); CS_TerminateRound(4.0, CSRoundEnd_Draw, true); } else { ReplyToCommand(client, "Incorrect input"); } return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Cmd_Say(int client, int args) { /* getclientteam might be checked unnecesarily this way because its also checking in ZmarketGetWeapon but this way most can be stopped to interferre from triggering cmd_say */ if (!IsValidClient(client)) { return Plugin_Continue; } if (GetClientTeam(client) != CS_TEAM_CT || !IsPlayerAlive(client)) return Plugin_Continue; char l_cBuffer[g_dLength]; char l_cBuffer2[g_dLength]; GetCmdArgString(l_cBuffer, sizeof(l_cBuffer)); if (StrContains(l_cBuffer, "!") == -1 && StrContains(l_cBuffer, "/") == -1) return Plugin_Continue; ReplaceString(l_cBuffer, sizeof(l_cBuffer), "\"", ""); ReplaceString(l_cBuffer, sizeof(l_cBuffer), "/", ""); ReplaceString(l_cBuffer, sizeof(l_cBuffer), "!", ""); if (StrContains(l_cBuffer, "sm_") == -1) { Format(l_cBuffer2, sizeof(l_cBuffer2), "sm_"); StrCat(l_cBuffer2, sizeof(l_cBuffer2), l_cBuffer); } for (int i = 0; i <= g_iWeaponIndex; i++) { if (strlen(g_cWeaponCommand[i][g_iLength]) < 1) continue; if (StrEqual(l_cBuffer, g_cWeaponCommand[i][g_iLength], false) || StrEqual(l_cBuffer2, g_cWeaponCommand[i][g_iLength], false)) { ZmarketGetWeapon(client, i); break; } } return Plugin_Continue; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action InfectionSlashHumanHandling(int client, int args, int state) { if (args < 1) { ReplyToCommand(client, "[SM] Usage: sm_human <#userid|name>"); ReplyToCommand(client, "[SM] Usage: sm_infect <#userid|name>"); return Plugin_Handled; } findTarget(client, state); return Plugin_Continue; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void findTarget(int client, int state) { //state 0 human, state 1 zm char target[MAX_NAME_LENGTH]; char targetname[MAX_NAME_LENGTH]; int targets[g_dLength]; int result; bool tn_is_ml; GetCmdArg(1, target, sizeof(target)); // Find a target. result = ProcessTargetString(target, client, targets, sizeof(targets), COMMAND_FILTER_ALIVE , targetname, sizeof(targetname), tn_is_ml); // Check if there was a problem finding a client. if (result != 1) { PrintToChat(client, "Found no specific Target!"); return; } if (!IsPlayerAlive(targets[0])) { PrintToChat(client, "Target is not alive. Cant be turned human or zombie."); return; } if (state == 0) { PrintToChat(client, "Humanized: %N", targets[0]); SelectWavebasedHuman(targets[0]); g_iClientRespawnCount[client] = g_iClientRespawnCountNum; } else { g_iClientRespawnCount[client] = 0; PrintToChat(client, "Infected: %N", targets[0]); SelectWaveBasedZM(targets[0], 1); } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void Zmarket(int client) { Menu ZmarketMenu = CreateMenu(Zmarket_menu); ZmarketMenu.SetTitle("Weapon Selection"); for (int i = 0; i < g_iWeaponIndex; i++) { ZmarketMenu.AddItem(g_cWeaponNames[i][g_iLength], g_cWeaponNames[i][g_iLength]); } ZmarketMenu.ExitButton = true; ZmarketMenu.ExitBackButton = true; ZmarketMenu.Display(client, 0); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- static void Zclass(int client) { char l_cHuman[g_dLength]; char l_cZM[g_dLength]; int l_iZMIndex = g_iClientZMClasses[client]; int l_iHumanIndex = g_iClientHumanClasses[client]; Menu ZclassMenu = CreateMenu(Zclass_Menu); //if you did not pick a zm skin it picks the first for you if (strlen(g_cZMRoundClasses[l_iZMIndex][g_iLength]) < 1) { for (int i = 0; i < g_dIndexes; i++) { if (strlen(g_cZMRoundClasses[i][g_iLength]) < 1) continue; l_iZMIndex = i; break; } } //if you did not pick a human skin it picks the first for you if (strlen(g_cHumanClasses[l_iHumanIndex][g_iLength]) < 1) { for (int i = 0; i < g_dIndexes; i++) { if (strlen(g_cHumanClasses[i][g_iLength]) < 1) continue; l_iHumanIndex = i; break; } } Format(l_cZM, sizeof(l_cZM), "Active Zombie Class: %s", g_cZMRoundClasses[l_iZMIndex][g_iLength]); Format(l_cHuman, sizeof(l_cHuman), "Active Human Class: %s", g_cHumanClasses[l_iHumanIndex][g_iLength]); ZclassMenu.SetTitle("TeamClass Selection"); ZclassMenu.AddItem("", "Human Classes"); ZclassMenu.AddItem("", l_cHuman, ITEMDRAW_DISABLED); ZclassMenu.AddItem("", "Zombie Classes"); ZclassMenu.AddItem("", l_cZM, ITEMDRAW_DISABLED); ZclassMenu.ExitButton = true; ZclassMenu.ExitBackButton = true; ZclassMenu.Display(client, 0); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int Zmarket_menu(Menu menu, MenuAction action, int client, int selection) { if (action == MenuAction_Select && IsValidClient(client)) { char info[64]; menu.GetItem(selection, info, sizeof(info)); int weapon_index = 0; for (int i = 0; i < g_iWeaponIndex; i++) { if (StrEqual(g_cWeaponNames[i][g_iLength], info)) { weapon_index = i; break; } } ZmarketGetWeapon(client, weapon_index); } else if (action == MenuAction_End) { delete(menu); } return 0; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int Zclass_Menu(Menu menu, MenuAction action, int client, int selection) { if (action == MenuAction_Select && IsValidClient(client)) { ZclassTeamMenu(client, selection); } else if (action == MenuAction_End) { delete(menu); } return 0; } int GetClientHEGrenades(int client) { return GetEntProp(client, Prop_Data, "m_iAmmo", _, HEGrenadeOffset); } int GetClientSmokeGrenades(int client) { return GetEntProp(client, Prop_Data, "m_iAmmo", _, SmokegrenadeOffset); } int GetClientFlashbangs(int client) { return GetEntProp(client, Prop_Data, "m_iAmmo", _, FlashbangOffset); } //---------------------------------------------------------------------------------------------------- // Purpose: //https://forums.alliedmods.net/showthread.php?t=305092 //---------------------------------------------------------------------------------------------------- public void ZmarketGetWeapon(int client, int index) { if (!IsValidClient(client) || GetClientTeam(client) != CS_TEAM_CT || !IsPlayerAlive(client)) { PrintToChat(client, "You have to be Human for obtaining weapons"); return; } int l_iClientCash = GetEntProp(client, Prop_Send, "m_iAccount"); int l_iEntity; int l_iWeapon; float l_fClientPos[3]; if (g_iWeaponPrice[index] <= l_iClientCash) { l_iEntity = CreateEntityByName(g_cWeaponEntity[index][g_iLength]); if (l_iEntity == -1) { ReplyToCommand(client, "Error occured. cry to jenz"); return; } GetClientAbsOrigin(client, l_fClientPos); l_iWeapon = GetPlayerWeaponSlot(client, g_iWeaponSlot[index]); int has_hegrenade = GetClientHEGrenades(client); int has_smoke = GetClientSmokeGrenades(client); int has_flashbang = GetClientFlashbangs(client); if (StrEqual(g_cWeaponNames[index][g_iLength], "HEGrenade",false) && has_hegrenade) { return; } if (StrEqual(g_cWeaponNames[index][g_iLength], "Smokegrenade",false) && has_smoke) { return; } if (StrEqual(g_cWeaponNames[index][g_iLength], "Flashbang",false) && has_flashbang) { return; } if (IsValidEntity(l_iWeapon)) { if (GetEntPropEnt(l_iWeapon, Prop_Send, "m_hOwnerEntity") != client) { SetEntPropEnt(l_iWeapon, Prop_Send, "m_hOwnerEntity", client); } if (g_iWeaponSlot[index] != 3) { CS_DropWeapon(client, l_iWeapon, false, true); AcceptEntityInput(l_iWeapon, "Kill"); } } TeleportEntity(l_iEntity, l_fClientPos, NULL_VECTOR, NULL_VECTOR); DispatchKeyValueInt(l_iEntity, "ammo", 4500); DispatchSpawn(l_iEntity); SetEntProp(client, Prop_Send, "m_iAccount", l_iClientCash - g_iWeaponPrice[index]); PrintToChat(client, "you purchased: %s", g_cWeaponNames[index][g_iLength]); } else { PrintToChat(client, "Not enough money, requires: %i", g_iWeaponPrice[index]); } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- static void ZclassTeamMenu(int client, int state) { //0 human, 2 zm Menu zclassMenu; AdminId l_AdminID = GetUserAdmin(client); int l_iAdminGroupCount = GetAdminGroupCount(l_AdminID); int l_iFound; int l_iFlags; if (state == 2) { zclassMenu = CreateMenu(Zombieclass_Menu); zclassMenu.SetTitle("Playerclass Zombie Selection"); for (int i = 0; i < g_dIndexes; i++) { if (strlen(g_cZMRoundClasses[i][g_iLength]) < 1) continue; if (strlen(g_cGroup[i][g_iLength]) < 1 && strlen(g_cSMFLAGS[i][g_iLength]) < 1) { zclassMenu.AddItem(g_cZMRoundClasses[i][g_iLength], g_cZMRoundClasses[i][g_iLength]); l_iFound++; } else { l_iFound = 0; if (strlen(g_cGroup[i][g_iLength]) > 0) { for (int j = 0; j < l_iAdminGroupCount; j++) { if (StrEqual(g_cGroup[i][g_iLength], g_cAdminGroups[client][j][g_iLength])) { zclassMenu.AddItem(g_cZMRoundClasses[i][g_iLength], g_cZMRoundClasses[i][g_iLength]); l_iFound++; break; } } } } l_iFlags = ReadFlagString(g_cSMFLAGS[i][g_iLength]); if (GetUserFlagBits(client) & l_iFlags && l_iFound < 1 && strlen(g_cSMFLAGS[i][g_iLength]) > 0) { zclassMenu.AddItem(g_cZMRoundClasses[i][g_iLength], g_cZMRoundClasses[i][g_iLength]); l_iFound++; } if (l_iFound == 0) { zclassMenu.AddItem(g_cZMRoundClasses[i][g_iLength], g_cZMRoundClasses[i][g_iLength], ITEMDRAW_DISABLED); } } } else { zclassMenu = CreateMenu(Humanclass_Menu); zclassMenu.SetTitle("Active Playerclass Human Selection"); for (int i = 0; i < g_dIndexes; i++) { if (strlen(g_cHumanClasses[i][g_iLength]) < 1) continue; if (strlen(g_cGroup[i][g_iLength]) < 1 && strlen(g_cSMFLAGS[i][g_iLength]) < 1) { zclassMenu.AddItem(g_cHumanClasses[i][g_iLength], g_cHumanClasses[i][g_iLength]); l_iFound++; } else { l_iFound = 0; if (strlen(g_cGroup[i][g_iLength]) > 0) { for (int j = 0; j < l_iAdminGroupCount; j++) { if (StrEqual(g_cGroup[i][g_iLength], g_cAdminGroups[client][j][g_iLength])) { zclassMenu.AddItem(g_cHumanClasses[i][g_iLength], g_cHumanClasses[i][g_iLength]); l_iFound++; break; } } } } l_iFlags = ReadFlagString(g_cSMFLAGS[i][g_iLength]); if (GetUserFlagBits(client) & l_iFlags && l_iFound < 1 && strlen(g_cSMFLAGS[i][g_iLength]) > 0) { zclassMenu.AddItem(g_cHumanClasses[i][g_iLength], g_cHumanClasses[i][g_iLength]); l_iFound++; } if (l_iFound == 0) { zclassMenu.AddItem(g_cHumanClasses[i][g_iLength], g_cHumanClasses[i][g_iLength], ITEMDRAW_DISABLED); } } } zclassMenu.ExitButton = true; zclassMenu.ExitBackButton = true; zclassMenu.Display(client, 0); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int Zombieclass_Menu(Menu menu, MenuAction action, int client, int selection) { if (action == MenuAction_Select && IsValidClient(client)) { char info[64]; menu.GetItem(selection, info, sizeof(info)); //going through all zm classes by name until finding the one that matches the menu selection. for (int i = g_iZMBeginindex; i < g_iLoadClassesIndex; i++) { if (StrEqual(g_cZMRoundClasses[i][g_iLength], info)) { g_iClientZMClasses[client] = i; //we found the zm class selected in the menu break; } } char l_cInfo[4]; IntToString(g_iClientZMClasses[client], l_cInfo, sizeof(l_cInfo)); SetClientCookie(client, g_hClientZMCookie, l_cInfo); if (g_bSwitchingIndex && GetClientTeam(client) == CS_TEAM_T && IsPlayerAlive(client)) //beginning of round, is correct team and alive { SelectWaveBasedZM(client, 1); } } else if (action == MenuAction_End) { delete(menu); } return 0; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int Humanclass_Menu(Menu menu, MenuAction action, int client, int selection) { if (action == MenuAction_Select && IsValidClient(client)) { char info[64]; menu.GetItem(selection, info, sizeof(info)); //going through all human classes by name until finding the one that matches the menu selection. for (int i = 0; i < g_iZMBeginindex; i++) { if (StrEqual(g_cHumanClasses[i][g_iLength], info)) { g_iClientHumanClasses[client] = i; //we found the human class selected in the menu break; } } char l_cInfo[4]; IntToString(g_iClientHumanClasses[client], l_cInfo, sizeof(l_cInfo)); SetClientCookie(client, g_hClientHumanCookie, l_cInfo); if (g_bSwitchingIndex && GetClientTeam(client) == CS_TEAM_CT && IsPlayerAlive(client)) //beginning of round, is correct team and alive { SelectWavebasedHuman(client); } } else if (action == MenuAction_End) { delete(menu); } return 0; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action AddDownloadContent() { Handle l_hFile = INVALID_HANDLE; char l_cLine[g_dLength]; l_hFile = OpenFile(g_cPathsDownload, "r"); if (l_hFile == INVALID_HANDLE) { Handle l_kv = CreateKeyValues("DownloadTable"); KeyValuesToFile(l_kv, g_cPathsDownload); CloseHandle(l_kv); delete l_hFile; return Plugin_Handled; } while (!IsEndOfFile(l_hFile) && ReadFileLine(l_hFile, l_cLine, sizeof(l_cLine))) { TrimString(l_cLine); if (strlen(l_cLine) > 0 && StrContains(l_cLine, "//") == -1 && StrContains(l_cLine, "\"") == -1 && StrContains(l_cLine, "{") == -1 && StrContains(l_cLine, "}") == -1) { AddFileToDownloadsTable(l_cLine); } } delete l_hFile; return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void LoadExtraSettings() { g_iSoundIndexes = 0; //forgot to reset, would run out bounds as well. Handle l_hFile = INVALID_HANDLE; char l_cLine[g_dLength]; if (!FileExists(g_cPathsExtra)) { delete l_hFile; LogError("create a extrasettings.txt file!"); return; } l_hFile = OpenFile(g_cPathsExtra, "r"); while (!IsEndOfFile(l_hFile) && ReadFileLine(l_hFile, l_cLine, sizeof(l_cLine))) { if (StrContains(l_cLine, "Respawn Time") > -1) { ReplaceStrings(l_cLine, "Respawn Time"); if (StringToFloat(l_cLine) > 0.0) g_fRespawnTimer = StringToFloat(l_cLine); else g_fRespawnTimer = 5.0; } if (StrContains(l_cLine, "Global command") > -1) { ReplaceStrings(l_cLine, "Global command"); if (strlen(l_cLine) > 1) ServerCommand(l_cLine); } if (StrContains(l_cLine, "round start zclass time") > -1) { ReplaceStrings(l_cLine, "round start zclass time"); if (StringToFloat(l_cLine) > 0.0) g_fSwitchingTimer = StringToFloat(l_cLine); else g_fSwitchingTimer = 15.0; } if (StrContains(l_cLine, "zm spawn protection") > -1) { ReplaceStrings(l_cLine, "zm spawn protection"); if (StringToFloat(l_cLine) > 0.0) g_fZMSpawnProtection = StringToFloat(l_cLine); else g_fZMSpawnProtection = 1.0; } if (StrContains(l_cLine, "human spawn protection") > -1) { ReplaceStrings(l_cLine, "human spawn protection"); if (StringToFloat(l_cLine) > 0.0) g_fHumanSpawnProtection = StringToFloat(l_cLine); else g_fHumanSpawnProtection = 4.0; } if (StrContains(l_cLine, "zmsoundInterval") > -1) { ReplaceStrings(l_cLine, "zmsoundInterval"); if (StringToFloat(l_cLine) > 0.0) g_fZMSounds = StringToFloat(l_cLine); else g_fZMSounds = 15.0; } if (StrContains(l_cLine, "botStuckCount") > -1) { ReplaceStrings(l_cLine, "botStuckCount"); if (StringToInt(l_cLine) > 1) g_iBotStuckCounts = StringToInt(l_cLine); else g_iBotStuckCounts = 3; } if (StrContains(l_cLine, "botStuckPush") > -1) { ReplaceStrings(l_cLine, "botStuckPush"); if (StringToInt(l_cLine) > 1) g_fBotStuckPush = StringToFloat(l_cLine); else g_fBotStuckPush = 250.0; } if (StrContains(l_cLine, "zmsoundsFile") > -1) { ReplaceStrings(l_cLine, "zmsoundsFile"); ReplaceString(l_cLine, sizeof(l_cLine), "sound/", "*/"); Format(g_cZMSounds[g_iSoundIndexes][g_iLength], sizeof(g_cZMSounds), l_cLine); PrecacheSound(g_cZMSounds[g_iSoundIndexes][g_iLength]); g_iSoundIndexes++; } if (StrContains(l_cLine, "ambientSound", false) > -1) { ReplaceStrings(l_cLine, "ambientSound"); ExplodeString(l_cLine, ",", g_cAmbientSOund, 64, 512); } if (StrContains(l_cLine, "ambientLoopDuration") > -1) { ReplaceStrings(l_cLine, "ambientLoopDuration"); if (StringToInt(l_cLine) > 1) g_fAmbientSoundLoopDuration = StringToFloat(l_cLine); else g_fAmbientSoundLoopDuration = 10.0; } if (StrContains(l_cLine, "bossSound", false) > -1) { ReplaceStrings(l_cLine, "bossSound"); Format(g_cBossSound, sizeof(g_cBossSound), l_cLine); } if (StrContains(l_cLine, "bossLoopDuration") > -1) { ReplaceStrings(l_cLine, "bossLoopDuration"); if (StringToInt(l_cLine) > 1) g_fBossSoundLoopDuration = StringToFloat(l_cLine); else g_fBossSoundLoopDuration = 10.0; } } delete l_hFile; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void loadWeapons() { KeyValues kv = CreateKeyValues("Weapons"); if (!FileExists(g_cPathsWeapons)) { delete kv; LogError("create kv file"); return; } g_iWeaponIndex = 0; //ofc this has to be reset, otherwise it ends up going out of bounds dx kv.ImportFromFile(g_cPathsWeapons); kv.GotoFirstSubKey(); kv.GetString("weaponentity", g_cWeaponEntity[g_iWeaponIndex][g_iLength], sizeof(g_cWeaponEntity)); kv.GetString("zmarketname", g_cWeaponNames[g_iWeaponIndex][g_iLength], sizeof(g_cWeaponNames)); g_iWeaponSlot[g_iWeaponIndex] = kv.GetNum("weaponslot"); g_iWeaponPrice[g_iWeaponIndex] = kv.GetNum("zmarketprice"); kv.GetString("zmarketcommand", g_cWeaponCommand[g_iWeaponIndex][g_iLength], sizeof(g_cWeaponCommand)); g_iWeaponIndex++; while (kv.GotoNextKey()) { kv.GetString("weaponentity", g_cWeaponEntity[g_iWeaponIndex][g_iLength], sizeof(g_cWeaponEntity)); kv.GetString("zmarketname", g_cWeaponNames[g_iWeaponIndex][g_iLength], sizeof(g_cWeaponNames)); g_iWeaponSlot[g_iWeaponIndex] = kv.GetNum("weaponslot"); g_iWeaponPrice[g_iWeaponIndex] = kv.GetNum("zmarketprice"); kv.GetString("zmarketcommand", g_cWeaponCommand[g_iWeaponIndex][g_iLength], sizeof(g_cWeaponCommand)); g_iWeaponIndex++; } delete kv; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action LoadClasses() { Handle l_hFile = INVALID_HANDLE; Handle l_hFileZM = INVALID_HANDLE; char l_cLine[g_dLength]; g_iLoadClassesIndex = 0; l_hFile = OpenFile(g_cPathsClassHuman, "r"); l_hFileZM = OpenFile(g_cPathsClassZM, "r"); if (!FileExists(g_cPathsClassHuman) || !FileExists(g_cPathsClassZM)) { delete l_hFile; delete l_hFileZM; LogError("You need to create the classeshuman.txt and the classeszm.txt"); return Plugin_Handled; } //first indexes go to human classes, all afterfollowing to zms while (!IsEndOfFile(l_hFile) && ReadFileLine(l_hFile, l_cLine, sizeof(l_cLine))) { ReadingClassValuesFromFile(g_iLoadClassesIndex, l_cLine); } //after going through humans are all remaining indexes for zombies. g_iZMBeginindex = g_iLoadClassesIndex; while (!IsEndOfFile(l_hFileZM) && ReadFileLine(l_hFileZM, l_cLine, sizeof(l_cLine))) { ReadingClassValuesFromFile(g_iLoadClassesIndex, l_cLine); } delete l_hFileZM; delete l_hFile; return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnMapStart() { g_iToolsVelocity = FindDataMapInfo(0, "m_vecAbsVelocity"); g_iWave = 1; //load content AddDownloadContent(); LoadClasses(); LoadExtraSettings(); loadWeapons(); loadDays(); } //just checking the knife when they spawn is appereantly not good enough. this is just repeating what Timer_StopProtection does. public Action Timer_FixKNife(Handle timer, any userid) { for (int client = 0; client < MaxClients; client++) { if (IsValidClient(client) && IsPlayerAlive(client)) { //the fucking forwards wont give the bots the client tags. it should obviously work. cause it works on ze. //too bad! if (IsFakeClient(client)) { char tag[64]; Format(tag, sizeof(tag), "UNLOZE "); CS_SetClientClanTag(client, tag); } if (GetClientTeam(client) == CS_TEAM_T) { if (GetPlayerWeaponSlot(client, CS_SLOT_KNIFE) == -1) //just making sure everybody has a knife. otherwise giving them one { GivePlayerItem(client, "weapon_knife"); CreateTimer(1.0, Timer_SwitchKnife, GetClientOfUserId(client)); } } } } return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnClientPostAdminCheck(int client) { g_iSpeedDelayClient[client] = 0; g_bClientProtection[client] = false; g_bFallDamage[client] = false; g_fKnockBackIndex[client] = 1.0; g_fJumpHeightIndex[client] = 1.0; g_fJumpDistanceIndex[client] = 1.0; g_fDamageMultiplier[client] = 1.0; g_bClientIsBoss[client] = false; g_iClientRespawnCount[client] = g_iClientRespawnCountNum; char sCookieValue[12]; GetClientCookie(client, g_hClientZMCookie, sCookieValue, sizeof(sCookieValue)); if (sCookieValue[0]) { g_iClientZMClasses[client] = StringToInt(sCookieValue); } else { g_iClientZMClasses[client] = g_iZMBeginindex; } GetClientCookie(client, g_hClientHumanCookie, sCookieValue, sizeof(sCookieValue)); if (sCookieValue[0]) { g_iClientHumanClasses[client] = StringToInt(sCookieValue); } else { g_iClientHumanClasses[client] = 0; } SetAdminGroups(client); } public void OnClientPutInServer(int client) { SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage); SDKHook(client, SDKHook_WeaponEquip, OnWeaponEquip); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void SetAdminGroups(int client) { AdminId l_AdminID = GetUserAdmin(client); int l_iAdminGroupCount = GetAdminGroupCount(l_AdminID); char l_cbuffer[g_dLength]; for (int j = 0; j < l_iAdminGroupCount; j++) { GetAdminGroup(l_AdminID, j, l_cbuffer, sizeof(l_cbuffer)); Format(g_cAdminGroups[client][j][g_iLength], sizeof(g_cAdminGroups), l_cbuffer); } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnClientDisconnect(int client) { g_iSpeedDelayClient[client] = 0; g_bClientProtection[client] = false; g_bFallDamage[client] = false; g_fKnockBackIndex[client] = 1.0; g_fJumpHeightIndex[client] = 1.0; g_fJumpDistanceIndex[client] = 1.0; g_fDamageMultiplier[client] = 1.0; g_iClientRespawnCount[client] = 0; g_bClientIsBoss[client] = false; SDKUnhook(client, SDKHook_OnTakeDamage, OnTakeDamage); SDKUnhook(client, SDKHook_WeaponEquip, OnWeaponEquip); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void Event_roundStart(Handle event, const char[] name, bool dontBroadcast) { g_iHumanCount = 999; g_iZombieCount = 999; g_bRoundInProgress = false; g_bSwitchingIndex = true; g_iBossBotCount = 0; CreateTimer(g_fSwitchingTimer, Timer_switchingModel, INVALID_HANDLE); if (g_hAmbient != null) delete g_hAmbient; if (StrContains(g_cDaysTitles[g_iWave - 1], "BOSS", false) != -1) //the daystitle contains the word boss in it { g_bIsBossRound = true; //boss rounds need BOSS in the title EmitAmbience(g_cBossSound); //nobody will ever understand why megalovania was on the servers since 2020. g_hAmbient = CreateTimer(g_fBossSoundLoopDuration, Timer_Ambient, INVALID_HANDLE, TIMER_REPEAT); // 0.3 seconds without sound } else { g_bIsBossRound = false; //boss rounds need BOSS in the title int index = ambient_index(); EmitAmbience(g_cAmbientSOund[index]); g_hAmbient = CreateTimer(g_fAmbientSoundLoopDuration, Timer_Ambient, INVALID_HANDLE, TIMER_REPEAT); // 0.3 seconds without sound } RetrieveWaveSettings(g_iWave); for (int i = 1; i <= MaxClients; i++) { if (IsValidClient(i) && !IsClientSourceTV(i)) { if (IsFakeClient(i)) { g_bClientIsBoss[i] = false; CreateTimer(0.3, Timer_delayedSelectWaveBasedZM, GetClientUserId(i)); continue; } g_iClientRespawnCount[i] = g_iClientRespawnCountNum; //even if not spawned in yet it should be set for every real player. if (IsPlayerAlive(i)) { SelectWavebasedHuman(i); } } } } public int ambient_index() { int index = 0; for (int i = 0; i < sizeof(g_cAmbientSOund); i++) { if (strlen(g_cAmbientSOund[i]) == 0) { index = (g_iWave - 1) % i; break; } } return index; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action RetrieveWaveSettings(int wave) { Handle l_hWave = INVALID_HANDLE; l_hWave = OpenFile(g_cPathsWaveSettings, "r"); if (l_hWave == INVALID_HANDLE) { LogError("create a wavesettings.txt file"); delete l_hWave; return Plugin_Handled; } int total_days = 23; for (int i = 0; i < sizeof(g_cDaysTitles); i++) { if (strlen(g_cDaysTitles[i]) == 0) { total_days = i; break; } } char hostname[512]; Format(hostname, sizeof(hostname), "UNLOZE | [ZRiot: Day %i/%i] %s | Ranking", wave, total_days, g_cDaysTitles[wave - 1]); ServerCommand("hostname \"%s\"", hostname); PrintToChatAll("Day %i: %s", wave, g_cDaysTitles[wave - 1]); LoadWave(wave); delete l_hWave; return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Timer_switchingModel(Handle timer, any data) { g_bSwitchingIndex = false; return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void LoadWave(int wave) { KeyValues kv = CreateKeyValues("Waves"); KeyValues kv1 = CreateKeyValues("Waves"); int l_iBotQuote; char l_cJumptokey[16]; char l_cJumptokey1[16]; char l_cLine[g_dLength]; bool l_bKeyIndex = false; Handle l_hFile = INVALID_HANDLE; l_hFile = OpenFile(g_cPathsWaveSettings, "r"); Format(l_cJumptokey, sizeof(l_cJumptokey), "Wave %i", wave); Format(l_cJumptokey1, sizeof(l_cJumptokey1), "Wave %i", wave +1); for (int i = 0; i < g_dIndexes; i++) { //resetting human and zombie classes each round/wave. Format(g_cHumanClasses[i][g_iLength], sizeof(g_cHumanClasses), ""); Format(g_cZMRoundClasses[i][g_iLength], sizeof(g_cZMRoundClasses), ""); } kv.ImportFromFile(g_cPathsWaveSettings); kv1.ImportFromFile(g_cPathsWaveSettings); if (!kv1.JumpToKey(l_cJumptokey1, false)) { //next wave does not exist, so we reached end wave right now. //according to the random guy from italy who made his identity smoking weed we force mapvotes on last day and then forcertv when restarting //from day 1 PrintToChatAll("Reached last day. Initiating the mapvote!"); ServerCommand("sm_mapvote"); //old zombieRiot did this so just copying it } if (kv.JumpToKey(l_cJumptokey, false)) { g_bRoundInProgress = true; g_iZMScaleability = kv.GetFloat("PlayerScaleAbility", 5.0); g_fZMHealthScaleability = kv.GetFloat("HealthScaleAbility", 1.0); g_iZMCount = kv.GetNum("Zombie Count", 5); int additional_zombie_per_player = RoundFloat(g_iZMCount * g_iZMScaleability); int l_iPlayers; for (int i = 1; i <= MaxClients; i++) { if (IsValidClient(i) && !IsFakeClient(i) && CS_TEAM_CT == GetClientTeam(i)) { l_iPlayers++; } } l_iPlayers -= 1; //first player equals the zombie count. //first player takes the zombie count, each additional player adds to additional_zombie_per_player //if 1 player then additional_zombie_per_player * 0. so just g_iZMCount g_iZMCount += additional_zombie_per_player * l_iPlayers; g_iClientRespawnCountNum = kv.GetNum("Respawns", 5); l_iBotQuote = kv.GetNum("bot_scaling", 1); int l_iBotQuoteStatic = kv.GetNum("bot_static", 1); l_iPlayers = 0; //counting legit players for bot scaling. for (int i = 1; i < MaxClients; i++) { if (IsValidClient(i) && !IsFakeClient(i) && CS_TEAM_CT == GetClientTeam(i)) { l_iPlayers++; } } if (g_bIsBossRound) { //its boss round. bot_scaling is used for minion bots. bot_static is used for boss bot amount // bot_static + bot_scaling addBots(l_iBotQuoteStatic + (l_iPlayers * l_iBotQuote)); g_iBossBotCount = l_iBotQuoteStatic; } else { //its not boss round. if (l_iBotQuote == 0) //we use static bot amount instead of scaling bots based on playercount. { addBots(l_iBotQuoteStatic); } else { //we use bot_scaling. addBots(l_iPlayers * l_iBotQuote); } } while (!IsEndOfFile(l_hFile) && ReadFileLine(l_hFile, l_cLine, sizeof(l_cLine))) { if (StrContains(l_cLine, l_cJumptokey) == -1 && !l_bKeyIndex) { continue; } l_bKeyIndex = true; if (StrContains(l_cLine, "wavecommand") > -1) { ReplaceStrings(l_cLine, "wavecommand"); if (strlen(l_cLine) > 0) ServerCommand(l_cLine); } else if (StrContains(l_cLine, "Zombie Class") > -1) { ReplaceStrings(l_cLine, "Zombie Class"); if (StrContains(l_cLine, "@all") > -1) { //in this case it just goes through all zombie classes for (int i = g_iZMBeginindex; i < g_iLoadClassesIndex; i++) { Format(g_cZMRoundClasses[i][g_iLength], sizeof(g_cZMRoundClasses), g_cUniqueName[i][g_iLength]); } } else if (StrContains(l_cLine, "@groups") > -1) { for (int i = 0; i < g_dIndexes; i++) { if (skipIndex(i)) { continue; } if ((strlen(g_cGroup[i][g_iLength]) > 0) && StrEqual(g_cTeam[i][g_iLength], "ZM")) { Format(g_cZMRoundClasses[i][g_iLength], sizeof(g_cZMRoundClasses), g_cUniqueName[i][g_iLength]); } } } else if (StrContains(l_cLine, "@flags") > -1) { for (int i = 0; i < g_dIndexes; i++) { if (skipIndex(i)) { continue; } if (strlen(g_cSMFLAGS[i][g_iLength]) > 0 && StrEqual(g_cTeam[i][g_iLength], "ZM")) { Format(g_cZMRoundClasses[i][g_iLength], sizeof(g_cZMRoundClasses), g_cUniqueName[i][g_iLength]); } } } else { for (int i = 0; i < g_dIndexes; i++) { if (skipIndex(i)) { continue; } if (StrEqual(l_cLine, g_cUniqueName[i][g_iLength], false)) { Format(g_cZMRoundClasses[i][g_iLength], sizeof(g_cZMRoundClasses), g_cUniqueName[i][g_iLength]); break; } } } } else if (StrContains(l_cLine, "Human Class") > -1) { ReplaceStrings(l_cLine, "Human Class"); if (StrContains(l_cLine, "@all") > -1) { for (int i = 0; i < g_iZMBeginindex; i++) { Format(g_cHumanClasses[i][g_iLength], sizeof(g_cHumanClasses), g_cUniqueName[i][g_iLength]); } } else if (StrContains(l_cLine, "@groups") > -1) { for (int i = 0; i < g_dIndexes; i++) { if (skipIndex(i)) { continue; } if (strlen(g_cGroup[i][g_iLength]) > 0 && StrEqual(g_cTeam[i][g_iLength], "Human")) { Format(g_cHumanClasses[i][g_iLength], sizeof(g_cHumanClasses), g_cUniqueName[i][g_iLength]); } } } else if (StrContains(l_cLine, "@flags") > -1) { for (int i = 0; i < g_dIndexes; i++) { if (skipIndex(i)) { continue; } if (strlen(g_cSMFLAGS[i][g_iLength]) > 0 && StrEqual(g_cTeam[i][g_iLength], "Human")) { Format(g_cHumanClasses[i][g_iLength], sizeof(g_cHumanClasses), g_cUniqueName[i][g_iLength]); } } } else { for (int i = 0; i < g_dIndexes; i++) { if (skipIndex(i)) { continue; } if (StrEqual(l_cLine, g_cUniqueName[i][g_iLength], false)) { Format(g_cHumanClasses[i][g_iLength], sizeof(g_cHumanClasses), g_cUniqueName[i][g_iLength]); break; } } } } if (StrContains(l_cLine, l_cJumptokey1) > -1) { break; } } } else { g_iWave = 1; PrintToChatAll("Finished last Day! Forcing map change..."); ServerCommand("sm_forcertv"); //old zombieRiot did this so just copying it CS_TerminateRound(4.0, CSRoundEnd_CTWin, true); //without this it wont change map i guess? or at least without it they get a wave without settings set. } delete kv; delete kv1; delete l_hFile; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void addBots(int botcount) { if (botcount > 44) { botcount = 44; } ServerCommand("bot_quota %i", botcount); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public bool skipIndex(int index) { if (strlen(g_cTeam[index][g_iLength]) < 1 || strlen(g_cUniqueName[index][g_iLength]) < 1) { return true; } return false; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void ReadingClassValuesFromFile(int index, char[] Line) { char li_c[g_dLength]; Format(li_c, sizeof(li_c), Line); if (StrContains(Line, "unique name") > -1) { ReplaceStrings(li_c, "unique name"); Format(g_cUniqueName[index][g_iLength], sizeof(g_cUniqueName), li_c); } else if (StrContains(Line, "team") > -1) { ReplaceStrings(li_c, "team"); Format(g_cTeam[index][g_iLength], sizeof(g_cTeam), li_c); } else if (StrContains(Line, "group") > -1) { ReplaceStrings(li_c, "group"); Format(g_cGroup[index][g_iLength], sizeof(g_cGroup), li_c); } else if (StrContains(Line, "sm_flags") > -1) { ReplaceStrings(li_c, "sm_flags"); Format(g_cSMFLAGS[index][g_iLength], sizeof(g_cSMFLAGS), li_c); } else if (StrContains(Line, "model path") > -1) { ReplaceStrings(li_c, "model path"); Format(g_cModelPath[index][g_iLength], sizeof(g_cModelPath), li_c); PrecacheModel(li_c); } else if (StrContains(Line, "no_fall_damage") > -1) { ReplaceStrings(li_c, "no_fall_damage"); Format(g_cNoFallDmg[index][g_iLength], sizeof(g_cNoFallDmg), li_c); } else if (StrContains(Line, "health") > -1) { ReplaceStrings(li_c, "health"); Format(g_cHealth[index][g_iLength], sizeof(g_cHealth), li_c); } else if (StrContains(Line, "speed") > -1) { ReplaceStrings(li_c, "speed"); Format(g_cSpeed[index][g_iLength], sizeof(g_cSpeed), li_c); } else if (StrContains(Line, "knockback") > -1) { ReplaceStrings(li_c, "knockback"); Format(g_cKnockback[index][g_iLength], sizeof(g_cKnockback), li_c); } else if (StrContains(Line, "jump_height") > -1) { ReplaceStrings(li_c, "jump_height"); Format(g_cJumpHeight[index][g_iLength], sizeof(g_cJumpHeight), li_c); } else if (StrContains(Line, "jump_distance") > -1) { ReplaceStrings(li_c, "jump_distance"); Format(g_cJumpDistance[index][g_iLength], sizeof(g_cJumpDistance), li_c); } else if (StrContains(Line, "damage_multiplier") > -1) { ReplaceStrings(li_c, "damage_multiplier"); Format(g_cDamageMultiplier[index][g_iLength], sizeof(g_cDamageMultiplier), li_c); } else if (StrContains(Line, "boss_class") > -1) { ReplaceStrings(li_c, "boss_class"); g_iZombieBossIndex[index] = StringToInt(li_c); g_iLoadClassesIndex++; //use this at the last keyvalue to indicate we are done. } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- //we should only be able to land in here if terrorist or CT. public Action SelectWavebasedHuman(int client) { if (!IsValidClient(client)) return Plugin_Handled; if (GetClientTeam(client) == CS_TEAM_T) { ChangeClientTeam(client, CS_TEAM_CT); //default putting humans to CT team CreateTimer(1.0, Timer_delayedRespawn, GetClientUserId(client)); return Plugin_Continue; } if (!IsPlayerAlive(client) && CS_TEAM_CT) //this should help if you spawn late into a round so that you actually respawn { CreateTimer(1.0, Timer_delayedRespawn, GetClientUserId(client)); return Plugin_Continue; } ModelSelection(client, 2, g_iClientHumanClasses[client]); return Plugin_Continue; } public Action Timer_delayedRespawn(Handle timer, any userid) { int client = GetClientOfUserId(userid); if (!IsValidClient(client)) { return Plugin_Handled; } CS_RespawnPlayer(client); //respawning because changeclientteam kills the player on css return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action SelectWaveBasedZM(int client, int state) { if (!IsValidClient(client)) return Plugin_Handled; if (GetClientTeam(client) == CS_TEAM_CT) { ChangeClientTeam(client, CS_TEAM_T); //default putting bots to t CreateTimer(0.3, Timer_delayedRespawn, GetClientUserId(client)); return Plugin_Handled; } //state 0 was bot, state 1 was real player. if (!IsValidClient(client)) return Plugin_Handled; int l_iZMIndex; int l_ibotIndex; if (state == 0) { if (g_bIsBossRound && g_iBossBotCount > 0 && !g_bClientIsBoss[client]) //does not work setting on roundstart. so instead doing when applying ZM skin. { g_bClientIsBoss[client] = true; g_iBossBotCount--; //picking certain bots as the boss bots. all other bots are the minions. } if (g_bIsBossRound) { if (g_bClientIsBoss[client]) { //its boss round and we set class for a boss bot for (int i = 0; i < g_dIndexes; i++) { if (strlen(g_cZMRoundClasses[i][g_iLength]) > 0 && strlen(g_cGroup[i][g_iLength]) < 1 && strlen(g_cSMFLAGS[i][g_iLength]) < 1 && g_iZombieBossIndex[i]) { l_iZMIndex++; //we set amount of boss classes that the boss bot can pick between. } } l_ibotIndex = GetRandomInt(0, l_iZMIndex -1); l_iZMIndex = 0; for (int i = 0; i < g_dIndexes; i++) { if (strlen(g_cZMRoundClasses[i][g_iLength]) > 0 && strlen(g_cGroup[i][g_iLength]) < 1 && strlen(g_cSMFLAGS[i][g_iLength]) < 1) { if (!g_iZombieBossIndex[i]) { continue; } else if (l_ibotIndex == l_iZMIndex) { g_iClientZMClasses[client] = i; break; } else { l_iZMIndex++; } } } } else { //its boss round and we set class for a minion bot for (int i = 0; i < g_dIndexes; i++) { if (strlen(g_cZMRoundClasses[i][g_iLength]) > 0 && strlen(g_cGroup[i][g_iLength]) < 1 && strlen(g_cSMFLAGS[i][g_iLength]) < 1 && !g_iZombieBossIndex[i]) { l_iZMIndex++; //we set amount of normal zombie classes the minion bot can pick between. skipping out the boss classes. } } l_ibotIndex = GetRandomInt(0, l_iZMIndex -1); l_iZMIndex = 0; for (int i = 0; i < g_dIndexes; i++) { if (strlen(g_cZMRoundClasses[i][g_iLength]) > 0 && strlen(g_cGroup[i][g_iLength]) < 1 && strlen(g_cSMFLAGS[i][g_iLength]) < 1) { if (g_iZombieBossIndex[i]) { continue; } else if (l_ibotIndex == l_iZMIndex) { g_iClientZMClasses[client] = i; break; } else { l_iZMIndex++; } } } } } else { //its normal round. just setting the classes randomly. for (int i = 0; i < g_dIndexes; i++) { if (strlen(g_cZMRoundClasses[i][g_iLength]) > 0 && strlen(g_cGroup[i][g_iLength]) < 1 && strlen(g_cSMFLAGS[i][g_iLength]) < 1) { l_iZMIndex++; //here we get to know what the last index is, that way the randomint can pick between index 0 and last index for ZM classes. } } l_ibotIndex = GetRandomInt(0, l_iZMIndex -1); l_iZMIndex = 0; for (int i = 0; i < g_dIndexes; i++) { if (strlen(g_cZMRoundClasses[i][g_iLength]) > 0 && strlen(g_cGroup[i][g_iLength]) < 1 && strlen(g_cSMFLAGS[i][g_iLength]) < 1) { if (l_ibotIndex == l_iZMIndex) { g_iClientZMClasses[client] = i; break; } else { l_iZMIndex++; } } } } } //if no model selected just picks the first available for players else if (strlen(g_cZMRoundClasses[g_iClientZMClasses[client]][g_iLength]) < 1) { for (int i = 0; i < g_dIndexes; i++) { if (strlen(g_cZMRoundClasses[i][g_iLength]) > 0) { g_iClientZMClasses[client] = i; break; } } } //im just getting desperate at this point for fixing the client crash by adding random ass delays. CreateTimer(0.3, Timer_delayedModelSelection, GetClientUserId(client)); return Plugin_Handled; } public Action Timer_delayedModelSelection(Handle timer, any userid) { int client = GetClientOfUserId(userid); if (!IsValidClient(client) || !IsPlayerAlive(client)) { return Plugin_Handled; } ModelSelection(client, 1, g_iClientZMClasses[client]); return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action ModelSelection(int client, int state, int modelIndex) { //state 1 = zombie players, state 2 = human players char l_cUniqueModel[g_dLength]; int l_iModelIndex; l_iModelIndex = modelIndex; if (state < 2) { Format(l_cUniqueModel, sizeof(l_cUniqueModel), g_cZMRoundClasses[l_iModelIndex][g_iLength]); } else if (state == 2) { Format(l_cUniqueModel, sizeof(l_cUniqueModel), g_cHumanClasses[l_iModelIndex][g_iLength]); } for (int i = 0; i < g_dIndexes; i++) { if (strlen(g_cUniqueName[i][g_iLength]) < 1) { continue; } if (StrContains(g_cUniqueName[i][g_iLength], l_cUniqueModel, false) > -1) { if (StrContains(g_cModelPath[i][g_iLength], ".mdl") != -1) { //if its a public skin we go in here. we skip this if its the "store skin". in those cases we let the store decide the .mdl for the player. //otherwise we assign the .mdl here. //in practise only one human skin will not have .mdl set. we only do not end here when its that one human model. SetEntityModel(client, g_cModelPath[i][g_iLength]); } g_bClientProtection[client] = true; if (StrContains(g_cNoFallDmg[i][g_iLength], "YES") > -1) g_bFallDamage[client] = true; else g_bFallDamage[client] = false; g_iSpeedDelayClient[client] = i; //setting this shit with a delay because it otherwise causes client crashes. CreateTimer(3.0, Timer_SetSpeed, GetClientUserId(client)); if (state < 2) { CreateTimer(g_fZMSpawnProtection, Timer_StopProtection, GetClientUserId(client)); } else { CreateTimer(g_fHumanSpawnProtection, Timer_StopProtection, GetClientUserId(client)); } g_fKnockBackIndex[client] = StringToFloat(g_cKnockback[i][g_iLength]); g_fJumpHeightIndex[client] = StringToFloat(g_cJumpHeight[i][g_iLength]); g_fJumpDistanceIndex[client] = StringToFloat(g_cJumpDistance[i][g_iLength]); g_fDamageMultiplier[client] = StringToFloat(g_cDamageMultiplier[i][g_iLength]); return Plugin_Handled; } } return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Timer_CheckIfBotsStuck(Handle timer, any userid) { float l_fClientVelocity[3]; for (int i = 1; i < MaxClients; i++) { if (IsValidClient(i) && IsFakeClient(i) && IsPlayerAlive(i)) { GetEntPropVector(i, Prop_Data, "m_vecAbsVelocity", l_fClientVelocity); if (l_fClientVelocity[0] < 30.0 && l_fClientVelocity[0] > -30.0 && l_fClientVelocity[1] < 30.0 && l_fClientVelocity[1] > -30.0) { g_iBotStuckindex[i]++; } else { g_iBotStuckindex[i] = 0; } if (g_iBotStuckindex[i] > g_iBotStuckCounts) { l_fClientVelocity[0] -= GetRandomInt(50, 250); l_fClientVelocity[1] -= GetRandomInt(50, 250); l_fClientVelocity[2] = g_fBotStuckPush * 5; Entity_SetAbsVelocity(i, l_fClientVelocity); g_iBotStuckindex[i] = 0; } } } return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Timer_zombieSounds(Handle timer, any userid) { int[] l_clients = new int[MaxClients + 1]; int l_client; int l_iclientCount; int l_iSoundIndexes; for (int i = 1; i < MaxClients; i++) { if (IsValidClient(i) && GetClientTeam(i) == CS_TEAM_T) { l_clients[l_iclientCount++] = i; } } l_client = l_clients[GetRandomInt(0, l_iclientCount - 1)]; l_iSoundIndexes = GetRandomInt(0, g_iSoundIndexes - 1); for (int i = 1; i < MaxClients; i++) { if (IsValidClient(i) && !IsFakeClient(i)) { EmitSoundToClient(i, g_cZMSounds[l_iSoundIndexes][g_iLength], l_client); } } return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Timer_Respawn(Handle timer, any userid) { int client = GetClientOfUserId(userid); if (client == 0) return Plugin_Continue; if (!IsValidClient(client) || IsPlayerAlive(client) || (GetClientTeam(client) != CS_TEAM_T && GetClientTeam(client) != CS_TEAM_CT)) { return Plugin_Continue; } UpdateWaveCount(client); if (!IsFakeClient(client) && g_iClientRespawnCount[client] < 1) { ChangeClientTeam(client, CS_TEAM_T); //ran out of respawns for CT } else if (IsFakeClient(client) && GetClientTeam(client) != CS_TEAM_T) { ChangeClientTeam(client, CS_TEAM_T); } else if (!IsFakeClient(client) && GetClientTeam(client) != CS_TEAM_CT) { ChangeClientTeam(client, CS_TEAM_CT); //default putting humans to CT team } CreateTimer(1.0, Timer_delayedRespawn, GetClientUserId(client)); return Plugin_Continue; } //this shit has to be delayed because it otherwise causes client crashes public Action Timer_SetSpeed(Handle timer, any userid) { int client = GetClientOfUserId(userid); if (client == 0) return Plugin_Continue; if (IsValidClient(client) && IsPlayerAlive(client) && g_iSpeedDelayClient[client] != 0) { //setting the class speed simply. SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", StringToFloat(g_cSpeed[g_iSpeedDelayClient[client]][g_iLength])); if (GetClientTeam(client) == CS_TEAM_T) //setting the zombie health here using the HealthScaleAbility. { int l_iPlayers; for (int j = 1; j <= MaxClients; j++) { if (IsValidClient(j) && !IsFakeClient(j) && CS_TEAM_CT == GetClientTeam(j)) { l_iPlayers++; } } l_iPlayers -= 1; //first player indicates the full health of the class, each additional uses scaleability health. int additional_zombie_health_per_player = RoundFloat(g_fZMHealthScaleability * StringToInt(g_cHealth[g_iSpeedDelayClient[client]][g_iLength])); SetEntityHealth(client, StringToInt(g_cHealth[g_iSpeedDelayClient[client]][g_iLength]) + (additional_zombie_health_per_player * l_iPlayers)); } else if (CS_TEAM_CT == GetClientTeam(client)) { // smrpg //checking if the health perk is used by the player, this basically makes the hp setting in the config useless most of the time. //but looks like people just anyways will want CT to always have 100 HP. if (SMRPG_Health_GetClientMaxHealth(client) == 100) { SetEntityHealth(client, StringToInt(g_cHealth[g_iSpeedDelayClient[client]][g_iLength])); } } } return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Timer_StopProtection(Handle timer, any userid) { int client = GetClientOfUserId(userid); if (client == 0) return Plugin_Continue; if (IsValidClient(client) && IsPlayerAlive(client)) { g_bClientProtection[client] = false; if (GetClientTeam(client) == CS_TEAM_T) { Client_ChangeWeapon(client, "weapon_knife"); } if (GetPlayerWeaponSlot(client, CS_SLOT_KNIFE) == -1) //just making sure everybody has a knife. otherwise giving them one { GivePlayerItem(client, "weapon_knife"); if (GetClientTeam(client) == CS_TEAM_T) { CreateTimer(1.0, Timer_SwitchKnife, GetClientOfUserId(client)); } } } return Plugin_Handled; } public Action Timer_SwitchKnife(Handle timer, any userid) { int client = GetClientOfUserId(userid); if (client == 0) return Plugin_Continue; if (!IsValidClient(client) || !IsPlayerAlive(client)) { return Plugin_Continue; } Client_ChangeWeapon(client, "weapon_knife"); return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Event_OnPlayerDeath(Handle event, const char[] name, bool dontBroadcast) { int client = GetClientOfUserId(GetEventInt(event, "userid")); if(!client || !IsClientInGame(client)) return Plugin_Continue; if (IsFakeClient(client)) { CreateTimer(1.0, Timer_Respawn, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE); } else { if (g_iClientRespawnCount[client] > 0) { PrintToChat(client, "You have %i respawns left as human. You will respawn in %f seconds.", g_iClientRespawnCount[client], g_fRespawnTimer); } else { PrintToChat(client, "You will respawn as a zombie in %f seconds.", g_fRespawnTimer); } CreateTimer(g_fRespawnTimer, Timer_Respawn, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE); } return Plugin_Continue; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action UpdateWaveCount(int client) { if (GetClientTeam(client) == CS_TEAM_CT) { g_iClientRespawnCount[client]--; for (int i = 1; i <= MaxClients; i++) { if (IsValidClient(i) && IsPlayerAlive(i) && GetClientTeam(i) == CS_TEAM_CT) { return Plugin_Handled; } } PrintToChatAll("All Humans died!"); CS_TerminateRound(4.0, CSRoundEnd_TerroristWin, true); return Plugin_Handled; } else if (GetClientTeam(client) == CS_TEAM_T) { int zombieCount = 0; int humanCount = 0; for (int i = 1; i <= MaxClients; i++) { if (IsValidClient(i)) { if (GetClientTeam(i) == CS_TEAM_CT) { humanCount++; } else if (GetClientTeam(i) == CS_TEAM_T) { zombieCount++; } } } if (g_bIsBossRound) { //we only reduce zombie count if the killed bot had a boss zombie class. //if the killed bot instead had a zombie class of a minion we do not reduce the zombie count. if (g_bClientIsBoss[client]) { g_iZMCount--; PrintHintTextToAll("Day %i: %s\nRemaining Zombies: %i\nHumans: %i\nZombies: %i", g_iWave, g_cDaysTitles[g_iWave - 1], g_iZMCount, humanCount, zombieCount); g_iHumanCount = humanCount; g_iZombieCount = zombieCount; } } else { g_iZMCount--; PrintHintTextToAll("Day %i: %s\nRemaining Zombies: %i\nHumans: %i\nZombies: %i", g_iWave, g_cDaysTitles[g_iWave - 1], g_iZMCount, humanCount, zombieCount); g_iHumanCount = humanCount; g_iZombieCount = zombieCount; } } if (g_iZMCount <= 0 && g_bRoundInProgress) { PrintToChatAll("Won Round!"); CS_TerminateRound(4.0, CSRoundEnd_CTWin, true); g_iWave++; g_bRoundInProgress = false; } return Plugin_Continue; } public Action CS_OnTerminateRound(float& delay, CSRoundEndReason& reason) { //generally we only want to block round termination when all (or the only) zombies are dead but the count requires that there //are more left to kill. we wait for the zombie to respawn so we can kill him again until g_iZMCount reaches 0. if (g_iZMCount > 0) { for (int i = 1; i <= MaxClients; i++) { if (IsValidClient(i) && IsPlayerAlive(i) && GetClientTeam(i) == CS_TEAM_CT) { return Plugin_Handled; } } } return Plugin_Changed; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action OnTakeDamage(int client, int &attacker, int &inflictor, float &damage, int &damagetype) { //it was requested that if round ended that CT and ZM should not be able to damage each other anymore. if (!g_bRoundInProgress) return Plugin_Handled; if (g_bClientProtection[client]) return Plugin_Handled; else if (damagetype & DMG_FALL && g_bFallDamage[client]) return Plugin_Handled; if (IsValidClient(attacker) && !IsFakeClient(attacker)) { if (g_iHumanCount != 999) //very lazy fix so its not looking stupid at round start when no zombie died yet. { PrintHintText(attacker, "Zombie HP: %i\nDay %i: %s\nRemaining Zombies: %i\nHumans: %i\nZombies: %i", GetClientHealth(client) , g_iWave, g_cDaysTitles[g_iWave - 1], g_iZMCount, g_iHumanCount, g_iZombieCount); } else { PrintHintText(attacker, "Zombie HP: %i\nDay %i: %s\nRemaining Zombies: %i", GetClientHealth(client) , g_iWave, g_cDaysTitles[g_iWave - 1], g_iZMCount); } } if (IsValidClient(attacker) && g_fDamageMultiplier[attacker] != 1.0) //damage multiplier { //value lower than 1.0 will reduce the actual damage. damage *= g_fDamageMultiplier[attacker]; return Plugin_Changed; } return Plugin_Continue; } //why do retards suggest using OnWeaponCanUse instead when its not even stopping zombies from using weapons that you drop to them. public Action OnWeaponEquip(int client, int weapon) { if (GetClientTeam(client) == CS_TEAM_T) { char sWeapon[64]; GetEdictClassname(weapon, sWeapon, sizeof(sWeapon)); if(!StrEqual(sWeapon, "weapon_knife")) { return Plugin_Handled; } } return Plugin_Continue; } //---------------------------------------------------------------------------------------------------- // Purpose: zombie reloaded copied knockback //---------------------------------------------------------------------------------------------------- public Action EventPlayerHurt(Handle event, const char[] name, bool dontBroadcast) { // Get all required event info. int client = GetClientOfUserId(GetEventInt(event, "userid")); int attacker = GetClientOfUserId(GetEventInt(event, "attacker")); int l_iDmg_health = GetEventInt(event, "dmg_health"); char l_cWeapon[g_dIndexes]; if (client < 1 || attacker < 1) { return Plugin_Continue; } if (GetClientTeam(client) != CS_TEAM_T || GetClientTeam(attacker) != CS_TEAM_CT) { return Plugin_Continue; } GetEventString(event, "weapon", l_cWeapon, sizeof(l_cWeapon)); KnockbackOnClientHurt(client, attacker, l_cWeapon, l_iDmg_health); return Plugin_Continue; } //---------------------------------------------------------------------------------------------------- // Purpose: zombie reloaded copy paste //---------------------------------------------------------------------------------------------------- public void KnockbackOnClientHurt(int client, int attacker, const char[] weapon, int dmg_health) { float l_fKnockback = g_fKnockBackIndex[client]; float l_fClientloc[3]; float l_fAttackerloc[3]; GetClientAbsOrigin(client, l_fClientloc); if (StrEqual(weapon, "hegrenade")) { if (KnockbackFindExplodingGrenade(l_fAttackerloc) == -1) { return; } } else { GetClientEyePosition(attacker, l_fAttackerloc); float l_fAttackerange[3]; GetClientEyeAngles(attacker, l_fAttackerange); TR_TraceRayFilter(l_fAttackerloc, l_fAttackerange, MASK_ALL, RayType_Infinite, KnockbackTRFilter); TR_GetEndPosition(l_fClientloc); } l_fKnockback *= float(dmg_health); KnockbackSetVelocity(client, l_fAttackerloc, l_fClientloc, l_fKnockback); } //---------------------------------------------------------------------------------------------------- // Purpose: Zombie reloaded knockback //---------------------------------------------------------------------------------------------------- public void KnockbackSetVelocity(int client, const float startpoint[3], const float endpoint[3], float magnitude) { float vector[3]; MakeVectorFromPoints(startpoint, endpoint, vector); NormalizeVector(vector, vector); ScaleVector(vector, magnitude); if (GetEngineVersion() == Engine_CSGO) { int flags = GetEntityFlags(client); float velocity[3]; //tools_functions.inc ToolsGetClientVelocity(client, velocity); if (velocity[2] > CSGO_KNOCKBACK_BOOST_MAX) { vector[2] = 0.0; } else if (flags & FL_ONGROUND && vector[2] < CSGO_KNOCKBACK_BOOST) { vector[2] = CSGO_KNOCKBACK_BOOST; } } // ADD the given vector to the clients current velocity. tools_functions.inc ToolsClientVelocity(client, vector); } //---------------------------------------------------------------------------------------------------- // Purpose: Zombie reloaded trfilter //---------------------------------------------------------------------------------------------------- public bool KnockbackTRFilter(int entity, int contentsMask) { if (entity > 0 && entity < MAXPLAYERS) { return false; } return true; } //---------------------------------------------------------------------------------------------------- // Purpose: Zombie reloaded applying grenades //---------------------------------------------------------------------------------------------------- public int KnockbackFindExplodingGrenade(float heLoc[3]) { char l_cClassname[g_dIndexes]; // Find max entities and loop through all of them. int l_iMaxentities = GetMaxEntities(); for (int x = MaxClients; x <= l_iMaxentities; x++) { // If entity is invalid, then stop. if (!IsValidEdict(x)) { continue; } // If entity isnt a grenade, then stop. GetEdictClassname(x, l_cClassname, sizeof(l_cClassname)); if (!StrEqual(l_cClassname, "hegrenade_projectile", false)) { continue; } // If m_takedamage is set to 0, we found our grenade. int takedamage = GetEntProp(x, Prop_Data, "m_takedamage"); if (takedamage == 0) { // Return its location. GetEntPropVector(x, Prop_Send, "m_vecOrigin", heLoc); // Return its entity index. return x; } } // Didnt find the grenade. return -1; } //---------------------------------------------------------------------------------------------------- // Purpose: zombie reloaded jump height //---------------------------------------------------------------------------------------------------- public Action EventPlayerJump(Handle event, const char[] name, bool dontBroadcast) { // Get all required event info. int index = GetClientOfUserId(GetEventInt(event, "userid")); // Fire post player_jump event. CreateTimer(0.0, EventPlayerJumpPost, GetClientUserId(index)); return Plugin_Handled; } public Action EventPlayerJumpPost(Handle timer, any userid) { int client = GetClientOfUserId(userid); if (!IsValidClient(client)) { return Plugin_Handled; } // If client isnt in-game, then stop. if (!IsClientInGame(client)) { return Plugin_Handled; } // Get class jump multipliers. float distancemultiplier = g_fJumpDistanceIndex[client]; float heightmultiplier = g_fJumpHeightIndex[client]; // If both are set to 1.0, then stop here to save some work. if (distancemultiplier == 1.0 && heightmultiplier == 1.0) { return Plugin_Continue; } float vecVelocity[3]; // Get clients current velocity. ToolsClientVelocity(client, vecVelocity, false); //maybe check JumpBoostIsBHop here // Apply height multiplier to jump vector. vecVelocity[2] *= heightmultiplier; // Set new velocity. ToolsClientVelocity(client, vecVelocity, true, false); return Plugin_Continue; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- stock bool IsValidClient(int client) { if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client)) { return true; } return false; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- stock void ToolsGetClientVelocity(int client, float vecVelocity[3]) { GetEntDataVector(client, g_iToolsVelocity, vecVelocity); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- stock void ToolsClientVelocity(int client, float vecVelocity[3], bool apply = true, bool stack = true) { // If retrieve is true, then get clients velocity. if (!apply) { ToolsGetClientVelocity(client, vecVelocity); // Stop here. return; } // If stack is true, then add clients velocity. if (stack) { // Get clients velocity. float vecClientVelocity[3]; ToolsGetClientVelocity(client, vecClientVelocity); AddVectors(vecClientVelocity, vecVelocity, vecVelocity); } // Apply velocity on client. SetEntDataVector(client, g_iToolsVelocity, vecVelocity); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- stock void ReplaceStrings(char[] str, char[] strReplace) { char l_cstrFix[g_dLength]; Format(l_cstrFix, sizeof(l_cstrFix), str); ReplaceString(l_cstrFix, sizeof(l_cstrFix), "\"", ""); ReplaceString(l_cstrFix, sizeof(l_cstrFix), strReplace, ""); TrimString(l_cstrFix); Format(str, sizeof(l_cstrFix), l_cstrFix); } //ambience void EmitAmbience(const char[] sound) { PrecacheSound(sound); StopAmbience(sound); EmitSoundToAll(sound, SOUND_FROM_PLAYER, SNDCHAN_AUTO, SNDLEVEL_NORMAL, SND_NOFLAGS, 1.0, SNDPITCH_NORMAL, -1, NULL_VECTOR, NULL_VECTOR, true, 0.0); } void StopAmbience(const char []sound) { for (int i = 0; i < MaxClients; i++) { if (!IsValidClient(i)) { continue; } StopSound(i, SNDCHAN_AUTO, sound); } } public Action Timer_Ambient(Handle timer, any userid) { if (StrContains(g_cDaysTitles[g_iWave - 1], "BOSS", false) != -1) //the daystitle contains the word boss in it { EmitAmbience(g_cBossSound); //nobody will ever understand why megalovania was on the servers since 2020. } else { int index = ambient_index(); EmitAmbience(g_cAmbientSOund[index]); } return Plugin_Handled; }