merged bcompat changed into trunk

removed amxmod compat files for now
This commit is contained in:
David Anderson
2006-09-01 03:29:27 +00:00
parent 95537e4840
commit 78956f3d89
32 changed files with 979 additions and 267 deletions

View File

@ -14,7 +14,8 @@ NAME = engine
BIN_SUFFIX_32 = amxx_i386.so
BIN_SUFFIX_64 = amxx_amd64.so
OBJECTS = amxxmodule.cpp amxxapi.cpp engine.cpp entity.cpp globals.cpp forwards.cpp
OBJECTS = amxxmodule.cpp amxxapi.cpp engine.cpp entity.cpp globals.cpp forwards.cpp \
amxmod_compat.cpp
LINK =

View File

@ -0,0 +1,453 @@
#include "engine.h"
#include <cbase.h>
static cvar_t *sv_knockback1 = NULL;
static cvar_t *sv_knockback2 = NULL;
static cvar_t *sv_friendlyfire = NULL;
static bool g_ff_check = false;
static bool g_kb1_check = false;
static bool g_kb2_check = false;
static int gmsgDamage = 0;
static int gmsgDeathMsg = 0;
static int gmsgScoreInfo = 0;
//From VexdUM (AMX Mod 2006.2)
//This is not exposed, and is only provided as a compatibility helper.
BOOL is_breakable(edict_t* pBreak)
{
if (FStrEq("func_breakable", STRING(pBreak->v.classname))
|| FStrEq("func_pushable", STRING(pBreak->v.classname))
&& pBreak->v.spawnflags & SF_PUSH_BREAKABLE)
{
return true;
}
return false;
}
//From VexdUM (AMX Mod 2006.2)
//This is not exposed, and is only provided as a compatibility helper.
BOOL is_monster(edict_t* pMonster)
{
if(pMonster->v.flags & FL_MONSTER)
{
return true;
}
return false;
}
//From VexdUM (AMX Mod 2006.2)
// Damage Monsters
void hurt_monster(edict_t* pMonster, float dmg, int bit, const float *origin)
{
int mdmg = (int)pMonster->v.health;
pMonster->v.health -= dmg;
// No need to create a trigger_hurt unless we are going to kill the monster ;)
if((int)pMonster->v.health < 1)
{
int hurt = MAKE_STRING("trigger_hurt");
char hbit[16];
char horigin[16];
snprintf(hbit, 15, "%i", bit);
snprintf(horigin, 15, "%f %f %f", origin[0], origin[1], origin[2]);
edict_t* pEntity = CREATE_NAMED_ENTITY(hurt);
KeyValueData pkvd1;
pkvd1.szClassName = "trigger_hurt";
pkvd1.szKeyName = "dmg";
pkvd1.szValue = "1.0";
pkvd1.fHandled = FALSE;
MDLL_KeyValue(pEntity, &pkvd1);
KeyValueData pkvd2;
pkvd2.szClassName = "trigger_hurt";
pkvd2.szKeyName = "damagetype";
pkvd2.szValue = hbit;
pkvd2.fHandled = FALSE;
MDLL_KeyValue(pEntity, &pkvd2);
KeyValueData pkvd3;
pkvd3.szClassName = "trigger_hurt";
pkvd3.szKeyName = "origin";
pkvd3.szValue = horigin;
pkvd3.fHandled = FALSE;
MDLL_KeyValue(pEntity, &pkvd3);
MDLL_Spawn(pEntity);
MDLL_Touch(pEntity, pMonster);
REMOVE_ENTITY(pEntity);
}
mdmg -= (int)pMonster->v.health;
//~dvander - Note, not porting the forward until this function is known to be truly wrapped
//g_forwards.executeForward(FF_MonsterHurt, ENTINDEX(pMonster), ENTINDEX(pMonster->v.dmg_inflictor), mdmg);
}
//From VexdUM (AMX Mod 2006.2)
//This appears to be from the HLSDK CBasePlayer::TakeDamage() function.
//This is not exposed, and is only provided as a compatibility helper.
float ArmorDamage(edict_t* pVictim, float dmg, int bit)
{
float flRatio = 0.2;
float flBonus = 0.5;
if(bit & DMG_BLAST)
{
// blasts damage armor more.
flBonus *= 2;
}
if(pVictim->v.armorvalue && !(bit & (DMG_FALL | DMG_DROWN)))
{
// armor doesn't protect against fall or drown damage!
float flNew = dmg * flRatio;
float flArmor = (dmg - flNew) * flBonus;
// Does this use more armor than we have?
if(flArmor > pVictim->v.armorvalue)
{
flArmor = pVictim->v.armorvalue;
flArmor *= (1/flBonus);
flNew = dmg - flArmor;
pVictim->v.armorvalue = 0;
} else {
pVictim->v.armorvalue -= flArmor;
}
dmg = flNew;
}
// Lets knock the view about abit
pVictim->v.punchangle.x = -4;
return dmg;
}
// Death emulation
//This is not exposed, and is only provided as a compatibility helper.
void Death(edict_t* pVictim, edict_t* pKiller, const char* weapon, int hs)
{
if (!gmsgDeathMsg)
{
gmsgDeathMsg = GET_USER_MSG_ID(PLID, "DeathMsg", NULL);
}
if (!gmsgScoreInfo)
{
gmsgScoreInfo = GET_USER_MSG_ID(PLID, "ScoreInfo", NULL);
}
// Make sure an entity is allowed to take damage
if(pVictim->v.takedamage > DAMAGE_NO)
{
// Breakable Check
if(is_breakable(pVictim))
{
MDLL_Use(pVictim, pKiller);
}
// Monster Check
if (is_monster(pVictim))
{
pVictim->v.dmg_inflictor = pKiller;
float dmg = pVictim->v.health;
int bit = DMG_BULLET;
const float *origin = pVictim->v.origin;
hurt_monster(pVictim, dmg, bit, origin);
}
// Player Check
if (pVictim->v.flags & (FL_CLIENT | FL_FAKECLIENT))
{
pVictim->v.dmg_inflictor = pKiller;
edict_t* inflictor = pKiller->v.owner;
int inflictorId = FNullEnt(inflictor) ? ENTINDEX(inflictor) : 0;
// See if it is a player attacking with a default weapon
if (pKiller->v.flags & (FL_CLIENT | FL_FAKECLIENT))
{
// We only modify the weapon if it = 0, otherwise its been specified
if(strcmp(weapon, "") == 0)
{
char view_weapon[64];
// Get the name from the view model
weapon = STRING(pKiller->v.viewmodel);
// Strip out the beginning of the viewmodel (models/v_)
if(strncmp(weapon, "models/v_", 9) == 0)
{
strcpy(view_weapon, weapon + 9);
}
// Strip out the end of viewmodel (.mdl)
view_weapon[strlen(view_weapon) - 4] = '\0';
weapon = view_weapon;
}
// See if its an entity attacking, if so lets find its owner
} else if (inflictorId >= 1 && inflictorId <= gpGlobals->maxClients) {
// We only modify the weapon if it = 0, otherwise its been specified
if(strcmp(weapon, "") == 0)
{
weapon = STRING(pKiller->v.classname);
// Strip out the default part of weapon name (HLSDK)
if(strncmp(weapon, "weapon_", 7) == 0)
{
weapon += 7;
} else if(strncmp(weapon, "monster_", 8) == 0) {
weapon += 8;
} else if(strncmp(weapon, "func_", 5) == 0) {
weapon += 5;
}
}
// Check to see if the victim is the owner
if(inflictor == pVictim)
{
pKiller = pVictim;
} else {
pKiller = inflictor;
}
}
// Send the Death Event
int killerId = ENTINDEX(pKiller);
int victimId = ENTINDEX(pVictim);
MESSAGE_BEGIN( MSG_ALL, gmsgDeathMsg );
WRITE_BYTE( killerId > gpGlobals->maxClients ? 0 : killerId );
WRITE_BYTE( victimId );
WRITE_BYTE( hs );
WRITE_STRING( weapon );
MESSAGE_END();
// Log this kill
if(pVictim == pKiller)
{
// killed self
UTIL_LogPrintf("\"%s<%i><%s><%s>\" killed self with \"%s\"\n",
STRING( pVictim->v.netname ),
GETPLAYERUSERID( pVictim ),
GETPLAYERAUTHID( pVictim ),
MF_GetPlayerTeam(victimId),
weapon );
// Killed by another player
} else if(pKiller->v.flags & (FL_CLIENT | FL_FAKECLIENT)) {
UTIL_LogPrintf("\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\"\n",
STRING( pKiller->v.netname ),
GETPLAYERUSERID( pKiller ),
GETPLAYERAUTHID( pKiller ),
MF_GetPlayerTeam(killerId),
STRING( pVictim->v.netname ),
GETPLAYERUSERID( pVictim ),
GETPLAYERAUTHID( pVictim ),
MF_GetPlayerTeam(victimId),
weapon);
int killerTeam = MF_GetPlayerTeamID(killerId);
int victimTeam = MF_GetPlayerTeamID(victimId);
if (killerTeam != victimTeam)
{
// Give Killer credit for this kill
pKiller->v.frags += 1;
} else {
pKiller->v.frags -= 1;
}
// Update the scoreboard for the killer
if (gmsgScoreInfo)
{
MESSAGE_BEGIN(MSG_ALL, gmsgScoreInfo);
WRITE_BYTE( killerId );
WRITE_SHORT( (int)pKiller->v.frags );
WRITE_SHORT( MF_GetPlayerDeaths(killerId) );
WRITE_SHORT( 0 );
WRITE_SHORT( MF_GetPlayerTeamID(killerId) );
MESSAGE_END();
}
// Give Victim back 1 point since they didn't kill themselves
pVictim->v.frags += 1;
}
// Killed by something else?
else {
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed by \"%s\"\n",
STRING( pVictim->v.netname ),
GETPLAYERUSERID( pVictim ),
GETPLAYERAUTHID( pVictim ),
MF_GetPlayerTeam(victimId),
weapon );
// Give Victim back 1 point since they didn't commit suicide
pVictim->v.frags += 1;
}
#if 0
//still a todo on this one
gInfo.logBlock = true;
#endif
int opt = BLOCK_ONCE;
MF_MessageBlock(MSGBLOCK_SET, gmsgDeathMsg, &opt);
// Kill the client, since the relevent logging blocks are in place
MDLL_ClientKill(pVictim);
// Restore the old message type
MF_MessageBlock(MSGBLOCK_SET, gmsgDeathMsg, &opt);
// Show the Victim the killing location
pVictim->v.iuser3 = (killerId > gpGlobals->maxClients) ? 0 : killerId;
}
}
}
// Damage emulation
// From VexdUM (AMX Mod 2006.2)
//This is not exposed, and is only provided as a compatibility helper.
void Damage(edict_t *pVictim,
edict_t *pAttacker,
const float *origin,
float dmg,
int bit,
const char *weapon,
int hs)
{
if (!g_ff_check && !sv_friendlyfire)
{
sv_friendlyfire = CVAR_GET_POINTER("sv_friendlyfire");
g_ff_check = true;
}
if (!gmsgDamage)
{
gmsgDamage = GET_USER_MSG_ID(PLID, "Damage", NULL);
}
// Make sure an entity is allowed to take damage
if(pVictim->v.takedamage > DAMAGE_NO)
{
// Breakable Check
if(is_breakable(pVictim) && (int)dmg > 0)
{
MDLL_Use(pVictim, pAttacker);
}
// Monster Check
if(is_monster(pVictim) && (int)dmg > 0)
{
pVictim->v.dmg_inflictor = pAttacker;
hurt_monster(pVictim, dmg, bit, origin);
}
// Player Check
if(pVictim->v.flags & (FL_CLIENT | FL_FAKECLIENT))
{
int AttackerId = ENTINDEX(pAttacker);
int AttackerOwnerId = ENTINDEX(pAttacker->v.owner);
int VictimId = ENTINDEX(pVictim);
int vTeam = MF_GetPlayerTeamID(VictimId);
int aTeam = 0;
if (AttackerId >= 1 && AttackerId <= gpGlobals->maxClients)
{
aTeam = MF_GetPlayerTeamID(AttackerId);
} else if (AttackerOwnerId >= 1 && AttackerOwnerId <= gpGlobals->maxClients) {
aTeam = MF_GetPlayerTeamID(AttackerOwnerId);
}
if((sv_friendlyfire && (int)sv_friendlyfire->value) || (vTeam != aTeam))
{
// Recalculate the damage since we might have armor
dmg = ArmorDamage(pVictim, dmg, bit);
// Only allow damage to process if more than 0.5
if((int)dmg > 0)
{
// Setting to externally flag who last attacked the Victim, pretty neat huh?
pVictim->v.dmg_inflictor = pAttacker;
pVictim->v.dmg_take += dmg;
// Register the Damage Event
MESSAGE_BEGIN( MSG_ONE, gmsgDamage, NULL, pVictim );
WRITE_BYTE( (int)pVictim->v.dmg_save );
WRITE_BYTE( (int)pVictim->v.dmg_take );
WRITE_LONG( bit );
WRITE_COORD( origin[0] );
WRITE_COORD( origin[1] );
WRITE_COORD( origin[2] );
MESSAGE_END();
if((int)dmg >= (int)pVictim->v.health)
{
// Kill the victim
pVictim->v.health = 0.0;
// Send info to Death system
Death(pVictim, pAttacker, weapon, hs);
}else {
// Take health away from victim
pVictim->v.health -= dmg;
}
}
}
}
}
}
// Radius Damage emulation -
// From VexdUM (AMX Mod 2006.2)
//This is not exposed, and is only provided as a compatibility helper.
void RadiusDamage_AMXMod_Base(edict_t *pAttacker,
float dmg,
Vector vecSrc,
float rad,
int bit,
const char *weapon,
int hs)
{
edict_t *pTarget = NULL;
TraceResult tr;
float falloff;
Vector vecSpot;
Vector vecSee;
if (!g_kb1_check && !sv_knockback1)
{
sv_knockback1 = CVAR_GET_POINTER("sv_knockback1");
g_kb1_check = true;
}
if (!g_kb2_check && !sv_knockback2)
{
sv_knockback2 = CVAR_GET_POINTER("sv_knockback2");
g_kb2_check = true;
}
if(rad > 0.0)
{
falloff = dmg / rad;
} else {
falloff = 1.0;
}
vecSrc.z += 1; // In case grenade is lying on the ground
int hitId;
int targetId;
while ((pTarget = UTIL_FindEntityInSphere(pTarget, vecSrc, rad)) != NULL)
{
// Make sure an entity is allowed to take damage
if (pTarget->v.takedamage > DAMAGE_NO)
{
//none of this code was working so I simplified it
//damage doesn't check for visibility now (it probably shouldn't anyway)
//for this to work it seems like an exception needs to be made for world OR
// the spot/see things aren't being calculated right.
#if 0
vecSpot = (pTarget->v.absmin + pTarget->v.absmax) * 0.5;
vecSee = (pAttacker->v.absmin + pAttacker->v.absmax) * 0.5;
TRACE_LINE(vecSee, vecSpot, FALSE, pAttacker, &tr);
// Explosion can 'see' this entity, so hurt them!
#endif
TRACE_LINE(vecSrc, pTarget->v.origin, FALSE, pAttacker, &tr);
hitId = ENTINDEX(tr.pHit);
targetId = ENTINDEX(pTarget);
if(tr.flFraction < 1.0 || (hitId == targetId))
{
// Work out the distance between impact and entity
float dist = (tr.vecEndPos - vecSrc).Length() * falloff;
// Damage algorithm, its just that easy :)
dmg -= dist;
// Knockback Effect
if(pTarget->v.flags & (FL_CLIENT | FL_FAKECLIENT) && (bit & (DMG_BLAST | DMG_CLUB | DMG_SHOCK | DMG_SONIC | DMG_ENERGYBEAM | DMG_MORTAR)))
{
Vector vecPush = (pTarget->v.origin - (pAttacker->v.absmin + pAttacker->v.absmax) * 0.5).Normalize();
if(dmg < 60.0)
{
pTarget->v.velocity = pTarget->v.velocity + vecPush * dmg * (sv_knockback1 ? sv_knockback1->value : 1.0f);
} else {
pTarget->v.velocity = pTarget->v.velocity + vecPush * dmg * (sv_knockback2 ? sv_knockback2->value : 1.0f);
}
}
// Send info to Damage system
Damage(pTarget, pAttacker, vecSrc, dmg, bit, weapon, hs);
}
}
}
pTarget = NULL;
}

