#include "ns.h" // These are natives directly from NS2AMX static cell AMX_NATIVE_CALL ns_has_weapon(AMX *amx,cell *params) { CHECK_ENTITY(params[1]); edict_t *pEntity = NULL; pEntity = INDEXENT2(params[1]); if (params[3] == -1) { if ((pEntity->v.weapons & (1< 0) { return 1; } } else { if ((pEntity->v.weapons & (1< 0) { if (params[3] == 0) { pEntity->v.weapons &= ~(1<v.weapons |= (1< 0) { if (FStrEq("team_advarmory",buildtype) || FStrEq("team_advturretfactory",buildtype)) { iCount++; } else { if (pBuild->v.fuser1 >= 1000 || pBuild->v.iuser4 & MASK_ELECTRICITY) { iCount++; } } } else { iCount++; } if (iNumber > 0 && iCount == iNumber) return ENTINDEX(pBuild); } return iCount++; } static cell AMX_NATIVE_CALL ns_get_speedchange(AMX *amx, cell *params) { // Params: get_speedchange(index) int index=params[1]; if (!(index>0 && index<=gpGlobals->maxClients)) return 0; CPlayer *player = GET_PLAYER_I(params[1]); return player->speedchange; } static cell AMX_NATIVE_CALL ns_set_speedchange(AMX *amx, cell *params) { // Params: set_speedchange(index,speedchange=0) if (!(params[1]>0&¶ms[1]<=32)) return 0; CPlayer *player = GET_PLAYER_I(params[1]); player->speedchange=params[2]; return 1; } static cell AMX_NATIVE_CALL ns_get_maxspeed(AMX *amx, cell *params) { // Params: get_maxspeed(index) (returns the max speed of the player BEFORE speed change is factored in.) if (!(params[1]>0 && params[1]<=32)) return 0; CPlayer *player = GET_PLAYER_I(params[1]); return player->maxspeed; } static cell AMX_NATIVE_CALL ns_set_player_model(AMX *amx, cell *params) { // Params: set_player_model(id,szModel[]) if (!(params[1] > 0 && params[1] <= gpGlobals->maxClients)) { MF_LogError(amx, AMX_ERR_NATIVE, "Can't set player model for a non-player entity"); return 0; } int len; char *temp = MF_GetAmxString(amx,params[2],0,&len); CPlayer *player = GET_PLAYER_I(params[1]); if (!FStrEq(temp,"")) { PRECACHE_MODEL(temp); snprintf(player->model,127,"%s",temp); player->custommodel=true; } else player->custommodel=false; return 1; } static cell AMX_NATIVE_CALL ns_set_player_skin(AMX *amx, cell *params) { // Params: set_player_skin(id,skin=-1) if (!(params[1] > 0 && params[1] <= gpGlobals->maxClients)) { MF_LogError(amx, AMX_ERR_NATIVE, "Can't set player skin for a non-player entity"); return 0; } CPlayer *player = GET_PLAYER_I(params[1]); if (params[2] < 0) { // Reset skin. player->skin=0; player->customskin=false; } else { player->customskin=true; player->skin=params[2]; } return 1; } static cell AMX_NATIVE_CALL ns_set_player_body(AMX *amx, cell *params) { // Params: set_player_body(id,body=-1) if (!(params[1] > 0 && params[1] <= gpGlobals->maxClients)) { MF_LogError(amx, AMX_ERR_NATIVE, "Can't set player body for a non-player entity"); return 0; } CPlayer *player = GET_PLAYER_I(params[1]); if (params[2] < 0) { // Reset body. player->body=0; player->custombody=false; } else { player->custombody=true; player->body=params[2]; } return 1; } static cell AMX_NATIVE_CALL ns_get_class(AMX *amx, cell *params) { if (params[1] < 1 || params[1] > gpGlobals->maxClients) return 0; CPlayer *player = GET_PLAYER_I(params[1]); return player->GetClass(); } static cell AMX_NATIVE_CALL ns_get_jpfuel(AMX *amx, cell *params) { if (params[1] < 1 || params[1] > gpGlobals->maxClients) return 0; CPlayer *player = GET_PLAYER_I(params[1]); return FLOAT_TO_CELL(player->pev->fuser3 / 10.0); } static cell AMX_NATIVE_CALL ns_set_jpfuel(AMX *amx, cell *params) { if (params[1] < 1 || params[1] > gpGlobals->maxClients) return 0; CPlayer *player = GET_PLAYER_I(params[1]); REAL fuel = CELL_TO_FLOAT(params[2]); if (fuel > 100.0) fuel = 100.0; if (fuel < 0.0) fuel = 0.0; player->pev->fuser3 = fuel * 10.0; return 1; } static cell AMX_NATIVE_CALL ns_is_combat(AMX *amx, cell *params) { return iscombat; } static cell AMX_NATIVE_CALL ns_get_mask(AMX *amx, cell *params) { int id = params[1]; if (id < 1 || id > gpGlobals->maxEntities) return -1; edict_t *pEntity = INDEXENT2(params[1]); if (pEntity->v.iuser4 & params[2]) return 1; return 0; } static cell AMX_NATIVE_CALL ns_set_mask(AMX *amx, cell *params) { int id = params[1]; if (id < 1 || id > gpGlobals->maxEntities) return -1; edict_t *pEntity = INDEXENT2(params[1]); if (params[3] > 0) { if (pEntity->v.iuser4 & params[2]) return 0; pEntity->v.iuser4 |= params[2]; return 1; } if (pEntity->v.iuser4 & params[2]) { pEntity->v.iuser4 &= ~params[2]; return 1; } return 0; } static cell AMX_NATIVE_CALL ns_popup(AMX *amx, cell *params) { if (!gmsgHudText2) gmsgHudText2 = GET_USER_MSG_ID(PLID, "HudText2", NULL); if (params[1]) { if (params[1] > gpGlobals->maxClients) return 0; CPlayer *player = GET_PLAYER_I(params[1]); MESSAGE_BEGIN(MSG_ONE,gmsgHudText2,NULL,player->edict); } else MESSAGE_BEGIN(MSG_ALL,gmsgHudText2); int len; char *blah = MF_GetAmxString(amx,params[2],0,&len); char msg[190]; strncpy(msg,blah,188); WRITE_STRING(msg); WRITE_BYTE(params[3]); MESSAGE_END(); return 1; } static cell AMX_NATIVE_CALL ns_set_fov(AMX *amx, cell *params) { if (params[1] < 1 || params[1] > gpGlobals->maxClients) return 0; CPlayer *player = GET_PLAYER_I(params[1]); REAL fov = CELL_TO_FLOAT(params[2]); LOG_CONSOLE(PLID,"Got fov. fov=%f",fov); int gmsgSetFov = GET_USER_MSG_ID(PLID, "SetFOV", NULL); if (fov == 0.0) { player->foved=false; player->fov=0.0; MESSAGE_BEGIN(MSG_ONE,gmsgSetFov,NULL,player->edict); WRITE_BYTE(0); MESSAGE_END(); return 1; } if (fov > 0) { player->foved=true; player->fov=fov; MESSAGE_BEGIN(MSG_ONE,gmsgSetFov,NULL,player->edict); WRITE_BYTE((int)fov); MESSAGE_END(); return 1; } return 0; } static cell AMX_NATIVE_CALL ns_giveitem(AMX *amx, cell *params) { int index=params[1]; int len; char *classname = MF_GetAmxString(amx,params[2],0,&len); if (index<1 || index>gpGlobals->maxClients) return 0; edict_t *player=INDEXENT2(index); if (player->v.deadflag > 0) return 0; edict_t *object=CREATE_NAMED_ENTITY(ALLOC_STRING(classname)); //create if (!object) { MF_LogError(amx, AMX_ERR_NATIVE, "Error creating entity \"%s\"", classname); return 0; } SET_ORIGIN(object,player->v.origin); // move to player gpGamedllFuncs->dllapi_table->pfnSpawn(object); // emulate spawn object->v.flags |= FL_ONGROUND; // make it think it's touched the ground gpGamedllFuncs->dllapi_table->pfnThink(object); // gpGamedllFuncs->dllapi_table->pfnTouch(object,player); // give it to the player return 1; } static cell AMX_NATIVE_CALL ns_user_kill(AMX *amx, cell *params) { int index = params[1]; if (index<1||index>gpGlobals->maxClients) return 0; edict_t *e=INDEXENT2(index); if (e->v.iuser3 == 2 /* Commander class*/) return 0; if (MF_IsPlayerIngame(index) && MF_IsPlayerAlive(index)) { float bef = e->v.frags; edict_t *pEntity = CREATE_NAMED_ENTITY(MAKE_STRING("trigger_hurt")); if (pEntity) { KeyValueData kvd; kvd.szClassName="trigger_hurt"; kvd.szKeyName="classname"; kvd.szValue="trigger_hurt"; kvd.fHandled=0; MDLL_KeyValue(pEntity,&kvd); kvd.szClassName="trigger_hurt"; kvd.szKeyName="dmg"; kvd.szValue="20000.0"; kvd.fHandled=0; MDLL_KeyValue(pEntity,&kvd); kvd.szClassName="trigger_hurt"; kvd.szKeyName="damagetype"; kvd.szValue="1"; kvd.fHandled=0; MDLL_KeyValue(pEntity,&kvd); kvd.szClassName="trigger_hurt"; kvd.szKeyName="origin"; kvd.szValue="8192 8192 8192"; kvd.fHandled=0; MDLL_KeyValue(pEntity,&kvd); MDLL_Spawn(pEntity); pEntity->v.classname=MAKE_STRING("slay"); MDLL_Touch(pEntity,e); REMOVE_ENTITY(pEntity); } if (params[2]) e->v.frags = bef; return 1; } return 0; } #define ANGLEVECTORS (*g_engfuncs.pfnAngleVectors) static cell AMX_NATIVE_CALL ns_user_slap(AMX *amx, cell *params) /* 2 param */ { int index = params[1]; if (index<1||index>gpGlobals->maxClients) return 0; int power = abs((int)params[2]); edict_t *e=INDEXENT2(index); if (e->v.iuser3 == 2 /* Commander class*/) return 0; if (MF_IsPlayerIngame(index) && MF_IsPlayerAlive(index)) { if (e->v.health <= power) { float bef = e->v.frags; /*MDLL_ClientKill(pPlayer->pEdict);*/ edict_t *pEntity = CREATE_NAMED_ENTITY(MAKE_STRING("trigger_hurt")); if (pEntity) { KeyValueData kvd; kvd.szClassName="trigger_hurt"; kvd.szKeyName="classname"; kvd.szValue="trigger_hurt"; kvd.fHandled=0; MDLL_KeyValue(pEntity,&kvd); kvd.szClassName="trigger_hurt"; kvd.szKeyName="dmg"; kvd.szValue="20000.0"; kvd.fHandled=0; MDLL_KeyValue(pEntity,&kvd); kvd.szClassName="trigger_hurt"; kvd.szKeyName="damagetype"; kvd.szValue="1"; kvd.fHandled=0; MDLL_KeyValue(pEntity,&kvd); kvd.szClassName="trigger_hurt"; kvd.szKeyName="origin"; kvd.szValue="8192 8192 8192"; kvd.fHandled=0; MDLL_KeyValue(pEntity,&kvd); MDLL_Spawn(pEntity); pEntity->v.classname=MAKE_STRING("slap"); MDLL_Touch(pEntity,e); REMOVE_ENTITY(pEntity); } e->v.frags = bef; } else { edict_t *pEdict = e; int numparam = *params/sizeof(cell); if (numparam<3 || params[3]) { pEdict->v.velocity.x += RANDOM_LONG(-600,600); pEdict->v.velocity.y += RANDOM_LONG(-180,180); pEdict->v.velocity.z += RANDOM_LONG(100,200); } else { vec3_t v_forward, v_right; vec3_t vang = pEdict->v.angles; float fang[3]; fang[0] = vang.x; fang[1] = vang.y; fang[2] = vang.z; ANGLEVECTORS( fang, v_forward, v_right, NULL ); pEdict->v.velocity = pEdict->v.velocity + v_forward * 220 + Vector(0,0,200); } pEdict->v.punchangle.x = RANDOM_LONG(-10,10); pEdict->v.punchangle.y = RANDOM_LONG(-10,10); pEdict->v.health -= power; int armor = (int)pEdict->v.armorvalue; armor -= power; if (armor < 0) armor = 0; pEdict->v.armorvalue = armor; pEdict->v.dmg_inflictor = pEdict; static const char *bit_sound[3] = { "weapons/cbar_hitbod1.wav", "weapons/cbar_hitbod2.wav", "weapons/cbar_hitbod3.wav" }; EMIT_SOUND_DYN2(pEdict, CHAN_VOICE, bit_sound[RANDOM_LONG(0,2)], 1.0, ATTN_NORM, 0, PITCH_NORM); } return 1; } return 0; } AMX_NATIVE_INFO ns_misc_natives[] = { /////////////////// { "user_kill", ns_user_kill }, { "user_slap", ns_user_slap }, { "ns_get_build", ns_get_build }, { "ns_set_player_model", ns_set_player_model }, { "ns_set_player_skin", ns_set_player_skin }, { "ns_set_player_body", ns_set_player_body }, { "ns_has_weapon", ns_has_weapon }, { "ns_get_spawn", ns_get_spawnpoints }, { "ns_get_speedchange", ns_get_speedchange }, { "ns_set_speedchange", ns_set_speedchange }, { "ns_get_maxspeed", ns_get_maxspeed }, { "ns_get_class", ns_get_class }, { "ns_get_jpfuel", ns_get_jpfuel }, { "ns_set_jpfuel", ns_set_jpfuel }, { "ns_get_energy", ns_get_jpfuel }, // They do the same thing... { "ns_set_energy", ns_set_jpfuel }, // { "ns_is_combat", ns_is_combat }, { "ns_get_mask", ns_get_mask }, { "ns_set_mask", ns_set_mask }, { "ns_popup", ns_popup }, { "ns_set_fov", ns_set_fov }, { "ns_give_item", ns_giveitem }, /////////////////// { NULL, NULL } };