From 6e8895bed98190d81db3968a98b180392ab95243 Mon Sep 17 00:00:00 2001 From: s1lent Date: Sat, 23 Sep 2017 22:20:40 +0700 Subject: [PATCH] Add native get_viewent --- .gitignore | 2 + reapi/build.gradle | 1 + .../extra/amxmodx/scripting/include/reapi.inc | 10 +- reapi/include/com_client.h | 129 ++++++++++ reapi/include/com_delta_packet.h | 39 +++ reapi/include/com_net.h | 237 ++++++++++++++++++ reapi/include/com_progdefs.h | 110 ++++---- reapi/include/cssdk/common/const.h | 7 +- reapi/include/cssdk/dlls/extdll.h | 1 - reapi/include/cssdk/dlls/util.h | 7 +- reapi/include/cssdk/dlls/weapons.h | 2 +- reapi/include/cssdk/engine/eiface.h | 40 +-- reapi/include/cssdk/engine/maintypes.h | 3 - reapi/include/typedef_strong.h | 35 +++ reapi/msvc/reapi.vcxproj | 7 +- reapi/msvc/reapi.vcxproj.filters | 9 + reapi/src/member_list.cpp | 42 ++-- reapi/src/natives/natives_common.cpp | 26 +- reapi/src/natives/natives_members.cpp | 4 +- reapi/src/precompiled.h | 2 + reapi/src/type_conversion.h | 26 +- 21 files changed, 626 insertions(+), 113 deletions(-) create mode 100644 reapi/include/com_client.h create mode 100644 reapi/include/com_delta_packet.h create mode 100644 reapi/include/com_net.h create mode 100644 reapi/include/typedef_strong.h diff --git a/.gitignore b/.gitignore index 9575227..1a58d04 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ **/.gradle .idea *.iml +*.bat **/msvc/Debug* **/msvc/Release* **/msvc/*.sdf @@ -10,6 +11,7 @@ **/msvc/*.suo **/msvc/*.db **/msvc/*.opendb +**/msvc/*.txt **/msvc/*.aps **/msvc/.vs **/msvc/START*.bat diff --git a/reapi/build.gradle b/reapi/build.gradle index 16183b6..d4f01ce 100644 --- a/reapi/build.gradle +++ b/reapi/build.gradle @@ -38,6 +38,7 @@ void postEvaluate(NativeBinarySpec b) { void setupToolchain(NativeBinarySpec b) { ToolchainConfig cfg = rootProject.createToolchainConfig(b) cfg.projectInclude(project, '', '/src', '/src/mods', '/src/natives', '/include', '/include/metamod', '/include/cssdk/common', '/include/cssdk/dlls', '/include/cssdk/engine', '/include/cssdk/game_shared', '/include/cssdk/pm_shared', '/include/cssdk/public') + cfg.singleDefines('HAVE_STRONG_TYPEDEF'); if (cfg instanceof MsvcToolchainConfig) { cfg.compilerOptions.pchConfig = new MsvcToolchainConfig.PrecompiledHeadersConfig( diff --git a/reapi/extra/amxmodx/scripting/include/reapi.inc b/reapi/extra/amxmodx/scripting/include/reapi.inc index 4045103..ee544ba 100644 --- a/reapi/extra/amxmodx/scripting/include/reapi.inc +++ b/reapi/extra/amxmodx/scripting/include/reapi.inc @@ -167,7 +167,7 @@ native bool:FClassnameIs(const entityIndex, const className[]); native WeaponIdType:GetGrenadeType(const entityIndex); /* -* Sets the view mode on a client. +* Sets the view entity on a client. * This allows pfnSetView able to hooks. * * @param index Client index @@ -176,6 +176,14 @@ native WeaponIdType:GetGrenadeType(const entityIndex); */ native engset_view(const index, const const viewEntity); +/* +* Gets the return index of the current view entity on a client. +* +* @param index Client index +* +*/ +native get_viewent(const index); + /* * Check if the entity is valid. * diff --git a/reapi/include/com_client.h b/reapi/include/com_client.h new file mode 100644 index 0000000..c1c6cd8 --- /dev/null +++ b/reapi/include/com_client.h @@ -0,0 +1,129 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +* +*/ + +#pragma once + +#include "userid_rehlds.h" + +#include "com_net.h" +#include "com_progdefs.h" +#include "com_delta_packet.h" + +// Key + value + 2 x slash + NULL +const int MAX_INFO_STRING = 256; + +typedef struct client_frame_s +{ + double senttime; + float ping_time; + clientdata_t clientdata; + weapon_data_t weapondata[64]; + packet_entities_t entities; +} client_frame_t; + +struct client_t +{ + qboolean active; + qboolean spawned; + qboolean fully_connected; + qboolean connected; + qboolean uploading; + qboolean hasusrmsgs; + qboolean has_force_unmodified; + netchan_t netchan; + int chokecount; + int delta_sequence; + qboolean fakeclient; + qboolean proxy; + usercmd_t lastcmd; + double connecttime; + double cmdtime; + double ignorecmdtime; + float latency; + float packet_loss; + double localtime; + double nextping; + double svtimebase; + sizebuf_t datagram; + byte datagram_buf[MAX_DATAGRAM]; + double connection_started; + double next_messagetime; + double next_messageinterval; + qboolean send_message; + qboolean skip_message; + client_frame_t *frames; + event_state_t events; + edict_t *edict; + const edict_t *pViewEntity; + int userid; + USERID_t network_userid; + char userinfo[MAX_INFO_STRING]; + qboolean sendinfo; + float sendinfo_time; + char hashedcdkey[64]; + char name[32]; + int topcolor; + int bottomcolor; + int entityId; + resource_t resourcesonhand; + resource_t resourcesneeded; + FILE *upload; + qboolean uploaddoneregistering; + customization_t customdata; + int crcValue; + int lw; + int lc; + char physinfo[MAX_INFO_STRING]; + qboolean m_bLoopback; + uint32 m_VoiceStreams[2]; + double m_lastvoicetime; + int m_sendrescount; +}; + +// index [1-32] +inline client_t *clientOfEdict(const edict_t *pEdict) +{ + if (g_RehldsSvs) + { + return g_RehldsSvs->GetClient_t(indexOfEdict(pEdict) - 1); + } + + char *pszUserInfo = g_engfuncs.pfnGetInfoKeyBuffer(const_cast(pEdict)); + if (pszUserInfo) + { + return reinterpret_cast(reinterpret_cast(pszUserInfo) - offsetof(client_t, userinfo)); + } + + return nullptr; +} + +// index [1-32] +inline client_t *clientOfIndex(const int index) +{ + return clientOfEdict(edictByIndex(index)); +} diff --git a/reapi/include/com_delta_packet.h b/reapi/include/com_delta_packet.h new file mode 100644 index 0000000..c6b61fb --- /dev/null +++ b/reapi/include/com_delta_packet.h @@ -0,0 +1,39 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +* +*/ + +#pragma once + +#include "entity_state.h" + +typedef struct packet_entities_s +{ + int num_entities; + unsigned char flags[32]; + entity_state_t *entities; +} packet_entities_t; + diff --git a/reapi/include/com_net.h b/reapi/include/com_net.h new file mode 100644 index 0000000..8be6b5d --- /dev/null +++ b/reapi/include/com_net.h @@ -0,0 +1,237 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +* +*/ + +#pragma once + +#include "netadr.h" +#include "enums.h" +#include "common_rehlds.h" + +enum +{ + FLOW_OUTGOING = 0, + FLOW_INCOMING, + + MAX_FLOWS +}; + +// 0 == regular, 1 == file stream +enum +{ + FRAG_NORMAL_STREAM = 0, + FRAG_FILE_STREAM, + + MAX_STREAMS +}; + +// NETWORKING INFO + +// Max size of udp packet payload +const int MAX_UDP_PACKET = 4010; // 9 bytes SPLITHEADER + 4000 payload? + +// Max length of a reliable message +const int MAX_MSGLEN = 3990; // 10 reserved for fragheader? + +// Max length of unreliable message +const int MAX_DATAGRAM = 4000; + +// This is the packet payload without any header bytes (which are attached for actual sending) +const int NET_MAX_PAYLOAD = 65536; + +// This is the payload plus any header info (excluding UDP header) + +// Packet header is: +// 4 bytes of outgoing seq +// 4 bytes of incoming seq +// and for each stream +// { +// byte (on/off) +// int (fragment id) +// short (startpos) +// short (length) +// } +#define HEADER_BYTES (8 + MAX_STREAMS * 9) + +// Pad this to next higher 16 byte boundary +// This is the largest packet that can come in/out over the wire, before processing the header +// bytes will be stripped by the networking channel layer +//#define NET_MAX_MESSAGE PAD_NUMBER( ( MAX_MSGLEN + HEADER_BYTES ), 16 ) +// This is currently used value in the engine. TODO: define above gives 4016, check it why. +const int NET_MAX_MESSAGE = 4037; + +// Message data +typedef struct +{ + int size; // Size of message sent/received + double time; // Time that message was sent/received +} flowstats_t; + +const int MAX_LATENT = 32; + +typedef struct flow_s +{ + flowstats_t stats[MAX_LATENT]; // Data for last MAX_LATENT messages + int current; // Current message position + double nextcompute; // Time when we should recompute k/sec data + + // Average data + float kbytespersec; + float avgkbytespersec; +} flow_t; + +const int FRAGMENT_C2S_MIN_SIZE = 16; +const int FRAGMENT_S2C_MIN_SIZE = 256; +const int FRAGMENT_S2C_MAX_SIZE = 1024; + +const int CLIENT_FRAGMENT_SIZE_ONCONNECT = 128; +const int CUSTOMIZATION_MAX_SIZE = 20480; + +const int FRAGMENT_MAX_SIZE = 1024; + +// Client sends normal fragments only while connecting +#define MAX_NORMAL_FRAGMENTS (NET_MAX_PAYLOAD / CLIENT_FRAGMENT_SIZE_ONCONNECT) + +// While client is connecting it sending fragments with minimal size, also it transfers sprays with minimal fragments... +// But with sv_delayed_spray_upload it sends with cl_dlmax fragment size +#define MAX_FILE_FRAGMENTS (CUSTOMIZATION_MAX_SIZE / FRAGMENT_C2S_MIN_SIZE) + +const int UDP_HEADER_SIZE = 28; +const int MAX_RELIABLE_PAYLOAD = 1200; + +#define MAKE_FRAGID(id,count) ((( id & 0xffff) << 16) | (count & 0xffff)) +#define FRAG_GETID(fragid) ((fragid >> 16) & 0xffff) +#define FRAG_GETCOUNT(fragid) (fragid & 0xffff) + +// Generic fragment structure +typedef struct fragbuf_s +{ + fragbuf_s *next; // Next buffer in chain + int bufferid; // Id of this buffer + sizebuf_t frag_message; // Message buffer where raw data is stored + + byte frag_message_buf[FRAGMENT_MAX_SIZE]; // The actual data sits here + + qboolean isfile; // Is this a file buffer? + qboolean isbuffer; // Is this file buffer from memory ( custom decal, etc. ). + qboolean iscompressed; + + char filename[MAX_PATH]; // Name of the file to save out on remote host + int foffset; // Offset in file from which to read data + int size; // Size of data to read at that offset +} fragbuf_t; + +// Waiting list of fragbuf chains +typedef struct fragbufwaiting_s +{ + fragbufwaiting_s *next; // Next chain in waiting list + int fragbufcount; // Number of buffers in this chain + fragbuf_t *fragbufs; // The actual buffers +} fragbufwaiting_t; + +// Network Connection Channel +typedef struct netchan_s +{ + // NS_SERVER or NS_CLIENT, depending on channel. + netsrc_t sock; + + // Address this channel is talking to. + netadr_t remote_address; + + int player_slot; + // For timeouts. Time last message was received. + float last_received; + // Time when channel was connected. + float connect_time; + + // Bandwidth choke + // Bytes per second + double rate; + // If realtime > cleartime, free to send next packet + double cleartime; + + // Sequencing variables + // + // Increasing count of sequence numbers + int incoming_sequence; + // # of last outgoing message that has been ack'd. + int incoming_acknowledged; + // Toggles T/F as reliable messages are received. + int incoming_reliable_acknowledged; + // single bit, maintained local + int incoming_reliable_sequence; + // Message we are sending to remote + int outgoing_sequence; + // Whether the message contains reliable payload, single bit + int reliable_sequence; + // Outgoing sequence number of last send that had reliable data + int last_reliable_sequence; + + void *connection_status; + int (*pfnNetchan_Blocksize)(void *pData); + + // Staging and holding areas + sizebuf_t message; + byte message_buf[MAX_MSGLEN]; + + // Reliable message buffer. We keep adding to it until reliable is acknowledged. Then we clear it. + int reliable_length; + byte reliable_buf[MAX_MSGLEN]; + + // Waiting list of buffered fragments to go onto queue. Multiple outgoing buffers can be queued in succession. + fragbufwaiting_t *waitlist[MAX_STREAMS]; + + // Is reliable waiting buf a fragment? + int reliable_fragment[MAX_STREAMS]; + // Buffer id for each waiting fragment + unsigned int reliable_fragid[MAX_STREAMS]; + + // The current fragment being set + fragbuf_t *fragbufs[MAX_STREAMS]; + // The total number of fragments in this stream + int fragbufcount[MAX_STREAMS]; + + // Position in outgoing buffer where frag data starts + short int frag_startpos[MAX_STREAMS]; + // Length of frag data in the buffer + short int frag_length[MAX_STREAMS]; + + // Incoming fragments are stored here + fragbuf_t *incomingbufs[MAX_STREAMS]; + // Set to true when incoming data is ready + qboolean incomingready[MAX_STREAMS]; + + // Only referenced by the FRAG_FILE_STREAM component + // Name of file being downloaded + char incomingfilename[MAX_PATH]; + + void *tempbuffer; + int tempbuffersize; + + // Incoming and outgoing flow metrics + flow_t flow[MAX_FLOWS]; +} netchan_t; diff --git a/reapi/include/com_progdefs.h b/reapi/include/com_progdefs.h index e60ae86..c7acbbe 100644 --- a/reapi/include/com_progdefs.h +++ b/reapi/include/com_progdefs.h @@ -1,5 +1,30 @@ #pragma once +#include "event_flags.h" +#include "event_args.h" + +typedef struct event_info_s +{ + unsigned short index; // 0 implies not in use + short packet_index; // Use data from state info for entity in delta_packet. + // -1 implies separate info based on event parameter signature + + short entity_index; // The edict this event is associated with + float fire_time; // if non-zero, the time when the event should be fired ( fixed up on the client ) + event_args_t args; + +// CLIENT ONLY + int flags; // Reliable or not, etc. +} event_info_t; + +// 16 simultaneous events, max +const int MAX_EVENT_QUEUE = 64; + +typedef struct event_state_s +{ + struct event_info_s ei[MAX_EVENT_QUEUE]; +} event_state_t; + struct qstring_t { unsigned int str; }; struct rstring_t { const char *str; }; @@ -47,8 +72,8 @@ struct com_entvars vec3_t oldorigin; vec3_t velocity; vec3_t basevelocity; - vec3_t clbasevelocity; // Base velocity that was passed in to server physics so - // client can predict conveyors correctly. Server zeroes it, so we need to store here, too. + vec3_t clbasevelocity; // Base velocity that was passed in to server physics so + // client can predict conveyors correctly. Server zeroes it, so we need to store here, too. vec3_t movedir; vec3_t angles; // Model angles @@ -62,7 +87,7 @@ struct com_entvars float impacttime; float starttime; - int fixangle; // 0:nothing, 1:force view angles, 2:add avelocity + int fixangle; // 0:nothing, 1:force view angles, 2:add avelocity float idealpitch; float pitch_speed; float ideal_yaw; @@ -74,11 +99,11 @@ struct com_entvars qstring_t viewmodel; // player's viewmodel qstring_t weaponmodel; // what other players see - vec3_t absmin; // BB max translated to world coord - vec3_t absmax; // BB max translated to world coord - vec3_t mins; // local BB min - vec3_t maxs; // local BB max - vec3_t size; // maxs - mins + vec3_t absmin; // BB max translated to world coord + vec3_t absmax; // BB max translated to world coord + vec3_t mins; // local BB min + vec3_t maxs; // local BB max + vec3_t size; // maxs - mins float ltime; float nextthink; @@ -87,21 +112,21 @@ struct com_entvars int solid; int skin; - int body; // sub-model selection for studiomodels + int body; // sub-model selection for studiomodels int effects; - float gravity; // % of "normal" gravity - float friction; // inverse elasticity of MOVETYPE_BOUNCE + float gravity; // % of "normal" gravity + float friction; // inverse elasticity of MOVETYPE_BOUNCE int light_level; - int sequence; // animation sequence - int gaitsequence; // movement animation sequence for player (0 for none) + int sequence; // animation sequence + int gaitsequence; // movement animation sequence for player (0 for none) float frame; // % playback position in animation sequences (0..255) - float animtime; // world time when frame was set + float animtime; // world time when frame was set float framerate; // animation playback rate (-8x to 8x) - byte controller[4]; // bone controller setting (0..255) - byte blending[2]; // blending amount between sub-sequences (0..255) + byte controller[4]; // bone controller setting (0..255) + byte blending[2]; // blending amount between sub-sequences (0..255) float scale; // sprite rendering scale (0..255) @@ -112,11 +137,11 @@ struct com_entvars float health; float frags; - int weapons; // bit mask for available weapons + int weapons; // bit mask for available weapons float takedamage; int deadflag; - vec3_t view_ofs; // eye position + vec3_t view_ofs; // eye position int button; int impulse; @@ -131,7 +156,7 @@ struct com_entvars int spawnflags; int flags; - int colormap; // lowbyte topcolor, highbyte bottomcolor + int colormap; // lowbyte topcolor, highbyte bottomcolor int team; float max_health; @@ -208,21 +233,21 @@ struct com_playermove { int player_index; // So we don't try to run the PM_CheckStuck nudging too quickly. qboolean server; // For debugging, are we running physics code on server side? - qboolean multiplayer; // 1 == multiplayer server - float time; // realtime on host, for reckoning duck timing + qboolean multiplayer; // 1 == multiplayer server + float time; // realtime on host, for reckoning duck timing float frametime; // Duration of this frame - vec3_t forward, right, up; // Vectors for angles + vec3_t forward, right, up; // Vectors for angles vec3_t origin; // Movement origin. vec3_t angles; // Movement view angles. vec3_t oldangles; // Angles before movement view angles were looked at. vec3_t velocity; // Current movement direction. vec3_t movedir; // For waterjumping, a forced forward velocity so we can fly over lip of ledge. - vec3_t basevelocity; // Velocity of the conveyor we are standing, e.g. + vec3_t basevelocity; // Velocity of the conveyor we are standing, e.g. vec3_t view_ofs; // For ducking/dead // Our eye position. float flDuckTime; // Time we started duck qboolean bInDuck; // In process of ducking or ducked already? - int flTimeStepSound; // For walking/falling + int flTimeStepSound; // For walking/falling // Next time we can play a step sound int iStepLeft; float flFallVelocity; @@ -230,12 +255,12 @@ struct com_playermove float flSwimTime; float flNextPrimaryAttack; int effects; // MUZZLE FLASH, e.g. - int flags; // FL_ONGROUND, FL_DUCKING, etc. + int flags; // FL_ONGROUND, FL_DUCKING, etc. int usehull; // 0 = regular player hull, 1 = ducked player hull, 2 = point hull float gravity; // Our current gravity and friction. float friction; int oldbuttons; // Buttons last usercmd - float waterjumptime; // Amount of time left in jumping out of water cycle. + float waterjumptime; // Amount of time left in jumping out of water cycle. qboolean dead; // Are we a dead player? int deadflag; int spectator; // Should we use spectator physics model? @@ -260,17 +285,17 @@ struct com_playermove vec3_t vuser2; vec3_t vuser3; vec3_t vuser4; - int numphysent; // world state + int numphysent; // world state // Number of entities to clip against. physent_t physents[MAX_PHYSENTS]; - int nummoveent; // Number of momvement entities (ladders) - physent_t moveents[MAX_MOVEENTS]; // just a list of ladders - int numvisent; // All things being rendered, for tracing against things you don't actually collide with + int nummoveent; // Number of momvement entities (ladders) + physent_t moveents[MAX_MOVEENTS]; // just a list of ladders + int numvisent; // All things being rendered, for tracing against things you don't actually collide with physent_t visents[MAX_PHYSENTS]; - usercmd_t cmd; // input to run through physics. - int numtouch; // Trace results for objects we collided with. + usercmd_t cmd; // input to run through physics. + int numtouch; // Trace results for objects we collided with. pmtrace_t touchindex[MAX_PHYSENTS]; - char physinfo[MAX_PHYSINFO_STRING]; // Physics info string + char physinfo[MAX_PHYSINFO_STRING]; // Physics info string struct movevars_s *movevars; Vector player_mins[4]; Vector player_maxs[4]; @@ -302,21 +327,8 @@ struct com_playermove void(*PM_PlaySound)(int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch); const char *(*PM_TraceTexture)(int ground, float *vstart, float *vend); void(*PM_PlaybackEventFull)(int flags, int clientindex, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2); -}; -class CWeaponBox_COM: public CBaseEntity { -public: - virtual void Spawn() = 0; - virtual void Precache() = 0; - virtual void KeyValue(KeyValueData *pkvd) = 0; - virtual int Save(CSave &save) = 0; - virtual int Restore(CRestore &restore) = 0; - virtual void SetObjectCollisionBox() = 0; - virtual void Touch(CBaseEntity *pOther) = 0; -public: - CBasePlayerItem *m_rgpPlayerItems[MAX_ITEM_TYPES]; - qstring_t m_rgiszAmmo[MAX_AMMO_SLOTS]; - int m_rgAmmo[MAX_AMMO_SLOTS]; - int m_cAmmoTypes; - bool m_bIsBomb; + pmtrace_t (*PM_PlayerTraceEx)(float *start, float *end, int traceFlags, int (*pfnIgnore)(physent_t *pe)); + int (*PM_TestPlayerPositionEx)(float *pos, pmtrace_t *ptrace, int (*pfnIgnore)(physent_t *pe)); + struct pmtrace_s *(*PM_TraceLineEx)(float *start, float *end, int flags, int usehulll, int (*pfnIgnore)(physent_t *pe)); }; diff --git a/reapi/include/cssdk/common/const.h b/reapi/include/cssdk/common/const.h index aa081dc..3ad5c53 100644 --- a/reapi/include/cssdk/common/const.h +++ b/reapi/include/cssdk/common/const.h @@ -741,7 +741,12 @@ enum typedef unsigned int func_t; -typedef unsigned int string_t; + +#ifdef HAVE_STRONG_TYPEDEF +enum class string_t: unsigned int {}; +#else +typedef unsigned int string_t; +#endif typedef unsigned char byte; typedef unsigned short word; diff --git a/reapi/include/cssdk/dlls/extdll.h b/reapi/include/cssdk/dlls/extdll.h index e81fcd1..7e956cc 100644 --- a/reapi/include/cssdk/dlls/extdll.h +++ b/reapi/include/cssdk/dlls/extdll.h @@ -62,7 +62,6 @@ // Header file containing definition of globalvars_t and entvars_t typedef int EOFFSET; // More explicit than "int" typedef unsigned int func_t; -typedef unsigned int string_t; // from engine's pr_comp.h; typedef float vec_t; // needed before including progdefs.h // Vector class diff --git a/reapi/include/cssdk/dlls/util.h b/reapi/include/cssdk/dlls/util.h index 8e36d48..ec035a7 100644 --- a/reapi/include/cssdk/dlls/util.h +++ b/reapi/include/cssdk/dlls/util.h @@ -29,8 +29,8 @@ #include "enginecallback.h" -#define eoNullEntity 0 // Testing the three types of "entity" for nullity -#define iStringNull 0 // Testing strings for nullity +#define eoNullEntity 0 // Testing the three types of "entity" for nullity +#define iStringNull (string_t)0 // Testing strings for nullity #define cchMapNameMost 32 @@ -146,7 +146,8 @@ inline void MESSAGE_BEGIN(int msg_dest, int msg_type, const float *pOrigin, entv inline BOOL FNullEnt(EOFFSET eoffset) { return (eoffset == 0); } inline BOOL FNullEnt(entvars_t *pev) { return (pev == NULL || FNullEnt(OFFSET(pev))); } inline BOOL FNullEnt(const edict_t *pent) { return (pent == NULL || FNullEnt(OFFSET(pent))); } -inline BOOL FStringNull(int iString) { return (iString == iStringNull); } +inline BOOL FStringNull(int iString) { return ((string_t)iString == iStringNull); } +inline BOOL FStringNull(string_t iString) { return (iString == iStringNull); } inline BOOL FStrEq(const char *sz1, const char *sz2) { return (strcmp(sz1, sz2) == 0); } inline BOOL FClassnameIs(entvars_t *pev, const char *szClassname) { return FStrEq(STRING(pev->classname), szClassname); } inline BOOL FClassnameIs(edict_t *pent, const char *szClassname) { return FStrEq(STRING(VARS(pent)->classname), szClassname); } diff --git a/reapi/include/cssdk/dlls/weapons.h b/reapi/include/cssdk/dlls/weapons.h index c4da501..3678a6c 100644 --- a/reapi/include/cssdk/dlls/weapons.h +++ b/reapi/include/cssdk/dlls/weapons.h @@ -311,7 +311,7 @@ public: virtual void Touch(CBaseEntity *pOther) = 0; public: CBasePlayerItem *m_rgpPlayerItems[MAX_ITEM_TYPES]; - int m_rgiszAmmo[MAX_AMMO_SLOTS]; + string_t m_rgiszAmmo[MAX_AMMO_SLOTS]; int m_rgAmmo[MAX_AMMO_SLOTS]; int m_cAmmoTypes; bool m_bIsBomb; diff --git a/reapi/include/cssdk/engine/eiface.h b/reapi/include/cssdk/engine/eiface.h index d2f072d..3120d39 100644 --- a/reapi/include/cssdk/engine/eiface.h +++ b/reapi/include/cssdk/engine/eiface.h @@ -1,9 +1,9 @@ /*** * * Copyright (c) 1999, Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * All Rights Reserved. * * Use, distribution, and modification of this source code and/or resulting @@ -86,7 +86,7 @@ struct TraceResult }; // CD audio status -typedef struct +typedef struct { int fPlaying;// is sound playing right now? int fWasPlaying;// if not, CD is paused if WasPlaying is true. @@ -128,7 +128,7 @@ typedef struct enginefuncs_s void (*pfnAngleVectors) (const float *rgflVector, float *forward, float *right, float *up); edict_t* (*pfnCreateEntity) (void); void (*pfnRemoveEntity) (edict_t* e); - edict_t* (*pfnCreateNamedEntity) (int className); + edict_t* (*pfnCreateNamedEntity) (string_t className); void (*pfnMakeStatic) (edict_t *ent); int (*pfnEntIsOnFloor) (edict_t *e); int (*pfnDropToFloor) (edict_t* e); @@ -172,7 +172,7 @@ typedef struct enginefuncs_s void* (*pfnPvEntPrivateData) (edict_t *pEdict); void (*pfnFreeEntPrivateData) (edict_t *pEdict); const char* (*pfnSzFromIndex) (int iString); - int (*pfnAllocString) (const char *szValue); + string_t (*pfnAllocString) (const char *szValue); struct entvars_s* (*pfnGetVarsOfEnt) (edict_t *pEdict); edict_t* (*pfnPEntityOfEntOffset) (int iEntOffset); int (*pfnEntOffsetOfPEntity) (const edict_t *pEdict); @@ -187,8 +187,8 @@ typedef struct enginefuncs_s const char *(*pfnNameForFunction) ( uint32 function ); void (*pfnClientPrintf) ( edict_t* pEdict, PRINT_TYPE ptype, const char *szMsg ); // JOHN: engine callbacks so game DLL can print messages to individual clients void (*pfnServerPrint) ( const char *szMsg ); - const char *(*pfnCmd_Args) ( void ); // these 3 added - const char *(*pfnCmd_Argv) ( int argc ); // so game DLL can easily + const char *(*pfnCmd_Args) ( void ); // these 3 added + const char *(*pfnCmd_Argv) ( int argc ); // so game DLL can easily int (*pfnCmd_Argc) ( void ); // access client 'cmd' strings void (*pfnGetAttachment) (const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles ); void (*pfnCRC32_Init) (CRC32_t *pulCRC); @@ -269,7 +269,7 @@ typedef struct enginefuncs_s // PSV: Added for CZ training map // const char *(*pfnKeyNameForBinding) ( const char* pBinding ); - + sequenceEntry_s* (*pfnSequenceGet) ( const char* fileName, const char* entryName ); sentenceEntry_s* (*pfnSequencePickSentence) ( const char* groupName, int pickMethod, int *picked ); @@ -328,7 +328,7 @@ typedef struct } LEVELLIST; #define MAX_LEVEL_CONNECTIONS 16 // These are encoded in the lower 16bits of ENTITYTABLE->flags -typedef struct +typedef struct { int id; // Ordinal ID of this entity (used for entity <--> pointer conversions) edict_t *pent; // Pointer to the in-game entity @@ -348,7 +348,7 @@ typedef struct typedef struct saverestore_s SAVERESTOREDATA; #ifdef _WIN32 -typedef +typedef #endif struct saverestore_s { @@ -372,9 +372,9 @@ struct saverestore_s float time; char szCurrentMapName[32]; // To check global entities -} +} #ifdef _WIN32 -SAVERESTOREDATA +SAVERESTOREDATA #endif ; @@ -416,7 +416,7 @@ typedef enum _fieldtypes #define FTYPEDESC_GLOBAL 0x0001 // This field is masked for global entity save/restore -typedef struct +typedef struct { FIELDTYPE fieldType; char *fieldName; @@ -429,10 +429,10 @@ typedef struct #define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0])) #endif -typedef struct +typedef struct { // Initialize/shutdown the game (one-time call after loading of game .dll ) - void (*pfnGameInit) ( void ); + void (*pfnGameInit) ( void ); int (*pfnSpawn) ( edict_t *pent ); void (*pfnThink) ( edict_t *pent ); void (*pfnUse) ( edict_t *pentUsed, edict_t *pentOther ); @@ -451,7 +451,7 @@ typedef struct void (*pfnResetGlobalState) ( void ); qboolean (*pfnClientConnect) ( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); - + void (*pfnClientDisconnect) ( edict_t *pEntity ); void (*pfnClientKill) ( edict_t *pEntity ); void (*pfnClientPutInServer) ( edict_t *pEntity ); @@ -469,10 +469,10 @@ typedef struct void (*pfnParmsChangeLevel) ( void ); // Returns string describing current .dll. E.g., TeamFotrress 2, Half-Life - const char *(*pfnGetGameDescription)( void ); + const char *(*pfnGetGameDescription)( void ); // Notify dll about a player customization. - void (*pfnPlayerCustomization) ( edict_t *pEntity, customization_t *pCustom ); + void (*pfnPlayerCustomization) ( edict_t *pEntity, customization_t *pCustom ); // Spectator funcs void (*pfnSpectatorConnect) ( edict_t *pEntity ); @@ -523,7 +523,7 @@ extern DLL_FUNCTIONS gEntityInterface; typedef struct { - // Called right before the object's memory is freed. + // Called right before the object's memory is freed. // Calls its destructor. void (*pfnOnFreeEntPrivateData)(edict_t *pEnt); void (*pfnGameShutdown)(void); diff --git a/reapi/include/cssdk/engine/maintypes.h b/reapi/include/cssdk/engine/maintypes.h index 40ae20c..5c7c3ad 100644 --- a/reapi/include/cssdk/engine/maintypes.h +++ b/reapi/include/cssdk/engine/maintypes.h @@ -46,7 +46,4 @@ #define BIT(n) (1<<(n)) - -typedef unsigned int string_t; // from engine's pr_comp.h; - #endif // MAINTYPES_H diff --git a/reapi/include/typedef_strong.h b/reapi/include/typedef_strong.h new file mode 100644 index 0000000..28f51a1 --- /dev/null +++ b/reapi/include/typedef_strong.h @@ -0,0 +1,35 @@ +/* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +* +*/ + +#pragma once + +class string_t +{ +public: + using unsigned int; +}; diff --git a/reapi/msvc/reapi.vcxproj b/reapi/msvc/reapi.vcxproj index 8c7f3a4..5d07f4b 100644 --- a/reapi/msvc/reapi.vcxproj +++ b/reapi/msvc/reapi.vcxproj @@ -11,6 +11,9 @@ + + + @@ -329,7 +332,7 @@ Use Level3 Disabled - WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + WIN32;HAVE_STRONG_TYPEDEF;_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreadedDebug precompiled.h @@ -379,7 +382,7 @@ Full true true - WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + WIN32;HAVE_STRONG_TYPEDEF;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) $(ProjectDir)\..\src;$(ProjectDir)\..\src\mods;$(ProjectDir)\..\src\natives;$(ProjectDir)\..\version;$(ProjectDir)\..\include;$(ProjectDir)\..\include\metamod;$(ProjectDir)\..\include\cssdk\common;$(ProjectDir)\..\include\cssdk\dlls;$(ProjectDir)\..\include\cssdk\engine;$(ProjectDir)\..\include\cssdk\game_shared;$(ProjectDir)\..\include\cssdk\pm_shared;$(ProjectDir)\..\include\cssdk\public;%(AdditionalIncludeDirectories) diff --git a/reapi/msvc/reapi.vcxproj.filters b/reapi/msvc/reapi.vcxproj.filters index 6ddb4f8..ea57442 100644 --- a/reapi/msvc/reapi.vcxproj.filters +++ b/reapi/msvc/reapi.vcxproj.filters @@ -681,6 +681,15 @@ src\mods + + include + + + include + + + include + diff --git a/reapi/src/member_list.cpp b/reapi/src/member_list.cpp index 4d2a0fd..2d1ca86 100644 --- a/reapi/src/member_list.cpp +++ b/reapi/src/member_list.cpp @@ -15,7 +15,7 @@ #define CLASS_MEMBERS(cx, mx, postf, pref) ((!(postf & (MAX_REGION_RANGE - 1)) ? regmember::current_cell = 1, true : false) || (postf & (MAX_REGION_RANGE - 1)) == regmember::current_cell++) ? regmember([](member_t* ptr){ decltypefx(cx, pref, ., mx) f = {};ptr->size = getTypeSize(f);ptr->max_size = sizeof(f);ptr->offset = offsetof(##cx, ##pref##mx);ptr->type = getMemberType(f);ptr->name = #postf;}) : regmember(#pref#mx) #define GM_MEMBERS(mx) CLASS_MEMBERS(CHalfLifeMultiplay, mx, mx,) -#define GM_VOICE_MEMBERS(mx) CLASS_MEMBERS(CHalfLifeMultiplay, mx, mx, m_VoiceGameMgr.) +#define GM_VOICE_MEMBERS(mx) CLASS_MEMBERS(CHalfLifeMultiplay, mx, mx, m_VoiceGameMgr.) #define BASE_MEMBERS(mx) CLASS_MEMBERS(CBaseEntity, mx, mx,) #define ANIM_MEMBERS(mx) CLASS_MEMBERS(CBaseAnimating, mx, mx,) #define MONST_MEMBERS(mx) CLASS_MEMBERS(CBaseMonster, mx, mx,) @@ -26,54 +26,56 @@ #define UCMD_MEMBERS(mx) CLASS_MEMBERS(usercmd_s, mx, ucmd_##mx,) #define PMTRACE_MEMBERS(mx) CLASS_MEMBERS(pmtrace_s, mx, pmt_##mx,) #define CSPL_MEMBERS(mx) CLASS_MEMBERS(CCSPlayer, mx, mx,) -#define BASEITEM_MEMBERS(mx) CLASS_MEMBERS(CBasePlayerItem, mx, mx,) +#define BASEITEM_MEMBERS(mx) CLASS_MEMBERS(CBasePlayerItem, mx, mx,) #define BASEWPN_MEMBERS(mx) CLASS_MEMBERS(CBasePlayerWeapon, mx, m_Weapon_##mx, m_) -#define WPNBOX_MEMBERS(mx) CLASS_MEMBERS(CWeaponBox_COM, mx, m_WeaponBox_##mx, m_) +#define WPNBOX_MEMBERS(mx) CLASS_MEMBERS(CWeaponBox, mx, m_WeaponBox_##mx, m_) #define ARMOURY_MEMBERS(mx) CLASS_MEMBERS(CArmoury, mx, m_Armoury_##mx, m_) -inline MType getMemberType(float*) { return MEMBER_FLOAT; } -inline MType getMemberType(float) { return MEMBER_FLOAT; } +inline MType getMemberType(float*) { return MEMBER_FLOAT; } +inline MType getMemberType(float) { return MEMBER_FLOAT; } -inline MType getMemberType(double) { return MEMBER_DOUBLE; } +inline MType getMemberType(double) { return MEMBER_DOUBLE; } inline MType getMemberType(CBasePlayer**) { return MEMBER_CLASSPTR; } inline MType getMemberType(CBasePlayer*) { return MEMBER_CLASSPTR; } -inline MType getMemberType(CBasePlayerItem**) { return MEMBER_CLASSPTR; } -inline MType getMemberType(CBasePlayerItem*) { return MEMBER_CLASSPTR; } +inline MType getMemberType(CBasePlayerItem**) { return MEMBER_CLASSPTR; } +inline MType getMemberType(CBasePlayerItem*) { return MEMBER_CLASSPTR; } inline MType getMemberType(CBaseEntity*) { return MEMBER_CLASSPTR; } -inline MType getMemberType(EHANDLE) { return MEMBER_EHANDLE; } +inline MType getMemberType(EHANDLE) { return MEMBER_EHANDLE; } inline MType getMemberType(entvars_t*) { return MEMBER_EVARS; } inline MType getMemberType(edict_t*) { return MEMBER_EDICT; } -inline MType getMemberType(Vector*) { return MEMBER_VECTOR; } -inline MType getMemberType(Vector) { return MEMBER_VECTOR; } +inline MType getMemberType(Vector*) { return MEMBER_VECTOR; } +inline MType getMemberType(Vector) { return MEMBER_VECTOR; } -inline MType getMemberType(char*) { return MEMBER_STRING; } +inline MType getMemberType(char*) { return MEMBER_STRING; } +inline MType getMemberType(string_t) { return MEMBER_QSTRING; } +inline MType getMemberType(string_t*) { return MEMBER_QSTRING; } inline MType getMemberType(qstring_t) { return MEMBER_QSTRING; } inline MType getMemberType(qstring_t*) { return MEMBER_QSTRING; } -inline MType getMemberType(char) { return MEMBER_BYTE; } -inline MType getMemberType(byte) { return MEMBER_BYTE; } -inline MType getMemberType(byte*) { return MEMBER_BYTE; } +inline MType getMemberType(char) { return MEMBER_BYTE; } +inline MType getMemberType(byte) { return MEMBER_BYTE; } +inline MType getMemberType(byte*) { return MEMBER_BYTE; } -inline MType getMemberType(int*) { return MEMBER_INTEGER; } -inline MType getMemberType(int) { return MEMBER_INTEGER; } +inline MType getMemberType(int*) { return MEMBER_INTEGER; } +inline MType getMemberType(int) { return MEMBER_INTEGER; } inline MType getMemberType(unsigned) { return MEMBER_INTEGER; } inline MType getMemberType(TeamName) { return MEMBER_INTEGER; } inline MType getMemberType(JoinState) { return MEMBER_INTEGER; } inline MType getMemberType(ModelName) { return MEMBER_INTEGER; } -inline MType getMemberType(_Menu) { return MEMBER_INTEGER; } +inline MType getMemberType(_Menu) { return MEMBER_INTEGER; } inline MType getMemberType(MusicState) { return MEMBER_INTEGER; } inline MType getMemberType(Activity) { return MEMBER_INTEGER; } inline MType getMemberType(MONSTERSTATE) { return MEMBER_INTEGER; } inline MType getMemberType(ArmorType) { return MEMBER_INTEGER; } inline MType getMemberType(ArmouryItemPack) { return MEMBER_INTEGER; } -inline MType getMemberType(short) { return MEMBER_SHORT; } +inline MType getMemberType(short) { return MEMBER_SHORT; } inline MType getMemberType(unsigned short) { return MEMBER_SHORT; } -inline MType getMemberType(bool) { return MEMBER_BOOL; } +inline MType getMemberType(bool) { return MEMBER_BOOL; } inline MType getMemberType(CUnifiedSignals) { return MEMBER_SIGNALS; } inline MType getMemberType(RebuyStruct) { return MEBMER_REBUYSTRUCT; } diff --git a/reapi/src/natives/natives_common.cpp b/reapi/src/natives/natives_common.cpp index 2bb4fd1..200f2b4 100644 --- a/reapi/src/natives/natives_common.cpp +++ b/reapi/src/natives/natives_common.cpp @@ -67,7 +67,7 @@ cell AMX_NATIVE_CALL amx_GetGrenadeType(AMX *amx, cell *params) } /* -* Sets the view mode on a client. +* Sets the view entity on a client. * This allows pfnSetView able to hooks. * * @param index Client index @@ -88,11 +88,35 @@ cell AMX_NATIVE_CALL amx_engset_view(AMX *amx, cell *params) return TRUE; } +/* +* Gets the return index of the current view entity on a client. +* +* @param index Client index +* +* native get_viewent(const index); +*/ +cell AMX_NATIVE_CALL amx_get_viewent(AMX *amx, cell *params) +{ + enum args_e { arg_count, arg_index }; + + CHECK_ISPLAYER(arg_index); + + client_t *pClient = clientOfIndex(params[arg_index]); + if (unlikely(pClient == nullptr || !(pClient->active | pClient->spawned | pClient->connected))) + { + MF_LogError(amx, AMX_ERR_NATIVE, "%s: player %i is not connected", __FUNCTION__, params[arg_index]); + return FALSE; + } + + return indexOfEdictAmx(pClient->pViewEntity); +} + AMX_NATIVE_INFO Natives_Common[] = { { "FClassnameIs", amx_FClassnameIs }, { "GetGrenadeType", amx_GetGrenadeType }, { "engset_view", amx_engset_view }, + { "get_viewent", amx_get_viewent }, { nullptr, nullptr } }; diff --git a/reapi/src/natives/natives_members.cpp b/reapi/src/natives/natives_members.cpp index 39d82df..260ac7e 100644 --- a/reapi/src/natives/natives_members.cpp +++ b/reapi/src/natives/natives_members.cpp @@ -453,7 +453,7 @@ void RegisterNatives_Members() { if (!api_cfg.hasReGameDLL()) fillNatives(ReGameVars_Natives, [](AMX *amx, cell *params) -> cell { MF_LogError(amx, AMX_ERR_NATIVE, "%s: isn't available", "ReGameDll"); return FALSE; }); - + g_amxxapi.AddNatives(ReGameVars_Natives); g_amxxapi.AddNatives(EngineVars_Natives); } @@ -512,7 +512,7 @@ BOOL set_member(void* pdata, const member_t *member, cell* value, size_t element case MEMBER_QSTRING: { char *source = getAmxString(value); - string_t newstr = (source && source[0] != '\0') ? ALLOC_STRING(source) : 0; + string_t newstr = (source && source[0] != '\0') ? ALLOC_STRING(source) : iStringNull; set_member(pdata, member->offset, newstr, element); return TRUE; } diff --git a/reapi/src/precompiled.h b/reapi/src/precompiled.h index 6990dba..0a7ca81 100644 --- a/reapi/src/precompiled.h +++ b/reapi/src/precompiled.h @@ -52,6 +52,8 @@ // AmxModX API #include "amxxmodule.h" +#include "com_client.h" + // reapi main #include "main.h" #include "reapi_utils.h" diff --git a/reapi/src/type_conversion.h b/reapi/src/type_conversion.h index 7d9eb87..b395d67 100644 --- a/reapi/src/type_conversion.h +++ b/reapi/src/type_conversion.h @@ -6,18 +6,18 @@ extern edict_t* g_pEdicts; -inline size_t indexOfEdict(edict_t* ed) +inline size_t indexOfEdict(const edict_t* ed) { return ed - g_pEdicts; } -inline size_t indexOfEdict(entvars_t* pev) +inline size_t indexOfEdict(const entvars_t* pev) { return indexOfEdict(pev->pContainingEntity); } // safe to nullptr -inline size_t indexOfEdictAmx(entvars_t* pev) +inline size_t indexOfEdictAmx(const entvars_t* pev) { size_t index = AMX_NULLENT; if (likely(pev != nullptr)) @@ -25,14 +25,22 @@ inline size_t indexOfEdictAmx(entvars_t* pev) return index; } +inline size_t indexOfEdictAmx(const edict_t *pEdict) +{ + size_t index = AMX_NULLENT; + if (likely(pEdict != nullptr)) + index = indexOfEdict(pEdict); + return index; +} + // fast -inline edict_t* edictByIndex(int index) +inline edict_t* edictByIndex(const int index) { return g_pEdicts + index; } // safe to index -1 -inline edict_t* edictByIndexAmx(int index) +inline edict_t* edictByIndexAmx(const int index) { auto ed = g_pEdicts + index; if (unlikely(index < 0)) // == AMX_NULLENT @@ -41,7 +49,7 @@ inline edict_t* edictByIndexAmx(int index) } template -inline T* getPrivate(int index) +inline T* getPrivate(const int index) { T* pdata = nullptr; if (likely(index >= 0)) // != AMX_NULLENT @@ -50,7 +58,7 @@ inline T* getPrivate(int index) } template -inline T* getPrivate(edict_t *pEdict) +inline T* getPrivate(const edict_t *pEdict) { T* pdata = nullptr; if (likely(pEdict != nullptr)) @@ -58,7 +66,7 @@ inline T* getPrivate(edict_t *pEdict) return pdata; } -inline entvars_t* PEV(int index) +inline entvars_t* PEV(const int index) { entvars_t* pvars = nullptr; if (likely(index >= 0)) // != AMX_NULLENT @@ -67,7 +75,7 @@ inline entvars_t* PEV(int index) } template -inline size_t indexOfPDataAmx(T* pdata) +inline size_t indexOfPDataAmx(const T* pdata) { size_t index = AMX_NULLENT; if (likely(pdata != nullptr))