View File

@ -0,0 +1,25 @@
#ifndef _INCLUDE_ENGINE_AMXMOD_BCOMPAT_H_
#define _INCLUDE_ENGINE_AMXMOD_BCOMPAT_H_
BOOL is_breakable(edict_t* pBreak);
BOOL is_monster(edict_t* pMonster);
void hurt_monster(edict_t* pMonster, float dmg, int bit, const float *origin);
float ArmorDamage(edict_t* pVictim, float dmg, int bit);
void Death(edict_t* pVictim, edict_t* pKiller, const char* weapon, int hs);
void Damage(edict_t *pVictim,
edict_t *pAttacker,
const float *origin,
float dmg,
int bit,
const char *weapon,
int hs);
void RadiusDamage_AMXMod_Base(edict_t *pAttacker,
float dmg,
Vector vecSrc,
float rad,
int bit,
const char *weapon,
int hs);
#endif //_INCLUDE_ENGINE_AMXMOD_BCOMPAT_H_

View File

@ -37,7 +37,9 @@ void OnAmxxAttach()
CmdStartForward = 0;
StartFrameForward = 0;
MF_AddNatives(ent_Natives);
MF_AddNewNatives(ent_NewNatives);
MF_AddNatives(engine_Natives);
MF_AddNewNatives(engine_NewNatives);
MF_AddNatives(global_Natives);
memset(glinfo.szLastLights, 0x0, 128);
memset(glinfo.szRealLights, 0x0, 128);

