.agents/skills/amxx-modding-kit/api/entity-grab/SKILL.md
Helps with Entity Grab API usage for attaching, carrying, and throwing entities.
npx skillsauth add hedgefog/amxx-modding-kit amxx-modding-kit-api-entity-grabInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
api_entity_grab)The Entity Grab API provides a system for attaching entities to players, enabling "grab and carry" mechanics with automatic movement and collision handling.
Reference: See README.md for complete documentation and examples.
This API allows you to:
// Attach entity at specified distance from player
EntityGrab_Player_AttachEntity(pPlayer, pEntity, flDistance);
Parameters:
pPlayer: The player indexpEntity: The entity to grabflDistance: Distance in units from player to hold the entity// Release the currently grabbed entity
EntityGrab_Player_DetachEntity(pPlayer);
// Get entity currently attached to player
new pGrabbedEntity = EntityGrab_Player_GetAttachedEntity(pPlayer);
if (pGrabbedEntity != FM_NULLENT) {
// Player is holding something
}
#include <api_entity_grab>
new g_pTrace;
public plugin_precache() {
g_pTrace = create_tr2();
}
public plugin_end() {
free_tr2(g_pTrace);
}
@Player_FindEntityToGrab(const &pPlayer, Float:flRange) {
static Float:vecSrc[3]; ExecuteHamB(Ham_Player_GetGunPosition, pPlayer, vecSrc);
static Float:vecAngles[3]; pev(pPlayer, pev_v_angle, vecAngles);
static Float:vecEnd[3];
angle_vector(vecAngles, ANGLEVECTOR_FORWARD, vecEnd);
xs_vec_add_scaled(vecSrc, vecEnd, flRange, vecEnd);
engfunc(EngFunc_TraceLine, vecSrc, vecEnd, DONT_IGNORE_MONSTERS, pPlayer, g_pTrace);
static pHit; pHit = get_tr2(g_pTrace, TR_pHit);
// Try hull trace if line trace missed
if (pHit == FM_NULLENT) {
engfunc(EngFunc_TraceHull, vecSrc, vecEnd, DONT_IGNORE_MONSTERS, HULL_HEAD, pPlayer, g_pTrace);
pHit = get_tr2(g_pTrace, TR_pHit);
}
if (pHit == FM_NULLENT) return FM_NULLENT;
if (!IsGrabbableEntity(pHit)) return FM_NULLENT;
return pHit;
}
public HamHook_Player_PreThink(const pPlayer) {
if (!is_user_alive(pPlayer)) return HAM_IGNORED;
static iButtons; iButtons = pev(pPlayer, pev_button);
static iOldButtons; iOldButtons = pev(pPlayer, pev_oldbuttons);
// Toggle grab with USE key
if (iButtons & IN_USE && ~iOldButtons & IN_USE) {
static pGrabbed; pGrabbed = EntityGrab_Player_GetAttachedEntity(pPlayer);
if (pGrabbed == FM_NULLENT) {
// Try to grab entity in front of player
static pEntity; pEntity = @Player_FindEntityToGrab(pPlayer, 64.0);
if (pEntity != FM_NULLENT) {
EntityGrab_Player_AttachEntity(pPlayer, pEntity, 48.0);
}
} else {
// Release grabbed entity
EntityGrab_Player_DetachEntity(pPlayer);
}
}
return HAM_HANDLED;
}
ThrowGrabbedEntity(const pPlayer, Float:flThrowForce) {
new pEntity = EntityGrab_Player_GetAttachedEntity(pPlayer);
if (pEntity == FM_NULLENT) return;
// Calculate throw direction
static Float:vecVelocity[3]; pev(pPlayer, pev_velocity, vecVelocity);
static Float:vecDirection[3]; pev(pPlayer, pev_v_angle, vecDirection);
angle_vector(vecDirection, ANGLEVECTOR_FORWARD, vecDirection);
// Add player velocity + throw force
xs_vec_add_scaled(vecVelocity, vecDirection, flThrowForce, vecVelocity);
// Detach and apply velocity
EntityGrab_Player_DetachEntity(pPlayer);
set_pev(pEntity, pev_velocity, vecVelocity);
}
// Usage in PreThink
if (iButtons & IN_ATTACK && ~iOldButtons & IN_ATTACK) {
ThrowGrabbedEntity(pPlayer, 500.0);
}
bool:IsGrabbableEntity(const pEntity) {
if (pEntity == FM_NULLENT) return false;
if (IS_PLAYER(pEntity)) return false;
// Check solid type
if (pev(pEntity, pev_solid) < SOLID_BBOX) return false;
// Check classname for allowed types
static szClassname[32]; pev(pEntity, pev_classname, szClassname, charsmax(szClassname));
if (equal(szClassname, "prop")) return true;
if (equal(szClassname, "item_crate")) return true;
return false;
}
// Scroll wheel to adjust distance
if (iButtons & IN_FORWARD) {
new pEntity = EntityGrab_Player_GetAttachedEntity(pPlayer);
if (pEntity != FM_NULLENT) {
// Re-attach with new distance
EntityGrab_Player_DetachEntity(pPlayer);
EntityGrab_Player_AttachEntity(pPlayer, pEntity, flNewDistance);
}
}
// In custom entity plugin
@Entity_CanPickup(const this, const pPlayer) {
// Prevent pickup while grabbed
if (EntityGrab_Player_GetAttachedEntity(pPlayer) != FM_NULLENT) {
return false;
}
return CE_CallBaseMethod(pPlayer);
}
plugin_precacheplugin_endFM_NULLENT before operationstools
Best practices for organizing large AMX Mod X projects with multiple plugins sharing entities, weapons, events, and other definitions. Use when creating mod-scale projects that need consistent namespace patterns and shared constants.
development
Guide for Waypoint Markers API creating 3D waypoint sprites visible through walls with per-player visibility.
development
Guide for States API usage implementing state machines with transitions, guards, and lifecycle hooks.
development
Guide for Shops API usage creating in-game shops with items, custom balance systems, and access control.