L4D2 Vscript Helpers
Jump to navigation
Jump to search
Sometimes an idea for a function is not immediately available in the List of L4D2 Script Functions
This function library was built to help you get more functions for your code.
/*
Eyal282's helper scripts:
*/
/**
* Helper function that prevents the game from giving a pistol to an incapped player.
*/
function OnGameEvent_item_pickup( params )
{
local ent = null
if("userid" in params && params.userid == 0){
return;
}
ent = GetPlayerFromUserID(params["userid"])
if(ent.IsIncapacitated())
{
local classname = "weapon_" + params["item"];
RemovePlayerWeapon(ent, classname);
}
}
/**
* Helper function to prevent witches from instakilling survivors. This is done by blocking the damage via AllowTakeDamage and manually setting the health to 0.
* It also caps the damage to 100 to prevent dealing 400 damage when incapped. Note that she still shreds through that 400 health in under a second.
*/
function AllowTakeDamage(damageTable)
{
local attacker = damageTable.Attacker;
local victim = damageTable.Victim;
if (attacker != null && victim != null && attacker.GetClassname() == "witch")
{
if(victim != null && victim.GetClassname() == "player" && victim.IsSurvivor())
{
if(damageTable.DamageDone > victim.GetMaxHealth())
damageTable.DamageDone = victim.GetMaxHealth(); // Caps incap damage at 100.
if(damageTable.DamageDone >= victim.GetHealth())
{
DoEntFire( "!self", "SetHealth", "0", 0, victim, victim );
}
else
{
victim.SetHealth(victim.GetHealth() - damageTable.DamageDone);
}
damageTable.DamageDone = 0;
return false;
}
}
}
/**
* Helper function to equip adrenaline and pipe bomb found in safe room to avoid wasting time, happens on grabbing any item, or when pressing E on safe room door.
* If someone has a tactic to make this run when the player spawns, please alter it.
*/
function OnGameEvent_player_use( params )
{
local autoEquipItems =
{
weapon_adrenaline = "Adrenaline"
weapon_pipe_bomb = "Pipe Bomb"
}
if(!player.IsDead() && !player.IsDying() && player.IsSurvivor() && IsEntityInStartSafeRoom(player))
{
foreach(key, val in autoEquipItems)
{
if(DoesPlayerHaveWeapon(player, key))
{
continue;
}
else
{
local weapon = null;
while ( weapon = Entities.FindByClassname( weapon, key + "_spawn" ) )
{
if ( weapon.IsValid() )
{
// If a weapon is nodraw, it's deleted for all intents and purposes.
if( IsEntityInStartSafeRoom(weapon) && !(NetProps.GetPropInt(weapon, "m_fEffects") & 32))
{
DoEntFire( "!self", "Use", "", 0, player, weapon );
ClientPrint(player, 5, "Equipped " + val + " from safe room.");
break;
}
}
}
}
}
}
}
}
/**
* Checks whether or not an entity is in the starting safe room
*
* @param entity Entity to check
* @return true if entity is in start safe room, false otherwise.
* @notes This works for the safe area on the first chapter of a campaign.
*/
function IsEntityInStartSafeRoom(entity)
{
local origin = entity.GetOrigin();
local navArea = NavMesh.GetNearestNavArea(origin, 2048, true, true);
if(navArea != null)
{
// Some stupid maps like Blood Harvest finale and The Passing finale have CHECKPOINT inside a FINALE marked area.
if(navArea.HasSpawnAttributes(64))
{
return false;
}
// https://developer.valvesoftware.com/wiki/List_of_L4D_Series_Nav_Mesh_Attributes
else if(navArea.HasSpawnAttributes(2048) && GetFlowPercentForPosition(origin, false) <= 50.0)
{
return true;
}
}
return false;
}
/**
* Checks whether or not an entity is in the ending safe room
*
* @param entity Entity to check
* @return true if entity is in end safe room, false otherwise.
* @notes It is unknown whether or not this works for rescue vehicles.
*/
function IsEntityInEndSafeRoom(entity)
{
local origin = entity.GetOrigin();
local navArea = NavMesh.GetNearestNavArea(origin, 2048, true, true);
if(navArea != null)
{
// Some stupid maps like Blood Harvest finale and The Passing finale have CHECKPOINT inside a FINALE marked area.
if(navArea.HasSpawnAttributes(64))
{
return false;
}
// https://developer.valvesoftware.com/wiki/List_of_L4D_Series_Nav_Mesh_Attributes
else if(navArea.HasSpawnAttributes(2048) && GetFlowPercentForPosition(origin, false) >= 50.0)
{
return true;
}
}
return false;
}
/**
* Checks whether or not an player owns a weapon by its classname
*
* @param player player to check
* @param classname classname string to check
* @return true if player has the weapon in inventory, false otherwise
*/
function DoesPlayerHaveWeapon(player, classname)
{
local invTable = {};
GetInvTable(player, invTable);
foreach(slot, weapon in invTable)
{
if(weapon.GetClassname() == classname)
{
return true;
}
}
return false;
}
/**
* Removes a weapon from a client's inventory by classname
*
* @param player player to remove
* @param classname classname string to remove.
* @noreturn
*/
function RemovePlayerWeapon(player, classname)
{
local invTable = {};
GetInvTable(player, invTable);
foreach(slot, weapon in invTable)
{
if(weapon.GetClassname() == classname)
{
weapon.Kill();
}
}
return false;
}
/**
* Checks whether or an entity is on the ground.
*
* @param entity Entity to check
* @return true if entity is on the ground, false otherwise ( in the air )
* @error Entity cannot have m_hGroundEntity, likely only for entities without physics.
* @notes It is unknown what happens for surfing entities on slopes.
*/
function IsEntityOnGround(entity)
{
local groundEntity = NetProps.GetPropEntity(entity, "m_hGroundEntity");
// Cannot find a ground entity = air.
if(groundEntity == null)
return false;
return true;
}
/**
* Checks whether or a player is throwing a tank rock. This can work on non-tanks by looping all rocks and finding their thrower
*
* @param player Player to check
* @return true if player has an active rock, false otherwise.
* @notes Due to checking every rock's owner, this won't error on non-tanks.
* @notes This is not exclusive to the tank rock animation. This is true for as long as the tank has a rock active.
*/
function IsPlayerThrowingRock(player)
{
local rock = null;
while((rock = Entities.FindByClassname(rock, "tank_rock")))
{
if(NetProps.GetPropEntity(rock, "m_hThrower") == player)
return true;
}
return false;
}
/**
* Checks how many seconds a burning tank has to live from fire alone.
*
* @param player Player to check
* @return returns a float of the seconds left for the player.
* @notes This works for every player, even if not a tank, and works if the player is not burning. It's just a formula.
*/
function GetTankBurnSecondsLeft(player)
{
local gamemode = Convars.GetStr("mp_gamemode")
local difficulty = Convars.GetStr("z_difficulty")
local burnDuration = 0.0;
switch(gamemode)
{
case "versus" : case "survival" :
burnDuration = Convars.GetFloat("tank_burn_duration");
break;
default:
switch(difficulty)
{
case "Impossible":
burnDuration = Convars.GetFloat("tank_burn_duration_expert");
break;
case "Hard":
burnDuration = Convars.GetFloat("tank_burn_duration_hard");
break;
default :
burnDuration = Convars.GetFloat("tank_burn_duration");
break;
}
break;
}
return (player.GetHealth().tofloat() / player.GetMaxHealth().tofloat()) * burnDuration;
}
/*
Anonymous's helper scripts:
*/
function IsMissionFinale()
{
if(IsMissionFinalMap())
{
return true;
}
return false;
}