View File

@ -2437,6 +2437,7 @@ static amxx_module_info_s g_ModuleInfo =
// Storage for the requested functions
PFN_ADD_NATIVES g_fn_AddNatives;
PFN_ADD_NEW_NATIVES g_fn_AddNewNatives;
PFN_BUILD_PATHNAME g_fn_BuildPathname;
PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
PFN_GET_AMXADDR g_fn_GetAmxAddr;
@ -2513,6 +2514,9 @@ PFN_ADDLIBRARIES g_fn_AddLibraries;
PFN_REMOVELIBRARIES g_fn_RemoveLibraries;
PFN_OVERRIDENATIVES g_fn_OverrideNatives;
PFN_GETLOCALINFO g_fn_GetLocalInfo;
PFN_AMX_REREGISTER g_fn_AmxReRegister;
PFN_REGISTERFUNCTIONEX g_fn_RegisterFunctionEx;
PFN_MESSAGE_BLOCK g_fn_MessageBlock;
// *** Exports ***
C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo)
@ -2563,6 +2567,7 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
REQFUNC("MergeDefinitionFile", g_fn_MergeDefinition_File, PFN_MERGEDEFINITION_FILE);
REQFUNC("Format", g_fn_Format, PFN_FORMAT);
REQFUNC("RegisterFunction", g_fn_RegisterFunction, PFN_REGISTERFUNCTION);
REQFUNC("RegisterFunctionEx", g_fn_RegisterFunctionEx, PFN_REGISTERFUNCTIONEX);
// Amx scripts
REQFUNC("GetAmxScript", g_fn_GetAmxScript, PFN_GET_AMXSCRIPT);
@ -2588,6 +2593,7 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
// Natives / Forwards
REQFUNC("AddNatives", g_fn_AddNatives, PFN_ADD_NATIVES);
REQFUNC("AddNewNatives", g_fn_AddNewNatives, PFN_ADD_NEW_NATIVES);
REQFUNC("RaiseAmxError", g_fn_RaiseAmxError, PFN_RAISE_AMXERROR);
REQFUNC("RegisterForward", g_fn_RegisterForward, PFN_REGISTER_FORWARD);
REQFUNC("RegisterSPForward", g_fn_RegisterSPForward, PFN_REGISTER_SPFORWARD);
@ -2627,11 +2633,15 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
REQFUNC("RegAuthFunc", g_fn_RegAuthFunc, PFN_REG_AUTH_FUNC);
REQFUNC("UnregAuthFunc", g_fn_UnregAuthFunc, PFN_UNREG_AUTH_FUNC);
//Added in 1.75
REQFUNC("FindLibrary", g_fn_FindLibrary, PFN_FINDLIBRARY);
REQFUNC("AddLibraries", g_fn_AddLibraries, PFN_ADDLIBRARIES);
REQFUNC("RemoveLibraries", g_fn_RemoveLibraries, PFN_REMOVELIBRARIES);
REQFUNC("OverrideNatives", g_fn_OverrideNatives, PFN_OVERRIDENATIVES);
REQFUNC("GetLocalInfo", g_fn_GetLocalInfo, PFN_GETLOCALINFO);
REQFUNC("AmxReregister", g_fn_AmxReRegister, PFN_AMX_REREGISTER);
REQFUNC("MessageBlock", g_fn_MessageBlock, PFN_MESSAGE_BLOCK);
#ifdef MEMORY_TEST
// Memory
@ -2766,6 +2776,7 @@ void ValidateMacros_DontCallThis_Smiley()
MF_GetPlayerEdict(0);
MF_Format("", 4, "str");
MF_RegisterFunction(NULL, "");
MF_RegisterFunctionEx(NULL, "");
MF_SetPlayerTeamInfo(0, 0, "");
MF_PlayerPropAddr(0, 0);
MF_RegAuthFunc(NULL);
@ -2773,7 +2784,8 @@ void ValidateMacros_DontCallThis_Smiley()
MF_FindLibrary(NULL, LibType_Class);
MF_AddLibraries(NULL, LibType_Class, NULL);
MF_RemoveLibraries(NULL);
MF_OverrideNatives(NULL, "");
MF_OverrideNatives(NULL, NULL);
MF_MessageBlock(0, 0, NULL);
}
#endif

