diff --git a/plugins/l4d2_extraplayeritems.smx b/plugins/l4d2_extraplayeritems.smx index 3e0302d..540ee5e 100644 Binary files a/plugins/l4d2_extraplayeritems.smx and b/plugins/l4d2_extraplayeritems.smx differ diff --git a/scripting/include/epi/director.sp b/scripting/include/epi/director.sp index 45eea3a..0318942 100644 --- a/scripting/include/epi/director.sp +++ b/scripting/include/epi/director.sp @@ -59,7 +59,7 @@ char DIRECTOR_STATE[8][] = { "tank in play", "high stress", }; -directorState g_lastState; +static directorState g_lastState; static float g_highestFlowAchieved; static float g_lastSpawnTime[TOTAL_NUM_SPECIALS]; @@ -69,9 +69,9 @@ static int g_spawnCount[TOTAL_NUM_SPECIALS]; static float g_minFlowSpawn; // The minimum flow for specials to start spawning (waiting for players to leave saferom) static float g_maxStressIntensity; // The max stress that specials arent allowed to spawn -static int extraWitchCount; +int g_extraWitchCount; static int g_infectedCount; -static int g_restCount; +int g_restCount; static Handle witchSpawnTimer = null; float g_extraWitchFlowPositions[DIRECTOR_WITCH_MAX_WITCHES] = {}; @@ -79,7 +79,8 @@ float g_extraWitchFlowPositions[DIRECTOR_WITCH_MAX_WITCHES] = {}; /// EVENTS void Director_OnMapStart() { - if(cvEPISpecialSpawning.IntValue & 2 && IsEPIActive()) { + // Only spawn witches if enabled, and not loate loaded + if(!g_isLateLoaded && cvEPISpecialSpawning.IntValue & 2 && IsEPIActive()) { InitExtraWitches(); } float time = GetGameTime(); @@ -126,7 +127,7 @@ void Director_CheckClient(int client) { if(class > view_as(Special_Tank)) { return; } - if(IsFakeClient(client) && class == view_as(Special_Tank) && IsEPIActive() && cvEPISpecialSpawning.IntValue & 4) { + if(IsFakeClient(client) && class == view_as(Special_Tank)) { OnTankBotSpawn(client); } @@ -139,17 +140,45 @@ void Director_CheckClient(int client) { } } +static int g_newTankHealth = 0; void OnTankBotSpawn(int client) { - if(g_finaleStage == Stage_FinaleActive) { - + if(!IsEPIActive() || !(cvEPISpecialSpawning.IntValue & 4)) return; + if(g_finaleStage == Stage_FinaleTank2) { + if(hExtraFinaleTank.IntValue > 0 && g_extraFinaleTankEnabled) { + float duration = GetRandomFloat(EXTRA_TANK_MIN_SEC, EXTRA_TANK_MAX_SEC); + // Pass it 0, which doesnt make it a split tank, has default health + CreateTimer(duration, Timer_SpawnSplitTank, 0); + } + } else if(g_newTankHealth > 0) { + // A split tank has spawned, set its health + PrintDebug(DEBUG_SPAWNLOGIC, "OnTankBotSpawn: split tank spawned, setting health", g_newTankHealth); + SetEntProp(client, Prop_Send, "m_iHealth", g_newTankHealth); + g_newTankHealth = 0; } else { + // Normal (non-finale) tank spawned. Set its health int health = GetEntProp(client, Prop_Send, "m_iHealth"); float additionalHealth = float(g_survivorCount - 4) * cvEPITankHealth.FloatValue; health += RoundFloat(additionalHealth); - SetEntProp(client, Prop_Send, "m_iHealth", health); + PrintDebug(DEBUG_SPAWNLOGIC, "OnTankBotSpawn: Setting tank health to %d", health); + + if(hExtraFinaleTank.IntValue & 1 && GetURandomFloat() <= hSplitTankChance.FloatValue) { + float duration = GetRandomFloat(EXTRA_TANK_MIN_SEC, EXTRA_TANK_MAX_SEC); + int splitHealth = health / 2; + PrintDebug(DEBUG_SPAWNLOGIC, "OnTankBotSpawn: split tank in %.1fs, health=%d", duration, g_newTankHealth); + CreateTimer(duration, Timer_SpawnSplitTank, splitHealth); + SetEntProp(client, Prop_Send, "m_iHealth", splitHealth); + } else { + SetEntProp(client, Prop_Send, "m_iHealth", health); + } } } +Action Timer_SpawnSplitTank(Handle h, int health) { + g_newTankHealth = health; + DirectorSpawn(Special_Tank); + return Plugin_Handled; +} + void Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast) { int client = GetClientOfUserId(event.GetInt("userid")); if(client > 0) { @@ -191,9 +220,9 @@ void InitExtraWitches() { // TODO: max based on count int max = RoundToFloor(float(count) / 4.0); - extraWitchCount = DiceRoll(min, DIRECTOR_WITCH_MAX_WITCHES, DIRECTOR_WITCH_ROLLS, BIAS_LEFT); - PrintDebug(DEBUG_SPAWNLOGIC, "InitExtraWitches: %d witches (min=%d, max=%d, rolls=%d) checkInterval=%f", extraWitchCount, min, max, DIRECTOR_WITCH_ROLLS, DIRECTOR_WITCH_CHECK_TIME); - for(int i = 0; i <= extraWitchCount; i++) { + g_extraWitchCount = DiceRoll(min, DIRECTOR_WITCH_MAX_WITCHES, DIRECTOR_WITCH_ROLLS, BIAS_LEFT); + PrintDebug(DEBUG_SPAWNLOGIC, "InitExtraWitches: %d witches (min=%d, max=%d, rolls=%d) checkInterval=%f", g_extraWitchCount, min, max, DIRECTOR_WITCH_ROLLS, DIRECTOR_WITCH_CHECK_TIME); + for(int i = 0; i <= g_extraWitchCount; i++) { g_extraWitchFlowPositions[i] = GetURandomFloat() * (flowMax-FLOW_CUTOFF) + FLOW_CUTOFF; PrintDebug(DEBUG_SPAWNLOGIC, "Witch position #%d: flow %.2f (%.0f%%)", i, g_extraWitchFlowPositions[i], g_extraWitchFlowPositions[i] / flowMax); } @@ -203,11 +232,10 @@ void InitExtraWitches() { } void Director_PrintDebug(int client) { - PrintToConsole(client, "===Extra Witches==="); PrintToConsole(client, "State: %s(%d)", DIRECTOR_STATE[g_lastState], g_lastState); PrintToConsole(client, "Map Bounds: [%f, %f]", FLOW_CUTOFF, L4D2Direct_GetMapMaxFlowDistance() - (FLOW_CUTOFF*2.0)); - PrintToConsole(client, "Total Witches Spawned: %d | Target: %d", g_spawnCount[Special_Witch], extraWitchCount); - for(int i = 0; i < extraWitchCount && i < DIRECTOR_WITCH_MAX_WITCHES; i++) { + PrintToConsole(client, "Total Witches Spawned: %d | Target: %d", g_spawnCount[Special_Witch], g_extraWitchCount); + for(int i = 0; i < g_extraWitchCount && i < DIRECTOR_WITCH_MAX_WITCHES; i++) { PrintToConsole(client, "%d. %f", i+1, g_extraWitchFlowPositions[i]); } PrintToConsole(client, "highestFlow = %f, g_minFlowSpawn = %f, current flow = %f", g_highestFlowAchieved, g_minFlowSpawn, L4D2Direct_GetFlowDistance(client)); @@ -353,8 +381,8 @@ Action Timer_Director(Handle h) { Action Timer_DirectorWitch(Handle h) { - if(g_spawnCount[Special_Witch] < extraWitchCount) { //&& time - g_lastSpawnTimes.witch > DIRECTOR_WITCH_MIN_TIME - for(int i = 0; i <= extraWitchCount; i++) { + if(g_spawnCount[Special_Witch] < g_extraWitchCount) { //&& time - g_lastSpawnTimes.witch > DIRECTOR_WITCH_MIN_TIME + for(int i = 0; i <= g_extraWitchCount; i++) { if(g_extraWitchFlowPositions[i] > 0.0 && g_highestFlowAchieved >= g_extraWitchFlowPositions[i]) { // Reset the flow so we don't spawn another g_extraWitchFlowPositions[i] = 0.0; diff --git a/scripting/l4d2_extraplayeritems.sp b/scripting/l4d2_extraplayeritems.sp index 2ca4441..c106ab8 100644 --- a/scripting/l4d2_extraplayeritems.sp +++ b/scripting/l4d2_extraplayeritems.sp @@ -48,6 +48,7 @@ #include #include #include +#include #define L4D2_WEPUPGFLAG_NONE (0 << 0) #define L4D2_WEPUPGFLAG_INCENDIARY (1 << 0) @@ -82,7 +83,7 @@ public Plugin myinfo = ConVar hExtraItemBasePercentage, hAddExtraKits, hMinPlayers, hUpdateMinPlayers, hMinPlayersSaferoomDoor, hSaferoomDoorWaitSeconds, hSaferoomDoorAutoOpen, hEPIHudState, hExtraFinaleTank, cvDropDisconnectTime, hSplitTankChance, cvFFDecreaseRate, cvZDifficulty, cvEPIHudFlags, cvEPISpecialSpawning, cvEPIGamemodes, hGamemode, cvEPITankHealth; int g_extraKitsAmount, g_extraKitsStart, g_saferoomDoorEnt, g_prevPlayerCount; static int g_currentChapter; -static bool g_isCheckpointReached, isLateLoaded, g_startCampaignGiven, g_isFailureRound, g_areItemsPopulated; +bool g_isCheckpointReached, g_isLateLoaded, g_startCampaignGiven, g_isFailureRound, g_areItemsPopulated; static ArrayList g_ammoPacks; static Handle updateHudTimer; static bool showHudPingMode; @@ -91,9 +92,9 @@ static char g_currentGamemode[32]; static bool g_isGamemodeAllowed; int g_survivorCount, g_realSurvivorCount; bool g_isFinaleEnding; +static bool g_epiEnabled; bool g_isSpeaking[MAXPLAYERS+1]; -bool isCoop; enum Difficulty { Difficulty_Easy, @@ -104,7 +105,7 @@ enum Difficulty { Difficulty zDifficulty; -static bool g_tankSplitEnabled = true; +bool g_extraFinaleTankEnabled; enum State { State_Empty, @@ -254,7 +255,7 @@ FinaleStage g_finaleStage; #include public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) { - if(late) isLateLoaded = true; + if(late) g_isLateLoaded = true; return APLRes_Success; } @@ -330,7 +331,7 @@ public void OnPluginStart() { if(hMinPlayers != null) PrintDebug(DEBUG_INFO, "Found convar abm_minplayers"); } - if(isLateLoaded) { + if(g_isLateLoaded) { for(int i = 1; i <= MaxClients; i++) { if(IsClientConnected(i) && IsClientInGame(i)) { if(GetClientTeam(i) == 2) { @@ -359,6 +360,7 @@ public void OnPluginStart() { AutoExecConfig(true, "l4d2_extraplayeritems"); RegAdminCmd("sm_epi_sc", Command_SetSurvivorCount, ADMFLAG_KICK); + RegAdminCmd("sm_epi_val", Command_EpiVal, ADMFLAG_GENERIC); #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"); @@ -520,6 +522,63 @@ public void Event_DifficultyChange(ConVar cvar, const char[] oldValue, const cha ///////////////////////////////////// /// COMMANDS //////////////////////////////////// +void ValBool(int client, const char[] name, bool &value, const char[] input) { + if(input[0] != '\0') { + value = input[0] == '1' || input[0] == 't'; + CReplyToCommand(client, "Set {olive}%s{default} to {yellow}%b", name, value); + } else { + CReplyToCommand(client, "Value of {olive}%s{default}: {yellow}%b", name, value); + } +} +void ValInt(int client, const char[] name, int &value, const char[] input) { + if(input[0] != '\0') { + value = StringToInt(input); + CReplyToCommand(client, "Set {olive}%s{default} to {yellow}%d", name, value); + } else { + CReplyToCommand(client, "Value of {olive}%s{default}: {yellow}%d", name, value); + } +} +void ValFloat(int client, const char[] name, float &value, const char[] input) { + if(input[0] != '\0') { + value = StringToFloat(input); + CReplyToCommand(client, "Set {olive}%s{default} to {yellow}%f", name, value); + } else { + CReplyToCommand(client, "Value of {olive}%s{default}: {yellow}%f", name, value); + } +} +Action Command_EpiVal(int client, int args) { + if(args == 0) { + PrintToConsole(client, "epiEnabled = %b", g_epiEnabled); + PrintToConsole(client, "isGamemodeAllowed = %b", g_isGamemodeAllowed); + PrintToConsole(client, "extraKitsAmount = %d", g_extraKitsAmount); + PrintToConsole(client, "extraKitsStart = %d", g_extraKitsStart); + PrintToConsole(client, "currentChapter = %d", g_currentChapter); + PrintToConsole(client, "extraWitchCount = %d", g_extraWitchCount); + PrintToConsole(client, "restCount = %d", g_restCount); + return Plugin_Handled; + } + char arg[32], value[32]; + GetCmdArg(1, arg, sizeof(arg)); + GetCmdArg(2, value, sizeof(value)); + if(StrEqual(arg, "epiEnabled")) { + ValBool(client, "g_epiEnabled", g_epiEnabled, value); + } else if(StrEqual(arg, "isGamemodeAllowed")) { + ValBool(client, "g_isGamemodeAllowed", g_isGamemodeAllowed, value); + } else if(StrEqual(arg, "extraKitsAmount")) { + ValInt(client, "g_extraKitsAmount", g_extraKitsAmount, value); + } else if(StrEqual(arg, "extraKitsStart")) { + ValInt(client, "g_extraKitsStart", g_extraKitsStart, value); + } else if(StrEqual(arg, "currentChapter")) { + ValInt(client, "g_currentChapter", g_currentChapter, value); + } else if(StrEqual(arg, "extraWitchCount")) { + ValInt(client, "g_extraWitchCount", g_extraWitchCount, value); + } else if(StrEqual(arg, "restCount")) { + ValInt(client, "g_restCount", g_restCount, value); + } else { + ReplyToCommand(client, "Unknown value"); + } + return Plugin_Handled; +} Action Command_Trigger(int client, int args) { char arg[32]; GetCmdArg(1, arg, sizeof(arg)); @@ -566,7 +625,7 @@ Action Command_RestoreInventory(int client, int args) { return Plugin_Handled; } - if(StrEqual(arg, "full")) { + if(StrEqual(arg, "full") || StrEqual(arg, "all")) { RestoreInventory(client, inv); } else if(StrEqual(arg, "pos")) { TeleportEntity(player, inv.location, NULL_VECTOR, NULL_VECTOR); @@ -577,34 +636,46 @@ Action Command_RestoreInventory(int client, int args) { return Plugin_Handled; } // TODO: allow sc for new sys -public Action Command_SetSurvivorCount(int client, int args) { - int oldCount = g_realSurvivorCount; - if(args > 0) { - static char arg1[8]; - GetCmdArg(1, arg1, sizeof(arg1)); - int newCount; - if(StringToIntEx(arg1, newCount) > 0) { - if(newCount < 0 || newCount > MaxClients) { - ReplyToCommand(client, "Invalid survivor count. Must be between 0 and %d", MaxClients); - return Plugin_Handled; - } else { - g_realSurvivorCount = g_survivorCount = newCount; - hMinPlayers.IntValue = g_realSurvivorCount; - ReplyToCommand(client, "Changed extra survivor count to %d -> %d", oldCount, newCount); - bool add = (newCount - oldCount) > 0; - if(add) - ServerCommand("abm-mk -%d 2", newCount); - else - ServerCommand("abm-rm -%d 2", newCount); - } - } else { - ReplyToCommand(client, "Invalid number"); +int parseSurvivorCount(const char arg[8]) { + int newCount; + if(StringToIntEx(arg, newCount) > 0) { + if(newCount >= 0 && newCount <= MaxClients) { + return newCount; } + } + return -1; +} +Action Command_SetSurvivorCount(int client, int args) { + if(args > 0) { + char arg[8]; + GetCmdArg(1, arg, sizeof(arg)); + int survivorCount = parseSurvivorCount(arg); + int oldSurvivorCount = g_survivorCount; + if(survivorCount == -1) { + ReplyToCommand(client, "Invalid survivor count. Must be between 0 and %d", MaxClients); + return Plugin_Handled; + } else if(args >= 2) { + GetCmdArg(2, arg, sizeof(arg)); + int realCount = parseSurvivorCount(arg); + if(realCount == -1 || realCount <= survivorCount) { + ReplyToCommand(client, "Invalid bot count. Must be between 0 and %d", survivorCount); + return Plugin_Handled; + } + int oldRealCount = g_realSurvivorCount; + g_realSurvivorCount = realCount; + ReplyToCommand(client, "Changed real survivor count %d -> %d", oldRealCount, realCount); + } else { + // If no real count count, it's the same as survivor count + g_realSurvivorCount = survivorCount; + } + g_survivorCount = survivorCount; + ReplyToCommand(client, "Changed survivor count %d -> %d", oldSurvivorCount, survivorCount); } else { - ReplyToCommand(client, "Current extra count is %d.", oldCount); + ReplyToCommand(client, "Survivor Count = %d | Real Survivor Count = %d", g_survivorCount, g_realSurvivorCount); } return Plugin_Handled; } + #if defined DEBUG_LEVEL Action Command_SetKitAmount(int client, int args) { char arg[32]; @@ -632,7 +703,7 @@ Action Command_ToggleDoorLocks(int client, int args) { Action Command_GetKitAmount(int client, int args) { ReplyToCommand(client, "Extra kits available: %d (%d) | Survivors: %d", g_extraKitsAmount, g_extraKitsStart, GetSurvivorsCount()); - ReplyToCommand(client, "isCheckpointReached %b, isLateLoaded %b, firstGiven %b", g_isCheckpointReached, isLateLoaded, g_startCampaignGiven); + ReplyToCommand(client, "isCheckpointReached %b, g_isLateLoaded %b, firstGiven %b", g_isCheckpointReached, g_isLateLoaded, g_startCampaignGiven); return Plugin_Handled; } Action Command_RunExtraItems(int client, int args) { @@ -717,7 +788,7 @@ void Event_TankSpawn(Event event, const char[] name, bool dontBroadcast) { int tank = GetClientOfUserId(user); if(tank > 0 && IsFakeClient(tank) && g_realSurvivorCount > 4 && hExtraFinaleTank.IntValue > 0) { PrintToConsoleAll("[EPI] Split tank is enabled, checking new spawned tank"); - if(g_finaleStage == Stage_FinaleTank2 && g_tankSplitEnabled && hExtraFinaleTank.IntValue & 2) { + if(g_finaleStage == Stage_FinaleTank2 && g_extraFinaleTankEnabled && hExtraFinaleTank.IntValue & 2) { PrintToConsoleAll("[EPI] Second tank spawned, setting health."); // Sets health in half, sets finaleStage to health float duration = GetRandomFloat(EXTRA_TANK_MIN_SEC, EXTRA_TANK_MAX_SEC); @@ -725,7 +796,7 @@ void Event_TankSpawn(Event event, const char[] name, bool dontBroadcast) { } else if(g_finaleStage == Stage_FinaleDuplicatePending) { PrintToConsoleAll("[EPI] Third & final tank spawned"); RequestFrame(Frame_SetExtraTankHealth, user); - } else if(g_finaleStage == Stage_Inactive && g_tankSplitEnabled && hExtraFinaleTank.IntValue & 1 && GetSurvivorsCount() > 6) { + } else if(g_finaleStage == Stage_Inactive && g_extraFinaleTankEnabled && hExtraFinaleTank.IntValue & 1 && GetSurvivorsCount() > 6) { g_finaleStage = Stage_TankSplit; if(GetRandomFloat() <= hSplitTankChance.FloatValue) { // Half their HP, assign half to self and for next tank @@ -733,7 +804,7 @@ void Event_TankSpawn(Event event, const char[] name, bool dontBroadcast) { PrintToConsoleAll("[EPI] Creating a split tank (hp=%d)", hp); extraTankHP = hp; CreateTimer(0.2, Timer_SetHealth, user); - CreateTimer(GetRandomFloat(10.0, 18.0), Timer_SpawnSplitTank, user); + CreateTimer(GetRandomFloat(10.0, 18.0), Timer_SpawnSplitTank, hp); } else { PrintToConsoleAll("[EPI] Random chance for split tank failed"); } @@ -751,11 +822,6 @@ Action Timer_SpawnFinaleTank(Handle t, int user) { } return Plugin_Handled; } -Action Timer_SpawnSplitTank(Handle t, int user) { - DirectorSpawn(Special_Tank); - // ServerCommand("sm_forcespecial tank"); - return Plugin_Handled; -} Action Timer_SetHealth(Handle h, int user) { int client = GetClientOfUserId(user); if(client > 0 ) { @@ -1113,10 +1179,9 @@ public void OnMapStart() { GetCurrentMap(curMap, sizeof(curMap)); // Disable tank split on hard rain finale + g_extraFinaleTankEnabled = true; if(StrEqual(curMap, "c4m5_milltown_escape")) { - g_tankSplitEnabled = false; - } else { - g_tankSplitEnabled = true; + g_extraFinaleTankEnabled = false; } int extraKits = GetSurvivorsCount() - 4; @@ -1130,10 +1195,6 @@ public void OnMapStart() { g_currentChapter++; } - if(!isLateLoaded) { - isLateLoaded = false; - } - //Lock the beginning door if(hMinPlayersSaferoomDoor.FloatValue > 0.0) { int entity = -1; @@ -1162,6 +1223,9 @@ public void OnMapStart() { L4D2_RunScript(HUD_SCRIPT_CLEAR); Director_OnMapStart(); + if(g_isLateLoaded) { + g_isLateLoaded = false; + } } /* @@ -1254,7 +1318,7 @@ public Action Event_MapTransition(Event event, const char[] name, bool dontBroad #if defined DEBUG PrintToServer("Map transition | %d Extra Kits", g_extraKitsAmount); #endif - isLateLoaded = false; + g_isLateLoaded = false; g_extraKitsStart = g_extraKitsAmount; // Update g_survivorCount, people may have dipped right before transition UpdateSurvivorCount(); @@ -1431,8 +1495,8 @@ void UnlockDoor(int flag) { } Action Timer_UpdateHud(Handle h) { - if(hEPIHudState.IntValue == 1 && !isCoop) { - PrintToServer("[EPI] Gamemode no longer coop, stopping (hudState=%d, g_survivorCount=%d, g_realSurvivorCount=%d)", hEPIHudState.IntValue, g_survivorCount, g_realSurvivorCount); + if(hEPIHudState.IntValue == 1 && !g_isGamemodeAllowed) { + PrintToServer("[EPI] Gamemode not whitelisted, stopping (hudState=%d, g_survivorCount=%d, g_realSurvivorCount=%d)", hEPIHudState.IntValue, g_survivorCount, g_realSurvivorCount); L4D2_RunScript(HUD_SCRIPT_CLEAR); updateHudTimer = null; return Plugin_Stop; @@ -1521,14 +1585,14 @@ Action Timer_UpdateHud(Handle h) { void PopulateItems() { if(g_areItemsPopulated) return; UpdateSurvivorCount(); - if(g_realSurvivorCount <= 4) return; + if(!IsEPIActive()) return; g_areItemsPopulated = true; //Generic Logic - float percentage = hExtraItemBasePercentage.FloatValue * g_realSurvivorCount; - PrintToServer("[EPI] Populating extra items based on player count (%d) | Percentage %.2f%%", g_realSurvivorCount, percentage * 100); - PrintToConsoleAll("[EPI] Populating extra items based on player count (%d) | Percentage %.2f%%", g_realSurvivorCount, percentage * 100); + float percentage = hExtraItemBasePercentage.FloatValue * (g_survivorCount - 4); + PrintToServer("[EPI] Populating extra items based on player count (%d-4) | Percentage %.2f%%", g_survivorCount, percentage * 100); + PrintToConsoleAll("[EPI] Populating extra items based on player count (%d-4) | Percentage %.2f%%", g_survivorCount, percentage * 100); char classname[64]; int affected = 0; @@ -1550,7 +1614,11 @@ void PopulateItems() { } PrintDebug(DEBUG_SPAWNLOGIC, "Incremented counts for %d items", affected); + PopulateCabinets(); +} +void PopulateCabinets() { + char classname[64]; //Cabinet logic PrintDebug(DEBUG_SPAWNLOGIC, "Populating cabinets with extra items"); int spawner, count; @@ -1633,8 +1701,9 @@ void SaveInventory(int client) { void RestoreInventory(int client, PlayerInventory inventory) { PrintToConsoleAll("[debug:RINV] health=%d primaryID=%d secondID=%d throw=%d kit=%d pill=%d surv=%d", inventory.primaryHealth, inventory.itemID[0], inventory.itemID[1], inventory.itemID[2], inventory.itemID[3], inventory.itemID[4], inventory.itemID[5], inventory.survivorType); - - SetEntityModel(client, inventory.model); + + if(inventory.model[0] != '\0') + SetEntityModel(client, inventory.model); SetEntProp(client, Prop_Send, "m_survivorCharacter", inventory.survivorType); char buffer[32]; @@ -1685,7 +1754,7 @@ bool DoesInventoryDiffer(int client) { } bool IsEPIActive() { - return g_realSurvivorCount > 4 && IsGamemodeAllowed(); + return g_epiEnabled; } void UpdateSurvivorCount() { @@ -1711,7 +1780,7 @@ void UpdateSurvivorCount() { g_realSurvivorCount = DEBUG_FORCE_PLAYERS; #endif - if(g_realSurvivorCount > 4) { + if(g_survivorCount > 4) { // Update friendly fire values to reduce accidental FF in crowded corridors ConVar friendlyFireFactor = GetActiveFriendlyFireFactor(); // TODO: Get previous default @@ -1719,10 +1788,12 @@ void UpdateSurvivorCount() { if(friendlyFireFactor.FloatValue < 0.0) { friendlyFireFactor.FloatValue = 0.01; } + g_epiEnabled = g_isGamemodeAllowed; + } else { + g_epiEnabled = false; } // TODO: update hMinPlayers - } stock int FindFirstSurvivor() {