merged bcompat changed into trunk
removed amxmod compat files for now
This commit is contained in:
parent
95537e4840
commit
78956f3d89
|
@ -33,6 +33,7 @@
|
|||
#include "amxmodx.h"
|
||||
#include "CLang.h"
|
||||
#include "format.h"
|
||||
#include "amxmod_compat.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#define _snprintf snprintf
|
||||
|
@ -287,7 +288,23 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
|||
static char outbuf[4096];
|
||||
cell *addr = get_amxaddr(amx, params[parm++]);
|
||||
|
||||
if (amx->flags & AMX_FLAG_OLDFILE)
|
||||
{
|
||||
if (*addr & BCOMPAT_TRANSLATE_BITS)
|
||||
{
|
||||
const char *key, *def;
|
||||
if (!translate_bcompat(amx, addr, &key, &def))
|
||||
{
|
||||
goto normal_string;
|
||||
}
|
||||
len = atcprintf(outbuf, sizeof(outbuf)-1, def, amx, params, &parm);
|
||||
} else {
|
||||
goto normal_string;
|
||||
}
|
||||
} else {
|
||||
normal_string:
|
||||
len = atcprintf(outbuf, sizeof(outbuf)-1, addr, amx, params, &parm);
|
||||
}
|
||||
|
||||
return outbuf;
|
||||
}
|
||||
|
|
|
@ -89,6 +89,7 @@ void CModule::clear(bool clearFilename)
|
|||
|
||||
m_DestroyableIndexes.clear();
|
||||
m_Natives.clear();
|
||||
m_NewNatives.clear();
|
||||
}
|
||||
|
||||
bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now)
|
||||
|
|
|
@ -117,6 +117,7 @@ public:
|
|||
void CallPluginsUnloading();
|
||||
|
||||
CVector<AMX_NATIVE_INFO*> m_Natives;
|
||||
CVector<AMX_NATIVE_INFO*> m_NewNatives; // Natives for new (AMXX, not AMX) plugins only
|
||||
CVector<size_t> m_DestroyableIndexes;
|
||||
};
|
||||
|
||||
|
|
|
@ -447,7 +447,8 @@ char *CPluginMngr::ReadIntoOrFromCache(const char *file, size_t &bufsize)
|
|||
|
||||
pl->file = new CAmxxReader(file, sizeof(cell));
|
||||
pl->buffer = NULL;
|
||||
if (pl->file->GetStatus() != CAmxxReader::Err_None)
|
||||
if (pl->file->GetStatus() != CAmxxReader::Err_None ||
|
||||
pl->file->IsOldFile())
|
||||
{
|
||||
delete pl->file;
|
||||
delete pl;
|
||||
|
|
|
@ -19,7 +19,8 @@ OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules
|
|||
srvcmd.cpp strptime.cpp amxcore.cpp amxtime.cpp power.cpp amxxlog.cpp fakemeta.cpp \
|
||||
amxxfile.cpp CLang.cpp md5.cpp emsg.cpp CForward.cpp CPlugin.cpp CModule.cpp \
|
||||
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp debugger.cpp \
|
||||
optimizer.cpp format.cpp messages.cpp libraries.cpp vector.cpp sorting.cpp
|
||||
optimizer.cpp format.cpp messages.cpp libraries.cpp vector.cpp sorting.cpp \
|
||||
amxmod_compat.cpp
|
||||
|
||||
LINK = -lgcc -static-libgcc
|
||||
|
||||
|
|
136
amxmodx/amxmod_compat.cpp
Normal file
136
amxmodx/amxmod_compat.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
#include "amxmodx.h"
|
||||
#include "amxmod_compat.h"
|
||||
#include "format.h"
|
||||
|
||||
struct translate_result
|
||||
{
|
||||
int suki;
|
||||
int dest;
|
||||
int lang;
|
||||
};
|
||||
|
||||
CVector<translate_result *> g_tr_results;
|
||||
CStack<size_t> g_old_ids;
|
||||
|
||||
bool GetTranslation(int id, int &key, int &dest, int &lang)
|
||||
{
|
||||
if (id < 0 || (unsigned int)id > g_tr_results.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
translate_result *pRes = g_tr_results[id];
|
||||
|
||||
key = pRes->suki;
|
||||
dest = pRes->dest;
|
||||
lang = pRes->lang;
|
||||
|
||||
g_old_ids.push((size_t)id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClearTransCache()
|
||||
{
|
||||
for (size_t i=0; i<g_tr_results.size(); i++)
|
||||
{
|
||||
delete g_tr_results[i];
|
||||
}
|
||||
g_tr_results.clear();
|
||||
|
||||
while (!g_old_ids.empty())
|
||||
{
|
||||
g_old_ids.pop();
|
||||
}
|
||||
}
|
||||
|
||||
bool translate_bcompat(AMX *amx, cell *source, const char **_key, const char **_def)
|
||||
{
|
||||
unsigned int trans = static_cast<unsigned int>(*source);
|
||||
trans &= ~BCOMPAT_TRANSLATE_BITS;
|
||||
int key, _dest, lang;
|
||||
if (!GetTranslation(trans, key, _dest, lang))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
cell amx_addr, *phys_addr;
|
||||
if (amx_Allot(amx, 3, &amx_addr, &phys_addr) != AMX_ERR_NONE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_dest == -1)
|
||||
{
|
||||
*phys_addr = LANG_PLAYER;
|
||||
} else if (_dest == 0) {
|
||||
*phys_addr = LANG_SERVER;
|
||||
} else if (lang >= 0 && lang < g_langMngr.GetLangsNum()) {
|
||||
const char *name = g_langMngr.GetLangName(lang);
|
||||
phys_addr[0] = static_cast<cell>(name[0]);
|
||||
phys_addr[1] = static_cast<cell>(name[1]);
|
||||
phys_addr[2] = static_cast<cell>('\0');
|
||||
} else {
|
||||
*phys_addr = LANG_SERVER;
|
||||
}
|
||||
|
||||
//not optimized but it works, eh
|
||||
//if someone cares they can make a translate() wrapper that takes the key # in directly
|
||||
const char *r_key = g_langMngr.GetKey(key);
|
||||
const char *def = translate(amx, amx_addr, r_key);
|
||||
if (!def)
|
||||
{
|
||||
def = r_key;
|
||||
}
|
||||
amx_Release(amx, amx_addr);
|
||||
|
||||
*_key = g_langMngr.GetKey(key);
|
||||
*_def = def;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_translate(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *key = get_amxstring(amx, params[1], 0, len);
|
||||
|
||||
translate_result *pRes;
|
||||
size_t id;
|
||||
if (g_old_ids.empty())
|
||||
{
|
||||
pRes = new translate_result;
|
||||
id = g_tr_results.size();
|
||||
g_tr_results.push_back(pRes);
|
||||
} else {
|
||||
if (g_tr_results.size() >= BCOMPAT_TRANSLATE_MAX)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Exceeded bcompat translation limit of %d!", BCOMPAT_TRANSLATE_MAX);
|
||||
return 0;
|
||||
}
|
||||
id = g_old_ids.front();
|
||||
g_old_ids.pop();
|
||||
pRes = g_tr_results[id];
|
||||
}
|
||||
|
||||
pRes->suki = g_langMngr.GetKeyEntry(key);
|
||||
|
||||
//Some AMX Mod plugins do not register everything they need. Prevent a crash.
|
||||
if (pRes->suki == -1)
|
||||
{
|
||||
pRes->suki = g_langMngr.AddKeyEntry(key);
|
||||
}
|
||||
|
||||
pRes->dest = params[2];
|
||||
pRes->lang = params[3];
|
||||
|
||||
return (cell)((unsigned int)BCOMPAT_TRANSLATE_BITS | (unsigned int)id);
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO g_BcompatNatives[] =
|
||||
{
|
||||
{"translate", amx_translate},
|
||||
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
12
amxmodx/amxmod_compat.h
Normal file
12
amxmodx/amxmod_compat.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef _INCLUDE_AMXMOD_CORE_COMPAT_H
|
||||
#define _INCLUDE_AMXMOD_CORE_COMPAT_H
|
||||
|
||||
#define BCOMPAT_TRANSLATE_BITS 0xFFFFF400
|
||||
#define BCOMPAT_TRANSLATE_MAX 0x400
|
||||
|
||||
bool GetTranslation(int id, int &key, int &dest, int &lang);
|
||||
void ClearTransCache();
|
||||
|
||||
extern AMX_NATIVE_INFO g_BcompatNatives[];
|
||||
|
||||
#endif //_INCLUDE_AMXMOD_CORE_COMPAT_H
|
|
@ -608,6 +608,7 @@ const char *Debugger::_GetFilename()
|
|||
void Debugger::FmtGenericMsg(AMX *amx, int error, char buffer[], size_t maxLength)
|
||||
{
|
||||
const char *filename = "";
|
||||
char native[sNAMEMAX+1];
|
||||
|
||||
CList<CScript,AMX*>::iterator a = g_loadedscripts.find(amx);
|
||||
if (a)
|
||||
|
@ -625,6 +626,9 @@ void Debugger::FmtGenericMsg(AMX *amx, int error, char buffer[], size_t maxLengt
|
|||
if (error == AMX_ERR_EXIT)
|
||||
{
|
||||
_snprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") - %s", error, filename, GenericError(AMX_ERR_EXIT));
|
||||
} else if (error == AMX_ERR_NATIVE) {
|
||||
amx_GetNative(amx, (int)amx->usertags[UT_NATIVE], native);
|
||||
_snprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") (native \"%s\") - debug not enabled!", error, filename, native);
|
||||
} else {
|
||||
_snprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") - debug not enabled!", error, filename);
|
||||
}
|
||||
|
|
|
@ -424,6 +424,54 @@ static cell AMX_NATIVE_CALL n_floatatan2(AMX *amx, cell *params)
|
|||
return amx_ftoc(fC);
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
/* Added by DS */
|
||||
static cell AMX_NATIVE_CALL n_floatsinh(AMX *amx, cell *params)
|
||||
{
|
||||
/*
|
||||
* params[1] = angle
|
||||
* params[2] = radix
|
||||
*/
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
fA = ToRadians(fA, params[2]);
|
||||
fA = sinh(fA);
|
||||
return amx_ftoc(fA);
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
/* Added by DS */
|
||||
static cell AMX_NATIVE_CALL n_floatcosh(AMX *amx, cell *params)
|
||||
{
|
||||
/*
|
||||
* params[1] = angle
|
||||
* params[2] = radix
|
||||
*/
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
fA = ToRadians(fA, params[2]);
|
||||
fA = cosh(fA);
|
||||
return amx_ftoc(fA);
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
/* Added by DS */
|
||||
static cell AMX_NATIVE_CALL n_floattanh(AMX *amx, cell *params)
|
||||
{
|
||||
/*
|
||||
* params[1] = angle
|
||||
* params[2] = radix
|
||||
*/
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
fA = ToRadians(fA, params[2]);
|
||||
fA = tanh(fA);
|
||||
return amx_ftoc(fA);
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
|
@ -456,6 +504,9 @@ AMX_NATIVE_INFO float_Natives[] = {
|
|||
{ "floatacos", n_floatacos },
|
||||
{ "floatatan", n_floatatan },
|
||||
{ "floatatan2", n_floatatan2 },
|
||||
{ "floatsinh", n_floatsinh },
|
||||
{ "floatcosh", n_floatcosh },
|
||||
{ "floattanh", n_floattanh },
|
||||
{ NULL, NULL } /* terminator */
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "amxmodx.h"
|
||||
#include "format.h"
|
||||
#include "amxmod_compat.h"
|
||||
|
||||
//Adapted from Quake3's vsprintf
|
||||
// thanks to cybermind for linking me to this :)
|
||||
|
@ -422,6 +423,24 @@ reswitch:
|
|||
break;
|
||||
case 's':
|
||||
CHECK_ARGS(0);
|
||||
if (amx->flags & AMX_FLAG_OLDFILE)
|
||||
{
|
||||
cell *addr = get_amxaddr(amx, params[arg]);
|
||||
if (*addr & BCOMPAT_TRANSLATE_BITS)
|
||||
{
|
||||
const char *key, *def;
|
||||
if (!translate_bcompat(amx, addr, &key, &def))
|
||||
{
|
||||
goto break_to_normal_string;
|
||||
}
|
||||
arg++;
|
||||
size_t written = atcprintf(buf_p, llen, def, amx, params, &arg);
|
||||
buf_p += written;
|
||||
llen -= written;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break_to_normal_string:
|
||||
AddString(&buf_p, llen, get_amxaddr(amx, params[arg]), width, prec);
|
||||
arg++;
|
||||
break;
|
||||
|
|
|
@ -5,4 +5,7 @@
|
|||
template <typename D, typename S>
|
||||
size_t atcprintf(D *buffer, size_t maxlen, const S *format, AMX *amx, cell *params, int *param);
|
||||
|
||||
const char *translate(AMX *amx, cell amxaddr, const char *key);
|
||||
bool translate_bcompat(AMX *amx, cell *source, const char **_key, const char **_def);
|
||||
|
||||
#endif //_INCLUDE_FORMATTING_H
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "optimizer.h"
|
||||
#include "libraries.h"
|
||||
#include "messages.h"
|
||||
#include "amxmod_compat.h"
|
||||
|
||||
plugin_info_t Plugin_info =
|
||||
{
|
||||
|
@ -357,6 +358,14 @@ int C_Spawn(edict_t *pent)
|
|||
get_localinfo("amxx_configsdir", "addons/amxmodx/configs");
|
||||
get_localinfo("amxx_customdir", "addons/amxmodx/custom");
|
||||
|
||||
// make sure bcompat localinfos are set
|
||||
get_localinfo("amx_basedir", "addons/amxmodx");
|
||||
get_localinfo("amx_configdir", "addons/amxmodx/configs");
|
||||
get_localinfo("amx_langdir", "addons/amxmodx/data/amxmod-lang");
|
||||
get_localinfo("amx_modulesdir", "addons/amxmodx/modules");
|
||||
get_localinfo("amx_pluginsdir", "addons/amxmodx/plugins");
|
||||
get_localinfo("amx_logdir", "addons/amxmodx/logs");
|
||||
|
||||
char map_pluginsfile_path[256];
|
||||
|
||||
// ###### Load modules
|
||||
|
@ -619,6 +628,7 @@ void C_ServerDeactivate_Post()
|
|||
g_xvars.clear();
|
||||
g_plugins.clear();
|
||||
ClearPluginLibraries();
|
||||
ClearTransCache();
|
||||
modules_callPluginsUnloaded();
|
||||
|
||||
ClearMessages();
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "binlog.h"
|
||||
#include "libraries.h"
|
||||
#include "messages.h"
|
||||
#include "amxmod_compat.h"
|
||||
|
||||
CList<CModule, const char*> g_modules;
|
||||
CList<CScript, AMX*> g_loadedscripts;
|
||||
|
@ -165,6 +166,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
|
|||
*error = 0;
|
||||
size_t bufSize;
|
||||
*program = (void *)g_plugins.ReadIntoOrFromCache(filename, bufSize);
|
||||
bool oldfile = false;
|
||||
if (!*program)
|
||||
{
|
||||
CAmxxReader reader(filename, PAWN_CELL_SIZE / 8);
|
||||
|
@ -218,6 +220,8 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
|
|||
strcpy(error, "Unknown error");
|
||||
return (amx->error = AMX_ERR_NOTFOUND);
|
||||
}
|
||||
|
||||
oldfile = reader.IsOldFile();
|
||||
} else {
|
||||
g_plugins.InvalidateFileInCache(filename, false);
|
||||
}
|
||||
|
@ -369,6 +373,17 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
|
|||
}
|
||||
#endif
|
||||
|
||||
if (oldfile)
|
||||
{
|
||||
amx->flags |= AMX_FLAG_OLDFILE;
|
||||
} else {
|
||||
cell addr;
|
||||
if (amx_FindPubVar(amx, "__b_old_plugin", &addr) == AMX_ERR_NONE)
|
||||
{
|
||||
amx->flags |= AMX_FLAG_OLDFILE;
|
||||
}
|
||||
}
|
||||
|
||||
CScript* aa = new CScript(amx, *program, filename);
|
||||
|
||||
g_loadedscripts.put(aa);
|
||||
|
@ -542,6 +557,12 @@ int set_amxnatives(AMX* amx, char error[128])
|
|||
{
|
||||
amx_Register(amx, cm->m_Natives[i], -1);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < cm->m_NewNatives.size(); i++)
|
||||
{
|
||||
if (!(amx->flags & AMX_FLAG_OLDFILE))
|
||||
amx_Register(amx, cm->m_NewNatives[i], -1);
|
||||
}
|
||||
}
|
||||
|
||||
amx_Register(amx, string_Natives, -1);
|
||||
|
@ -558,6 +579,11 @@ int set_amxnatives(AMX* amx, char error[128])
|
|||
amx_Register(amx, vector_Natives, -1);
|
||||
amx_Register(amx, g_SortNatives, -1);
|
||||
|
||||
if (amx->flags & AMX_FLAG_OLDFILE)
|
||||
{
|
||||
amx_Register(amx, g_BcompatNatives, -1);
|
||||
}
|
||||
|
||||
//we're not actually gonna check these here anymore
|
||||
amx->flags |= AMX_FLAG_PRENIT;
|
||||
|
||||
|
@ -1178,6 +1204,18 @@ int MNF_AddNatives(AMX_NATIVE_INFO* natives)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
int MNF_AddNewNatives(AMX_NATIVE_INFO *natives)
|
||||
{
|
||||
CList<CModule, const char *>::iterator a = g_modules.begin();
|
||||
|
||||
if (!g_CurrentlyCalledModule || g_ModuleCallReason != ModuleCall_Attach)
|
||||
return FALSE; // may only be called from attach
|
||||
|
||||
g_CurrentlyCalledModule->m_NewNatives.push_back(natives);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const char *MNF_GetModname(void)
|
||||
{
|
||||
// :TODO: Do we have to do this??
|
||||
|
@ -1870,6 +1908,7 @@ void Module_CacheFunctions()
|
|||
|
||||
// Natives / Forwards
|
||||
REGISTER_FUNC("AddNatives", MNF_AddNatives)
|
||||
REGISTER_FUNC("AddNewNatives", MNF_AddNewNatives)
|
||||
REGISTER_FUNC("RaiseAmxError", amx_RaiseError)
|
||||
REGISTER_FUNC("RegisterForward", registerForward)
|
||||
REGISTER_FUNC("RegisterSPForward", registerSPForward)
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "amxmodx.h"
|
||||
#include "format.h"
|
||||
#include "binlog.h"
|
||||
#include "amxmod_compat.h"
|
||||
|
||||
const char* stristr(const char* str, const char* substr)
|
||||
{
|
||||
|
@ -115,8 +116,21 @@ extern "C" size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, in
|
|||
register char *dest = destination;
|
||||
char *start = dest;
|
||||
|
||||
if ( (amx->flags & AMX_FLAG_OLDFILE) &&
|
||||
(*source & BCOMPAT_TRANSLATE_BITS) )
|
||||
{
|
||||
const char *def, *key;
|
||||
if (!translate_bcompat(amx, source, &key, &def))
|
||||
{
|
||||
goto normal_string;
|
||||
}
|
||||
while (maxlen-- && *def)
|
||||
*dest++=(*source++);
|
||||
} else {
|
||||
normal_string:
|
||||
while (maxlen-- && *source)
|
||||
*dest++=(char)(*source++);
|
||||
}
|
||||
|
||||
*dest = '\0';
|
||||
|
||||
|
@ -139,9 +153,22 @@ char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len)
|
|||
register char* dest = buffor[id];
|
||||
char* start = dest;
|
||||
|
||||
if ( (amx->flags & AMX_FLAG_OLDFILE) &&
|
||||
(*source & BCOMPAT_TRANSLATE_BITS) )
|
||||
{
|
||||
const char *def, *key;
|
||||
if (!translate_bcompat(amx, source, &key, &def))
|
||||
{
|
||||
goto normal_string;
|
||||
}
|
||||
while ( (*dest++ = (*def++)) );
|
||||
len = --dest - start;
|
||||
} else {
|
||||
normal_string:
|
||||
while ((*dest++=(char)(*source++)));
|
||||
|
||||
len = --dest - start;
|
||||
}
|
||||
|
||||
#if defined BINLOG_ENABLED
|
||||
if (g_binlog_level & 2)
|
||||
|
|
|
@ -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 =
|
||||
|
||||
|
|
453
dlls/engine/amxmod_compat.cpp
Normal file
453
dlls/engine/amxmod_compat.cpp
Normal 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;
|
||||
}
|
25
dlls/engine/amxmod_compat.h
Normal file
25
dlls/engine/amxmod_compat.h
Normal 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_
|
||||
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 ***/
|
||||
|
|
|
@ -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}
|
||||
///////////////////
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}
|
||||
///////////////////
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
/* Vexd Utility backwards compatibility
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
* This file is provided as is (no warranties).
|
||||
*/
|
||||
|
||||
#if defined _Vexd_Utilities_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _Vexd_Utilities_included
|
||||
|
||||
#include <engine>
|
||||
|
||||
stock Entvars_Get_Int(iIndex, iVariable)
|
||||
return entity_get_int(iIndex, iVariable)
|
||||
|
||||
stock Entvars_Set_Int(iIndex, iVariable, iNewValue)
|
||||
return entity_set_int(iIndex, iVariable, iNewValue)
|
||||
|
||||
stock Float:Entvars_Get_Float(iIndex, iVariable)
|
||||
return entity_get_float(iIndex, iVariable)
|
||||
|
||||
stock Entvars_Set_Float(iIndex, iVariable, Float:fNewValue)
|
||||
return entity_set_float(iIndex, iVariable, fNewValue)
|
||||
|
||||
stock Entvars_Get_Vector(iIndex, iVariable, Float:vRetVector[3])
|
||||
return entity_get_vector(iIndex, iVariable, vRetVector)
|
||||
|
||||
stock Entvars_Set_Vector(iIndex, iVariable, Float:vNewVector[3])
|
||||
return entity_set_vector(iIndex, iVariable, vNewVector)
|
||||
|
||||
stock Entvars_Get_Edict(iIndex, iVariable)
|
||||
return entity_get_edict(iIndex, iVariable)
|
||||
|
||||
stock Entvars_Set_Edict(iIndex, iVariable, iNewIndex)
|
||||
return entity_set_edict(iIndex, iVariable, iNewIndex)
|
||||
|
||||
stock Entvars_Get_String(iIndex, iVariable, szReturnValue[], iReturnLen)
|
||||
return entity_get_string(iIndex, iVariable, szReturnValue, iReturnLen)
|
||||
|
||||
stock Entvars_Set_String(iIndex, iVariable, szNewValue[])
|
||||
return entity_set_string(iIndex, iVariable, szNewValue)
|
||||
|
||||
stock Entvars_Get_Byte(iIndex, iVariable)
|
||||
return entity_get_byte(iIndex, iVariable)
|
||||
|
||||
stock Entvars_Set_Byte(iIndex, iVariable, iNewValue)
|
||||
return entity_set_byte(iIndex, iVariable, iNewValue)
|
||||
|
||||
stock CreateEntity(szClassname[])
|
||||
return create_entity(szClassname)
|
||||
|
||||
stock ENT_SetModel(iIndex, szModel[])
|
||||
return entity_set_model(iIndex, szModel)
|
||||
|
||||
stock ENT_SetOrigin(iIndex, Float:fNewOrigin[3])
|
||||
return entity_set_origin(iIndex, fNewOrigin)
|
||||
|
||||
stock FindEntity(iIndex, szValue[])
|
||||
return find_ent_by_class(iIndex, szValue)
|
||||
|
||||
stock RemoveEntity(iIndex)
|
||||
return remove_entity(iIndex)
|
||||
|
||||
stock TraceLn(iIgnoreEnt, Float:fStart[3], Float:fEnd[3], Float:vReturn[3])
|
||||
return trace_line(iIgnoreEnt, fStart, fEnd, vReturn)
|
||||
|
||||
stock TraceNormal(iIgnoreEnt, Float:fStart[3], Float:fEnd[3], Float:vReturn[3])
|
||||
return trace_normal(iIgnoreEnt, fStart, fEnd, vReturn)
|
||||
|
||||
stock VecToAngles(Float:fVector[3], Float:vReturn[3])
|
||||
return vector_to_angle(fVector, vReturn)
|
||||
|
||||
stock Float:VecLength(Float:vVector[3])
|
||||
return vector_length(vVector)
|
||||
|
||||
stock Float:VecDist(Float:vVector[3], Float:vVector2[3])
|
||||
return vector_distance(vVector, vVector2)
|
||||
|
||||
stock MessageBlock(iMessage, iMessageFlags)
|
||||
return set_msg_block(iMessage, iMessageFlags)
|
||||
|
||||
stock GetMessageBlock(iMessage)
|
||||
return get_msg_block(iMessage)
|
||||
|
||||
stock Float:HLTime()
|
||||
return halflife_time()
|
||||
|
||||
stock FakeTouch(iToucher, iTouched)
|
||||
return fake_touch(iToucher, iTouched)
|
||||
|
||||
stock AttachView(iIndex, iTargetIndex)
|
||||
return attach_view(iIndex, iTargetIndex)
|
||||
|
||||
stock SetView(iIndex, ViewType)
|
||||
return set_view(iIndex, ViewType)
|
||||
|
||||
stock SetSpeak(iIndex, iSpeakFlags)
|
||||
return set_speak(iIndex, iSpeakFlags)
|
||||
|
||||
forward vexd_pfntouch(pToucher, pTouched)
|
||||
|
||||
forward ServerFrame()
|
|
@ -11,6 +11,14 @@
|
|||
#endif
|
||||
#define _amxmisc_included
|
||||
|
||||
#if defined AMXMOD_BCOMPAT
|
||||
#if defined _translator_included
|
||||
#define SIMPLE_T(%1) _T(%1)
|
||||
#else
|
||||
#define SIMPLE_T(%1) %1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
stock is_user_admin(id)
|
||||
{
|
||||
return ( get_user_flags(id)>0 && !(get_user_flags(id)&ADMIN_USER) )
|
||||
|
@ -30,13 +38,21 @@ stock cmd_access(id,level,cid,num) {
|
|||
}
|
||||
|
||||
if ( has_access==0 ) {
|
||||
#if defined AMXMOD_BCOMPAT
|
||||
console_print(id, SIMPLE_T("You have no access to that command."))
|
||||
#else
|
||||
console_print(id,"%L",id,"NO_ACC_COM")
|
||||
#endif
|
||||
return 0
|
||||
}
|
||||
if (read_argc() < num) {
|
||||
new hcmd[32], hinfo[128], hflag
|
||||
get_concmd(cid,hcmd,31,hflag,hinfo,127,level)
|
||||
#if defined AMXMOD_BCOMPAT
|
||||
console_print(id, SIMPLE_T("Usage: %s %s"), hcmd, SIMPLE_T(hinfo))
|
||||
#else
|
||||
console_print(id,"%L: %s %s",id,"USAGE",hcmd,hinfo)
|
||||
#endif
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
|
@ -58,21 +74,33 @@ stock cmd_target(id,const arg[],flags = 1) {
|
|||
new player = find_player("bl",arg)
|
||||
if (player) {
|
||||
if ( player != find_player("blj",arg) ) {
|
||||
#if defined AMXMOD_BCOMPAT
|
||||
console_print(id, SIMPLE_T("There are more clients matching to your argument"))
|
||||
#else
|
||||
console_print(id,"%L",id,"MORE_CL_MATCHT")
|
||||
#endif
|
||||
return 0
|
||||
}
|
||||
}
|
||||
else if ( ( player = find_player("c",arg) )==0 && arg[0]=='#' && arg[1] )
|
||||
player = find_player("k",str_to_num(arg[1]))
|
||||
if (!player) {
|
||||
#if defined AMXMOD_BCOMPAT
|
||||
console_print(id, SIMPLE_T("Client with that name or userid not found"))
|
||||
#else
|
||||
console_print(id,"%L",id,"CL_NOT_FOUND")
|
||||
#endif
|
||||
return 0
|
||||
}
|
||||
if (flags & 1) {
|
||||
if ((get_user_flags(player)&ADMIN_IMMUNITY) && ((flags&2)?(id!=player):true) ) {
|
||||
new imname[32]
|
||||
get_user_name(player,imname,31)
|
||||
#if defined AMXMOD_BCOMPAT
|
||||
console_print(id, SIMPLE_T("Client ^"%s^" has immunity"), imname)
|
||||
#else
|
||||
console_print(id,"%L",id,"CLIENT_IMM",imname)
|
||||
#endif
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
@ -80,7 +108,11 @@ stock cmd_target(id,const arg[],flags = 1) {
|
|||
if (!is_user_alive(player)) {
|
||||
new imname[32]
|
||||
get_user_name(player,imname,31)
|
||||
#if defined AMXMOD_BCOMPAT
|
||||
console_print(id, SIMPLE_T("That action can't be performed on dead client ^"%s^""), imname)
|
||||
#else
|
||||
console_print(id,"%L",id,"CANT_PERF_DEAD",imname)
|
||||
#endif
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +120,11 @@ stock cmd_target(id,const arg[],flags = 1) {
|
|||
if (is_user_bot(player)) {
|
||||
new imname[32]
|
||||
get_user_name(player,imname,31)
|
||||
#if defined AMXMOD_BCOMPAT
|
||||
console_print(id, SIMPLE_T("That action can't be performed on bot ^"%s^""), imname)
|
||||
#else
|
||||
console_print(id,"%L",id,"CANT_PERF_BOT",imname)
|
||||
#endif
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
@ -98,11 +134,20 @@ stock cmd_target(id,const arg[],flags = 1) {
|
|||
stock show_activity( id, const name[], {Float,_}: ... ) {
|
||||
new buffer[128]
|
||||
format_args( buffer , 127 , 2 )
|
||||
switch(get_cvar_num("amx_show_activity")) {
|
||||
case 2: client_print(0,print_chat,"%L %s: %s",
|
||||
id, is_user_admin(id) ? "ADMIN" : "PLAYER" , name , buffer )
|
||||
case 1: client_print(0,print_chat,"%L: %s",
|
||||
id, is_user_admin(id) ? "ADMIN" : "PLAYER", buffer )
|
||||
switch(get_cvar_num("amx_show_activity"))
|
||||
{
|
||||
case 2:
|
||||
#if defined AMXMOD_BCOMPAT
|
||||
client_print(0, print_chat, "%s %s: %s", is_user_admin(id) ? SIMPLE_T("ADMIN") : SIMPLE_T("PLAYER"), name, buffer)
|
||||
#else
|
||||
client_print(0, print_chat, "%L %s: %s", id, is_user_admin(id) ? "ADMIN" : "PLAYER" , name , buffer )
|
||||
#endif
|
||||
case 1:
|
||||
#if defined AMXMOD_BCOMPAT
|
||||
client_print(0, print_chat, "%s: %s", is_user_admin(id) ? SIMPLE_T("ADMIN") : SIMPLE_T("PLAYER"), buffer)
|
||||
#else
|
||||
client_print(0, print_chat, "%L: %s", id, is_user_admin(id) ? "ADMIN" : "PLAYER", buffer )
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
/* AMX Mod X Backwards Compatibility
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
* This file is provided as is (no warranties).
|
||||
*/
|
||||
|
||||
#if defined _amxmod_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _amxmod_included
|
||||
|
||||
#include <amxmodx>
|
||||
#include <cstrike>
|
||||
#include <engine>
|
||||
#include <fun>
|
||||
|
||||
stock user_spawn(index)
|
||||
return spawn(index)
|
||||
|
||||
stock get_logfile( name[], len )
|
||||
return get_time("admin%m%d.log",name,len)
|
||||
|
||||
stock get_user_money(index)
|
||||
return cs_get_user_money(index)
|
||||
|
||||
stock set_user_money(index,money,flash=1)
|
||||
return cs_set_user_money(index,money,flash)
|
||||
|
||||
stock numtostr(num,string[],len)
|
||||
return num_to_str(num,string,len)
|
||||
|
||||
stock strtonum(const string[])
|
||||
return str_to_num(string)
|
||||
|
||||
stock build_path( path[] , len , {Float,_}:... )
|
||||
{
|
||||
new basedir[32]
|
||||
get_localinfo("amxx_basedir",basedir,31)
|
||||
format_args(path,len,2)
|
||||
return replace(path,len,"$basedir",basedir)
|
||||
}
|
|
@ -121,7 +121,9 @@ native fake_touch(entTouched, entToucher);
|
|||
/* 2 formats.
|
||||
Format: DispatchKeyValue("KeyName","Value") - sets keyvalues for the entity specified in the keyvalue() forward.
|
||||
Format: DispatchKeyValue(index,"KeyName","Value") - Sets keyvalue for entity not specified in keyvalue() forward. */
|
||||
#if !defined AMXMOD_BCOMPAT
|
||||
native DispatchKeyValue(...);
|
||||
#endif
|
||||
|
||||
native get_keyvalue(entity, szKey[], value[], maxLength);
|
||||
|
||||
|
@ -131,14 +133,18 @@ native copy_keyvalue(szClassName[],sizea,szKeyName[],sizeb,szValue[],sizec);
|
|||
native DispatchSpawn(iIndex);
|
||||
|
||||
/* Hurts/Kills players in a sphere, like an explosion, Multiplier determines damage. */
|
||||
#if !defined AMXMOD_BCOMPAT
|
||||
native radius_damage(Float:fExplodeAt[3], iDamageMultiplier, iRadiusMultiplier);
|
||||
#endif
|
||||
|
||||
/* Will return the contents of a point (inside map? in sky? outside map? etc.). */
|
||||
native point_contents(Float:fCheckAt[3]);
|
||||
|
||||
/* Trace a line from Start(X, Y, Z) to End(X, Y, Z), will return the point hit in vReturn[3]
|
||||
* and an entity index if an entity is hit. */
|
||||
#if !defined AMXMOD_BCOMPAT
|
||||
native trace_line(iIgnoreEnt, Float:fStart[3], Float:fEnd[3], Float:vReturn[3]);
|
||||
#endif
|
||||
|
||||
/* Traces a hull. */
|
||||
native trace_hull(Float:origin[3],hull,ignoredent=0,ignoremonsters=0);
|
||||
|
|
|
@ -66,14 +66,22 @@ native Float:floatpower(Float:value, Float:exponent);
|
|||
native Float:floatlog(Float:value, Float:base=10.0);
|
||||
|
||||
/* Return the sine, cosine or tangent.
|
||||
* The input angle may be in radian, degrees or grades. */
|
||||
* The input angle may be in radians, degrees or grades. */
|
||||
native Float:floatsin(Float:value, anglemode:mode=radian);
|
||||
native Float:floatcos(Float:value, anglemode:mode=radian);
|
||||
native Float:floattan(Float:value, anglemode:mode=radian);
|
||||
|
||||
/* Return the hyperbolic sine, cosine or tangent.
|
||||
* The input angle may be in radians, degrees or grades. */
|
||||
native Float:floatsinh(Float:angle, anglemode:mode=radian);
|
||||
native Float:floatcosh(Float:angle, anglemode:mode=radian);
|
||||
native Float:floattanh(Float:angle, anglemode:mode=radian);
|
||||
|
||||
/* Return the absolute value */
|
||||
native Float:floatabs(Float:value);
|
||||
|
||||
/* Return the angle of a sine, cosine or tangent.
|
||||
* The output angle may be in radians, degrees, or grades. */
|
||||
native Float:floatatan(Float:angle, radix);
|
||||
native Float:floatacos(Float:angle, radix);
|
||||
native Float:floatasin(Float:angle, radix);
|
||||
|
|
|
@ -159,6 +159,12 @@
|
|||
#define DMG_MORTAR (1<<23) // Hit by air raid (done to distinguish grenade from mortar)
|
||||
#define DMG_TIMEBASED (~(0x3fff)) // Mask for time-based damage
|
||||
|
||||
// The fNoMonsters parameter of EngFunc_TraceLine, EngFunc_TraceMonsterHull, EngFunc_TraceHull, and EngFunc_TraceSphere
|
||||
#define DONT_IGNORE_MONSTERS 0
|
||||
#define IGNORE_MONSTERS 1
|
||||
#define IGNORE_MISSILE 2
|
||||
#define IGNORE_GLASS 0x100
|
||||
|
||||
// The hullnumber paramater of EngFunc_TraceHull, EngFunc_TraceModel and DLLFunc_GetHullBounds
|
||||
#define HULL_POINT 0
|
||||
#define HULL_HUMAN 1
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
/* Xtrafun backwards compatibility
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* These natives were originally made by SpaceDude, EJ, and JustinHoMi.
|
||||
*
|
||||
* This file is provided as is (no warranties).
|
||||
*/
|
||||
|
||||
#if !defined _xtrafun_included
|
||||
#define _xtrafun_included
|
||||
|
||||
#if !defined _engine_included
|
||||
#include <engine.inc>
|
||||
#endif
|
||||
|
||||
/* Gets the velocity of an entity */
|
||||
stock get_entity_velocity(index, velocity[3]) {
|
||||
new Float:vector[3]
|
||||
entity_get_vector(index, EV_VEC_velocity, vector)
|
||||
FVecIVec(vector, velocity)
|
||||
}
|
||||
|
||||
/* Sets the velocity of an entity */
|
||||
stock set_entity_velocity(index, velocity[3]) {
|
||||
new Float:vector[3]
|
||||
IVecFVec(velocity, vector)
|
||||
entity_set_vector(index, EV_VEC_velocity, vector)
|
||||
}
|
||||
|
||||
/* Gets the origin of an entity */
|
||||
stock get_entity_origin(index, origin[3]) {
|
||||
new Float:vector[3]
|
||||
entity_get_vector(index, EV_VEC_origin, vector)
|
||||
FVecIVec(vector, origin)
|
||||
}
|
||||
|
||||
/* Sets the origin of an entity */
|
||||
stock set_entity_origin(index, origin[3]) {
|
||||
new Float:vector[3]
|
||||
IVecFVec(origin, vector)
|
||||
entity_set_vector(index, EV_VEC_origin, vector)
|
||||
}
|
||||
|
||||
/* Get the index of the grenade belonging to index.
|
||||
* Model of grenade is returned in model[].
|
||||
* Specify the grenadeindex to start searching from,
|
||||
* or leave it at 0 to search from the start.
|
||||
* Returns grenade index.
|
||||
* Paths + models of grenades in Counter-Strike:
|
||||
* HEGRENADE = "models/w_hegrenade.mdl"
|
||||
* FLASHBANG = "models/w_flashbang.mdl"
|
||||
* SMOKEGRENADE = "models/w_smokegrenade.mdl" */
|
||||
stock get_grenade_index(index, model[], len, grenadeindex = 0) {
|
||||
new entfind = grenadeindex
|
||||
new entowner = index
|
||||
|
||||
for (;;) {
|
||||
entfind = find_ent_by_class(entfind, "grenade")
|
||||
|
||||
if (entfind && is_valid_ent(entfind)) {
|
||||
if (entity_get_edict(entFind, EV_ENT_owner) == entowner) {
|
||||
entity_get_string(entfind, EV_SZ_model, model)
|
||||
return entfind
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Eventually comes here if loop fails to find a grenade with specified owner.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the number of entities in the game */
|
||||
stock current_num_ents() {
|
||||
return entity_count();
|
||||
}
|
||||
|
||||
enum {
|
||||
classname = 0,
|
||||
target,
|
||||
targetname
|
||||
}
|
||||
|
||||
/* Find an entity ID from start_from_ent id (use 0 to start from
|
||||
* the beginning, category is either "classname", "target" or
|
||||
* "targetname", value is the name you are searching for */
|
||||
stock find_entity(start_from_ent, category, value[]) {
|
||||
switch (category) {
|
||||
case target: return find_ent_by_target(start_from_ent, value)
|
||||
case targetname: return find_ent_by_tname(start_from_ent, value)
|
||||
}
|
||||
return find_ent_by_class(start_from_ent, value)
|
||||
}
|
||||
|
||||
#endif // _xtrafun_included
|
Loading…
Reference in New Issue
Block a user