View File

@ -2095,9 +2095,16 @@ enum LibType
LibType_Class
};
#define MSGBLOCK_SET 0
#define MSGBLOCK_GET 1
#define BLOCK_NOT 0
#define BLOCK_ONCE 1
#define BLOCK_SET 2
typedef void (*AUTHORIZEFUNC)(int player, const char *authstring);
typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
typedef int (*PFN_ADD_NEW_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
typedef char * (*PFN_BUILD_PATHNAME) (const char * /*format*/, ...);
typedef char * (*PFN_BUILD_PATHNAME_R) (char * /*buffer*/, size_t /* maxlen */, const char * /* format */, ...);
typedef cell * (*PFN_GET_AMXADDR) (AMX * /*amx*/, cell /*offset*/);
@ -2183,8 +2190,10 @@ typedef void (*PFN_OVERRIDENATIVES) (AMX_NATIVE_INFO * /*natives*/, const ch
typedef const char * (*PFN_GETLOCALINFO) (const char * /*name*/, const char * /*def*/);
typedef int (*PFN_AMX_REREGISTER) (AMX * /*amx*/, AMX_NATIVE_INFO * /*list*/, int /*list*/);
typedef void * (*PFN_REGISTERFUNCTIONEX) (void * /*pfn*/, const char * /*desc*/);
typedef void (*PFN_MESSAGE_BLOCK) (int /* mode */, int /* message */, int * /* opt */);
extern PFN_ADD_NATIVES g_fn_AddNatives;
extern PFN_ADD_NEW_NATIVES g_fn_AddNewNatives;
extern PFN_BUILD_PATHNAME g_fn_BuildPathname;
extern PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
extern PFN_GET_AMXADDR g_fn_GetAmxAddr;
@ -2257,11 +2266,13 @@ extern PFN_OVERRIDENATIVES g_fn_OverrideNatives;
extern PFN_GETLOCALINFO g_fn_GetLocalInfo;
extern PFN_AMX_REREGISTER g_fn_AmxReRegister;
extern PFN_REGISTERFUNCTIONEX g_fn_RegisterFunctionEx;
extern PFN_MESSAGE_BLOCK g_fn_MessageBlock;
#ifdef MAY_NEVER_BE_DEFINED
// Function prototypes for intellisense and similar systems
// They understand #if 0 so we use #ifdef MAY_NEVER_BE_DEFINED
int MF_AddNatives (const AMX_NATIVE_INFO *list) { }
int MF_AddNewNatives (const AMX_NATIVE_INFO *list) { }
char * MF_BuildPathname (const char * format, ...) { }
char * MF_BuildPathnameR (char *buffer, size_t maxlen, const char *fmt, ...) { }
cell * MF_GetAmxAddr (AMX * amx, cell offset) { }
@ -2328,9 +2339,11 @@ void MF_OverrideNatives (AMX_NATIVE_INFO *natives, const char *myname) { }
const char * MF_GetLocalInfo (const char *name, const char *def) { }
int MF_AmxReRegister (AMX *amx, AMX_NATIVE_INFO *list, int number) { return 0; }
void * MF_RegisterFunctionEx (void *pfn, const char *description) { }
void * MF_MessageBlock (int mode, int msg, int *opt) { }
#endif // MAY_NEVER_BE_DEFINED
#define MF_AddNatives g_fn_AddNatives
#define MF_AddNewNatives g_fn_AddNewNatives
#define MF_BuildPathname g_fn_BuildPathname
#define MF_BuildPathnameR g_fn_BuildPathnameR
#define MF_FormatAmxString g_fn_FormatAmxString
@ -2404,6 +2417,7 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...);
#define MF_GetLocalInfo g_fn_GetLocalInfo
#define MF_AmxReRegister g_fn_AmxReRegister
#define MF_RegisterFunctionEx g_fn_RegisterFunctionEx
#define MF_MessageBlock g_fn_MessageBlock
#ifdef MEMORY_TEST
/*** Memory ***/

View File

@ -1,4 +1,5 @@
#include "engine.h"
#include "amxmod_compat.h"
struct usercmd_s *g_cmd;
struct PlayerInfo plinfo[33];
@ -97,11 +98,33 @@ static cell AMX_NATIVE_CALL halflife_time(AMX *amx, cell *params)
return amx_ftoc(fVal);
}
// RadiusDamage. Damages players within a certain radius. ToDo: add the
// damage messaging so players know where the damage is coming from
// (the red arrow-like things on the screen).
//(vexd)
static cell AMX_NATIVE_CALL RadiusDamage(AMX *amx, cell *params) {
//This is not exposed, and is only provided as a compatibility helper.
static cell AMX_NATIVE_CALL RadiusDamage_AMXMod(AMX *amx, cell *params)
{
int ent = params[1];
CHECK_ENTITY_SIMPLE(ent);
edict_t* pEntity = INDEXENT(ent);
float dmg = amx_ctof(params[2]);
cell *vInput = MF_GetAmxAddr(amx, params[3]);
float vOrig[3];
vOrig[0] = amx_ctof(vInput[0]);
vOrig[1] = amx_ctof(vInput[1]);
vOrig[2] = amx_ctof(vInput[2]);
float rad = amx_ctof(params[4]);
int bit = params[5];
int iLen;
char *vxWeapon = MF_GetAmxString(amx, params[6], 0, &iLen);
int hs = params[7];
RadiusDamage_AMXMod_Base(pEntity, dmg, vOrig, rad, bit, vxWeapon, hs);
return 1;
}
static cell AMX_NATIVE_CALL RadiusDamage_AMXModX(AMX *amx, cell *params)
{
cell *cAddr = MF_GetAmxAddr(amx,params[1]);
REAL fCurrentX = amx_ctof(cAddr[0]);
@ -164,6 +187,24 @@ static cell AMX_NATIVE_CALL RadiusDamage(AMX *amx, cell *params) {
return 1;
}
// RadiusDamage. Damages players within a certain radius. ToDo: add the
// damage messaging so players know where the damage is coming from
// (the red arrow-like things on the screen).
//(vexd)
static cell AMX_NATIVE_CALL RadiusDamage(AMX *amx, cell *params)
{
cell numParams = params[0] / sizeof(cell);
if (numParams == 3)
{
return RadiusDamage_AMXModX(amx, params);
} else if (numParams == 7) {
return RadiusDamage_AMXMod(amx, params);
}
return 0;
}
static cell AMX_NATIVE_CALL PointContents(AMX *amx, cell *params)
{
cell *cAddr = MF_GetAmxAddr(amx, params[1]);
@ -926,6 +967,12 @@ static cell AMX_NATIVE_CALL trace_forward(AMX *amx, cell *params)
return 1;
}
AMX_NATIVE_INFO engine_NewNatives[] =
{
{"trace_line", trace_line},
{NULL, NULL}
};
AMX_NATIVE_INFO engine_Natives[] = {
{"halflife_time", halflife_time},
@ -934,7 +981,6 @@ AMX_NATIVE_INFO engine_Natives[] = {
{"radius_damage", RadiusDamage},
{"point_contents", PointContents},
{"trace_normal", trace_normal},
{"trace_line", trace_line},
{"trace_hull", trace_hull},
{"traceresult", traceresult},
@ -965,6 +1011,6 @@ AMX_NATIVE_INFO engine_Natives[] = {
{"is_visible", is_visible},
{"trace_forward", trace_forward},
{NULL, NULL},
{NULL, NULL}
///////////////////
};

View File

@ -210,6 +210,7 @@ extern struct usercmd_s *g_cmd;
extern struct PlayerInfo plinfo[33];
extern struct GlobalInfo glinfo;
extern AMX_NATIVE_INFO engine_Natives[];
extern AMX_NATIVE_INFO engine_NewNatives[];
extern CVector<Impulse *> Impulses;
extern CVector<EntClass *> Thinks;
extern CVector<Touch *> Touches;

View File

@ -117,6 +117,9 @@
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\amxmod_compat.cpp">
</File>
<File
RelativePath=".\amxxapi.cpp">
</File>
@ -137,6 +140,9 @@
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\amxmod_compat.h">
</File>
<File
RelativePath=".\CString.h">
</File>

View File

@ -1509,6 +1509,12 @@ static cell AMX_NATIVE_CALL get_grenade_id(AMX *amx, cell *params) /* 4 param *
return 0;
}
AMX_NATIVE_INFO ent_NewNatives[] =
{
{"DispatchKeyValue", DispatchKeyValue},
{NULL, NULL}
};
AMX_NATIVE_INFO ent_Natives[] = {
{"create_entity", create_entity},
{"remove_entity", remove_entity},
@ -1532,7 +1538,6 @@ AMX_NATIVE_INFO ent_Natives[] = {
{"entity_set_origin", entity_set_origin},
{"entity_set_model", entity_set_model},
{"entity_set_size", entity_set_size},
{"DispatchKeyValue", DispatchKeyValue},
{"DispatchSpawn", DispatchSpawn},
{"call_think", call_think},
@ -1554,7 +1559,7 @@ AMX_NATIVE_INFO ent_Natives[] = {
{"copy_keyvalue", copy_keyvalue},
{NULL, NULL},
{NULL, NULL}
///////////////////
};

View File

@ -151,6 +151,7 @@ enum {
void UTIL_SetSize(edict_t *pev, const Vector &vecMin, const Vector &vecMax);
extern AMX_NATIVE_INFO ent_Natives[];
extern AMX_NATIVE_INFO ent_NewNatives[];
#endif //_INCLUDE_ENGINE_ENTSTUFF