2014-08-04 14:05:55 +04:00
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Engine Module
//
2004-05-26 12:44:15 +04:00
# include "engine.h"
2004-05-26 09:15:40 +04:00
2004-08-11 16:17:39 +04:00
BOOL CheckForPublic ( const char * publicname ) ;
2004-08-12 08:14:47 +04:00
edict_t * g_player_edicts [ 33 ] ;
2004-05-26 09:15:40 +04:00
int AmxStringToEngine ( AMX * amx , cell param , int & len )
{
char * szString = MF_GetAmxString ( amx , param , 0 , & len ) ;
2004-07-06 20:48:20 +04:00
return ALLOC_STRING ( szString ) ;
2004-05-26 09:15:40 +04:00
}
2004-09-09 01:43:50 +04:00
void ClearHooks ( )
2004-08-31 06:05:27 +04:00
{
2006-05-11 11:49:45 +04:00
size_t i ;
2005-07-14 08:50:46 +04:00
2014-08-09 22:30:31 +04:00
for ( i = 0 ; i < Touches . length ( ) ; i + + )
2004-08-31 06:05:27 +04:00
delete Touches [ i ] ;
2014-08-09 22:30:31 +04:00
for ( i = 0 ; i < Impulses . length ( ) ; i + + )
2004-08-31 06:05:27 +04:00
delete Impulses [ i ] ;
2014-08-09 22:30:31 +04:00
for ( i = 0 ; i < Thinks . length ( ) ; i + + )
2004-08-31 06:05:27 +04:00
delete Thinks [ i ] ;
2005-07-14 08:50:46 +04:00
2004-08-31 06:05:27 +04:00
Touches . clear ( ) ;
Impulses . clear ( ) ;
Thinks . clear ( ) ;
}
2004-05-26 09:15:40 +04:00
void OnAmxxAttach ( )
{
pfnTouchForward = 0 ;
pfnThinkForward = 0 ;
PlayerPreThinkForward = 0 ;
PlayerPostThinkForward = 0 ;
ClientKillForward = 0 ;
2013-07-03 02:19:12 +04:00
ClientImpulseForward = 0 ;
2013-07-03 03:00:52 +04:00
CmdStartForward = 0 ;
2004-05-26 09:15:40 +04:00
StartFrameForward = 0 ;
MF_AddNatives ( ent_Natives ) ;
2006-09-01 07:29:27 +04:00
MF_AddNewNatives ( ent_NewNatives ) ;
2004-05-26 09:15:40 +04:00
MF_AddNatives ( engine_Natives ) ;
2006-09-01 07:29:27 +04:00
MF_AddNewNatives ( engine_NewNatives ) ;
2004-05-26 09:15:40 +04:00
MF_AddNatives ( global_Natives ) ;
memset ( glinfo . szLastLights , 0x0 , 128 ) ;
memset ( glinfo . szRealLights , 0x0 , 128 ) ;
glinfo . bCheckLights = false ;
}
void OnPluginsLoaded ( )
{
2004-08-11 16:17:39 +04:00
g_CameraCount = 0 ;
pfnThinkForward = MF_RegisterForward ( " pfn_think " , ET_STOP , FP_CELL , FP_DONE ) ; // done
PlayerPreThinkForward = MF_RegisterForward ( " client_PreThink " , ET_STOP , FP_CELL , FP_DONE ) ; // done
PlayerPostThinkForward = MF_RegisterForward ( " client_PostThink " , ET_STOP , FP_CELL , FP_DONE ) ; // done
ClientKillForward = MF_RegisterForward ( " client_kill " , ET_STOP , FP_CELL , FP_DONE ) ; // done
2013-07-03 02:19:12 +04:00
ClientImpulseForward = MF_RegisterForward ( " client_impulse " , ET_STOP , FP_CELL , FP_CELL , FP_DONE ) ; // done
2013-07-03 03:00:52 +04:00
CmdStartForward = MF_RegisterForward ( " client_cmdStart " , ET_STOP , FP_CELL , FP_DONE ) ; // done
2004-08-11 16:17:39 +04:00
StartFrameForward = MF_RegisterForward ( " server_frame " , ET_IGNORE , FP_DONE ) ; // done
DispatchKeyForward = MF_RegisterForward ( " pfn_keyvalue " , ET_STOP , FP_CELL , FP_DONE ) ; // done
PlaybackForward = MF_RegisterForward ( " pfn_playbackevent " , ET_STOP , FP_CELL , FP_CELL , FP_CELL , FP_FLOAT , FP_ARRAY , FP_ARRAY , FP_FLOAT , FP_FLOAT , FP_CELL , FP_CELL , FP_CELL , FP_CELL , FP_DONE ) ; // done
2005-09-06 02:05:23 +04:00
SpawnForward = MF_RegisterForward ( " pfn_spawn " , ET_STOP , FP_CELL , FP_DONE ) ; // done
2004-08-11 16:17:39 +04:00
pfnTouchForward = MF_RegisterForward ( " pfn_touch " , ET_STOP , FP_CELL , FP_CELL , FP_DONE ) ; // done
VexdTouchForward = MF_RegisterForward ( " vexd_pfntouch " , ET_IGNORE , FP_CELL , FP_CELL , FP_DONE ) ; // done
VexdServerForward = MF_RegisterForward ( " ServerFrame " , ET_IGNORE , FP_DONE ) ; // done
// Reset all standard engine callbacks
// These will be reset through native calls, if need be
g_pFunctionTable - > pfnAddToFullPack = NULL ;
g_pFunctionTable - > pfnKeyValue = NULL ;
if ( CheckForPublic ( " pfn_keyvalue " ) )
g_pFunctionTable - > pfnKeyValue = KeyValue ;
g_pengfuncsTable - > pfnPlaybackEvent = NULL ; // "pfn_playbackevent"
if ( CheckForPublic ( " pfn_playbackevent " ) )
g_pengfuncsTable - > pfnPlaybackEvent = PlaybackEvent ;
g_pFunctionTable - > pfnPlayerPreThink = NULL ; // "client_PreThink"
if ( CheckForPublic ( " client_PreThink " ) )
g_pFunctionTable - > pfnPlayerPreThink = PlayerPreThink ;
2004-08-12 08:21:03 +04:00
g_pFunctionTable_Post - > pfnPlayerPostThink = NULL ; // "client_PostThink"
2004-08-11 16:17:39 +04:00
if ( CheckForPublic ( " client_PostThink " ) )
g_pFunctionTable - > pfnPlayerPostThink = PlayerPostThink_Post ;
g_pFunctionTable - > pfnSpawn = NULL ; // "pfn_spawn"
2004-10-27 23:06:43 +04:00
//if (CheckForPublic("pfn_spawn")) // JGHG: I commented this if out because we always need the Spawn to precache the rocket mdl used with SetView native
g_pFunctionTable - > pfnSpawn = Spawn ;
2004-08-11 16:17:39 +04:00
g_pFunctionTable - > pfnClientKill = NULL ; // "client_kill"
if ( CheckForPublic ( " client_kill " ) )
g_pFunctionTable - > pfnClientKill = ClientKill ;
2013-07-03 03:00:52 +04:00
g_pFunctionTable - > pfnCmdStart = NULL ; // "client_impulse","register_impulse","client_cmdStart"
if ( CheckForPublic ( " client_impulse " ) | | CheckForPublic ( " client_cmdStart " ) )
2004-08-11 16:17:39 +04:00
g_pFunctionTable - > pfnCmdStart = CmdStart ;
g_pFunctionTable - > pfnThink = NULL ; // "pfn_think", "register_think"
if ( CheckForPublic ( " pfn_think " ) )
g_pFunctionTable - > pfnThink = Think ;
g_pFunctionTable - > pfnStartFrame = NULL ; // "server_frame","ServerFrame"
if ( CheckForPublic ( " server_frame " ) )
g_pFunctionTable - > pfnStartFrame = StartFrame ;
if ( CheckForPublic ( " ServerFrame " ) )
g_pFunctionTable - > pfnStartFrame = StartFrame ;
g_pFunctionTable - > pfnTouch = NULL ; // "pfn_touch","vexd_pfntouch"
if ( CheckForPublic ( " pfn_touch " ) )
g_pFunctionTable - > pfnTouch = pfnTouch ;
if ( CheckForPublic ( " vexd_pfntouch " ) )
g_pFunctionTable - > pfnTouch = pfnTouch ;
2004-05-26 09:15:40 +04:00
}
qboolean Voice_SetClientListening ( int iReceiver , int iSender , qboolean bListen )
{
if ( ( plinfo [ iSender ] . iSpeakFlags & SPEAK_MUTED ) ! = 0 ) {
( g_engfuncs . pfnVoice_SetClientListening ) ( iReceiver , iSender , false ) ;
RETURN_META_VALUE ( MRES_SUPERCEDE , false ) ;
}
if ( ( plinfo [ iSender ] . iSpeakFlags & SPEAK_ALL ) ! = 0 ) {
( g_engfuncs . pfnVoice_SetClientListening ) ( iReceiver , iSender , true ) ;
RETURN_META_VALUE ( MRES_SUPERCEDE , true ) ;
}
if ( ( plinfo [ iReceiver ] . iSpeakFlags & SPEAK_LISTENALL ) ! = 0 ) {
( g_engfuncs . pfnVoice_SetClientListening ) ( iReceiver , iSender , true ) ;
RETURN_META_VALUE ( MRES_SUPERCEDE , true ) ;
}
RETURN_META_VALUE ( MRES_IGNORED , bListen ) ;
}
2013-06-16 00:02:24 +04:00
int AddToFullPack_Post ( struct entity_state_s * state , int e , edict_t * ent , edict_t * host , int hostflags , int player , unsigned char * pSet )
2004-05-26 09:15:40 +04:00
{
2015-03-10 18:51:45 +03:00
if ( player & & ent = = host & & plinfo [ ENTINDEX ( ent ) ] . iViewType ! = CAMERA_NONE )
{
state - > rendermode = kRenderTransTexture ;
state - > renderamt = 100 ;
2004-05-26 09:15:40 +04:00
}
RETURN_META_VALUE ( MRES_IGNORED , 0 ) ;
}
void ClientDisconnect ( edict_t * pEntity )
{
int id = ENTINDEX ( pEntity ) ;
2004-08-11 16:17:39 +04:00
if ( plinfo [ ENTINDEX ( pEntity ) ] . iViewType ! = CAMERA_NONE ) // Verify that they were originally in a modified view
{
g_CameraCount - - ;
if ( g_CameraCount < 0 )
g_CameraCount = 0 ;
2004-08-12 08:14:47 +04:00
if ( g_CameraCount = = 0 ) // Reset the AddToFullPack pointer if there's no more cameras in use...
g_pFunctionTable - > pfnAddToFullPack = NULL ;
2004-08-11 16:17:39 +04:00
}
2004-05-26 09:15:40 +04:00
plinfo [ id ] . iSpeakFlags = SPEAK_NORMAL ;
plinfo [ id ] . iViewType = CAMERA_NONE ;
RETURN_META ( MRES_IGNORED ) ;
}
BOOL ClientConnect ( edict_t * pEntity , const char * pszName , const char * pszAddress , char szRejectReason [ 128 ] )
{
int id = ENTINDEX ( pEntity ) ;
plinfo [ id ] . iSpeakFlags = SPEAK_NORMAL ;
plinfo [ id ] . iViewType = CAMERA_NONE ;
plinfo [ id ] . pViewEnt = NULL ;
RETURN_META_VALUE ( MRES_IGNORED , 0 ) ;
}
void ServerDeactivate ( )
{
memset ( glinfo . szLastLights , 0x0 , 128 ) ;
memset ( glinfo . szRealLights , 0x0 , 128 ) ;
2005-11-26 23:38:58 +03:00
glinfo . bCheckLights = false ;
2004-08-12 08:14:47 +04:00
// Reset all forwarding function tables (so that forwards won't be called before plugins are initialized)
g_pFunctionTable - > pfnAddToFullPack = NULL ;
g_pFunctionTable - > pfnKeyValue = NULL ;
g_pengfuncsTable - > pfnPlaybackEvent = NULL ; // "pfn_playbackevent"
g_pFunctionTable - > pfnPlayerPreThink = NULL ; // "client_PreThink"
2004-08-12 08:21:03 +04:00
g_pFunctionTable_Post - > pfnPlayerPostThink = NULL ; // "client_PostThink"
2004-08-12 08:14:47 +04:00
g_pFunctionTable - > pfnSpawn = NULL ; // "pfn_spawn"
g_pFunctionTable - > pfnClientKill = NULL ; // "client_kill"
g_pFunctionTable - > pfnCmdStart = NULL ; // "client_impulse","register_impulse"
g_pFunctionTable - > pfnThink = NULL ; // "pfn_think", "register_think"
g_pFunctionTable - > pfnStartFrame = NULL ; // "server_frame","ServerFrame"
g_pFunctionTable - > pfnTouch = NULL ; // "pfn_touch","vexd_pfntouch"
2005-11-26 23:38:58 +03:00
g_pFunctionTable_Post - > pfnStartFrame = NULL ; // "set_lights"
2004-06-26 02:51:18 +04:00
2004-09-09 01:43:50 +04:00
ClearHooks ( ) ;
2004-05-26 09:15:40 +04:00
RETURN_META ( MRES_IGNORED ) ;
2004-06-24 11:36:43 +04:00
}
2004-05-26 09:15:40 +04:00
2004-06-24 11:36:43 +04:00
void ServerActivate ( edict_t * pEdictList , int edictCount , int clientMax )
{
2004-08-12 08:14:47 +04:00
for ( int f = 1 ; f < = gpGlobals - > maxClients ; f + + )
g_player_edicts [ f ] = pEdictList + f ;
2004-06-26 00:51:48 +04:00
RETURN_META ( MRES_IGNORED ) ;
2004-05-26 09:15:40 +04:00
}
2015-05-11 00:21:12 +03:00
void LightStyle_Post ( int style , const char * val ) {
if ( ! style & & strcmp ( val , glinfo . szRealLights ) ) {
2004-05-26 09:15:40 +04:00
memset ( glinfo . szRealLights , 0x0 , 128 ) ;
2015-05-11 00:21:12 +03:00
memcpy ( glinfo . szRealLights , val , min ( strlen ( val ) , 127 ) ) ;
if ( glinfo . bCheckLights & & strcmp ( val , glinfo . szLastLights ) )
g_pFunctionTable_Post - > pfnStartFrame = StartFrame_Post ;
2004-05-26 09:15:40 +04:00
}
RETURN_META ( MRES_IGNORED ) ;
}
2004-08-11 16:17:39 +04:00
BOOL CheckForPublic ( const char * publicname )
{
AMX * amx ;
char blah [ 64 ] ;
strncpy ( blah , publicname , 63 ) ;
int iFunctionIndex ;
int i = 0 ;
// Loop through all running scripts
while ( ( amx = MF_GetScriptAmx ( i + + ) ) ! = NULL )
{
// Scan for public
if ( MF_AmxFindPublic ( amx , blah , & iFunctionIndex ) = = AMX_ERR_NONE )
{
// Public was found.
return TRUE ;
}
}
return FALSE ; // no public found in any loaded script
}