mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2025-03-16 07:30:21 +03:00
Fun: Clean up code
This commit is contained in:
parent
b89e995fa6
commit
5b74e3285a
@ -11,297 +11,200 @@
|
|||||||
// Fun Module
|
// Fun Module
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "fun.h"
|
#include "fun.h"
|
||||||
#include <HLTypeConversion.h>
|
#include <HLTypeConversion.h>
|
||||||
|
|
||||||
/*
|
|
||||||
JGHG says:
|
|
||||||
|
|
||||||
Ok this is what I use below, it may probably not be right with all natives etc but I try to maintain this style to natives.
|
|
||||||
Note that this is still very much subject to change, regarding return values etc!
|
|
||||||
(Ok I haven't checked all natives that they comply with this yet, this is just a model I'm working on and which I might implement soon.)
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL nativename(AMX *amx, cell *params) // nativename(argument1, argument2); = 2 params
|
|
||||||
{
|
|
||||||
// Description what this native does. <--- Description what this native does
|
|
||||||
// params[1] = argument1 <--- Description of each argument, so we don't have to allocate new variables and can
|
|
||||||
// params[2] = argument2 <--- use the ones in params[n] directly, to save some time.
|
|
||||||
|
|
||||||
// Check receiver and sender validity. <--- Check ents, maybe need to do this better and more proper later?
|
|
||||||
CHECK_PLAYER(params[1])
|
|
||||||
CHECK_PLAYER(params[2])
|
|
||||||
|
|
||||||
// Get * pointer.
|
|
||||||
edict_t *pPlayer = MF_GetPlayerEdict(params[1]); <--- Players require a different function than INDEXENT because of an HLSDK bug
|
|
||||||
|
|
||||||
return 1 <--- If native succeeded, return 1, if the native isn't supposed to return a specific value.
|
|
||||||
Note: Should be able to do: if (thenative()) and it should return false when it fails, and true when succeeds... is -1 treated as false, or is 0 a must?
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
HLTypeConversion TypeConversion;
|
HLTypeConversion TypeConversion;
|
||||||
CPlayer Players[kMaxClients + 1];
|
CPlayer Players[kMaxClients + 1];
|
||||||
|
|
||||||
|
// native get_client_listen(receiver, sender)
|
||||||
// ######## Natives:
|
static cell AMX_NATIVE_CALL get_client_listening(AMX *amx, cell *params)
|
||||||
static cell AMX_NATIVE_CALL get_client_listening(AMX *amx, cell *params) // get_client_listening(receiver, sender); = 2 params
|
|
||||||
{
|
{
|
||||||
// Gets who can listen to who.
|
enum args { arg_count, arg_receiver, arg_sender };
|
||||||
// params[1] = receiver
|
|
||||||
// params[2] = sender
|
|
||||||
|
|
||||||
// Check receiver and sender validity.
|
CHECK_PLAYER(params[arg_receiver]);
|
||||||
CHECK_PLAYER(params[1]);
|
CHECK_PLAYER(params[arg_sender]);
|
||||||
CHECK_PLAYER(params[2]);
|
|
||||||
|
|
||||||
// GET- AND SETCLIENTLISTENING returns "qboolean", an int, probably 0 or 1...
|
return GETCLIENTLISTENING(params[arg_receiver], params[arg_sender]);
|
||||||
return GETCLIENTLISTENING(params[1], params[2]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_client_listening(AMX *amx, cell *params) // set_client_listening(receiver, sender, listen); = 3 params
|
// native set_client_listen(receiver, sender, listen)
|
||||||
|
static cell AMX_NATIVE_CALL set_client_listening(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
// Sets who can listen to who.
|
enum args { arg_count, arg_receiver, arg_sender, arg_listen };
|
||||||
// params[1] = receiver
|
|
||||||
// params[2] = sender
|
|
||||||
// params[3] = listen
|
|
||||||
|
|
||||||
// Check receiver and sender validity.
|
CHECK_PLAYER(params[arg_receiver]);
|
||||||
CHECK_PLAYER(params[1]);
|
CHECK_PLAYER(params[arg_sender]);
|
||||||
CHECK_PLAYER(params[2]);
|
|
||||||
|
|
||||||
// Make a check on params[3] here later, and call run time error when it's wrong.
|
return SETCLIENTLISTENING(params[arg_receiver], params[arg_sender], params[arg_listen]);
|
||||||
// To do: find out the possible values to set (0, 1?)
|
|
||||||
|
|
||||||
// GET- AND SETCLIENTLISTENING returns "qboolean", an int, probably 0 or 1...
|
|
||||||
return SETCLIENTLISTENING(params[1], params[2], params[3]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_user_godmode(AMX *amx, cell *params) // set_user_godmode(index, godmode = 0); = 2 params
|
// native set_user_godmode(index, godmode = 0)
|
||||||
|
static cell AMX_NATIVE_CALL set_user_godmode(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
/* Sets player godmode. If you want to disable godmode set only first parameter. */
|
enum args { arg_count, arg_user, arg_godmode };
|
||||||
// params[1] = index
|
|
||||||
// params[2] = godmode = 0
|
|
||||||
|
|
||||||
// Check index.
|
CHECK_PLAYER(params[arg_user]);
|
||||||
CHECK_PLAYER(params[1]);
|
|
||||||
|
|
||||||
// Get player pointer.
|
auto pPlayer = TypeConversion.id_to_edict(params[arg_user]);
|
||||||
edict_t *pPlayer = TypeConversion.id_to_edict(params[1]);
|
|
||||||
|
|
||||||
if (params[2] == 1) {
|
pPlayer->v.takedamage = params[arg_godmode] != 0 ? DAMAGE_NO : DAMAGE_AIM;
|
||||||
// Enable godmode
|
|
||||||
pPlayer->v.takedamage = 0.0; // 0.0, the player doesn't seem to be able to get hurt.
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Disable godmode
|
|
||||||
pPlayer->v.takedamage = 2.0; // 2.0 seems to be standard value?
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL get_user_godmode(AMX *amx, cell *params) // get_user_godmode(index); = 1 param
|
// native get_user_godmode(index)
|
||||||
|
static cell AMX_NATIVE_CALL get_user_godmode(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
/* Returns 1 if godmode is set. */
|
enum args { arg_count, arg_user };
|
||||||
// params[1] = index
|
|
||||||
|
|
||||||
// Check index.
|
CHECK_PLAYER(params[arg_user]);
|
||||||
CHECK_PLAYER(params[1]);
|
|
||||||
|
|
||||||
// Get player pointer.
|
auto pPlayer = TypeConversion.id_to_edict(params[arg_user]);
|
||||||
edict_t *pPlayer = TypeConversion.id_to_edict(params[1]);
|
|
||||||
|
|
||||||
int godmode = 0;
|
return pPlayer->v.takedamage == DAMAGE_NO;
|
||||||
|
|
||||||
if (pPlayer->v.takedamage == 0.0) {
|
|
||||||
// God mode is enabled
|
|
||||||
godmode = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return godmode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL give_item(AMX *amx, cell *params) // native give_item(index, const item[]); = 2 params
|
// native give_item(index, const item[])
|
||||||
|
static cell AMX_NATIVE_CALL give_item(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
/* Gives item to player, name of item can start
|
enum args { arg_count, arg_index, arg_item };
|
||||||
* with weapon_, ammo_ and item_. This event
|
|
||||||
* is announced with proper message to all players. */
|
|
||||||
// params[1] = index
|
|
||||||
// params[2] = item...
|
|
||||||
|
|
||||||
// Check index.
|
CHECK_PLAYER(params[arg_index]);
|
||||||
CHECK_PLAYER(params[1]);
|
|
||||||
|
|
||||||
// Get player pointer.
|
auto itemLength = 0;
|
||||||
edict_t *pPlayer = TypeConversion.id_to_edict(params[1]);
|
auto item = MF_GetAmxString(amx, params[arg_item], 1, &itemLength);
|
||||||
|
|
||||||
// Create item entity pointer
|
if (!itemLength
|
||||||
edict_t *pItemEntity;
|
||(strncmp(item, "weapon_", 7)
|
||||||
|
&& strncmp(item, "ammo_", 5)
|
||||||
// Make an "intstring" out of 2nd parameter
|
&& strncmp(item, "item_", 5)
|
||||||
int length;
|
&& strncmp(item, "tf_weapon_", 10)))
|
||||||
const char *szItem = MF_GetAmxString(amx, params[2], 1, &length);
|
{
|
||||||
|
|
||||||
//check for valid item
|
|
||||||
if (strncmp(szItem, "weapon_", 7) &&
|
|
||||||
strncmp(szItem, "ammo_", 5) &&
|
|
||||||
strncmp(szItem, "item_", 5) &&
|
|
||||||
strncmp(szItem, "tf_weapon_", 10)
|
|
||||||
) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//string_t item = MAKE_STRING(szItem);
|
auto pEntity = CREATE_NAMED_ENTITY(ALLOC_STRING(item));
|
||||||
string_t item = ALLOC_STRING(szItem); // Using MAKE_STRING makes "item" contents get lost when we leave this scope! ALLOC_STRING seems to allocate properly...
|
|
||||||
// Create the entity, returns to pointer
|
|
||||||
pItemEntity = CREATE_NAMED_ENTITY(item);
|
|
||||||
|
|
||||||
if (FNullEnt(pItemEntity)) {
|
if (FNullEnt(pEntity))
|
||||||
MF_LogError(amx, AMX_ERR_NATIVE, "Item \"%s\" failed to create", szItem);
|
{
|
||||||
|
MF_LogError(amx, AMX_ERR_NATIVE, "Item \"%s\" failed to create", item);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//VARS(pItemEntity)->origin = VARS(pPlayer)->origin; // nice to do VARS(ent)->origin instead of ent->v.origin? :-I
|
auto pPlayer = TypeConversion.id_to_edict(params[arg_index]);
|
||||||
//I'm not sure, normally I use macros too =P
|
|
||||||
pItemEntity->v.origin = pPlayer->v.origin;
|
|
||||||
pItemEntity->v.spawnflags |= SF_NORESPAWN; //SF_NORESPAWN;
|
|
||||||
|
|
||||||
MDLL_Spawn(pItemEntity);
|
pEntity->v.origin = pPlayer->v.origin;
|
||||||
|
pEntity->v.spawnflags |= SF_NORESPAWN;
|
||||||
|
|
||||||
int save = pItemEntity->v.solid;
|
MDLL_Spawn(pEntity);
|
||||||
|
|
||||||
MDLL_Touch(pItemEntity, ENT(pPlayer));
|
auto oldSolid = pEntity->v.solid;
|
||||||
|
|
||||||
//The problem with the original give_item was the
|
MDLL_Touch(pEntity, pPlayer);
|
||||||
// item was not removed. I had tried this but it
|
|
||||||
// did not work. OLO's implementation is better.
|
|
||||||
/*
|
|
||||||
int iEnt = ENTINDEX(pItemEntity->v.owner);
|
|
||||||
if (iEnt > 32 || iEnt <1 ) {
|
|
||||||
MDLL_Think(pItemEntity);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (pItemEntity->v.solid == save) {
|
if (pEntity->v.solid == oldSolid)
|
||||||
REMOVE_ENTITY(pItemEntity);
|
{
|
||||||
//the function did not fail - we're just deleting the item
|
REMOVE_ENTITY(pEntity); // The function did not fail - we're just deleting the item
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TypeConversion.edict_to_id(pItemEntity);
|
return TypeConversion.edict_to_id(pEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL spawn(AMX *amx, cell *params) // spawn(id) = 1 param
|
// native spawn(index)
|
||||||
|
static cell AMX_NATIVE_CALL spawn(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
// Spawns an entity, this can be a user/player -> spawns at spawnpoints, or created entities seems to need this as a final "kick" into the game? :-)
|
enum args { arg_count, arg_index };
|
||||||
// params[1] = entity to spawn
|
|
||||||
|
|
||||||
CHECK_ENTITY(params[1]);
|
CHECK_ENTITY(params[arg_index]);
|
||||||
|
|
||||||
edict_t *pEnt = TypeConversion.id_to_edict(params[1]);
|
auto pEntity = TypeConversion.id_to_edict(params[arg_index]);
|
||||||
|
|
||||||
MDLL_Spawn(pEnt);
|
MDLL_Spawn(pEntity);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_user_health(AMX *amx, cell *params) // set_user_health(index, health); = 2 arguments
|
// native set_user_health(index, health)
|
||||||
|
static cell AMX_NATIVE_CALL set_user_health(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
// Sets user health. If health is 0 and below, also kill...
|
enum args { arg_count, arg_index, arg_health };
|
||||||
// params[1] = index
|
|
||||||
// params[2] = health
|
|
||||||
|
|
||||||
// Check index
|
CHECK_PLAYER(params[arg_index]);
|
||||||
CHECK_PLAYER(params[1]);
|
|
||||||
|
|
||||||
// Fetch player pointer
|
auto pPlayer = TypeConversion.id_to_edict(params[arg_index]);
|
||||||
edict_t *pPlayer = TypeConversion.id_to_edict(params[1]);
|
auto health = float(params[arg_health]);
|
||||||
|
|
||||||
// Kill if health too low.
|
if (health > 0.0f)
|
||||||
if (params[2] > 0)
|
{
|
||||||
pPlayer->v.health = float(params[2]);
|
pPlayer->v.health = health;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
MDLL_ClientKill(pPlayer);
|
MDLL_ClientKill(pPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_user_frags(AMX *amx, cell *params) // set_user_frags(index, frags); = 2 arguments
|
// native set_user_frags(index, frags)
|
||||||
|
static cell AMX_NATIVE_CALL set_user_frags(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
// Sets user frags.
|
enum args { arg_count, arg_index, arg_frags };
|
||||||
// params[1] = index
|
|
||||||
// params[2] = frags
|
|
||||||
|
|
||||||
// Check index
|
CHECK_PLAYER(params[arg_index]);
|
||||||
CHECK_PLAYER(params[1]);
|
|
||||||
|
|
||||||
// Fetch player pointer
|
auto pPlayer = TypeConversion.id_to_edict(params[arg_index]);
|
||||||
edict_t *pPlayer = TypeConversion.id_to_edict(params[1]);
|
|
||||||
|
|
||||||
pPlayer->v.frags = params[2];
|
pPlayer->v.frags = float(params[arg_frags]);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_user_armor(AMX *amx, cell *params) // set_user_armor(index, armor); = 2 arguments
|
// native set_user_armor(index, armor)
|
||||||
|
static cell AMX_NATIVE_CALL set_user_armor(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
// Sets user armor.
|
enum args { arg_count, arg_index, arg_armor };
|
||||||
// params[1] = index
|
|
||||||
// params[2] = armor
|
|
||||||
|
|
||||||
// Check index
|
CHECK_PLAYER(params[arg_index]);
|
||||||
CHECK_PLAYER(params[1]);
|
|
||||||
|
|
||||||
// Fetch player pointer
|
auto pPlayer = TypeConversion.id_to_edict(params[arg_index]);
|
||||||
edict_t *pPlayer = TypeConversion.id_to_edict(params[1]);
|
|
||||||
|
|
||||||
pPlayer->v.armorvalue = params[2];
|
pPlayer->v.armorvalue = float(params[arg_armor]);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_user_origin(AMX *amx, cell *params) // set_user_origin(index, origin[3]); = 2 arguments
|
// native set_user_origin(index, const origin[3])
|
||||||
|
static cell AMX_NATIVE_CALL set_user_origin(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
// Sets user origin.
|
enum args { arg_count, arg_index, arg_origin };
|
||||||
// params[1] = index
|
|
||||||
// params[2] = origin
|
|
||||||
|
|
||||||
// Check index
|
CHECK_PLAYER(params[arg_index]);
|
||||||
CHECK_PLAYER(params[1]);
|
|
||||||
|
|
||||||
// Fetch player pointer
|
auto pPlayer = TypeConversion.id_to_edict(params[arg_index]);
|
||||||
edict_t *pPlayer = TypeConversion.id_to_edict(params[1]);
|
auto pVector = MF_GetAmxAddr(amx, params[arg_origin]);
|
||||||
|
|
||||||
cell *newVectorCell = MF_GetAmxAddr(amx, params[2]);
|
|
||||||
|
|
||||||
SET_SIZE(pPlayer, pPlayer->v.mins, pPlayer->v.maxs);
|
SET_SIZE(pPlayer, pPlayer->v.mins, pPlayer->v.maxs);
|
||||||
SET_ORIGIN(pPlayer, Vector((float)newVectorCell[0], (float)newVectorCell[1], (float)newVectorCell[2]));
|
SET_ORIGIN(pPlayer, Vector(float(pVector[0]), float(pVector[1]), float(pVector[2])));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_user_rendering(AMX *amx, cell *params) // set_user_rendering(index, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16); = 7 arguments
|
// native set_user_rendering(index, fx = kRenderFxNone, r = 0, g = 0, b = 0, render = kRenderNormal, amount = 0)
|
||||||
|
static cell AMX_NATIVE_CALL set_user_rendering(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
// Sets user rendering.
|
enum args { arg_count, arg_index, arg_fx, arg_red, arg_green, arg_blue, arg_render, arg_amount };
|
||||||
// params[1] = index
|
|
||||||
// params[2] = fx
|
|
||||||
// params[3] = r
|
|
||||||
// params[4] = g
|
|
||||||
// params[5] = b
|
|
||||||
// params[6] = render
|
|
||||||
// params[7] = amount
|
|
||||||
|
|
||||||
// Check index
|
CHECK_PLAYER(params[arg_index]);
|
||||||
CHECK_PLAYER(params[1]);
|
|
||||||
|
|
||||||
// Fetch player pointer
|
auto pPlayer = TypeConversion.id_to_edict(params[arg_index]);
|
||||||
edict_t *pPlayer = TypeConversion.id_to_edict(params[1]);
|
|
||||||
|
|
||||||
pPlayer->v.renderfx = params[2];
|
pPlayer->v.renderfx = params[arg_fx];
|
||||||
Vector newVector = Vector(float(params[3]), float(params[4]), float(params[5]));
|
pPlayer->v.rendercolor = Vector(float(params[arg_red]), float(params[arg_green]), float(params[arg_blue]));
|
||||||
pPlayer->v.rendercolor = newVector;
|
pPlayer->v.rendermode = params[arg_render];
|
||||||
pPlayer->v.rendermode = params[6];
|
pPlayer->v.renderamt = float(params[arg_amount]);
|
||||||
pPlayer->v.renderamt = params[7];
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -333,248 +236,249 @@ static cell AMX_NATIVE_CALL get_user_rendering(AMX *amx, cell *params) // get_us
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_user_maxspeed(AMX *amx, cell *params) // set_user_maxspeed(index, Float:speed = -1.0) = 2 arguments
|
// native set_user_maxspeed(index, Float:speed = -1.0)
|
||||||
|
static cell AMX_NATIVE_CALL set_user_maxspeed(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
// Sets user maxspeed.
|
enum args { arg_count, arg_index, arg_speed };
|
||||||
// params[1] = index
|
|
||||||
// params[2] = speed (should be -1.0 if not specified) (JGHG: unspecified parameters seems to always be -1.0!)
|
|
||||||
|
|
||||||
REAL fNewSpeed = amx_ctof(params[2]);
|
CHECK_PLAYER(params[arg_index]);
|
||||||
|
|
||||||
// Check index
|
auto pPlayer = TypeConversion.id_to_edict(params[arg_index]);
|
||||||
CHECK_PLAYER(params[1]);
|
auto newSpeed = amx_ctof(params[arg_speed]);
|
||||||
|
|
||||||
// Fetch player pointer
|
SETCLIENTMAXSPEED(pPlayer, newSpeed);
|
||||||
edict_t *pPlayer = TypeConversion.id_to_edict(params[1]);
|
pPlayer->v.maxspeed = newSpeed;
|
||||||
|
|
||||||
SETCLIENTMAXSPEED(pPlayer, fNewSpeed);
|
|
||||||
pPlayer->v.maxspeed = fNewSpeed;
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL get_user_maxspeed(AMX *amx, cell *params) // Float:get_user_maxspeed(index) = 1 argument
|
// native Float:get_user_maxspeed(index)
|
||||||
|
static cell AMX_NATIVE_CALL get_user_maxspeed(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
// Gets user maxspeed.
|
enum args { arg_count, arg_index };
|
||||||
// params[1] = index
|
|
||||||
|
|
||||||
// Check index
|
CHECK_PLAYER(params[arg_index]);
|
||||||
CHECK_PLAYER(params[1]);
|
|
||||||
|
|
||||||
// Fetch player pointer
|
auto pPlayer = TypeConversion.id_to_edict(params[arg_index]);
|
||||||
edict_t *pPlayer = TypeConversion.id_to_edict(params[1]);
|
|
||||||
|
|
||||||
return amx_ftoc(pPlayer->v.maxspeed);
|
return amx_ftoc(pPlayer->v.maxspeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_user_gravity(AMX *amx, cell *params) // set_user_gravity(index, Float:gravity = 1.0) = 2 arguments
|
// native set_user_gravity(index, Float:gravity = 1.0)
|
||||||
|
static cell AMX_NATIVE_CALL set_user_gravity(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
// Sets user gravity.
|
enum args { arg_count, arg_index, arg_gravity };
|
||||||
// params[1] = index
|
|
||||||
// params[2] = gravity (=-1.0)
|
|
||||||
// Check index
|
|
||||||
CHECK_PLAYER(params[1]);
|
|
||||||
|
|
||||||
// Fetch player pointer
|
CHECK_PLAYER(params[arg_index]);
|
||||||
edict_t *pPlayer = TypeConversion.id_to_edict(params[1]);
|
|
||||||
|
|
||||||
pPlayer->v.gravity = amx_ctof(params[2]);
|
auto pPlayer = TypeConversion.id_to_edict(params[arg_index]);
|
||||||
|
|
||||||
|
pPlayer->v.gravity = amx_ctof(params[arg_gravity]);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL get_user_gravity(AMX *amx, cell *params) // Float:get_user_gravity(index) = 1 argument
|
// native Float:get_user_gravity(index)
|
||||||
|
static cell AMX_NATIVE_CALL get_user_gravity(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
// Gets user gravity.
|
enum args { arg_count, arg_index };
|
||||||
// params[1] = index
|
|
||||||
|
|
||||||
// Check index
|
CHECK_PLAYER(params[arg_index]);
|
||||||
CHECK_PLAYER(params[1]);
|
|
||||||
|
|
||||||
// Fetch player pointer
|
auto pPlayer = TypeConversion.id_to_edict(params[arg_index]);
|
||||||
edict_t *pPlayer = TypeConversion.id_to_edict(params[1]);
|
|
||||||
|
|
||||||
return amx_ftoc(pPlayer->v.gravity);
|
return amx_ftoc(pPlayer->v.gravity);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_user_hitzones(AMX *amx, cell *params) // set_user_hitzones(index = 0, target = 0, body = 255); = 3 arguments
|
// native set_user_hitzones(index = 0, target = 0, body = 255)
|
||||||
|
static cell AMX_NATIVE_CALL set_user_hitzones(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
// Sets user hitzones.
|
enum args { arg_count, arg_attacker, arg_target, arg_hitzones };
|
||||||
// params[1] = the one(s) who shoot(s), shooter
|
|
||||||
int shooter = params[1];
|
|
||||||
|
|
||||||
// params[2] = the one getting hit
|
int attacker = params[arg_attacker];
|
||||||
int gettingHit = params[2];
|
int target = params[arg_target];
|
||||||
|
int hitzones = params[arg_hitzones];
|
||||||
|
|
||||||
// params[3] = specified hit zones
|
if (attacker == 0 && target == 0)
|
||||||
int hitzones = params[3];
|
{
|
||||||
|
for (auto i = 1; i <= gpGlobals->maxClients; ++i)
|
||||||
//set_user_hitzones(id, 0, 0) // Makes ID not able to shoot EVERYONE - id can shoot on 0 (all) at 0
|
{
|
||||||
//set_user_hitzones(0, id, 0) // Makes EVERYONE not able to shoot ID - 0 (all) can shoot id at 0
|
for (auto j = 1; j <= gpGlobals->maxClients; ++j)
|
||||||
if (shooter == 0 && gettingHit == 0) {
|
{
|
||||||
for (int i = 1; i <= gpGlobals->maxClients; i++) {
|
|
||||||
for (int j = 1; j <= gpGlobals->maxClients; j++) {
|
|
||||||
Players[i].SetBodyHits(j, hitzones);
|
Players[i].SetBodyHits(j, hitzones);
|
||||||
}
|
}
|
||||||
//g_zones_toHit[i] = hitzones;
|
|
||||||
//g_zones_getHit[i] = hitzones;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (shooter == 0 && gettingHit != 0) {
|
else if (attacker == 0 && target != 0)
|
||||||
// "All" shooters, target (gettingHit) should be existing player id
|
{
|
||||||
CHECK_PLAYER(gettingHit);
|
CHECK_PLAYER(target);
|
||||||
// Where can all hit gettingHit?
|
|
||||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
for (auto i = 1; i <= gpGlobals->maxClients; ++i)
|
||||||
Players[i].SetBodyHits(gettingHit, hitzones);
|
{
|
||||||
|
Players[i].SetBodyHits(target, hitzones);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (shooter != 0 && gettingHit == 0) {
|
else if (attacker != 0 && target == 0)
|
||||||
// Shooter can hit all in bodyparts.
|
{
|
||||||
CHECK_PLAYER(shooter);
|
CHECK_PLAYER(attacker);
|
||||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
|
||||||
Players[shooter].SetBodyHits(i, hitzones);
|
for (auto i = 1; i <= gpGlobals->maxClients; ++i)
|
||||||
|
{
|
||||||
|
Players[attacker].SetBodyHits(i, hitzones);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// Specified, where can player A hit player B?
|
|
||||||
CHECK_PLAYER(shooter);
|
|
||||||
CHECK_PLAYER(gettingHit);
|
|
||||||
Players[shooter].SetBodyHits(gettingHit, hitzones);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL get_user_hitzones(AMX *amx, cell *params) // get_user_hitzones(index, target); = 2 arguments
|
|
||||||
{
|
|
||||||
int shooter = params[1];
|
|
||||||
CHECK_PLAYER(shooter);
|
|
||||||
int target = params[2];
|
|
||||||
CHECK_PLAYER(target);
|
|
||||||
return Players[shooter].GetBodyHits(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_user_noclip(AMX *amx, cell *params) // set_user_noclip(index, noclip = 0); = 2 arguments
|
|
||||||
{
|
|
||||||
// Sets user to no clipping mode.
|
|
||||||
// params[1] = index
|
|
||||||
// params[2] = no clip or not...
|
|
||||||
|
|
||||||
// Check index
|
|
||||||
CHECK_PLAYER(params[1]);
|
|
||||||
|
|
||||||
// Fetch player pointer
|
|
||||||
edict_t *pPlayer = TypeConversion.id_to_edict(params[1]);
|
|
||||||
|
|
||||||
if (params[2] == 1)
|
|
||||||
pPlayer->v.movetype = MOVETYPE_NOCLIP;
|
|
||||||
else
|
else
|
||||||
pPlayer->v.movetype = MOVETYPE_WALK;
|
{
|
||||||
|
CHECK_PLAYER(attacker);
|
||||||
|
CHECK_PLAYER(target);
|
||||||
|
|
||||||
|
Players[attacker].SetBodyHits(target, hitzones);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL get_user_noclip(AMX *amx, cell *params) // get_user_noclip(index); = 1 argument
|
// native get_user_hitzones(index, target)
|
||||||
|
static cell AMX_NATIVE_CALL get_user_hitzones(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
// Gets user noclip.
|
enum args { arg_count, arg_attacker, arg_target };
|
||||||
// params[1] = index
|
|
||||||
|
|
||||||
// Check index
|
auto attacker = params[arg_attacker];
|
||||||
CHECK_PLAYER(params[1]);
|
|
||||||
|
|
||||||
// Fetch player pointer
|
CHECK_PLAYER(attacker);
|
||||||
edict_t *pPlayer = TypeConversion.id_to_edict(params[1]);
|
|
||||||
|
auto target = params[arg_target];
|
||||||
|
|
||||||
|
CHECK_PLAYER(target);
|
||||||
|
|
||||||
|
return Players[attacker].GetBodyHits(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
// native set_user_noclip(index, noclip = 0)
|
||||||
|
static cell AMX_NATIVE_CALL set_user_noclip(AMX *amx, cell *params)
|
||||||
|
{
|
||||||
|
enum args { arg_count, arg_index, arg_noclip };
|
||||||
|
|
||||||
|
CHECK_PLAYER(params[arg_index]);
|
||||||
|
|
||||||
|
auto pPlayer = TypeConversion.id_to_edict(params[arg_index]);
|
||||||
|
|
||||||
|
pPlayer->v.movetype = params[arg_noclip] != 0 ? MOVETYPE_NOCLIP : MOVETYPE_WALK;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// native get_user_noclip(index)
|
||||||
|
static cell AMX_NATIVE_CALL get_user_noclip(AMX *amx, cell *params)
|
||||||
|
{
|
||||||
|
enum args { arg_count, arg_index };
|
||||||
|
|
||||||
|
CHECK_PLAYER(params[arg_index]);
|
||||||
|
|
||||||
|
auto pPlayer = TypeConversion.id_to_edict(params[arg_index]);
|
||||||
|
|
||||||
return pPlayer->v.movetype == MOVETYPE_NOCLIP;
|
return pPlayer->v.movetype == MOVETYPE_NOCLIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
// JustinHoMi made this one originally
|
// native set_user_footsteps(id, set = 1)
|
||||||
static cell AMX_NATIVE_CALL set_user_footsteps(AMX *amx, cell *params) // set_user_footsteps(id, set = 1); = 2 params
|
static cell AMX_NATIVE_CALL set_user_footsteps(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
// Gives player silent footsteps.
|
enum args { arg_count, arg_index, arg_footsteps };
|
||||||
// if set=0 it will return footsteps to normal
|
|
||||||
// params[1] = index of player
|
|
||||||
// params[2] = 0 = normal footstep sound, 1 = silent slippers
|
|
||||||
|
|
||||||
// Check index
|
auto index = params[arg_index];
|
||||||
CHECK_PLAYER(params[1]);
|
|
||||||
|
|
||||||
// Fetch player pointer
|
CHECK_PLAYER(index);
|
||||||
edict_t *pPlayer = TypeConversion.id_to_edict(params[1]);
|
|
||||||
|
|
||||||
if (params[2]) {
|
auto pPlayer = TypeConversion.id_to_edict(index);
|
||||||
|
|
||||||
|
if (params[arg_footsteps] != 0)
|
||||||
|
{
|
||||||
pPlayer->v.flTimeStepSound = 999;
|
pPlayer->v.flTimeStepSound = 999;
|
||||||
Players[params[1]].SetSilentFootsteps(true);
|
Players[index].SetSilentFootsteps(true);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
pPlayer->v.flTimeStepSound = STANDARDTIMESTEPSOUND;
|
pPlayer->v.flTimeStepSound = STANDARDTIMESTEPSOUND;
|
||||||
Players[params[1]].SetSilentFootsteps(false);
|
Players[index].SetSilentFootsteps(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// native get_user_footsteps(index)
|
||||||
static cell AMX_NATIVE_CALL get_user_footsteps(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL get_user_footsteps(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
CHECK_PLAYER(params[1]);
|
enum args { arg_count, arg_index };
|
||||||
|
|
||||||
return Players[params[1]].HasSilentFootsteps();
|
auto index = params[arg_index];
|
||||||
|
|
||||||
|
CHECK_PLAYER(index);
|
||||||
|
|
||||||
|
return Players[index].HasSilentFootsteps();
|
||||||
}
|
}
|
||||||
|
|
||||||
// SidLuke
|
// native strip_user_weapons(index)
|
||||||
static cell AMX_NATIVE_CALL strip_user_weapons(AMX *amx, cell *params) // index
|
static cell AMX_NATIVE_CALL strip_user_weapons(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
CHECK_PLAYER(params[1]);
|
enum args { arg_count, arg_index };
|
||||||
|
|
||||||
edict_t* pPlayer = TypeConversion.id_to_edict(params[1]);
|
auto index = params[arg_index];
|
||||||
|
|
||||||
string_t item = MAKE_STRING("player_weaponstrip");
|
CHECK_PLAYER(index);
|
||||||
edict_t *pent = CREATE_NAMED_ENTITY(item);
|
|
||||||
|
|
||||||
if (FNullEnt(pent))
|
auto pPlayer = TypeConversion.id_to_edict(index);
|
||||||
|
auto pEntity = CREATE_NAMED_ENTITY(MAKE_STRING("player_weaponstrip"));
|
||||||
|
|
||||||
|
if (FNullEnt(pEntity))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MDLL_Spawn(pent);
|
MDLL_Spawn(pEntity);
|
||||||
MDLL_Use(pent, pPlayer);
|
MDLL_Use(pEntity, pPlayer);
|
||||||
REMOVE_ENTITY(pent);
|
REMOVE_ENTITY(pEntity);
|
||||||
|
|
||||||
*reinterpret_cast<int *>(MF_PlayerPropAddr(params[1], Player_CurrentWeapon)) = 0;
|
*reinterpret_cast<int *>(MF_PlayerPropAddr(index, Player_CurrentWeapon)) = 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
AMX_NATIVE_INFO fun_Exports[] = {
|
|
||||||
{"get_client_listen", get_client_listening},
|
AMX_NATIVE_INFO fun_Exports[] =
|
||||||
{"set_client_listen", set_client_listening},
|
{
|
||||||
{"set_user_godmode", set_user_godmode},
|
{ "get_client_listen" , get_client_listening },
|
||||||
{"get_user_godmode", get_user_godmode},
|
{ "set_client_listen" , set_client_listening },
|
||||||
{"set_user_health", set_user_health},
|
{ "set_user_godmode" , set_user_godmode },
|
||||||
{"give_item", give_item},
|
{ "get_user_godmode" , get_user_godmode },
|
||||||
{"spawn", spawn},
|
{ "set_user_health" , set_user_health },
|
||||||
{"set_user_frags", set_user_frags},
|
{ "give_item" , give_item },
|
||||||
{"set_user_armor", set_user_armor},
|
{ "spawn" , spawn },
|
||||||
{"set_user_origin", set_user_origin},
|
{ "set_user_frags" , set_user_frags },
|
||||||
{"set_user_rendering", set_user_rendering},
|
{ "set_user_armor" , set_user_armor },
|
||||||
{"get_user_rendering", get_user_rendering},
|
{ "set_user_origin" , set_user_origin },
|
||||||
{"set_user_maxspeed", set_user_maxspeed},
|
{ "set_user_rendering", set_user_rendering },
|
||||||
{"get_user_maxspeed", get_user_maxspeed},
|
{ "get_user_rendering", get_user_rendering},
|
||||||
{"set_user_gravity", set_user_gravity},
|
{ "set_user_maxspeed" , set_user_maxspeed },
|
||||||
{"get_user_gravity", get_user_gravity},
|
{ "get_user_maxspeed" , get_user_maxspeed },
|
||||||
{"get_user_footsteps", get_user_footsteps},
|
{ "set_user_gravity" , set_user_gravity },
|
||||||
{"set_user_hitzones", set_user_hitzones},
|
{ "get_user_gravity" , get_user_gravity },
|
||||||
{"get_user_hitzones", get_user_hitzones},
|
{ "get_user_footsteps", get_user_footsteps },
|
||||||
{"set_user_noclip", set_user_noclip},
|
{ "set_user_hitzones" , set_user_hitzones },
|
||||||
{"get_user_noclip", get_user_noclip},
|
{ "get_user_hitzones" , get_user_hitzones },
|
||||||
{"set_user_footsteps", set_user_footsteps},
|
{ "set_user_noclip" , set_user_noclip },
|
||||||
{"strip_user_weapons", strip_user_weapons},
|
{ "get_user_noclip" , get_user_noclip },
|
||||||
/////////////////// <--- 19 chars max in current small version
|
{ "set_user_footsteps", set_user_footsteps },
|
||||||
{NULL, NULL}
|
{ "strip_user_weapons", strip_user_weapons },
|
||||||
|
{ NULL , NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************************/
|
|
||||||
void PlayerPreThink(edict_t *pEntity)
|
void PlayerPreThink(edict_t *pEntity)
|
||||||
{
|
{
|
||||||
if (Players[TypeConversion.edict_to_id(pEntity)].HasSilentFootsteps()) {
|
auto index = TypeConversion.edict_to_id(pEntity);
|
||||||
|
|
||||||
|
if (Players[index].HasSilentFootsteps())
|
||||||
|
{
|
||||||
pEntity->v.flTimeStepSound = 999;
|
pEntity->v.flTimeStepSound = 999;
|
||||||
RETURN_META(MRES_HANDLED);
|
RETURN_META(MRES_HANDLED);
|
||||||
}
|
}
|
||||||
@ -584,75 +488,44 @@ void PlayerPreThink(edict_t *pEntity)
|
|||||||
|
|
||||||
int ClientConnect(edict_t *pPlayer, const char *pszName, const char *pszAddress, char szRejectReason[128])
|
int ClientConnect(edict_t *pPlayer, const char *pszName, const char *pszAddress, char szRejectReason[128])
|
||||||
{
|
{
|
||||||
Players[TypeConversion.edict_to_id(pPlayer)].Reset();
|
auto index = TypeConversion.edict_to_id(pPlayer);
|
||||||
|
|
||||||
|
Players[index].Reset();
|
||||||
|
|
||||||
RETURN_META_VALUE(MRES_IGNORED, 0);
|
RETURN_META_VALUE(MRES_IGNORED, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TraceLine(const float *v1, const float *v2, int fNoMonsters, edict_t *shooter, TraceResult *ptr) {
|
void TraceLine(const float *v1, const float *v2, int fNoMonsters, edict_t *shooter, TraceResult *ptr)
|
||||||
|
{
|
||||||
TRACE_LINE(v1, v2, fNoMonsters, shooter, ptr);
|
TRACE_LINE(v1, v2, fNoMonsters, shooter, ptr);
|
||||||
if ( ptr->pHit && (ptr->pHit->v.flags& (FL_CLIENT | FL_FAKECLIENT))
|
|
||||||
&& shooter && (shooter->v.flags & (FL_CLIENT | FL_FAKECLIENT)) ) {
|
if (ptr->pHit && (ptr->pHit->v.flags & (FL_CLIENT | FL_FAKECLIENT))
|
||||||
int shooterIndex = TypeConversion.edict_to_id(shooter);
|
&& shooter && (shooter->v.flags & (FL_CLIENT | FL_FAKECLIENT)) )
|
||||||
if ( !(Players[shooterIndex].GetBodyHits(TypeConversion.edict_to_id(ptr->pHit))& (1<<ptr->iHitgroup)) )
|
{
|
||||||
|
auto shooterIndex = TypeConversion.edict_to_id(shooter);
|
||||||
|
auto targetIndex = TypeConversion.edict_to_id(ptr->pHit);
|
||||||
|
|
||||||
|
if (!(Players[shooterIndex].GetBodyHits(targetIndex) & (1 << ptr->iHitgroup)))
|
||||||
|
{
|
||||||
ptr->flFraction = 1.0;
|
ptr->flFraction = 1.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//int g_hitIndex, g_canTargetGetHit, g_canShooterHitThere;
|
|
||||||
//void TraceLine(const float *v1, const float *v2, int fNoMonsters, edict_t *shooter, TraceResult *ptr) {
|
|
||||||
// if (!pentToSkip || (pentToSkip->v.flags & (FL_CLIENT | FL_FAKECLIENT)) == false || pentToSkip->v.deadflag != DEAD_NO)
|
|
||||||
// RETURN_META(MRES_IGNORED);
|
|
||||||
//
|
|
||||||
// TRACE_LINE(v1, v2, fNoMonsters, shooter, ptr); // Filter shooter
|
|
||||||
//
|
|
||||||
// if (!ptr->pHit || (ptr->pHit->v.flags & (FL_CLIENT | FL_FAKECLIENT)) == false )
|
|
||||||
// RETURN_META(MRES_SUPERCEDE);
|
|
||||||
//
|
|
||||||
// g_hitIndex = ENTINDEX(ptr->pHit);
|
|
||||||
// //bool blocked = false;
|
|
||||||
// g_canTargetGetHit = g_zones_getHit[g_hitIndex] & (1 << ptr->iHitgroup);
|
|
||||||
// g_canShooterHitThere = g_zones_toHit[ENTINDEX(shooter)] & (1 << ptr->iHitgroup);
|
|
||||||
//
|
|
||||||
// if (!g_canTargetGetHit || !g_canShooterHitThere) {
|
|
||||||
// ptr->flFraction = 1.0; // set to not hit anything (1.0 = shot doesn't hit anything)
|
|
||||||
// //blocked = true;
|
|
||||||
// }
|
|
||||||
// /*
|
|
||||||
// if (blocked) {
|
|
||||||
// MF_PrintSrvConsole("%s was blocked from hitting %s: %d and %d\n", MF_GetPlayerName(ENTINDEX(pentToSkip)), MF_GetPlayerName(hitIndex), canTargetGetHit, canShooterHitThere);
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// MF_PrintSrvConsole("%s was NOT blocked from hitting %s: %d and %d\n", MF_GetPlayerName(ENTINDEX(pentToSkip)), MF_GetPlayerName(hitIndex), canTargetGetHit, canShooterHitThere);
|
|
||||||
// }
|
|
||||||
// */
|
|
||||||
//
|
|
||||||
// RETURN_META(MRES_SUPERCEDE);
|
|
||||||
//}
|
|
||||||
|
|
||||||
void OnAmxxAttach()
|
void OnAmxxAttach()
|
||||||
{
|
{
|
||||||
MF_AddNatives(fun_Exports);
|
MF_AddNatives(fun_Exports);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The content of OnPluginsLoaded() was moved from OnAmxxAttach with AMXx 1.5 because for some reason gpGlobals->maxClients wasn't
|
void OnPluginsLoaded()
|
||||||
// initialized to its proper value until some time after OnAmxxAttach(). In OnAmxxAttach() it always showed 0. /JGHG
|
{
|
||||||
void OnPluginsLoaded() {
|
for (auto i = 1; i <= gpGlobals->maxClients; ++i)
|
||||||
// Reset stuff - hopefully this should
|
{
|
||||||
for (int i = 1; i <= gpGlobals->maxClients; i++) {
|
|
||||||
// Reset all hitzones
|
|
||||||
Players[i].Reset();
|
Players[i].Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeConversion.init();
|
TypeConversion.init();
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void ClientConnectFakeBot(int index)
|
|
||||||
{
|
|
||||||
FUNUTIL_ResetPlayer(index);
|
|
||||||
//MF_Log("A bot connects, forwarded to fun! The bot is %d!", index);
|
|
||||||
//CPlayer* player;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user