View Single Post
backwards
AlliedModders Donor
Join Date: Feb 2014
Location: USA
Old 07-21-2022 , 08:51   Re: [CSGO] how to warp players without getting stuck in walls?
Reply With Quote #2

You want to use a trace hull to scan a rectangular prism area for intersecting entitys before teleporting the player.
The trace hull size would be the max size of the player entity.
If something is intersecting the end point then you would want to move the endpoint away from the wall/ent you just hit by a fixed value in the inverse direction of the tracerays view angle.
Then you run the tracehull scan again until it is cleared or a max threshold of scans are reached.
If the area is then clear we would teleport the player entity or else deny it.


PHP Code:
#include <sourcemod>
#include <sdktools>

int beammdl = -1;

public 
void OnPluginStart()
{
    
beammdl PrecacheModel("materials/sprites/laserbeam.vmt"true);
    
RegConsoleCmd("warpfarbot"Command_WarpFarBot);
}

public 
void OnMapStart()
{
    
beammdl PrecacheModel("materials/sprites/laserbeam.vmt"true);
}

bool IsAreaClear(int clientfloat position[3])
{
    
//This is the players collision rectangular prism size defined by two 3D Points farthest away from each other
    
static float vecMins[3] = {-16.0, -16.00.0};
    static 
float vecMaxs[3] = {16.016.072.0};
    
    
TR_TraceHullFilter(positionpositionvecMinsvecMaxsMASK_PLAYERSOLIDFilter_LocalPlayerclient);
    
    if(!
TR_DidHit())
        return 
true;
    
    return 
false;
}

public 
bool Filter_LocalPlayer(int entityint contentsMaskany client)
{
    return !(
entity == client)
}

public 
bool Filter_ExcludePlayers(int entityint contentsMaskany data)
{
    return !((
entity 0) && (entity <= MaxClients));
}  

int GetFarthestBot(int client)
{
    
float playerPos[3];
    
GetClientEyePosition(clientplayerPos);

    
float farthestDistance 0.0;
    
int farthestBot = -1;
    
    for(
int bot 1;bot<MaxClients+1;bot++)
    {
        if(
IsValidClient(bot) && IsFakeClient(bot) && IsPlayerAlive(bot))
        {
            
float botPos[3];
            
GetClientEyePosition(botbotPos);
    
            
float dist GetVectorDistance(playerPosbotPos);
            if(
dist farthestDistance)
            {
                
farthestDistance dist;
                
farthestBot bot;
            }
        }
    }
    
    return 
farthestBot;
}

public 
Action Command_WarpFarBot(int clientint args)
{
    
int farthestBotIndex GetFarthestBot(client);

    if(
farthestBotIndex == -1)
    {
        
PrintToChat(client"no active bots!");
        return 
Plugin_Handled;
    }

    
float g_Origin[3], g_Angle[3], HitEndPoint[3];
    
    
GetClientEyePosition(clientg_Origin);
    
GetClientEyeAngles(clientg_Angle);
    
TR_TraceRayFilter(g_Origing_AngleMASK_SHOTRayType_InfiniteFilter_LocalPlayerclient);
    
    if(!
TR_DidHit(INVALID_HANDLE))
    {
        
PrintToChat(client"\x01\x02 \x02Trace ray did not hit anything!");
        return 
Plugin_Handled;
    }
    
    
TR_GetEndPosition(HitEndPoint);
    
    
//We can get the ground underneath the player by shooting another raytrace directly down
    //This prevents players from spawning on the wall really high and causing fall damage
    
float down[3] = {90.00.00.0};
        
    
TR_TraceRayFilter(HitEndPointdownMASK_SHOTRayType_InfiniteFilter_ExcludePlayers);
    if(!
TR_DidHit(INVALID_HANDLE))
    {
        
PrintToChat(client"\x01\x02 \x02Could not find ground!");
        return 
Plugin_Handled;
    }
    
    
TR_GetEndPosition(HitEndPoint);
    
    
//Elevate off the ground
    
HitEndPoint[2] += 10.0;
    
    
float fForwards[3];
    
GetAngleVectors(g_AnglefForwardsNULL_VECTORNULL_VECTOR);
    
    
//Invert forwards angle to change direction to face from hitpos to client running the cmd
    
for(int i 0;3i++)
        
fForwards[i] *= -1;
    
    
//Move 32 units from hit point on the wall
    
for(int i 0;3i++)
        
HitEndPoint[i] = HitEndPoint[i] + (fForwards[i] * 32.0);
    
    
int iterationCount 0;
    
    
//Check if point is clear
    
while(!IsAreaClear(clientHitEndPoint))
    {
        
float HitEndPointDebug[3];
        
        
//Just create offset point for debug draw line secondary point
        
for(int i 0;3i++)
            
HitEndPointDebug[i] = HitEndPoint[i] + 5.0;
        
        
//debug visuals
        
TE_SetupBeamPoints(HitEndPointHitEndPointDebugbeammdl00010.01.01.010.0, {25500255}, 1);
        
TE_SendToAll();
                    
        
iterationCount++;
        if(
iterationCount 10)
        {
            
PrintToChat(client"\x01\x02 \x02Area is not Clear!");
            return 
Plugin_Handled;
        }
        
        
//Iterate point 32 units towards the player camera for next trace hull check
        
for(int i 0;3i++)
            
HitEndPoint[i] = HitEndPoint[i] + (fForwards[i] * 32.0);
    }
    
    
//debug message for iteration loop count
    //PrintToChat(client, "\x01\x02 \x10Exit loop after %i iterations", iterationCount);
    
    
TeleportEntity(farthestBotIndexHitEndPointNULL_VECTORNULL_VECTOR);      
    
PrintToChat(client"\x01\x10 \x06Teleported %N"farthestBotIndex);
    
    return 
Plugin_Handled;
}

bool IsValidClient(int client

    if (!(
<= client <= MaxClients) || !IsClientConnected(client) || !IsClientInGame(client) || IsClientSourceTV(client) || IsClientReplay(client)) 
        return 
false
         
    return 
true

Video of above plugin code


Last edited by backwards; 07-21-2022 at 08:52.
backwards is offline