Giter Site home page Giter Site logo

l4d2_scavenge_1st_round_skip's People

Contributors

nagadomi avatar

Watchers

 avatar  avatar

Forkers

cocosouth

l4d2_scavenge_1st_round_skip's Issues

Better solution to fixing gas can bug, but requires sigscanning

#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <left4dhooks>

/**
*    @param    sMapName                Map String without .bsp
*    @param    bShouldResetScores        Reset all scores in all gamemodes
*    @noreturn
*/
native void L4D2_ChangeLevel(const char[] sMapName, bool bShouldResetScores=true); 

#define PLUGIN_VERSION "1.0"
#pragma newdecls required

#pragma semicolon 1

public Plugin myinfo =
{
	name = "[L4D2] Scavenge Hardcore",
	author = "Eyal282",
	description = "Hardcore Scavenge Rules",
	version = "1.0",
	url = "None."
}

int ghostSpawnIncreaseByInfected[4] = {0, 10, 15, 20};

int ghostSpawnIncreasePerUnbalanced[4] = {5, 10, 15, 20};

int ghostSpawnDecreasePerUnbalanced[4] = {5, 10, 15, 20};

char g_sRemoveMapWeapons[][] =
{
    "weapon_adrenaline_spawn",
    "weapon_defibrillator_spawn",
    "weapon_molotov_spawn",
    "weapon_pain_pills_spawn",
    "weapon_pipe_bomb_spawn",
    "weapon_propanetank_spawn",
    "weapon_vomitjar_spawn",
    "weapon_item_spawn",
    //"weapon_melee_spawn",
    "weapon_autoshotgun_spawn",
    "weapon_chainsaw_spawn",
    "weapon_hunting_rifle_spawn",
    "weapon_pistol_magnum_spawn",
    "weapon_pistol_spawn",
    "weapon_pumpshotgun_spawn",
    "weapon_rifle_ak47_spawn",
    "weapon_rifle_desert_spawn",
    "weapon_rifle_m60_spawn",
    "weapon_rifle_sg552_spawn",
    "weapon_rifle_spawn",
    "weapon_shotgun_chrome_spawn",
    "weapon_shotgun_spas_spawn",
    "weapon_smg_mp5_spawn",
    "weapon_smg_silenced_spawn",
    "weapon_sniper_awp_spawn",
    "weapon_sniper_military_spawn",
    "weapon_sniper_scout_spawn"
};

enum struct enReplaceWeapons 
{
    char sClassname[64];
    L4D2WeaponId wepID;

    // How many times can you take the new weapon before it disappears
    int count;

    // Maximum amount of entities to replace.
    int maxReplace;

    bool bSafeAreaOnly;


    // Ignore this.
    int currentReplace;
}

enReplaceWeapons g_sReplaceMapWeapons[] =
{
    { "weapon_spawn", L4D2WeaponId_Smg, 2, 99, true, 0 },
    { "weapon_first_aid_kit_spawn", L4D2WeaponId_PainPills, 1, 4, true, 0},
    { "weapon_melee_spawn", L4D2WeaponId_Molotov, 9999, 1, true, 0 }
};

ConVar g_hAllBotGame;
ConVar g_hGamemode;
ConVar g_hStartingClock;
ConVar g_hGhostDelayMin;
ConVar g_hGhostDelayMax;
ConVar g_hGhostDelayTrueMin;

float g_fMapStartTime;

public Action L4D_OnMaterializeFromGhostPre(int client)
{
    if(!L4D_HasAnySurvivorLeftSafeArea())
        return Plugin_Handled;

    return Plugin_Continue;
}

