From ebdf2a2a1fc3ae92eeb0427c7e91f8de6bd4544c Mon Sep 17 00:00:00 2001 From: Jackz Date: Mon, 17 May 2021 14:17:07 -0500 Subject: [PATCH] epi: Fix extra kits running on 4 players --- plugins/l4d2_extraplayeritems.smx | Bin 12864 -> 15162 bytes scripting/l4d2_extraplayeritems.sp | 242 ++++++++++++++++++++--------- 2 files changed, 166 insertions(+), 76 deletions(-) diff --git a/plugins/l4d2_extraplayeritems.smx b/plugins/l4d2_extraplayeritems.smx index d352acc7a2f7282ce09e6f1a1ed709f949aaa6a7..ba222d44efbc6024ebd925ce6a4feb5d522d5a06 100644 GIT binary patch literal 15162 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 DO*tm; literal 12864 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 JCQ - ammoPacks = new ArrayList(2); + ammoPacks = new ArrayList(2); // HookEvent("player_spawn", Event_PlayerSpawn); HookEvent("player_first_spawn", Event_PlayerFirstSpawn); HookEvent("round_end", Event_RoundEnd); - //HookEvent("heal_success", Event_HealFinished); HookEvent("map_transition", Event_MapTransition); HookEvent("game_start", Event_GameStart); HookEvent("round_freeze_end", Event_RoundFreezeEnd); @@ -81,7 +97,7 @@ public void OnPluginStart() { if(hUpdateMinPlayers.BoolValue) { hMinPlayers = FindConVar("abm_minplayers"); - if(hMinPlayers != null) PrintToServer("Found convar abm_minplayers"); + if(hMinPlayers != null) PrintDebug(DEBUG_INFO, "Found convar abm_minplayers"); } if(isLateLoaded) { @@ -91,22 +107,24 @@ public void OnPluginStart() { } } + #if defined DEBUG_FORCE_PLAYERS + abmExtraCount = DEBUG_FORCE_PLAYERS; + #endif + AutoExecConfig(true, "l4d2_extraplayeritems"); - #if defined DEBUG + #if defined DEBUG_LEVEL RegAdminCmd("sm_epi_setkits", Command_SetKitAmount, ADMFLAG_CHEATS, "Sets the amount of extra kits that will be provided"); RegAdminCmd("sm_epi_lock", Command_ToggleDoorLocks, ADMFLAG_CHEATS, "Toggle all toggle's lock state"); RegAdminCmd("sm_epi_kits", Command_GetKitAmount, ADMFLAG_CHEATS); RegAdminCmd("sm_epi_items", Command_RunExtraItems, ADMFLAG_CHEATS); #endif - - } ///////////////////////////////////// /// COMMANDS //////////////////////////////////// -#if defined DEBUG +#if defined DEBUG_LEVEL public Action Command_SetKitAmount(int client, int args) { char arg[32]; GetCmdArg(1, arg, sizeof(arg)); @@ -158,9 +176,9 @@ public Action Event_GameStart(Event event, const char[] name, bool dontBroadcast public Action Event_PlayerFirstSpawn(Event event, const char[] name, bool dontBroadcast) { int client = GetClientOfUserId(event.GetInt("userid")); if(GetClientTeam(client) == 2 && !IsFakeClient(client)) { - if(L4D_IsFirstMapInScenario()) { + if(L4D_IsFirstMapInScenario() && !firstGiven) { //Check if all clients are ready, and survivor count is > 4. - if(AreAllClientsReady() && !firstGiven) { + if(AreAllClientsReady()) { abmExtraCount = GetRealSurvivorsCount(); if(abmExtraCount > 4) { firstGiven = true; @@ -170,8 +188,6 @@ public Action Event_PlayerFirstSpawn(Event event, const char[] name, bool dontBr } CreateTimer(1.0, Timer_GiveKits); } - }else if(firstGiven) { - RequestFrame(Frame_GiveNewClientKit, client); } }else { RequestFrame(Frame_GiveNewClientKit, client); @@ -198,7 +214,7 @@ public Action Timer_UpdateMinPlayers(Handle hdl) { if(newPlayerCount > 4 && hMinPlayers.IntValue < newPlayerCount && newPlayerCount < 18) { abmExtraCount = newPlayerCount; #if defined DEBUG - PrintToServer("update abm_minplayers -> %d", abmExtraCount); + PrintDebug(DEBUG_GENERIC, "update abm_minplayers -> %d", abmExtraCount); #endif hMinPlayers.IntValue = abmExtraCount; } @@ -207,7 +223,7 @@ public Action Timer_UpdateMinPlayers(Handle hdl) { public Action Timer_GiveKits(Handle timer) { GiveStartingKits(); } -//Provide extra kits when a player spawns (aka after a map transition) +//Provide extra kits when a player spawns (ahttps://www.youtube.com/watch?v=P1IcaBn3ejka after a map transition) public Action Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast) { int user = event.GetInt("userid"); int client = GetClientOfUserId(user); @@ -222,9 +238,7 @@ public Action Event_PlayerSpawn(Event event, const char[] name, bool dontBroadca } } - public void OnMapStart() { - isGameFrozen = true; //If previous round was a failure, restore the amount of kits that were left directly after map transition if(isFailureRound) { extraKitsAmount = extraKitsStarted; @@ -247,6 +261,25 @@ public void OnMapStart() { if(!isLateLoaded) { isLateLoaded = false; } + + //Lock the beginning door + if(hMinPlayersSaferoomDoor.FloatValue > 0.0) { + int entity = -1; + while ((entity = FindEntityByClassname(entity, "prop_door_rotating_checkpoint")) != -1 && entity > MaxClients) { + bool isLocked = GetEntProp(entity, Prop_Send, "m_bLocked") == 1; + if(isLocked) { + firstSaferoomDoorEntity = entity; + AcceptEntityInput(firstSaferoomDoorEntity, "Close"); + AcceptEntityInput(firstSaferoomDoorEntity, "Lock"); + AcceptEntityInput(firstSaferoomDoorEntity, "ForceClosed"); + SDKHook(firstSaferoomDoorEntity, SDKHook_Use, Hook_Use); + CreateTimer(hSaferoomDoorWaitSeconds.FloatValue, Timer_OpenSaferoomDoor, _, TIMER_FLAG_NO_MAPCHANGE); + break; + } + } + + } + //Hook the end saferoom as event HookEntityOutput("info_changelevel", "OnStartTouch", EntityOutput_OnStartTouchSaferoom); HookEntityOutput("trigger_changelevel", "OnStartTouch", EntityOutput_OnStartTouchSaferoom); @@ -254,65 +287,38 @@ public void OnMapStart() { playersLoadedIn = 0; } + public void OnMapEnd() { for(int i = 0; i < ammoPacks.Length; i++) { ArrayList clients = ammoPacks.Get(i, AMMOPACK_USERS); delete clients; } + for(int i = 0; i < sizeof(cabinets); i++) { + cabinets[i].id = 0; + for(int b = 0; b < CABINET_ITEM_BLOCKS; b++) { + cabinets[i].items[b] = 0; + } + } ammoPacks.Clear(); playersLoadedIn = 0; - isGameFrozen = true; } public void Event_RoundFreezeEnd(Event event, const char[] name, bool dontBroadcast) { - isGameFrozen = false; - if(!isLateLoaded) - PopulateItems(); - int client = FindFirstSurvivor(); - if(client <= 0) return; //Ignore if no players - - float survPos[3], doorPos[3]; - GetClientAbsOrigin(client, survPos); - if(hMinPlayersSaferoomDoor.FloatValue > 0.0) { - int entity = -1; - float smallestDistance = -1.0; - while ((entity = FindEntityByClassname(entity, "prop_door_rotating_checkpoint")) != -1 && entity > MaxClients) { - GetEntPropVector(entity, Prop_Send, "m_vecOrigin", doorPos); - float distance = GetVectorDistance(survPos, doorPos); - if(distance < smallestDistance || smallestDistance == -1.0) { - smallestDistance = distance; - firstSaferoomDoorEntity = entity; - } - } - AcceptEntityInput(firstSaferoomDoorEntity, "Close"); - AcceptEntityInput(firstSaferoomDoorEntity, "Lock"); - AcceptEntityInput(firstSaferoomDoorEntity, "ForceClosed"); - SDKHook(firstSaferoomDoorEntity, SDKHook_Use, Hook_Use); - CreateTimer(hSaferoomDoorWaitSeconds.FloatValue, Timer_OpenSaferoomDoor, _, TIMER_FLAG_NO_MAPCHANGE); - } -} - - -public Action Hook_Use(int entity, int activator, int caller, UseType type, float value) { - SetEntProp(entity, Prop_Send, "m_bLocked", 1); - AcceptEntityInput(entity, "Close"); - ClientCommand(activator, "play ui/menu_invalid.wav"); - PrintHintText(activator, "Waiting for players"); - return Plugin_Handled; + PopulateItems(); } public void EntityOutput_OnStartTouchSaferoom(const char[] output, int caller, int client, float time) { //TODO: Possibly check client (as entity) if it is a kit, to check that the kit being picked up is in saferoom? if(!isCheckpointReached && client > 0 && client <= MaxClients && IsValidClient(client) && GetClientTeam(client) == 2) { isCheckpointReached = true; - int extraPlayers = GetSurvivorsCount() - 4; - if(extraPlayers > 0) { - + abmExtraCount = GetSurvivorsCount(); + if(abmExtraCount > 4) { + int extraPlayers = abmExtraCount - 4; float averageTeamHP = GetAverageHP(); if(averageTeamHP <= 30.0) extraPlayers += extraPlayers; //if perm. health < 30, give an extra 4 on top of the extra else if(averageTeamHP <= 50.0) extraPlayers = (extraPlayers / 2); //if the team's average health is less than 50 (permament) then give another //Chance to get 1-2 extra kits (might need to be nerfed or restricted to > 50 HP) - if(GetRandomFloat() < 0.3) ++extraPlayers; + if(GetRandomFloat() < 0.3 && averageTeamHP <= 80.0) ++extraPlayers; //If hAddExtraKits TRUE: Append to previous, FALSE: Overwrite @@ -323,13 +329,15 @@ public void EntityOutput_OnStartTouchSaferoom(const char[] output, int caller, i extraKitsStarted = extraKitsAmount; PrintToConsoleAll("CHECKPOINT REACHED BY %N | EXTRA KITS: %d", client, extraPlayers); - PrintToServer(">>> Player entered saferoom. An extra %d kits will be provided", extraKitsAmount); + PrintToServer("Player entered saferoom. Providing %d extra kits", extraKitsAmount); } } } + public Action Event_RoundEnd(Event event, const char[] name, bool dontBroadcast) { if(!isFailureRound) isFailureRound = true; } + public Action Event_MapTransition(Event event, const char[] name, bool dontBroadcast) { #if defined DEBUG PrintToServer("Map transition | %d Extra Kits", extraKitsAmount); @@ -347,22 +355,55 @@ public Action Event_Pickup(int client, int weapon) { GetEntityClassname(weapon, name, sizeof(name)); if(StrEqual(name, "weapon_first_aid_kit", true)) { if(isBeingGivenKit[client]) return Plugin_Continue; - if(UseExtraKit(client)) { - return Plugin_Stop; + if((L4D_IsInFirstCheckpoint(client) || L4D_IsInLastCheckpoint(client)) && UseExtraKit(client)) { + return Plugin_Handled; } } return Plugin_Continue; } public void OnEntityCreated(int entity, const char[] classname) { - static float spawnPos[3]; - if (StrEqual(classname, "upgrade_ammo_explosive") || StrEqual(classname, "upgrade_ammo_incendiary")) { + if(StrEqual(classname, "weapon_pain_pills_spawn") || StrEqual(classname, "weapon_first_aid_kit_spawn")) { + SDKHook(entity, SDKHook_SpawnPost, Hook_CabinetItemSpawn); + }else if(StrEqual(classname, "prop_health_cabinet", true)) { + SDKHook(entity, SDKHook_SpawnPost, Hook_CabinetSpawn); + }else if (StrEqual(classname, "upgrade_ammo_explosive") || StrEqual(classname, "upgrade_ammo_incendiary")) { int index = ammoPacks.Push(entity); ammoPacks.Set(index, new ArrayList(1), AMMOPACK_USERS); SDKHook(entity, SDKHook_Use, OnUpgradePackUse); } } +//TODO: Implement extra kit amount to this +//TODO: Possibly check ammo pack and kit (relv. distance). Would fire on Last Stand 2nd . +public Action Hook_CabinetItemSpawn(int entity) { + int cabinet = FindNearestEntityInRange(entity, "prop_health_cabinet", 60.0); + if(cabinet > 0) { + int ci = FindCabinetIndex(cabinet); + //Check for any open block + for(int block = 0; block < CABINET_ITEM_BLOCKS; block++) { + int cabEnt = cabinets[ci].items[block]; + PrintDebug(DEBUG_ANY, "cabinet %d spawner %d block %d: %d", cabinet, entity, block, cabEnt); + if(cabEnt <= 0) { + cabinets[ci].items[block] = entity; + PrintDebug(DEBUG_SPAWNLOGIC, "Adding spawner %d for cabinet %d block %d", entity, cabinet, block); + break; + } + } + //If Cabinet is full, spawner can not be a part of cabinet and is ignored. + } +} + +public Action Hook_CabinetSpawn(int entity) { + for(int i = 0; i < sizeof(cabinets); i++) { + if(cabinets[i].id == 0) { + cabinets[i].id = entity; + break; + } + } + PrintDebug(DEBUG_SPAWNLOGIC, "Adding cabinet %d", entity); +} + public Action OnUpgradePackUse(int entity, int activator, int caller, UseType type, float value) { if (entity > 2048 || entity <= MaxClients || !IsValidEntity(entity)) return Plugin_Continue; @@ -410,6 +451,14 @@ public Action OnUpgradePackUse(int entity, int activator, int caller, UseType ty return Plugin_Continue; } +public Action Hook_Use(int entity, int activator, int caller, UseType type, float value) { + SetEntProp(entity, Prop_Send, "m_bLocked", 1); + AcceptEntityInput(entity, "Close"); + ClientCommand(activator, "play ui/menu_invalid.wav"); + PrintHintText(activator, "Waiting for players"); + return Plugin_Handled; +} + ///////////////////////////////////// /// TIMERS //////////////////////////////////// @@ -426,12 +475,14 @@ public void PopulateItems() { int survivors = GetRealSurvivorsCount(); if(survivors <= 4) return; + //Generic Logic float percentage = hExtraItemBasePercentage.FloatValue * survivors; PrintToServer("Populating extra items based on player count (%d) | Percentage %.2f%%", survivors, percentage * 100); PrintToConsoleAll("Populating extra items based on player count (%d) | Percentage %.2f%%", survivors, percentage * 100); - char classname[32]; + static char classname[32]; int affected = 0; + //TODO: Possibly convert to method of FindEntityByClassname for(int i = MaxClients + 1; i < 2048; i++) { if(IsValidEntity(i)) { GetEntityClassname(i, classname, sizeof(classname)); @@ -440,22 +491,44 @@ public void PopulateItems() { && StrContains(classname, "scavenge", true) == -1 ) { int count = GetEntProp(i, Prop_Data, "m_itemCount"); - //Add extra kits (equal to player count) to any 4 set of kits. - if(count == 4 && StrEqual(classname, "weapon_first_aid_kit_spawn", true)) { - SetEntProp(i, Prop_Data, "m_itemCount", survivors); - ++affected; - }else if(count > 0 && GetRandomFloat() < percentage) { + if(count > 0 && GetRandomFloat() < percentage) { SetEntProp(i, Prop_Data, "m_itemCount", ++count); ++affected; } } } } - PrintToServer("Incremented counts for %d items", affected); + PrintDebug(DEBUG_SPAWNLOGIC, "Incremented counts for %d items", affected); + + + //Cabinet logic + PrintDebug(DEBUG_SPAWNLOGIC, "Populating cabinets with extra items"); + int spawner, count; + for(int i = 0; i < sizeof(cabinets); i++) { + if(cabinets[i].id == 0) break; + int spawnCount = GetEntProp(cabinets[i].id, Prop_Data, "m_pillCount"); + int extraAmount = RoundToCeil(float(abmExtraCount) * (float(spawnCount)/4.0) - spawnCount); + bool hasASpawner; + while(extraAmount > 0) { + //FIXME: spawner is sometimes invalid entity. Ref needed? + for(int block = 0; block < CABINET_ITEM_BLOCKS; block++) { + spawner = cabinets[i].items[block]; + if(spawner > 0) { + hasASpawner = true; + count = GetEntProp(spawner, Prop_Data, "m_itemCount") + 1; + SetEntProp(spawner, Prop_Data, "m_itemCount", count); + if(--extraAmount == 0) break; + } + } + //Incase cabinet is empty + if(!hasASpawner) break; + } + } } public Action Timer_OpenSaferoomDoor(Handle h) { - UnlockDoor(firstSaferoomDoorEntity, 1); + if(firstSaferoomDoorEntity > 0) + UnlockDoor(firstSaferoomDoorEntity, 1); } void UnlockDoor(int entity, int flag) { @@ -467,6 +540,13 @@ void UnlockDoor(int entity, int flag) { firstSaferoomDoorEntity = -1; } +int FindCabinetIndex(int cabinetId) { + for(int i = 0; i < sizeof(cabinets); i++) { + if(cabinets[i].id == cabinetId) return i; + } + return -1; +} + ///////////////////////////////////// /// Stocks //////////////////////////////////// @@ -498,6 +578,9 @@ stock void GiveStartingKits() { } stock int GetSurvivorsCount() { + #if defined DEBUG_FORCE_PLAYERS + return DEBUG_FORCE_PLAYERS; + #endif int count = 0; for(int i = 1; i <= MaxClients; i++) { if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2) { @@ -508,6 +591,9 @@ stock int GetSurvivorsCount() { } stock int GetRealSurvivorsCount() { + #if defined DEBUG_FORCE_PLAYERS + return DEBUG_FORCE_PLAYERS; + #endif int count = 0; for(int i = 1; i <= MaxClients; i++) { if(IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == 2) { @@ -543,7 +629,6 @@ stock bool UseExtraKit(int client) { int ent = GivePlayerItem(client, "weapon_first_aid_kit"); EquipPlayerWeapon(client, ent); isBeingGivenKit[client] = false; - PrintDebug("Used extra kit #%d - ent %d", extraKitsAmount, ent); if(--extraKitsAmount <= 0) { extraKitsAmount = 0; } @@ -552,10 +637,15 @@ stock bool UseExtraKit(int client) { return false; } -stock void PrintDebug(const char[] format, any ... ) { - char buffer[256]; - VFormat(buffer, sizeof(buffer), format, 2); - PrintToServer(buffer); +stock void PrintDebug(int level, const char[] format, any ... ) { + #if defined DEBUG_LEVEL + if(level <= DEBUG_LEVEL) { + char buffer[256]; + VFormat(buffer, sizeof(buffer), format, 3); + PrintToServer("[Debug] %s", buffer); + PrintToConsoleAll("[Debug] %s", buffer); + } + #endif } stock float GetAverageHP() { int totalHP, clients;