mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-25 14:25:38 +03:00
c71be87a3a
Oh dear, what has DS done now?
497 lines
12 KiB
C++
Executable File
497 lines
12 KiB
C++
Executable File
#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<<params[2])) > 0)
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((pEntity->v.weapons & (1<<params[2])) > 0)
|
|
{
|
|
if (params[3] == 0)
|
|
{
|
|
pEntity->v.weapons &= ~(1<<params[2]);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
if (params[3] == 1)
|
|
{
|
|
pEntity->v.weapons |= (1<<params[2]);
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
static cell AMX_NATIVE_CALL ns_get_spawnpoints(AMX *amx, cell *params)
|
|
{
|
|
vec3_t vRet;
|
|
if (params[2] == 0)
|
|
{
|
|
return (int)ns_spawnpoints.getnum(params[1]);
|
|
}
|
|
else
|
|
{
|
|
vRet=ns_spawnpoints.getpoint(params[1],params[2]);
|
|
cell *vCell = MF_GetAmxAddr(amx,params[3]);
|
|
vCell[0] = FLOAT_TO_CELL(vRet.x);
|
|
vCell[1] = FLOAT_TO_CELL(vRet.y);
|
|
vCell[2] = FLOAT_TO_CELL(vRet.z);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
#define MASK_ELECTRICITY 8192
|
|
static cell AMX_NATIVE_CALL ns_get_build(AMX *amx, cell *params)
|
|
{
|
|
int iLength;
|
|
char *buildtype = MF_GetAmxString(amx,params[1],0,&iLength);
|
|
int iBuiltOnly = params[2];
|
|
int iNumber = params[3];
|
|
edict_t* pBuild = NULL;
|
|
int iCount=0;
|
|
|
|
while ((pBuild = UTIL_FindEntityByString(pBuild,"classname",buildtype)) != NULL)
|
|
{
|
|
if (iBuiltOnly > 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 }
|
|
};
|