diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2026-08-24 11:16:07 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2026-08-24 11:16:07 +0200 |
| commit | c068f22329d5cc722622a2183bbb22eef2093df7 (patch) | |
| tree | 12d56c1aede67988a55e241364606bfbb4dba933 /src/parsec_server/con_act_sv.cpp | |
| download | openparsec-main.tar.xz openparsec-main.zip | |
Diffstat (limited to 'src/parsec_server/con_act_sv.cpp')
| -rwxr-xr-x | src/parsec_server/con_act_sv.cpp | 3681 |
1 files changed, 3681 insertions, 0 deletions
diff --git a/src/parsec_server/con_act_sv.cpp b/src/parsec_server/con_act_sv.cpp new file mode 100755 index 0000000..98de7b3 --- /dev/null +++ b/src/parsec_server/con_act_sv.cpp @@ -0,0 +1,3681 @@ +/* + * PARSEC - Server Action Commands + * + * $Author: uberlinuxguy $ - $Date: 2004/09/26 03:43:47 $ + * + * Orginally written by: + * Copyright (c) Clemens Beer <cbx@parsec.org> 2002 + * Copyright (c) Markus Hadwiger <msh@parsec.org> 1997-2000 + * + * 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 + */ + +// C library +#include <math.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +// compilation flags/debug support +#include "config.h" +#include "debug.h" + +// general definitions +#include "general.h" +#include "objstruc.h" + +// global externals +#include "globals.h" +#include "e_world_trans.h" + +// subsystem headers +//#include "aud_defs.h" +//#include "inp_defs.h" +#include "net_defs.h" +#include "sys_defs.h" +//#include "vid_defs.h" + +// mathematics header +#include "utl_math.h" + +// local module header +#include "con_act_sv.h" + +// proprietary module headers +#include "con_aux_sv.h" +#include "con_ext_sv.h" +#include "con_int_sv.h" +#include "con_main_sv.h" +//#include "e_demo.h" +//#include "e_record.h" +//#include "e_replay.h" +//#include "e_supp.h" +//#include "g_camera.h" +//#include "g_supp.h" +//#include "h_drwhud.h" +//#include "h_supp.h" +//#include "h_text.h" +//#include "m_main.h" +//#include "net_game.h" +#ifdef LINKED_PROTOCOL_GAMESERVER +// #include "net_serv.h" +#endif // LINKED_PROTOCOL_GAMESERVER +#include "obj_clas.h" +//#include "obj_ctrl.h" +//#include "obj_xtra.h" +//#include "part_sfx.h" +//#include "part_wfx.h" +//#include "g_emp.h" +#include "sys_file.h" + + +// flags +#define REINIT_LOCAL_SHIP_ON_PREP_RESTORE +#define RECOVER_TARGET_ON_MISSILE_CREATION + + + +// generic string paste area -------------------------------------------------- +// +#define PASTE_STR_LEN 255 +static char paste_str[ PASTE_STR_LEN + 1 ]; + + +// string constants ----------------------------------------------------------- +// +static char invalid_key_id[] = "invalid key identifier."; +static char no_batch_open[] = "no script open."; +static char too_many_pseudos[] = "too many pseudo stars."; +static char no_objcam_allowed[] = "object camera must not be active."; +static char invalid_list[] = "invalid list identifier."; +static char invalid_class[] = "invalid object class identifier."; +static char invalid_action[] = "invalid action."; +static char invalid_id_range[] = "object class id out of range."; +static char no_action_found[] = "no action specified."; +static char non_batch_use[] = "only valid if called from command script."; +static char stream_name_inval[] = "stream name is invalid."; +static char no_stream_started[] = "stream could not be started."; +static char no_stream_stopped[] = "no stream has been stopped."; +static char action_preempted[] = "action command not allowed."; +static char compile_write_err[] = "write error during compilation."; +static char compile_arg_inval[] = "invalid argument found during compilation."; +static char compile_non_comp[] = "non-compilable command found during compilation."; +static char compile_pkt_inval[] = "packet not found during compilation."; +static char only_for_compile[] = "command is only for compilation."; +static char invalid_bin_wait[] = "invalid binary wait argument encountered."; +static char maxplayers_diff[] = "netplayers limit is different from recording."; + + +// pointer to binary parameters ----------------------------------------------- +// +static char *bin_params = NULL; + + +// swap array of int values --------------------------------------------------- +// +INLINE +void SwapParams_int( int num, int32 *source, int32 *dest ) +{ + +#ifdef SYSTEM_BIG_ENDIAN + + for ( int indx = 0; indx < num; indx++ ) { + dest[ indx ] = SWAP_32( source[ indx ] ); + } + +#else + + memcpy( dest, source, sizeof( int32 ) * num ); + +#endif + +} + + +// swap array of hprec_t values ----------------------------------------------- +// +INLINE +void SwapParams_hprec( int num, hprec_t *source, hprec_t *dest ) +{ + +#ifdef SYSTEM_BIG_ENDIAN + + for ( int indx = 0; indx < num; indx++ ) { + + dword *s = (dword *) &source[ indx ]; + dword *d = (dword *) &dest[ indx ]; + + d[ 0 ] = SWAP_32( s[ 1 ] ); + d[ 1 ] = SWAP_32( s[ 0 ] ); + } + +#else + + memcpy( dest, source, sizeof( hprec_t ) * num ); + +#endif + +} + + +// allow no arguments at all instead of all arguments (one-shot flag!!) ------- +// +static int silent_missing_args = FALSE; // all args missing allowed +static int silent_missing_ok; // args were missing, not invalid + + +// check single parameter for action command ---------------------------------- +// +PRIVATE +int AcFetchIntParams( int num, int32 *params ) +{ + ASSERT( num > 0 ); + ASSERT( params != NULL ); + + // assume incorrectly missing arg + silent_missing_ok = FALSE; + + // read parameters binary if possible + if ( bin_params != NULL ) { + SwapParams_int( num, (int32 *) bin_params, params ); + silent_missing_args = FALSE; + return TRUE; + } + + // read specified number of int parameters + while ( num-- ) { + + char *nextparam = strtok( NULL, " " ); + if ( nextparam == NULL ) { + if ( !silent_missing_args ) + CON_AddLine( arg_missing ); + silent_missing_ok = silent_missing_args; + silent_missing_args = FALSE; + return FALSE; + } + + // disabling after first argument enforces either no + // arguments at all, or the entire specified number + // of arguments have to be specified + silent_missing_args = FALSE; + + char *errpart; + int32 ival = (int32) strtol( nextparam, &errpart, int_calc_base ); + + if ( *errpart != 0 ) { + CON_AddLine( invalid_arg ); + return FALSE; + } + + *params++ = ival; + } + + // make sure flag is reset + ASSERT( !silent_missing_args ); + silent_missing_args = FALSE; + + if ( strtok( NULL, " " ) != NULL ) { + CON_AddLine( too_many_args ); + return FALSE; + } + + return TRUE; +} + + +// check float parameters for action command ---------------------------------- +// +PRIVATE +int AcFetchFloatParams( int num, hprec_t *params ) +{ + ASSERT( num > 0 ); + ASSERT( params != NULL ); + + // assume incorrectly missing arg + silent_missing_ok = TRUE; + + // read parameters binary if possible + if ( bin_params != NULL ) { + SwapParams_hprec( num, (hprec_t *) bin_params, params ); + silent_missing_args = FALSE; + return TRUE; + } + + // read specified number of high precision float parameters + while ( num-- ) { + + char *nextparam = strtok( NULL, " " ); + if ( nextparam == NULL ) { + if ( !silent_missing_args ) + CON_AddLine( arg_missing ); + silent_missing_ok = silent_missing_args; + silent_missing_args = FALSE; + return FALSE; + } + + // disabling after first argument enforces either no + // arguments at all, or the entire specified number + // of arguments have to be specified + silent_missing_args = FALSE; + + char *errpart; + hprec_t dval = strtod( nextparam, &errpart ); + + if ( *errpart != 0 ) { + CON_AddLine( invalid_arg ); + return FALSE; + } + + *params++ = dval; + } + + // make sure flag is reset + ASSERT( !silent_missing_args ); + silent_missing_args = FALSE; + + if ( strtok( NULL, " " ) != NULL ) { + CON_AddLine( too_many_args ); + return FALSE; + } + + return TRUE; +} + + +// check string parameter for action command ---------------------------------- +// +PRIVATE +int AcFetchStringParam( char **param, int stripspace ) +{ + ASSERT( param != NULL ); + + // no invalid args + silent_missing_ok = TRUE; + + // read parameter binary if possible + if ( bin_params != NULL ) { + *param = bin_params; + silent_missing_args = FALSE; + return TRUE; + } + + char *nextparam = strtok( NULL, "" ); + if ( nextparam != NULL ) { + + if ( stripspace ) { + + // eat whitespace + char *scan = nextparam; + while ( *scan == ' ' ) + scan++; + + // argument found? + if ( *scan != 0 ) { + + nextparam = scan; + + // cut off trailing whitespace + while ( *scan != 0 ) + scan++; + while ( *--scan == ' ' ) + {} + *( scan + 1 ) = 0; + + } else { + + if ( !silent_missing_args ) + CON_AddLine( arg_missing ); + nextparam = NULL; + } + } + + } else { + + if ( !silent_missing_args ) { + CON_AddLine( arg_missing ); + } + } + + // reset flag + silent_missing_args = FALSE; + + *param = nextparam; + return ( nextparam != NULL ); +} + + +// set automatic pitch (global variable) -------------------------------------- +// +PRIVATE +void AcAutoPitch() +{ + /*bams_t angle; + if ( AcFetchIntParams( 1, &angle ) ) { + AutomaticPitch = angle; + }*/ +} + + +// set automatic yaw (global variable) ---------------------------------------- +// +PRIVATE +void AcAutoYaw() +{ + /*bams_t angle; + if ( AcFetchIntParams( 1, &angle ) ) { + AutomaticYaw = angle; + }*/ +} + + +// set automatic roll (global variable) --------------------------------------- +// +PRIVATE +void AcAutoRoll() +{ + /*bams_t angle; + if ( AcFetchIntParams( 1, &angle ) ) { + AutomaticRoll = angle; + }*/ +} + + +// set automatic horizontal slide (global variable) --------------------------- +// +PRIVATE +void AcAutoSlideX() +{ + /*hprec_t slideval; + if ( AcFetchFloatParams( 1, &slideval ) ) { + AutomaticSlideHorz = FLOAT_TO_GEOMV( slideval ); + }*/ +} + + +// set automatic vertical slide (global variable) ----------------------------- +// +PRIVATE +void AcAutoSlideY() +{ + /*hprec_t slideval; + if ( AcFetchFloatParams( 1, &slideval ) ) { + AutomaticSlideVert = FLOAT_TO_GEOMV( slideval ); + }*/ +} + + +// set automatic movement (global variable and MyShip's speed) ---------------- +// +PRIVATE +void AcAutoMove() +{ + /*fixed_t translation; + if ( AcFetchIntParams( 1, &translation ) ) { + AutomaticMovement = translation; + MyShip->CurSpeed = AutomaticMovement; + }*/ +} + + +// set idle wait count -------------------------------------------------------- +// +PRIVATE +void AcIdleCommand() +{ + /*int32 waitcount; + if ( AcFetchIntParams( 1, &waitcount ) ) { + + // set duration to wait for + ASSERT( waitcount >= 0 ); + CurActionWait = waitcount; + + // remember for info + demoinfo_lastwait = (refframe_t) waitcount; + + // save level recursion is stalled on + idle_reclevel = rec_depth; + }*/ +} + + +// flag for view camera filter reset after matrix init ------------------------ +// +static int reset_viewcam_filter_on_update = FALSE; + + +// set single column of camera matrix ----------------------------------------- +// +INLINE +void SetCameraColumn( Camera cam, int col, hprec_t *v ) +{ + cam[ 0 ][ col ] = FLOAT_TO_GEOMV( v[ 0 ] ); + cam[ 1 ][ col ] = FLOAT_TO_GEOMV( v[ 1 ] ); + cam[ 2 ][ col ] = FLOAT_TO_GEOMV( v[ 2 ] ); +} + + +// set column #1 of camera matrix --------------------------------------------- +// +PRIVATE +void AcSetCamRotCol1() +{ + /*hprec_t v[ 3 ]; + if ( AcFetchFloatParams( 3, v ) ) { + SetCameraColumn( ShipViewCamera, 0, v ); + }*/ +} + + +// set column #2 of camera matrix --------------------------------------------- +// +PRIVATE +void AcSetCamRotCol2() +{ + /*hprec_t v[ 3 ]; + if ( AcFetchFloatParams( 3, v ) ) { + SetCameraColumn( ShipViewCamera, 1, v ); + }*/ +} + + +// set column #3 of camera matrix --------------------------------------------- +// +PRIVATE +void AcSetCamRotCol3() +{ + /*hprec_t v[ 3 ]; + if ( AcFetchFloatParams( 3, v ) ) { + SetCameraColumn( ShipViewCamera, 2, v ); + }*/ +} + + +// set column #4 of camera matrix --------------------------------------------- +// +PRIVATE +void AcSetCamOrigin() +{ + /*hprec_t v[ 3 ]; + if ( AcFetchFloatParams( 3, v ) ) { + SetCameraColumn( ShipViewCamera, 3, v ); + } + + // reset view camera smoothing filter if flag set + // (must be used if matrix is updated discontinuously) + if ( reset_viewcam_filter_on_update ) { + CAMERA_ResetFilter(); + reset_viewcam_filter_on_update = FALSE; + }*/ +} + + +// set single column of object position matrix -------------------------------- +// +PRIVATE +void SetObjectMatrxCol( int listid, int col, geomv_t x, geomv_t y, geomv_t z ) +{ + GenObject *obj = NULL; + + switch ( listid ) { + + case PSHIP_LIST_NO: + obj = (GenObject *) FetchFirstShip(); + break; + + case LASER_LIST_NO: + obj = (GenObject *) FetchFirstLaser(); + break; + + case MISSL_LIST_NO: + obj = (GenObject *) FetchFirstMissile(); + break; + + case EXTRA_LIST_NO: + obj = (GenObject *) FetchFirstExtra(); + break; + + case CUSTM_LIST_NO: + obj = (GenObject *) FetchFirstCustom(); + break; + } + + if ( obj != NULL ) { + obj->ObjPosition[ 0 ][ col ] = x; + obj->ObjPosition[ 1 ][ col ] = y; + obj->ObjPosition[ 2 ][ col ] = z; + } else { + CON_AddLine( invalid_list ); + } +} + + +// mapping table for class ids in demo to corresponding current ids ----------- +// +static dword class_map_id_to_name[ MAX_DISTINCT_OBJCLASSES ]; +static dword class_map_old_id; + + +// reset mapping table for class ids ------------------------------------------ +// +void ResetClassMapTable() +{ + // needed to preserve table across multiple + // demos that are played back-to-back + if ( SV_CLASS_MAP_TABLE_DISABLE_RESET ) + return; + + class_map_old_id = CLASS_ID_INVALID; + + for ( int cid = 0; cid < MAX_DISTINCT_OBJCLASSES; cid++ ) { + class_map_id_to_name[ cid ] = CLASS_ID_INVALID; + } +} + + +// set class id for which class name will be specified ------------------------ +// +void AcClassMapId() +{ + int32 classid; + if ( AcFetchIntParams( 1, &classid ) ) { + if ( (dword)classid < MAX_DISTINCT_OBJCLASSES ) { + class_map_old_id = classid; + } else { + class_map_old_id = CLASS_ID_INVALID; + } + } +} + + +// map class name to current id and set map to corresponding current id ------- +// +void AcClassMapName() +{ + char *classname; + if ( AcFetchStringParam( &classname, ACM_EAT_SPACE( ACM_CLASSMAPNAME ) ) ) { + + dword classid = OBJ_FetchObjectClassId( classname ); + if ( class_map_old_id != CLASS_ID_INVALID ) { + ASSERT( class_map_old_id < MAX_DISTINCT_OBJCLASSES ); + class_map_id_to_name[ class_map_old_id ] = classid; + } + } +} + + +// execute recorded object creation ------------------------------------------- +// +PRIVATE +GenObject *CreateRecordedObject( dword objclass, Xmatrx startmatrx ) +{ + ASSERT( startmatrx != NULL ); + + if ( objclass >= MAX_DISTINCT_OBJCLASSES ) { + CON_AddLine( invalid_id_range ); + return NULL; + } + + // map the recorded class id to the corresponding current class id + if ( class_map_id_to_name[ objclass ] != CLASS_ID_INVALID ) { + objclass = class_map_id_to_name[ objclass ]; + } + + // create object corresponding to original class +#ifdef PARSEC_SERVER + GenObject *obj = CreateObject( objclass, startmatrx, PLAYERID_SERVER ); +#else + GenObject *obj = CreateObject( objclass, startmatrx, LocalPlayerId ); +#endif // PARSEC_SERVER + if ( obj == NULL ) { + + CON_AddLine( invalid_class ); + + } else { + + // play sound effects for certain types + switch ( obj->ObjectType ) { + + case LASER1TYPE: + case LASER2TYPE: + case LASER3TYPE: + //AUD_Laser( obj ); + break; + + case MISSILE1TYPE: + case MISSILE4TYPE: + //AUD_Missile( obj ); + break; + + case MINE1TYPE: + //AUD_Mine( obj ); + break; + } + } + + return obj; +} + + +// for object creation on "ac.objmatrxcol4" instead of "ac.creatobject" ------- +// +static int delayed_object_creation = FALSE; +static dword delayed_object_class; +static dword delayed_object_id; +static dword delayed_object_hostid; +static Xmatrx delayed_object_matrix; + + +// execute delayed creation of recorded object -------------------------------- +// +INLINE +void DelayedObjectCreation() +{ + //NOTE: + // delayed object creation ensures that the objposition matrix + // is already valid on call of OBJ_CTRL::CreateObject(). + + // create object on setting of last matrix column + if ( delayed_object_creation ) { + delayed_object_creation = FALSE; + + GenObject *obj = + CreateRecordedObject( delayed_object_class, delayed_object_matrix ); + + if ( obj != NULL ) { +/* + if ( delayed_object_id != -1 ) { + obj->ObjectNumber = delayed_object_id; + } +*/ + if ( delayed_object_hostid != (dword)-1 ) { + obj->HostObjNumber = delayed_object_hostid; + } + } + } +} + + +// set single column of object position matrix -------------------------------- +// +INLINE +void SetObjMCol( int col ) +{ + hprec_t v[ 4 ]; + if ( AcFetchFloatParams( 4, v ) ) { + + if ( delayed_object_creation ) { + // remember for later use + delayed_object_matrix[ 0 ][ col ] = FLOAT_TO_GEOMV( v[ 1 ] ); + delayed_object_matrix[ 1 ][ col ] = FLOAT_TO_GEOMV( v[ 2 ] ); + delayed_object_matrix[ 2 ][ col ] = FLOAT_TO_GEOMV( v[ 3 ] ); + } else { + // set column directly in object structure + SetObjectMatrxCol( (int) v[ 0 ], col, + FLOAT_TO_GEOMV( v[ 1 ] ), + FLOAT_TO_GEOMV( v[ 2 ] ), + FLOAT_TO_GEOMV( v[ 3 ] ) ); + } + } +} + + +// set single column of object position matrix -------------------------------- +// +PRIVATE +void AcObjectMatrxColumn1() +{ + SetObjMCol( 0 ); +} + +PRIVATE +void AcObjectMatrxColumn2() +{ + SetObjMCol( 1 ); +} + +PRIVATE +void AcObjectMatrxColumn3() +{ + SetObjMCol( 2 ); +} + +PRIVATE +void AcObjectMatrxColumn4() +{ + SetObjMCol( 3 ); + DelayedObjectCreation(); +} + + +// set column #1 of fixed star matrix ----------------------------------------- +// +PRIVATE +void AcSetFixedStarRotCol1() +{ + // dummy for compatibility +} + + +// set column #2 of fixed star matrix ----------------------------------------- +// +PRIVATE +void AcSetFixedStarRotCol2() +{ + // dummy for compatibility +} + + +// set column #3 of fixed star matrix ----------------------------------------- +// +PRIVATE +void AcSetFixedStarRotCol3() +{ + // dummy for compatibility +} + + +// create object of specified class ------------------------------------------- +// +PRIVATE +void AcCreateObject() +{ + /*ASSERT( !delayed_object_creation ); + + int32 objclass; + if ( AcFetchIntParams( 1, &objclass ) ) { + + if ( AUX_NO_DELAYED_CREATE_OBJECT_REPLAY ) { + + // create on "ac.creatobject" + Xmatrx im; + MakeIdMatrx( im ); + CreateRecordedObject( objclass, im ); + + } else { + + // create later on "ac.objmatrxcol4" + delayed_object_creation = TRUE; + delayed_object_class = objclass; + delayed_object_id = -1; // not yet set + delayed_object_hostid = -1; // not yet set + } + }*/ +} + + +// delete all objects from specified object list ------------------------------ +// +PRIVATE +void AcDestroyObjectList() +{ + int32 listid; + if ( AcFetchIntParams( 1, &listid ) ) { + + switch ( listid ) { + + case PSHIP_LIST_NO: + FreeObjList( PShipObjects ); + break; + + case LASER_LIST_NO: + FreeObjList( LaserObjects ); + break; + + case MISSL_LIST_NO: + FreeObjList( MisslObjects ); + break; + + case EXTRA_LIST_NO: + FreeObjList( ExtraObjects ); + break; + + case CUSTM_LIST_NO: + FreeObjList( CustmObjects ); + break; + + default: + CON_AddLine( invalid_list ); + } + } +} + + +// write line 0 in small letters ---------------------------------------------- +// +PRIVATE +void AcWriteSmall() +{ + /*char *nextparam; + if ( AcFetchStringParam( &nextparam, ACM_EAT_SPACE( ACM_WRITESMALL ) ) ) { + HUD_SetDemoText( 0, nextparam ); + }*/ +} + + +// write line 1 in capital letters -------------------------------------------- +// +PRIVATE +void AcWriteBig() +{ + /*char *nextparam; + if ( AcFetchStringParam( &nextparam, ACM_EAT_SPACE( ACM_WRITEBIG1 ) ) ) { + HUD_SetDemoText( 1, nextparam ); + }*/ +} + + +// write line 2 in capital letters -------------------------------------------- +// +PRIVATE +void AcWriteBig2() +{ + /*char *nextparam; + if ( AcFetchStringParam( &nextparam, ACM_EAT_SPACE( ACM_WRITEBIG2 ) ) ) { + HUD_SetDemoText( 2, nextparam ); + }*/ +} + + +// write line 3 in capital letters -------------------------------------------- +// +PRIVATE +void AcWriteBig3() +{ + /*char *nextparam; + if ( AcFetchStringParam( &nextparam, ACM_EAT_SPACE( ACM_WRITEBIG3 ) ) ) { + HUD_SetDemoText( 3, nextparam ); + }*/ +} + + +// scroll demo text out ------------------------------------------------------- +// +PRIVATE +void AcClearText() +{ + //HUD_ClearDemoText(); +} + + +// set global maximum number of remote players (NET_GLOB::CurMaxPlayers) ------ +// +PRIVATE +void AcRemoteMaxPlayers() +{ + /*int32 maxnumplayers; + if ( AcFetchIntParams( 1, &maxnumplayers ) ) { + + if ( NetConnected == NETWORK_GAME_SIMULATED ) { + // simply set it + CurMaxPlayers = maxnumplayers; + } else { + // can't set it, display warning if different + if ( CurMaxPlayers != maxnumplayers ) { + CON_AddLine( maxplayers_diff ); + } + } + }*/ +} + + +// remember id of remote player whose state was set last ---------------------- +// +static int last_remote_playerid = 0; + + +// create remote player with specified state ---------------------------------- +// +PRIVATE +void AcRemotePlayer() +{ + /* + + //NOTE: + // if this is invoked specifying the local player, the + // local id may change. this has to happen in order to + // restore a consistent state with respect to the state + // during recording. the state of the local player will + // also be used to determine whether to activate or + // deactivate entry-mode automatically. + + int32 params[ 4 ]; + if ( AcFetchIntParams( 4, params ) ) { + + // remember id for AcRemoteMatrix(), AcRemoteName(), + // and AcRemoteWeaponsActive() + last_remote_playerid = params[ 0 ]; + + // init state except matrix and name + NET_SetRemotePlayerState( params[ 0 ], params[ 1 ], params[ 2 ], params[ 3 ] ); + } + + */ +} + + +// set remote player matrix --------------------------------------------------- +// +PRIVATE +void AcRemoteMatrix() +{ + /*if ( !NetConnected ) { + CON_AddLine( "AcRemoteMatrix(): no net." ); + return; + } + + hprec_t v[ 12 ]; + if ( AcFetchFloatParams( 12, v ) ) { + + Xmatrx matrix; + matrix[ 0 ][ 0 ] = FLOAT_TO_GEOMV( v[ 0 ] ); + matrix[ 0 ][ 1 ] = FLOAT_TO_GEOMV( v[ 1 ] ); + matrix[ 0 ][ 2 ] = FLOAT_TO_GEOMV( v[ 2 ] ); + matrix[ 0 ][ 3 ] = FLOAT_TO_GEOMV( v[ 3 ] ); + matrix[ 1 ][ 0 ] = FLOAT_TO_GEOMV( v[ 4 ] ); + matrix[ 1 ][ 1 ] = FLOAT_TO_GEOMV( v[ 5 ] ); + matrix[ 1 ][ 2 ] = FLOAT_TO_GEOMV( v[ 6 ] ); + matrix[ 1 ][ 3 ] = FLOAT_TO_GEOMV( v[ 7 ] ); + matrix[ 2 ][ 0 ] = FLOAT_TO_GEOMV( v[ 8 ] ); + matrix[ 2 ][ 1 ] = FLOAT_TO_GEOMV( v[ 9 ] ); + matrix[ 2 ][ 2 ] = FLOAT_TO_GEOMV( v[ 10 ] ); + matrix[ 2 ][ 3 ] = FLOAT_TO_GEOMV( v[ 11 ] ); + + // set matrix of remote player (using id set by AcRemotePlayer()) + NET_SetRemotePlayerMatrix( last_remote_playerid, matrix ); + + // for local player additionally set view camera + if ( Player_ShipId[ last_remote_playerid ] == SHIPID_LOCALPLAYER ) { + + ASSERT( LocalPlayerId == last_remote_playerid ); + ASSERT( Player_Ship[ last_remote_playerid ] == MyShip ); + + ObjCamOff(); + CalcOrthoInverse( MyShip->ObjPosition, DestXmatrx ); + memcpy( ShipViewCamera, DestXmatrx, sizeof( Camera ) ); + CAMERA_ResetFilter(); + } + }*/ +} + + +// set remote player weapons state -------------------------------------------- +// +PRIVATE +void AcRemoteWeaponsActive() +{ + /* + //NOTE: + // if new duration weapons are added this function + // should be updated. + + if ( !NetConnected ) { + CON_AddLine( "AcRemoteWeaponsActive(): no net." ); + return; + } + + int32 weaponsactive; + if ( AcFetchIntParams( 1, &weaponsactive ) ) { + + ASSERT( Player_Ship[ last_remote_playerid ] != NULL ); + ASSERT( Player_ShipId[ last_remote_playerid ] != SHIPID_LOCALPLAYER ); + + ShipObject *shippo = (ShipObject *) Player_Ship[ last_remote_playerid ]; + ASSERT( shippo != NULL ); + ASSERT( shippo != MyShip ); + + // check for lightning state change + dword oldstate = shippo->WeaponsActive & WPMASK_CANNON_LIGHTNING; + dword newstate = weaponsactive & WPMASK_CANNON_LIGHTNING; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_RemoteActivateLightning( last_remote_playerid ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_RemoteDeactivateLightning( last_remote_playerid ); + } + + // check for helix state change + oldstate = shippo->WeaponsActive & WPMASK_CANNON_HELIX; + newstate = weaponsactive & WPMASK_CANNON_HELIX; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_RemoteActivateHelix( last_remote_playerid ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_RemoteDeactivateHelix( last_remote_playerid ); + } + + // check for photon state change + oldstate = shippo->WeaponsActive & WPMASK_CANNON_PHOTON; + newstate = weaponsactive & WPMASK_CANNON_PHOTON; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_RemoteActivatePhoton( last_remote_playerid ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_RemoteDeactivatePhoton( last_remote_playerid ); + } + + // check for emp state change + oldstate = shippo->WeaponsActive & WPMASK_DEVICE_EMP; + newstate = weaponsactive & WPMASK_DEVICE_EMP; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_RemoteActivateEmp( last_remote_playerid ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_RemoteDeactivateEmp( last_remote_playerid ); + } + + // fallback for unknown duration weapons + // (simply set/reset activation bits) + dword unknownmask = 0xffffffff; + unknownmask &= ~WPMASK_CANNON_LIGHTNING; + unknownmask &= ~WPMASK_CANNON_HELIX; + unknownmask &= ~WPMASK_CANNON_PHOTON; + unknownmask &= ~WPMASK_DEVICE_EMP; + shippo->WeaponsActive &= ~unknownmask; + shippo->WeaponsActive |= weaponsactive & unknownmask; + } + */ +} + + +// should a join be performed on the next "ac.remotename" ? ------------------- +// +static int join_on_setname = FALSE; + + +// perform recorded join ------------------------------------------------------ +// +PRIVATE +void PerformRecordedJoin() +{ +/* if ( !NetJoined ) { + HideFloatingMenu(); + NETs_Join(); + EntryMode = FALSE; + InFloatingMenu = FALSE; + } + + ASSERT( EntryMode == FALSE ); + ASSERT( InFloatingMenu == FALSE ); +*/ +} + + +// set remote player name ----------------------------------------------------- +// +PRIVATE +void AcRemoteName() +{ + /*if ( !NetConnected ) { + CON_AddLine( "AcRemoteName(): no net." ); + return; + } + + char *nextparam; + if ( AcFetchStringParam( &nextparam, ACM_EAT_SPACE( ACM_REMOTENAME ) ) ) { + + // set name of remote player (using id set by AcRemotePlayer()) + NET_SetRemotePlayerName( last_remote_playerid, nextparam ); + } + + // perform delayed join + if ( join_on_setname ) { + join_on_setname = FALSE; + PerformRecordedJoin(); + }*/ +} + + +// perform join for local player ---------------------------------------------- +// +PRIVATE +void AcRemoteJoin() +{ + /*ASSERT( !join_on_setname ); + + int32 params[ 3 ]; + if ( AcFetchIntParams( 3, params ) ) { + + ASSERT( LocalPlayerId == params[ 0 ] ); + + //NOTE: + // player position has to be set by following "ac.remotematrix". + + // remember id for AcRemoteMatrix(), AcRemoteName(), + // and AcRemoteWeaponsActive() + last_remote_playerid = params[ 0 ]; + + // prepare local ship for join + InitJoinReplay(); + + if ( AUX_NO_DELAYED_JOIN_REPLAY ) { + PerformRecordedJoin(); + } else { + join_on_setname = TRUE; + } + }*/ +} + + +// perform unjoin for local player -------------------------------------------- +// +PRIVATE +void AcRemoteUnjoin() +{ + /*ASSERT( !join_on_setname ); + + if ( !NetConnected ) { + CON_AddLine( "AcRemoteUnjoin(): no net." ); + return; + } + + int32 params[ 3 ]; + if ( AcFetchIntParams( 3, params ) ) { + + ASSERT( LocalPlayerId == params[ 0 ] ); + + // set flags if not already unjoined + if ( NetJoined ) { + ExitGameLoop = 2; + if ( params[ 1 ] == SHIP_DOWNED ) { + ShipDowned = TRUE; + AUD_PlayerKilled(); + } else { + ShipDowned = FALSE; + } + } + }*/ +} + + +// clear remnants of demo replay ---------------------------------------------- +// +PRIVATE +void AcClearDemo() +{ +/* //NOTE: + // this function has to be used after a demo containing network packets + // has been replayed (and ended) to restore/ensure a proper game state. + + //NOTE: + // if the network mode is not active or the net simulation has already + // been stopped (e.g., the demo has finished) the network state will + // be left untouched (i.e., not reset!). + + ASSERT( !join_on_setname ); + + // specify optional argument flag + silent_missing_args = TRUE; + + // default is stop demo if running + int32 stopflag = 1; + AcFetchIntParams( 1, &stopflag ); + + //NOTE: + // ( silent_missing_ok == FALSE ) is alright here, since an error + // message will already have been displayed and we only wanted to + // override a default value anyway. + + // perform actual clear + DEMO_ClearDemo( stopflag ); +*/ +} + + +// start playback of recorded remote packet ----------------------------------- +// +PRIVATE +void AcPlayRemotePacket() +{ +/* int32 params[ 2 ]; + if ( AcFetchIntParams( 2, params ) ) { + + REC_PlayRemotePacket( params[ 0 ], params[ 1 ] ); + } +*/ +} + + +// replay recorded server message --------------------------------------------- +// +PRIVATE +void AcPlayServerMessage() +{ +/* char *nextparam; + if ( AcFetchStringParam( &nextparam, ACM_EAT_SPACE( ACM_SERVERMSG ) ) ) { + +#ifdef LINKED_PROTOCOL_GAMESERVER + if ( NET_ProtocolGMSV() ) { + NET_ServerParseMessage( nextparam ); + } else { + DBGTXT( MSGOUT( "AcPlayServerMessage(): in non GMSV mode !" ); ); + } +#endif // LINKED_PROTOCOL_GAMESERVER + + } +*/ +} + + +// display message in console ------------------------------------------------- +// +PRIVATE +void AcWriteConsoleText() +{ + /*char *msgtext; + if ( AcFetchStringParam( &msgtext, ACM_EAT_SPACE( ACM_WRITECONSOLETEXT ) ) ) { + + CON_AddLine( msgtext ); + }*/ +} + + +// display message in message area -------------------------------------------- +// +PRIVATE +void AcDisplayMessage() +{ + /*char *msgtext; + if ( AcFetchStringParam( &msgtext, ACM_EAT_SPACE( ACM_DISPLAYMESSAGE ) ) ) { + + ShowMessage( msgtext ); + }*/ +} + + +// execute a command supplied as string --------------------------------------- +// +PRIVATE +void AcExecCommandString() +{ + // make sure this is called from within a compiled demo + if ( bin_params == NULL ) { + CON_AddLine( "only valid during binary replay." ); + return; + } + + //NOTE: + // extreme care must be taken which commands are supplied to this + // function. right now, there are no safety checks for commands + // that must not be executed using this function. + + char *command; + if ( AcFetchStringParam( &command, ACM_EAT_SPACE( ACM_EXECCOMMAND ) ) ) { + + // command must belong to the class of non-compilable commands + ProcessExternalLine( command ); + ExecNonCompilableCommand( command ); + } +} + + +// macro to return with error message if recording inactive ------------------- +// +#define CHECK_RECORDING_STATE() \ +\ +if ( !RecordingActive ) { \ + CON_AddLine( no_batch_open ); \ + return; \ +} + + +// save all objects from specified object list -------------------------------- +// +PRIVATE +void AcSaveObjectList() +{ +/* CHECK_RECORDING_STATE(); + + // disallow object camera + if ( ObjCameraActive ) { + CON_AddLine( no_objcam_allowed ); + return; + } + + int32 listid; + if ( AcFetchIntParams( 1, &listid ) ) { + + switch ( listid ) { + + case PSHIP_LIST_NO: + Save_ObjListShips( RecordingFp ); + break; + + case LASER_LIST_NO: + Save_ObjListLasers( RecordingFp ); + break; + + case MISSL_LIST_NO: + Save_ObjListMissls( RecordingFp ); + break; + + case EXTRA_LIST_NO: + Save_ObjListExtras( RecordingFp ); + break; + + case CUSTM_LIST_NO: + Save_ObjListCustom( RecordingFp ); + break; + + default: + CON_AddLine( invalid_list ); + } + } +*/ +} + + +// save pseudo star positions ------------------------------------------------- +// +PRIVATE +void AcSavePseudoStars() +{ +/* + CHECK_RECORDING_STATE(); + Save_PseudoStars( RecordingFp ); +*/ +} + + +// save camera position and orientation --------------------------------------- +// +PRIVATE +void AcSaveCamera() +{ +/* + CHECK_RECORDING_STATE(); + Save_Camera( RecordingFp ); +*/ +} + + +// save fixed stars orientation ----------------------------------------------- +// +PRIVATE +void AcSaveFixedStars() +{ + // dummy for compatibility +} + + +// save state of all remote players ------------------------------------------- +// +PRIVATE +void AcSaveRemoteState() +{ +/* + CHECK_RECORDING_STATE(); + Save_RemoteState( RecordingFp ); +*/ +} + + +// kill all pseudo stars ------------------------------------------------------ +// +PRIVATE +void AcKillPseudoStars() +{ + //NumPseudoStars = 0; +} + + +// add single pseudo star ----------------------------------------------------- +// +PRIVATE +void AcAddPseudoStar() +{ + /*if ( NumPseudoStars < MAX_PSEUDO_STARS ) { + hprec_t pos[ 3 ]; + if ( AcFetchFloatParams( 3, pos ) ) { + int no = NumPseudoStars++; + PseudoStars[ no ].X = FLOAT_TO_GEOMV( pos[ 0 ] ); + PseudoStars[ no ].Y = FLOAT_TO_GEOMV( pos[ 1 ] ); + PseudoStars[ no ].Z = FLOAT_TO_GEOMV( pos[ 2 ] ); + } + } else { + CON_AddLine( too_many_pseudos ); + }*/ +} + + +// prepare restoration of data screen shot ------------------------------------ +// +PRIVATE +void AcPrepareDataRestore() +{ +/* + int shipclass = MyShip->ObjectClass; + + // allow optional specification of ship class + int32 sclass; + if ( AcFetchIntParams( 1, &sclass ) ) { + shipclass = sclass; + } + + // free objects and particles + KillAllObjects(); + + // delete pseudo stars + AcKillPseudoStars(); + +#ifdef REINIT_LOCAL_SHIP_ON_PREP_RESTORE + + // reinit local player's ship + InitLocalShipStatus( shipclass ); + InitHudDisplay(); + +#endif // REINIT_LOCAL_SHIP_ON_PREP_RESTORE + + // globally select shipclass + LocalShipClass = MyShip->ObjectClass; + + // set flag that view camera filter has to be reset + // after the new matrix has been set + reset_viewcam_filter_on_update = TRUE; + + // reset mapping table for class ids + ResetClassMapTable(); +*/ +} + + +// save data screen shot ------------------------------------------------------ +// +PRIVATE +void AcSaveDataInfo() +{ +/* + //NOTE: + // this function tries to create the logical analog to a screenshot. + // for this, it records the current state (that is, commands that + // are able to restore the current state on their execution). + + CHECK_RECORDING_STATE(); + Save_StateInfo( RecordingFp ); +*/ +} + + +// fade screen out (to black) ------------------------------------------------- +// +PRIVATE +void AcFadeOut() +{ +/* + +// VIDs_FadeScreenToBlack( PAL_GAME, FALSE ); + + int32 speed; + if ( AcFetchIntParams( 1, &speed ) ) { + + SetScreenFadeSpeed = speed; + + SetScreenFadeColor.R = 0; + SetScreenFadeColor.G = 0; + SetScreenFadeColor.B = 0; +// SetScreenFadeColor.A = irrelevant; + + // continue fading from current value + if ( SetScreenFade == 0 ) { + SetScreenFade = 0xff00; + } else if ( SetScreenFade < 0 ) { + SetScreenFade += 0xff00; + if ( SetScreenFade < 0 ) { + SetScreenFade = 0; + } + } + } +*/ +} + + +// fade screen in (from black) ------------------------------------------------ +// +PRIVATE +void AcFadeIn() +{ +/* +// VIDs_FadeScreenFromBlack( PAL_GAME ); + + int32 speed; + if ( AcFetchIntParams( 1, &speed ) ) { + + SetScreenFadeSpeed = speed; + + SetScreenFadeColor.R = 0; + SetScreenFadeColor.G = 0; + SetScreenFadeColor.B = 0; +// SetScreenFadeColor.A = irrelevant; + + // continue fading from current value + if ( ( SetScreenFade == 0 ) || ( SetScreenFade == 1 ) ) { + SetScreenFade = -0xff00; + } else if ( SetScreenFade > 0 ) { + SetScreenFade += -0xff00; + if ( SetScreenFade > 0 ) { + SetScreenFade = 0; + } + } + } +*/ +} + + +// fade screen out (to white) ------------------------------------------------- +// +PRIVATE +void AcWhiteFadeOut() +{ +/* +// colrgba_s scol = COLRGBA_WHITE; +// VIDs_SetScreenToColor( scol ); + + int32 speed; + if ( AcFetchIntParams( 1, &speed ) ) { + + SetScreenFadeSpeed = speed; + + SetScreenFadeColor.R = 255; + SetScreenFadeColor.G = 255; + SetScreenFadeColor.B = 255; +// SetScreenFadeColor.A = irrelevant; + + // continue fading from current value + if ( SetScreenFade == 0 ) { + SetScreenFade = 0xff00; + } else if ( SetScreenFade < 0 ) { + SetScreenFade += 0xff00; + if ( SetScreenFade < 0 ) { + SetScreenFade = 0; + } + } + } +*/ +} + + +// fade screen in (from white) ------------------------------------------------ +// +PRIVATE +void AcWhiteFadeIn() +{ +/* +// VIDs_FadeScreenFromWhite( PAL_GAME ); + + int32 speed; + if ( AcFetchIntParams( 1, &speed ) ) { + + SetScreenFadeSpeed = speed; + + SetScreenFadeColor.R = 255; + SetScreenFadeColor.G = 255; + SetScreenFadeColor.B = 255; +// SetScreenFadeColor.A = irrelevant; + + // continue fading from current value + if ( ( SetScreenFade == 0 ) || ( SetScreenFade == 1 ) ) { + SetScreenFade = -0xff00; + } else if ( SetScreenFade > 0 ) { + SetScreenFade += -0xff00; + if ( SetScreenFade > 0 ) { + SetScreenFade = 0; + } + } + } +*/ +} + + +// set standard palette ------------------------------------------------------- +// +PRIVATE +void AcStandardPalette() +{ +/* +// AwaitVertSync(); + + // turn off fading + SetScreenFade = 0; +*/ +} + + +// set entire palette to black ------------------------------------------------ +// +PRIVATE +void AcBlackScreen() +{ +/* +// colrgba_s scol = COLRGBA_BLACK; +// VIDs_SetScreenToColor( scol ); + + SetScreenFadeColor.R = 0; + SetScreenFadeColor.G = 0; + SetScreenFadeColor.B = 0; +// SetScreenFadeColor.A = irrelevant; + + // hold fading at opaque level + SetScreenFade = 1; +*/ +} + + +// set entire palette to white ------------------------------------------------ +// +PRIVATE +void AcWhiteScreen() +{ +/* +// colrgba_s scol = COLRGBA_WHITE; +// VIDs_SetScreenToColor( scol ); + + SetScreenFadeColor.R = 255; + SetScreenFadeColor.G = 255; + SetScreenFadeColor.B = 255; +// SetScreenFadeColor.A = irrelevant; + + // hold fading at opaque level + SetScreenFade = 1; +*/ +} + + +// set speed property of laser object ----------------------------------------- +// +PRIVATE +void AcSetLaserSpeed() +{ + fixed_t speed; + if ( AcFetchIntParams( 1, (int32 *) &speed ) ) { + LaserObject *scanpo = FetchFirstLaser(); + ASSERT( scanpo != NULL ); + scanpo->Speed = speed; + } +} + + +// set direction vector property of laser object ------------------------------ +// +PRIVATE +void AcSetLaserDirVec() +{ + hprec_t vec[ 3 ]; + if ( AcFetchFloatParams( 3, vec ) ) { + LaserObject *scanpo = FetchFirstLaser(); + ASSERT( scanpo != NULL ); + scanpo->DirectionVec.X = FLOAT_TO_GEOMV( vec[ 0 ] ); + scanpo->DirectionVec.Y = FLOAT_TO_GEOMV( vec[ 1 ] ); + scanpo->DirectionVec.Z = FLOAT_TO_GEOMV( vec[ 2 ] ); + } +} + + +// set owner property of laser object ----------------------------------------- +// +PRIVATE +void AcSetLaserOwner() +{ + int32 owner; + if ( AcFetchIntParams( 1, &owner ) ) { + LaserObject *scanpo = FetchFirstLaser(); + ASSERT( scanpo != NULL ); + scanpo->Owner = owner; + } +} + + +// set speed property of missile object --------------------------------------- +// +PRIVATE +void AcSetMisslSpeed() +{ + fixed_t speed; + if ( AcFetchIntParams( 1, (int32 *) &speed ) ) { + MissileObject *scanpo = FetchFirstMissile(); + ASSERT( scanpo != NULL ); + scanpo->Speed = speed; + } + +} + + +// set direction vector property of missile object ---------------------------- +// +PRIVATE +void AcSetMisslDirVec() +{ + hprec_t vec[ 3 ]; + if ( AcFetchFloatParams( 3, vec ) ) { + MissileObject *scanpo = FetchFirstMissile(); + ASSERT( scanpo != NULL ); + scanpo->DirectionVec.X = FLOAT_TO_GEOMV( vec[ 0 ] ); + scanpo->DirectionVec.Y = FLOAT_TO_GEOMV( vec[ 1 ] ); + scanpo->DirectionVec.Z = FLOAT_TO_GEOMV( vec[ 2 ] ); + } +} + + +// set owner property of missile object --------------------------------------- +// +PRIVATE +void AcSetMisslOwner() +{ + int32 owner; + if ( AcFetchIntParams( 1, &owner ) ) { + MissileObject *scanpo = FetchFirstMissile(); + ASSERT( scanpo != NULL ); + scanpo->Owner = owner; + } +} + + +// set target id property of missile object ----------------------------------- +// +PRIVATE +void AcSetMisslTarget() +{ +/* + //NOTE: + // this command will only occur to set the target + // of a guided missile fired by the local player. + + int32 target; + if ( AcFetchIntParams( 1, &target ) ) { + + TargetMissileObject *scanpo = (TargetMissileObject *) FetchFirstMissile(); + ASSERT( scanpo != NULL ); + ASSERT( ( scanpo->ObjectType & TYPECONTROLMASK ) == TYPEMISSILEISHOMING ); + scanpo->TargetObjNumber = target; + +#ifdef RECOVER_TARGET_ON_MISSILE_CREATION + + if ( TargetObjNumber != target ) { + + // set selected target to ensure the current + // selection is not wrong due to a lost keypress + TargetObjNumber = target; + CON_AddLine( "recovering target." ); + } +#endif + + } +*/ +} + + +// set owner property of mine object ------------------------------------------ +// +PRIVATE +void AcSetMineOwner() +{ +/* + int32 owner; + if ( AcFetchIntParams( 1, &owner ) ) { + MineObject *scanpo = (MineObject *) FetchFirstExtra(); + ASSERT( scanpo != NULL ); + scanpo->Owner = owner; + } +*/ +} + + +// create an extra ------------------------------------------------------------ +// +PRIVATE +void AcCreateExtra() +{ +/* + ASSERT( !delayed_object_creation ); + + int32 objclass; + if ( AcFetchIntParams( 1, &objclass ) ) { + + if ( (dword)objclass >= MAX_DISTINCT_OBJCLASSES ) { + CON_AddLine( invalid_id_range ); + return; + } + + // map the recorded class id to the corresponding current class id + if ( class_map_id_to_name[ objclass ] != CLASS_ID_INVALID ) { + objclass = class_map_id_to_name[ objclass ]; + } + + // create extra corresponding to original class + Xmatrx im; + MakeIdMatrx( im ); + ExtraObject *extrapo = (ExtraObject *) CreateObject( objclass, im ); + if ( extrapo == NULL ) { + CON_AddLine( invalid_class ); + } else { + OBJ_FillExtraMemberVars( extrapo ); + } + } +*/ +} + + +// create an energy field ----------------------------------------------------- +// +PRIVATE +void AcEnergyField() +{ +/* + hprec_t vec[ 3 ]; + if ( AcFetchFloatParams( 3, vec ) ) { + Vertex3 origin; + origin.X = FLOAT_TO_GEOMV( vec[ 0 ] ); + origin.Y = FLOAT_TO_GEOMV( vec[ 1 ] ); + origin.Z = FLOAT_TO_GEOMV( vec[ 2 ] ); + SFX_CreateEnergyField( origin ); + } +*/ +} + + +// shoot spreadfire gun ------------------------------------------------------- +// +PRIVATE +void AcSpreadfire() +{ +/* + WFX_ShootParticleWeapon( MyShip, PARTICLEGUN_SPREADFIRE ); +*/ +} + + +// activate lightning --------------------------------------------------------- +// +PRIVATE +void AcLightningOn() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_CANNON_LIGHTNING ) == 0 ) { + WFX_ActivateLightning( MyShip ); + } else { + CON_AddLine( "filtering redundant lightning activation." ); + } +*/ +} + + +// deactivate lightning ------------------------------------------------------- +// +PRIVATE +void AcLightningOff() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_CANNON_LIGHTNING ) != 0 ) { + WFX_DeactivateLightning( MyShip ); + } else { + CON_AddLine( "filtering redundant lightning deactivation." ); + } +*/ +} + + +// activate helix ------------------------------------------------------------- +// +void AcHelixOn() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_CANNON_HELIX ) == 0 ) { + WFX_ActivateHelix( MyShip ); + } else { + CON_AddLine( "filtering redundant helix activation." ); + } +*/ +} + + +// deactivate helix ----------------------------------------------------------- +// +void AcHelixOff() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_CANNON_HELIX ) != 0 ) { + WFX_DeactivateHelix( MyShip ); + } else { + CON_AddLine( "filtering redundant helix deactivation." ); + } +*/ +} + + +// activate photon ------------------------------------------------------------ +// +void AcPhotonOn() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_CANNON_PHOTON ) == 0 ) { + WFX_ActivatePhoton( MyShip ); + } else { + CON_AddLine( "filtering redundant photon activation." ); + } +*/ +} + + +// deactivate photon ---------------------------------------------------------- +// +void AcPhotonOff() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_CANNON_PHOTON ) != 0 ) { + WFX_DeactivatePhoton( MyShip ); + } else { + CON_AddLine( "filtering redundant photon deactivation." ); + } +*/ +} + + +// activate emp --------------------------------------------------------------- +// +void AcEmpOn() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_DEVICE_EMP ) == 0 ) { + WFX_ActivateEmp( MyShip ); + } else { + CON_AddLine( "filtering redundant emp activation." ); + } +*/ +} + + +// deactivate emp ------------------------------------------------------------- +// +void AcEmpOff() +{ +/* + if ( ( MyShip->WeaponsActive & WPMASK_DEVICE_EMP) != 0 ) { + WFX_DeactivateEmp( MyShip ); + } else { + CON_AddLine( "filtering redundant emp deactivation." ); + } +*/ +} + + +// fire emp ------------------------------------------------------------------- +// +void AcEmp() +{ +/* + WFX_EmpBlast( MyShip ); +*/ +} + + +// set id of ship object that is first in list to specific value -------------- +// +PRIVATE +void AcSetObjectId() +{ +/* + int32 objid; + if ( AcFetchIntParams( 1, &objid ) ) { + if ( delayed_object_creation ) { + delayed_object_id = objid; + } else { + ShipObject *scanpo = FetchFirstShip(); + // ship must have been created previously + ASSERT( scanpo != NULL ); + if ( scanpo != NULL ) { + scanpo->ObjectNumber = objid; + } + } + } +*/ +} + + +// set host id of object to specific value to enable targeting for missiles --- +// +PRIVATE +void AcSetObjectHostId() +{ +/* + int32 objid; + if ( AcFetchIntParams( 1, &objid ) ) { + if ( delayed_object_creation ) { + delayed_object_hostid = objid; + } else { + ShipObject *scanpo = FetchFirstShip(); + // ship must have been created previously + ASSERT( scanpo != NULL ); + if ( scanpo != NULL ) { + scanpo->HostObjNumber = objid; + } + } + } +*/ +} + + +// simulate depression of single key ------------------------------------------ +// +PRIVATE +void AcSimulateKeyPress() +{ +/* int32 keynum; + if ( AcFetchIntParams( 1, &keynum ) ) { + if ( keynum < sizeof( keyfunc_s ) ) { + + ASSERT( sizeof( DepressedKeys->key_Escape ) == sizeof( byte ) ); + ((byte*)DepressedKeys)[ keynum ] = 1; + ((byte*)key_replay_map)[ keynum ] = 1; + + // explicitly check for object camera toggling + if ( offsetof( keyfunc_s, key_ToggleObjCamera ) == keynum ) { + ReplayObjCamActive = !ReplayObjCamActive; + } + + } else { + CON_AddLine( invalid_key_id ); + } + } +*/ +} + + +// simulate release of single key --------------------------------------------- +// +PRIVATE +void AcSimulateKeyRelease() +{ +/* + int32 keynum; + if ( AcFetchIntParams( 1, &keynum ) ) { + if ( keynum < sizeof( keyfunc_s ) ) { + ASSERT( sizeof( DepressedKeys->key_Escape ) == sizeof( byte ) ); + ((byte*)DepressedKeys)[ keynum ] = 0; + ((byte*)key_replay_map)[ keynum ] = 0; + } else { + CON_AddLine( invalid_key_id ); + } + } +*/ +} + + +// ---------------------------------------------------------------------------- +// local ship configuration commands - +// ---------------------------------------------------------------------------- + + +// current damage ------------------------------------------------------------- +// +PRIVATE +void AcMyShip_CurDamage() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->CurDamage = ivalue; + } +*/ +} + + +// maximum damage ------------------------------------------------------------- +// +PRIVATE +void AcMyShip_MaxDamage() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->MaxDamage = ivalue; + } +*/ +} + + +// current energy ------------------------------------------------------------- +// +PRIVATE +void AcMyShip_CurEnergy() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->CurEnergy = ivalue; + } +*/ +} + + +// maximum energy ------------------------------------------------------------- +// +PRIVATE +void AcMyShip_MaxEnergy() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->MaxEnergy = ivalue; + } +*/ +} + + +// current speed -------------------------------------------------------------- +// +PRIVATE +void AcMyShip_CurSpeed() +{ +/* + fixed_t ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->CurSpeed = ivalue; + } +*/ +} + + +// maximum speed -------------------------------------------------------------- +// +PRIVATE +void AcMyShip_MaxSpeed() +{ +/* + fixed_t ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->MaxSpeed = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_NumMissls() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->NumMissls = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_MaxNumMissls() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->MaxNumMissls = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_NumHomMissls() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->NumHomMissls = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_MaxNumHomMissls() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->MaxNumHomMissls = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_NumPartMissls() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->NumPartMissls = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_MaxNumPartMissls() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->MaxNumPartMissls = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_NumMines() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->NumMines = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_MaxNumMines() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->MaxNumMines = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_Weapons() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->Weapons = ivalue; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_WeaponsActive() +{ +/* + //NOTE: + // if new duration weapons are added this function + // should be updated. + + int32 weaponsactive; + if ( AcFetchIntParams( 1, &weaponsactive ) ) { + + // check for lightning state change + dword oldstate = MyShip->WeaponsActive & WPMASK_CANNON_LIGHTNING; + dword newstate = weaponsactive & WPMASK_CANNON_LIGHTNING; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_ActivateLightning( MyShip ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_DeactivateLightning( MyShip ); + } + + // check for helix state change + oldstate = MyShip->WeaponsActive & WPMASK_CANNON_HELIX; + newstate = weaponsactive & WPMASK_CANNON_HELIX; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_ActivateHelix( MyShip ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_DeactivateHelix( MyShip ); + } + + // check for photon state change + oldstate = MyShip->WeaponsActive & WPMASK_CANNON_PHOTON; + newstate = weaponsactive & WPMASK_CANNON_PHOTON; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_ActivatePhoton( MyShip ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_DeactivatePhoton( MyShip ); + } + + // check for emp state change + oldstate = MyShip->WeaponsActive & WPMASK_DEVICE_EMP; + newstate = weaponsactive & WPMASK_DEVICE_EMP; + if ( ( oldstate == 0 ) && ( newstate != 0 ) ) { + WFX_ActivateEmp( MyShip ); + } else if ( ( oldstate != 0 ) && ( newstate == 0 ) ) { + WFX_DeactivateEmp( MyShip ); + } + + // fallback for unknown duration weapons + // (simply set/reset activation bits) + dword unknownmask = 0xffffffff; + unknownmask &= ~WPMASK_CANNON_LIGHTNING; + unknownmask &= ~WPMASK_CANNON_HELIX; + unknownmask &= ~WPMASK_CANNON_PHOTON; + unknownmask &= ~WPMASK_DEVICE_EMP; + MyShip->WeaponsActive &= ~unknownmask; + MyShip->WeaponsActive |= weaponsactive & unknownmask; + } +*/ +} + + +// ---------------------------------------------------------------------------- +// +PRIVATE +void AcMyShip_Specials() +{ +/* + int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + MyShip->Specials = ivalue; + } +*/ +} + + +// global variables configuration commands pertaining to local ship ----------- +// +PRIVATE +void AcGlobals_SelectedLaser() +{ + /*int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + SelectedLaser = ivalue; + }*/ +} + +PRIVATE +void AcGlobals_SelectedMissile() +{ + /*int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + SelectedMissile = ivalue; + }*/ +} + +PRIVATE +void AcGlobals_CurGun() +{ + /*int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + CurGun = ivalue; + }*/ +} + +PRIVATE +void AcGlobals_CurLauncher() +{ + /*int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + CurLauncher = ivalue; + }*/ +} + +PRIVATE +void AcGlobals_AUX_HUD_PANEL_3_CONTROL() +{ + /*int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + AUX_HUD_PANEL_3_CONTROL = ivalue; + }*/ +} + +PRIVATE +void AcGlobals_AUX_HUD_PANEL_4_CONTROL() +{ + /*int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + AUX_HUD_PANEL_4_CONTROL = ivalue; + }*/ +} + +PRIVATE +void AcGlobals_TargetObjNumber() +{ + /*int32 ivalue; + if ( AcFetchIntParams( 1, &ivalue ) ) { + TargetObjNumber = ivalue; + }*/ +} + + +// play specified sound effect ------------------------------------------------ +// +PRIVATE +void AcPlaySound() +{ + // dummy for compatibility +} + + +// flag whether audio stream has been started with an action command ---------- +// +PUBLIC int con_audio_stream_started = FALSE; + + +// start playing of specific audio stream ------------------------------------- +// +PRIVATE +void AcPlayStream() +{ +/* + char *streamname; + if ( AcFetchStringParam( &streamname, ACM_EAT_SPACE( ACM_PLAYSTREAM ) ) ) { + + if ( strlen( streamname ) + strlen( console_audio_stream_path ) > PATH_MAX ) { + // resulting file name too long + CON_AddLine( stream_name_inval ); + return; + } + + //NOTE: + // apart from its length the filename is + // not checked for validity in any way! + + // create full filename including path + char fname[ PATH_MAX + 1 ]; + strcpy( fname, console_audio_stream_path ); + strcat( fname, streamname ); + + // check first if file exists in pack or current directory + FILE *fp = SYS_fopen( streamname, "rb" ); + if ( fp == NULL ) { + + // check if file exists in audio stream path + fp = SYS_fopen( fname, "rb" ); + if ( fp == NULL ) { + CON_AddLine( stream_name_inval ); + return; + } + + //NOTE: + // we use SYS_fopen() here, because the streaming code + // also uses the SYS_f*() functions. + + } else { + + // strip path + strcpy( fname, streamname ); + } + SYS_fclose( fp ); + + // play audio stream (automatically determines stream's format) + int started = AUDs_PlayAudioStream( fname ); + + if ( started ) { + con_audio_stream_started = TRUE; + } else { + CON_AddLine( no_stream_started ); + } + } +*/ +} + + +// stop playing of currently active audio stream ------------------------------ +// +PRIVATE +void AcStopStream() +{ +/* + int stopped = AUDs_StopAudioStream(); + + if ( stopped ) { + con_audio_stream_started = FALSE; + } else { + CON_AddLine( no_stream_stopped ); + } +*/ +} + + +// set aux flag with ac. command ---------------------------------------------- +// +PRIVATE +void AcSetAuxFlag() +{ +/* + int32 params[ 2 ]; + if ( AcFetchIntParams( 2, params ) ) { + + if ( (dword)params[ 0 ] < MAX_AUX_ENABLING ) { + AuxEnabling[ params[ 0 ] ] = params[ 1 ]; + } + } +*/ +} + + +// set aux data with ac. command ---------------------------------------------- +// +PRIVATE +void AcSetAuxData() +{ +/* + int32 params[ 2 ]; + if ( AcFetchIntParams( 2, params ) ) { + + if ( (dword)params[ 0 ] < MAX_AUX_DATA ) { + AuxData[ params[ 0 ] ] = params[ 1 ]; + } + } +*/ +} + + +// set new refframe frequency ------------------------------------------------- +// +PRIVATE +void AcSetRefFrameFrequency() +{ +/* + int32 param; + if ( AcFetchIntParams( 1, ¶m ) ) { + + if ( RefFrameFrequency != param ) { + + RefFrameFrequency = param; + + // reinit frame timer to apply frequency change + SYSs_InitFrameTimer(); + } + } +*/ +} + + +// alter entry-mode flag ------------------------------------------------------ +// +PRIVATE +void AcSetEntryMode() +{ +/* + int32 param; + if ( AcFetchIntParams( 1, ¶m ) ) { + + EntryMode = param; + InFloatingMenu = EntryMode ? FloatingMenu : FALSE; + + // reset the floating menu state + if ( InFloatingMenu ) { + ActivateFloatingMenu( FALSE ); + } + } +*/ +} + + +// this gets called on execution instead of compilation, which is a nop ------- +// +PRIVATE +void AcIncludeDemo() +{ +/* + //NOTE: + // this command is a nop in a script file and should never + // occur in a compiled demo, since it will be substituted + // by the specified demo on compilation. + + CON_AddLine( only_for_compile ); +*/ +} + + +// this gets called on execution instead of compilation, which is a nop ------- +// +PRIVATE +void AcScheduleCommand() +{ +/* + //NOTE: + // this command is a nop in a script file. + // in a compiled demo this function will not be called at all. + + CON_AddLine( only_for_compile ); +*/ +} + + +// set the ambient light color ------------------------------------------------ +// +PRIVATE +void AcLightAmbient() +{ +/* + int32 params[ 4 ]; + if ( AcFetchIntParams( 4, params ) ) { + + LightColorAmbient.R = params[ 0 ]; + LightColorAmbient.G = params[ 1 ]; + LightColorAmbient.B = params[ 2 ]; + LightColorAmbient.A = params[ 3 ]; + } +*/ +} + + +// set the diffuse light color ------------------------------------------------ +// +PRIVATE +void AcLightDiffuse() +{ +/* + int32 params[ 4 ]; + if ( AcFetchIntParams( 4, params ) ) { + + LightColorDiffuse.R = params[ 0 ]; + LightColorDiffuse.G = params[ 1 ]; + LightColorDiffuse.B = params[ 2 ]; + LightColorDiffuse.A = params[ 3 ]; + } +*/ +} + + +// set the specular light color ----------------------------------------------- +// +PRIVATE +void AcLightSpecular() +{ +/* + int32 params[ 4 ]; + if ( AcFetchIntParams( 4, params ) ) { + + LightColorSpecular.R = params[ 0 ]; + LightColorSpecular.G = params[ 1 ]; + LightColorSpecular.B = params[ 2 ]; + LightColorSpecular.A = params[ 3 ]; + } +*/ +} + + +// cd audio: open drive ------------------------------------------------------- +// +PRIVATE +void AcCD_Open() +{ +/* + int32 param; + if ( AcFetchIntParams( 1, ¶m ) ) { + + AUDs_CDOpen( param ); + } +*/ +} + + +// cd audio: close drive ------------------------------------------------------ +// +PRIVATE +void AcCD_Close() +{ +// AUDs_CDClose(); +} + + +// cd audio: play audio track ------------------------------------------------- +// +PRIVATE +void AcCD_Play() +{ +/* + //NOTE: + // the from and to params (param 1 and 2) cannot be omitted + // when using this command. however, they can be set to -1 + // in order to avoid specifying specific from/to locations. + + int32 params[ 3 ]; + if ( AcFetchIntParams( 3, params ) ) { + + AUDs_CDPlay( params[ 0 ], params[ 1 ], params[ 2 ] ); + } +*/ +} + + +// cd audio: pause playing ---------------------------------------------------- +// +PRIVATE +void AcCD_Pause() +{ + //AUDs_CDPause(); +} + + +// cd audio: resume playing --------------------------------------------------- +// +PRIVATE +void AcCD_Resume() +{ + //AUDs_CDResume(); +} + + +// cd audio: stop playing ----------------------------------------------------- +// +PRIVATE +void AcCD_Stop() +{ + //AUDs_CDStop(); +} + + +// cd audio: set volume ------------------------------------------------------- +// +PRIVATE +void AcCD_Volume() +{ +/* + int32 param; + if ( AcFetchIntParams( 1, ¶m ) ) { + + AUDs_CDSetVolume( param ); + } +*/ +} + + +// list of valid action commands and functions to be called for each ---------- +// +act_command_s action_commands[] = { + + // general signature + { "ac.", NULL, ACF_NODIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + + { "ac.wait", AcIdleCommand, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.pitch", AcAutoPitch, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.yaw", AcAutoYaw, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.roll", AcAutoRoll, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.slidex", AcAutoSlideX, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 1 }, + { "ac.slidey", AcAutoSlideY, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 1 }, + { "ac.move", AcAutoMove, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.camrot1", AcSetCamRotCol1, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + { "ac.camrot2", AcSetCamRotCol2, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + { "ac.camrot3", AcSetCamRotCol3, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + { "ac.camorigin", AcSetCamOrigin, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + + { "ac.fixrot1", AcSetFixedStarRotCol1, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + { "ac.fixrot2", AcSetFixedStarRotCol2, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + { "ac.fixrot3", AcSetFixedStarRotCol3, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + + { "ac.packet", AcPlayRemotePacket, ACF_NODIRECT | ACF_COMPILE | ACF_PACKETPARAM, 1 }, + + { "ac.fadeout", AcFadeOut, ACF_DIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.fadein", AcFadeIn, ACF_DIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.wfadeout", AcWhiteFadeOut, ACF_DIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.wfadein", AcWhiteFadeIn, ACF_DIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.black", AcBlackScreen, ACF_DIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.white", AcWhiteScreen, ACF_DIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.stdpalette", AcStandardPalette, ACF_DIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + + { "ac.savescreen", AcSaveDataInfo, ACF_DIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + { "ac.savelist", AcSaveObjectList, ACF_DIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + { "ac.savecam", AcSaveCamera, ACF_DIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + { "ac.savefstars", AcSaveFixedStars, ACF_DIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + { "ac.savepstars", AcSavePseudoStars, ACF_DIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + { "ac.saveremote", AcSaveRemoteState, ACF_DIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + + { "ac.killpstars", AcKillPseudoStars, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.addpstar", AcAddPseudoStar, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + + { "ac.preprestore", AcPrepareDataRestore, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.creatobj", AcCreateObject, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.creatextra", AcCreateExtra, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.destlist", AcDestroyObjectList, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.remoteplayer", AcRemotePlayer, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 4 }, + { "ac.remotematrix", AcRemoteMatrix, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 12 }, + { "ac.remotename", AcRemoteName, ACF_NODIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + { "ac.remotejoin", AcRemoteJoin, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 3 }, + { "ac.remoteunjoin", AcRemoteUnjoin, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 3 }, + + { "ac.cleardemo", AcClearDemo, ACF_DIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.objmatrxcol1", AcObjectMatrxColumn1, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 4 }, + { "ac.objmatrxcol2", AcObjectMatrxColumn2, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 4 }, + { "ac.objmatrxcol3", AcObjectMatrxColumn3, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 4 }, + { "ac.objmatrxcol4", AcObjectMatrxColumn4, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 4 }, + + { "ac.laserspeed", AcSetLaserSpeed, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.laserdirvec", AcSetLaserDirVec, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + { "ac.laserowner", AcSetLaserOwner, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.misslspeed", AcSetMisslSpeed, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.missldirvec", AcSetMisslDirVec, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + + { "ac.misslowner", AcSetMisslOwner, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.missltarget", AcSetMisslTarget, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.mineowner", AcSetMineOwner, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.energyfield", AcEnergyField, ACF_NODIRECT | ACF_COMPILE | ACF_FLOATPARAMS, 3 }, + { "ac.spreadfire", AcSpreadfire, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.lightningon", AcLightningOn, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.lightningoff", AcLightningOff, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + + { "ac.setobjid", AcSetObjectId, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.setobjhostid", AcSetObjectHostId, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.keypress", AcSimulateKeyPress, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.keyrelease", AcSimulateKeyRelease, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.ms.curdamage", AcMyShip_CurDamage, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.maxdamage", AcMyShip_MaxDamage, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.curenergy", AcMyShip_CurEnergy, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.maxenergy", AcMyShip_MaxEnergy, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.curspeed", AcMyShip_CurSpeed, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.maxspeed", AcMyShip_MaxSpeed, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.nummissls", AcMyShip_NumMissls, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.maxnummissls", AcMyShip_MaxNumMissls, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.numhommissls", AcMyShip_NumHomMissls, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.maxnumhommissls", AcMyShip_MaxNumHomMissls, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.nummines", AcMyShip_NumMines, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.maxnummines", AcMyShip_MaxNumMines, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.weapons", AcMyShip_Weapons, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.specials", AcMyShip_Specials, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.gl.selectedlaser", AcGlobals_SelectedLaser, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.gl.selectedmissile", AcGlobals_SelectedMissile, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.gl.curgun", AcGlobals_CurGun, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.gl.curlauncher", AcGlobals_CurLauncher, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.gl.panel3control", AcGlobals_AUX_HUD_PANEL_3_CONTROL, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.gl.panel4control", AcGlobals_AUX_HUD_PANEL_4_CONTROL, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.gl.targetobjnumber", AcGlobals_TargetObjNumber, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.writesmall", AcWriteSmall, ACF_DIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + { "ac.writebig", AcWriteBig, ACF_DIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + { "ac.writebig2", AcWriteBig2, ACF_DIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + { "ac.writebig3", AcWriteBig3, ACF_DIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + { "ac.cleartext", AcClearText, ACF_DIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + + { "ac.playstream", AcPlayStream, ACF_DIRECT | ACF_COMPILE | ACF_STRINGSTRIP, 1 }, + { "ac.stopstream", AcStopStream, ACF_DIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.playsound", AcPlaySound, ACF_DIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.aux", AcSetAuxFlag, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 2 }, + { "ac.entrymode", AcSetEntryMode, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.servermsg", AcPlayServerMessage, ACF_NODIRECT | ACF_COMPILE | ACF_STRINGSTRIP, 1 }, + + { "ac.helixon", AcHelixOn, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.helixoff", AcHelixOff, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + + { "ac.remotemaxplayers", AcRemoteMaxPlayers, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.include", AcIncludeDemo, ACF_NODIRECT | ACF_COMPILE | ACF_DEMOPARAM, 1 }, + + { "ac.ms.weaponsactive", AcMyShip_WeaponsActive, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.remoteweaponsactive", AcRemoteWeaponsActive, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.write", AcWriteConsoleText, ACF_NODIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + { "ac.display", AcDisplayMessage, ACF_NODIRECT | ACF_COMPILE | ACF_STRINGSTRIP, 1 }, + + { "ac.cd.open", AcCD_Open, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.cd.close", AcCD_Close, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.cd.play", AcCD_Play, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 3 }, + { "ac.cd.pause", AcCD_Pause, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.cd.resume", AcCD_Resume, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.cd.stop", AcCD_Stop, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.cd.volume", AcCD_Volume, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.command", AcExecCommandString, ACF_NODIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + + { "ac.classmapid", AcClassMapId, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.classmapname", AcClassMapName, ACF_NODIRECT | ACF_COMPILE | ACF_STRINGPARAM, 1 }, + + { "ac.auxdata", AcSetAuxData, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 2 }, + { "ac.refframes", AcSetRefFrameFrequency, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.schedule", AcScheduleCommand, ACF_NODIRECT | ACF_COMPILE | ACF_SCHEDPARAM, 1 }, + + { "ac.ambient", AcLightAmbient, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 4 }, + { "ac.diffuse", AcLightDiffuse, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 4 }, + { "ac.specular", AcLightSpecular, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 4 }, + + { "ac.ms.numpartmissls", AcMyShip_NumPartMissls, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + { "ac.ms.maxnumpartmissls", AcMyShip_MaxNumPartMissls, ACF_NODIRECT | ACF_COMPILE | ACF_INTPARAMS, 1 }, + + { "ac.photonon", AcPhotonOn, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.photonoff", AcPhotonOff, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + + { "ac.empon", AcEmpOn, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.empoff", AcEmpOff, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + { "ac.emp", AcEmp, ACF_NODIRECT | ACF_COMPILE | ACF_NOPARAMS, 0 }, + + { NULL, NULL, ACF_NODIRECT | ACF_NOCOMPILE | ACF_NOPARAMS, 0 }, + +}; + + +// determine the number of parameter bytes of an action command --------------- +// +size_t GetActionParamSize( int actid, char *params ) +{ + ASSERT( actid > ACM_SIGNATURE ); + ASSERT( params != NULL ); + + size_t paramsize = 0; + + if ( action_commands[ actid ].flags & ACF_INTPARAMS ) { + paramsize = sizeof( int32 ) * action_commands[ actid ].numparameters; + } else if ( action_commands[ actid ].flags & ACF_FLOATPARAMS ) { + paramsize = sizeof( hprec_t ) * action_commands[ actid ].numparameters; + } else if ( action_commands[ actid ].flags & ACF_STRINGPARAM ) { + paramsize = strlen( params ) + 1; + } + + return paramsize; +} + + +// scheduled action commands -------------------------------------------------- +// +struct scheduled_command_s { + + refframe_t timestamp; + char* command; +}; + +#define MAX_SCHEDULED_COMMANDS 64 +static int num_scheduled_commands = 0; +static scheduled_command_s scheduled_commands[ MAX_SCHEDULED_COMMANDS ]; + + +// remainder of a wait interval split by a scheduled command ------------------ +// +static int scheduled_wait = 0; + + +// clear all scheduled action commands ---------------------------------------- +// +void ResetScheduledActions() +{ + num_scheduled_commands = 0; + scheduled_wait = 0; +} + + +// schedule an action command for automatic execution at a later time --------- +// +PRIVATE +size_t ScheduleCommand( int *params ) +{ + ASSERT( params != NULL ); +/* + // fetch delta time and command to schedule + int timedelta = SWAP_32( params[ 0 ] ); + int actid = SWAP_32( params[ 1 ] ); + + // calc absolute activation timestamp + refframe_t timestamp = demoinfo_curtime + timedelta; + + // insert at correct position if already commands scheduled + for ( int cid = 0; cid < num_scheduled_commands; cid++ ) { + + if ( scheduled_commands[ cid ].timestamp >= timestamp ) { + + // this also ensures the move works correctly + if ( num_scheduled_commands < MAX_SCHEDULED_COMMANDS ) { + num_scheduled_commands++; + } + + // move back commands scheduled for a later time + if ( cid < MAX_SCHEDULED_COMMANDS - 1 ) { + size_t movesize = ( num_scheduled_commands - cid - 1 ); + movesize *= sizeof( scheduled_command_s ); + memmove( &scheduled_commands[ cid + 1 ], &scheduled_commands[ cid ], movesize ); + } + + // store this command + scheduled_commands[ cid ].timestamp = timestamp; + scheduled_commands[ cid ].command = (char *) ¶ms[ 1 ]; + break; + } + } + + // insert if no commands scheduled or position should be last + if ( cid == num_scheduled_commands ) { + + // commands that exceed the available space will be dropped silently + if ( cid < MAX_SCHEDULED_COMMANDS ) { + scheduled_commands[ cid ].timestamp = timestamp; + scheduled_commands[ cid ].command = (char *) ¶ms[ 1 ]; + num_scheduled_commands++; + } + } + + // return number of parameter bytes to skip + size_t paramsize = sizeof( int ) * 2; + paramsize += GetActionParamSize( actid, (char *) ¶ms[ 2 ] ); + return paramsize; +*/ + ASSERT( FALSE ); + return 0; +} + + +// execute command in binary format as written by WriteActionCommand() -------- +// +int ExecBinCommands( char* &data, int interactive ) +{ +/* // non-interactive console mode + con_non_interactive = !interactive; + + // to remember the current replay position when + // it is temporarily set to a scheduled command + char *curpos = NULL; + +restartwait: + + // execute commands until wait encountered + for (;;) { + + // restore position after scheduled command + if ( curpos != NULL ) { + data = curpos; + curpos = NULL; + } + + // check for execution of scheduled command + if ( num_scheduled_commands > 0 ) { + + if ( scheduled_commands[ 0 ].timestamp == demoinfo_curtime ) { + + // temporarily jump to position of scheduled command + curpos = data; + data = scheduled_commands[ 0 ].command; + + // remove this command from scheduled commands + if ( num_scheduled_commands > 1 ) { + size_t movesize = ( num_scheduled_commands - 1 ); + movesize *= sizeof( scheduled_command_s ); + memmove( &scheduled_commands[ 0 ], &scheduled_commands[ 1 ], movesize ); + } + num_scheduled_commands--; + } + } + + // for regular (non-scheduled) commands + if ( curpos == NULL ) { + + // exit loop on implied wait command + if ( scheduled_wait > 0 ) { + break; + } + + // count executed commands + demoinfo_curline++; + } + + // fetch command id + int actid = SWAP_32( *(int *)data ); + ASSERT( ( actid >= ACM_SIGNATURE ) && ( actid < ACM_NUM_COMMANDS ) ); + + // stop execution if end of command file reached + if ( actid == ACM_SIGNATURE ) { + bin_params = NULL; + con_non_interactive = FALSE; + return FALSE; + } + + data += sizeof( actid ); + bin_params = data; + + // exit loop on wait command + if ( actid == ACM_IDLEWAIT ) { + break; + } + + // check for packet replay + if ( action_commands[ actid ].flags & ACF_PACKETPARAM ) { + + // replay packet and get pointer advance + size_t advance = REC_PlayRemotePacketBin( (NetPacketExternal *) bin_params ); + + // check for invalid pointer advance ( -1 ... invalid packet ) + if ( advance == (size_t)-1 ) { + bin_params = NULL; + con_non_interactive = FALSE; + return FALSE; + } + + data += advance; + continue; + } + + // check for command scheduling + if ( action_commands[ actid ].flags & ACF_SCHEDPARAM ) { + // schedule command and advance pointer + data += ScheduleCommand( (int *) bin_params ); + continue; + } + + // determine how many parameter bytes need to be skipped. + // we do this before calling the action function because + // it might destroy its string parameter while parsing. + size_t paramsize = GetActionParamSize( actid, bin_params ); + + // call corresponding action function + // (it knows the type of its parameters) + ASSERT( action_commands[ actid ].func != NULL ); + (*action_commands[ actid ].func)(); + + // skip command's parameters (already read by action function) + data += paramsize; + } + + // wait command must not be scheduled + ASSERT( curpos == NULL ); + + // determine length of next wait interval + int waitcount; + if ( scheduled_wait > 0 ) { + + // completion of wait interval split by scheduled command + waitcount = scheduled_wait; + scheduled_wait = 0; + + } else { + + // preadvance over wait argument + data += sizeof( int32 ); + + // process wait + int32 suppliedwait; + if ( !AcFetchIntParams( 1, &suppliedwait ) ) { + + ASSERT( 0 ); + CON_AddLine( invalid_bin_wait ); + goto restartwait; + } + + waitcount = suppliedwait; + } + + // consume zero-waits transparently + if ( waitcount == 0 ) { + goto restartwait; + } + + ASSERT( waitcount > 0 ); + if ( waitcount < 0 ) { + CON_AddLine( invalid_bin_wait ); + goto restartwait; + } + + // check for scheduled commands in the middle of the next wait interval + if ( num_scheduled_commands > 0 ) { + ASSERT( demoinfo_curtime < scheduled_commands[ 0 ].timestamp ); + if ( demoinfo_curtime + waitcount > scheduled_commands[ 0 ].timestamp ) { + scheduled_wait = waitcount; + waitcount = scheduled_commands[ 0 ].timestamp - demoinfo_curtime; + scheduled_wait -= waitcount; + } + } + + // set duration to wait for + //CurActionWait = waitcount; + + // remember for info + demoinfo_lastwait = (refframe_t) waitcount; + + // flag must be reset + con_non_interactive = FALSE; + + bin_params = NULL; +*/ + return TRUE; +} + + +// save game state to current recording --------------------------------------- +// +void SaveGameState() +{ + //NOTE: + // this function is called by CON_EXT::StartRecording() to save + // the game state before a recording is started. + + AcSaveDataInfo(); +} + + +// include an entire demo file in the current compilation --------------------- +// +PRIVATE +int IncludeDemoFile( FILE *fp ) +{ +/* ASSERT( fp != NULL ); + + // read demo name + char *demoname; + if ( AcFetchStringParam( &demoname, TRUE ) ) { + + // open demo for inclusion + FILE *cpfp = DEMO_BinaryOpenDemo( demoname ); + if ( cpfp == NULL ) { + strcpy( paste_str, "demo file not found. (" ); + strcat( paste_str, demoname ); + strcat( paste_str, CON_FILE_COMPILED_EXTENSION ); + strcat( paste_str, ")" ); + CON_AddLine( paste_str ); + return TRUE; + } + + // skip header if present + DEMO_ParseDemoHeader( cpfp, -1, FALSE ); + + // demo will be copied in chunks + #define INCLUDE_BLOCK_SIZE 16384 + char *cpblock = (char *) ALLOCMEM( INCLUDE_BLOCK_SIZE ); + if ( cpblock == NULL ) + OUTOFMEM( 0 ); + + // paste in entire demo in chunks + size_t numread = 1; + while ( numread > 0 ) { + numread = fread( cpblock, 1, INCLUDE_BLOCK_SIZE, cpfp ); + if ( fwrite( cpblock, 1, numread, fp ) != numread ) { + CON_AddLine( compile_write_err ); + FREEMEM( cpblock ); + return FALSE; + } + } + + FREEMEM( cpblock ); + fclose( cpfp ); + + // strip off terminating eof marker + fseek( fp, -sizeof( int ), SEEK_CUR ); + } +*/ + return TRUE; +} + + +// write int parameters of action command in binary format to file ------------ +// +PRIVATE +int WriteActionIntParams( FILE *fp, int paranum ) +{ + ASSERT( fp != NULL ); + ASSERT( paranum > 0 ); + + // write int parameters + int32 *intparams = (int32 *) ALLOCMEM( sizeof( int32 ) * paranum * 2 ); + int32 *intparams_swapped = &intparams[ paranum ]; + if ( AcFetchIntParams( paranum, intparams ) ) { + + // must be written in little-endian format + SwapParams_int( paranum, intparams, intparams_swapped ); + + if ( fwrite( intparams_swapped, sizeof( int32 ), paranum, fp ) != (unsigned int)paranum ) { + CON_AddLine( compile_write_err ); + FREEMEM( intparams ); + return FALSE; + } + + } else { + + CON_AddLine( compile_arg_inval ); + } + + FREEMEM( intparams ); + + return TRUE; +} + + +// write float parameters of action command in binary format to file ---------- +// +PRIVATE +int WriteActionFloatParams( FILE *fp, int paranum ) +{ + ASSERT( fp != NULL ); + ASSERT( paranum > 0 ); + + // write float parameters + hprec_t *floatparams = (hprec_t *) ALLOCMEM( sizeof( hprec_t ) * paranum * 2 ); + hprec_t *floatparams_swapped = &floatparams[ paranum ]; + if ( AcFetchFloatParams( paranum, floatparams ) ) { + + // must be written in little-endian format + SwapParams_hprec( paranum, floatparams, floatparams_swapped ); + + if ( fwrite( floatparams_swapped, sizeof( hprec_t ), paranum, fp ) != (unsigned int)paranum ) { + CON_AddLine( compile_write_err ); + FREEMEM( floatparams ); + return FALSE; + } + + } else { + + CON_AddLine( compile_arg_inval ); + } + + FREEMEM( floatparams ); + + return TRUE; +} + + +// write string parameter of action command in binary format to file ---------- +// +PRIVATE +int WriteActionStringParam( FILE *fp, dword flags ) +{ + ASSERT( fp != NULL ); + + // read string parameter + char *strparam; + if ( AcFetchStringParam( &strparam, ACF_EAT_SPACE( flags ) ) ) { + + unsigned int slen = strlen( strparam ) + 1; + if ( fwrite( strparam, 1, slen, fp ) != slen ) { + CON_AddLine( compile_write_err ); + return FALSE; + } + + } else { + + CON_AddLine( compile_arg_inval ); + } + + return TRUE; +} + + +// write packet parameter of action command in binary format to file ---------- +// +PRIVATE +int WriteActionPacketParam( FILE *fp ) +{ + ASSERT( fp != NULL ); + + int rc = TRUE; +/* + // read session and packet ids and fetch corresponding packet + int32 params[ 2 ]; + if ( AcFetchIntParams( 2, params ) ) { + + // fetch packet + NetPacketExternal* ext_gamepacket = (NetPacketExternal*) ALLOCMEM( RECORD_PACKET_SIZE ); + size_t psize = REC_FetchRemotePacket( ext_gamepacket, params[ 0 ], params[ 1 ] ); + + // write packet if valid + if ( psize > 0 ) { + if ( fwrite( ext_gamepacket, 1, psize, fp ) != psize ) { + CON_AddLine( compile_write_err ); + rc = FALSE; + } + } else { + CON_AddLine( compile_pkt_inval ); + rc = FALSE; + } + + FREEMEM( ext_gamepacket ); + + } else { + + CON_AddLine( compile_arg_inval ); + } +*/ + ASSERT( FALSE ); + + return rc; +} + + +// forward declaration -------------------------------------------------------- +// +PRIVATE +void ExecActionCommand( char *cstr ); + + +// write a scheduled command into the current compilation --------------------- +// +PRIVATE +int WriteScheduledCommand( FILE *fp ) +{ + ASSERT( fp != NULL ); + + // prevent recursive call (scheduling of schedule command) + static int scheduled_command_writing_active = FALSE; + if ( scheduled_command_writing_active ) { + CON_AddLine( invalid_arg ); + return FALSE; + } + scheduled_command_writing_active = TRUE; + + // parse delta time parameter + char *timeparam = strtok( NULL, " " ); + if ( timeparam == NULL ) { + CON_AddLine( arg_missing ); + return FALSE; + } + + char *errpart; + int timedelta = strtol( timeparam, &errpart, int_calc_base ); + if ( *errpart != 0 ) { + CON_AddLine( invalid_arg ); + return FALSE; + } + + // write delta time in little-endian format + timedelta = SWAP_32( timedelta ); + if ( fwrite( &timedelta, sizeof( timedelta ), 1, fp ) != 1 ) { + CON_AddLine( compile_write_err ); + return FALSE; + } + + // append scheduled command as parameter after scheduling prefix + ExecActionCommand( NULL ); + + scheduled_command_writing_active = FALSE; + return TRUE; +} + + +// write action command in binary format to file ------------------------------ +// +PRIVATE +int WriteActionCommand( FILE *fp, int actid ) +{ + ASSERT( fp != NULL ); + ASSERT( actid > ACM_SIGNATURE ); + + dword flags = action_commands[ actid ].flags; + int paranum = action_commands[ actid ].numparameters; + + // exit if command may not be compiled + if ( ( flags & ACF_COMPILE ) == 0 ) { + CON_AddLine( compile_non_comp ); + return TRUE; + } + + // check for demo inclusion + // (command will be substituted) + if ( flags & ACF_DEMOPARAM ) { + return IncludeDemoFile( fp ); + } + + // must be written in little-endian format + actid = SWAP_32( actid ); + + // write id of command + if ( fwrite( &actid, sizeof( actid ), 1, fp ) != 1 ) { + CON_AddLine( compile_write_err ); + return FALSE; + } + + if ( flags & ACF_INTPARAMS ) { + + // write int parameters to file + if ( !WriteActionIntParams( fp, paranum ) ) { + return FALSE; + } + + } else if ( flags & ACF_FLOATPARAMS ) { + + // write float parameters to file + if ( !WriteActionFloatParams( fp, paranum ) ) { + return FALSE; + } + + } else if ( flags & ACF_STRINGPARAM ) { + + // write string parameter to file + ASSERT( paranum == 1 ); + if ( !WriteActionStringParam( fp, flags ) ) { + return FALSE; + } + + } else if ( flags & ACF_PACKETPARAM ) { + + // write packet parameter to file + if ( !WriteActionPacketParam( fp ) ) { + return FALSE; + } + + } else if ( flags & ACF_SCHEDPARAM ) { + + // write scheduled command to file + if ( !WriteScheduledCommand( fp ) ) { + return FALSE; + } + } + + return TRUE; +} + + +// call action function corresponding to action command or compile it --------- +// +INLINE +void CallActionFunction( int actid ) +{ + ASSERT( actid > ACM_SIGNATURE ); + + if ( compile_script ) { + + // if fp is NULL write error occurred earlier on + if ( compile_fp != NULL ) { + + // write command to file but do not execute it + if ( !WriteActionCommand( compile_fp, actid ) ) { + // write error cleanup + fclose( compile_fp ); + compile_fp = NULL; + } + } + + } else { + + // call corresponding action function + ASSERT( action_commands[ actid ].func != NULL ); + (*action_commands[ actid ].func)(); + } +} + + +// lookup action command and execute it --------------------------------------- +// +PRIVATE +void ExecActionCommand( char *cstr ) +{ + // scan table + char *aspec = strtok( cstr, " " ); + int aid; + for ( aid = ACM_SIGNATURE + 1; ACMSTR( aid ) != NULL; aid++ ) { + + if ( strcmp( ACMSTR( aid ), aspec ) == 0 ) { + + dword flags = action_commands[ aid ].flags; + if ( ( action_commands[ aid ].func != NULL ) && + ( processing_batch || ( flags & ACF_DIRECT ) ) ) { + + CallActionFunction( aid ); + + } else { + + CON_AddLine( non_batch_use ); + } + break; + } + } + + if ( ACMSTR( aid ) == NULL ) { + + // no action command with specified name found + CON_AddLine( invalid_action ); + } +} + + +// exec action command (command prefixed with "ac.") -------------------------- +// +void ActionCommand( char *cstr ) +{ + ASSERT( cstr != NULL ); + + // exit if action commands currently not allowed + if ( preempt_action_commands ) { + CON_AddLine( action_preempted ); + return; + } + + char *bdot = cstr + ACMLEN( ACM_SIGNATURE ); + if ( *bdot != 0 ) { + + // look up command and execute it + ExecActionCommand( cstr ); + + } else { + + // no action specified after "ac." + CON_AddLine( no_action_found ); + } +} + + +// module registration function ----------------------------------------------- +// +REGISTER_MODULE( CON_ACT_SV ) +{ + // reset mapping table for class ids + int oldflag = SV_CLASS_MAP_TABLE_DISABLE_RESET; + SV_CLASS_MAP_TABLE_DISABLE_RESET = FALSE; + ResetClassMapTable(); + SV_CLASS_MAP_TABLE_DISABLE_RESET = oldflag; +} + + + |
