From f5e0662e5882106529f773b1788d55f1a316c20f Mon Sep 17 00:00:00 2001 From: Jackz Date: Thu, 15 Feb 2024 09:03:07 -0600 Subject: [PATCH] Update dhooks --- scripting/include/left4dhooks.inc | 1288 +++++++++++++++-- scripting/include/left4dhooks_anim.inc | 4 +- scripting/include/left4dhooks_lux_library.inc | 22 +- scripting/include/left4dhooks_silver.inc | 71 +- scripting/include/left4dhooks_stocks.inc | 30 +- 5 files changed, 1281 insertions(+), 134 deletions(-) diff --git a/scripting/include/left4dhooks.inc b/scripting/include/left4dhooks.inc index 5f9d215..1ae9749 100644 --- a/scripting/include/left4dhooks.inc +++ b/scripting/include/left4dhooks.inc @@ -18,7 +18,7 @@ * Copyright (C) 2017 "Accelerator74" * * Left 4 DHooks Direct SourceMod plugin - * Copyright (C) 2023 "SilverShot" / "Silvers" + * Copyright (C) 2024 "SilverShot" / "Silvers" * * ============================================================================= * @@ -51,6 +51,8 @@ #endif #define _l4dh_included +#pragma newdecls required + #include #include #include @@ -58,17 +60,18 @@ -// Natives: 256 (including 3 for L4D1 only) -// L4D1 = 31 [left4downtown] + 47 [l4d_direct] + 16 [l4d2addresses] + 61 [silvers - mine!] + 4 [anim] = 159 -// L4D2 = 61 [left4downtown] + 59 [l4d_direct] + 31 [l4d2addresses] + 98 [silvers - mine!] + 4 [anim] = 253 +// Natives: 272 (including 3 for L4D1 only) +// L4D1 = 31 [left4downtown] + 47 [l4d_direct] + 16 [l4d2addresses] + 70 [silvers - mine!] + 4 [anim] = 169 +// L4D2 = 61 [left4downtown] + 59 [l4d_direct] + 31 [l4d2addresses] + 114 [silvers - mine!] + 4 [anim] = 269 +// Methods and Natives by "Forgetest": 53 [PlayerAnimState] + 22 [Ammo_t] + 15 [AmmoDef] = 90 -// Forwards: 195 (including 5 for L4D1 only) -// L4D1 = 135 -// L4D2 = 190 +// Forwards: 217 (including 5 for L4D1 only) +// L4D1 = 146 +// L4D2 = 212 -// Stocks: 169 (L4D1 = 112, L4D2 = 165) +// Stocks: 169 (L4D1 = 114, L4D2 = 167) // left4dhooks_silver 46 stocks (L4D1 = 39, L4D2 = 53) -// left4dhooks_stocks 83 stocks (L4D1 = 44, L4D2 = 79) +// left4dhooks_stocks 84 stocks (L4D1 = 45, L4D2 = 80) // left4dhooks_lux_library 34 stocks (L4D1 = 30, L4D2 = 34) @@ -96,7 +99,6 @@ public void __pl_l4dh_SetNTVOptional() MarkNativeAsOptional("AnimHookDisable"); MarkNativeAsOptional("AnimGetActivity"); MarkNativeAsOptional("AnimGetFromActivity"); - MarkNativeAsOptional("L4D_GetGameModeType"); MarkNativeAsOptional("L4D_Deafen"); MarkNativeAsOptional("L4D_GetTempHealth"); @@ -136,13 +138,16 @@ public void __pl_l4dh_SetNTVOptional() MarkNativeAsOptional("L4D_MolotovPrj"); MarkNativeAsOptional("L4D2_VomitJarPrj"); MarkNativeAsOptional("L4D2_GrenadeLauncherPrj"); - + MarkNativeAsOptional("L4D_PrecacheParticle"); + MarkNativeAsOptional("L4D_RemoveEntityDelay"); MarkNativeAsOptional("L4D_GetPointer"); MarkNativeAsOptional("L4D_GetClientFromAddress"); MarkNativeAsOptional("L4D_GetEntityFromAddress"); MarkNativeAsOptional("L4D_ReadMemoryString"); + MarkNativeAsOptional("L4D_WriteMemoryString"); MarkNativeAsOptional("L4D_GetServerOS"); MarkNativeAsOptional("Left4DHooks_Version"); + MarkNativeAsOptional("L4D_HasMapStarted"); MarkNativeAsOptional("L4D2_GetScriptScope"); MarkNativeAsOptional("L4D2_GetVScriptEntity"); MarkNativeAsOptional("L4D2_ExecVScriptCode"); @@ -157,6 +162,8 @@ public void __pl_l4dh_SetNTVOptional() MarkNativeAsOptional("L4D2_AreWanderersAllowed"); MarkNativeAsOptional("L4D2_GetCurrentFinaleStage"); MarkNativeAsOptional("L4D2_ForceNextStage"); + MarkNativeAsOptional("L4D2_GetSurvivalStartTime"); + MarkNativeAsOptional("L4D2_SetSurvivalStartTime"); MarkNativeAsOptional("L4D_ForceVersusStart"); MarkNativeAsOptional("L4D_ForceSurvivalStart"); MarkNativeAsOptional("L4D2_ForceScavengeStart"); @@ -178,7 +185,6 @@ public void __pl_l4dh_SetNTVOptional() MarkNativeAsOptional("L4D_IsSurvivalMode"); MarkNativeAsOptional("L4D2_IsScavengeMode"); MarkNativeAsOptional("L4D_IsVersusMode"); - MarkNativeAsOptional("L4D2_VScriptWrapper_GetMapNumber"); MarkNativeAsOptional("L4D2_VScriptWrapper_HasEverBeenInjured"); MarkNativeAsOptional("L4D2_VScriptWrapper_GetAliveDuration"); @@ -221,8 +227,8 @@ public void __pl_l4dh_SetNTVOptional() MarkNativeAsOptional("L4D_SetNavArea_SpawnAttributes"); MarkNativeAsOptional("L4D_GetNavArea_AttributeFlags"); MarkNativeAsOptional("L4D_SetNavArea_AttributeFlags"); - MarkNativeAsOptional("L4D_ScavengeBeginRoundSetupTime"); + MarkNativeAsOptional("L4D2_SpawnAllScavengeItems"); MarkNativeAsOptional("L4D_ResetMobTimer"); MarkNativeAsOptional("L4D_GetPlayerSpawnTime"); MarkNativeAsOptional("L4D_SetPlayerSpawnTime"); @@ -306,7 +312,6 @@ public void __pl_l4dh_SetNTVOptional() MarkNativeAsOptional("L4DDirect_GetSurvivorHealthBonus"); MarkNativeAsOptional("L4DDirect_SetSurvivorHealthBonus"); MarkNativeAsOptional("L4DDirect_RecomputeTeamScores"); - MarkNativeAsOptional("L4D2Direct_GetTankCount"); MarkNativeAsOptional("L4D2Direct_GetMobSpawnTimer"); MarkNativeAsOptional("L4D2Direct_GetSIClassDeathTimer"); @@ -341,7 +346,6 @@ public void __pl_l4dh_SetNTVOptional() MarkNativeAsOptional("ITimer_Invalidate"); MarkNativeAsOptional("ITimer_HasStarted"); MarkNativeAsOptional("ITimer_GetElapsedTime"); - MarkNativeAsOptional("CTimer_GetDuration"); MarkNativeAsOptional("CTimer_SetDuration"); MarkNativeAsOptional("CTimer_GetTimestamp"); @@ -359,8 +363,15 @@ public void __pl_l4dh_SetNTVOptional() MarkNativeAsOptional("L4D2_Charger_StartCarryingVictim"); MarkNativeAsOptional("L4D2_Charger_PummelVictim"); MarkNativeAsOptional("L4D2_Charger_EndPummel"); + MarkNativeAsOptional("L4D2_Charger_EndCarry"); MarkNativeAsOptional("L4D2_Jockey_EndRide"); + MarkNativeAsOptional("L4D_Hunter_ReleaseVictim"); + MarkNativeAsOptional("L4D_Smoker_ReleaseVictim"); MarkNativeAsOptional("L4D_CancelStagger"); + MarkNativeAsOptional("L4D_FindUseEntity"); + MarkNativeAsOptional("L4D_ForceHunterVictim"); + MarkNativeAsOptional("L4D_ForceSmokerVictim"); + MarkNativeAsOptional("L4D2_ForceJockeyVictim"); MarkNativeAsOptional("L4D_CreateRescuableSurvivors"); MarkNativeAsOptional("L4D_ReviveSurvivor"); MarkNativeAsOptional("L4D_GetHighestFlowSurvivor"); @@ -375,18 +386,123 @@ public void __pl_l4dh_SetNTVOptional() MarkNativeAsOptional("L4D_State_Transition"); MarkNativeAsOptional("L4D_RegisterForbiddenTarget"); MarkNativeAsOptional("L4D_UnRegisterForbiddenTarget"); - MarkNativeAsOptional("L4D2_CTerrorPlayer_OnHitByVomitJar"); MarkNativeAsOptional("L4D2_Infected_OnHitByVomitJar"); MarkNativeAsOptional("L4D2_CTerrorPlayer_Fling"); MarkNativeAsOptional("L4D2_GetVersusCompletionPlayer"); MarkNativeAsOptional("L4D2_SwapTeams"); MarkNativeAsOptional("L4D2_AreTeamsFlipped"); + MarkNativeAsOptional("L4D_EndVersusModeRound"); MarkNativeAsOptional("L4D2_StartRematchVote"); + MarkNativeAsOptional("L4D2_Rematch"); MarkNativeAsOptional("L4D2_FullRestart"); MarkNativeAsOptional("L4D2_HideVersusScoreboard"); MarkNativeAsOptional("L4D2_HideScavengeScoreboard"); MarkNativeAsOptional("L4D2_HideScoreboard"); + + PlayerAnimState_MarkNativeAsOptional(); + Ammo_t_MarkNativeAsOptional(); + AmmoDef_MarkNativeAsOptional(); +} + +// ANIMATION NATIVES +void PlayerAnimState_MarkNativeAsOptional() +{ + MarkNativeAsOptional("PlayerAnimState.FromPlayer"); + MarkNativeAsOptional("PlayerAnimState.GetMainActivity"); + MarkNativeAsOptional("PlayerAnimState.ResetMainActivity"); + MarkNativeAsOptional("PlayerAnimState.m_bIsCustomSequence.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsCustomSequence.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsDead.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsDead.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsHealing.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsHealing.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsResurrection.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsResurrection.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsHitByCharger.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsHitByCharger.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsPummeled.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsPummeled.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsSlammedIntoWall.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsSlammedIntoWall.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsSlammedIntoGround.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsSlammedIntoGround.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsStartPummel.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsStartPummel.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsPounded.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsPounded.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsCarriedByCharger.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsCarriedByCharger.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsPunchedByTank.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsPunchedByTank.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsSpitting.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsSpitting.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsPouncedOn.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsPouncedOn.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsTongueAttacked.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsTongueAttacked.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsStartChainsaw.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsStartChainsaw.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsIsPouncing.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsIsPouncing.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsRiding.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsRiding.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsJockeyRidden.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsJockeyRidden.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsTonguing.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsTonguing.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsCharging.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsCharging.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsPummeling.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsPummeling.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsPounding.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsPounding.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsTongueReelingIn.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsTongueReelingIn.set"); + MarkNativeAsOptional("PlayerAnimState.m_bIsTongueAttacking.get"); + MarkNativeAsOptional("PlayerAnimState.m_bIsTongueAttacking.set"); +} + +void Ammo_t_MarkNativeAsOptional() +{ + MarkNativeAsOptional("Ammo_t.GetName"); + MarkNativeAsOptional("Ammo_t.nDamageType.get"); + MarkNativeAsOptional("Ammo_t.nDamageType.set"); + MarkNativeAsOptional("Ammo_t.eTracerType.get"); + MarkNativeAsOptional("Ammo_t.eTracerType.set"); + MarkNativeAsOptional("Ammo_t.physicsForceImpulse.get"); + MarkNativeAsOptional("Ammo_t.physicsForceImpulse.set"); + MarkNativeAsOptional("Ammo_t.nMinSplashSize.get"); + MarkNativeAsOptional("Ammo_t.nMinSplashSize.set"); + MarkNativeAsOptional("Ammo_t.nMaxSplashSize.get"); + MarkNativeAsOptional("Ammo_t.nMaxSplashSize.set"); + MarkNativeAsOptional("Ammo_t.nFlags.get"); + MarkNativeAsOptional("Ammo_t.nFlags.set"); + MarkNativeAsOptional("Ammo_t.pPlrDmg.get"); + MarkNativeAsOptional("Ammo_t.pPlrDmg.set"); + MarkNativeAsOptional("Ammo_t.pNPCDmg.get"); + MarkNativeAsOptional("Ammo_t.pNPCDmg.set"); + MarkNativeAsOptional("Ammo_t.pMaxCarry.get"); + MarkNativeAsOptional("Ammo_t.pMaxCarry.set"); + MarkNativeAsOptional("Ammo_t.pPlrDmgCVar.get"); + MarkNativeAsOptional("Ammo_t.pNPCDmgCVar.get"); + MarkNativeAsOptional("Ammo_t.pMaxCarryCVar.get"); +} + +void AmmoDef_MarkNativeAsOptional() +{ + MarkNativeAsOptional("AmmoDef.GetAmmoOfIndex"); + MarkNativeAsOptional("AmmoDef.Index"); + MarkNativeAsOptional("AmmoDef.PlrDamage"); + MarkNativeAsOptional("AmmoDef.NPCDamage"); + MarkNativeAsOptional("AmmoDef.MaxCarry"); + MarkNativeAsOptional("AmmoDef.DamageType"); + MarkNativeAsOptional("AmmoDef.Flags"); + MarkNativeAsOptional("AmmoDef.MinSplashSize"); + MarkNativeAsOptional("AmmoDef.MaxSplashSize"); + MarkNativeAsOptional("AmmoDef.TracerType"); + MarkNativeAsOptional("AmmoDef.DamageForce"); + MarkNativeAsOptional("AmmoDef.GetAmmoIndex"); } #endif @@ -408,6 +524,7 @@ enum }; // For the "L4D_GetPointer" native +// Some of these will only be valid after OnMapStart() because they change on each new map. For example: POINTER_GAMERULES, POINTER_THENAVAREAS, POINTER_MISSIONINFO and possibly others enum PointerType { POINTER_DIRECTOR = 1, // @TheDirector @@ -421,7 +538,10 @@ enum PointerType POINTER_SCAVENGEMODE = 9, // pScavengeMode (L4D2 Only) POINTER_VERSUSMODE = 10, // pVersusMode POINTER_SCRIPTVM = 11, // @g_pScriptVM (L4D2 Only) - POINTER_THENAVAREAS = 12 // @TheNavAreas + POINTER_THENAVAREAS = 12, // @TheNavAreas + POINTER_MISSIONINFO = 13, // MissionInfo pointer + POINTER_SURVIVALMODE = 14, // pSurvivalMode pointer (assuming this is the same as pVersusMode in L4D1 and also TheDirector) + POINTER_AMMODEF = 15 // ammoDef Pointer }; // Provided by "BHaType": @@ -462,7 +582,8 @@ enum FINALE_GAUNTLET_HORDE_BONUSTIME = 14, FINALE_GAUNTLET_BOSS_INCOMING = 15, FINALE_GAUNTLET_BOSS = 16, - FINALE_GAUNTLET_ESCAPE = 17 + FINALE_GAUNTLET_ESCAPE = 17, + FINALE_NONE = 18 }; // Used as the "reason" by the "L4D_OnKnockedDown*" forwards @@ -554,6 +675,7 @@ enum // Some constants from 'l4d2util_contants.inc' // These are used by the "L4D2Direct_DoAnimationEvent" native and "L4D_OnDoAnimationEvent*" forwards // L4D1 seems to only have 35 animation events, the names may not be relative to those listed here +// For L4D1: See below the enum. enum PlayerAnimEvent_t { // Made by A1m` @@ -566,9 +688,7 @@ enum PlayerAnimEvent_t PLAYERANIMEVENT_RELOAD_END = 6, //CMultiPlayerAnimState::DoAnimationEvent, CBaseShotgun::CheckReload->PlayReloadAnim, CTerrorGun::AbortReload PLAYERANIMEVENT_JUMP = 7, // CMultiPlayerAnimState::DoAnimationEvent, CTerrorGameMovement::DoJump, CCSGameMovement::CheckJumpButton PLAYERANIMEVENT_LAND = 8, // CTerrorGameMovement::PlayerRoughLandingEffects - PLAYERANIMEVENT_SWIM = 9, // Not sure, not used in the game anyway - PLAYERANIMEVENT_DIE = 10, // CMultiPlayerAnimState::DoAnimationEvent, CTerrorPlayer::StartSurvivorDeathAnim, CTerrorPlayer::OnIncapacitatedAsTank PLAYERANIMEVENT_FLINCH_CHEST = 11, // CMultiPlayerAnimState::DoAnimationEvent PLAYERANIMEVENT_FLINCH_HEAD = 12, // CMultiPlayerAnimState::DoAnimationEvent @@ -576,19 +696,14 @@ enum PlayerAnimEvent_t PLAYERANIMEVENT_FLINCH_RIGHTARM = 14, // CMultiPlayerAnimState::DoAnimationEvent PLAYERANIMEVENT_FLINCH_LEFTLEG = 15, // CMultiPlayerAnimState::DoAnimationEvent PLAYERANIMEVENT_FLINCH_RIGHTLEG = 16, // CMultiPlayerAnimState::DoAnimationEvent - PLAYERANIMEVENT_DOUBLEJUMP = 17, // Not sure, not used in the game anyway - PLAYERANIMEVENT_CANCEL_GESTURE_ATTACK_AND_RELOAD = 18, // CTerrorPlayer::OnShovedByPounceLanding, CTerrorPlayer::OnShovedBySurvivor, CTerrorPlayer::OnRideEnded, CTerrorPlayer::OnPounceEnded - PLAYERANIMEVENT_CANCEL = 19, // Not sure, not used in the game anyway - PLAYERANIMEVENT_SPAWN = 20, // CMultiPlayerAnimState::DoAnimationEvent PLAYERANIMEVENT_SNAP_YAW = 21, // CMultiPlayerAnimState::DoAnimationEvent PLAYERANIMEVENT_CUSTOM = 22, // CMultiPlayerAnimState::DoAnimationEvent PLAYERANIMEVENT_CUSTOM_GESTURE = 23, // CMultiPlayerAnimState::DoAnimationEvent PLAYERANIMEVENT_CUSTOM_SEQUENCE = 24, // CMultiPlayerAnimState::DoAnimationEvent - PLAYERANIMEVENT_CUSTOM_GESTURE_SEQUENCE = 25, // Not sure, not used in the game anyway // TF Specific. Here until there's a derived game solution to this @@ -599,7 +714,6 @@ enum PlayerAnimEvent_t PLAYERANIMEVENT_GRENADE1_THROW = 30, // Not sure, not used in the game anyway PLAYERANIMEVENT_GRENADE2_THROW = 31, // Not sure, not used in the game anyway PLAYERANIMEVENT_VOICE_COMMAND_GESTURE = 32, // Not sure, not used in the game?. CTerrorPlayerAnimState::DoAnimationEvent - PLAYERANIMEVENT_HAND_ATTACK = 33, // CClaw::OnSwingStart, CTerrorPlayer::UpdateTankEffects, CTankClaw::OnSwingStart PLAYERANIMEVENT_HAND_LOW_ATTACK = 34, // CTankClaw::OnSwingStart, CTerrorWeapon::OnSwingStart PLAYERANIMEVENT_SHOVE_COMMON = 35, // CTerrorWeapon::OnSwingStart @@ -627,17 +741,13 @@ enum PlayerAnimEvent_t PLAYERANIMEVENT_FLINCH_EVENT_SHOVED_BY_TEAMMATE = 57, // CTerrorPlayer::OnTakeDamageInternal->GetFlinchEvent, CTerrorPlayer::OnTakeDamage_Alive->GetFlinchEvent, CTerrorWeapon::OnHit->GetFlinchEvent PLAYERANIMEVENT_FLINCH_EVENT_TAKE_DAMAGE = 58, // CTerrorPlayer::GetFlinchEvent PLAYERANIMEVENT_THROW_ITEM_START = 59, // CBaseCSGrenade::PrimaryAttack - PLAYERANIMEVENT_ROLL_GRENADE = 60, // Not sure, not used in the game anyway - PLAYERANIMEVENT_THROW_ITEM_FINISH = 61, // CBaseCSGrenade::ItemPostFrame PLAYERANIMEVENT_THROW_GRENADE = 62, // CCSPlayer::DoAnimationEvent PLAYERANIMEVENT_THROW_ITEM_HOLSTER = 63, // CBaseCSGrenade::Holster PLAYERANIMEVENT_PLAYER_USE = 64, // CTerrorPlayer::OnUseEntity PLAYERANIMEVENT_CHANGE_SLOT = 65, // CWeaponCSBase::DefaultDeploy - PLAYERANIMEVENT_UNKNOWN_START_GESTURE = 66, // Don't know. Not used in the game? Something like option 32? CTerrorPlayerAnimState::DoAnimationEvent - PLAYERANIMEVENT_TUG_HANGING_PLAYER = 67, // CTerrorPlayer::StartTug PLAYERANIMEVENT_STUMBLE = 68, // CTerrorPlayer::UpdateStagger, CTerrorPlayer::OnShovedByPounceLanding, CTerrorPlayer::OnStaggered, CTerrorPlayer::UpdateStagger, CTerrorPlayer::OnShovedBySurvivor PLAYERANIMEVENT_POUNCE_VICTIM_END = 69, @@ -674,6 +784,428 @@ enum PlayerAnimEvent_t PLAYERANIMEVENT_COUNT // Total size 99. Function 'CTerrorPlayer::DoAnimationEvent' }; +// L4D1 anim values appear to be related to these below. Thanks to "Dragokas" for gathering a list of them: +/* +1 - Primary Attack +2 - Unused +3 - Aiming +4 - Reload Reserved Ammo +5 - Chambering Of A Cartridge (No Sound) +6 - Chambering Of A Cartridge (With Sound) +7 - Shotgun Reload (With Sound) +8 - Shotgun Reload (No Sound) +9 - Shove (Side) +10 - Shove (Forward) +11 - Shove (Right Arm) +12 - Stomp +13 - Heal Myself +14 - Heal Teammate1 +15 - Pick Up Incapped Player +16 - Heal Teammate2 +21 - Headbutt +22 - Headbutt2 +23 - Pick Up Item From Ground +24 - Take Item From Teammate +25 - Change Weapon +26 - Weapon Reload Fast +27 - Weapon Recoil + Reload +28 - Weapon Recoil + Reload (same) +29... - Seems unused (Same for 2, 17-20). +*/ + +enum WeaponType +{ + WEAPONTYPE_PISTOL, + WEAPONTYPE_SMG, + WEAPONTYPE_RIFLE, + WEAPONTYPE_SHOTGUN, + WEAPONTYPE_SNIPERRIFLE, + WEAPONTYPE_MACHINEGUN, + + WEAPONTYPE_GRENADE = 7, + WEAPONTYPE_HEALING, + WEAPONTYPE_REVIVING, + WEAPONTYPE_MELEE, + WEAPONTYPE_CHAINSAW, + WEAPONTYPE_GRENADELAUNCHER, + WEAPONTYPE_CARRIEDPROP, + WEAPONTYPE_CLAW, + WEAPONTYPE_UPGRADEPACK, + + WEAPONTYPE_UNKNOWN +}; + +stock const char g_sWeaponTypes[WeaponType][] = +{ + "pistol", + "smg", + "rifle", + "shotgun", + "sniperrifle", + "machinegun", + "", + "grenade", + "healing", + "reviving", + "melee", + "chainsaw", + "grenadelauncher", + "carriedprop", + "claw", + "upgradepack", + "" +}; + + + + + +// ==================================================================================================== +// ANIMATION NATIVES +// ==================================================================================================== +methodmap PlayerAnimState { + // Get the PlayerAnimState instance of a player. + public static native PlayerAnimState FromPlayer(int client); + + // Main activity of player's animation, matching enums in "left4dhooks_anim.inc". + public native int GetMainActivity(); + + // Restart and recalculate the main activity. + public native void ResetMainActivity(); + + // All booleans (or flags) that used for animation events. + property bool m_bIsCustomSequence { // True only after "CTerrorPlayerAnimState::SetCustomSequence". + public native get(); + public native set(bool value); + } + property bool m_bIsDead { + public native get(); + public native set(bool value); + } + property bool m_bIsHealing { + public native get(); + public native set(bool value); + } + property bool m_bIsResurrection { + public native get(); + public native set(bool value); + } + property bool m_bIsHitByCharger { // aka multi-charged, bowling. + public native get(); + public native set(bool value); + } + property bool m_bIsPummeled { + public native get(); + public native set(bool value); + } + property bool m_bIsSlammedIntoWall { + public native get(); + public native set(bool value); + } + property bool m_bIsSlammedIntoGround { + public native get(); + public native set(bool value); + } + property bool m_bIsStartPummel { // Something to do with charger pummel animation, not sure about the name. + public native get(); + public native set(bool value); + } + property bool m_bIsPounded { // Pummel get-up + public native get(); + public native set(bool value); + } + property bool m_bIsCarriedByCharger { + public native get(); + public native set(bool value); + } + property bool m_bIsPunchedByTank { // Rock get-up shares this + public native get(); + public native set(bool value); + } + property bool m_bIsSpitting { + public native get(); + public native set(bool value); + } + property bool m_bIsPouncedOn { + public native get(); + public native set(bool value); + } + property bool m_bIsTongueAttacked { + public native get(); + public native set(bool value); + } + property bool m_bIsStartChainsaw { + public native get(); + public native set(bool value); + } + property bool m_bIsIsPouncing { + public native get(); + public native set(bool value); + } + property bool m_bIsRiding { + public native get(); + public native set(bool value); + } + property bool m_bIsJockeyRidden { + public native get(); + public native set(bool value); + } + property bool m_bIsTonguing { + public native get(); + public native set(bool value); + } + property bool m_bIsCharging { + public native get(); + public native set(bool value); + } + property bool m_bIsPummeling { + public native get(); + public native set(bool value); + } + property bool m_bIsPounding { + public native get(); + public native set(bool value); + } + property bool m_bIsTongueReelingIn { + public native get(); + public native set(bool value); + } + property bool m_bIsTongueAttacking { + public native get(); + public native set(bool value); + } +} + + + + + +// ==================================================================================================== +// AMMO NATIVES - Thanks for "Forgetest" for providing. +// See link for more info: https://github.com/alliedmodders/hl2sdk/blob/l4d2/game/shared/ammodef.h +// ==================================================================================================== +/* +struct Ammo_t +{ + char *pName; + int nDamageType; + int eTracerType; + float physicsForceImpulse; + int nMinSplashSize; + int nMaxSplashSize; + + int nFlags; + + // Values for player/NPC damage and carrying capability + // If the integers are set, they override the CVars + int pPlrDmg; // CVar for player damage amount + int pNPCDmg; // CVar for NPC damage amount + int pMaxCarry; // CVar for maximum number can carry + const ConVar* pPlrDmgCVar; // CVar for player damage amount + const ConVar* pNPCDmgCVar; // CVar for NPC damage amount + const ConVar* pMaxCarryCVar; // CVar for maximum number can carry +}; +*/ + + +/** + * A simple wrapper for C++ ConVar pointers, with hardcoded offsets into the structure that probably never gonna change. + */ +methodmap ConVarPtrWrapper { + /** + * @brief Constructor accepting a C++ pointer (address). + * + * @param p Pointer (address) of ConVar. + */ + public ConVarPtrWrapper(Address p) { + return view_as(p); + } + + /** + * @brief Retrieves an integer value for the convar. + */ + public int GetInt() { + return this.m_pParent.m_nValue; + } + + /** + * @brief Retrieves a float value for the convar. + */ + public float GetFloat() { + return this.m_pParent.m_fValue; + } + + /** + * @brief Retrieves the SourceMod Handle for the convar. + * + * @return SourceMod ConVar handle. + */ + public ConVar GetSMHandle() { + char name[MAX_NAME_LENGTH]; + L4D_ReadMemoryString(this.m_pszName, name, sizeof(name)); + return FindConVar(name); + } + + /** + * @brief Retrieves the C string pointer for the convar. + */ + property Address m_pszName { + public get() { return LoadFromAddress(view_as
(this) + view_as
(12), NumberType_Int32); } + } + + /** + * @brief Retrieves the parent convar. + * @remarks This either points to "this" or it points to the original declaration of a ConVar. + * @remarks This allows ConVars to exist in separate modules, and they all use the first one to be declared. + * @remarks m_pParent->m_pParent must equal m_pParent (ie: m_pParent must be the root, or original, ConVar). + */ + property ConVarPtrWrapper m_pParent { + public get() { return LoadFromAddress(view_as
(this) + view_as
(28), NumberType_Int32); } + } + + /** + * @brief DO NOT USE THIS PROPERTY. USE "GetFloat" INSTEAD. Retrieves the float value stored in this convar struct. + */ + property float m_fValue { + public get() { return LoadFromAddress(view_as
(this) + view_as
(44), NumberType_Int32); } + } + + /** + * @brief DO NOT USE THIS PROPERTY. USE "GetInt" INSTEAD. Retrieves the integer value stored in this convar struct. + */ + property int m_nValue { + public get() { return LoadFromAddress(view_as
(this) + view_as
(48), NumberType_Int32); } + } +} + +// Used to tell AmmoDef to use the cvars, not the integers +#define USE_CVAR -1 +// Ammo is infinite +#define INFINITE_AMMO -2 + +methodmap Ammo_t +{ + public native void GetName(char[] buffer, int maxlength); + + property int nDamageType { + public native get(); + public native set(int nDamageType); + } + + property int eTracerType { + public native get(); + public native set(int eTracerType); + } + + property float physicsForceImpulse { + public native get(); + public native set(float physicsForceImpulse); + } + + property int nMinSplashSize { + public native get(); + public native set(int nMinSplashSize); + } + + property int nMaxSplashSize { + public native get(); + public native set(int nMaxSplashSize); + } + + property int nFlags { + public native get(); + public native set(int nFlags); + } + + // Values for player/NPC damage and carrying capability + // If the integers are set, they override the CVars + property int pPlrDmg { // CVar for player damage amount + public native get(); + public native set(int pPlrDmg); + } + + property int pNPCDmg { // CVar for NPC damage amount + public native get(); + public native set(int pNPCDmg); + } + + property int pMaxCarry { // CVar for maximum number can carry + public native get(); + public native set(int pMaxCarry); + } + + property ConVarPtrWrapper pPlrDmgCVar { // CVar for player damage amount + public native get(); + } + + property ConVarPtrWrapper pNPCDmgCVar { // CVar for NPC damage amount + public native get(); + } + + property ConVarPtrWrapper pMaxCarryCVar { // CVar for maximum number can carry + public native get(); + } +} + +enum AmmoTracer_t +{ + TRACER_NONE, + TRACER_LINE, + TRACER_RAIL, + TRACER_BEAM, + TRACER_LINE_AND_WHIZ, +}; + +enum AmmoFlags_t +{ + AMMO_FORCE_DROP_IF_CARRIED = 0x1, + AMMO_INTERPRET_PLRDAMAGE_AS_DAMAGE_TO_PLAYER = 0x2, +}; + +methodmap AmmoDef +{ + /** + * @brief Retrieves the ammo index (m_nAmmoIndex). + * @remarks Start with an index of 1. Subtract by 1 to get the number of total ammo types. + * + * @return Current top ammo index. + */ + public static native int GetAmmoIndex(); + + /** + * @brief Returns a pointer to the Ammo at the Index passed in. + * + * @param nAmmoIndex Ammo index. + * @return Ammo_t methodmap. + */ + public static native Ammo_t GetAmmoOfIndex(int nAmmoIndex); + + /** + * @brief Returns an index for the ammo name. + * + * @param psz Ammo name. + * @return An ammo index if found, -1 otherwise. + */ + public static native int Index(const char[] psz); + + /** + * @brief Retrieves the maximum ammo that a player can carry. + * + * @param nAmmoIndex Ammo index. + * @return Ammo count. + */ + public static native int MaxCarry(int nAmmoIndex); + + public static native int PlrDamage(int nAmmoIndex); + public static native int NPCDamage(int nAmmoIndex); + public static native int DamageType(int nAmmoIndex); + public static native int Flags(int nAmmoIndex); + public static native int MinSplashSize(int nAmmoIndex); + public static native int MaxSplashSize(int nAmmoIndex); + public static native int TracerType(int nAmmoIndex); + public static native float DamageForce(int nAmmoIndex); +} + @@ -690,7 +1222,7 @@ typeset AnimHookCallback * @param client Client triggering * @param sequence The animation "activity" (pre-hook) or "m_nSequence" (post-hook) sequence number being used * - * @return Plugin_Changed to change animation, Plugin_Continue otherwise + * @return Plugin_Changed to change the animation sequence, Plugin_Continue otherwise */ function Action(int client, int &sequence); } @@ -1671,6 +2203,44 @@ forward Action L4D_TankRock_OnRelease(int tank, int rock, float vecPos[3], float */ forward void L4D_TankRock_OnRelease_Post(int tank, int rock, const float vecPos[3], const float vecAng[3], const float vecVel[3], const float vecRot[3]); +/** + * @brief Called whenever CTankRock::BounceTouch is invoked + * @remarks When a tank rock touches an entity to bounce + * + * @param tank tank client index (can be -1 if the rock was created by the native "L4D_TankRockPrj" or the "env_rock_launcher" entity) + * @param rock the rock entity index + * @param entity the entity index it touched (can be 0 for world) + * + * @return Plugin_Handled to prevent exploding/hitting(?) - this will cause the rock to float in position and call L4D_TankRock_BounceTouch over and over, manually teleport to bounce off an object, Plugin_Continue otherwise + */ +forward Action L4D_TankRock_BounceTouch(int tank, int rock, int entity); + +/** + * @brief Called whenever CTankRock::BounceTouch is invoked + * @remarks When a tank rock touches an entity to bounce + * @remarks This forward will not trigger if the relative pre-hook forward has been blocked with Plugin_Handled + * + * @param tank tank client index (can be -1 if the rock was created by the native "L4D_TankRockPrj" or the "env_rock_launcher" entity) + * @param rock the rock entity index + * @param entity the entity index it touched (can be 0 for world) + * + * @noreturn + */ +forward void L4D_TankRock_BounceTouch_Post(int tank, int rock, int entity); + +/** + * @brief Called whenever CTankRock::BounceTouch is invoked + * @remarks When a tank rock touches an entity to bounce + * @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled + * + * @param tank tank client index (can be -1 if the rock was created by the native "L4D_TankRockPrj" or the "env_rock_launcher" entity) + * @param rock the rock entity index + * @param entity the entity index it touched (can be 0 for world) + * + * @noreturn + */ +forward void L4D_TankRock_BounceTouch_PostHandled(int tank, int rock, int entity); + /** * @brief Called whenever CDirector::TryOfferingTankBot is invoked * @remarks Is used for displaying the "X gets Tank" window and transferring Tank control @@ -1923,6 +2493,8 @@ forward void L4D2_OnChangeFinaleStage_PostHandled(int finaleType, const char[] a * @remarks Not sure what bool does exactly yet. Just monitor it. If true, survivors will be counted for multiplier. If false, survival multiplier will be set to 0 * @remarks A lot of Score calculations happen on this function, and the round-end scoreboard comes up doing this. Don't block unless you're sure you can reproduce this logic * + * @param countSurvivors False = Survivors didn't make it to saferoom. True = Survivors made to the saferoom + * * @return Plugin_Handled to block, Plugin_Continue otherwise */ forward Action L4D2_OnEndVersusModeRound(bool countSurvivors); @@ -1947,6 +2519,7 @@ forward void L4D2_OnEndVersusModeRound_Post(); */ forward void L4D2_OnEndVersusModeRound_PostHandled(); + /** * @brief Called whenever CTerrorPlayer::OnLedgeGrabbed(CTerrorPlayer *this, const Vector *) is invoked * @remarks Called when a player is about to grab a ledge @@ -2205,14 +2778,12 @@ forward void L4D2_OnPlayerFling_PostHandled(int client, int attacker, const floa * @brief Called when CTerrorPlayer::IsMotionControlledXY is invoked * @remarks Called when a player is staggering or a Hunter has been knocked off someone * @remarks Blocking this will allow the player to fall with gravity instead of floating in the air - * @remarks Pre-public release: various bugs surrounding this method. To be addressed later * * @param client Client index of the player - * @param activity The activity sequence playing that has overridden gravity + * @param activity The activity sequence playing that has a fixed set of motions * * @return Plugin_Handled to block, Plugin_Continue otherwise **/ -#pragma deprecated This is for private testing and not released for public usage yet forward Action L4D_OnMotionControlledXY(int client, int activity); /** @@ -2251,7 +2822,7 @@ forward void L4D2_OnPounceOrLeapStumble_PostHandled(int victim, int attacker); * @brief Called when CTerrorPlayer::OnKnockedDown(CTerrorPlayer*) is invoked * @remarks Called when someone is about to be hit by a Tank rock or lunged by a Hunter * @remarks You can use the "KNOCKDOWN_*" enum values for the reason - * @remarks Called multiple times when someone is about to be has been pounced by a Hunter + * @remarks Called multiple times when someone is about to be pounced by a Hunter * * @param victim Client index of the victim * @param reason The Knockdown reason type. 1=Hunter lunge, 2=Tank rock, 3=Charger impact @@ -2263,12 +2834,12 @@ forward Action L4D_OnKnockedDown(int client, int reason); /** * @brief Called when CTerrorPlayer::OnKnockedDown(CTerrorPlayer*) is invoked * @remarks Called when someone is about to be hit by a Tank rock or lunged by a Hunter - * @remarks Called multiple times when someone is about to be has been pounced by a Hunter + * @remarks Called multiple times when someone is about to be pounced by a Hunter * @remarks You can use the "KNOCKDOWN_*" enum values for the reason * @remarks This forward will not trigger if the relative pre-hook forward has been blocked with Plugin_Handled * * @param victim Client index of the victim - * @param reason The Knockdown reason type. 1=Hunter lunge, 2=Tank rock + * @param reason The Knockdown reason type. 1=Hunter lunge, 2=Tank rock, 3=Charger impact * * @noreturn **/ @@ -2277,12 +2848,12 @@ forward void L4D_OnKnockedDown_Post(int client, int reason); /** * @brief Called when CTerrorPlayer::OnKnockedDown(CTerrorPlayer*) is invoked * @remarks Called when someone is about to be hit by a Tank rock or lunged by a Hunter - * @remarks Called multiple times when someone is about to be has been pounced by a Hunter + * @remarks Called multiple times when someone is about to be pounced by a Hunter * @remarks You can use the "KNOCKDOWN_*" enum values for the reason * @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled * * @param victim Client index of the victim - * @param reason The Knockdown reason type. 1=Hunter lunge, 2=Tank rock + * @param reason The Knockdown reason type. 1=Hunter lunge, 2=Tank rock, 3=Charger impact * * @noreturn **/ @@ -2382,6 +2953,68 @@ forward void L4D_OnPlayerCough_Post(int client, int attacker); **/ forward void L4D_OnPlayerCough_PostHandled(int client, int attacker); +/** + * @brief Called when CTerrorPlayer::OnIncapacitatedAsSurvivor() is invoked + * @remarks Called when a player is about to be incapacitated + * + * @param client Client index of the player affected + * @param inflictor The inflictor entity index + * @param attacker The attacker entity index + * @param damage Amount of damage being caused + * @param damagetype Type of damage being caused + * + * @return return Plugin_Handled to block, Plugin_Changed to modify values, Plugin_Continue otherwise + **/ +forward Action L4D_OnIncapacitated(int client, int &inflictor, int &attacker, float &damage, int &damagetype); + +/** + * @brief Called when CTerrorPlayer::OnIncapacitatedAsSurvivor() is invoked + * @remarks Called when a player is about to be incapacitated + * @remarks This forward will not trigger if the relative pre-hook forward has been blocked with Plugin_Handled + * + * @param client Client index of the player affected + * @param inflictor The inflictor entity index + * @param attacker The attacker entity index + * @param damage Amount of damage being caused + * @param damagetype Type of damage being caused + * + * @noreturn + **/ +forward void L4D_OnIncapacitated_Post(int client, int inflictor, int attacker, float damage, int damagetype); + +/** + * @brief Called when CTerrorPlayer::OnIncapacitatedAsSurvivor() is invoked + * @remarks Called when a player is about to be incapacitated + * @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled + * + * @param client Client index of the player affected + * @param inflictor The inflictor entity index + * @param attacker The attacker entity index + * @param damage Amount of damage being caused + * @param damagetype Type of damage being caused + * + * @noreturn + **/ +forward void L4D_OnIncapacitated_PostHandled(int client, int inflictor, int attacker, float damage, int damagetype); + +/** + * @brief Called when CTerrorPlayer::DropWeapons() is invoked + * @remarks Called when a player dies, listing their currently held weapons and objects that are being dropped + * @remarks Array index is as follows: + * @remarks [0] = L4DWeaponSlot_Primary + * @remarks [1] = L4DWeaponSlot_Secondary + * @remarks [2] = L4DWeaponSlot_Grenade + * @remarks [3] = L4DWeaponSlot_FirstAid + * @remarks [4] = L4DWeaponSlot_Pills + * @remarks [5] = Held item (e.g. weapon_gascan, weapon_gnome etc) + * + * @param client Client index of the player who died + * @param weapons Array of weapons dropped, valid entity index or -1 if empty + * + * @noreturn + **/ +forward void L4D_OnDeathDroppedWeapons(int client, int weapons[6]); + /** * @brief Called whenever CInferno::Spread(Vector const&) is invoked (only for spitters -- ignores fire) * @@ -2430,6 +3063,21 @@ forward Action L4D2_OnUseHealingItems(int client); */ forward Action L4D2_OnFindScavengeItem(int client, int &item); +/** + * @brief Called whenever BossZombiePlayer(CTerrorPlayer *, int, CBaseEntity *) is invoked + * @remarks Called when Special Infected are targeting a victim + * + * @param specialInfected the SI entity index + * @param lastTarget the last targeted chosen victim + * + * @return Plugin_Handled to block, Plugin_Changed to use overwritten values from plugin, Plugin_Continue otherwise + */ +// FOr a future update: +// * @param targetScanFlags targeting flags (unknown) +// * @param ignoreTarget entity to ignore targeting +// forward Action L4D2_OnChooseVictim_Pre(int specialInfected, int &lastTarget, int &targetScanFlags, int &ignoreTarget); // For a future update +forward Action L4D2_OnChooseVictim_Pre(int specialInfected, int &lastTarget); + /** * @brief Called whenever BossZombiePlayer(CTerrorPlayer *, int, CBaseEntity *) is invoked * @remarks Called when Special Infected are targeting a victim @@ -2759,6 +3407,41 @@ forward void L4D2_OnHitByVomitJar_Post(int victim, int attacker); */ forward void L4D2_OnHitByVomitJar_PostHandled(int victim, int attacker); +/** + * @brief Called whenever Infected::OnHitByVomitJar is invoked + * @remarks Called when a common infected or Witch is about to be hit from a Bilejar explosion and possibly boomer explosion + * + * @param victim the common who's now it + * @param attacker the attacker who caused the vomit (can be 0) + * + * @return Plugin_Handled to block, Plugin_Changed to use overwritten values from plugin, Plugin_Continue otherwise + */ +forward Action L4D2_Infected_HitByVomitJar(int victim, int &attacker); + +/** + * @brief Called whenever Infected::OnHitByVomitJar is invoked + * @remarks Called when a common infected or Witch is hit from a Bilejar explosion and possibly boomer explosion + * @remarks This forward will not trigger if the relative pre-hook forward has been blocked with Plugin_Handled + * + * @param victim the common who's now it + * @param attacker the attacker who caused the vomit (can be 0) + * + * @noreturn + */ +forward void L4D2_Infected_HitByVomitJar_Post(int victim, int attacker); + +/** + * @brief Called whenever Infected::OnHitByVomitJar is invoked + * @remarks Called when a common infected or Witch is hit from a Bilejar explosion and possibly boomer explosion + * @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled + * + * @param victim the common who's now it + * @param attacker the attacker who caused the vomit (can be 0) + * + * @noreturn + */ +forward void L4D2_Infected_HitByVomitJar_PostHandled(int victim, int attacker); + /** * @brief Called whenever CPipeBombProjectile::Create is invoked * @remarks Called when a PipeBomb projectile is being created @@ -2791,7 +3474,7 @@ forward void L4D_PipeBombProjectile_Post(int client, int projectile, const float /** * @brief Called whenever CPipeBombProjectile::Create is invoked - * @remarks Called when a PipeBomb projectile has been created + * @remarks Called when a PipeBomb projectile has been blocked * @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled * * @param client the client who is throwing the grenade (can be -1 if blocked) @@ -2805,6 +3488,150 @@ forward void L4D_PipeBombProjectile_Post(int client, int projectile, const float */ forward void L4D_PipeBombProjectile_PostHandled(int client, int projectile, const float vecPos[3], const float vecAng[3], const float vecVel[3], const float vecRot[3]); +/** + * @brief Called whenever CMolotovProjectile::Create is invoked + * @remarks Called when a Molotov projectile is being created + * + * @param client the client who is throwing the grenade (can be 0) + * @param vecPos the position vector of the projectile + * @param vecAng the angle vector of the projectile + * @param vecVel the velocity vector of the projectile + * @param vecRot the rotation vector of the projectile + * + * @return Plugin_Handled to block the grenade creation, Plugin_Changed to modify the vector values, Plugin_Continue otherwise + */ +forward Action L4D_MolotovProjectile_Pre(int client, float vecPos[3], float vecAng[3], float vecVel[3], float vecRot[3]); + +/** + * @brief Called whenever CMolotovProjectile::Create is invoked + * @remarks Called when a Molotov projectile has been created + * @remarks This forward will not trigger if the relative pre-hook forward has been blocked with Plugin_Handled + * + * @param client the client who is throwing the grenade + * @param projectile the projectile entity index (can be 0 if blocked in the pre hook) + * @param vecPos the position vector of the projectile + * @param vecAng the angle vector of the projectile + * @param vecVel the velocity vector of the projectile + * @param vecRot the rotation vector of the projectile + * + * @noreturn + */ +forward void L4D_MolotovProjectile_Post(int client, int projectile, const float vecPos[3], const float vecAng[3], const float vecVel[3], const float vecRot[3]); + +/** + * @brief Called whenever CMolotovProjectile::Create is invoked + * @remarks Called when a Molotov projectile has been blocked + * @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled + * + * @param client the client who is throwing the grenade (can be -1 if blocked) + * @param projectile the projectile entity index (can be 0 if blocked in the pre hook) + * @param vecPos the position vector of the projectile + * @param vecAng the angle vector of the projectile + * @param vecVel the velocity vector of the projectile + * @param vecRot the rotation vector of the projectile + * + * @noreturn + */ +forward void L4D_MolotovProjectile_PostHandled(int client, int projectile, const float vecPos[3], const float vecAng[3], const float vecVel[3], const float vecRot[3]); + +/** + * @brief Called whenever CVomitJarProjectile::Create is invoked + * @remarks Called when a VomitJar projectile is being created + * + * @param client the client who is throwing the grenade (can be 0) + * @param vecPos the position vector of the projectile + * @param vecAng the angle vector of the projectile + * @param vecVel the velocity vector of the projectile + * @param vecRot the rotation vector of the projectile + * + * @return Plugin_Handled to block the grenade creation, Plugin_Changed to modify the vector values, Plugin_Continue otherwise + */ +// L4D2 only +forward Action L4D2_VomitJarProjectile_Pre(int client, float vecPos[3], float vecAng[3], float vecVel[3], float vecRot[3]); + +/** + * @brief Called whenever CVomitJarProjectile::Create is invoked + * @remarks Called when a VomitJar projectile has been created + * @remarks This forward will not trigger if the relative pre-hook forward has been blocked with Plugin_Handled + * + * @param client the client who is throwing the grenade + * @param projectile the projectile entity index (can be 0 if blocked in the pre hook) + * @param vecPos the position vector of the projectile + * @param vecAng the angle vector of the projectile + * @param vecVel the velocity vector of the projectile + * @param vecRot the rotation vector of the projectile + * + * @noreturn + */ +// L4D2 only +forward void L4D2_VomitJarProjectile_Post(int client, int projectile, const float vecPos[3], const float vecAng[3], const float vecVel[3], const float vecRot[3]); + +/** + * @brief Called whenever CVomitJarProjectile::Create is invoked + * @remarks Called when a VomitJar projectile has been blocked + * @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled + * + * @param client the client who is throwing the grenade (can be -1 if blocked) + * @param projectile the projectile entity index (can be 0 if blocked in the pre hook) + * @param vecPos the position vector of the projectile + * @param vecAng the angle vector of the projectile + * @param vecVel the velocity vector of the projectile + * @param vecRot the rotation vector of the projectile + * + * @noreturn + */ +// L4D2 only +forward void L4D2_VomitJarProjectile_PostHandled(int client, int projectile, const float vecPos[3], const float vecAng[3], const float vecVel[3], const float vecRot[3]); + +/** + * @brief Called whenever CGrenadeLauncher_Projectile::Create is invoked + * @remarks Called when a Grenade Launcher projectile is being created + * + * @param client the client who is shooting the grenade launcher projectile (can be 0) + * @param vecPos the position vector of the projectile + * @param vecAng the angle vector of the projectile + * @param vecVel the velocity vector of the projectile + * @param vecRot the rotation vector of the projectile + * + * @return Plugin_Handled to block the grenade creation, Plugin_Changed to modify the vector values and incendiary flag, Plugin_Continue otherwise + */ +// L4D2 only +forward Action L4D2_GrenadeLauncherProjectile_Pre(int client, float vecPos[3], float vecAng[3], float vecVel[3], float vecRot[3], bool &bIncendiary); + +/** + * @brief Called whenever CGrenadeLauncher_Projectile::Create is invoked + * @remarks Called when a Grenade Launcher projectile has been created + * @remarks This forward will not trigger if the relative pre-hook forward has been blocked with Plugin_Handled + * + * @param client the client who is shooting the grenade launcher projectile + * @param projectile the projectile entity index (can be 0 if blocked in the pre hook) + * @param vecPos the position vector of the projectile + * @param vecAng the angle vector of the projectile + * @param vecVel the velocity vector of the projectile + * @param vecRot the rotation vector of the projectile + * + * @noreturn + */ +// L4D2 only +forward void L4D2_GrenadeLauncherProjectile_Post(int client, int projectile, const float vecPos[3], const float vecAng[3], const float vecVel[3], const float vecRot[3], bool bIncendiary); + +/** + * @brief Called whenever CGrenadeLauncher_Projectile::Create is invoked + * @remarks Called when a Grenade Launcher projectile has been blocked + * @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled + * + * @param client the client who is shooting the grenade launcher projectile (can be -1 if blocked) + * @param projectile the projectile entity index (can be 0 if blocked in the pre hook) + * @param vecPos the position vector of the projectile + * @param vecAng the angle vector of the projectile + * @param vecVel the velocity vector of the projectile + * @param vecRot the rotation vector of the projectile + * + * @noreturn + */ +// L4D2 only +forward void L4D2_GrenadeLauncherProjectile_PostHandled(int client, int projectile, const float vecPos[3], const float vecAng[3], const float vecVel[3], const float vecRot[3], bool bIncendiary); + /** * @brief Called whenever CMolotovProjectile::Detonate is invoked * @remarks Called when a Molotov projectile is about to explode @@ -2913,6 +3740,44 @@ forward void L4D2_VomitJar_Detonate_Post(int entity, int client); // L4D2 only forward void L4D2_VomitJar_Detonate_PostHandled(int entity, int client); +/** + * @brief Called whenever CGrenadeLauncher_Projectile::Explode is invoked + * @remarks Called when a Grenade Launcher projectile is about to explode + * + * @param entity the entity that exploded + * @param client the client who shot the grenade, can be -1 + * + * @return Plugin_Handled to block explosion which will cause the Grenade Launcher projectile to bounce and remain active, Plugin_Continue otherwise + */ +// L4D2 only +forward Action L4D2_GrenadeLauncher_Detonate(int entity, int client); + +/** + * @brief Called whenever CGrenadeLauncher_Projectile::Explode is invoked + * @remarks Called when a Grenade Launcher projectile is about to explode + * @remarks This forward will not trigger if the relative pre-hook forward has been blocked with Plugin_Handled + * + * @param entity the entity that exploded + * @param client the client who shot the grenade, can be -1 + * + * @noreturn + */ +// L4D2 only +forward void L4D2_GrenadeLauncher_Detonate_Post(int entity, int client); + +/** + * @brief Called whenever CGrenadeLauncher_Projectile::Explode is invoked + * @remarks Called when a Grenade Launcher projectile is about to explode + * @remarks This forward will ONLY trigger if the relative pre-hook forward has been blocked with Plugin_Handled + * + * @param entity the entity that exploded + * @param client the client who shot the grenade, can be -1 + * + * @noreturn + */ +// L4D2 only +forward void L4D2_GrenadeLauncher_Detonate_PostHandled(int entity, int client); + /** * @brief Called whenever CInsectSwarm::CanHarm() is invoked * @remarks Called when Spitter Acid is determining if a client or entity can be damaged @@ -2969,8 +3834,10 @@ forward void L4D_CBreakableProp_Break(int prop, int entity); /** * @brief Called whenever CFirstAidKit::StartHealing() is invoked * @remarks Called when a player is using a first aid kit to heal - * @note: Detouring as a pre-hook for changing "first_aid_heal_percent" per player before healing finishes. - * @note: Detouring as a post-hook for changing "first_aid_heal_percent" back to default value after healing finishes. + * @note: Detouring as a pre-hook for changing "first_aid_heal_percent" per player before healing finishes + * @note: Detouring as a post-hook for changing "first_aid_heal_percent" back to default value after healing finishes + * @note: This does not change the animation speed + * @note: To find the use entity that is being targeted, use the native: "L4D_FindUseEntity" * * @param client the client performing the action * @param entity the medkit entity they are using @@ -2983,8 +3850,10 @@ forward Action L4D1_FirstAidKit_StartHealing(int client, int entity); /** * @brief Called whenever CFirstAidKit::StartHealing() is invoked * @remarks Called when a player is using a first aid kit to heal - * @note: Detouring as a pre-hook for changing "first_aid_heal_percent" per player before healing finishes. - * @note: Detouring as a post-hook for changing "first_aid_heal_percent" back to default value after healing finishes. + * @note: Detouring as a pre-hook for changing "first_aid_heal_percent" per player before healing finishes + * @note: Detouring as a post-hook for changing "first_aid_heal_percent" back to default value after healing finishes + * @note: This does not change the animation speed + * @note: To find the use entity that is being targeted, use the native: "L4D_FindUseEntity" * * @param client the client performing the action * @param entity the medkit entity they are using @@ -2997,8 +3866,10 @@ forward void L4D1_FirstAidKit_StartHealing_Post(int client, int entity); /** * @brief Called whenever CFirstAidKit::StartHealing() is invoked * @remarks Called when a player is using a first aid kit to heal - * @note: Detouring as a pre-hook for changing "first_aid_heal_percent" per player before healing finishes. - * @note: Detouring as a post-hook for changing "first_aid_heal_percent" back to default value after healing finishes. + * @note: Detouring as a pre-hook for changing "first_aid_heal_percent" per player before healing finishes + * @note: Detouring as a post-hook for changing "first_aid_heal_percent" back to default value after healing finishes + * @note: This does not change the animation speed + * @note: To find the use entity that is being targeted, use the native: "L4D_FindUseEntity" * * @param client the client performing the action * @param entity the medkit entity they are using @@ -3009,8 +3880,9 @@ forward void L4D1_FirstAidKit_StartHealing_Post(int client, int entity); forward void L4D1_FirstAidKit_StartHealing_PostHandled(int client, int entity); /** - * @brief Called whenever sourcemodCBaseBackpackItem::StartAction() is invoked - * @remarks Called when a player is using an item and about to use it + * @brief Called whenever CBaseBackpackItem::StartAction() is invoked + * @remarks Called when a player is holding an item and about to use it + * @note: This does not change the animation speed * @note: Detouring as a pre-hook for changing the following per player before starting any actions: * - "first_aid_kit_use_duration" * - "ammo_pack_use_duration" @@ -3018,19 +3890,22 @@ forward void L4D1_FirstAidKit_StartHealing_PostHandled(int client, int entity); * - "defibrillator_use_duration" * - "gas_can_use_duration" * - "upgrade_pack_use_duration" - * @note: Detouring as a post-hook for changing the above back to default values after starting any actions. + * @note: Detouring as a post-hook for changing the above back to default values after starting any actions + * @note: To find the use entity that is being targeted, use the native: "L4D_FindUseEntity" * * @param client the client performing the action * @param entity the medkit entity they are using + * @param type the weapon type ID. Can be found as L4D2WeaponId in the left4dhooks_stocks include file * * @return Plugin_Handled to block healing, Plugin_Continue otherwise */ // L4D2 only -forward Action L4D2_BackpackItem_StartAction(int client, int entity); +forward Action L4D2_BackpackItem_StartAction(int client, int entity, any type); /** - * @brief Called whenever sourcemodCBaseBackpackItem::StartAction() is invoked - * @remarks Called when a player is using an item and about to use it + * @brief Called whenever CBaseBackpackItem::StartAction() is invoked + * @remarks Called when a player is holding an item and about to use it + * @note: This does not change the animation speed * @note: Detouring as a pre-hook for changing the following per player before starting any actions: * - "first_aid_kit_use_duration" * - "ammo_pack_use_duration" @@ -3038,19 +3913,22 @@ forward Action L4D2_BackpackItem_StartAction(int client, int entity); * - "defibrillator_use_duration" * - "gas_can_use_duration" * - "upgrade_pack_use_duration" - * @note: Detouring as a post-hook for changing the above back to default values after starting any actions. + * @note: Detouring as a post-hook for changing the above back to default values after starting any actions + * @note: To find the use entity that is being targeted, use the native: "L4D_FindUseEntity" * * @param client the client performing the action * @param entity the medkit entity they are using + * @param type the weapon type ID. Can be found as L4D2WeaponId in the left4dhooks_stocks include file * * @noreturn */ // L4D2 only -forward void L4D2_BackpackItem_StartAction_Post(int client, int entity); +forward void L4D2_BackpackItem_StartAction_Post(int client, int entity, any type); /** - * @brief Called whenever sourcemodCBaseBackpackItem::StartAction() is invoked - * @remarks Called when a player is using an item and about to use it + * @brief Called whenever CBaseBackpackItem::StartAction() is invoked + * @remarks Called when a player is holding an item and about to use it + * @note: This does not change the animation speed * @note: Detouring as a pre-hook for changing the following per player before starting any actions: * - "first_aid_kit_use_duration" * - "ammo_pack_use_duration" @@ -3058,15 +3936,17 @@ forward void L4D2_BackpackItem_StartAction_Post(int client, int entity); * - "defibrillator_use_duration" * - "gas_can_use_duration" * - "upgrade_pack_use_duration" - * @note: Detouring as a post-hook for changing the above back to default values after starting any actions. + * @note: Detouring as a post-hook for changing the above back to default values after starting any actions + * @note: To find the use entity that is being targeted, use the native: "L4D_FindUseEntity" * * @param client the client performing the action * @param entity the medkit entity they are using + * @param type the weapon type ID. Can be found as L4D2WeaponId in the left4dhooks_stocks include file * * @noreturn */ // L4D2 only -forward void L4D2_BackpackItem_StartAction_PostHandled(int client, int entity); +forward void L4D2_BackpackItem_StartAction_PostHandled(int client, int entity, any type); /** * @brief Called whenever CGasCan::Event_Killed() is invoked @@ -3261,6 +4141,27 @@ forward Action L4D_OnGetRandomPZSpawnPosition(int &client, int &zombieClass, int // ==================================================================================================== // NATIVES - Silvers // ==================================================================================================== +/** + * @brief Precaches a particle effect + * + * @param sEffectName String of the particle name e.g. "fuse" or "fire_small_02" etc + * + * @noreturn + */ +native void L4D_PrecacheParticle(const char[] sEffectName); + +/** + * @brief Kills an entity of X seconds using the FireUser input/output + * @remarks This triggers OnUser1 and FireUser1 etc using the AcceptEntityInput method to "Kill" an entity + * + * @param entity The entity to kill + * @param time After how long to kill the entity + * @param user Which user input/output to use. Valid values 1-4 only. + * + * @noreturn + */ +native void L4D_RemoveEntityDelay(int entity, float time, int user = 4); + /** * @brief Returns the address pointer to various internal game objects * @@ -3291,12 +4192,22 @@ native int L4D_GetEntityFromAddress(Address addy); /** * @brief Returns a string read from a memory address * - * @param addy Address to check + * @param addy Address to read from * * @return Entity index or -1 on failure */ native int L4D_ReadMemoryString(Address addy, char[] buffer, int maxlength); +/** + * @brief Writes a string to a memory address + * + * @param addy Address to write to + * @param buffer String to write + * + * @noreturn + */ +native void L4D_WriteMemoryString(Address addy, const char[] buffer); + /** * @brief Returns the servers operating system * @@ -3322,6 +4233,13 @@ native int L4D_GetServerOS(); */ native int Left4DHooks_Version(); +/** + * @brief Checks if the map and addresses are loaded that some natives rely on + * + * @return True if the map has started and addresses are loaded, false otherwise + */ +native bool L4D_HasMapStarted(); + /** * @brief Returns an entities script scope (HSCRIPT) * @@ -3793,85 +4711,98 @@ native void L4D_DetonateProjectile(int entity); * @remarks It seems when using a Survivor for the client index and hitting another Survivor, the victim will take 1.0 damage (maybe due to friendly fire settings) * @remarks Suggest using an OnTakeDamage hook if you want to apply more damage * - * @param client Client id to attribute the projectile to for damage credit. Passing 0 (world) is allowed - * @param vecPos Vector coordinate of the projectile on creation - * @param vecAng Vector direction of the projectile + * @param client Client id to attribute the projectile to for damage credit. Passing 0 (world) is allowed + * @param vecPos Vector coordinate of the projectile on creation + * @param vecAng Vector direction of the projectile + * @param vecVel Vector velocity of the projectile * - * @return Entity index of the projectile + * @return Entity index of the projectile */ -native int L4D_TankRockPrj(int client, const float vecPos[3], const float vecAng[3]); +native int L4D_TankRockPrj(int client, const float vecPos[3], const float vecAng[3], const float vecVel[3] = NULL_VECTOR); /** * @brief Creates an activated PipeBomb projectile - * @remarks Does not attach the "Fuse" or "Light" particles, see the "left4dhooks_test" plugin for example on attaching these - * @remarks Also used in the "PipeBomb Shove" plugin by Silvers + * @remarks Example use in the "PipeBomb Shove" plugin by Silvers * - * @param client Client id to attribute the projectile to for damage credit. Passing 0 (world) is allowed - * @param vecPos Vector coordinate of the projectile on creation - * @param vecAng Vector velocity and direction of the projectile + * @param client Client id to attribute the projectile to for damage credit. Passing 0 (world) and -1 (null) is allowed + * @param vecPos Vector coordinate of the projectile on creation + * @param vecAng Vector direction of the projectile + * @param effects True = create fuse/light particles. False = don't create (default before 1.139 update) + * @param vecVel Vector velocity of the projectile + * @param vecRot Angular velocity impulse (rotation) of the projectile * - * @return Entity index of the projectile + * @return Entity index of the projectile */ -native int L4D_PipeBombPrj(int client, const float vecPos[3], const float vecAng[3]); +native int L4D_PipeBombPrj(int client, const float vecPos[3], const float vecAng[3], bool effects = false, const float vecVel[3] = NULL_VECTOR, const float vecRot[3] = NULL_VECTOR); /** * @brief Creates an activated Molotov projectile * - * @param client Client id to attribute the projectile to for damage credit Passing 0 (world) is allowed - * @param vecPos Vector coordinate of the projectile on creation - * @param vecAng Vector velocity and direction of the projectile + * @param client Client id to attribute the projectile to for damage credit Passing 0 (world) and -1 (null) is allowed + * @param vecPos Vector coordinate of the projectile on creation + * @param vecAng Vector velocity and direction of the projectile + * @param vecVel Vector velocity of the projectile + * @param vecRot Angular velocity impulse (rotation) of the projectile * - * @return Entity index of the projectile + * @return Entity index of the projectile */ -native int L4D_MolotovPrj(int client, const float vecPos[3], const float vecAng[3]); +native int L4D_MolotovPrj(int client, const float vecPos[3], const float vecAng[3], const float vecVel[3] = NULL_VECTOR, const float vecRot[3] = NULL_VECTOR); /** * @brief Creates an activated VomitJar projectile * - * @param client Client id to attribute the projectile to for damage credit Passing 0 (world) is allowed - * @param vecPos Vector coordinate of the projectile on creation - * @param vecAng Vector velocity and direction of the projectile + * @param client Client id to attribute the projectile to for damage credit Passing 0 (world) and -1 (null) is allowed + * @param vecPos Vector coordinate of the projectile on creation + * @param vecAng Vector velocity and direction of the projectile + * @param vecVel Vector velocity of the projectile + * @param vecRot Angular velocity impulse (rotation) of the projectile * - * @return Entity index of the projectile + * @return Entity index of the projectile */ // L4D2 Only -native int L4D2_VomitJarPrj(int client, const float vecPos[3], const float vecAng[3]); +native int L4D2_VomitJarPrj(int client, const float vecPos[3], const float vecAng[3], const float vecVel[3] = NULL_VECTOR, const float vecRot[3] = NULL_VECTOR); /** * @brief Creates an activated Grenade Launcher projectile * - * @param client Client id to attribute the projectile to for damage credit Passing 0 (world) is allowed - * @param vecPos Vector coordinate of the projectile on creation - * @param vecAng Vector velocity and direction of the projectile + * @param client Client id to attribute the projectile to for damage credit Passing 0 (world) and -1 (null) is allowed + * @param vecPos Vector coordinate of the projectile on creation + * @param vecAng Vector velocity and direction of the projectile + * @param vecVel Vector velocity of the projectile + * @param vecRot Angular velocity impulse (rotation) of the projectile + * @param bIncendiary Incendiary effect of the projectile (explosive ammo adds no effect) * - * @return Entity index of the projectile + * @return Entity index of the projectile */ // L4D2 Only -native int L4D2_GrenadeLauncherPrj(int client, const float vecPos[3], const float vecAng[3]); +native int L4D2_GrenadeLauncherPrj(int client, const float vecPos[3], const float vecAng[3], const float vecVel[3] = NULL_VECTOR, const float vecRot[3] = NULL_VECTOR, bool bIncendiary = false); /** * @brief Creates a Spitter goo projectile * - * @param client Client id to attribute the projectile to for damage credit Passing 0 (world) is allowed - * @param vecPos Vector coordinate of the projectile on creation - * @param vecAng Vector velocity and direction of the projectile + * @param client Client id to attribute the projectile to for damage credit Passing 0 (world) is allowed + * @param vecPos Vector coordinate of the projectile on creation + * @param vecAng Vector velocity and direction of the projectile + * @param vecVel Vector velocity of the projectile + * @param vecRot Angular velocity impulse (rotation) of the projectile * - * @return Entity index of the projectile + * @return Entity index of the projectile */ // L4D2 only -native int L4D2_SpitterPrj(int client, const float vecPos[3], const float vecAng[3]); +native int L4D2_SpitterPrj(int client, const float vecPos[3], const float vecAng[3], const float vecVel[3] = NULL_VECTOR, const float vecRot[3] = NULL_VECTOR); /** * @brief Gives the player adrenaline effect and health benefits * * @param client Client id to affect * @param fTime Duration of screen effects (game default: 15.0 - Cvar: "adrenaline_duration") - * @param heal True = give health benefits and fire "adrenaline_used" event. False = only screen effects + * @param heal True = give health benefits. False = only screen effects + * @param event True = fire the "adrenaline_used" event. False = no event triggered * * @return True on success, false otherwise */ // L4D2 only -native void L4D2_UseAdrenaline(int client, float fTime = 15.0, bool heal = true); +native void L4D2_UseAdrenaline(int client, float fTime = 15.0, bool heal = true, bool event = true); /** * @brief Respawns a player from dead state @@ -3964,6 +4895,23 @@ native any L4D2_GetCurrentFinaleStage(); // L4D2 only native void L4D2_ForceNextStage(); +/** + * @brief Returns the Survival setup countdown time before start (director_survival_setup_time must be non-0) + * @remarks Shows the time as 140/130/120 seconds, which is related to the chat messages shown as "SPAWNING STARTS IN 130 SECONDS" + * + * @return Seconds until start, or 0 if director_survival_setup_time is 0 + */ +// L4D2 only +native int L4D2_GetSurvivalStartTime(); + +/** + * @brief Sets the Survival countdown time before start + * + * @noreturn + */ +// L4D2 only +native void L4D2_SetSurvivalStartTime(int time); + /** * @brief Forces the game to start in Versus * @@ -4042,6 +4990,7 @@ native float L4D2_GetScriptValueFloat(const char[] key, float value); /** * @brief Returns if there is a configurable difficulty setting * @brief Returns true for Coop/Realism modes + * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid - Since version 1.133 Left4DHooks will block these calls and log an error * * @return True if there is a configurable difficulty setting, false otherwise **/ @@ -4051,7 +5000,7 @@ native bool L4D2_HasConfigurableDifficultySetting(); /** * @brief Returns the maps default Survivor set * @brief Does not return the overridden value when changed from the "L4D_OnGetSurvivorSet" or "L4D_OnFastGetSurvivorSet" forwards - * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid + * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid - Since version 1.133 Left4DHooks will block these calls and log an error * * @return Maps default survivor set **/ @@ -4069,6 +5018,7 @@ native int L4D2_GetSurvivorSetMod(); /** * @brief Returns if the current game mode is Coop/Realism mode + * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid - Since version 1.133 Left4DHooks will block these calls and log an error * * @return True if the current game mode is Coop/Realism mode, false otherwise **/ @@ -4084,10 +5034,11 @@ native bool L4D_IsCoopMode(); /** * @brief Returns if the current game mode is Realism mode + * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid - Since version 1.133 Left4DHooks will block these calls and log an error * * @return True if the current game mode is Realism mode, false otherwise - **/ // L4D2 only + **/ native bool L4D2_IsRealismMode(); /** @@ -4245,6 +5196,18 @@ native float L4D2_VScriptWrapper_NavAreaTravelDistance(const float startPos[3], // L4D2 only native int L4D_ScavengeBeginRoundSetupTime(); +/** + * @brief Spawns all Scavenge gascans in the map + * @remarks Requires the Director to be available--map must be started + * @remarks Enables to fix https://github.com/ValveSoftware/Source-1-Games/issues/1616 + * @remarks Spawns them even if they exist already + * + * @noreturn + */ +// L4D2 only +native void L4D2_SpawnAllScavengeItems(); + + /** * @brief Resets the natural mob (horde) timer * @remarks Requires the Director to be available--map must be started @@ -4290,8 +5253,7 @@ native int L4D_RestartScenarioFromVote(const char[] map); /** * @brief Gets the max versus completion score for the map - * @remarks Requires GameRules to be initialized--map must be loaded - * Seems to be updated before OnMapStart + * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid - Since version 1.133 Left4DHooks will block these calls and log an error * * @return The map's max completion distance (map distance score) */ @@ -4299,8 +5261,7 @@ native int L4D_GetVersusMaxCompletionScore(); /** * @brief Sets the max versus completion score for the map - * @remarks Requires GameRules to be initialized--map must be loaded - * Seems to be updated before OnMapStart and checked on round_start + * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid - Since version 1.133 Left4DHooks will block these calls and log an error * * @param score The versus max completion score to set for the round */ @@ -4333,9 +5294,11 @@ native bool L4D_IsFirstMapInScenario(); /** * @brief Tells if the Mission (map) is the final map of the campaign * + * @param anyMap True to return true if any map is a finale, not just the last map of a campaign (useful for campaigns that have multiple finale maps) + * * @return true if the map is the last map of the campaign (finale) */ -native bool L4D_IsMissionFinalMap(); +native bool L4D_IsMissionFinalMap(bool anyMap = false); /** * @brief Notifies the CGameRulesProxy that the game state has been changed @@ -4534,7 +5497,7 @@ native int L4D_GetCurrentChapter(); /** * @brief Returns the maximum number of chapters for the current game mode - * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid + * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid - Since version 1.133 Left4DHooks will block these calls and log an error * * @return Max chapters */ @@ -4542,7 +5505,7 @@ native int L4D_GetMaxChapters(); /** * @brief Returns all TheNavAreas addresses - * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid + * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid - Since version 1.133 Left4DHooks will block these calls and log an error * *param aList The ArrayList to store all nav area addresses * @@ -4552,7 +5515,7 @@ native void L4D_GetAllNavAreas(ArrayList aList); /** * @brief Returns a given NavArea's ID from it's address - * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid + * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid - Since version 1.133 Left4DHooks will block these calls and log an error * *param area The NavArea address * @@ -4562,7 +5525,7 @@ native int L4D_GetNavAreaID(Address area); /** * @brief Returns a given NavArea address from it's ID - * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid + * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid - Since version 1.133 Left4DHooks will block these calls and log an error * *param id The NavArea ID * @@ -4572,7 +5535,6 @@ native Address L4D_GetNavAreaByID(int id); /** * @brief Returns origin of a given NavArea - * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid * *param area The address of the NavArea to read *param vecPos The vector to store the position read @@ -4583,7 +5545,6 @@ native void L4D_GetNavAreaPos(Address area, float vecPos[3]); /** * @brief Returns center of a given NavArea - * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid * *param area The address of the NavArea to read *param vecPos The vector to store the center position @@ -4594,7 +5555,6 @@ native void L4D_GetNavAreaCenter(Address area, float vecPos[3]); /** * @brief Returns size of a given NavArea - * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid * *param area The address of the NavArea to read *param vecPos The vector to store the size read @@ -4605,7 +5565,6 @@ native void L4D_GetNavAreaSize(Address area, float vecSize[3]); /** * @brief Returns true if this area is connected to other area in given direction. (If you set direction to -1 or 4, it will automatically check all directions for a connection) - * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid * *param area1 The address of the first NavArea *param are2a The address of the second NavArea @@ -4618,7 +5577,6 @@ native bool L4D_NavArea_IsConnected(Address area1, Address area2, int direction) /** * @brief Returns the nav area attribute flags * @remarks See the "NAV_BASE_*" near the top of the include file - * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid * *param pTerrorNavArea Pointer to a NavArea * @@ -4629,7 +5587,6 @@ native int L4D_GetNavArea_AttributeFlags(Address pTerrorNavArea); /** * @brief Sets the nav area attribute flags * @remarks See the "NAV_BASE_*" near the top of the include file - * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid * *param pTerrorNavArea Pointer to a NavArea *param flags Attribute flags to set @@ -4641,7 +5598,6 @@ native void L4D_SetNavArea_AttributeFlags(Address pTerrorNavArea, int flags); /** * @brief Returns the terror nav area attribute flags * @remarks See the "NAV_SPAWN_*" near the top of the include file - * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid * *param pTerrorNavArea Pointer to a TerrorNavArea * @@ -4652,7 +5608,6 @@ native int L4D_GetNavArea_SpawnAttributes(Address pTerrorNavArea); /** * @brief Sets the terror nav area attribute flags * @remarks See the "NAV_SPAWN_*" near the top of the include file - * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid * *param pTerrorNavArea Pointer to a TerrorNavArea *param flags Attribute flags to set @@ -4746,7 +5701,8 @@ enum L4D2CountdownTimer L4D2CT_JockeySpawnTimer, L4D2CT_ChargerSpawnTimer, L4D2CT_VersusStartTimer, - L4D2CT_UpdateMarkersTimer + L4D2CT_UpdateMarkersTimer, + L4D2CT_SurvivalSetupTimer }; enum L4D2IntervalTimer @@ -4929,6 +5885,7 @@ enum L4D2IntWeaponAttributes L4D2IWA_Bucket, L4D2IWA_Tier, // L4D2 only L4D2IWA_DefaultSize, // Default weapon clip size + L4D2IWA_WeaponType, // Can use with the "WeaponType" enum MAX_SIZE_L4D2IntWeaponAttributes }; @@ -4952,7 +5909,7 @@ enum L4D2FloatWeaponAttributes L4D2FWA_PelletScatterPitch, L4D2FWA_PelletScatterYaw, L4D2FWA_VerticalPunch, - L4D2FWA_HorizontalPunch, // Requires "z_gun_horiz_punch" cvar changed to "1" + L4D2FWA_HorizontalPunch, // Requires "z_gun_horiz_punch" cvar changed to "1" - maybe not, read/write might work fine without L4D2FWA_GainRange, L4D2FWA_ReloadDuration, MAX_SIZE_L4D2FloatWeaponAttributes @@ -5013,7 +5970,7 @@ native bool L4D2_IsValidWeapon(const char[] weaponName); * * @return The value read */ -native int L4D2_GetIntWeaponAttribute(const char[] weaponName, L4D2IntWeaponAttributes attr); +native any L4D2_GetIntWeaponAttribute(const char[] weaponName, L4D2IntWeaponAttributes attr); /** * @brief Read a float-typed attribute for a given weapon from the WeaponInformationDatabase @@ -5054,7 +6011,7 @@ native void L4D2_SetFloatWeaponAttribute(const char[] weaponName, L4D2FloatWeapo /** * @brief Retrieve the index for a given melee weapon from the Melee Weapon Database - * @remarks Index updated on OnMapStart - suggest using RequestFrame to find index + * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid - Since version 1.133 Left4DHooks will block these calls and log an error * @remarks Index can change depending on available melee weapons each map * * @param weaponName Weapon to lookup index id for @@ -5647,7 +6604,7 @@ native float L4D2Direct_GetFlowDistance(int client); * * @noreturn */ -native void L4D2Direct_DoAnimationEvent(int client, int event, int variant_param = 0); +native void L4D2Direct_DoAnimationEvent(int client, any event, int variant_param = 0); /** * Get the clients health bonus @@ -5934,6 +6891,48 @@ native void L4D2_CTerrorPlayer_Fling(int client, int attacker, const float vecDi */ native void L4D_CancelStagger(int client); +/** + * @brief Finds the Use client/entity if available + * @remarks See the "L4D1_FirstAidKit_StartHealing" and "L4D2_BackpackItem_StartAction" pre hook forwards for examples of usage and games range values + * + * @param client Client ID of the person to check + * @param players True = only search for players, false = search for any use entity + * @param range Maximum distance to search for a usable entity + * + * @return Entity index or maybe 0 or -1 if none (not validated). May return an attached entity on the client (for example prop_dynamic) or other nearby entities + */ +native int L4D_FindUseEntity(int client, bool players = false, float range = 96.0); + +/** + * @brief Forces a Hunter to pin a victim + * + * @param victim Client index of the Survivor affect + * @param attacker Client index of the client attacking the Survivor + * + * @noreturn + */ +native void L4D_ForceHunterVictim(int victim, int attacker); + +/** + * @brief Forces a Smoker to grab a victim with their tongue + * + * @param victim Client index of the Survivor affect + * @param attacker Client index of the client attacking the Survivor + * + * @noreturn + */ +native void L4D_ForceSmokerVictim(int victim, int attacker); + +/** + * @brief Forces a Jockey to pin a victim + * + * @param victim Client index of the Survivor affect + * @param attacker Client index of the client attacking the Survivor + * + * @noreturn + */ +native void L4D2_ForceJockeyVictim(int victim, int attacker); + /** * @brief Flings a Survivor like when they're flung by a nearby Charger impact * @remarks attacker can be the same client index as victim @@ -5981,17 +6980,48 @@ native void L4D2_Charger_PummelVictim(int victim, int attacker); // L4D2 only native void L4D2_Charger_EndPummel(int victim, int attacker); +/** + * @brief Makes a Charger stop carrying a Survivor + * + * @param victim Client index of the Survivor to affect + * @param attacker Client index of the Charger + * + * @noreturn + */ +// L4D2 only +native void L4D2_Charger_EndCarry(int victim, int attacker); + /** * @brief Makes a Jockey stop riding a Survivor * * @param victim Client index of the Survivor to affect - * @param attacker Client index of the Jockey riding the Survivor + * @param attacker Client index of the Jockey * * @noreturn */ // L4D2 only native void L4D2_Jockey_EndRide(int victim, int attacker); +/** + * @brief Makes a Hunter end pounce on a Survivor + * + * @param victim Client index of the Survivor to affect + * @param attacker Client index of the Hunter + * + * @noreturn + */ +native void L4D_Hunter_ReleaseVictim(int victim, int attacker); + +/** + * @brief Makes a Smoker stop hanging a Survivor from it's tongue + * + * @param victim Client index of the Survivor to affect + * @param attacker Client index of the Smoker + * + * @noreturn + */ +native void L4D_Smoker_ReleaseVictim(int victim, int attacker); + /** * @brief Spawns all dead survivors in rescuable rooms * @remarks L4D1: Any survivor must not be in the starting area for it to work @@ -6013,6 +7043,7 @@ native void L4D_ReviveSurvivor(int client); /** * @brief Retrieve a clients map flow progress percentage. Doesn't have to be Versus mode + * @remarks Can only be called 1 frame after OnMapStart at the earliest otherwise the addresses are invalid - Since version 1.133 Left4DHooks will block these calls and log an error * * @param client Client ID of the person to affect * @@ -6133,10 +7164,19 @@ native void L4D2_SwapTeams(); * * @return 0=Not flipped. 1=Flipped */ -// L4D2 only #pragma deprecated Use this instead: GameRules_GetProp("m_bAreTeamsFlipped"); native bool L4D2_AreTeamsFlipped(); +/** + * @brief Ends a Versus round + * @remarks This will only end the first round, calculating scores and swapping players to the other team + * + * @param countSurvivors False = Survivors didn't make it to saferoom. True = Survivors made to the saferoom + * + * @noreturn + */ +native void L4D_EndVersusModeRound(bool countSurvivors); + /** * @brief Starts a Versus rematch vote like end of game before credits roll * @remarks Failing a successful vote players are kicked back to lobby @@ -6146,6 +7186,16 @@ native bool L4D2_AreTeamsFlipped(); // L4D2 only native void L4D2_StartRematchVote(); +/** + * @brief Passes a Versus rematch vote like end of game before credits roll + * @remarks A failed vote would have kicked players back to lobby + * @remarks Do not use this in conjunction with "L4D2_StartRematchVote" + * + * @noreturn + */ +// L4D2 only +native void L4D2_Rematch(); + /** * @brief Seems to restart the chapter like "mp_restartgame". In Versus the teams flip * diff --git a/scripting/include/left4dhooks_anim.inc b/scripting/include/left4dhooks_anim.inc index 776a509..15190af 100644 --- a/scripting/include/left4dhooks_anim.inc +++ b/scripting/include/left4dhooks_anim.inc @@ -1,6 +1,6 @@ /* * Left 4 DHooks Direct -* Copyright (C) 2023 Silvers +* Copyright (C) 2024 Silvers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +21,8 @@ #endif #define _l4d_anim_included +#pragma newdecls required + #include #include diff --git a/scripting/include/left4dhooks_lux_library.inc b/scripting/include/left4dhooks_lux_library.inc index 037ab5c..6e83841 100644 --- a/scripting/include/left4dhooks_lux_library.inc +++ b/scripting/include/left4dhooks_lux_library.inc @@ -1,5 +1,5 @@ /** -* Copyright (C) 2023 LuxLuma +* Copyright (C) 2024 LuxLuma * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +20,8 @@ #endif #define _lux_library_included +#pragma newdecls required + #include #include @@ -27,7 +29,7 @@ #tryinclude #tryinclude -#define LUX_LIBRARY_VERSION "0.5.7" +#define LUX_LIBRARY_VERSION "0.5.8" #define GIMMEDATA "lux_library" @@ -385,6 +387,9 @@ stock float Terror_GetAdrenalineTime(int iClient) timerAddress = FindSendPropInfo("CTerrorPlayer", "m_bAdrenalineActive") - 12; } + if(GetEntProp(iClient, Prop_Send, "m_bAdrenalineActive", 1) < 1) + return -1.0; + //timerAddress + 8 = TimeStamp float flGameTime = GetGameTime(); float flTime = GetEntDataFloat(iClient, timerAddress + 8); @@ -1431,10 +1436,10 @@ stock void EmitMixedAmbientSound(int client, const char[] sample, if(flDistMulti > 1.0) { - newPitch = FloatToInt(newPitch / (flDistMulti > 2.0 ? 2.0 : flDistMulti)); + newPitch = RoundToNearest(newPitch / (flDistMulti > 2.0 ? 2.0 : flDistMulti)); } - DistLevelBoost = FloatToInt((flDistPercent * exponent) * levelBoost); + DistLevelBoost = RoundToNearest((flDistPercent * exponent) * levelBoost); if(DistLevelBoost > levelBoost) DistLevelBoost = levelBoost; @@ -1515,21 +1520,16 @@ stock void EmitMixedAmbientSound_FallBack(int client, const char[] sample, newPitch = pitch; if(flDistMulti > 1.0) { - newPitch = FloatToInt(newPitch / (flDistMulti > 2.0 ? 2.0 : flDistMulti)); + newPitch = RoundToNearest(newPitch / (flDistMulti > 2.0 ? 2.0 : flDistMulti)); } - DistLevelBoost = FloatToInt((flDistPercent * exponent) * levelBoost); + DistLevelBoost = RoundToNearest((flDistPercent * exponent) * levelBoost); if(DistLevelBoost > levelBoost) DistLevelBoost = levelBoost; EmitSoundToClient(client, sample, entity, sndChannel, level + DistLevelBoost, _, _, newPitch, _, origin); } -int FloatToInt(float val) -{ - return RoundFloat(val); -} - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////Legacy Particle Stock/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/scripting/include/left4dhooks_silver.inc b/scripting/include/left4dhooks_silver.inc index 49a46ea..d341a64 100644 --- a/scripting/include/left4dhooks_silver.inc +++ b/scripting/include/left4dhooks_silver.inc @@ -1,6 +1,6 @@ /* * Left 4 DHooks Direct - Stock Functions -* Copyright (C) 2023 Silvers +* Copyright (C) 2024 Silvers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +21,8 @@ #endif #define _l4d_silver_included +#pragma newdecls required + #include #include @@ -949,6 +951,72 @@ stock void L4D_LedgeHangDisable(int client) * * @return Returns true if player is staggering, false otherwise */ +// Updated more accurate version thanks to "HarryPotter" for providing. +stock bool L4D_IsPlayerStaggering(int client) +{ + static int Activity = -1; + + if( L4D_IsEngineLeft4Dead2() ) + { + Activity = PlayerAnimState.FromPlayer(client).GetMainActivity(); + + switch( Activity ) + { + case L4D2_ACT_TERROR_SHOVED_FORWARD_MELEE, // 633, 634, 635, 636: stumble + L4D2_ACT_TERROR_SHOVED_BACKWARD_MELEE, + L4D2_ACT_TERROR_SHOVED_LEFTWARD_MELEE, + L4D2_ACT_TERROR_SHOVED_RIGHTWARD_MELEE: + return true; + } + } + else + { + Activity = L4D1_GetMainActivity(client); + + switch( Activity ) + { + case L4D1_ACT_TERROR_SHOVED_FORWARD, // 1145, 1146, 1147, 1148: stumble + L4D1_ACT_TERROR_SHOVED_BACKWARD, + L4D1_ACT_TERROR_SHOVED_LEFTWARD, + L4D1_ACT_TERROR_SHOVED_RIGHTWARD: + return true; + } + } + + static int m_iQueuedStaggerType = -1; + if( m_iQueuedStaggerType == -1 ) + m_iQueuedStaggerType = FindSendPropInfo("CTerrorPlayer", "m_staggerDist") + 4; + + if( GetEntData(client, m_iQueuedStaggerType, 4) == -1 ) + { + if( GetGameTime() >= GetEntPropFloat(client, Prop_Send, "m_staggerTimer", 1) ) + { + return false; + } + + static float vStgDist[3], vOrigin[3]; + GetEntPropVector(client, Prop_Send, "m_staggerStart", vStgDist); + GetEntPropVector(client, Prop_Send, "m_vecOrigin", vOrigin); + + static float fStgDist2; + fStgDist2 = GetEntPropFloat(client, Prop_Send, "m_staggerDist"); + + return GetVectorDistance(vStgDist, vOrigin) <= fStgDist2; + } + + return true; +} + +stock int L4D1_GetMainActivity(int client) +{ + static int s_iOffs_m_eCurrentMainSequenceActivity = -1; + if( s_iOffs_m_eCurrentMainSequenceActivity == -1 ) + s_iOffs_m_eCurrentMainSequenceActivity = FindSendPropInfo("CTerrorPlayer", "m_iProgressBarDuration") + 476; + + return LoadFromAddress(GetEntityAddress(client) + view_as
(s_iOffs_m_eCurrentMainSequenceActivity), NumberType_Int32); +} + +/* OLD VERSION (Before being updated by "HarryPotter") stock bool L4D_IsPlayerStaggering(int client) { static int m_iQueuedStaggerType = -1; @@ -974,6 +1042,7 @@ stock bool L4D_IsPlayerStaggering(int client) return true; } +*/ diff --git a/scripting/include/left4dhooks_stocks.inc b/scripting/include/left4dhooks_stocks.inc index 374c4f7..9acc0bf 100644 --- a/scripting/include/left4dhooks_stocks.inc +++ b/scripting/include/left4dhooks_stocks.inc @@ -1,7 +1,7 @@ /** * ============================================================================= * Left 4 Dead Stocks Library (C)2011-2012 Buster "Mr. Zero" Nielsen - * Syntax Update and merge into "Left 4 DHooks Direct" (C) 2023 "SilverShot" + * Syntax Update and merge into "Left 4 DHooks Direct" (C) 2024 "SilverShot" * ============================================================================= * * This program is free software; you can redistribute it and/or modify it @@ -32,6 +32,8 @@ #endif #define _l4d_stocks_included +#pragma newdecls required + #tryinclude #tryinclude #tryinclude @@ -665,7 +667,7 @@ stock int L4D_GetPendingTankPlayer() * @return True if glow was set, false if entity does not support glow. */ // L4D2 only. -stock bool L4D2_SetEntityGlow(int entity, L4D2GlowType type, int range, int minRange, colorOverride[3], bool flashing) +stock bool L4D2_SetEntityGlow(int entity, L4D2GlowType type, int range, int minRange, int colorOverride[3], bool flashing) { if (!IsValidEntity(entity)) { @@ -1321,6 +1323,30 @@ stock void L4D_SetPlayerTempHealth(int client, int tempHealth) SetEntPropFloat(client, Prop_Send, "m_healthBufferTime", GetGameTime()); } +/** + * Set players temporarily health. Allows for setting above 200 HP. + * + * @param client Client index. + * @param tempHealth Temporarily health. + * @noreturn + * @error Invalid client index. + */ +stock void L4D_SetPlayerTempHealthFloat(int client, float tempHealth) +{ + static ConVar painPillsDecayCvar; + if (painPillsDecayCvar == null) + { + painPillsDecayCvar = FindConVar("pain_pills_decay_rate"); + if (painPillsDecayCvar == null) + { + return; + } + } + + SetEntPropFloat(client, Prop_Send, "m_healthBuffer", tempHealth); + SetEntPropFloat(client, Prop_Send, "m_healthBufferTime", GetGameTime() + ((tempHealth - 200) / painPillsDecayCvar.FloatValue + 1 / painPillsDecayCvar.FloatValue)); +} + /** * Returns player use action. *