- 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);
|
||||
|
||||
MathLib_Init(2.2f, 2.2f, 0.0f, 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
CallHelper s_Teleport;
|
||||
CallHelper s_GetVelocity;
|
||||
CallHelper s_EyeAngles;
|
||||
|
||||
bool SetupTeleport()
|
||||
{
|
||||
@ -53,7 +54,7 @@ bool SetupTeleport()
|
||||
|
||||
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;
|
||||
}
|
||||
@ -101,7 +102,7 @@ bool SetupGetVelocity()
|
||||
|
||||
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;
|
||||
}
|
||||
@ -130,6 +131,65 @@ bool IsGetVelocitySupported()
|
||||
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()
|
||||
{
|
||||
s_Teleport.Shutdown();
|
||||
|
@ -63,6 +63,9 @@ bool IsTeleportSupported();
|
||||
void GetVelocity(CBaseEntity *pEntity, Vector *velocity, AngularImpulse *angvelocity);
|
||||
bool IsGetVelocitySupported();
|
||||
|
||||
bool GetEyeAngles(CBaseEntity *pEntity, QAngle *pAngles);
|
||||
bool IsEyeAnglesSupported();
|
||||
|
||||
void ShutdownHelpers();
|
||||
|
||||
#endif //_INCLUDE_SDKTOOLS_VHELPERS_H_
|
||||
|
@ -113,6 +113,23 @@ bool CreateBaseCall(const char *name,
|
||||
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)
|
||||
{
|
||||
@ -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 ValveCall *pCall = NULL;
|
||||
if (!pCall)
|
||||
int client = params[1];
|
||||
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
|
||||
|
||||
if (!pPlayer)
|
||||
{
|
||||
ValvePassInfo retinfo[1];
|
||||
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");
|
||||
}
|
||||
return pContext->ThrowNativeError("Invalid client index %d", client);
|
||||
}
|
||||
else if (!pPlayer->IsInGame())
|
||||
{
|
||||
return pContext->ThrowNativeError("Client %d is not in game", client);
|
||||
}
|
||||
|
||||
QAngle *ang;
|
||||
START_CALL();
|
||||
DECODE_VALVE_PARAM(1, thisinfo, 0);
|
||||
FINISH_CALL_SIMPLE(&ang);
|
||||
edict_t *pEdict = pPlayer->GetEdict();
|
||||
CBaseEntity *pEntity = pEdict->GetUnknown() ? pEdict->GetUnknown()->GetBaseEntity() : NULL;
|
||||
|
||||
/* 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;
|
||||
pContext->LocalToPhysAddr(params[2], &addr);
|
||||
addr[0] = sp_ftoc(ang->x);
|
||||
addr[1] = sp_ftoc(ang->y);
|
||||
addr[2] = sp_ftoc(ang->z);
|
||||
addr[0] = sp_ftoc(angles.x);
|
||||
addr[1] = sp_ftoc(angles.y);
|
||||
addr[2] = sp_ftoc(angles.z);
|
||||
|
||||
return 1;
|
||||
return got_angles ? 1 : 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
@ -814,6 +840,78 @@ static cell_t DispatchKeyValueVector(IPluginContext *pContext, const cell_t *par
|
||||
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[] =
|
||||
{
|
||||
{"ExtinguishPlayer", ExtinguishEntity},
|
||||
@ -838,5 +936,6 @@ sp_nativeinfo_t g_Natives[] =
|
||||
{"DispatchKeyValue", DispatchKeyValue},
|
||||
{"DispatchKeyValueFloat", DispatchKeyValueFloat},
|
||||
{"DispatchKeyValueVector", DispatchKeyValueVector},
|
||||
{"GetClientAimTarget", GetClientAimTarget},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
@ -137,16 +137,16 @@ native FindEntityByClassname(startEnt, const String:classname[]);
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @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.
|
||||
*/
|
||||
native GetClientEyeAngles(client, Float:ang[3]);
|
||||
native bool:GetClientEyeAngles(client, Float:ang[3]);
|
||||
|
||||
/**
|
||||
* Returns if the client is alive or dead.
|
||||
*
|
||||
* @param client Player's index.
|
||||
* @return True if the client is alive, false otherwise.
|
||||
* @return True if the client is alive, false otherwise.
|
||||
* @error Invalid client index, client not in game, or no mod support.
|
||||
*/
|
||||
native bool:IsPlayerAlive(client);
|
||||
@ -156,10 +156,10 @@ native bool:IsPlayerAlive(client);
|
||||
* If ForceEdictIndex is not -1, then it will use the edict by that index. If the index is
|
||||
* invalid or there is already an edict using that index, it will error out.
|
||||
*
|
||||
* @param classname Entity classname.
|
||||
* @param classname Entity classname.
|
||||
* @param ForceEdictIndex Edict index used by the created entity.
|
||||
* @return Entity index on success, or -1 on failure.
|
||||
* @error Invalid edict index, or no mod support.
|
||||
* @return Entity index on success, or -1 on failure.
|
||||
* @error Invalid edict index, or no mod support.
|
||||
*/
|
||||
native CreateEntityByName(const String:classname[], ForceEdictIndex=-1);
|
||||
|
||||
@ -167,8 +167,8 @@ native CreateEntityByName(const String:classname[], ForceEdictIndex=-1);
|
||||
* Spawns an entity into the game.
|
||||
*
|
||||
* @param entity Entity index of the created entity.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid entity index, or no mod support.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid entity index, or no mod support.
|
||||
*/
|
||||
native bool:DispatchSpawn(entity);
|
||||
|
||||
@ -178,8 +178,8 @@ native bool:DispatchSpawn(entity);
|
||||
* @param entity Destination entity index.
|
||||
* @param keyName Name of the key.
|
||||
* @param value String value.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid entity index, or no mod support.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid entity index, or no mod support.
|
||||
*/
|
||||
native bool:DispatchKeyValue(entity, const String:keyName[], const String:value[]);
|
||||
|
||||
@ -189,8 +189,8 @@ native bool:DispatchKeyValue(entity, const String:keyName[], const String:value[
|
||||
* @param entity Destination entity index.
|
||||
* @param keyName Name of the key.
|
||||
* @param value Floating point value.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid entity index, or no mod support.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid entity index, or no mod support.
|
||||
*/
|
||||
native bool:DispatchKeyValueFloat(entity, const String:keyName[], Float:value);
|
||||
|
||||
@ -200,11 +200,23 @@ native bool:DispatchKeyValueFloat(entity, const String:keyName[], Float:value);
|
||||
* @param entity Destination entity index.
|
||||
* @param keyName Name of the key.
|
||||
* @param vec Vector value.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid entity index, or no mod support.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid entity index, or no mod support.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user