From 83e70d7dd7fbfca3b4e6e8aa9f7583932ec22e92 Mon Sep 17 00:00:00 2001 From: Vincent Herbet Date: Tue, 2 Jul 2013 20:48:18 +0200 Subject: [PATCH] Add [Get|Set]ModelCollisionBox and [Get|Set]ModelBoundingBox (bug 3527, r=joropito) Former-commit-id: 4d174007b14a9b6b8589f96a9259f3249db23799 --- dlls/fakemeta/misc.cpp | 171 ++++++++++++++++++++++++++++++++++- plugins/include/fakemeta.inc | 67 ++++++++++++++ 2 files changed, 237 insertions(+), 1 deletion(-) diff --git a/dlls/fakemeta/misc.cpp b/dlls/fakemeta/misc.cpp index 1bae3c71..c9399830 100644 --- a/dlls/fakemeta/misc.cpp +++ b/dlls/fakemeta/misc.cpp @@ -150,12 +150,181 @@ static cell AMX_NATIVE_CALL set_controller(AMX* amx, cell* params) return amx_ftoc(setting * (1.0 / 255.0) * (pbonecontroller->end - pbonecontroller->start) + pbonecontroller->start); } +enum +{ + Model_DefaultSize = -2, + Model_CurrentSequence = -1, +}; +// GetModelCollisionBox( index, Float:mins[3], Float:maxs[3] ); +static cell AMX_NATIVE_CALL GetModelCollisionBox(AMX *amx, cell *params) +{ + int entityIndex = params[1]; + + CHECK_ENTITY(entityIndex); + + edict_t *pEdict = INDEXENT2(entityIndex); + + if (!FNullEnt(pEdict)) + { + studiohdr_t *pStudiohdr = static_cast(GET_MODEL_PTR(pEdict)); + + if (!pStudiohdr) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Could not find the model pointer for the entity."); + return 0; + } + + cell *cmins = MF_GetAmxAddr(amx, params[2]); + cell *cmaxs = MF_GetAmxAddr(amx, params[3]); + + cmins[0] = amx_ftoc(pStudiohdr->bbmin.x); + cmins[1] = amx_ftoc(pStudiohdr->bbmin.y); + cmins[2] = amx_ftoc(pStudiohdr->bbmin.z); + + cmaxs[0] = amx_ftoc(pStudiohdr->bbmax.x); + cmaxs[1] = amx_ftoc(pStudiohdr->bbmax.y); + cmaxs[2] = amx_ftoc(pStudiohdr->bbmax.z); + + return 1; + } + + return 0; +}; + +// GetModelBoundingBox( index, Float:mins[3], Float:maxs[3], sequence = Model_DefaultSize ); +static cell AMX_NATIVE_CALL GetModelBoundingBox(AMX *amx, cell *params) +{ + int entityIndex = params[1]; + + CHECK_ENTITY(entityIndex); + + edict_t *pentModel = INDEXENT2(entityIndex); + + if (!FNullEnt(pentModel)) + { + studiohdr_t *pStudiohdr = static_cast(GET_MODEL_PTR(pentModel)); + + if (!pStudiohdr) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Could not find the model pointer for the entity."); + return 0; + } + + cell *bbmins = MF_GetAmxAddr(amx, params[2]); + cell *bbmaxs = MF_GetAmxAddr(amx, params[3]); + + int sequence = params[4]; + + if (sequence <= Model_DefaultSize) + { + bbmins[0] = amx_ftoc(pStudiohdr->min.x); + bbmins[1] = amx_ftoc(pStudiohdr->min.y); + bbmins[2] = amx_ftoc(pStudiohdr->min.z); + + bbmaxs[0] = amx_ftoc(pStudiohdr->max.x); + bbmaxs[1] = amx_ftoc(pStudiohdr->max.y); + bbmaxs[2] = amx_ftoc(pStudiohdr->max.z); + } + else + { + if (sequence <= Model_CurrentSequence || sequence >= pStudiohdr->numseq) + sequence = pentModel->v.sequence; + + mstudioseqdesc_t *pSeqdesc; + pSeqdesc = (mstudioseqdesc_t*)((byte*)pStudiohdr + pStudiohdr->seqindex); + + bbmins[0] = amx_ftoc(pSeqdesc[sequence].bbmin.x); + bbmins[1] = amx_ftoc(pSeqdesc[sequence].bbmin.y); + bbmins[2] = amx_ftoc(pSeqdesc[sequence].bbmin.z); + + bbmaxs[0] = amx_ftoc(pSeqdesc[sequence].bbmax.x); + bbmaxs[1] = amx_ftoc(pSeqdesc[sequence].bbmax.y); + bbmaxs[2] = amx_ftoc(pSeqdesc[sequence].bbmax.z); + } + + return 1; + } + + return 0; +}; + +// SetModelCollisionBox( index ); +static cell AMX_NATIVE_CALL SetModelCollisionBox(AMX *amx, cell *params) +{ + int entityIndex = params[1]; + + CHECK_ENTITY(entityIndex); + + edict_t *pentModel = INDEXENT2(entityIndex); + + if (!FNullEnt(pentModel)) + { + studiohdr_t *pStudiohdr = static_cast(GET_MODEL_PTR(pentModel)); + + if (!pStudiohdr) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Could not find the model pointer for the entity."); + return 0; + } + + SET_SIZE(pentModel, pStudiohdr->bbmin, pStudiohdr->bbmax); + + return 1; + } + + return 0; +}; + +// SetModelBoudingBox( index, sequence = Model_DefaultSize ); +static cell AMX_NATIVE_CALL SetModelBoundingBox(AMX *amx, cell *params) +{ + int entityIndex = params[1]; + + CHECK_ENTITY(entityIndex); + + edict_t *pentModel = INDEXENT2(entityIndex); + + if (!FNullEnt(pentModel)) + { + studiohdr_t *pStudiohdr = static_cast(GET_MODEL_PTR(pentModel)); + + if (!pStudiohdr) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Could not find the model pointer for the entity."); + return 0; + } + + int sequence = params[2]; + + if (sequence <= Model_DefaultSize) + { + SET_SIZE(pentModel, pStudiohdr->min, pStudiohdr->max); + } + else + { + if (sequence <= Model_CurrentSequence || sequence >= pStudiohdr->numseq) + sequence = pentModel->v.sequence; + + mstudioseqdesc_t *pSeqdesc; + pSeqdesc = (mstudioseqdesc_t*)((byte*)pStudiohdr + pStudiohdr->seqindex); + + SET_SIZE(pentModel, pSeqdesc[sequence].bbmin, pSeqdesc[sequence].bbmax); + + return 1; + } + } + + return 0; +} AMX_NATIVE_INFO misc_natives[] = { { "copy_infokey_buffer", copy_infokey_buffer }, { "lookup_sequence", lookup_sequence }, { "set_controller", set_controller }, - + { "GetModelCollisionBox", GetModelCollisionBox }, + { "SetModelCollisionBox", SetModelCollisionBox }, + { "GetModelBoundingBox", GetModelBoundingBox }, + { "SetModelBoundingBox", SetModelBoundingBox }, {NULL, NULL}, }; diff --git a/plugins/include/fakemeta.inc b/plugins/include/fakemeta.inc index c9d22e89..e161ce49 100755 --- a/plugins/include/fakemeta.inc +++ b/plugins/include/fakemeta.inc @@ -536,3 +536,70 @@ native lookup_sequence(entity, const name[], &Float:framerate = 0.0, &bool:loops * @return The percentage that the controller is extended (0.0 through 1.0) */ native Float:set_controller(entity, controller, Float:value); + + +enum +{ + Model_DefaultSize = -2, + Model_CurrentSequence = -1, +}; + +/** + * Gets size of the entity models collision box. + * + * @param entity The entity index to use. + * @param mins The local negative collision box distance. + * @param maxs The local positive collision box distance. + * + * @return 1 on success, 0 on faillure. + * + * @error Invalid entity. + * Invalid model pointer. + */ +native GetModelCollisionBox( entity, Float:mins[3], Float:maxs[3] ); + +/** + * Sets entity size to the models collision box. + * + * @param entity The entity index to set the value on. + * + * @return 1 on success, 0 on faillure. + * + * @error Invalid entity. + * Invalid model pointer. + */ +native SetModelCollisionBox( entity ); + +/** + * Gets size of a model bounding box. + * + * @param entity The entity index to use. + * @param mins The local negative bounding box distance. + * @param maxs The local positive bounding box distance. + * @param sequence The animation sequence to retrieve. + * Model_DefaultSize retrieves ideal moevement hull size. + * Model_CurrentSequence retrieves hull size of the current sequence. + * Values >= 0 will specify which sequence to retrieve size from. + * + * @return 1 on success, 0 on faillure. + * + * @error Invalid entity. + * Invalid model pointer. + */ +native GetModelBoundingBox( entity, Float:mins[3], Float:maxs[3], sequence = Model_DefaultSize ); + +/** + * Sets size to a model bounding box. + * + * @param entity The entity index to set the value on. + * @param sequence The sequence to apply. + * Model_DefaultSize sets size of ideal movement hull. + * Model_CurrentSequence sets size of the current sequence. + * Values >= 0 will specify which sequence to use. + * + * @return 1 on success, 0 on faillure. + * + * @error Invalid entity. + * Invalid model pointer. + */ +native SetModelBoundingBox( index, sequence = Model_DefaultSize );