Veteran Member
|
04-30-2019
, 15:18
Re: Teleporting Player Check "Non-Stuck"
|
#12
|
Quote:
Originally Posted by scorpius2k1
EDIT: Error fixed. TheDS1337's script needs compiled against latest #include files from the SourceMod git repo. As of this post, stable version (1.9) does not yet include 'TR_GetStartPosition'
Thanks, that fixed the warning but the error is still present regardless of including 'sdktools' or 'sdktools_trace.inc' which has that specific native reference.
Unfortunately, in my previous post I had tried that already:
I used TheDS1337's original code they posted above, which also has...
PHP Code:
#include <sdktools>
...already, but still get the error. Weird!
|
Sorry, didn't know it wasn't included before.. I mean even the signature of TR_GetStartPosition compared to TR_GetEndPosition seemed odd.
PHP Code:
#include <sourcemod> #include <sdktools> #include <sdkhooks>
/* X: 32.000000Y: 32.000000Z: 72.000000 Mins[0]: -16.000000, Mins[1]: -16.000000, Mins[2]: 0.000000 Maxs[0]: 16.000000, Maxs[1]: 16.000000, Maxs[2]: 72.000000 Min/Maxs: 85.041168 Min/Origin: 2477.570312 Max/Origin: 2446.154785 */
#pragma newdecls required
#define PLAYER_WIDTH 32.0 #define PLAYER_HEIGHT 72.0
int g_LaserBeam;
public void OnPluginStart() { }
public void OnMapStart() { g_LaserBeam = PrecacheModel("materials/sprites/laserbeam.vmt", true); }
public void OnClientSayCommand_Post(int client, const char[] command, const char[] sArgs) { if( !IsPlayerAlive(client) ) { return; } if( strcmp(sArgs, "check_fitness", false) == 0 ) { float oldPos[3], newPos[3]; GetClientAbsOrigin(client, oldPos); AddVectors(oldPos, {0.0, 0.0, 25.0}, oldPos); // Just elevating it a little bit, this fixes some problems with the trace collision for some reason VectorCopy(oldPos, newPos); // CanPlayerFit fct is gonna modify the origin we give it, so we better store the old one for comparasion purposes if( CanPlayerFit(client, newPos) && !VectorsEqual(oldPos, newPos) ) { PrintToChat(client, "Teleported from %f %f %f to %f %f %f", oldPos[0], oldPos[1], oldPos[2], newPos[0], newPos[1], newPos[2]); PrintToChat(client, "Distance new/old: %f", GetVectorDistance(oldPos, newPos)); TeleportEntity(client, newPos, NULL_VECTOR, NULL_VECTOR); } } }
bool CanPlayerFit(int client, float pos[3]) { float radius = SquareRoot(2 * (PLAYER_WIDTH * PLAYER_WIDTH) + PLAYER_HEIGHT * PLAYER_HEIGHT); float heads[4][3]; heads[0][0] = pos[0] + PLAYER_WIDTH / 2; heads[0][1] = pos[1] + PLAYER_WIDTH / 2; heads[0][2] = pos[2] + PLAYER_HEIGHT / 2; heads[1][0] = pos[0] - PLAYER_WIDTH / 2; heads[1][1] = pos[1] - PLAYER_WIDTH / 2; heads[1][2] = pos[2] - PLAYER_HEIGHT / 2; heads[2][0] = pos[0] + PLAYER_WIDTH / 2; heads[2][1] = pos[1] - PLAYER_WIDTH / 2; heads[2][2] = pos[2] - PLAYER_HEIGHT / 2; heads[3][0] = pos[0] - PLAYER_WIDTH / 2; heads[3][1] = pos[1] + PLAYER_WIDTH / 2; heads[3][2] = pos[2] + PLAYER_HEIGHT / 2; TE_SetupBeamPoints(heads[0], heads[1], g_LaserBeam, 0, 0, 0, 30.0, 2.0, 2.0, 1, 0.0, {0, 0, 255, 255}, 15); TE_SendToAll(); TE_SetupBeamPoints(heads[3], heads[2], g_LaserBeam, 0, 0, 0, 30.0, 2.0, 2.0, 1, 0.0, {255, 0, 0, 255}, 15); TE_SendToAll(); int i = 0, trials = 0, dirSelection = -1; Handle ray = INVALID_HANDLE; float endPos[3], dir[3]; float dist = 0.0, lastDist = 0.0; do { PrintToChat(client, "Trial: %d", trials + 1); SubtractVectors(heads[1], heads[0], dir); ray = TR_TraceRayFilterEx(heads[0], dir, MASK_PLAYERSOLID, RayType_Infinite, CollisionCheck, client); if( ray ) { if( TR_DidHit(ray) ) { TR_GetEndPosition(endPos, ray); if( GetVectorDistance(pos, endPos) > radius ) { PrintToChat(client, "Point does not belong to %f", radius); delete ray; return true; } if( dirSelection == -1 || GetRandomInt(0, 3) == 0 ) { for( i = 0; i < 4; i++ ) { dist = GetVectorDistance(endPos, heads[i]); if( i == 0 ) { lastDist = dist; dirSelection = 0; } else if( dist < lastDist ) { lastDist = dist; dirSelection = i; } } } TE_SetupBeamPoints(pos, endPos, g_LaserBeam, 0, 0, 0, 30.0, 2.0, 2.0, 1, 0.0, {0, 255, 0, 255}, 15); TE_SendToAll(); SubtractVectors(heads[dirSelection], pos, dir); NormalizeVector(dir, dir); PrintToChat(client, "Point does belong to: %f", radius); ScaleVector(dir, radius / 2.0); AddVectors(pos, dir, pos); for( i = 0; i < 4; i++ ) { AddVectors(heads[i], dir, heads[i]); } } else { PrintToChat(client, "Trace not hitting it"); delete ray; return false; } delete ray; } } while( ++trials < 1000 ) return false; }
public bool CollisionCheck(int entity, int contentsMask, any data) { return entity != view_as<int> (data); }
void VectorCopy(float a[3], float b[3]) { b[0] = a[0]; b[1] = a[1]; b[2] = a[2]; }
bool VectorsEqual(float a[3], float b[3]) { return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] ? true : false; }
This should do the same thing.
Quote:
Originally Posted by 1337norway
You can call this function from CBaseEdict -> AreaNum()
https://github.com/VSES/SourceEngine...c/edict.h#L370
https://github.com/VSES/SourceEngine...roperty.h#L251
This will return an index value of the calculated PVS box an entity is currently in. These are sections in maps that aren't visible to each other and prevent ents from other pvs's from being networked frequently or at all. This reduces cpu load and networking along with preventing stuff like wallhack/esp from functioning. This function simply computes which PVS box the entity is in and if he's not in one it will return 0. This is one method to detect if the point is outside the skybox. You can move the client and check this within the same frame, if it fails to 0 you can teleport him back and the client wont see anything on his end.
|
This seems nice, but I'm not sure if it can be done with SDKTools/Dhooks, looks more like an extension work here.
Quote:
Originally Posted by 1337norway
Alternativly if you don't want to call internal functions and want a quick test that should work out on all maps that have sealed skyboxs 99% of the time. Make 6 raytraces from the point you want to check going in the forward direction of all 6 sides of a cube (forward, backward, up, down, left, right). In theory all 6 rays should hit something before they timeout from a very far distance if the point is within the level. Otherwise you can assum the void is visible from that point and not a valid teleportation location.
PHP Code:
#include <sourcemod> #include <smlib/effects>
new beammdl, halomdl;
new Float:fAngle[6][3] = {{1.0, 0.0, 0.0}, {-1.0,0.0,0.0}, {0.0,1.0,0.0}, {0.0,-1.0,0.0}, {0.0,0.0,1.0}, {0.0,0.0,-1.0}};
public OnPluginStart() { RegConsoleCmd("sm_testpoint1", TestPoint1_CMD); RegConsoleCmd("sm_testmypoint", TestMyPoint_CMD); }
public OnMapStart() { beammdl = PrecacheModel("materials/sprites/laserbeam.vmt", true); halomdl = PrecacheModel("materials/sprites/halo01.vmt"); }
public Action TestPoint1_CMD(int client, int args) { float fTestSpot[3] = {274.0, 2204.0, -14.0}; if(IsPointInLevel(fTestSpot)) PrintToChat(client, "Your point is inside the map."); else PrintToChat(client, "Your point is outside of the map."); }
public Action TestMyPoint_CMD(int client, int args) { float fPlayerPos[3]; GetClientEyePosition(client, fPlayerPos); if(IsPointInLevel(fPlayerPos)) PrintToChat(client, "Your point is inside the map."); else PrintToChat(client, "Your point is outside of the map."); }
bool IsPointInLevel(float fPoint[3]) { new Hits = 0; float fMin[3] = {-2.5, -2.5, -2.5}; float fMax[3] = {2.5, 2.5, 2.5}; AddVectors(fPoint, fMin, fMin); AddVectors(fPoint, fMax, fMax); Effect_DrawBeamBoxToAll(fMin, fMax, beammdl, halomdl, 0, 30, 10.0, 1.0, 1.0, 2, 1.0, { 255, 255, 255, 255 }); for(int c = 0;c < 6; c++) { float fEndPoint[3]; for(int i = 0;i < 3; i++) fEndPoint[i] = fPoint[i] + (fAngle[c][i] * 8192.0) TR_TraceRayFilter(fPoint, fEndPoint, MASK_SHOT, RayType_EndPoint, TraceRay); if(TR_GetEntityIndex(INVALID_HANDLE) != -1) { float fRealEndPos[3]; TR_GetEndPosition(fRealEndPos); TE_SetupBeamPoints(fPoint, fRealEndPos, beammdl, 0, 0, 0, 10.0, 1.0, 1.0, 1, 0.0, {255, 0, 0, 255}, 1); Hits++; } else { TE_SetupBeamPoints(fPoint, fEndPoint, beammdl, 0, 0, 0, 10.0, 1.0, 1.0, 1, 0.0, {0, 255, 0, 255}, 1); } TE_SendToAll(); } return (Hits == 6); }
public bool:TraceRay(entity, mask) { return true; }
|
Yeah, I thought about that but the invisible entities got into my head, usually mappers keep the map surrounded with invisible entities that do certain functions, and also, some maps even have these kind of "invisible" rooms so I don't know if this method really works..
Last edited by TheDS1337; 04-30-2019 at 15:26.
|
|