public Action L4D_OnSpawnSpecial(int &zombieClass, const float vecPos[3], const float vecAng[3])
{
    if(!L4D_HasAnySurvivorLeftSafeArea())
        return Plugin_Handled;

    return Plugin_Continue;
}
public void OnPluginStart()
{
    HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy);
    HookEvent("scavenge_round_start", Event_ScavengeRoundStart, EventHookMode_Post);
    HookEvent("player_spawn", Event_PlayerSpawn, EventHookMode_Post);
    HookEvent("bot_player_replace", Event_PlayerReplacesABot, EventHookMode_Post);
    //HookEvent("gascan_pour_completed", Event_GasCanPourCompleted, EventHookMode_PostNoCopy);

    g_hAllBotGame = FindConVar("sb_all_bot_game");
    g_hGamemode = FindConVar("mp_gamemode");
    g_hStartingClock = FindConVar("scavenge_round_initial_time");
    g_hGhostDelayMin = FindConVar("z_ghost_delay_min");
    g_hGhostDelayMax = FindConVar("z_ghost_delay_max");
    g_hGhostDelayTrueMin = FindConVar("z_ghost_delay_minspawn");

    HookVoteMsgs();
}

public void OnMapStart()
{
    g_fMapStartTime = GetGameTime();
    
    
    CreateTimer(1.0, Timer_CheckConfig, _, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT);
}

public Action Timer_CheckConfig(Handle hTimer)
{
    char MapName[32];
    GetCurrentMap(MapName, sizeof(MapName));

    int count, survivorCount, infectedCount;
    bool bLoading = false;

    for(int i=1;i <= MaxClients;i++)
    {
        if(IsClientConnected(i) && !IsClientInGame(i))
            bLoading = true;
        
        if(!IsClientInGame(i))
            continue;

        else if(IsFakeClient(i))
            continue;

        count++;

        switch(L4D_GetClientTeam(i))
        {
            case L4DTeam_Survivor:
            {
                count++;
                survivorCount++;
            }
            case L4DTeam_Infected:
            {
                count++;
                infectedCount++;
            }
        }
    }

    if(count == 0 || bLoading)
    {
        g_hAllBotGame.BoolValue = false;
    }
    else
    {
        // Weird bug.

        char sValue[32];
        g_hGamemode.GetString(sValue, sizeof(sValue));

        if(StrEqual(sValue, "scavenge") && GetGameTime() - g_fMapStartTime > 5.0 && GameRules_GetProp("m_nScavengeItemsRemaining") == 0 && GameRules_GetProp("m_nScavengeItemsGoal") == 0 && GetGasCanCount() == 0)
        {
            Scavenge_FixNoGascanSpawnBug();

            return Plugin_Continue;
        }
        g_hAllBotGame.BoolValue = true;
        g_hStartingClock.IntValue = 300;

        GetCurrentMap(MapName, sizeof(MapName));
        
        if(!StrEqual(MapName, "c8m5_rooftop") && !StrEqual(MapName, "c14m2_lighthouse"))
        {

            g_fMapStartTime = GetGameTime();

            L4D2_ChangeLevel("c8m5_rooftop");

            return Plugin_Stop;
        } 
    }

    g_hGhostDelayMin.IntValue = 0;
    g_hGhostDelayMax.IntValue = 0;

    if(infectedCount == 0)
        return Plugin_Continue;

    int timer = ghostSpawnIncreaseByInfected[infectedCount-1];

    if(infectedCount > survivorCount)
    {
        timer += ghostSpawnIncreasePerUnbalanced[(infectedCount - survivorCount - 1)];
    }
    else if(survivorCount > infectedCount)
    {
        timer -= ghostSpawnDecreasePerUnbalanced[(survivorCount - infectedCount - 1)];
    }

    g_hGhostDelayTrueMin.IntValue = timer;


    // Weird bug.

    char sValue[32];
    g_hGamemode.GetString(sValue, sizeof(sValue));

    if(!StrEqual(sValue, "scavenge"))
        g_hGamemode.SetString("scavenge");

    return Plugin_Continue;
}

public Action Event_RoundStart(Handle hEvent, const char[] Name, bool dontBroadcast)
{
    CreateTimer(1.0, Timer_ReplaceWeapons);

    return Plugin_Continue;
}

