Merge of rewritten NS module into trunk
This commit is contained in:
553
dlls/ns/natives/general.cpp
Normal file
553
dlls/ns/natives/general.cpp
Normal file
@ -0,0 +1,553 @@
|
||||
/* AMX Mod X
|
||||
* Natural Selection Module
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
* This file is part of AMX Mod X.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../sdk/amxxmodule.h"
|
||||
|
||||
#include "cbase.h" // TakeDamage
|
||||
|
||||
#include "../ns.h"
|
||||
|
||||
#include "../utilfunctions.h"
|
||||
#include "../NEW_Util.h"
|
||||
|
||||
#include "../GameManager.h"
|
||||
#include "../SpawnManager.h"
|
||||
#include "../LocationManager.h"
|
||||
#include "../TitleManager.h"
|
||||
|
||||
#include "../CPlayer.h"
|
||||
|
||||
|
||||
edict_t* avhgameplay=NULL;
|
||||
|
||||
// drop-in replacement for user_kill
|
||||
static cell AMX_NATIVE_CALL ns_user_kill(AMX *amx, cell *params)
|
||||
{
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
// 2 is commander, never slay commander
|
||||
if (player->GetPev()->iuser3 == 2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (MF_IsPlayerIngame(params[1]) && MF_IsPlayerAlive(params[1]))
|
||||
{
|
||||
REAL bef = player->GetPev()->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="50000.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,player->GetEdict());
|
||||
|
||||
REMOVE_ENTITY(pEntity);
|
||||
}
|
||||
|
||||
// If the optional parameter is 1, restore the frag count
|
||||
if (params[2])
|
||||
{
|
||||
player->GetPev()->frags = bef;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
// drop-in replacement for user_slap
|
||||
#define ANGLEVECTORS (*g_engfuncs.pfnAngleVectors)
|
||||
static cell AMX_NATIVE_CALL ns_user_slap(AMX *amx, cell *params) /* 2 param */
|
||||
{
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
int power = abs((int)params[2]);
|
||||
|
||||
// Check if commander, if player is comm then stop
|
||||
if (player->GetPev()->iuser3 == 2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (MF_IsPlayerIngame(player->index()) && MF_IsPlayerAlive(player->index()))
|
||||
{
|
||||
if (player->GetPev()->health <= power)
|
||||
{
|
||||
float bef = player->GetPev()->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,player->GetEdict());
|
||||
|
||||
REMOVE_ENTITY(pEntity);
|
||||
}
|
||||
|
||||
player->GetPev()->frags = bef;
|
||||
}
|
||||
else
|
||||
{
|
||||
int numparam = *params/sizeof(cell);
|
||||
if (numparam<3 || params[3])
|
||||
{
|
||||
player->GetPev()->velocity.x += RANDOM_LONG(-600,600);
|
||||
player->GetPev()->velocity.y += RANDOM_LONG(-180,180);
|
||||
player->GetPev()->velocity.z += RANDOM_LONG(100,200);
|
||||
}
|
||||
else
|
||||
{
|
||||
vec3_t v_forward, v_right;
|
||||
vec3_t vang = player->GetPev()->angles;
|
||||
float fang[3];
|
||||
fang[0] = vang.x;
|
||||
fang[1] = vang.y;
|
||||
fang[2] = vang.z;
|
||||
ANGLEVECTORS( fang, v_forward, v_right, NULL );
|
||||
player->GetPev()->velocity = player->GetPev()->velocity + v_forward * 220 + Vector(0,0,200);
|
||||
}
|
||||
player->GetPev()->punchangle.x = RANDOM_LONG(-10,10);
|
||||
player->GetPev()->punchangle.y = RANDOM_LONG(-10,10);
|
||||
|
||||
player->GetPev()->health -= power;
|
||||
|
||||
int armor = (int)player->GetPev()->armorvalue;
|
||||
armor -= power;
|
||||
|
||||
if (armor < 0)
|
||||
{
|
||||
armor = 0;
|
||||
}
|
||||
|
||||
player->GetPev()->armorvalue = armor;
|
||||
|
||||
player->GetPev()->dmg_inflictor = player->GetEdict();
|
||||
|
||||
static const char *bit_sound[3] = {
|
||||
"weapons/cbar_hitbod1.wav",
|
||||
"weapons/cbar_hitbod2.wav",
|
||||
"weapons/cbar_hitbod3.wav"
|
||||
};
|
||||
|
||||
EMIT_SOUND_DYN2(player->GetEdict(), CHAN_VOICE, bit_sound[RANDOM_LONG(0,2)], 1.0, ATTN_NORM, 0, PITCH_NORM);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// native ns_get_locationname(Float:x, Float:y, name[], len, lookup=0);
|
||||
static cell AMX_NATIVE_CALL ns_get_locationname(AMX *amx, cell *params)
|
||||
{
|
||||
vec3_t location;
|
||||
|
||||
|
||||
location.x=amx_ctof2(params[1]);
|
||||
location.y=amx_ctof2(params[2]);
|
||||
|
||||
if ((params[0] / sizeof(cell)) >= 5)
|
||||
{
|
||||
return MF_SetAmxString(amx,params[3],LocationMan.Lookup(location,params[5]),params[4]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return MF_SetAmxString(amx,params[3],LocationMan.Lookup(location,0),params[4]);
|
||||
}
|
||||
}
|
||||
// ns_lookup_title(const Key[], Output[], Size)
|
||||
static cell AMX_NATIVE_CALL ns_lookup_title(AMX *amx, cell *params)
|
||||
{
|
||||
// FIX: some keys have upper case characters; to fix i store all keys as lower case
|
||||
String Input(MF_GetAmxString(amx,params[1],0,NULL));
|
||||
|
||||
Input.toLower();
|
||||
|
||||
const char *Output=TitleMan.Lookup(Input);
|
||||
|
||||
if (Output==NULL) // not found
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return MF_SetAmxString(amx,params[2],Output,params[3]);
|
||||
};
|
||||
// ns_round_in_progress()
|
||||
static cell AMX_NATIVE_CALL ns_round_in_progress(AMX *amx, cell *params)
|
||||
{
|
||||
return GameMan.RoundInProgress();
|
||||
}
|
||||
// ns_get_spawn(team,number=0,Float:ret[3])
|
||||
static cell AMX_NATIVE_CALL ns_get_spawn(AMX *amx, cell *params)
|
||||
{
|
||||
return SpawnMan.Lookup(amx,params);
|
||||
}
|
||||
// ns_get_mask(id,MASK_*)
|
||||
static cell AMX_NATIVE_CALL ns_get_mask(AMX *amx, cell *params)
|
||||
{
|
||||
CreateEdict(amx,params[1],-1);
|
||||
|
||||
if (Entity->v.iuser4 & static_cast<int>(params[2]))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
// ns_set_mask(id,MASK_*,1 or 0)
|
||||
static cell AMX_NATIVE_CALL ns_set_mask(AMX *amx, cell *params)
|
||||
{
|
||||
CreateEdict(amx,params[1],-1);
|
||||
|
||||
if (static_cast<int>(params[3]) > 0)
|
||||
{
|
||||
if (Entity->v.iuser4 & static_cast<int>(params[2]))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Entity->v.iuser4 |= static_cast<int>(params[2]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (Entity->v.iuser4 & static_cast<int>(params[2]))
|
||||
{
|
||||
Entity->v.iuser4 &= ~static_cast<int>(params[2]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
// ns_popup(id (0 for all),"text",OnlyShowWithCLHelpOn=0)
|
||||
static cell AMX_NATIVE_CALL ns_popup(AMX *amx, cell *params)
|
||||
{
|
||||
GameMan.UpdateHudText2();
|
||||
|
||||
if (params[1])
|
||||
{
|
||||
CreatePlayerPointer(amx, params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
MESSAGE_BEGIN(MSG_ONE,GameMan.GetHudText2(),NULL,player->GetEdict());
|
||||
}
|
||||
else
|
||||
{
|
||||
MESSAGE_BEGIN(MSG_ALL,GameMan.GetHudText2());
|
||||
}
|
||||
|
||||
char msg[190];
|
||||
strncpy(&msg[0],MF_GetAmxString(amx,params[2],0,NULL),188);
|
||||
|
||||
WRITE_STRING(msg);
|
||||
WRITE_BYTE(params[3]);
|
||||
|
||||
MESSAGE_END();
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ns_is_combat()
|
||||
static cell AMX_NATIVE_CALL ns_is_combat(AMX *amx, cell *params)
|
||||
{
|
||||
return GameMan.IsCombat();
|
||||
}
|
||||
/**
|
||||
* Pretty much a direct port of CheezyPeteza's unstick routine
|
||||
* from the old unstuck.amxx plugin. This is included here
|
||||
* to remove the engine requirement.
|
||||
* -
|
||||
* Return values:
|
||||
* 1 success
|
||||
* 0 no spot to move to
|
||||
* -1 invalid state (stunned/webbed)
|
||||
* -2 invalid class (commander/gorge)
|
||||
* -3 player is dead or a spectator
|
||||
* -4 player is invalid (unknown)
|
||||
* -5 player is invalid (disconnected)
|
||||
*/
|
||||
|
||||
inline int GetPlayerHullSize(CPlayer *Player, int PlayerClass)
|
||||
{
|
||||
switch (PlayerClass)
|
||||
{
|
||||
case CLASS_SKULK:
|
||||
case CLASS_GORGE:
|
||||
case CLASS_LERK:
|
||||
return static_cast<int>(head_hull);
|
||||
|
||||
case CLASS_FADE:
|
||||
case CLASS_JETPACK:
|
||||
case CLASS_HEAVY:
|
||||
case CLASS_MARINE:
|
||||
if (Player->GetPev()->button & IN_DUCK || Player->GetPev()->flags & FL_DUCKING)
|
||||
{
|
||||
return static_cast<int>(head_hull);
|
||||
}
|
||||
|
||||
return static_cast<int>(human_hull);
|
||||
|
||||
case CLASS_ONOS:
|
||||
if (Player->GetPev()->button & IN_DUCK || Player->GetPev()->flags & FL_DUCKING)
|
||||
{
|
||||
return static_cast<int>(human_hull);
|
||||
}
|
||||
|
||||
return static_cast<int>(large_hull);
|
||||
|
||||
default:
|
||||
return -1;
|
||||
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_unstick_player(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return -5;
|
||||
}
|
||||
|
||||
if (player->GetPev()->iuser4 & (MASK_ENSNARED | MASK_PLAYER_STUNNED))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int PlayerClass=player->GetClass();
|
||||
if (PlayerClass == CLASS_GESTATE || PlayerClass == CLASS_COMMANDER)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (PlayerClass == CLASS_DEAD || PlayerClass == CLASS_NOTEAM || PlayerClass == CLASS_UNKNOWN)
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
|
||||
int HullSize=GetPlayerHullSize(player, PlayerClass);
|
||||
|
||||
|
||||
if (HullSize==-1)
|
||||
{
|
||||
return -4;
|
||||
}
|
||||
|
||||
Vector OriginalOrigin=player->GetPev()->origin;
|
||||
|
||||
Vector NewOrigin;
|
||||
int Distance=params[2];
|
||||
int Attempts;
|
||||
TraceResult Result;
|
||||
|
||||
while (Distance < 1000)
|
||||
{
|
||||
Attempts=params[3];
|
||||
|
||||
while (Attempts--)
|
||||
{
|
||||
NewOrigin.x = RANDOM_FLOAT(OriginalOrigin.x - Distance,OriginalOrigin.x + Distance);
|
||||
NewOrigin.y = RANDOM_FLOAT(OriginalOrigin.y - Distance,OriginalOrigin.y + Distance);
|
||||
NewOrigin.z = RANDOM_FLOAT(OriginalOrigin.z - Distance,OriginalOrigin.z + Distance);
|
||||
|
||||
// (const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr);
|
||||
TRACE_HULL(NewOrigin, NewOrigin, 0, HullSize, player->GetEdict(), &Result);
|
||||
|
||||
if (Result.fInOpen && !Result.fAllSolid && !Result.fStartSolid)
|
||||
{
|
||||
SET_ORIGIN(player->GetEdict(),NewOrigin);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Distance += params[2];
|
||||
}
|
||||
|
||||
|
||||
return 0; // Couldn't be found
|
||||
}
|
||||
// Type: 131072 = DoT
|
||||
// ns_takedamage
|
||||
static cell AMX_NATIVE_CALL ns_takedamage(AMX *amx, cell *params)
|
||||
{
|
||||
// NASTY
|
||||
// Reinterprets pvPrivateData as CBaseEntity, then calls TakeDamage with the entvar of Inflictor, and Attacker, with the float value and damage type
|
||||
// The NS offset of TakeDamage hasn't changed from the HLSDK fortunately, so no offset digging is necessary
|
||||
return (reinterpret_cast<CBaseEntity *>(INDEXENT_NEW(params[1])->pvPrivateData))->TakeDamage(&(INDEXENT_NEW(params[2])->v),&(INDEXENT_NEW(params[3])->v),amx_ctof2(params[4]),static_cast<int>(params[5]));
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_gameplay(AMX* amx, cell* params)
|
||||
{
|
||||
if (avhgameplay == NULL)
|
||||
{
|
||||
avhgameplay = FIND_ENTITY_BY_CLASSNAME(NULL, "avhgameplay");
|
||||
}
|
||||
if (avhgameplay == NULL ||
|
||||
avhgameplay->pvPrivateData == NULL) // Still null? Get out of here
|
||||
{
|
||||
return NSGame_CantTell;
|
||||
}
|
||||
|
||||
int ATeam /* i pity da foo */ = *reinterpret_cast<int*>(reinterpret_cast<char*>(avhgameplay->pvPrivateData) + MAKE_OFFSET(GAMEPLAY_TEAMA));
|
||||
int BTeam = *reinterpret_cast<int*>(reinterpret_cast<char*>(avhgameplay->pvPrivateData) + MAKE_OFFSET(GAMEPLAY_TEAMB));
|
||||
|
||||
if (ATeam == 2 && // alien
|
||||
BTeam == 2) // alien
|
||||
{
|
||||
return NSGame_AlienVAlien;
|
||||
}
|
||||
if (ATeam == 1 && // marine
|
||||
BTeam == 1) // marine
|
||||
{
|
||||
return NSGame_MarineVMarine;
|
||||
}
|
||||
if (ATeam == 1 && // marine
|
||||
BTeam == 2) // alien
|
||||
{
|
||||
return NSGame_MarineVAlien;
|
||||
}
|
||||
return NSGame_Unknown;
|
||||
|
||||
}
|
||||
|
||||
#ifdef DEVELOPER_BUILD
|
||||
static cell AMX_NATIVE_CALL refmem(AMX *amx, cell *params)
|
||||
{
|
||||
return *(reinterpret_cast<int *>(params[1]));
|
||||
};
|
||||
static cell AMX_NATIVE_CALL setmem(AMX *amx, cell *params)
|
||||
{
|
||||
int *ptr=reinterpret_cast<int *>(params[1]);
|
||||
|
||||
*ptr=params[2];
|
||||
|
||||
return 1;
|
||||
};
|
||||
#endif
|
||||
|
||||
AMX_NATIVE_INFO general_natives[] = {
|
||||
|
||||
{ "user_kill", ns_user_kill }, // replacement natives
|
||||
{ "user_slap", ns_user_slap }, // since ClientKill is changed in NS
|
||||
|
||||
{ "ns_get_locationname", ns_get_locationname },
|
||||
{ "ns_lookup_title", ns_lookup_title },
|
||||
{ "ns_round_in_progress", ns_round_in_progress },
|
||||
{ "ns_get_spawn", ns_get_spawn },
|
||||
{ "ns_get_mask", ns_get_mask },
|
||||
{ "ns_set_mask", ns_set_mask },
|
||||
{ "ns_is_combat", ns_is_combat },
|
||||
{ "ns_unstick_player", ns_unstick_player },
|
||||
|
||||
{ "ns_popup", ns_popup },
|
||||
|
||||
{ "ns_takedamage", ns_takedamage},
|
||||
|
||||
{ "ns_get_gameplay", ns_get_gameplay },
|
||||
|
||||
#ifdef DEVELOPER_BUILD
|
||||
{ "refmem", refmem },
|
||||
{ "setmem", setmem },
|
||||
#endif
|
||||
|
||||
{ NULL, NULL }
|
||||
|
||||
};
|
||||
void AddNatives_General()
|
||||
{
|
||||
MF_AddNatives(general_natives);
|
||||
}
|
275
dlls/ns/natives/memberfuncs.cpp
Normal file
275
dlls/ns/natives/memberfuncs.cpp
Normal file
@ -0,0 +1,275 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "../sdk/amxxmodule.h"
|
||||
|
||||
#include "../ns.h"
|
||||
#include "../ns_const.h"
|
||||
|
||||
#include "../utilfunctions.h"
|
||||
|
||||
#include "../FastDelegate.h"
|
||||
#include "../GameManager.h"
|
||||
|
||||
extern int IsValidBuilding[AVH_USER3_MAX + 1];
|
||||
|
||||
using namespace fastdelegate::detail;
|
||||
|
||||
|
||||
void *GameRules=NULL;
|
||||
|
||||
|
||||
mBOOL dlclose_handle_invalid; // Linking errors with metamod
|
||||
|
||||
// void AvHBaseBuildable::StartRecycle()
|
||||
static void (GenericClass::*MFP_Recycle)();
|
||||
|
||||
// void AvHWeldable::AddBuildTime(float)
|
||||
static void (GenericClass::*MFP_WeldFinished)(float);
|
||||
|
||||
// AvHGameRules *GetGameRules(void)
|
||||
static void *(*FP_GetGameRules)();
|
||||
|
||||
|
||||
char *FuncBase;
|
||||
|
||||
/**
|
||||
* sizeof(void (detail::GenericClass::*fptr)())
|
||||
* is 8 in GCC. Add an empty void * pointer at
|
||||
* the end to compensate.
|
||||
* Layout in GCC:
|
||||
* union {
|
||||
* void *address; // When this is an address it will always be positive
|
||||
* int vtable_index; // When it is a vtable index it will always be odd = (vindex*2)+1
|
||||
* };
|
||||
* int delta;
|
||||
* -
|
||||
* Delta is the adjustment to the this pointer
|
||||
* For my implementations I will only need it to 0
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
template <typename OutType>
|
||||
inline void set_mfp(OutType &out, void *in)
|
||||
{
|
||||
union
|
||||
{
|
||||
void *in[2];
|
||||
OutType out;
|
||||
} mfpu;
|
||||
|
||||
mfpu.in[0]=in;
|
||||
mfpu.in[1]=NULL;
|
||||
out=mfpu.out;
|
||||
};
|
||||
#else
|
||||
template <typename OutType>
|
||||
inline void set_mfp(OutType &out, void *in)
|
||||
{
|
||||
out=horrible_cast<OutType>(in);
|
||||
};
|
||||
#endif
|
||||
|
||||
void MFuncs_Initialize(void)
|
||||
{
|
||||
char FileName[256];
|
||||
DLHANDLE DLLBase;
|
||||
#ifdef __linux__
|
||||
snprintf(FileName,sizeof(FileName)-1,"%s/dlls/ns_i386.so",MF_GetModname());
|
||||
#else
|
||||
snprintf(FileName,sizeof(FileName)-1,"%s\\dlls\\ns.dll",MF_GetModname());
|
||||
#endif
|
||||
|
||||
DLLBase=DLOPEN(FileName);
|
||||
FuncBase=(char *)DLSYM(DLLBase, MAKE_OFFSET(BASE));
|
||||
DLCLOSE(DLLBase);
|
||||
|
||||
#define MFP(Offs) (((void *)(((char *)FuncBase)+MAKE_OFFSET(Offs))))
|
||||
|
||||
set_mfp(MFP_Recycle,MFP(MEMBER_RECYCLE));
|
||||
|
||||
set_mfp(MFP_WeldFinished,MFP(MEMBER_TRIGGER_WELDABLE));
|
||||
|
||||
// This is not a member function pointer, but use MFP since it
|
||||
// uses the same address conversion as MFPs do
|
||||
FP_GetGameRules=horrible_cast<void *(*)()>(MFP(GETGAMERULES));
|
||||
};
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_recycle(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->free || Entity->pvPrivateData==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Entity->v.iuser3 <= AVH_USER3_NONE || Entity->v.iuser3 >= AVH_USER3_MAX)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (IsValidBuilding[Entity->v.iuser3]!=1) // Not a marine structure?
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Make sure it's a marine building, undefined stuff happens on alien structures
|
||||
(reinterpret_cast<GenericClass *>(Entity->pvPrivateData)->*(MFP_Recycle))();
|
||||
|
||||
|
||||
return 1;
|
||||
};
|
||||
static cell AMX_NATIVE_CALL ns_finish_weldable(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->free || Entity->pvPrivateData==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// verify the classname since this will crash if it's the wrong class!
|
||||
if (strcmp(STRING(Entity->v.classname),"avhweldable")!=0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// First need to set the weldable to 100% complete
|
||||
set_private_f(Entity,MAKE_OFFSET(WELD_DONE),get_private_f(Entity,MAKE_OFFSET(WELD_TIME)));
|
||||
|
||||
// Now make NS think the weldable has been welded again
|
||||
// This has to call AvHWeldable::AddBuildTime(float)
|
||||
// because AvHWeldable::TriggerFinished() does not work properly
|
||||
(reinterpret_cast<GenericClass *>(Entity->pvPrivateData)->*(MFP_WeldFinished))(100.0);
|
||||
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_teamres(AMX *amx, cell *params)
|
||||
{
|
||||
if (GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (GameRules==NULL) // GameRules not initialized yet
|
||||
{
|
||||
GameRules=(*(FP_GetGameRules))();
|
||||
}
|
||||
if (GameRules==NULL) // Still null? Get out of here
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
switch(params[1])
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
return amx_ftoc2(*(REAL *)((char *)GameRules+GAMERULES_TEAMA_RESOURCES));
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
return amx_ftoc2(*(REAL *)((char *)GameRules+GAMERULES_TEAMB_RESOURCES));
|
||||
}
|
||||
default:
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "ns_get_teamres: Expected 1 for team a or 2 for team b, got %d", params[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_teamres(AMX *amx, cell *params)
|
||||
{
|
||||
if (GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (GameRules==NULL) // GameRules not initialized yet
|
||||
{
|
||||
GameRules=(*(FP_GetGameRules))();
|
||||
}
|
||||
if (GameRules==NULL) // Still null? Get out of here
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
switch(params[1])
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
*(REAL *)((char *)GameRules+GAMERULES_TEAMA_RESOURCES)=amx_ctof2(params[2]);
|
||||
return 1;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
*(REAL *)((char *)GameRules+GAMERULES_TEAMB_RESOURCES)=amx_ctof2(params[2]);
|
||||
return 1;
|
||||
}
|
||||
default:
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "ns_set_teamres: Expected 1 for team a or 2 for team b, got %d", params[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_add_teamres(AMX *amx, cell *params)
|
||||
{
|
||||
if (GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (GameRules==NULL) // GameRules not initialized yet
|
||||
{
|
||||
GameRules=(*(FP_GetGameRules))();
|
||||
}
|
||||
if (GameRules==NULL) // Still null? Get out of here
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
switch(params[1])
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
return amx_ftoc2(*(REAL *)((char *)GameRules+GAMERULES_TEAMA_RESOURCES)+=amx_ctof2(params[2]));
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
return amx_ftoc2(*(REAL *)((char *)GameRules+GAMERULES_TEAMB_RESOURCES)+=amx_ctof2(params[2]));
|
||||
}
|
||||
default:
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "ns_add_teamres: Expected 1 for team a or 2 for team b, got %d", params[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEVELOPER_BUILD
|
||||
static cell AMX_NATIVE_CALL findgameinfo(AMX *amx, cell *params)
|
||||
{
|
||||
void *Ret=(*(FP_GetGameRules))();
|
||||
union
|
||||
{
|
||||
void *v;
|
||||
int i;
|
||||
}vi;
|
||||
vi.v=Ret;
|
||||
|
||||
printf("GameRules=%d\n",vi.i);
|
||||
return 1;
|
||||
};
|
||||
#endif
|
||||
AMX_NATIVE_INFO memberfunc_natives[] = {
|
||||
#ifdef DEVELOPER_BUILD
|
||||
{ "getgameinfo", findgameinfo },
|
||||
#endif
|
||||
{ "ns_recycle", ns_recycle },
|
||||
{ "ns_finish_weldable", ns_finish_weldable },
|
||||
{ "ns_get_teamres", ns_get_teamres },
|
||||
{ "ns_set_teamres", ns_set_teamres },
|
||||
{ "ns_add_teamres", ns_add_teamres },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
void AddNatives_MemberFunc()
|
||||
{
|
||||
MF_AddNatives(memberfunc_natives);
|
||||
};
|
276
dlls/ns/natives/particles.cpp
Normal file
276
dlls/ns/natives/particles.cpp
Normal file
@ -0,0 +1,276 @@
|
||||
/* AMX Mod X
|
||||
* Natural Selection Module
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
* This file is part of AMX Mod X.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include "../sdk/amxxmodule.h"
|
||||
|
||||
#include "../ns.h"
|
||||
#include "../utilfunctions.h"
|
||||
#include "../NEW_Util.h"
|
||||
|
||||
#include "../CVector.h"
|
||||
#include "../CString.h"
|
||||
#include "../ParticleManager.h"
|
||||
|
||||
#define KVI(__KEY) PSKeyValueI(__KEY,amx,params)
|
||||
#define KVF(__KEY) PSKeyValueF(__KEY,amx,params)
|
||||
#define KVS(__KEY) PSKeyValueS(__KEY,amx,params)
|
||||
#define NEXT params[__pcount++]
|
||||
|
||||
typedef enum partsystype_e
|
||||
{
|
||||
PSYS_TYPE_INT,
|
||||
PSYS_TYPE_FLOAT,
|
||||
PSYS_TYPE_STRING
|
||||
}partsystype;
|
||||
typedef struct partsyskey_s
|
||||
{
|
||||
const char *Name;
|
||||
partsystype type;
|
||||
}partsyskey;
|
||||
|
||||
cell PSKeyValueI(char *name, AMX *amx, cell *params)
|
||||
{
|
||||
if (params[1]==0)
|
||||
{
|
||||
MF_LogError(amx,AMX_ERR_NATIVE,"Invalid particle system handle provided!");
|
||||
return 0;
|
||||
}
|
||||
KeyValueData kvd;
|
||||
|
||||
char StrData[1024];
|
||||
|
||||
snprintf(StrData,sizeof(StrData)-1,"%d",params[2]);
|
||||
|
||||
kvd.szClassName=const_cast<char *>(STRING(reinterpret_cast<edict_t *>(params[1])->v.classname));
|
||||
kvd.szKeyName=name;
|
||||
kvd.szValue=&StrData[0];
|
||||
kvd.fHandled=0;
|
||||
//printf("\"%s\" \"%s\"\n",kvd.szKeyName,kvd.szValue);
|
||||
|
||||
MDLL_KeyValue(reinterpret_cast<edict_t *>(params[1]),&kvd);
|
||||
|
||||
return 1;
|
||||
}
|
||||
cell PSKeyValueF(char *name, AMX *amx, cell *params)
|
||||
{
|
||||
if (params[1]==0)
|
||||
{
|
||||
MF_LogError(amx,AMX_ERR_NATIVE,"Invalid particle system handle provided!");
|
||||
return 0;
|
||||
}
|
||||
KeyValueData kvd;
|
||||
|
||||
char StrData[1024];
|
||||
|
||||
snprintf(StrData,sizeof(StrData)-1,"%f",amx_ctof2(params[2]));
|
||||
|
||||
kvd.szClassName=const_cast<char *>(STRING(reinterpret_cast<edict_t *>(params[1])->v.classname));
|
||||
kvd.szKeyName=name;
|
||||
kvd.szValue=&StrData[0];
|
||||
kvd.fHandled=0;
|
||||
|
||||
//printf("\"%s\" \"%s\"\n",kvd.szKeyName,kvd.szValue);
|
||||
|
||||
MDLL_KeyValue(reinterpret_cast<edict_t *>(params[1]),&kvd);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
cell PSKeyValueS(char *name, AMX *amx, cell *params)
|
||||
{
|
||||
if (params[1]==0)
|
||||
{
|
||||
MF_LogError(amx,AMX_ERR_NATIVE,"Invalid particle system handle provided!");
|
||||
return 0;
|
||||
}
|
||||
KeyValueData kvd;
|
||||
|
||||
kvd.szClassName=const_cast<char *>(STRING(reinterpret_cast<edict_t *>(params[1])->v.classname));
|
||||
kvd.szKeyName=name;
|
||||
kvd.szValue=MF_GetAmxString(amx,params[2],0,NULL);
|
||||
kvd.fHandled=0;
|
||||
//printf("\"%s\" \"%s\"\n",kvd.szKeyName,kvd.szValue);
|
||||
|
||||
MDLL_KeyValue(reinterpret_cast<edict_t *>(params[1]),&kvd);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_name(AMX *amx, cell *params)
|
||||
{
|
||||
return KVS("targetname");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_sprite(AMX *amx, cell *params)
|
||||
{
|
||||
return KVS("pSprite");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_genrate(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("pGenRate");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_genshape(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("pGenShape");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_genshape_params(AMX *amx, cell *params)
|
||||
{
|
||||
return KVS("pGenShapeParams");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_spriteframes(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("pSpriteNumFrames");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_numparticles(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("pNumParticles");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_size(AMX *amx, cell *params)
|
||||
{
|
||||
return KVF("pSize");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_vel_params(AMX *amx, cell *params)
|
||||
{
|
||||
return KVS("pVelParams");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_vel_shape(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("pVelShape");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_sys_life(AMX *amx, cell *params)
|
||||
{
|
||||
return KVF("pSystemLifetime");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_particle_life(AMX *amx, cell *params)
|
||||
{
|
||||
return KVF("pLifetime");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_rendermode(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("pRenderMode");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_to_gen(AMX *amx, cell *params)
|
||||
{
|
||||
return KVS("pPSToGen");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_anim_speed(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("pAnimationSpeed");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_spawn_flags(AMX *amx, cell *params)
|
||||
{
|
||||
return KVI("spawnflags");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_base_color(AMX *amx, cell *params)
|
||||
{
|
||||
return KVS("pBaseColor");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_scale(AMX *amx, cell *params)
|
||||
{
|
||||
return KVF("pScale");
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_ps_max_alpha(AMX *amx, cell *params)
|
||||
{
|
||||
return KVF("pMaxAlpha");
|
||||
}
|
||||
// ns_create_partsys(const name[], pGenShape, const pGenShapeParams[], pGenRate, const pSprite[],
|
||||
// pSpriteFrames, pNumParticles, Float:pSize, const pVelParams[], pVelShape,
|
||||
// Float:pSystemLifetime, Float:pParticleLifetime, pRenderMode, const pPSToGen[], pAnimationSpeed, pSpawnFlags)
|
||||
static cell AMX_NATIVE_CALL ns_create_partsys(AMX *amx, cell *params)
|
||||
{
|
||||
return (cell)CREATE_NAMED_ENTITY(MAKE_STRING("env_particles_custom"));
|
||||
};
|
||||
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);
|
||||
}
|
||||
// ns_fire_ps(Particle:id,Float:origin[3],Float:angles[3],flags=0)
|
||||
static cell AMX_NATIVE_CALL ns_fire_partsys(AMX *amx, cell *params)
|
||||
{
|
||||
float *origin=(float*)MF_GetAmxAddr(amx,params[2]);
|
||||
float *angles=(float*)MF_GetAmxAddr(amx,params[3]);
|
||||
|
||||
ParticleMan.FireSystem(static_cast<int>(params[1]),origin,angles,static_cast<int>(params[4]));
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_partsys_id(AMX *amx, cell *params)
|
||||
{
|
||||
return ParticleMan.Find(MF_GetAmxString(amx,params[1],0,NULL));;
|
||||
};
|
||||
|
||||
AMX_NATIVE_INFO particle_natives[] = {
|
||||
{ "ns_create_ps", ns_create_partsys },
|
||||
{ "ns_set_ps_name", ns_set_ps_name },
|
||||
{ "ns_set_ps_sprite", ns_set_ps_sprite },
|
||||
{ "ns_set_ps_genrate", ns_set_ps_genrate },
|
||||
{ "ns_set_ps_genshape", ns_set_ps_genshape },
|
||||
{ "ns_set_ps_genshape_params", ns_set_ps_genshape_params },
|
||||
{ "ns_set_ps_spriteframes", ns_set_ps_spriteframes },
|
||||
{ "ns_set_ps_numparticles", ns_set_ps_numparticles },
|
||||
{ "ns_set_ps_size", ns_set_ps_size },
|
||||
{ "ns_set_ps_vel_params", ns_set_ps_vel_params },
|
||||
{ "ns_set_ps_vel_shape", ns_set_ps_vel_shape },
|
||||
{ "ns_set_ps_sys_life", ns_set_ps_sys_life },
|
||||
{ "ns_set_ps_particle_life", ns_set_ps_particle_life },
|
||||
{ "ns_set_ps_rendermode", ns_set_ps_rendermode },
|
||||
{ "ns_set_ps_to_gen", ns_set_ps_to_gen },
|
||||
{ "ns_set_ps_anim_speed", ns_set_ps_anim_speed },
|
||||
{ "ns_set_ps_spawn_flags", ns_set_ps_spawn_flags },
|
||||
{ "ns_set_ps_base_color", ns_set_ps_base_color },
|
||||
{ "ns_set_ps_scale", ns_set_ps_scale },
|
||||
{ "ns_set_ps_max_alpha", ns_set_ps_max_alpha },
|
||||
{ "ns_spawn_ps", ns_spawn_ps },
|
||||
|
||||
{ "ns_fire_ps", ns_fire_partsys },
|
||||
{ "ns_get_ps_id", ns_get_partsys_id },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
void AddNatives_Particles()
|
||||
{
|
||||
MF_AddNatives(particle_natives);
|
||||
}
|
222
dlls/ns/natives/player.cpp
Normal file
222
dlls/ns/natives/player.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
/* AMX Mod X
|
||||
* Natural Selection Module
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
* This file is part of AMX Mod X.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include "../sdk/amxxmodule.h"
|
||||
|
||||
#include "../ns.h"
|
||||
|
||||
#include "../utilfunctions.h"
|
||||
#include "../NEW_Util.h"
|
||||
|
||||
#include "../GameManager.h"
|
||||
#include "../CPlayer.h"
|
||||
|
||||
#include "../AllocString.h"
|
||||
|
||||
StringManager AllocStringList;
|
||||
|
||||
// ns_set_player_model(id,const Model[]="")
|
||||
static cell AMX_NATIVE_CALL ns_set_player_model(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
player->SetModel(MF_GetAmxString(amx,params[2],0,NULL));
|
||||
|
||||
GameMan.HookPostThink_Post();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ns_set_player_skin(id,skin=-1)
|
||||
static cell AMX_NATIVE_CALL ns_set_player_skin(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
player->SetSkin(params[2]);
|
||||
|
||||
GameMan.HookPostThink_Post();
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ns_set_player_body(id,body=-1)
|
||||
static cell AMX_NATIVE_CALL ns_set_player_body(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
player->SetBody(params[2]);
|
||||
|
||||
GameMan.HookPostThink_Post();
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ns_get_class(id)
|
||||
static cell AMX_NATIVE_CALL ns_get_class(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
return player->GetClass();
|
||||
}
|
||||
// ns_get_jpfuel(id)
|
||||
static cell AMX_NATIVE_CALL ns_get_jpfuel(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
REAL ret=(player->GetPev()->fuser3) / 10.0;
|
||||
|
||||
return amx_ftoc2(ret);
|
||||
}
|
||||
// ns_set_jpfuel(id,Float:fuelpercent)
|
||||
static cell AMX_NATIVE_CALL ns_set_jpfuel(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
REAL fuel = amx_ctof2(params[2]);
|
||||
if (fuel > 100.0)
|
||||
{
|
||||
fuel = 100.0;
|
||||
}
|
||||
if (fuel < 0.0)
|
||||
{
|
||||
fuel = 0.0;
|
||||
}
|
||||
|
||||
player->GetPev()->fuser3 = fuel * 10.0;
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_add_jpfuel(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
REAL fuel = clamp(amx_ctof2(params[2]),0.0,100.0);
|
||||
|
||||
return amx_ftoc2(player->GetPev()->fuser3 = clamp(static_cast<float>(player->GetPev()->fuser3 + (fuel * 10.0)),static_cast<float>(0.0)));
|
||||
};
|
||||
// ns_get_speedchange(index)
|
||||
static cell AMX_NATIVE_CALL ns_get_speedchange(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
return player->GetSpeedChange();
|
||||
}
|
||||
|
||||
// ns_set_speedchange(index,speedchange=0)
|
||||
static cell AMX_NATIVE_CALL ns_set_speedchange(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
player->SetSpeedChange(params[2]);
|
||||
|
||||
// Update PreThink_Post if we need to
|
||||
GameMan.HookPreThink_Post();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ns_get_maxspeed(index) (returns the max speed of the player BEFORE speed change is factored in.)
|
||||
static cell AMX_NATIVE_CALL ns_get_maxspeed(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
return player->GetMaxSpeed();
|
||||
}
|
||||
// ns_set_fov(id,Float:fov);
|
||||
static cell AMX_NATIVE_CALL ns_set_fov(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
return player->SetFOV(amx_ctof3(¶ms[2]));
|
||||
}
|
||||
// ns_giveiteM(id,"item");
|
||||
static cell AMX_NATIVE_CALL ns_giveitem(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
char *classname = MF_GetAmxString(amx,params[2],0,NULL);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (player->GetPev()->deadflag > 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
edict_t *object=CREATE_NAMED_ENTITY(ALLOC_STRING2(classname));
|
||||
|
||||
if (!object)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Error creating entity \"%s\"", classname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SET_ORIGIN(object,player->GetPev()->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->GetEdict()); // give it to the player
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
AMX_NATIVE_INFO player_natives[] = {
|
||||
|
||||
{ "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_get_class", ns_get_class },
|
||||
|
||||
{ "ns_get_jpfuel", ns_get_jpfuel },
|
||||
{ "ns_set_jpfuel", ns_set_jpfuel },
|
||||
{ "ns_add_jpfuel", ns_add_jpfuel },
|
||||
|
||||
{ "ns_get_energy", ns_get_jpfuel }, // They do the same thing...
|
||||
{ "ns_set_energy", ns_set_jpfuel }, //
|
||||
{ "ns_add_energy", ns_add_jpfuel },
|
||||
|
||||
{ "ns_get_speedchange", ns_get_speedchange },
|
||||
{ "ns_set_speedchange", ns_set_speedchange },
|
||||
{ "ns_get_maxspeed", ns_get_maxspeed },
|
||||
|
||||
{ "ns_set_fov", ns_set_fov },
|
||||
|
||||
{ "ns_give_item", ns_giveitem },
|
||||
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
void AddNatives_Player()
|
||||
{
|
||||
MF_AddNatives(player_natives);
|
||||
}
|
355
dlls/ns/natives/player_memory.cpp
Normal file
355
dlls/ns/natives/player_memory.cpp
Normal file
@ -0,0 +1,355 @@
|
||||
/* AMX Mod X
|
||||
* Natural Selection Module
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
* This file is part of AMX Mod X.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include "../sdk/amxxmodule.h"
|
||||
|
||||
#include "../ns.h"
|
||||
|
||||
#include "../utilfunctions.h"
|
||||
#include "../NEW_Util.h"
|
||||
|
||||
#include "../GameManager.h"
|
||||
#include "../CPlayer.h"
|
||||
|
||||
// Float:ns_get_res(Player)
|
||||
static cell AMX_NATIVE_CALL ns_get_res(AMX *amx, cell *params)
|
||||
{
|
||||
if (GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(get_private_f(player->GetEdict(),MAKE_OFFSET(RESOURCES)));
|
||||
}
|
||||
|
||||
// ns_set_res(Player,Float:res)
|
||||
static cell AMX_NATIVE_CALL ns_set_res(AMX *amx, cell *params)
|
||||
{
|
||||
if (GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private_f(player->GetEdict(),MAKE_OFFSET(RESOURCES),amx_ctof2(params[2]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
// Float:ns_add_res(Player,Float:res)
|
||||
static cell AMX_NATIVE_CALL ns_add_res(AMX *amx, cell *params)
|
||||
{
|
||||
if (GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(inc_private_f(player->GetEdict(),MAKE_OFFSET(RESOURCES),amx_ctof2(params[2]),0.0,100.0));
|
||||
}
|
||||
// Float:ns_get_exp(Player)
|
||||
static cell AMX_NATIVE_CALL ns_get_exp(AMX *amx, cell *params)
|
||||
{
|
||||
if (!GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(get_private_f(player->GetEdict(),MAKE_OFFSET(EXP)));
|
||||
}
|
||||
|
||||
// ns_set_exp(Player,Float:exp)
|
||||
static cell AMX_NATIVE_CALL ns_set_exp(AMX *amx, cell *params)
|
||||
{
|
||||
if (!GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private_f(player->GetEdict(),MAKE_OFFSET(EXP),amx_ctof2(params[2]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
// Float:ns_add_exp(Player,Float:exp)
|
||||
static cell AMX_NATIVE_CALL ns_add_exp(AMX *amx, cell *params)
|
||||
{
|
||||
if (!GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(inc_private_f(player->GetEdict(),MAKE_OFFSET(EXP),amx_ctof2(params[2]),0.0));
|
||||
}
|
||||
|
||||
// ns_get_points(Player)
|
||||
static cell AMX_NATIVE_CALL ns_get_points(AMX *amx, cell *params)
|
||||
{
|
||||
if (!GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(POINTS));
|
||||
}
|
||||
|
||||
// ns_set_points(Player,points)
|
||||
static cell AMX_NATIVE_CALL ns_set_points(AMX *amx, cell *params)
|
||||
{
|
||||
if (!GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx, params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(POINTS),static_cast<int>(params[2]));
|
||||
return 1;
|
||||
}
|
||||
// ns_add_points(Player,points)
|
||||
static cell AMX_NATIVE_CALL ns_add_points(AMX *amx, cell *params)
|
||||
{
|
||||
if (!GameMan.IsCombat())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreatePlayerPointer(amx, params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(POINTS),static_cast<int>(params[2]),0,9);
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_score(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(SCORE));
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_score(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(SCORE),static_cast<int>(params[2]));
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_add_score(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(SCORE),static_cast<int>(params[2]));
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_deaths(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(DEATHS));
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_deaths(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(DEATHS),static_cast<int>(params[2]));
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_add_deaths(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(DEATHS),static_cast<int>(params[2]));
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_hive_ability(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
int result = get_private(player->GetEdict(), MAKE_OFFSET(HIVEABILITY));
|
||||
|
||||
return (params[2] > 0) ? (result >= params[2] - 1) : result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
AMX_NATIVE_INFO player_memory_natives[] = {
|
||||
|
||||
{ "ns_get_res", ns_get_res },
|
||||
{ "ns_set_res", ns_set_res },
|
||||
{ "ns_add_res", ns_add_res },
|
||||
|
||||
{ "ns_get_exp", ns_get_exp },
|
||||
{ "ns_set_exp", ns_set_exp },
|
||||
{ "ns_add_exp", ns_add_exp },
|
||||
|
||||
{ "ns_get_points", ns_get_points },
|
||||
{ "ns_set_points", ns_set_points },
|
||||
{ "ns_add_points", ns_add_points },
|
||||
|
||||
{ "ns_set_score", ns_set_score },
|
||||
{ "ns_get_score", ns_get_score },
|
||||
{ "ns_add_score", ns_add_score },
|
||||
|
||||
{ "ns_get_deaths", ns_get_deaths },
|
||||
{ "ns_set_deaths", ns_set_deaths },
|
||||
{ "ns_add_deaths", ns_add_deaths },
|
||||
|
||||
{ "ns_get_hive_ability", ns_get_hive_ability},
|
||||
|
||||
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
void AddNatives_PlayerMemory()
|
||||
{
|
||||
MF_AddNatives(player_memory_natives);
|
||||
}
|
405
dlls/ns/natives/structure.cpp
Normal file
405
dlls/ns/natives/structure.cpp
Normal file
@ -0,0 +1,405 @@
|
||||
/* AMX Mod X
|
||||
* Natural Selection Module
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
* This file is part of AMX Mod X.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include "../sdk/amxxmodule.h"
|
||||
|
||||
#include "../ns.h"
|
||||
|
||||
#include "../utilfunctions.h"
|
||||
#include "../NEW_Util.h"
|
||||
|
||||
int IsValidBuilding[AVH_USER3_MAX + 1] = {
|
||||
0, // AVH_USER3_NONE = 0,
|
||||
0, // AVH_USER3_MARINE_PLAYER,
|
||||
0, // AVH_USER3_COMMANDER_PLAYER,
|
||||
0, // AVH_USER3_ALIEN_PLAYER1,
|
||||
0, // AVH_USER3_ALIEN_PLAYER2,
|
||||
0, // AVH_USER3_ALIEN_PLAYER3,
|
||||
0, // AVH_USER3_ALIEN_PLAYER4,
|
||||
0, // AVH_USER3_ALIEN_PLAYER5,
|
||||
0, // AVH_USER3_ALIEN_EMBRYO,
|
||||
0, // AVH_USER3_SPAWN_TEAMONE,
|
||||
0, // AVH_USER3_SPAWN_TEAMTWO,
|
||||
0, // AVH_USER3_PARTICLE_ON, // only valid for AvHParticleEntity: entindex as int in fuser1, template index stored in fuser2
|
||||
0, // AVH_USER3_PARTICLE_OFF, // only valid for AvHParticleEntity: particle system handle in fuser1
|
||||
0, // AVH_USER3_WELD, // float progress (0 - 100) stored in fuser1
|
||||
0, // AVH_USER3_ALPHA, // fuser1 indicates how much alpha this entity toggles to in commander mode, fuser2 for players
|
||||
0, // AVH_USER3_MARINEITEM, // Something a friendly marine can pick up
|
||||
0, // AVH_USER3_WAYPOINT,
|
||||
2, // AVH_USER3_HIVE,
|
||||
0, // AVH_USER3_NOBUILD,
|
||||
0, // AVH_USER3_USEABLE,
|
||||
0, // AVH_USER3_AUDIO_ON,
|
||||
0, // AVH_USER3_AUDIO_OFF,
|
||||
0, // AVH_USER3_FUNC_RESOURCE,
|
||||
1, // AVH_USER3_COMMANDER_STATION,
|
||||
1, // AVH_USER3_TURRET_FACTORY,
|
||||
1, // AVH_USER3_ARMORY,
|
||||
1, // AVH_USER3_ADVANCED_ARMORY,
|
||||
1, // AVH_USER3_ARMSLAB,
|
||||
1, // AVH_USER3_PROTOTYPE_LAB,
|
||||
1, // AVH_USER3_OBSERVATORY,
|
||||
0, // AVH_USER3_CHEMLAB,
|
||||
0, // AVH_USER3_MEDLAB,
|
||||
0, // AVH_USER3_NUKEPLANT,
|
||||
1, // AVH_USER3_TURRET,
|
||||
1, // AVH_USER3_SIEGETURRET,
|
||||
1, // AVH_USER3_RESTOWER,
|
||||
0, // AVH_USER3_PLACEHOLDER,
|
||||
1, // AVH_USER3_INFANTRYPORTAL,
|
||||
0, // AVH_USER3_NUKE,
|
||||
0, // AVH_USER3_BREAKABLE,
|
||||
0, // AVH_USER3_UMBRA,
|
||||
1, // AVH_USER3_PHASEGATE,
|
||||
2, // AVH_USER3_DEFENSE_CHAMBER,
|
||||
2, // AVH_USER3_MOVEMENT_CHAMBER,
|
||||
2, // AVH_USER3_OFFENSE_CHAMBER,
|
||||
2, // AVH_USER3_SENSORY_CHAMBER,
|
||||
2, // AVH_USER3_ALIENRESTOWER,
|
||||
0, // AVH_USER3_HEAVY,
|
||||
0, // AVH_USER3_JETPACK,
|
||||
1, // AVH_USER3_ADVANCED_TURRET_FACTORY,
|
||||
0, // AVH_USER3_SPAWN_READYROOM,
|
||||
0, // AVH_USER3_CLIENT_COMMAND,
|
||||
0, // AVH_USER3_FUNC_ILLUSIONARY,
|
||||
0, // AVH_USER3_MENU_BUILD,
|
||||
0, // AVH_USER3_MENU_BUILD_ADVANCED,
|
||||
0, // AVH_USER3_MENU_ASSIST,
|
||||
0, // AVH_USER3_MENU_EQUIP,
|
||||
0, // AVH_USER3_MINE,
|
||||
0 // AVH_USER3_MAX
|
||||
|
||||
};
|
||||
|
||||
|
||||
// ns_build_structure(idStructure);
|
||||
static cell AMX_NATIVE_CALL ns_build_structure(AMX *amx, cell *params)
|
||||
{
|
||||
// Trick NS into thinking that this structure is being spawned from the map
|
||||
// set the "startbuilt" setting to 1, then remove it.
|
||||
// "startbuilt" is set as "spawnflag" "1" in the ns.fgd
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->free)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
if (Entity->v.iuser3 <= AVH_USER3_NONE || Entity->v.iuser3 >= AVH_USER3_MAX)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int StructureType=IsValidBuilding[Entity->v.iuser3];
|
||||
if (StructureType==0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Entity->v.iuser3==AVH_USER3_HIVE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Already set?
|
||||
if (Entity->v.spawnflags & 1)
|
||||
{
|
||||
MDLL_Spawn(Entity);
|
||||
|
||||
goto undo_ghost;
|
||||
}
|
||||
|
||||
Entity->v.spawnflags |= 1;
|
||||
|
||||
MDLL_Spawn(Entity);
|
||||
|
||||
Entity->v.spawnflags &= ~1;
|
||||
|
||||
undo_ghost:
|
||||
if (StructureType==1) // marine, remove "ghost" appearance
|
||||
{
|
||||
if (get_private(Entity,MAKE_OFFSET(GHOST_STRUCTURE))!=0)
|
||||
{
|
||||
set_private(Entity,MAKE_OFFSET(GHOST_STRUCTURE),0);
|
||||
|
||||
Entity->v.rendermode=kRenderNormal;
|
||||
Entity->v.renderamt=100.0;
|
||||
}
|
||||
}
|
||||
|
||||
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_NEW(pBuild);
|
||||
}
|
||||
return iCount++;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_hive_trait(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private(Entity,MAKE_OFFSET(HIVE_TRAIT),static_cast<int>(params[2]));
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_get_hive_trait(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return get_private(Entity,MAKE_OFFSET(HIVE_TRAIT));
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ns_get_struct_owner(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return get_private(Entity,MAKE_OFFSET(STRUCTOWNER));
|
||||
}
|
||||
// ns_set_struct_owner(idStructure,idPlayer) - -1 means no owner
|
||||
static cell AMX_NATIVE_CALL ns_set_struct_owner(AMX *amx, cell *params)
|
||||
{
|
||||
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (params[2] > gpGlobals->maxClients || params[2] < -1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
set_private(Entity,MAKE_OFFSET(STRUCTOWNER),params[2]);
|
||||
return 1;
|
||||
}
|
||||
// Float:ns_get_obs_energy(id);
|
||||
static cell AMX_NATIVE_CALL ns_get_obs_energy(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(get_private(Entity,MAKE_OFFSET(OBS_ENERGY)));
|
||||
};
|
||||
// Float:ns_set_obs_energy(id,Float:energy);
|
||||
static cell AMX_NATIVE_CALL ns_set_obs_energy(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private_f(Entity,MAKE_OFFSET(OBS_ENERGY),amx_ctof2(params[2]));
|
||||
return 1;
|
||||
};
|
||||
|
||||
// Float:ns_add_obs_energy(id,Float:energy);
|
||||
static cell AMX_NATIVE_CALL ns_add_obs_energy(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(inc_private_f(Entity,MAKE_OFFSET(OBS_ENERGY),amx_ctof2(params[2]),0.0,100.0));
|
||||
};
|
||||
|
||||
// Float:ns_get_weld_time(idWeldable);
|
||||
static cell AMX_NATIVE_CALL ns_get_weld_time(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(get_private_f(Entity,MAKE_OFFSET(WELD_TIME)));
|
||||
};
|
||||
// ns_set_weld_time(idWeldable,Float:value);
|
||||
static cell AMX_NATIVE_CALL ns_set_weld_time(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private_f(Entity,MAKE_OFFSET(WELD_TIME),amx_ctof2(params[2]));
|
||||
|
||||
return 1;
|
||||
};
|
||||
// Float:ns_add_weld_time(idWeldable,Float:value);
|
||||
static cell AMX_NATIVE_CALL ns_add_weld_time(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(inc_private_f(Entity,MAKE_OFFSET(WELD_TIME),amx_ctof2(params[2]),0.0));
|
||||
};
|
||||
// Float:ns_get_weld_done(idWeldable);
|
||||
static cell AMX_NATIVE_CALL ns_get_weld_done(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(get_private_f(Entity,MAKE_OFFSET(WELD_DONE)));
|
||||
};
|
||||
// ns_set_weld_done(idWeldable,Float:value);
|
||||
static cell AMX_NATIVE_CALL ns_set_weld_done(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private_f(Entity,MAKE_OFFSET(WELD_DONE),amx_ctof2(params[2]));
|
||||
|
||||
return 1;
|
||||
};
|
||||
// Float:ns_add_weld_done(idWeldable,Float:value);
|
||||
static cell AMX_NATIVE_CALL ns_add_weld_done(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc2(inc_private_f(Entity,MAKE_OFFSET(WELD_DONE),amx_ctof2(params[2]),0.0));
|
||||
};
|
||||
|
||||
|
||||
AMX_NATIVE_INFO structure_natives[] = {
|
||||
{ "ns_build_structure", ns_build_structure },
|
||||
|
||||
{ "ns_get_build", ns_get_build },
|
||||
|
||||
{ "ns_get_hive_trait", ns_get_hive_trait },
|
||||
{ "ns_set_hive_trait", ns_set_hive_trait },
|
||||
|
||||
{ "ns_get_struct_owner", ns_get_struct_owner },
|
||||
{ "ns_set_struct_owner", ns_set_struct_owner },
|
||||
|
||||
{ "ns_get_obs_energy", ns_get_obs_energy },
|
||||
{ "ns_set_obs_energy", ns_set_obs_energy },
|
||||
{ "ns_add_obs_energy", ns_add_obs_energy },
|
||||
|
||||
{ "ns_get_weld_time", ns_get_weld_time },
|
||||
{ "ns_set_weld_time", ns_set_weld_time },
|
||||
{ "ns_add_weld_time", ns_add_weld_time },
|
||||
|
||||
{ "ns_get_weld_done", ns_get_weld_done },
|
||||
{ "ns_set_weld_done", ns_set_weld_done },
|
||||
{ "ns_add_weld_done", ns_add_weld_done },
|
||||
|
||||
/* prototypes for natives i have planned */
|
||||
//{ "ns_get_phase_target", ns_get_phase_target },
|
||||
//{ "ns_set_phase_target", ns_set_phase_target },
|
||||
|
||||
//{ "ns_set_phase_nextuse", ns_set_phase_nextuse },
|
||||
//{ "ns_get_phase_nextuse", ns_get_phase_nextuse },
|
||||
//{ "ns_add_phase_nextuse", ns_add_phase_nextuse },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
void AddNatives_Structure()
|
||||
{
|
||||
MF_AddNatives(structure_natives);
|
||||
}
|
479
dlls/ns/natives/weapons.cpp
Normal file
479
dlls/ns/natives/weapons.cpp
Normal file
@ -0,0 +1,479 @@
|
||||
/* AMX Mod X
|
||||
* Natural Selection Module
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
* This file is part of AMX Mod X.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include "../sdk/amxxmodule.h"
|
||||
|
||||
#include "../ns.h"
|
||||
|
||||
#include "../utilfunctions.h"
|
||||
#include "../NEW_Util.h"
|
||||
|
||||
#include "../GameManager.h"
|
||||
#include "../CPlayer.h"
|
||||
|
||||
// ns_has_weapon(idPlayer,NsWeapon,set=0)
|
||||
static cell AMX_NATIVE_CALL ns_has_weapon(AMX *amx,cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (params[3] == -1)
|
||||
{
|
||||
if ((player->GetPev()->weapons & (1<<params[2])) > 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((player->GetPev()->weapons & (1<<params[2])) > 0)
|
||||
{
|
||||
if (params[3] == 0)
|
||||
{
|
||||
player->GetPev()->weapons &= ~(1<<params[2]);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (params[3] == 1)
|
||||
{
|
||||
player->GetPev()->weapons |= (1<<params[2]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// ns_set_weap_dmg(WeaponID,Float:damage)
|
||||
static cell AMX_NATIVE_CALL ns_set_weapon_dmg(AMX *amx, cell *params)
|
||||
{
|
||||
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL || Entity->free)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private_f(Entity,MAKE_OFFSET(WEAPDMG),amx_ctof2(params[2]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Float:ns_get_weap_dmg(WeaponID)
|
||||
static cell AMX_NATIVE_CALL ns_get_weapon_dmg(AMX *amx, cell *params)
|
||||
{
|
||||
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL || Entity->free)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
REAL ret=get_private_f(Entity,MAKE_OFFSET(WEAPDMG));
|
||||
return amx_ftoc2(ret);
|
||||
}
|
||||
|
||||
// ns_set_weap_range(WeaponID,Float:range)
|
||||
static cell AMX_NATIVE_CALL ns_set_weapon_range(AMX *amx, cell *params)
|
||||
{
|
||||
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL || Entity->free)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private_f(Entity,MAKE_OFFSET(WEAPRANGE),amx_ctof2(params[2]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
// Float:ns_get_weap_range(WeaponID)
|
||||
static cell AMX_NATIVE_CALL ns_get_weapon_range(AMX *amx, cell *params)
|
||||
{
|
||||
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL || Entity->free)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
REAL ret=get_private_f(Entity,MAKE_OFFSET(WEAPRANGE));
|
||||
return amx_ftoc2(ret);
|
||||
}
|
||||
// ns_get_weap_ammo(WeaponID)
|
||||
static cell AMX_NATIVE_CALL ns_get_weapon_clip(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL || Entity->free)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return get_private(Entity,MAKE_OFFSET(WEAPCLIP));
|
||||
}
|
||||
// ns_set_weap_ammo(WeaponID,ammo)
|
||||
static cell AMX_NATIVE_CALL ns_set_weapon_clip(AMX *amx, cell *params)
|
||||
{
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL || Entity->free)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_private(Entity,MAKE_OFFSET(WEAPCLIP),params[2]);
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_add_weapon_clip(AMX *amx, cell *params)
|
||||
{
|
||||
|
||||
CreateNonPlayerEdict(amx,params[1]);
|
||||
|
||||
if (Entity->pvPrivateData == NULL || Entity->free)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return inc_private(Entity,MAKE_OFFSET(WEAPCLIP),static_cast<int>(params[2]),0);
|
||||
}
|
||||
// ns_get_weap_reserve(PlayerID,WeaponType)
|
||||
static cell AMX_NATIVE_CALL ns_get_weap_reserve(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (params[2])
|
||||
{
|
||||
case WEAPON_PISTOL:
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(AMMO_PISTOL));
|
||||
case WEAPON_LMG:
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(AMMO_LMG));
|
||||
case WEAPON_SHOTGUN:
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(AMMO_SHOTGUN));
|
||||
case WEAPON_HMG:
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(AMMO_HMG));
|
||||
case WEAPON_GRENADE_GUN:
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(AMMO_GL));
|
||||
case WEAPON_GRENADE:
|
||||
return get_private(player->GetEdict(),MAKE_OFFSET(AMMO_HG));
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_set_weap_reserve(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (params[2])
|
||||
{
|
||||
case WEAPON_PISTOL:
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(AMMO_PISTOL),params[3]);
|
||||
return 1;
|
||||
case WEAPON_LMG:
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(AMMO_LMG),(int)params[3]);
|
||||
return 1;
|
||||
case WEAPON_SHOTGUN:
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(AMMO_SHOTGUN),(int)params[3]);
|
||||
return 1;
|
||||
case WEAPON_HMG:
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(AMMO_HMG),(int)params[3]);
|
||||
return 1;
|
||||
case WEAPON_GRENADE_GUN:
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(AMMO_GL),(int)params[3]);
|
||||
return 1;
|
||||
case WEAPON_GRENADE:
|
||||
set_private(player->GetEdict(),MAKE_OFFSET(AMMO_HG),(int)params[3]);
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ns_add_weap_reserve(AMX *amx, cell *params)
|
||||
{
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected() || !player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (params[2])
|
||||
{
|
||||
case WEAPON_PISTOL:
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(AMMO_PISTOL),params[3],0);
|
||||
case WEAPON_LMG:
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(AMMO_LMG),(int)params[3],0);
|
||||
case WEAPON_SHOTGUN:
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(AMMO_SHOTGUN),(int)params[3],0);
|
||||
case WEAPON_HMG:
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(AMMO_HMG),(int)params[3],0);
|
||||
case WEAPON_GRENADE_GUN:
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(AMMO_GL),(int)params[3],0);
|
||||
case WEAPON_GRENADE:
|
||||
return inc_private(player->GetEdict(),MAKE_OFFSET(AMMO_HG),(int)params[3],0);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// ns_get_weapon(idPlayer,weaponid,&weapontype=0)
|
||||
static cell AMX_NATIVE_CALL ns_get_weapon(AMX *amx, cell *params)
|
||||
{
|
||||
// Peachy did it like this:
|
||||
// if weapontype is 0, return the primary weapon index of the player
|
||||
// if weapontype is < 0, return the last inventory weapon index of the player
|
||||
// otherwise, scan the player's inventory and look for a weapon of the given type
|
||||
// such as WEAPON_KNIFE, etc, etc
|
||||
// I added the last parameter, which will byref the weapontype of the weapon found
|
||||
// returns 0 on failure
|
||||
// last param default value added to not conflict with his version
|
||||
|
||||
CreatePlayerPointer(amx,params[1]);
|
||||
|
||||
if (!player->IsConnected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!player->HasPrivateData())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (params[2]<0) // find lastinv weapon
|
||||
{
|
||||
edict_t *Weapon=private_to_edict(get_private_p<void *>(player->GetEdict(),MAKE_OFFSET(LAST_WEAPON)));
|
||||
|
||||
if (Weapon==NULL) // no weapon
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((params[0] / sizeof(cell))>2) // If this plugin was compiled with peachy's .inc then don't byref
|
||||
{
|
||||
*MF_GetAmxAddr_NEW(amx,params[3])=get_private(Weapon,MAKE_OFFSET(WEAPID));
|
||||
}
|
||||
|
||||
return ENTINDEX_NEW(Weapon);
|
||||
|
||||
}
|
||||
if (params[2]==0) // find current weapon
|
||||
{
|
||||
edict_t *Weapon=private_to_edict(get_private_p<void *>(player->GetEdict(),MAKE_OFFSET(CURRENT_WEAPON)));
|
||||
|
||||
if (Weapon==NULL) // no weapon
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((params[0] / sizeof(cell))>2) // If this plugin was compiled with peachy's .inc then don't byref
|
||||
{
|
||||
*MF_GetAmxAddr_NEW(amx,params[3])=get_private(Weapon,MAKE_OFFSET(WEAPID));
|
||||
}
|
||||
|
||||
return ENTINDEX_NEW(Weapon);
|
||||
}
|
||||
|
||||
// Finding weapon by ID
|
||||
|
||||
char **pPlayerItems = reinterpret_cast<char**>(static_cast<char*>(player->GetEdict()->pvPrivateData) + MAKE_OFFSET(PLAYER_ITEMS));
|
||||
char *pItem;
|
||||
int weapon=params[2];
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
pItem = pPlayerItems[i];
|
||||
while (pItem)
|
||||
{
|
||||
if (*(int *)(pItem + MAKE_OFFSET(WEAPID)) == weapon)
|
||||
{
|
||||
return ENTINDEX_NEW(private_to_edict(pItem));
|
||||
}
|
||||
else
|
||||
{
|
||||
pItem = *(char **)(pItem + MAKE_OFFSET(WEAP_NEXT));
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#ifdef DEVELOPER_BUILD
|
||||
// ns_find_weapon_offset(idPlayer,"primweapon","lastinvweapon")
|
||||
static cell AMX_NATIVE_CALL ns_find_weapon_offset(AMX *amx, cell *params)
|
||||
{
|
||||
char *SPrimWeapon=MF_GetAmxString(amx,params[2],0,NULL);
|
||||
char *SLastInv=MF_GetAmxString(amx,params[3],1,NULL);
|
||||
edict_t *ePlayer=INDEXENT_NEW(params[1]);
|
||||
|
||||
// Locate entities by name
|
||||
edict_t *PrimWeapon=NULL;
|
||||
edict_t *LastInv=NULL;
|
||||
|
||||
edict_t *Temp=NULL;
|
||||
|
||||
while ((Temp=UTIL_FindEntityByString(Temp,"classname",SPrimWeapon))!=NULL)
|
||||
{
|
||||
if (Temp->v.owner==ePlayer)
|
||||
{
|
||||
PrimWeapon=Temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Temp=NULL;
|
||||
while ((Temp=UTIL_FindEntityByString(Temp,"classname",SLastInv))!=NULL)
|
||||
{
|
||||
if (Temp->v.owner==ePlayer)
|
||||
{
|
||||
LastInv=Temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (LastInv == NULL || PrimWeapon == NULL)
|
||||
{
|
||||
if (LastInv==NULL)
|
||||
{
|
||||
MF_Log("LastInv==NULL");
|
||||
}
|
||||
if (PrimWeapon==NULL)
|
||||
{
|
||||
MF_Log("PrimWeapon=NULL");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// now iterate through the client's private data until we find the pointer to PrimWeapon/LastInv's offset
|
||||
unsigned int *Ptr=(unsigned int*)ePlayer->pvPrivateData;
|
||||
|
||||
int FoundLastInv=0;
|
||||
int FoundPrim=0;
|
||||
size_t count=0;
|
||||
unsigned int iPrim;
|
||||
unsigned int iLast;
|
||||
|
||||
// so nasty D: this is basically horrible_cast
|
||||
union bleh
|
||||
{
|
||||
void *ptr;
|
||||
unsigned int ival;
|
||||
}blah;
|
||||
|
||||
blah.ptr=PrimWeapon->pvPrivateData;
|
||||
iPrim=blah.ival;
|
||||
|
||||
blah.ptr=LastInv->pvPrivateData;
|
||||
iLast=blah.ival;
|
||||
|
||||
while (count<4000)
|
||||
{
|
||||
if (*Ptr==iLast)
|
||||
{
|
||||
MF_Log("Found LastInv: %d",count);
|
||||
FoundLastInv=1;
|
||||
}
|
||||
if (*Ptr==iPrim)
|
||||
{
|
||||
MF_Log("Found Primary: %d",count);
|
||||
FoundPrim=1;
|
||||
}
|
||||
|
||||
if (FoundLastInv && FoundPrim)
|
||||
{
|
||||
//break;
|
||||
}
|
||||
count+=4;
|
||||
Ptr++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
AMX_NATIVE_INFO weapon_natives[] = {
|
||||
|
||||
{ "ns_has_weapon", ns_has_weapon },
|
||||
|
||||
{ "ns_set_weap_dmg", ns_set_weapon_dmg },
|
||||
{ "ns_get_weap_dmg", ns_get_weapon_dmg },
|
||||
|
||||
{ "ns_set_weap_range", ns_set_weapon_range },
|
||||
{ "ns_get_weap_range", ns_get_weapon_range },
|
||||
|
||||
{ "ns_set_weap_clip", ns_set_weapon_clip },
|
||||
{ "ns_get_weap_clip", ns_get_weapon_clip },
|
||||
{ "ns_add_weap_clip", ns_add_weapon_clip },
|
||||
|
||||
{ "ns_set_weap_reserve", ns_set_weap_reserve },
|
||||
{ "ns_get_weap_reserve", ns_get_weap_reserve },
|
||||
{ "ns_add_weap_reserve", ns_add_weap_reserve },
|
||||
|
||||
{ "ns_get_weapon", ns_get_weapon},
|
||||
|
||||
#ifdef DEVELOPER_BUILD
|
||||
{ "ns_find_weapon_offset", ns_find_weapon_offset},
|
||||
#endif
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
void AddNatives_Weapons()
|
||||
{
|
||||
MF_AddNatives(weapon_natives);
|
||||
}
|
Reference in New Issue
Block a user