Can you help me please, find out why TraceHull can't find end position for some (identical) places on the map?
PHP Code:
#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <sdktools>
int g_sprite;
#define PRINT_LASER 1
#define RED {255, 0, 0, 255}
#define GREEN {0, 255, 0, 255}
public void OnPluginStart()
{
RegAdminCmd("sm_distdir", CmdDistanceDir, ADMFLAG_ROOT, "Get distance between you and end point of direction you are looking at (considering collision)");
}
public void OnMapStart()
{
g_sprite = PrecacheModel("materials/sprites/laser.vmt", true);
}
public Action CmdDistanceDir(int client, int args)
{
float vOrigin[3], vEnd[3], vEndNonCol[3];
float dist;
GetClientAbsOrigin(client, vOrigin);
if (GetDirectionEndPoint(client, vEnd))
{
dist = GetVectorDistance(vOrigin, vEnd);
PrintToChat(client, "Directional end point: %f %f %f. Distance: %f", vEnd[0], vEnd[1], vEnd[2], dist);
if (GetNonCollideEndPoint(client, vEnd, vEndNonCol))
{
dist = GetVectorDistance(vOrigin, vEndNonCol);
PrintToChat(client, "Non-collide end point: %f %f %f. Distance: %f", vEndNonCol[0], vEndNonCol[1], vEndNonCol[2], dist);
}
else {
PrintToChat(client, "Non-collide end point doesn't found.");
}
}
else {
PrintToChat(client, "Directional end point doesn't found.");
}
return Plugin_Handled;
}
stock bool GetDirectionEndPoint(int client, float vEndPos[3])
{
float vDir[3], vPos[3];
GetClientEyePosition(client, vPos);
GetClientEyeAngles(client, vDir);
Handle hTrace = TR_TraceRayFilterEx(vPos, vDir, MASK_PLAYERSOLID, RayType_Infinite, TraceRayNoPlayers, client);
if (hTrace != INVALID_HANDLE) {
if(TR_DidHit(hTrace)) {
TR_GetEndPosition(vEndPos, hTrace);
CloseHandle(hTrace);
#if PRINT_LASER
LaserP(vPos, vEndPos, RED);
#endif
return true;
}
CloseHandle(hTrace);
}
return false;
}
stock bool GetNonCollideEndPoint(int client, float vEnd[3], float vEndNonCol[3])
{
float vMin[3], vMax[3], vStart[3];
GetClientAbsOrigin(client, vStart);
GetClientMins(client, vMin);
GetClientMaxs(client, vMax);
vStart[2] += 20.0; // if nearby area is irregular
Handle hTrace = TR_TraceHullFilterEx(vStart, vEnd, vMin, vMax, MASK_PLAYERSOLID, TraceRayNoPlayers, client);
if (hTrace != INVALID_HANDLE) {
if(TR_DidHit(hTrace))
{
TR_GetEndPosition(vEndNonCol, hTrace);
CloseHandle(hTrace);
#if PRINT_LASER
LaserP(vStart, vEndNonCol, GREEN, 5.0);
#endif
return true;
}
CloseHandle(hTrace);
}
return false;
}
public bool TraceRayNoPlayers(int entity, int mask, any data)
{
if(entity == data || (entity >= 1 && entity <= MaxClients))
{
return false;
}
return true;
}
stock void LaserP(float start[3], float end[3], int color[4], float width = 3.0)
{
TE_SetupBeamPoints(start, end, g_sprite, 0, 0, 0, 10.0, width, width, 7, 0.0, color, 5);
TE_SendToAll();
}
P.S. Red laser is - TR_TraceRayFilterEx, Green - is TR_TraceHullFilterEx.