public Action Event_ScavengeRoundStart(Handle hEvent, const char[] Name, bool dontBroadcast)
{
    for(int i=1;i <= MaxClients;i++)
    {
        if(!IsClientInGame(i))
            continue;

        else if(L4D_GetClientTeam(i) != L4DTeam_Survivor)
            continue;

        SetEntityMoveType(i, MOVETYPE_WALK);
    }

    return Plugin_Continue;
}

public Action Event_PlayerSpawn(Handle hEvent, const char[] Name, bool dontBroadcast)
{
    int client = GetClientOfUserId(GetEventInt(hEvent, "userid"));

    if(L4D_GetClientTeam(client) != L4DTeam_Survivor)
        return Plugin_Continue;

    else if(L4D_HasAnySurvivorLeftSafeArea())
        return Plugin_Continue;
    
    
    if(IsFakeClient(client))        
        SetEntityMoveType(client, MOVETYPE_NONE);

    else
        SetEntityMoveType(client, MOVETYPE_WALK);

    return Plugin_Continue;
}

public Action Event_PlayerReplacesABot(Handle hEvent, const char[] Name, bool dontBroadcast)
{
    int client = GetClientOfUserId(GetEventInt(hEvent, "player"));

    if(L4D_GetClientTeam(client) != L4DTeam_Survivor)
        return Plugin_Continue;

    else if(L4D_HasAnySurvivorLeftSafeArea())
        return Plugin_Continue;
    
    SetEntityMoveType(client, MOVETYPE_WALK);

    return Plugin_Continue;
}

public Action Timer_ReplaceWeapons(Handle hTimer)
{

    for(int i=0;i < sizeof(g_sReplaceMapWeapons);i++)
    {
        g_sReplaceMapWeapons[i].currentReplace = g_sReplaceMapWeapons[i].maxReplace;
    }

    int count = GetEntityCount();

    for(int ent=MaxClients+1;ent < count;ent++)
    {
        if(!IsValidEdict(ent))
            continue;

        char sClassname[64];
        GetEdictClassname(ent, sClassname, sizeof(sClassname));

        for(int i=0;i < sizeof(g_sReplaceMapWeapons);i++)
        {	
        
            if(StrEqual(sClassname, g_sReplaceMapWeapons[i].sClassname))
            {
                OnSpawnPost_ReplaceWeaponSpawn(ent, i);

                i = 999999;
            }
        }
    }

    return Plugin_Continue;
}

public void OnSpawnPost_ReplaceWeaponSpawn(int entity, int replaceIndex)
{
    DataPack DP;
    CreateDataTimer(0.1, Timer_ReplaceWeaponSpawn, DP, TIMER_FLAG_NO_MAPCHANGE);

    WritePackCell(DP, EntIndexToEntRef(entity));
    WritePackCell(DP, replaceIndex);
}

public Action Timer_ReplaceWeaponSpawn(Handle hTimer, DataPack DP)
{
    ResetPack(DP);

    int entity = EntRefToEntIndex(ReadPackCell(DP));
    int replaceIndex = ReadPackCell(DP);

    if(entity == INVALID_ENT_REFERENCE)
        return Plugin_Stop;

    float fOrigin[3], fAngles[3];

    GetEntPropVector(entity, Prop_Send, "m_vecOrigin", fOrigin);
    GetEntPropVector(entity, Prop_Send, "m_angRotation", fAngles);

    AcceptEntityInput(entity, "Kill");

    if(g_sReplaceMapWeapons[replaceIndex].bSafeAreaOnly && !IsPositionInAnyCheckpoint(fOrigin))
        return Plugin_Stop;

    else if(g_sReplaceMapWeapons[replaceIndex].currentReplace <= 0)
        return Plugin_Stop;


    g_sReplaceMapWeapons[replaceIndex].currentReplace--;

    int spawn = CreateEntityByName("weapon_spawn");

    SetEntProp(spawn, Prop_Data, "m_weaponID", g_sReplaceMapWeapons[replaceIndex].wepID);

    char sCount[11];
    IntToString(g_sReplaceMapWeapons[replaceIndex].count, sCount, sizeof(sCount));

    DispatchKeyValue(spawn, "count", sCount);
    TeleportEntity(spawn, fOrigin, fAngles, NULL_VECTOR);
    DispatchSpawn(spawn);
    SetEntityMoveType(spawn, MOVETYPE_NONE);

    return Plugin_Stop;
}

