- added GetClientAimTarget()
- fixed a bug where GetClientEyeAngles() was basically bogus --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401617
This commit is contained in:
parent
ab8f67fc42
commit
c2644b2f94
@ -104,6 +104,8 @@ bool SDKTools::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
|||||||
|
|
||||||
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SDKTools::LevelInit, true);
|
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, LevelInit, gamedll, this, &SDKTools::LevelInit, true);
|
||||||
|
|
||||||
|
MathLib_Init(2.2f, 2.2f, 0.0f, 2);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
CallHelper s_Teleport;
|
CallHelper s_Teleport;
|
||||||
CallHelper s_GetVelocity;
|
CallHelper s_GetVelocity;
|
||||||
|
CallHelper s_EyeAngles;
|
||||||
|
|
||||||
bool SetupTeleport()
|
bool SetupTeleport()
|
||||||
{
|
{
|
||||||
@ -53,7 +54,7 @@ bool SetupTeleport()
|
|||||||
|
|
||||||
s_Teleport.call = g_pBinTools->CreateVCall(offset, 0, 0, NULL, info, 3);
|
s_Teleport.call = g_pBinTools->CreateVCall(offset, 0, 0, NULL, info, 3);
|
||||||
|
|
||||||
if (s_Teleport.call)
|
if (s_Teleport.call != NULL)
|
||||||
{
|
{
|
||||||
s_Teleport.supported = true;
|
s_Teleport.supported = true;
|
||||||
}
|
}
|
||||||
@ -101,7 +102,7 @@ bool SetupGetVelocity()
|
|||||||
|
|
||||||
s_GetVelocity.call = g_pBinTools->CreateVCall(offset, 0, 0, NULL, info, 2);
|
s_GetVelocity.call = g_pBinTools->CreateVCall(offset, 0, 0, NULL, info, 2);
|
||||||
|
|
||||||
if (s_GetVelocity.call)
|
if (s_GetVelocity.call != NULL)
|
||||||
{
|
{
|
||||||
s_GetVelocity.supported = true;
|
s_GetVelocity.supported = true;
|
||||||
}
|
}
|
||||||
@ -130,6 +131,65 @@ bool IsGetVelocitySupported()
|
|||||||
return SetupGetVelocity();
|
return SetupGetVelocity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SetupGetEyeAngles()
|
||||||
|
{
|
||||||
|
if (s_EyeAngles.setup)
|
||||||
|
{
|
||||||
|
return s_EyeAngles.supported;
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset;
|
||||||
|
if (g_pGameConf->GetOffset("EyeAngles", &offset))
|
||||||
|
{
|
||||||
|
PassInfo info[2];
|
||||||
|
info[0].flags = info[1].flags = PASSFLAG_BYVAL;
|
||||||
|
info[0].size = info[1].size = sizeof(void *);
|
||||||
|
info[0].type = info[1].type = PassType_Basic;
|
||||||
|
|
||||||
|
s_EyeAngles.call = g_pBinTools->CreateVCall(offset, 0, 0, &info[0], &info[1], 1);
|
||||||
|
|
||||||
|
if (s_EyeAngles.call != NULL)
|
||||||
|
{
|
||||||
|
s_EyeAngles.supported = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s_EyeAngles.setup = true;
|
||||||
|
|
||||||
|
return s_EyeAngles.supported;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetEyeAngles(CBaseEntity *pEntity, QAngle *pAngles)
|
||||||
|
{
|
||||||
|
if (!IsEyeAnglesSupported())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAngle *pRetAngle = NULL;
|
||||||
|
unsigned char params[sizeof(void *)];
|
||||||
|
unsigned char *vptr = params;
|
||||||
|
|
||||||
|
*(CBaseEntity **)vptr = pEntity;
|
||||||
|
vptr += sizeof(CBaseEntity *);
|
||||||
|
|
||||||
|
s_EyeAngles.call->Execute(params, &pRetAngle);
|
||||||
|
|
||||||
|
if (pRetAngle == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pAngles = *pRetAngle;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsEyeAnglesSupported()
|
||||||
|
{
|
||||||
|
return SetupGetEyeAngles();
|
||||||
|
}
|
||||||
|
|
||||||
void ShutdownHelpers()
|
void ShutdownHelpers()
|
||||||
{
|
{
|
||||||
s_Teleport.Shutdown();
|
s_Teleport.Shutdown();
|
||||||
|
@ -63,6 +63,9 @@ bool IsTeleportSupported();
|
|||||||
void GetVelocity(CBaseEntity *pEntity, Vector *velocity, AngularImpulse *angvelocity);
|
void GetVelocity(CBaseEntity *pEntity, Vector *velocity, AngularImpulse *angvelocity);
|
||||||
bool IsGetVelocitySupported();
|
bool IsGetVelocitySupported();
|
||||||
|
|
||||||
|
bool GetEyeAngles(CBaseEntity *pEntity, QAngle *pAngles);
|
||||||
|
bool IsEyeAnglesSupported();
|
||||||
|
|
||||||
void ShutdownHelpers();
|
void ShutdownHelpers();
|
||||||
|
|
||||||
#endif //_INCLUDE_SDKTOOLS_VHELPERS_H_
|
#endif //_INCLUDE_SDKTOOLS_VHELPERS_H_
|
||||||
|
@ -113,6 +113,23 @@ bool CreateBaseCall(const char *name,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CTraceFilterSimple : public CTraceFilterEntitiesOnly
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CTraceFilterSimple(const IHandleEntity *passentity): m_pPassEnt(passentity)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual bool ShouldHitEntity(IHandleEntity *pServerEntity, int contentsMask)
|
||||||
|
{
|
||||||
|
if (pServerEntity == m_pPassEnt)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
const IHandleEntity *m_pPassEnt;
|
||||||
|
};
|
||||||
|
|
||||||
static cell_t RemovePlayerItem(IPluginContext *pContext, const cell_t *params)
|
static cell_t RemovePlayerItem(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
@ -567,31 +584,39 @@ static cell_t GetClientEyePosition(IPluginContext *pContext, const cell_t *param
|
|||||||
|
|
||||||
static cell_t GetClientEyeAngles(IPluginContext *pContext, const cell_t *params)
|
static cell_t GetClientEyeAngles(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
static ValveCall *pCall = NULL;
|
int client = params[1];
|
||||||
if (!pCall)
|
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
|
||||||
|
|
||||||
|
if (!pPlayer)
|
||||||
{
|
{
|
||||||
ValvePassInfo retinfo[1];
|
return pContext->ThrowNativeError("Invalid client index %d", client);
|
||||||
InitPass(retinfo[0], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
|
|
||||||
if (!CreateBaseCall("EyeAngles", ValveCall_Player, retinfo, NULL, 0, &pCall))
|
|
||||||
{
|
|
||||||
return pContext->ThrowNativeError("\"EyeAngles\" not supported by this mod");
|
|
||||||
} else if (!pCall) {
|
|
||||||
return pContext->ThrowNativeError("\"EyeAngles\" wrapper failed to initialized");
|
|
||||||
}
|
}
|
||||||
|
else if (!pPlayer->IsInGame())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Client %d is not in game", client);
|
||||||
}
|
}
|
||||||
|
|
||||||
QAngle *ang;
|
edict_t *pEdict = pPlayer->GetEdict();
|
||||||
START_CALL();
|
CBaseEntity *pEntity = pEdict->GetUnknown() ? pEdict->GetUnknown()->GetBaseEntity() : NULL;
|
||||||
DECODE_VALVE_PARAM(1, thisinfo, 0);
|
|
||||||
FINISH_CALL_SIMPLE(&ang);
|
/* We always set the angles for backwards compatibility --
|
||||||
|
* The original function had no return value.
|
||||||
|
*/
|
||||||
|
QAngle angles;
|
||||||
|
bool got_angles = false;
|
||||||
|
|
||||||
|
if (pEntity == NULL)
|
||||||
|
{
|
||||||
|
got_angles = GetEyeAngles(pEntity, &angles);
|
||||||
|
}
|
||||||
|
|
||||||
cell_t *addr;
|
cell_t *addr;
|
||||||
pContext->LocalToPhysAddr(params[2], &addr);
|
pContext->LocalToPhysAddr(params[2], &addr);
|
||||||
addr[0] = sp_ftoc(ang->x);
|
addr[0] = sp_ftoc(angles.x);
|
||||||
addr[1] = sp_ftoc(ang->y);
|
addr[1] = sp_ftoc(angles.y);
|
||||||
addr[2] = sp_ftoc(ang->z);
|
addr[2] = sp_ftoc(angles.z);
|
||||||
|
|
||||||
return 1;
|
return got_angles ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell_t FindEntityByClassname(IPluginContext *pContext, const cell_t *params)
|
static cell_t FindEntityByClassname(IPluginContext *pContext, const cell_t *params)
|
||||||
@ -638,7 +663,8 @@ static cell_t IsPlayerAlive(IPluginContext *pContext, const cell_t *params)
|
|||||||
if (player == NULL)
|
if (player == NULL)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid client index %d", params[1]);
|
return pContext->ThrowNativeError("Invalid client index %d", params[1]);
|
||||||
} else if (!player->IsInGame())
|
}
|
||||||
|
else if (!player->IsInGame())
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Client %d is not in game", params[1]);
|
return pContext->ThrowNativeError("Client %d is not in game", params[1]);
|
||||||
}
|
}
|
||||||
@ -814,6 +840,78 @@ static cell_t DispatchKeyValueVector(IPluginContext *pContext, const cell_t *par
|
|||||||
return (ret) ? 1 : 0;
|
return (ret) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cell_t GetClientAimTarget(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
int client = params[1];
|
||||||
|
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
|
||||||
|
|
||||||
|
if (!pPlayer)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid client index %d", client);
|
||||||
|
}
|
||||||
|
else if (!pPlayer->IsInGame())
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Client %d is not in game", client);
|
||||||
|
}
|
||||||
|
|
||||||
|
edict_t *pEdict = pPlayer->GetEdict();
|
||||||
|
CBaseEntity *pEntity = pEdict->GetUnknown() ? pEdict->GetUnknown()->GetBaseEntity() : NULL;
|
||||||
|
|
||||||
|
if (pEntity == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector eye_position;
|
||||||
|
QAngle eye_angles;
|
||||||
|
|
||||||
|
/* Get the private information we need */
|
||||||
|
serverClients->ClientEarPosition(pEdict, &eye_position);
|
||||||
|
if (!GetEyeAngles(pEntity, &eye_angles))
|
||||||
|
{
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector aim_dir;
|
||||||
|
AngleVectors(eye_angles, &aim_dir);
|
||||||
|
VectorNormalize(aim_dir);
|
||||||
|
|
||||||
|
Vector vec_end = eye_position + aim_dir * 8000;
|
||||||
|
|
||||||
|
Ray_t ray;
|
||||||
|
ray.Init(eye_position, vec_end);
|
||||||
|
|
||||||
|
trace_t tr;
|
||||||
|
CTraceFilterSimple simple(pEdict->GetIServerEntity());
|
||||||
|
|
||||||
|
enginetrace->TraceRay(ray, MASK_SOLID|CONTENTS_DEBRIS|CONTENTS_HITBOX, &simple, &tr);
|
||||||
|
|
||||||
|
if (tr.fraction == 1.0f || tr.m_pEnt == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
edict_t *pTarget = gameents->BaseEntityToEdict(tr.m_pEnt);
|
||||||
|
if (pTarget == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ent_index = engine->IndexOfEdict(pTarget);
|
||||||
|
|
||||||
|
IGamePlayer *pTargetPlayer = playerhelpers->GetGamePlayer(ent_index);
|
||||||
|
if (pTargetPlayer != NULL && !pTargetPlayer->IsInGame())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (params[2] && pTargetPlayer == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ent_index;
|
||||||
|
}
|
||||||
|
|
||||||
sp_nativeinfo_t g_Natives[] =
|
sp_nativeinfo_t g_Natives[] =
|
||||||
{
|
{
|
||||||
{"ExtinguishPlayer", ExtinguishEntity},
|
{"ExtinguishPlayer", ExtinguishEntity},
|
||||||
@ -838,5 +936,6 @@ sp_nativeinfo_t g_Natives[] =
|
|||||||
{"DispatchKeyValue", DispatchKeyValue},
|
{"DispatchKeyValue", DispatchKeyValue},
|
||||||
{"DispatchKeyValueFloat", DispatchKeyValueFloat},
|
{"DispatchKeyValueFloat", DispatchKeyValueFloat},
|
||||||
{"DispatchKeyValueVector", DispatchKeyValueVector},
|
{"DispatchKeyValueVector", DispatchKeyValueVector},
|
||||||
|
{"GetClientAimTarget", GetClientAimTarget},
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
@ -137,10 +137,10 @@ native FindEntityByClassname(startEnt, const String:classname[]);
|
|||||||
*
|
*
|
||||||
* @param client Player's index.
|
* @param client Player's index.
|
||||||
* @param ang Destination vector to store the client's eye angles.
|
* @param ang Destination vector to store the client's eye angles.
|
||||||
* @noreturn
|
* @return True on success, false on failure.
|
||||||
* @error Invalid client index, client not in game, or no mod support.
|
* @error Invalid client index, client not in game, or no mod support.
|
||||||
*/
|
*/
|
||||||
native GetClientEyeAngles(client, Float:ang[3]);
|
native bool:GetClientEyeAngles(client, Float:ang[3]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if the client is alive or dead.
|
* Returns if the client is alive or dead.
|
||||||
@ -205,6 +205,18 @@ native bool:DispatchKeyValueFloat(entity, const String:keyName[], Float:value);
|
|||||||
*/
|
*/
|
||||||
native bool:DispatchKeyValueVector(entity, const String:keyName[], const Float:vector[3]);
|
native bool:DispatchKeyValueVector(entity, const String:keyName[], const Float:vector[3]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the entity a client is aiming at.
|
||||||
|
*
|
||||||
|
* @param client Client performing the aiming.
|
||||||
|
* @param only_clients True to exclude all entities but clients.
|
||||||
|
* @return Entity index being aimed at.
|
||||||
|
* -1 if no entity is being aimed at.
|
||||||
|
* -2 if the function is not supported.
|
||||||
|
* @error Invalid client index.
|
||||||
|
*/
|
||||||
|
native GetClientAimTarget(client, bool:only_clients=true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user