Code:
#include <sdktools>
#include <sdkhooks>
#include <tf2>
#include <tf2_stocks>
#include <PathFollower>
#pragma newdecls required
int g_iPathLaserModelIndex = -1;
float g_flGoal[MAXPLAYERS + 1][3];
//What is this "Cursor" thing
public Plugin myinfo =
{
name = "[TF2] PathFollower extension testing",
author = "Pelipoika",
description = "",
version = "1.0",
url = "http://www.sourcemod.net/plugins.php?author=Pelipoika&search=1"
};
public void OnMapStart()
{
g_iPathLaserModelIndex = PrecacheModel("materials/sprites/laserbeam.vmt");
}
public void OnPluginStart()
{
RegAdminCmd("sm_pathgoal", Command_PathGoal, ADMFLAG_ROOT);
RegAdminCmd("sm_path", Command_PathToggle, ADMFLAG_ROOT);
}
public Action Command_PathGoal(int client, int args)
{
if(client > 0 && client <= MaxClients && IsClientInGame(client) && IsPlayerAlive(client))
{
GetClientAbsOrigin(client, g_flGoal[client]);
PrintToChat(client, "Goal set to your absorigin");
}
return Plugin_Handled;
}
public Action Command_PathToggle(int client, int args)
{
if(client > 0 && client <= MaxClients && IsClientInGame(client) && IsPlayerAlive(client))
{
if(!PF_Exists(client))
{
PrintToChat(client, "Pathing: ON");
PF_Create(client, 18.0, 72.0, 1000.0, 0.6, MASK_PLAYERSOLID, 300.0, 0.5, 1.5, 1.0);
PF_SetGoalVector(client, g_flGoal[client]);
PF_EnableCallback(client, PFCB_Approach, PF_Approach);
PF_EnableCallback(client, PFCB_ClimbUpToLedge, PF_ClibmUpToLedge);
PF_EnableCallback(client, PFCB_IsEntityTraversable, PF_IsEntityTraversable);
PF_EnableCallback(client, PFCB_PathFailed, PF_PathFailed);
PF_StartPathing(client);
}
else if(PF_Exists(client))
{
PrintToChat(client, "Pathing: OFF");
PF_StopPathing(client);
PF_Destroy(client);
}
}
return Plugin_Handled;
}
public void PF_Approach(int bot_entindex, float vecGoal[3])
{
g_flGoal[bot_entindex][0] = vecGoal[0];
g_flGoal[bot_entindex][1] = vecGoal[1];
g_flGoal[bot_entindex][2] = vecGoal[2];
// TE_ShowPole(g_flGoal[bot_entindex], {255, 0, 0, 255});
}
bool bJump;
public bool PF_ClibmUpToLedge(int bot_entidx, const float dst[3], const float dir[3])
{
bJump = true;
PrintCenterText(bot_entidx, "PF_ClibmUpToLedge");
}
public bool PF_IsEntityTraversable(int bot_entindex, int other_entidx, TraverseWhenType when)
{
char strClass[64];
GetEntityClassname(other_entidx, strClass, 64);
PrintCenterText(bot_entindex, "PF_ClibmUpToLedge %s", strClass);
}
public void PF_PathFailed(int bot_entindex)
{
PrintCenterText(bot_entindex, "PF_PathFailed");
}
public Action OnPlayerRunCmd(int client, int &iButtons, int &iImpulse, float fVel[3], float fAng[3], int &iWeapon)
{
if(IsFakeClient(client) || !PF_Exists(client) || !IsPlayerAlive(client))
return Plugin_Continue;
/* for (int i = 0; i < 32; i++)
{
float flFromPos[3];
float flToPos[3];
if(PF_GetFutureSegment(client, i, flFromPos) && PF_GetFutureSegment(client, i + 1, flToPos))
{
TE_ShowPole(flFromPos, {0, 255, 255, 100});
TE_SetupBeamPoints(flFromPos,
flToPos,
g_iPathLaserModelIndex,
g_iPathLaserModelIndex,
0,
30,
0.25,
5.0,
5.0,
5,
0.0,
{255, 255, 255, 100},
30);
TE_SendToClient(client);
}
}*/
TF2_MoveTo(client, g_flGoal[client], fVel, fAng);
if(bJump)
{
iButtons |= IN_JUMP;
bJump = false;
return Plugin_Changed;
}
return Plugin_Continue;
}
stock void TF2_MoveTo(int client, float flGoal[3], float fVel[3], float fAng[3])
{
float flPos[3];
GetClientAbsOrigin(client, flPos);
float newmove[3];
SubtractVectors(flGoal, flPos, newmove);
newmove[1] = -newmove[1];
float sin = Sine(fAng[1] * FLOAT_PI / 180.0);
float cos = Cosine(fAng[1] * FLOAT_PI / 180.0);
fVel[0] = cos * newmove[0] - sin * newmove[1];
fVel[1] = sin * newmove[0] + cos * newmove[1];
NormalizeVector(fVel, fVel);
ScaleVector(fVel, 450.0);
}
stock bool TF2_IsNextToWall(int client)
{
float flPos[3];
GetClientAbsOrigin(client, flPos);
float flMaxs[3], flMins[3];
GetEntPropVector(client, Prop_Send, "m_vecMaxs", flMaxs);
GetEntPropVector(client, Prop_Send, "m_vecMins", flMins);
flMaxs[0] += 2.5;
flMaxs[1] += 2.5;
flMins[0] -= 2.5;
flMins[1] -= 2.5;
flPos[2] += 18.0;
//Perform a wall check to see if we are near any obstacles we should try jump over
Handle TraceRay = TR_TraceHullFilterEx(flPos, flPos, flMins, flMaxs, MASK_PLAYERSOLID, ExcludeFilter, client);
bool bHit = TR_DidHit(TraceRay);
delete TraceRay;
return bHit;
}
public bool ExcludeFilter(int entity, int contentsMask, any iExclude)
{
return !(entity == iExclude);
}
stock void TE_ShowPole(float flPos[3], int Color[4])
{
float flToPos[3];
flToPos[0] = flPos[0];
flToPos[1] = flPos[1];
flToPos[2] = flPos[2];
flToPos[2] += 60.0;
//Show a giant vertical beam at our goal node
TE_SetupBeamPoints(flPos, flToPos, g_iPathLaserModelIndex, g_iPathLaserModelIndex, 0, 30, 0.1, 5.0, 5.0, 5, 0.0, Color, 30);
TE_SendToAll();
}