public void OnEntityCreated(int entity, const char[] classname)
{
    // Sometimes a map will want to give RPG to continue progress.
    //if(StrEqual(classname, "game_player_equip"))
    //	SDKHook(entity, SDKHook_Spawn, OnShouldSpawn_NeverSpawn);

    for(int i=0;i < sizeof(g_sRemoveMapWeapons);i++)
    {
        if(StrEqual(classname, g_sRemoveMapWeapons[i]))
        {
            SDKHook(entity, SDKHook_Spawn, OnShouldSpawn_NeverSpawn);
        }
    }
}

public Action OnShouldSpawn_NeverSpawn(int entity)
{
    AcceptEntityInput(entity, "Kill");
    return Plugin_Handled;
}

void HookVoteMsgs()
{
	char msgname[64];
	int i = 1;
	while( i )
	{
		if( GetUserMessageName(view_as<UserMsg>(i), msgname, sizeof msgname) )
		{
			if( strcmp(msgname, "PZEndGamePanelMsg") == 0 )
			{
				HookUserMessage(view_as<UserMsg>(i), OnMessage, true);
				break;
			}

			i++;
		} else {
			i = 0;
		}
	}
}

public Action OnMessage(UserMsg msg_id, BfRead hMsg, const int[] players, int playersNum, bool reliable, bool init)
{
    char MapName[32];

    GetCurrentMap(MapName, sizeof(MapName));
    
    L4D2_ChangeLevel(MapName);

    g_fMapStartTime = GetGameTime();

	return Plugin_Handled;
}

public Action L4D_OnSpawnTank(const float vecPos[3], const float vecAng[3])
{
    return Plugin_Handled;
}

public Action L4D2_CGasCan_ShouldStartAction(int client, int gascan, int nozzle)
{

    float fOrigin[3], fNozzleOrigin[3];
    GetEntPropVector(client, Prop_Data, "m_vecAbsOrigin", fOrigin);
    GetEntPropVector(nozzle, Prop_Data, "m_vecOrigin", fNozzleOrigin);

    if(fOrigin[2] - fNozzleOrigin[2] > -40.0)
        return Plugin_Handled;

    return Plugin_Continue;
}
// Be careful, this includes scavenge safe areas.
stock bool IsPositionInAnyCheckpoint(float fOrigin[3])
{
    Address navarea = L4D_GetNearestNavArea(fOrigin);

    if(navarea == Address_Null)
        return false;

    int spawnAttributes = L4D_GetNavArea_SpawnAttributes(navarea);

    if(spawnAttributes & NAV_SPAWN_CHECKPOINT)
        return true;

    return false;
}

stock int GetGasCanCount()
{
    int count;
    int entCount = GetEntityCount();

    for(int ent=MaxClients+1;ent < entCount;ent++)
    {
        if(!IsValidEdict(ent))
            continue;

        char sClassname[64];
        GetEdictClassname(ent, sClassname, sizeof(sClassname));

        if(StrEqual(sClassname, "weapon_gascan") || StrEqual(sClassname, "weapon_gascan_spawn"))
            count++;
    }

    return count;
}

stock void Scavenge_FixNoGascanSpawnBug()
{   
    char sSignature[128];
    sSignature = "@_ZN9CDirector21SpawnAllScavengeItemsEv";
   
	Handle Call = INVALID_HANDLE;
	if (Call == INVALID_HANDLE)
	{
		StartPrepSDKCall(SDKCall_Raw);
		if (!PrepSDKCall_SetSignature(SDKLibrary_Server, sSignature, strlen(sSignature)-1))
		{
			return;
		}

		Call = EndPrepSDKCall();
		if (Call == INVALID_HANDLE)
		{
			return;
		}
	}

	SDKCall(Call, L4D_GetPointer(POINTER_DIRECTOR));
}```

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.