2
0
mirror of https://github.com/rehlds/reapi.git synced 2024-12-29 08:05:36 +03:00

Add natives GetAttachment, GetBonePosition

This commit is contained in:
s1lent 2017-10-02 21:29:56 +07:00
parent 23fe1507a1
commit 69669ef6ce
No known key found for this signature in database
GPG Key ID: 0FE401DC73916B5C
8 changed files with 238 additions and 11 deletions

View File

@ -653,6 +653,8 @@
#define FCAP_ONOFF_USE 0x00000020 // Can be used by the player
#define FCAP_DIRECTIONAL_USE 0x00000040 // Player sends +/- 1 when using (currently only tracktrains)
#define FCAP_MASTER 0x00000080 // Can be used to "master" other entities (like multisource)
#define FCAP_MUST_RESET 0x00000100 // Should reset on the new round
#define FCAP_MUST_RELEASE 0x00000200 // Should release on the new round
#define FCAP_DONT_SAVE 0x80000000 // Don't save this
// UNDONE: This will ignore transition volumes (trigger_transition), but not the PVS!!!
@ -713,7 +715,18 @@ enum ArmouryItemPack
ARMOURY_HEGRENADE,
ARMOURY_KEVLAR,
ARMOURY_ASSAULT,
ARMOURY_SMOKEGRENADE
ARMOURY_SMOKEGRENADE,
ARMOURY_SHIELD,
ARMOURY_FAMAS,
ARMOURY_SG550,
ARMOURY_GALIL,
ARMOURY_UMP45,
ARMOURY_GLOCK18,
ARMOURY_USP,
ARMOURY_ELITE,
ARMOURY_FIVESEVEN,
ARMOURY_P228,
ARMOURY_DEAGLE,
};
enum RewardType

View File

