Great Tester of Whatever
|
02-18-2022
, 21:20
Re: [L4D2] Remove bile effect if Vomit jar out of map (NAV)
|
#6
|
The "Action" method is the most convenient and has 100% accuracy but requires to install Actions extension other methods will still work but not in all situations
Action
PHP Code:
#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <sdktools>
#include <left4dhooks>
#include <actions>
public void OnActionCreated( BehaviorAction action, int actor, const char[] name )
{
if ( strcmp(name, "InfectedAttack") == 0 )
{
action.OnUpdate = OnUpdate;
}
}
public Action OnUpdate( BehaviorAction action, float interval, ActionResult result )
{
BehaviorAction chaseVictim = action.Child;
/* ChaseVictim has property to set animation for waiving arms */
/* In other words this is isReachable property */
if ( chaseVictim == INVALID_ACTION || chaseVictim.Get(0x4844 /* 4850 - linux */, NumberType_Int8) == 1 )
return Plugin_Continue;
/* InfectedAttack stores victim handle at 0x34 */
int victim = action.Get(0x34) & 0xFFF;
if ( !IsValidEntity(victim) )
return Plugin_Continue;
char name[32];
GetEntityClassname(victim, name, sizeof name);
if ( strcmp(name, "info_goal_infected_chase") == 0 )
{
PrintToChatAll("Infected(%i) can't reach his target...", action.Actor);
RemoveEntity(victim);
victim = GetRandomSurvivor(1, -1);
if ( victim )
{
/* Go attack random survivor */
action.Set(0x34, GetEntityHandle(victim));
}
}
return Plugin_Continue;
}
stock int GetEntityHandle( int entity )
{
return EntIndexToEntRef(entity) & ~(1 << 31);
}
Navigation
PHP Code:
#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <sdktools>
#include <left4dhooks>
#include <actions>
Handle g_hGetNavArea;
public void OnPluginStart()
{
StartPrepSDKCall(SDKCall_Raw);
PrepSDKCall_SetSignature(SDKLibrary_Server, "\x55\x8B\xEC\x83\xEC\x18\x83\x79\x1C\x00", 10);
PrepSDKCall_AddParameter(SDKType_Vector, SDKPass_ByRef);
PrepSDKCall_AddParameter(SDKType_Float, SDKPass_Plain);
PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);
g_hGetNavArea = EndPrepSDKCall();
}
public void OnEntityCreated( int entity, const char[] name )
{
if ( strcmp(name, "info_goal_infected_chase") == 0 )
{
SDKHook(entity, SDKHook_SpawnPost, OnEntitySpawned);
}
}
public void OnEntitySpawned( int entity )
{
RequestFrame(NextFrame, EntIndexToEntRef(entity));
}
public void NextFrame( int entity )
{
if ( !entity || !IsValidEntity(entity) )
return;
entity = EntRefToEntIndex(entity);
float vOrigin[3];
GetEntPropVector(entity, Prop_Data, "m_vecOrigin", vOrigin);
Address area = GetNavArea(vOrigin, 25.0);
if ( area == Address_Null )
{
RemoveEntity(entity);
}
}
Address GetNavArea( const float vPos[3], float beneathLimit)
{
return SDKCall(g_hGetNavArea, L4D_GetPointer(POINTER_NAVMESH), vPos, beneathLimit);
}
Left 4 DHooks & VScript
PHP Code:
#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <sdktools>
#include <left4dhooks>
#include <sdkhooks>
int g_iGoalChase;
bool g_bChecked;
public void OnEntityCreated( int entity, const char[] name )
{
if ( strcmp(name, "info_goal_infected_chase") == 0 )
{
g_iGoalChase = EntIndexToEntRef(entity);
g_bChecked = false;
SDKHook(entity, SDKHook_SpawnPost, OnEntitySpawned);
}
else if ( !g_bChecked && strcmp(name, "infected") == 0 )
{
SDKHook(entity, SDKHook_SpawnPost, OnEntitySpawned);
}
}
public void OnEntitySpawned( int entity )
{
RequestFrame(NextFrame);
}
public void NextFrame()
{
if ( IsValidEntity(g_iGoalChase) && !CheckGoalChaseTraversablity() )
{
RemoveEntity(EntRefToEntIndex(g_iGoalChase));
g_iGoalChase = -1;
}
}
int CheckGoalChaseTraversablity()
{
if ( g_bChecked )
return -1;
int infected = FindEntityByClassname(MaxClients + 1, "infected");
if ( infected == -1 )
return -1;
float startPos[3], endPos[3];
GetEntPropVector(infected, Prop_Data, "m_vecOrigin", startPos);
GetEntPropVector(EntRefToEntIndex(g_iGoalChase), Prop_Data, "m_vecOrigin", endPos);
g_bChecked = true;
return L4D2_VScriptWrapper_NavAreaBuildPath(startPos, endPos, 1550.0, false, true, 3, false);
}
__________________
|
|