diff --git a/plugins/amxmod_compat/amxmod_compat.sma b/plugins/amxmod_compat/amxmod_compat.sma new file mode 100644 index 00000000..085325b3 --- /dev/null +++ b/plugins/amxmod_compat/amxmod_compat.sma @@ -0,0 +1,64 @@ +/** + * AMX Mod Compatibility engine + * by the AMX Mod X Development Team + */ + +#include +#include //we want fun running for extra compatibility +#include //we want engine running for extra compatibility +#include +#include +#define AMXMODX_NOAUTOLOAD +#include +#include + +#define MOD_NORMAL 0 +#define MOD_CSTRIKE 1 + +new g_ModType = MOD_NORMAL +new g_MaxPlayers + +#include "core.sma" +#include "vexdum.sma" +#include "mysql.sma" + +public plugin_init() +{ + register_plugin("AMX Mod Compat Engine", AMXX_VERSION_STR, "AMXX Dev Team") + + g_MaxPlayers = get_maxplayers() + + VexdUM_Register() +} + +public plugin_natives() +{ + set_module_filter("Plugin_ModuleFilter") + + new modname[32] + get_modname(modname, 31) + if (equali(modname, "cstrike") || equali(modname, "czero")) + { + g_ModType = MOD_CSTRIKE + } + + Core_Natives() + VexdUM_Natives() + MySQL_Natives() +} + +public Plugin_ModuleFilter(const module[]) +{ + if (equali(module, "sqlx")) + { + return PLUGIN_HANDLED + } + + return PLUGIN_CONTINUE +} + +public client_connect(id) +{ + VexdUM_ClientConnect(id) +} + diff --git a/plugins/amxmod_compat/core.sma b/plugins/amxmod_compat/core.sma new file mode 100644 index 00000000..7402f786 --- /dev/null +++ b/plugins/amxmod_compat/core.sma @@ -0,0 +1,182 @@ +/** + * AMX Mod Compatibility engine + * by the AMX Mod X Development Team + */ + +Core_Natives() +{ + /* implicit compatibility */ + register_native("VelocityByAim", "__VelocityByAim") + register_native("load_translations", "__load_translations") + register_native("is_user_authorized", "__is_user_authorized") + register_native("get_user_money", "__get_user_money") + register_native("set_user_money", "__set_user_money") + register_native("angle_to_vector", "__angle_to_vector") + register_native("fabs", "__fabs") + register_native("asin", "__asin") + register_native("sin", "__sin") + register_native("sinh", "__sinh") + register_native("acos", "__acos") + register_native("cos", "__cos") + register_native("cosh", "__cosh") + register_native("atan", "__atan") + register_native("atan2", "__atan2") + register_native("tan", "__tan") + register_native("tanh", "__tanh") + register_native("fsqroot", "__fsqroot") + register_native("fpower", "__fpower") + register_native("flog", "__flog") +} + +public __VelocityByAim(plid, num) +{ + new iIndex + new iVelocity + new Float:vRetValue[3] + + iIndex = get_param(1) + iVelocity = get_param(2) + + new ret = velocity_by_aim(iIndex, iVelocity, vRetValue) + set_array_f(3, vRetValue, 3) + + return ret +} + +public __load_translations(plid, num) +{ + static file[255] + + get_string(1, file, 254) + + return load_translations(file) +} + +public __is_user_authorized(plid, num) +{ + return is_user_authorized(get_param(1)) +} + +public __get_user_money(plid, num) +{ + return get_user_money(get_param(1)) +} + +public __set_user_money(plid, num) +{ + return set_user_money(get_param(1), get_param(2), get_param(3)) +} + +public __angle_to_vector(plid, num) +{ + new Float:angle[3] + new Float:vRetValue[3] + + get_array_f(1, angle, 3) + + new ret = angle_vector(angle, get_param(2), vRetValue) + set_array_f(3, vRetValue, 3) + + return ret +} + +public Float:__fabs(plid, num) +{ + new Float:value = get_param_f(1) + + return floatabs(value) +} + +public Float:__asin(plid, num) +{ + new Float:value = get_param_f(1) + + return floatasin(value, radian) +} + +public Float:__sin(plid, num) +{ + new Float:value = get_param_f(1) + + return floatsin(value, radian) +} + +public Float:__sinh(plid, num) +{ + new Float:value = get_param_f(1) + + return floatsinh(value, radian) +} + +public Float:__acos(plid, num) +{ + new Float:value = get_param_f(1) + + return floatacos(value, radian) +} + +public Float:__cos(plid, num) +{ + new Float:value = get_param_f(1) + + return floatcos(value, radian) +} + +public Float:__cosh(plid, num) +{ + new Float:value = get_param_f(1) + + return floatcosh(value, radian) +} + +public Float:__atan(plid, num) +{ + new Float:value = get_param_f(1) + + return floatatan(value, radian) +} + +public Float:__atan2(plid, num) +{ + new Float:value1 = get_param_f(1) + new Float:value2 = get_param_f(2) + + return floatatan2(value1, value2, radian) +} + +public Float:__tan(plid, num) +{ + new Float:value = get_param_f(1) + + return floattan(value, radian) +} + +public Float:__tanh(plid, num) +{ + new Float:value = get_param_f(1) + + return floattanh(value, radian) +} + +public Float:__fsqroot(plid, num) +{ + new Float:value = get_param_f(1) + + return floatsqroot(value) +} + +public Float:__fpower(plid, num) +{ + new Float:value = get_param_f(1) + new Float:exponent = get_param_f(2) + + return floatpower(value, exponent) +} + +public Float:__flog(plid, num) +{ + new Float:value = get_param_f(1) + new Float:base = get_param_f(2) + + return floatlog(value, base) +} diff --git a/plugins/amxmod_compat/mysql.sma b/plugins/amxmod_compat/mysql.sma new file mode 100644 index 00000000..00c037d6 --- /dev/null +++ b/plugins/amxmod_compat/mysql.sma @@ -0,0 +1,415 @@ +/** + * AMX Mod Compatibility engine + * by the AMX Mod X Development Team + */ + +#define MAX_CONNECTIONS 64 + +new Connections[MAX_CONNECTIONS+1] = {0} +new ConnectionTracker[MAX_CONNECTIONS+1] = {0} +new ConnectionErrors[MAX_CONNECTIONS+1][255] +new ConnectionQueries[MAX_CONNECTIONS+1] = {0} +new QueryPositions[MAX_CONNECTIONS+1] + +MySQL_Natives() +{ + register_native("mysql_connect", "__mysql_connect") + register_native("mysql_query", "__mysql_query") + register_native("mysql_error", "__mysql_error") + register_native("mysql_close", "__mysql_close") + register_native("mysql_nextrow", "__mysql_nextrow") + register_native("mysql_getfield", "__mysql_getfield") + register_native("mysql_getresult", "__mysql_getresult") + register_native("mysql_affected_rows", "__mysql_affected_rows") + register_native("mysql_num_fields", "__mysql_num_fields") + register_native("mysql_num_rows", "__mysql_num_rows") + register_native("mysql_field_name", "__mysql_field_name") + register_native("mysql_insert_id", "__mysql_insert_id") +} + +MakeConnectionIndex(Handle:cn) +{ + if (ConnectionTracker[0]) + { + new idx = ConnectionTracker[ConnectionTracker[0]] + ConnectionTracker[0]-- + Connections[idx] = _:cn + return idx + } else { + Connections[0]++ + if (Connections[0] > MAX_CONNECTIONS) + { + return 0 + } + + Connections[Connections[0]] = _:cn + return Connections[0] + } + + return 0 +} + +Handle:GetConnectionIndex(idx) +{ + if (idx < 1 || idx > MAX_CONNECTIONS || !Connections[idx]) + { + return Empty_Handle + } + + return Handle:Connections[idx] +} + +FreeConnectionIndex(idx) +{ + Connections[idx] = 0 + ConnectionTracker[0]++ + ConnectionTracker[ConnectionTracker[0]] = idx + ConnectionErrors[idx][0] = 0 + ConnectionQueries[idx] = 0 + QueryPositions[idx] = 0 +} + +/* + * Unlike the previous this does not check for a matching connection. + * Unless a plugin breaks I'm not going to take that step. + */ + +public __mysql_connect(plid, num) +{ + static host[255], user[128], pass[128], dbname[128], error[512] + new errcode + + get_string(1, host, 254) + get_string(2, user, 127) + get_string(3, pass, 127) + get_string(4, dbname, 127) + + new Handle:info = SQL_MakeDbTuple(host, user, pass, dbname) + new Handle:cn = SQL_Connect(info, errcode, error, 511) + + if (cn == Empty_Handle) + { + set_string(5, error, get_param(6)) + return 0 + } + + SQL_FreeHandle(info) + + new idx = MakeConnectionIndex(cn) + if (idx == 0) + { + set_string(5, "Reached max unclosed connections", get_param(6)) + return 0 + } + + ConnectionQueries[idx] = 0 + + return idx +} + +public __mysql_query(plid, num) +{ + static queryString[4096] + new cn_idx = get_param(1) + new Handle:cn + + if ((cn=GetConnectionIndex(cn_idx)) == Empty_Handle) + { + return 0 + } + + vdformat(queryString, 4095, 2, 3) + + new Handle:query = SQL_PrepareQuery(cn, "%s", queryString) + + if (!SQL_Execute(query)) + { + SQL_QueryError(query, ConnectionErrors[cn_idx], 254) + SQL_FreeHandle(query) + return 0 + } + + if (ConnectionQueries[cn_idx]) + { + SQL_FreeHandle(Handle:ConnectionQueries[cn_idx]) + } + + ConnectionQueries[cn_idx] = _:query + QueryPositions[cn_idx] = 0 + + return 1 +} + +public __mysql_error(plid, num) +{ + new cn_idx = get_param(1) + + if (Connections[cn_idx] < 1) + { + static error[255] + format(error, 254, "Invalid connection index: %d", cn_idx) + set_string(2, error, get_param(3)) + return 1 + } + + set_string(2, ConnectionErrors[cn_idx], get_param(3)) + + return 1 +} + +public __mysql_close(plid, num) +{ + new cn_idx = get_param(1) + + new Handle:cn = GetConnectionIndex(cn_idx) + + if (cn == Empty_Handle) + { + return 0 + } + + new Handle:query = Handle:ConnectionQueries[cn_idx] + + if (query != Empty_Handle) + { + SQL_FreeHandle(query) + } + + SQL_FreeHandle(cn) + + FreeConnectionIndex(cn_idx) + + return 1 +} + +public __mysql_nextrow(plid, num) +{ + new cn_idx = get_param(1) + + new Handle:cn = GetConnectionIndex(cn_idx) + if (cn == Empty_Handle) + { + return 0 + } + + new Handle:query = Handle:ConnectionQueries[cn_idx] + if (query == Empty_Handle) + { + return 0 + } + + if (QueryPositions[cn_idx] != 0) + { + SQL_NextRow(query) + } + + if (SQL_MoreResults(query)) + { + return ++QueryPositions[cn_idx] + } + + return 0 +} + +public __mysql_getresult(plid, num) +{ + new cn_idx = get_param(1) + + new Handle:cn = GetConnectionIndex(cn_idx) + if (cn == Empty_Handle) + { + return 0 + } + + new Handle:query = Handle:ConnectionQueries[cn_idx] + if (query == Empty_Handle) + { + return 0 + } + + if (!SQL_MoreResults(query)) + { + return 0 + } + + static name[64] + get_string(2, name, 63) + new column = SQL_FieldNameToNum(query, name) + if (column == -1) + { + log_error(AMX_ERR_NATIVE, "Invalid column name: %s", name) + return 0 + } + + switch (num) + { + case 2: + { + return SQL_ReadResult(query, column) + } + case 3: + { + new Float:fma + SQL_ReadResult(query, column, fma) + set_param_byref(3, _:fma) + } + case 4: + { + static str[2048] + SQL_ReadResult(query, column, str, 2047) + set_string(3, str, get_param_byref(4)) + } + } + + return 1 +} + +public __mysql_getfield(plid, num) +{ + new cn_idx = get_param(1) + + new Handle:cn = GetConnectionIndex(cn_idx) + if (cn == Empty_Handle) + { + return 0 + } + + new Handle:query = Handle:ConnectionQueries[cn_idx] + if (query == Empty_Handle) + { + return 0 + } + + if (!SQL_MoreResults(query)) + { + return 0 + } + + switch (num) + { + case 2: + { + return SQL_ReadResult(query, get_param(2)-1) + } + case 3: + { + new Float:fma + SQL_ReadResult(query, get_param(2)-1, fma) + set_param_byref(3, _:fma) + } + case 4: + { + static str[2048] + SQL_ReadResult(query, get_param(2)-1, str, 2047) + set_string(3, str, get_param_byref(4)) + } + } + + return 1 +} + +public __mysql_affected_rows(plid, num) +{ + new cn_idx = get_param(1) + + new Handle:cn = GetConnectionIndex(cn_idx) + if (cn == Empty_Handle) + { + return 0 + } + + new Handle:query = Handle:ConnectionQueries[cn_idx] + if (query == Empty_Handle) + { + return 0 + } + + return SQL_AffectedRows(query) +} + +public __mysql_num_fields(plid, num) +{ + new cn_idx = get_param(1) + + new Handle:cn = GetConnectionIndex(cn_idx) + if (cn == Empty_Handle) + { + return 0 + } + + new Handle:query = Handle:ConnectionQueries[cn_idx] + if (query == Empty_Handle) + { + return 0 + } + + return SQL_NumColumns(query) +} + +public __mysql_insert_id(plid, num) +{ + new cn_idx = get_param(1) + + new Handle:cn = GetConnectionIndex(cn_idx) + if (cn == Empty_Handle) + { + return 0 + } + + new Handle:query = Handle:ConnectionQueries[cn_idx] + if (query == Empty_Handle) + { + return 0 + } + + return SQL_GetInsertId(query) +} + +public __mysql_num_rows(plid, num) +{ + new cn_idx = get_param(1) + + new Handle:cn = GetConnectionIndex(cn_idx) + if (cn == Empty_Handle) + { + return 0 + } + + new Handle:query = Handle:ConnectionQueries[cn_idx] + if (query == Empty_Handle) + { + return 0 + } + + return SQL_NumResults(query) +} + +public __mysql_field_name(plid, num) +{ + new cn_idx = get_param(1) + + new Handle:cn = GetConnectionIndex(cn_idx) + if (cn == Empty_Handle) + { + return 0 + } + + new Handle:query = Handle:ConnectionQueries[cn_idx] + if (query == Empty_Handle) + { + return 0 + } + + new column = get_param(2) - 1 + if (column < 0 || column >= SQL_NumColumns(query)) + { + return 0 + } + + new field[64] + SQL_FieldNumToName(query, column, field, 63) + + set_string(3, field, get_param(4)) + + return 1 +} diff --git a/plugins/amxmod_compat/vexdum.sma b/plugins/amxmod_compat/vexdum.sma new file mode 100644 index 00000000..32b5d4a7 --- /dev/null +++ b/plugins/amxmod_compat/vexdum.sma @@ -0,0 +1,569 @@ +/** + * AMX Mod Compatibility engine + * by the AMX Mod X Development Team + */ + +#include +#include + +/* Forwards */ +new g_FwdTouch +new g_FwdThink +new g_FwdSpawn +new g_FwdClientPreThink +new g_FwdClientPostThink +new g_FwdEmitSound +new g_FwdEmitAmbientSound +new g_FwdSetModel +new g_FwdTraceLine +new g_FwdSetCliKeyValue +new g_FwdKeyValue +new g_PlayerModels[33][64] +new g_PlayerModeled[33] + +new g_LastTrace = 0 + +VexdUM_Register() +{ + /* Fakemeta Hooks */ + register_forward(FM_EmitSound, "Hook_FM_EmitSound") + register_forward(FM_EmitAmbientSound, "Hook_FM_EmitAmbientSound") + register_forward(FM_SetModel, "Hook_FM_SetModel") + register_forward(FM_TraceLine, "Hook_FM_TraceLine") + register_forward(FM_SetClientKeyValue, "Hook_FM_SetClientKeyValue") + register_forward(FM_KeyValue, "Hook_FM_KeyValue") + register_forward(FM_Touch, "Hook_FM_Touch") + register_forward(FM_Think, "Hook_FM_Think") + register_forward(FM_Spawn, "Hook_FM_Spawn") + register_forward(FM_PlayerPreThink, "Hook_FM_PlayerPreThink") + register_forward(FM_PlayerPostThink, "Hook_FM_PlayerPostThink") + register_forward(FM_ClientUserInfoChanged, "Hook_ClientUserInfoChanged") + + /* Global Forwards */ + g_FwdTouch = CreateMultiForward("entity_touch", ET_STOP, FP_CELL, FP_CELL) + g_FwdThink = CreateMultiForward("entity_think", ET_STOP, FP_CELL) + g_FwdSpawn = CreateMultiForward("entity_spawn", ET_STOP, FP_CELL) + g_FwdClientPreThink = CreateMultiForward("client_prethink", ET_IGNORE, FP_CELL) + g_FwdClientPostThink = CreateMultiForward("client_postthink", ET_IGNORE, FP_CELL) + g_FwdEmitSound = CreateMultiForward("emitsound", ET_STOP, FP_CELL, FP_STRING) + g_FwdEmitAmbientSound = CreateMultiForward("emitambientsound", ET_STOP, FP_CELL, FP_STRING) + g_FwdSetModel = CreateMultiForward("set_model", ET_STOP, FP_CELL, FP_STRING) + g_FwdTraceLine = CreateMultiForward("traceline", ET_STOP, FP_CELL) + g_FwdSetCliKeyValue = CreateMultiForward("setclientkeyvalue", ET_STOP, FP_CELL, FP_STRING, FP_STRING) + g_FwdKeyValue = CreateMultiForward("keyvalue", ET_STOP, FP_CELL) +} + +VexdUM_Natives() +{ + /* implicit compatibility */ + register_native("is_entity", "__is_entity") + register_native("find_entity", "__find_entity") + register_native("find_entity_sphere", "__find_entity_sphere") + register_native("in_view_cone", "__in_view_cone") + register_native("get_offset_int", "__get_offset_int") + register_native("set_offset_int", "__set_offset_int") + register_native("trace_line", "__trace_line") + register_native("traceline_get_int", "__traceline_get_int") + register_native("traceline_set_int", "__traceline_set_int") + register_native("traceline_get_edict", "__traceline_get_edict") + register_native("traceline_set_edict", "__traceline_set_edict") + register_native("traceline_set_float", "__traceline_set_float") + register_native("can_see", "__can_see") + register_native("user_spawn", "__user_spawn") + register_native("get_maxentities", "__get_maxentities") + register_native("PointContents", "__PointContents") + register_native("DispatchKeyValue", "__DispatchKeyValue") + + if (g_ModType == MOD_CSTRIKE) + { + register_native("set_user_model", "__cs_set_user_model") + } else { + register_native("set_user_model", "__set_user_model") + } +} + +VexdUM_ClientConnect(id) +{ + g_PlayerModels[id][0] = 0 + g_PlayerModeled[id] =0 +} + +SetClientKeyValue(id, const key[], const value[]) +{ + new buffer = engfunc(EngFunc_GetInfoKeyBuffer, id) + + return engfunc(EngFunc_SetClientKeyValue, buffer, key, value) +} + +GetClientKeyValue(id, const key[], value[], maxlen) +{ + new buffer = engfunc(EngFunc_GetInfoKeyBuffer, id) + + engfunc(EngFunc_InfoKeyValue, buffer, key, value, maxlen) +} + +public __is_entity(plid, num) +{ + new ent = get_param(1) + return is_entity(ent) +} + +public __find_entity(plid, num) +{ + static entstr[256] + new startEnt, type + + startEnt = get_param(1) + get_string(2, entstr, 255) + type = get_param(3) + + return find_entity(startEnt, entstr, type) +} + +public __find_entity_sphere(plid, num) +{ + new ent + new Float:orig[3] + new Float:radius + + ent = get_param(1) + get_array_f(2, orig, 3) + radius = get_param_f(3) + + return find_entity_sphere(ent, orig, radius) +} + +public __in_view_cone(plid, num) +{ + new ent + new Float:orig[3] + + ent = get_param(1) + get_array_f(2, orig, 3) + + return in_view_cone(ent, orig) +} + +public __get_offset_int(plid, num) +{ + new ent = get_param(1) + new offs = get_param(2) + new linux = get_param(3) + + return get_pdata_int(ent, offs, linux) +} + +public __set_offset_int(plid, num) +{ + return set_offset_int(get_param(1), get_param(2), get_param(3), get_param(4)) +} + +public __trace_line(plid, num) +{ + new ent = get_param(1) + + new Float:vStart[3], Float:vEnd[3], Float:vReturn[3] + + get_array_f(2, vStart, 3) + get_array_f(3, vEnd, 3) + + if (ent == FM_NULLENT) + engfunc(EngFunc_TraceLine, vStart, vEnd, IGNORE_MONSTERS, 0, 0) + else + engfunc(EngFunc_TraceLine, vStart, vEnd, DONT_IGNORE_MONSTERS, ent, 0) + + get_tr2(0, TraceResult:TR_vecEndPos, vReturn) + + set_array_f(4, vReturn, 3) + + new traceHit = get_tr2(0, TraceResult:TR_pHit) + + if (!pev_valid(traceHit)) + return FM_NULLENT + + return traceHit +} + +public __traceline_get_int(plid, num) +{ + new iSet = get_param(1) + new iValue = 0 + + switch (iSet) + { + case TR_INT_fAllSolid: + iValue = get_tr2(g_LastTrace, TraceResult:TR_AllSolid) + case TR_INT_fStartSolid: + iValue = get_tr2(g_LastTrace, TraceResult:TR_StartSolid) + case TR_INT_fInOpen: + iValue = get_tr2(g_LastTrace, TraceResult:TR_InOpen) + case TR_INT_fInWater: + iValue = get_tr2(g_LastTrace, TraceResult:TR_InWater) + case TR_INT_iHitgroup: + iValue = get_tr2(g_LastTrace, TraceResult:TR_iHitgroup) + default: + log_error(AMX_ERR_NATIVE, "Invalid TR_ parameter") + } + + return iValue +} + +public __traceline_set_int(plid, num) +{ + new iSet = get_param(1) + new iValue = get_param(2) + + switch (iSet) + { + case TR_INT_fAllSolid: + set_tr2(g_LastTrace, TraceResult:TR_AllSolid, iValue) + case TR_INT_fStartSolid: + set_tr2(g_LastTrace, TraceResult:TR_StartSolid, iValue) + case TR_INT_fInOpen: + set_tr2(g_LastTrace, TraceResult:TR_InOpen, iValue) + case TR_INT_fInWater: + set_tr2(g_LastTrace, TraceResult:TR_InWater, iValue) + case TR_INT_iHitgroup: + set_tr2(g_LastTrace, TraceResult:TR_iHitgroup, iValue) + default: + { + log_error(AMX_ERR_NATIVE, "Invalid TR_ parameter") + return 0 + } + } + + return 1 +} + +public __traceline_get_edict(plid, num) +{ + new iSet = get_param(1) + new iValue = 0 + + switch (iSet) + { + case TR_ENT_pHit: + iValue = get_tr2(g_LastTrace, TraceResult:TR_pHit) + default: + log_error(AMX_ERR_NATIVE, "Invalid TR_ parameter") + } + + return iValue +} + +public __traceline_set_edict(plid, num) +{ + new iSet = get_param(1) + new iValue = get_param(2) + + switch (iSet) + { + case TR_ENT_pHit: + set_tr2(g_LastTrace, TraceResult:TR_pHit, iValue) + default: + { + log_error(AMX_ERR_NATIVE, "Invalid TR_ parameter") + return 0 + } + } + + return 1 +} + +public Float:__traceline_get_float(plid, num) +{ + new iSet = get_param(1) + new Float:fValue = 0.0 + + switch (iSet) + { + case TR_FL_flFraction: + get_tr2(g_LastTrace, TraceResult:TR_flFraction, fValue) + case TR_FL_flPlaneDist: + get_tr2(g_LastTrace, TraceResult:TR_flPlaneDist, fValue) + default: + log_error(AMX_ERR_NATIVE, "Invalid TR_ parameter") + } + + return fValue +} + +public __traceline_set_float(plid, num) +{ + new iSet = get_param(1) + new Float:fValue = get_param_f(2) + + switch (iSet) + { + case TR_FL_flFraction: + set_tr2(g_LastTrace, TraceResult:TR_flFraction, fValue) + case TR_FL_flPlaneDist: + get_tr2(g_LastTrace, TraceResult:TR_flPlaneDist, fValue) + default: + { + log_error(AMX_ERR_NATIVE, "Invalid TR_ parameter") + return 0 + } + } + + return 1 +} + +public __traceline_get_vector(plid, num) +{ + new iSet = get_param(1) + new Float:vValue[3] + + switch (iSet) + { + case TR_VEC_vecEndPos: + get_tr2(g_LastTrace, TraceResult:TR_vecEndPos, vValue) + case TR_VEC_vecPlaneNormal: + get_tr2(g_LastTrace, TraceResult:TR_vecPlaneNormal, vValue) + default: + { + log_error(AMX_ERR_NATIVE, "Invalid TR_ parameter") + return 0 + } + } + + set_array_f(2, vValue, 3) + + return 1 +} + +public __traceline_set_vector(plid, num) +{ + new iSet = get_param(1) + new Float:vValue[3] + + get_array_f(2, vValue, 3) + + switch (iSet) + { + case TR_VEC_vecEndPos: + set_tr2(g_LastTrace, TraceResult:TR_vecEndPos, vValue) + case TR_VEC_vecPlaneNormal: + set_tr2(g_LastTrace, TraceResult:TR_vecPlaneNormal, vValue) + default: + { + log_error(AMX_ERR_NATIVE, "Invalid TR_ parameter") + return 0 + } + } + + return 1 +} + +public __can_see(plid, num) +{ + return can_see(get_param(1), get_param(2)) +} + +public __user_spawn(plid, num) +{ + return dllfunc(DLLFunc_Spawn, get_param(1)) +} + +public __set_user_model(plid, num) +{ + new id = get_param(1) + if (id < 1 || id > g_MaxPlayers) + { + return 0 + } + + new model[64] + get_string(2, model, 63) + if (model[0] == 0) + { + if (!g_PlayerModeled[id]) + { + return 0 + } + g_PlayerModeled[id] = 0 + g_PlayerModels[id][0] = 0 + dllfunc(DLLFunc_ClientUserInfoChanged, id) + } else { + copy(g_PlayerModels[id], 63, model) + g_PlayerModeled[id] = 1 + SetClientKeyValue(id, "model", model) + } + + return 1 +} + +public __cs_set_user_model(plid, num) +{ + new id = get_param(1) + new model[64] + + get_string(2, model, 63) + + return cs_set_user_model(id, model) +} + +public __get_maxentities(plid, num) +{ + return get_maxentities() +} + +public __PointContents(plid, num) +{ + new Float:vCheckAt[3] + + get_array_f(1, vCheckAt, 3) + + return point_contents(vCheckAt) +} + +public __DispatchKeyValue(plid, num) +{ + new ent = get_param(1) + + new szClassname[32], szKey[32], szValue[32] + + if (pev_valid(ent)) + { + get_string(2, szKey, 31) + get_string(3, szValue, 31) + pev(ent, pev_classname, szClassname, 31) + + set_kvd(0, KV_ClassName, szClassname) + set_kvd(0, KV_KeyName, szKey) + set_kvd(0, KV_Value, szValue) + set_kvd(0, KV_fHandled, 0) + + dllfunc(DLLFunc_KeyValue, ent, 0) + } + + return 1 +} + + +/********************************* + ***** HOOKS ********************* + *********************************/ + +public Hook_ClientUserInfoChanged(id, buffer) +{ + if (g_PlayerModeled[id] && (pev(id, pev_deadflag) == DEAD_NO)) + { + return FMRES_SUPERCEDE + } + + return FMRES_IGNORED +} + +public Hook_FM_EmitSound(entid, channel, const sample[]) //we don't care about the rest +{ + new ret + + ExecuteForward(g_FwdEmitSound, ret, entid, sample) + + return (ret == PLUGIN_HANDLED) ? FMRES_SUPERCEDE : FMRES_IGNORED +} + +public Hook_FM_EmitAmbientSound(entid, Float:pos[3], const sample[]) //we don't care about the rest +{ + new ret + + ExecuteForward(g_FwdEmitAmbientSound, ret, entid, sample) + + return (ret == PLUGIN_HANDLED) ? FMRES_SUPERCEDE : FMRES_IGNORED +} + +public Hook_FM_SetModel(entid, const model[]) +{ + new ret + + ExecuteForward(g_FwdSetModel, ret, entid, model) + + return (ret == PLUGIN_HANDLED) ? FMRES_SUPERCEDE : FMRES_IGNORED +} + +public Hook_FM_TraceLine(Float:v1[3], Float:v2[3], noMonsters, skip_ent, ptr) +{ + g_LastTrace = ptr + + engfunc(EngFunc_TraceLine, v1, v2, noMonsters, skip_ent, ptr) + + new ret + + ExecuteForward(g_FwdTraceLine, ret, skip_ent) + + return (ret == PLUGIN_HANDLED) ? FMRES_SUPERCEDE : FMRES_IGNORED +} + +public Hook_FM_SetClientKeyValue(id, const infobuffer[], const key[], const value[]) +{ + new ret + + ExecuteForward(g_FwdSetCliKeyValue, ret, id, key, value) + + return (ret == PLUGIN_HANDLED) ? FMRES_SUPERCEDE : FMRES_IGNORED +} + +public Hook_FM_KeyValue(ent, kvd) +{ + new ret + + ExecuteForward(g_FwdKeyValue, ret, ent) + + return (ret == PLUGIN_HANDLED) ? FMRES_SUPERCEDE : FMRES_IGNORED +} + +public Hook_FM_Touch(ent1, ent2) +{ + new ret + + ExecuteForward(g_FwdTouch, ret, ent1, ent2) + + return (ret == PLUGIN_HANDLED) ? FMRES_SUPERCEDE : FMRES_IGNORED +} + +public Hook_FM_Think(entid) +{ + new ret + + ExecuteForward(g_FwdThink, ret, entid) + + return (ret == PLUGIN_HANDLED) ? FMRES_SUPERCEDE : FMRES_IGNORED +} + +public Hook_FM_Spawn(entid) +{ + new ret + + ExecuteForward(g_FwdSpawn, ret, entid) + + return (ret == PLUGIN_HANDLED) ? FMRES_SUPERCEDE : FMRES_IGNORED +} + +public Hook_FM_PlayerPreThink(id) +{ + new ret + + ExecuteForward(g_FwdClientPreThink, ret, id) + + return (ret == PLUGIN_HANDLED) ? FMRES_SUPERCEDE : FMRES_IGNORED +} + +public Hook_FM_PlayerPostThink(id) +{ + new ret + + if (g_PlayerModeled[id]) + { + new model[64] + GetClientKeyValue(id, "model", model, 63) + if (!equal(g_PlayerModels[id], model)) + { + SetClientKeyValue(id, "model", g_PlayerModels[id]) + } + } + + ExecuteForward(g_FwdClientPostThink, ret, id) + + return (ret == PLUGIN_HANDLED) ? FMRES_SUPERCEDE : FMRES_IGNORED +} diff --git a/plugins/include/amxmod_compat/VexdUM.inc b/plugins/include/amxmod_compat/VexdUM.inc new file mode 100644 index 00000000..692afa7c --- /dev/null +++ b/plugins/include/amxmod_compat/VexdUM.inc @@ -0,0 +1,86 @@ +/* VexdUM backwards compatibility + * + * by the AMX Mod X Development Team + * + * This file is provided as is (no warranties). + */ + + +#if !defined _fakemeta_included + #include +#endif + +#if !defined _engine_included + #include +#endif + +#if defined _vexd_bcompat_included + #endinput +#endif +#define _vexd_bcompat_included + +#include + +native radius_damage(inflictor, Float:dmg, Float:orig[3], Float:rad, bit = DMG_BULLET, wpnName[]="", hs = 0); +native set_user_model(id, const Model[]=""); + +native DispatchKeyValue(ent, szKey[], szValue[]); + +// Trace a line from Start(X, Y, Z) to End(X, Y, Z), will return the point hit in vReturn[3] +// Will return an entindex if an entity is hit. +native trace_line(ent, Float:vStart[3], Float:vEnd[3], Float:vReturn[3]); + +native traceline_get_int(iVar); +native traceline_set_int(iVar, iVal); +native Float:traceline_get_float(iVar); +native traceline_set_float(iVar, Float:fVal); +native traceline_get_vector(iVar, Float:vVal[3]); +native traceline_set_vector(iVar, Float:vVal[3]); +native traceline_get_edict(iVar); +native traceline_set_edict(iVar, iEnt); + +/* Wrapper around pfn_touch */ +forward entity_touch(entity1, entity2); + +/* Wrapper around pfn_think */ +forward entity_think(entity); + +/* Wrapper around pfn_spawn */ +forward entity_spawn(entity); + +/* Wrapper around client_PreThink */ +forward client_prethink(id); + +/* Wrapper around client_PostThink */ +forward client_postthink(id); + +//From AMX Mod: +// Called when an Emitting Sound is played Server-Side +forward emitsound(entity, const sample[]); + +//From AMX Mod: +// Called when an Emitting Ambient Sound is played Server-Side +forward emitambientsound(entity, const sample[]); + +//From AMX Mod: +// Called when a model spawns +forward set_model(entity, const model[]); + +//From AMX Mod: +// Called whatever an entity looks at +forward traceline(entity); + +//:TODO: ? +// Called when a monster is hurt by VexdUM damage natives +// forward monster_hurt(monster, attacker, damage); + +//From AMX Mod: +// Called when a keyvalue is set on a player +forward setclientkeyvalue(id, key[], value[]); + +//From AMX Mod: +// Called when an entity gets a keyvalue set on it from the engine. +// Use copy_keyvalue to get the keyvalue information +forward keyvalue(entity); + +#include diff --git a/plugins/include/amxmod_compat/VexdUM_const.inc b/plugins/include/amxmod_compat/VexdUM_const.inc new file mode 100644 index 00000000..f44dca62 --- /dev/null +++ b/plugins/include/amxmod_compat/VexdUM_const.inc @@ -0,0 +1,30 @@ +#if defined _vexdum_const_included + #endinput +#endif +#define _vexdum_const_included + +// TraceLine Integer +enum { + TR_INT_fAllSolid, // if true, plane is not valid + TR_INT_fStartSolid, // if true, the initial point was in a solid area + TR_INT_fInOpen, + TR_INT_fInWater, + TR_INT_iHitgroup, // 0 == generic, non zero is specific body part +}; + +// TraceLine Float +enum { + TR_FL_flFraction, // time completed, 1.0 = didn't hit anything + TR_FL_flPlaneDist, +}; + +// TraceLine Vector +enum { + TR_VEC_vecEndPos, // final position + TR_VEC_vecPlaneNormal, // surface normal at impact +}; + +// TraceLine Edict +enum { + TR_ENT_pHit, // entity the surface is on +}; diff --git a/plugins/include/amxmod_compat/VexdUM_stock.inc b/plugins/include/amxmod_compat/VexdUM_stock.inc new file mode 100644 index 00000000..3e2d23ce --- /dev/null +++ b/plugins/include/amxmod_compat/VexdUM_stock.inc @@ -0,0 +1,132 @@ +/* VexdUM stocks backwards compatibility + * + * by the AMX Mod X Development Team + * + * This file is provided as is (no warranties). + */ + +#if defined _vexd_bcompat_stocks_included + #endinput +#endif +#define _vexd_bcompat_stocks_included + +#if !defined _engine_included + #include +#endif + +stock is_entity(ent) +{ + return pev_valid(ent); +} + +stock get_offset_int(ent, offset, linos = 5) +{ + return get_pdata_int(ent, offset, linos); +} + +stock set_offset_int(ent, offset, value, linos = 5) +{ + return set_pdata_int(ent, offset, value, linos); +} + +stock in_view_cone(ent, Float:Orig[3]) +{ + return is_in_viewcone(ent, Orig); +} + +stock get_maxentities() +{ + return global_get(glb_maxEntities); +} + +stock can_see(ent1, ent2) +{ + if (is_entity(ent1) && is_entity(ent2)) + { + new flags = pev(ent1, pev_flags); + if (flags & EF_NODRAW || flags & FL_NOTARGET) + { + return 0; + } + + new Float:lookerOrig[3]; + new Float:targetOrig[3]; + new Float:temp[3]; + + pev(ent1, pev_origin, lookerOrig); + pev(ent1, pev_view_ofs, temp); + lookerOrig[0] += temp[0]; + lookerOrig[1] += temp[1]; + lookerOrig[2] += temp[2]; + + pev(ent2, pev_origin, targetOrig); + pev(ent2, pev_view_ofs, temp); + targetOrig[0] += temp[0]; + targetOrig[1] += temp[1]; + targetOrig[2] += temp[2]; + + engfunc(EngFunc_TraceLine, lookerOrig, targetOrig, 0, ent1, 0); + if (get_tr2(0, TraceResult:TR_InOpen) && get_tr2(0, TraceResult:TR_InWater)) + { + return 0; + } else { + new Float:flFraction; + get_tr2(0, TraceResult:TR_Fraction, flFraction); + if (flFraction == 1.0 || (get_tr2(0, TraceResult:TR_Hit) == ent2)) + { + return 1; + } + } + } + + return 0; +} + +//From AMX Mod: +// Find an entity in the world, will return -1 if nothing is found +// type = 0: "classname" +// type = 1: "globalname" +// type = 2: "model" +// type = 3: "target" +// type = 4: "targetname" +// type = 5: "netname" +// type = 6: "message" +// type = 7: "noise" +// type = 8: "noise1" +// type = 9: "noise2" +// type = 10: "noise3" +// type = 11: "viewmodel" +// type = 12: "weaponmodel" +stock find_entity(ent, szValue[], type=0) +{ + static _g_FindEntTypes[13][] = + { + "classname", + "globalname", + "model", + "target", + "targetname", + "netname", + "messages", + "noise", + "noise1", + "noise2", + "noise3", + "viewmodel", + "weaponmodel" + }; + + if (type < 0 || type >= 13) + { + type = 0; + } + + return engfunc(EngFunc_FindEntityByString, ent, _g_FindEntTypes[type], szValue); +} + +//From AMX Mod: +// Find an entity within a given origin and radius +stock find_entity_sphere(ent, Float:Orig[3], Float:Rad) +{ + return engfunc(EngFunc_FindEntityInSphere, ent, Orig, Rad); +} diff --git a/plugins/include/amxmod_compat/Vexd_Utilities.inc b/plugins/include/amxmod_compat/Vexd_Utilities.inc new file mode 100644 index 00000000..82cda4fc --- /dev/null +++ b/plugins/include/amxmod_compat/Vexd_Utilities.inc @@ -0,0 +1,104 @@ +/* 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 + +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() \ No newline at end of file diff --git a/plugins/include/amxmod_compat/amxmod.inc b/plugins/include/amxmod_compat/amxmod.inc new file mode 100644 index 00000000..e7189e53 --- /dev/null +++ b/plugins/include/amxmod_compat/amxmod.inc @@ -0,0 +1,127 @@ +/* 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 + +#if !defined AMXMOD_BCOMPAT + #define AMXMOD_BCOMPAT +#endif + +#include +#include +#include +#include +#include + +stock AMX_VERSION[] = "1.76-BC" + +/* Core will identify us as an "old plugin" this way. */ +public __b_old_plugin = 1; + +public __b_ident_vers() +{ + return __b_old_plugin; +} + +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,_}:... ) { + format_args(path, len, 2) + new pathlen = strlen(path) + new basedir[32] + if(containi(path, "$basedir") != -1) { + get_localinfo("amxx_basedir", basedir, 31) + if(!basedir[0]) copy(basedir, 31, "addons/amxmodx") + if((pathlen+strlen(basedir)-strlen("$basedir")) < len) { + replace(path, len, "$basedir", basedir) + } + } + new dir[64], subdir[63] + if(containi(path, "$configdir") != -1) { + get_localinfo("amxx_configsdir", dir, 63) + if(!dir[0]) format(dir, 63, "%s/configs", basedir) + if((pathlen+strlen(basedir)-strlen("$configdir")) < len) { + replace(path, len, "$configdir", dir) + } + dir[0] = '^0' + } + if(containi(path, "$langdir") != -1) { + get_localinfo("amxx_datadir", subdir, 63) + if(!subdir[0]) format(subdir, 63, "%s/data", basedir) + format(dir, 63, "%s/amxmod-lang", subdir) + if((pathlen+strlen(basedir)-strlen("$langdir")) < len) { + replace(path, len, "$langdir", dir) + } + dir[0] = '^0' + } + if(containi(path, "$modulesdir") != -1) { + get_localinfo("amxx_modules", dir, 63) + if(!dir[0]) format(dir, 63, "%s/modules", basedir) + if((pathlen+strlen(basedir)-strlen("$modulesdir")) < len) { + replace(path, len, "$modulesdir", dir) + } + dir[0] = '^0' + } + if(containi(path, "$pluginsdir") != -1) { + get_localinfo("amx_pluginsdir", dir, 63) + if(!dir[0]) format(dir, 63, "%s/plugins", basedir) + if((pathlen+strlen(basedir)-strlen("$pluginsdir")) < len) { + replace(path, len, "$pluginsdir", dir) + } + dir[0] = '^0' + } + if(containi(path, "$logdir") != -1) { + get_localinfo("amx_logs", dir, 63) + if(!dir[0]) format(dir, 63, "%s/logs", basedir) + if((pathlen+strlen(basedir)-strlen("$logdir")) < len) { + replace(path, len, "$logdir", dir) + } + } + return 1 +} + +stock is_user_authorized(id) +{ + static auth[32]; + + get_user_authid(id, auth, 31); + if (auth[0] == 0 || equali(auth, "STEAM_ID_PENDING")) + { + return 0; + } + + return 1; +} + +/* Vector AMX Mod compatibility */ +#define ANGLEVECTORS_FORWARD 1 +#define ANGLEVECTORS_RIGHT 2 +#define ANGLEVECTORS_UP 3 + +stock angle_to_vector(Float:vector[3], FRU, Float:ret[3]) +{ + return angle_vector(vector, FRU, ret) +} diff --git a/plugins/include/amxmod_compat/maths.inc b/plugins/include/amxmod_compat/maths.inc new file mode 100644 index 00000000..25a0b6a0 --- /dev/null +++ b/plugins/include/amxmod_compat/maths.inc @@ -0,0 +1,85 @@ +/* AMX Mod math functions backwards compatibility + * + * by the AMX Mod X Development Team + * + * This file is provided as is (no warranties). + */ + +#if defined _maths_bcompat_included + #endinput +#endif +#define _maths_bcompat_included + +#if !defined _float_included + #include +#endif + +stock Float:fabs(Float:value) +{ + return floatabs(value) +} + +stock Float:asin(Float:value) +{ + return floatasin(value, radian) +} + +stock Float:sin(Float:value) +{ + return floatsin(value, radian) +} + +stock Float:sinh(Float:value) +{ + return floatsinh(value, radian) +} + +stock Float:acos(Float:value) +{ + return floatacos(value, radian) +} + +stock Float:cos(Float:value) +{ + return floatcos(value, radian) +} + +stock Float:cosh(Float:value) +{ + retuen floatcosh(value, radian) +} + +stock Float:atan(Float:value) +{ + return floatatan(value, radian) +} + +stock Float:atan2(Float:value1, Float:value2) +{ + return floatatan2(value1, value2, radian) +} + +stock Float:tan(Float:value) +{ + return floattan(value, radian) +} + +stock Float:tanh(Float:value) +{ + return floattanh(value, radian) +} + +stock Float:fsqroot(Float:value) +{ + return floatsqroot(value) +} + +stock Float:fpower(Float:value, Float:exponent) +{ + return floatpower(value, exponent) +} + +stock Float:flog(Float:value, Float:base=10.0) +{ + return floatlog(value, base) +} diff --git a/plugins/include/amxmod_compat/mysql.inc b/plugins/include/amxmod_compat/mysql.inc new file mode 100644 index 00000000..09d22fe3 --- /dev/null +++ b/plugins/include/amxmod_compat/mysql.inc @@ -0,0 +1,20 @@ + +#if defined _mysql_included + #endinput +#endif +#define _mysql_included + +#include + +native mysql_connect(host[], user[], pass[], dbname[], error[], maxlength); +native mysql_query(sql, query[], {Float,_}:... ); +native mysql_error(sql, dest[], maxlength); +native mysql_close(sql); +native mysql_nextrow(sql); +native mysql_getfield(sql, fieldnum, {Float,_}:... ); +native mysql_getresult(sql, field[], {Float,_}:... ); +native mysql_affected_rows(sql); +native mysql_num_fields(sql); +native mysql_num_rows(sql); +native mysql_field_name(sql, field, name[], length); +native mysql_insert_id(sql); diff --git a/plugins/include/amxmod_compat/translator.inc b/plugins/include/amxmod_compat/translator.inc new file mode 100644 index 00000000..f7a5c41a --- /dev/null +++ b/plugins/include/amxmod_compat/translator.inc @@ -0,0 +1,86 @@ +/* AMX Mod X Backwards Compatibility + * + * by the AMX Mod X Development Team + * + * This file is provided as is (no warranties). + */ + +#if defined _amxmod_translator_included + #endinput +#endif +#define _amxmod_translator_included + +#define _translator_included + +#include +#include +#include + +//From AMX Mod. This is implemented in Core due to the nature of the +// translation engine and what AMX Mod did. +/* Translation backend, used by _T (since natives can't return arrays). */ +native translate(const string[], destid=-1, forcelang=-1); + +stock _T(const string[], destid=-1, forcelang=-1) +{ + new TranslationResult[2] = {0, 0} + TranslationResult[0] = translate(string, destid, forcelang) + return TranslationResult +} + +stock load_translations(const file[]) +{ + static dir[255], path[255]; + get_datadir(dir, 254); + + format(path, 254, "%s/amxmod-lang/%s.txt", dir, file); + new fp + if (!(fp=fopen(path, "r"))) + { + abort(AMX_ERR_NATIVE, "Could not find file: %s", path); + return 0; + } + + static buffer[1024]; + new lang[3]; + new TransKey:bad_key = TransKey:-1; + new TransKey:cur_key = bad_key; + new len; + while (!feof(fp)) + { + buffer[0] = 0; + fgets(fp, buffer, 1023); + len = strlen(buffer); + if (len == 0) + { + continue; + } + if (isspace(buffer[len-1])) + { + buffer[--len] = 0; + } + if (buffer[0] == '"') + { + remove_quotes(buffer); + cur_key = CreateLangKey(buffer); + AddTranslation("en", cur_key, buffer); + continue; + } + if (isspace(buffer[0])) + { + continue; + } + if ((cur_key != bad_key) && (buffer[2] == ':' && buffer[3] == '"')) + { + lang[0] = buffer[0]; + lang[1] = buffer[1]; + lang[2] = 0; + remove_quotes(buffer[3]); + AddTranslation(lang, cur_key, buffer[3]); + } + } + + fclose(fp); + + return 1; +} diff --git a/plugins/include/amxmod_compat/xtrafun.inc b/plugins/include/amxmod_compat/xtrafun.inc new file mode 100644 index 00000000..f49c756d --- /dev/null +++ b/plugins/include/amxmod_compat/xtrafun.inc @@ -0,0 +1,95 @@ +/* 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 +#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 \ No newline at end of file