@ -55,6 +55,34 @@ native get_key_value(const pbuffer, const key[], const value[], const maxlen);
*/
native set_key_value(const pbuffer, const key[], const value[]);
/*
* Gets the position of the bone
*
* @param entity Entity index
* @param bone Number of the bone
* @param vecOrigin Array to store origin in
* @param vecAngles Array to store angles in
*
* @return 1 on success, 0 otherwise
* @error If the index is not within the range of 1 to maxEntities or
* the entity is not valid, an error will be thrown.
*/
native GetBonePosition(const entity, const bone, Float:vecOrigin[3], Float:vecAngles[3] = {0.0, 0.0, 0.0});
/*
* Gets the position of the attachment
*
* @param entity Entity index
* @param attachment Number of the attachment
* @param vecOrigin Array to store origin in
* @param vecAngles Array to store angles in
*
* @return 1 on success, 0 otherwise
* @error If the index is not within the range of 1 to maxEntities or
* the entity is not valid, an error will be thrown.
*/
native GetAttachment(const entity, const attachment, Float:vecOrigin[3], Float:vecAngles[3] = {0.0, 0.0, 0.0});
/*
* Sets the name of the map.
*

View File

@ -181,14 +181,90 @@ cell AMX_NATIVE_CALL amx_set_key_value(AMX *amx, cell *params)
return TRUE;
}
/*
* Gets the position of the bone
*
* @param entity Entity index
* @param bone Number of the bone
* @param vecOrigin Array to store origin in
* @param vecAngles Array to store angles in
*
* @return 1 on success, 0 otherwise
* @error If the index is not within the range of 1 to maxEntities or
* the entity is not valid, an error will be thrown.
*
* native GetBonePosition(const entity, const bone, Float:vecOrigin[3], Float:vecAngles[3] = {0.0, 0.0, 0.0});
*/
cell AMX_NATIVE_CALL amx_GetBonePosition(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_bone, arg_origin, arg_angles };
CHECK_ISENTITY(arg_index);
CBaseEntity *pEntity = getPrivate<CBaseEntity>(params[arg_index]);
if (unlikely(pEntity == nullptr)) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid or uninitialized entity", __FUNCTION__);
return FALSE;
}
if (FNullEnt(params[arg_index])) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: worldspawn not allowed", __FUNCTION__);
return FALSE;
}
Vector *pVecOrigin = (Vector *)getAmxAddr(amx, params[arg_origin]);
Vector *pVecAngles = (PARAMS_COUNT == 4) ? (Vector *)getAmxAddr(amx, params[arg_angles]) : nullptr;
GetBonePosition(pEntity, params[arg_bone], pVecOrigin, pVecAngles);
return TRUE;
}
/*
* Gets the position of the attachment
*
* @param entity Entity index
* @param attachment Number of the attachment
* @param vecOrigin Array to store origin in
* @param vecAngles Array to store angles in
*
* @return 1 on success, 0 otherwise
* @error If the index is not within the range of 1 to maxEntities or
* the entity is not valid, an error will be thrown.
*
* native GetAttachment(const entity, const attachment, Float:vecOrigin[3], Float:vecAngles[3] = {0.0, 0.0, 0.0});
*/
cell AMX_NATIVE_CALL amx_GetAttachment(AMX *amx, cell *params)
{
enum args_e { arg_count, arg_index, arg_bone, arg_attachment, arg_angles };
CHECK_ISENTITY(arg_index);
CBaseEntity *pEntity = getPrivate<CBaseEntity>(params[arg_index]);
if (unlikely(pEntity == nullptr)) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: invalid or uninitialized entity", __FUNCTION__);
return FALSE;
}
if (FNullEnt(params[arg_index])) {
MF_LogError(amx, AMX_ERR_NATIVE, "%s: worldspawn not allowed", __FUNCTION__);
return FALSE;
}
Vector *pVecOrigin = (Vector *)getAmxAddr(amx, params[arg_attachment]);
Vector *pVecAngles = (PARAMS_COUNT == 4) ? (Vector *)getAmxAddr(amx, params[arg_angles]) : nullptr;
GetAttachment(pEntity, params[arg_bone], pVecOrigin, pVecAngles);
return TRUE;
}
AMX_NATIVE_INFO Natives_Common[] =
{
{ "FClassnameIs", amx_FClassnameIs },
{ "GetGrenadeType", amx_GetGrenadeType },
{ "engset_view", amx_engset_view },
{ "get_viewent", amx_get_viewent },
{ "get_key_value", amx_get_key_value },
{ "set_key_value", amx_set_key_value },
{ "FClassnameIs", amx_FClassnameIs },
{ "GetGrenadeType", amx_GetGrenadeType },
{ "engset_view", amx_engset_view },
{ "get_viewent", amx_get_viewent },
{ "get_key_value", amx_get_key_value },
{ "set_key_value", amx_set_key_value },
{ "GetBonePosition", amx_GetBonePosition },
{ "GetAttachment", amx_GetAttachment },
{ nullptr, nullptr }
};

View File

@ -618,7 +618,7 @@ void RegisterNatives_Members()
g_amxxapi.AddNatives(EngineVars_Natives);
}
BOOL set_member(void* pdata, const member_t *member, cell* value, size_t element)
cell set_member(void* pdata, const member_t *member, cell* value, size_t element)
{
switch (member->type) {
case MEMBER_CLASSPTR:
@ -674,7 +674,7 @@ BOOL set_member(void* pdata, const member_t *member, cell* value, size_t element
char *source = getAmxString(value);
string_t newstr = (source && source[0] != '\0') ? ALLOC_STRING(source) : iStringNull;
set_member<string_t>(pdata, member->offset, newstr, element);
return TRUE;
return (cell)newstr;
}
case MEMBER_FLOAT:
case MEMBER_INTEGER:
@ -806,7 +806,7 @@ cell get_member(void* pdata, const member_t *member, cell* dest, size_t element,
}
setAmxString(dest, STRING(str), length);
return 1;
return (cell)str;
}
case MEMBER_FLOAT:
case MEMBER_INTEGER:

View File

@ -2,7 +2,7 @@
void RegisterNatives_Members();
BOOL set_member(void* pdata, const member_t *member, cell* value, size_t element);
cell set_member(void* pdata, const member_t *member, cell* value, size_t element);
cell get_member(void* pdata, const member_t *member, cell* dest, size_t element, size_t length = 0);
bool isTypeReturnable(MType type);

View File

@ -26,6 +26,7 @@
#include <com_progdefs.h>
#include <gamerules.h>
#include <mapinfo.h>
#include <studio.h>
// metamod SDK
#include <meta_api.h>

View File

@ -92,3 +92,109 @@ CBaseEntity *GiveNamedItemInternal(AMX *amx, CBasePlayer *pPlayer, const char *p
return pEntity;
}
void StudioFrameAdvanceEnt(edict_t *pEdict)
{
float flInterval = gpGlobals->time - pEdict->v.animtime;
if (flInterval <= 0.001f) {
pEdict->v.animtime = gpGlobals->time;
return;
}
if (pEdict->v.animtime == 0.0f) {
flInterval = 0.0f;
}
studiohdr_t *pstudiohdr = static_cast<studiohdr_t *>(GET_MODEL_PTR(pEdict));
if (!pstudiohdr) {
return;
}
if (pEdict->v.sequence >= pstudiohdr->numseq || pEdict->v.sequence < 0) {
return;
}
float flFrameRate = 256.0f;
mstudioseqdesc_t *pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + int(pEdict->v.sequence);
if (pseqdesc->numframes > 1)
{
flFrameRate = pseqdesc->fps * 256.0f / (pseqdesc->numframes - 1);
}
pEdict->v.frame += flInterval * flFrameRate * pEdict->v.framerate;
pEdict->v.animtime = gpGlobals->time;
if (pEdict->v.frame < 0.0f || pEdict->v.frame >= 256.0f)
{
// true if the sequence loops
if (pseqdesc->flags & STUDIO_LOOPING)
pEdict->v.frame -= int(pEdict->v.frame / 256.0f) * 256.0f;
else
pEdict->v.frame = (pEdict->v.frame < 0.0f) ? 0.0f : 255.0f;
}
}
void FixupAngles(edict_t *pEdict, Vector &vecSrc)
{
vecSrc.x -= pEdict->v.origin.x;
vecSrc.y -= pEdict->v.origin.y;
float x = vecSrc.x;
float y = vecSrc.y;
float c = cos((pEdict->v.angles.y * M_PI / 180.0));
float s = sin((pEdict->v.angles.y * M_PI / 180.0));
vecSrc.x = x * c - y * s;
vecSrc.y = y * c + x * s;
vecSrc.x += pEdict->v.origin.x;
vecSrc.y += pEdict->v.origin.y;
}
void GetBonePosition(CBaseEntity *pEntity, int iBone, Vector *pVecOrigin, Vector *pVecAngles)
{
Vector vecOrigin, vecAngles;
edict_t *pEdict = pEntity->edict();
// force to update frame
StudioFrameAdvanceEnt(pEdict);
pEntity->pev->angles.x = -pEntity->pev->angles.x;
GET_BONE_POSITION(pEdict, iBone, vecOrigin, vecAngles);
pEntity->pev->angles.x = -pEntity->pev->angles.x;
if (!pEntity->IsPlayer()) {
FixupAngles(pEdict, vecOrigin);
}
if (pVecOrigin) {
*pVecOrigin = vecOrigin;
}
if (pVecAngles) {
*pVecAngles = vecAngles;
}
}
void GetAttachment(CBaseEntity *pEntity, int iBone, Vector *pVecOrigin, Vector *pVecAngles)
{
Vector vecOrigin, vecAngles;
edict_t *pEdict = pEntity->edict();
// force to update frame
StudioFrameAdvanceEnt(pEdict);
GET_ATTACHMENT(pEdict, iBone, vecOrigin, vecAngles);
if (!pEntity->IsPlayer()) {
FixupAngles(pEdict, vecOrigin);
}
if (pVecOrigin) {
*pVecOrigin = vecOrigin;
}
if (pVecAngles) {
*pVecAngles = vecAngles;
}
}

View File

@ -53,4 +53,7 @@ ModelName GetModelAuto(TeamName team);
void UTIL_ServerPrint(const char *fmt, ...);
CBaseEntity *GiveNamedItemInternal(AMX *amx, CBasePlayer *pPlayer, const char *pszItemName);
void GetBonePosition(CBaseEntity *pEntity, int iBone, Vector *vecOrigin, Vector *vecAngles);
void GetAttachment(CBaseEntity *pEntity, int iBone, Vector *pVecOrigin, Vector *pVecAngles);
extern void __declspec(noreturn) UTIL_SysError(const char *fmt, ...);