Raised This Month: $ Target: $400
 0% 

Player-Teleport (sm_goto, sm_bring)


  
 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
dcx2
Senior Member
Join Date: Sep 2011
Old 01-02-2012 , 23:47   Re: Player-Teleport (sm_goto, sm_bring)
Reply With Quote #11

Hi HyperKiLLeR,

Thank you for your teleportation plugin. Yours is the only version with a goto, which is a feature I wanted. It mostly works for L4D2. I say mostly because if you aim at a wall or a ceiling they will become stuck.

I had an idea. Get the collision point, and then do a bounds check with the client mins/maxs. If the player would become stuck, walk the ray backwards a little bit and try it again, until you collide with yourself or you've taken 100 steps. If you can't succeed, try again from the feet; this allows you to hit the ceiling. If that fails too, then they teleport to you, much like sm_goto.

I also wanted to change to a MASK_SHOT filter for collision, so I can teleport through fences and stuff like that. And I wanted ProcessTargetString support.

So I made these modifications and tested them and they work for me on my L4D2 server. I am sharing them with you in case you wish to add them to your plugin.

I think the backwards-ray-tracing with slightly inflated bounding box idea is cool enough that I'll share that bit in-line so that forum searches can find it. It might help some other people trying to teleport stuff without letting it get stuck.

PHP Code:
// Traces forward from a client's eye or foot position until the ray hits MASK_SHOT
// Then checks for the possibility to get stuck.  If teleportee would get stuck,
// walk the ray backwards little by little until they won't get stuck anymore
// If we get too close to the client's position, or we take 100 steps, fail with client pos
stock bool:GetCollisionPoint(clientFloat:pos[3], bool:eyes=true)
{
    
decl Float:vOrigin[3], Float:vAngles[3], Float:vBackwards[3];
    new 
bool:failed false;
    new 
loopLimit 100;    // only check 100 times, as a precaution against runaway loops

    
if (eyes)
    {
        
GetClientEyePosition(clientvOrigin);
    }
    else
    {
        
// if eyes is false, fall back to the AbsOrigin ( = feet)
        
GetClientAbsOrigin(clientvOrigin);
    }
    
    
GetClientEyeAngles(clientvAngles);
    
GetAngleVectors(vAnglesvBackwardsNULL_VECTORNULL_VECTOR);
    
NormalizeVector(vBackwardsvBackwards);
    
ScaleVector(vBackwards10.0);    // TODO: percentage of distance from endpoint to eyes instead of fixed distance?
    
    
new Handle:trace TR_TraceRayFilterEx(vOriginvAnglesMASK_SHOTRayType_InfiniteTraceEntityFilterPlayer);
        
    if (
TR_DidHit(trace))
    {    
        
TR_GetEndPosition(postrace);
        
//PrintToChat(client, "endpos %f %f %f", pos[0], pos[1], pos[2]);
        
        
while (IsPlayerStuck(posclient) && !failed)    // iteratively check if they would become stuck
        
{
            
SubtractVectors(posvBackwardspos);        // if they would, subtract backwards from the position
            //PrintToChat(client, "endpos %f %f %f", pos[0], pos[1], pos[2]);
            
if (GetVectorDistance(posvOrigin) < 10 || loopLimit-- < 1)
            {
                
                
failed true;    // If we get all the way back to the origin without colliding, we have failed
                //PrintToChat(client, "failed to find endpos");
                
pos vOrigin;    // Use the client position as a fallback
            
}
        }
    }
    
    
CloseHandle(trace);
    return !
failed;        // If we have not failed, return true to let the caller know pos has teleport coordinates
}

#define BOUNDINGBOX_INFLATION_OFFSET 3

// Checks to see if a player would collide with MASK_SOLID (i.e. they would be stuck)
// Inflates player mins/maxs a little bit for better protection against sticking
// Thanks to andersso for the basis of this function
stock bool:IsPlayerStuck(Float:pos[3], client)
{
    new 
Float:mins[3];
    new 
Float:maxs[3];

    
GetClientMins(clientmins);
    
GetClientMaxs(clientmaxs);
    
    
// inflate the sizes just a little bit
    
for (new i=0i<sizeof(mins); i++)
    {
        
mins[i] -= BOUNDINGBOX_INFLATION_OFFSET;
        
maxs[i] += BOUNDINGBOX_INFLATION_OFFSET;
    }

    
TR_TraceHullFilter(posposminsmaxsMASK_SOLIDTraceEntityFilterPlayerclient);

    return 
TR_DidHit();
}  

// filter out players, since we can't get stuck on them
public bool:TraceEntityFilterPlayer(entitycontentsMask)
{
    return 
entity <= || entity MaxClients;

Attached Files
File Type: sp Get Plugin or Get Source (sm_gotoRevA.sp - 940 views - 6.6 KB)

Last edited by dcx2; 01-02-2012 at 23:49. Reason: forgot to attach script
dcx2 is offline
 



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 09:34.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode