CBaseEntity *GiveNamedItemInternal(AMX *amx, CBasePlayer *pPlayer, const char *pszItemName, const size_t uid) { edict_t *pEdict = CREATE_NAMED_ENTITY(ALLOC_STRING(pszItemName)); if (FNullEnt(pEdict)) { AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: Item \"%s\" failed to create!\n", __FUNCTION__, pszItemName); return nullptr; } pEdict->v.origin = pPlayer->pev->origin; pEdict->v.spawnflags |= SF_NORESPAWN; // In some cases, we must to sets unique id // for the entity before it will triggered a spawn. pEdict->v.impulse = uid; MDLL_Spawn(pEdict); MDLL_Touch(pEdict, ENT(pPlayer->pev)); CBaseEntity *pEntity = getPrivate<CBaseEntity>(pEdict); // not allow the item to fall to the ground. if (FNullEnt(pEntity->pev->owner) || pEntity->pev->owner != pPlayer->edict()) { pEntity->pev->targetname = iStringNull; pEntity->pev->flags |= FL_KILLME; return nullptr; } return pEntity; }
void Bot::Kill (void) { // this function kills a bot (not just using ClientKill, but like the CSBot does) // base code courtesy of Lazy (from bots-united forums!) edict_t *hurtEntity = (*g_engfuncs.pfnCreateNamedEntity) (MAKE_STRING ("trigger_hurt")); if (FNullEnt (hurtEntity)) return; hurtEntity->v.classname = MAKE_STRING (g_weaponDefs[m_currentWeapon].className); hurtEntity->v.dmg_inflictor = GetEntity (); hurtEntity->v.dmg = 9999.0f; hurtEntity->v.dmg_take = 1.0f; hurtEntity->v.dmgtime = 2.0f; hurtEntity->v.effects |= EF_NODRAW; (*g_engfuncs.pfnSetOrigin) (hurtEntity, Vector (-4000, -4000, -4000)); KeyValueData kv; kv.szClassName = const_cast <char *> (g_weaponDefs[m_currentWeapon].className); kv.szKeyName = "damagetype"; kv.szValue = FormatBuffer ("%d", (1 << 4)); kv.fHandled = false; MDLL_KeyValue (hurtEntity, &kv); MDLL_Spawn (hurtEntity); MDLL_Touch (hurtEntity, GetEntity ()); (*g_engfuncs.pfnRemoveEntity) (hurtEntity); }
//shamelessly pulled from fun static cell AMX_NATIVE_CALL csdm_give_item(AMX *amx, cell *params) // native give_item(index, const item[]); = 2 params { // Check index. if (params[1] < 1 || params[1] > gpGlobals->maxClients) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid player %d", params[1]); return 0; } else if (!MF_IsPlayerIngame(params[1])) { MF_LogError(amx, AMX_ERR_NATIVE, "Player %d is not in game", params[1]); return 0; } // Get player pointer. edict_t *pPlayer = MF_GetPlayerEdict(params[1]); // Create item entity pointer edict_t *pItemEntity; // Make an "intstring" out of 2nd parameter int length; const char *szItem = MF_GetAmxString(amx, params[2], 1, &length); //check for valid item if (strncmp(szItem, "weapon_", 7) && strncmp(szItem, "ammo_", 5) && strncmp(szItem, "item_", 5) && strncmp(szItem, "tf_weapon_", 10) ) { return 0; } string_t item = ALLOC_STRING(szItem); // Using MAKE_STRING makes "item" contents get lost when we leave this scope! ALLOC_STRING seems to allocate properly... pItemEntity = CREATE_NAMED_ENTITY(item); if (FNullEnt(pItemEntity)) { MF_LogError(amx, AMX_ERR_NATIVE, "Item \"%s\" failed to create", szItem); return 0; } pItemEntity->v.origin = pPlayer->v.origin; pItemEntity->v.spawnflags |= (1 << 30); //SF_NORESPAWN; MDLL_Spawn(pItemEntity); int save = pItemEntity->v.solid; MDLL_Touch(pItemEntity, ENT(pPlayer)); if (pItemEntity->v.solid == save) { REMOVE_ENTITY(pItemEntity); //the function did not fail - we're just deleting the item return -1; } return ENTINDEX(pItemEntity); }
/* create new model entity */ void editorBrush::newModel() { model = CREATE_NAMED_ENTITY(ALLOC_STRING(BRUSH_CLASSNAME)); SET_MODEL(model,BRUSH_MODELNAME); model->v.origin = mins; Vector size = (maxs-mins)/4; for(int i = 0; i < 3; i++) { model->v.controller[i] = size[i]; } model->v.skin = g_textures->getSkin(faces[0].texture); //faces[0]->texture should do the trick MDLL_Spawn(model); }
static cell AMX_NATIVE_CALL DispatchSpawn(AMX *amx, cell *params) { int iEnt = params[1]; CHECK_ENTITY(iEnt); edict_t *pEnt = INDEXENT2(iEnt); MDLL_Spawn(pEnt); return 1; }
static cell AMX_NATIVE_CALL spawn(AMX *amx, cell *params) // spawn(id) = 1 param { // Spawns an entity, this can be a user/player -> spawns at spawnpoints, or created entities seems to need this as a final "kick" into the game? :-) // params[1] = entity to spawn CHECK_ENTITY(params[1]); edict_t *pEnt = GETEDICT(params[1]); MDLL_Spawn(pEnt); return 1; }
static cell AMX_NATIVE_CALL ns_spawn_ps(AMX *amx, cell *params) { if (params[1]==0) { MF_LogError(amx, AMX_ERR_NATIVE, "Invalid particle system handle"); return 0; } edict_t *Ent=reinterpret_cast<edict_t *>(params[1]); MDLL_Spawn(Ent); if (!Ent->free) { REMOVE_ENTITY(Ent); } return ParticleMan.Add(STRING(Ent->v.targetname),0); }
// SidLuke static cell AMX_NATIVE_CALL strip_user_weapons(AMX *amx, cell *params) // index { CHECK_PLAYER(params[1]); edict_t* pPlayer = MF_GetPlayerEdict(params[1]); string_t item = MAKE_STRING("player_weaponstrip"); edict_t *pent = CREATE_NAMED_ENTITY(item); if (FNullEnt(pent)) { return 0; } MDLL_Spawn(pent); MDLL_Use(pent, pPlayer); REMOVE_ENTITY(pent); *reinterpret_cast<int *>(MF_PlayerPropAddr(params[1], Player_CurrentWeapon)) = 0; return 1; }
static cell AMX_NATIVE_CALL give_item(AMX *amx, cell *params) // native give_item(index, const item[]); = 2 params { /* Gives item to player, name of item can start * with weapon_, ammo_ and item_. This event * is announced with proper message to all players. */ // params[1] = index // params[2] = item... // Check index. CHECK_PLAYER(params[1]); // Get player pointer. edict_t *pPlayer = MF_GetPlayerEdict(params[1]); // Create item entity pointer edict_t *pItemEntity; // Make an "intstring" out of 2nd parameter int length; const char *szItem = MF_GetAmxString(amx, params[2], 1, &length); //check for valid item if (strncmp(szItem, "weapon_", 7) && strncmp(szItem, "ammo_", 5) && strncmp(szItem, "item_", 5) && strncmp(szItem, "tf_weapon_", 10) ) { return 0; } //string_t item = MAKE_STRING(szItem); string_t item = ALLOC_STRING(szItem); // Using MAKE_STRING makes "item" contents get lost when we leave this scope! ALLOC_STRING seems to allocate properly... // Create the entity, returns to pointer pItemEntity = CREATE_NAMED_ENTITY(item); if (FNullEnt(pItemEntity)) { MF_LogError(amx, AMX_ERR_NATIVE, "Item \"%s\" failed to create", szItem); return 0; } //VARS(pItemEntity)->origin = VARS(pPlayer)->origin; // nice to do VARS(ent)->origin instead of ent->v.origin? :-I //I'm not sure, normally I use macros too =P pItemEntity->v.origin = pPlayer->v.origin; pItemEntity->v.spawnflags |= SF_NORESPAWN; //SF_NORESPAWN; MDLL_Spawn(pItemEntity); int save = pItemEntity->v.solid; MDLL_Touch(pItemEntity, ENT(pPlayer)); //The problem with the original give_item was the // item was not removed. I had tried this but it // did not work. OLO's implementation is better. /* int iEnt = ENTINDEX(pItemEntity->v.owner); if (iEnt > 32 || iEnt <1 ) { MDLL_Think(pItemEntity); }*/ if (pItemEntity->v.solid == save) { REMOVE_ENTITY(pItemEntity); //the function did not fail - we're just deleting the item return -1; } return ENTINDEX(pItemEntity); }