mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-05 15:53:20 +00:00
Attempt to prevent early tanks on escape vehicle rdy
This commit is contained in:
parent
61698e20c4
commit
3262a98203
3 changed files with 28 additions and 14 deletions
Binary file not shown.
|
@ -12,6 +12,7 @@ ConVar directorSpawnChance; // Base chance of a special spawning, changed by pla
|
||||||
#define DIRECTOR_STRESS_CUTOFF 0.75 // The minimum chance a random cut off stress value is chosen [this, 1.0]
|
#define DIRECTOR_STRESS_CUTOFF 0.75 // The minimum chance a random cut off stress value is chosen [this, 1.0]
|
||||||
#define DIRECTOR_REST_CHANCE 0.04 // The chance the director ceases spawning
|
#define DIRECTOR_REST_CHANCE 0.04 // The chance the director ceases spawning
|
||||||
#define DIRECTOR_REST_MAX_COUNT 8 // The maximum amount of rest given (this * DIRECTOR_TIMER_INTERVAL)
|
#define DIRECTOR_REST_MAX_COUNT 8 // The maximum amount of rest given (this * DIRECTOR_TIMER_INTERVAL)
|
||||||
|
#define DIRECTOR_ESCAPE_TANK_MIN_TIME_S 40 // The min time in seconds that must elapse since escape vehicle arrival until tank can spawn
|
||||||
|
|
||||||
#define DIRECTOR_DEBUG_SPAWN 1 // Dont actually spawn
|
#define DIRECTOR_DEBUG_SPAWN 1 // Dont actually spawn
|
||||||
|
|
||||||
|
@ -155,6 +156,12 @@ void Director_CheckClient(int client) {
|
||||||
static int g_newTankHealth = 0;
|
static int g_newTankHealth = 0;
|
||||||
void OnTankBotSpawn(int client) {
|
void OnTankBotSpawn(int client) {
|
||||||
if(!IsEPIActive() || !(cvEPISpecialSpawning.IntValue & 4)) return;
|
if(!IsEPIActive() || !(cvEPISpecialSpawning.IntValue & 4)) return;
|
||||||
|
if(g_finaleVehicleStartTime > 0 && GetTime() - g_finaleVehicleStartTime > DIRECTOR_ESCAPE_TANK_MIN_TIME_S) {
|
||||||
|
PrintDebug(DEBUG_SPAWNLOGIC, "OnTankBotSpawn: Tank too early, killing");
|
||||||
|
ForcePlayerSuicide(client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if any finale is active
|
// Check if any finale is active
|
||||||
if(g_newTankHealth > 0) {
|
if(g_newTankHealth > 0) {
|
||||||
// A split tank has spawned, set its health
|
// A split tank has spawned, set its health
|
||||||
|
@ -164,29 +171,29 @@ void OnTankBotSpawn(int client) {
|
||||||
return;
|
return;
|
||||||
} else if(g_realSurvivorCount >= hExtraTankThreshold.IntValue && g_extraFinaleTankEnabled && hExtraFinaleTank.IntValue > 1) {
|
} else if(g_realSurvivorCount >= hExtraTankThreshold.IntValue && g_extraFinaleTankEnabled && hExtraFinaleTank.IntValue > 1) {
|
||||||
// If we have hExtraTankThreshold or more and finale tanks enabled, spawn finale tanks:
|
// If we have hExtraTankThreshold or more and finale tanks enabled, spawn finale tanks:
|
||||||
if(g_finaleStage == Stage_Active) {
|
if(g_epiTankState == Stage_Active) {
|
||||||
// 1st tank spawned
|
// 1st tank spawned
|
||||||
PrintDebug(DEBUG_SPAWNLOGIC, "OnTankBotSpawn: [FINALE] 1st tank spawned");
|
PrintDebug(DEBUG_SPAWNLOGIC, "OnTankBotSpawn: [FINALE] 1st tank spawned");
|
||||||
int health = CalculateExtraTankHealth(client);
|
int health = CalculateExtraTankHealth(client);
|
||||||
SetEntProp(client, Prop_Send, "m_iHealth", health);
|
SetEntProp(client, Prop_Send, "m_iHealth", health);
|
||||||
g_finaleStage = Stage_FirstTankSpawned;
|
g_epiTankState = Stage_FirstTankSpawned;
|
||||||
return;
|
return;
|
||||||
} else if(g_realSurvivorCount >= 6 && g_finaleStage == Stage_FirstTankSpawned) {
|
} else if(g_realSurvivorCount >= 6 && g_epiTankState == Stage_FirstTankSpawned) {
|
||||||
PrintDebug(DEBUG_SPAWNLOGIC, "OnTankBotSpawn: [FINALE] 2nd tank spawned");
|
PrintDebug(DEBUG_SPAWNLOGIC, "OnTankBotSpawn: [FINALE] 2nd tank spawned");
|
||||||
float duration = GetRandomFloat(EXTRA_TANK_MIN_SEC, EXTRA_TANK_MAX_SEC);
|
float duration = GetRandomFloat(EXTRA_TANK_MIN_SEC, EXTRA_TANK_MAX_SEC);
|
||||||
// Pass it 0, which doesnt make it a split tank, has default health
|
// Pass it 0, which doesnt make it a split tank, has default health
|
||||||
CreateTimer(duration, Timer_SpawnSplitTank, 0);
|
CreateTimer(duration, Timer_SpawnSplitTank, 0);
|
||||||
int health = CalculateExtraTankHealth(client);
|
int health = CalculateExtraTankHealth(client);
|
||||||
SetEntProp(client, Prop_Send, "m_iHealth", health);
|
SetEntProp(client, Prop_Send, "m_iHealth", health);
|
||||||
g_finaleStage = Stage_SecondTankSpawned;
|
g_epiTankState = Stage_SecondTankSpawned;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// End finale logic:
|
// End finale logic:
|
||||||
if(g_finaleStage == Stage_SecondTankSpawned) {
|
if(g_epiTankState == Stage_SecondTankSpawned) {
|
||||||
PrintDebug(DEBUG_SPAWNLOGIC, "OnTankBotSpawn: [FINALE] Health set, tank logic done");
|
PrintDebug(DEBUG_SPAWNLOGIC, "OnTankBotSpawn: [FINALE] Health set, tank logic done");
|
||||||
g_finaleStage = Stage_ActiveDone;
|
g_epiTankState = Stage_ActiveDone;
|
||||||
// We don't return, letting the 2nd 5+ finale tank get buffed:
|
// We don't return, letting the 2nd 5+ finale tank get buffed:
|
||||||
}
|
}
|
||||||
// This should not run on active finales (different than finale maps, such as swamp fever's, where finale isnt full map)
|
// This should not run on active finales (different than finale maps, such as swamp fever's, where finale isnt full map)
|
||||||
|
@ -200,7 +207,7 @@ void OnTankBotSpawn(int client) {
|
||||||
(4) random chance set by hSplitTankChance
|
(4) random chance set by hSplitTankChance
|
||||||
Otherwise, just scale health based on survivor count
|
Otherwise, just scale health based on survivor count
|
||||||
*/
|
*/
|
||||||
if(g_finaleStage == Stage_Inactive && g_realSurvivorCount >= hExtraTankThreshold.IntValue && hExtraFinaleTank.IntValue & 1 && GetURandomFloat() <= hSplitTankChance.FloatValue) {
|
if(g_epiTankState == Stage_Inactive && g_realSurvivorCount >= hExtraTankThreshold.IntValue && hExtraFinaleTank.IntValue & 1 && GetURandomFloat() <= hSplitTankChance.FloatValue) {
|
||||||
float duration = GetRandomFloat(EXTRA_TANK_MIN_SEC, EXTRA_TANK_MAX_SEC);
|
float duration = GetRandomFloat(EXTRA_TANK_MIN_SEC, EXTRA_TANK_MAX_SEC);
|
||||||
int splitHealth = health / 2;
|
int splitHealth = health / 2;
|
||||||
PrintDebug(DEBUG_SPAWNLOGIC, "OnTankBotSpawn: split tank in %.1fs, health=%d", duration, splitHealth);
|
PrintDebug(DEBUG_SPAWNLOGIC, "OnTankBotSpawn: split tank in %.1fs, health=%d", duration, splitHealth);
|
||||||
|
@ -303,7 +310,7 @@ void Director_PrintDebug(int client) {
|
||||||
}
|
}
|
||||||
PrintToConsole(client, "highestFlow = %f, g_minFlowSpawn = %f, current flow = %f", g_highestFlowAchieved, g_minFlowSpawn, L4D2Direct_GetFlowDistance(client));
|
PrintToConsole(client, "highestFlow = %f, g_minFlowSpawn = %f, current flow = %f", g_highestFlowAchieved, g_minFlowSpawn, L4D2Direct_GetFlowDistance(client));
|
||||||
PrintToConsole(client, "g_maxStressIntensity = %f, current avg = %f", g_maxStressIntensity, L4D_GetAvgSurvivorIntensity());
|
PrintToConsole(client, "g_maxStressIntensity = %f, current avg = %f", g_maxStressIntensity, L4D_GetAvgSurvivorIntensity());
|
||||||
PrintToConsole(client, "TankInPlay=%b, FinaleStage=%d, FinaleEscapeReady=%b, DirectorTankCheck:%b", L4D2_IsTankInPlay(), g_finaleStage, g_isFinaleEnding, L4D2_IsTankInPlay() && !g_isFinaleEnding);
|
PrintToConsole(client, "TankInPlay=%b, FinaleStage=%d, FinaleEscapeReady=%b, DirectorTankCheck:%b", L4D2_IsTankInPlay(), g_epiTankState, g_isFinaleEnding, L4D2_IsTankInPlay() && !g_isFinaleEnding);
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
float time = GetGameTime();
|
float time = GetGameTime();
|
||||||
PrintToConsole(client, "Last Spawn Deltas: (%.1f s) (min %f)", time - g_lastSpecialSpawnTime, DIRECTOR_MIN_SPAWN_TIME);
|
PrintToConsole(client, "Last Spawn Deltas: (%.1f s) (min %f)", time - g_lastSpecialSpawnTime, DIRECTOR_MIN_SPAWN_TIME);
|
||||||
|
|
|
@ -99,6 +99,7 @@ static char g_currentGamemode[32];
|
||||||
static bool g_isGamemodeAllowed;
|
static bool g_isGamemodeAllowed;
|
||||||
int g_survivorCount, g_realSurvivorCount;
|
int g_survivorCount, g_realSurvivorCount;
|
||||||
bool g_isFinaleEnding;
|
bool g_isFinaleEnding;
|
||||||
|
int g_finaleVehicleStartTime;
|
||||||
static bool g_epiEnabled;
|
static bool g_epiEnabled;
|
||||||
bool g_isOfficialMap;
|
bool g_isOfficialMap;
|
||||||
|
|
||||||
|
@ -230,14 +231,15 @@ enum struct Cabinet {
|
||||||
}
|
}
|
||||||
static Cabinet cabinets[10]; //Store 10 cabinets
|
static Cabinet cabinets[10]; //Store 10 cabinets
|
||||||
|
|
||||||
enum FinaleStage {
|
enum EPI_FinaleTankState {
|
||||||
Stage_Inactive = 0,
|
Stage_Inactive = 0,
|
||||||
Stage_Active = 1, // Finale has started
|
Stage_Active = 1, // Finale has started
|
||||||
Stage_FirstTankSpawned = 2,
|
Stage_FirstTankSpawned = 2,
|
||||||
Stage_SecondTankSpawned = 3,
|
Stage_SecondTankSpawned = 3,
|
||||||
Stage_ActiveDone = 10 // No more logic to be done
|
Stage_ActiveDone = 10 // No more logic to be done
|
||||||
}
|
}
|
||||||
FinaleStage g_finaleStage;
|
EPI_FinaleTankState g_epiTankState;
|
||||||
|
int g_finaleState;
|
||||||
|
|
||||||
//// Definitions completSe
|
//// Definitions completSe
|
||||||
|
|
||||||
|
@ -295,6 +297,7 @@ public void OnPluginStart() {
|
||||||
HookEvent("finale_vehicle_incoming", Event_FinaleVehicleIncoming);
|
HookEvent("finale_vehicle_incoming", Event_FinaleVehicleIncoming);
|
||||||
HookEvent("player_bot_replace", Event_PlayerToIdle);
|
HookEvent("player_bot_replace", Event_PlayerToIdle);
|
||||||
HookEvent("bot_player_replace", Event_PlayerFromIdle);
|
HookEvent("bot_player_replace", Event_PlayerFromIdle);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -384,7 +387,9 @@ public void OnPluginStart() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Event_FinaleVehicleIncoming(Event event, const char[] name, bool dontBroadcast) {
|
void Event_FinaleVehicleIncoming(Event event, const char[] name, bool dontBroadcast) {
|
||||||
|
PrintDebug(DEBUG_INFO, "Finale vehicle incoming, preventing early tank spawns");
|
||||||
g_isFinaleEnding = true;
|
g_isFinaleEnding = true;
|
||||||
|
g_finaleVehicleStartTime = GetTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
Action Timer_ForceUpdateInventories(Handle h) {
|
Action Timer_ForceUpdateInventories(Handle h) {
|
||||||
|
@ -1331,6 +1336,7 @@ void Debug_GetAttributes(int attributes, char[] output, int maxlen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void L4D2_OnChangeFinaleStage_Post(int stage) {
|
public void L4D2_OnChangeFinaleStage_Post(int stage) {
|
||||||
|
g_finaleState = stage;
|
||||||
if(stage == 1 && IsEPIActive()) {
|
if(stage == 1 && IsEPIActive()) {
|
||||||
IncreaseKits(true);
|
IncreaseKits(true);
|
||||||
}
|
}
|
||||||
|
@ -1387,7 +1393,7 @@ public void OnMapStart() {
|
||||||
HookEntityOutput("info_changelevel", "OnStartTouch", EntityOutput_OnStartTouchSaferoom);
|
HookEntityOutput("info_changelevel", "OnStartTouch", EntityOutput_OnStartTouchSaferoom);
|
||||||
HookEntityOutput("trigger_changelevel", "OnStartTouch", EntityOutput_OnStartTouchSaferoom);
|
HookEntityOutput("trigger_changelevel", "OnStartTouch", EntityOutput_OnStartTouchSaferoom);
|
||||||
|
|
||||||
g_finaleStage = Stage_Inactive;
|
g_epiTankState = Stage_Inactive;
|
||||||
|
|
||||||
L4D2_RunScript(HUD_SCRIPT_CLEAR);
|
L4D2_RunScript(HUD_SCRIPT_CLEAR);
|
||||||
Director_OnMapStart();
|
Director_OnMapStart();
|
||||||
|
@ -1488,11 +1494,12 @@ public void OnMapEnd() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete updateHudTimer;
|
delete updateHudTimer;
|
||||||
|
g_finaleVehicleStartTime = 0;
|
||||||
Director_OnMapEnd();
|
Director_OnMapEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Event_FinaleStart(Event event, const char[] name, bool dontBroadcast) {
|
void Event_FinaleStart(Event event, const char[] name, bool dontBroadcast) {
|
||||||
g_finaleStage = Stage_Active;
|
g_epiTankState = Stage_Active;
|
||||||
}
|
}
|
||||||
public void OnClientSpeaking(int client) {
|
public void OnClientSpeaking(int client) {
|
||||||
g_isSpeaking[client] = true;
|
g_isSpeaking[client] = true;
|
||||||
|
@ -1836,7 +1843,6 @@ void PopulateItemSpawns(int minWalls = 4) {
|
||||||
navs.Sort(Sort_Random, Sort_Integer);
|
navs.Sort(Sort_Random, Sort_Integer);
|
||||||
float pos[3];
|
float pos[3];
|
||||||
float percentage = hExtraSpawnBasePercentage.FloatValue * (g_survivorCount - 4);
|
float percentage = hExtraSpawnBasePercentage.FloatValue * (g_survivorCount - 4);
|
||||||
PrintToServer("[EPI] Populating extra item spawns based on player count (%d-4) | Percentage %.2f%%", g_survivorCount, percentage * 100);
|
|
||||||
int tier;
|
int tier;
|
||||||
// On first chapter, 10% chance to give tier 2
|
// On first chapter, 10% chance to give tier 2
|
||||||
if(g_currentChapter == 1) tier = GetRandomFloat() < 0.15 ? 1 : 0;
|
if(g_currentChapter == 1) tier = GetRandomFloat() < 0.15 ? 1 : 0;
|
||||||
|
@ -1844,10 +1850,11 @@ void PopulateItemSpawns(int minWalls = 4) {
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
float mapFlowMax = L4D2Direct_GetMapMaxFlowDistance();
|
float mapFlowMax = L4D2Direct_GetMapMaxFlowDistance();
|
||||||
PrintToServer("[EPI] PopulateItemSpawns: flow[0, %f]", mapFlowMax);
|
|
||||||
int maxSpawns = RoundFloat(mapFlowMax / MAX_RANDOM_SPAWNS);
|
int maxSpawns = RoundFloat(mapFlowMax / MAX_RANDOM_SPAWNS);
|
||||||
int defibCount = CalculateExtraDefibCount();
|
int defibCount = CalculateExtraDefibCount();
|
||||||
bool isFinale = L4D_IsMissionFinalMap();
|
bool isFinale = L4D_IsMissionFinalMap();
|
||||||
|
PrintToServer("[EPI] Populating extra item spawns based on player count (%d-4) | Percentage %.2f%%", g_survivorCount, percentage * 100);
|
||||||
|
PrintToServer("[EPI] PopulateItemSpawns: flow[0, %f] tier=%d maxSpawns=%d defibCount=%d", mapFlowMax, tier, maxSpawns, defibCount);
|
||||||
|
|
||||||
for(int i = 0; i < navs.Length; i++) {
|
for(int i = 0; i < navs.Length; i++) {
|
||||||
Address nav = navs.Get(i);
|
Address nav = navs.Get(i);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue