diff --git a/_jump.gsc b/iw4/scripts/mp/_jump.gsc similarity index 100% rename from _jump.gsc rename to iw4/scripts/mp/_jump.gsc diff --git a/iw5/scripts/mp/_jump.gsc b/iw5/scripts/mp/_jump.gsc new file mode 100644 index 0000000..98a5a6e --- /dev/null +++ b/iw5/scripts/mp/_jump.gsc @@ -0,0 +1,121 @@ +// Call Of Duty: Modern Warfare 3 + +#ifdef IW5 +#define TOOL +#endif + +#define _UTILITY_DEBUG +#inline scripts\mp\_utility; + +GENERIC_INIT; + +onPlayerConnect() +{ + while ( true ) + { + level waittill( "connected", player ); + + waittillframeend; + + BOT_CHK( player ); + +#if defined(TOOL) + player notifyOnPlayerCommand( "save_pos", "+reload" ); + player notifyOnPlayerCommand( "load_saved_pos", "+activate" ); +#else + PLAYER_NOTIFY_CMD( player, "save_pos", "+reload" ); + PLAYER_NOTIFY_CMD( player, "load_saved_pos", "+activate" ); +#endif + + player thread jumper(); + player thread displaySpeed(); + } +} + +displaySpeed() +{ + GENERIC_COROUTINE_END; + + self.speed_text = maps\mp\gametypes\_hud_util::createFontString( "hudsmall" , 1 ); + self.speed_text maps\mp\gametypes\_hud_util::setPoint( "TOP", "TOP", -2, -2 ); + self.speed_text.hideWhenInMenu = true; + self.speed_text.label = &""; + + self.last_speed_sample = 0; + + while ( true ) + { + player_speed = distance( ZERO_VEC3, self getvelocity() ); + current_speed = int( player_speed ); + + if ( self.last_speed_sample == current_speed ) + { + // White + self.speed_text.color = ( 255, 255, 255 ); + } + else if ( self.last_speed_sample > current_speed ) + { + // Slowing down (Red) + self.speed_text.color = ( 255, 0, 0 ); + } + else + { + // Speeding up (Green) + self.speed_text.color = ( 0, 255, 0 ); + } + + self.last_speed_sample = current_speed; + + self.speed_text setValue( current_speed ); + wait( 0.1 ); + } +} + +canInteract( player ) +{ + return maps\mp\_utility::isReallyAlive( player ); +} + +canSave( player ) +{ + if ( !player isOnGround() ) + { + player iPrintLn( "Cannot save while in the air\n" ); + return false; + } + + return true; +} + +jumper() +{ + GENERIC_COROUTINE_END; + + self.jumper_pos = ZERO_VEC3; + self.jumper_angles = ZERO_VEC3; + self.jumper_pos_num = 0; + while ( true ) + { + msg = self common_scripts\utility::waittill_any_return( "save_pos", "load_saved_pos" ); + + if ( !isDefined( msg ) ) + { + continue; + } + + if ( msg == "save_pos" && canInteract( self ) && canSave( self ) ) + { + self.jumper_pos = self.origin; + self.jumper_angles = self getPlayerAngles(); + self.jumper_pos_num += 1; + self iPrintLn( "saved pos ", self.jumper_pos_num, "\n" ); + } + else if ( msg == "load_saved_pos" && canInteract( self ) ) + { + self setOrigin( self.jumper_pos ); + self setVelocity( ZERO_VEC3 ); + self setPlayerAngles( self.jumper_angles ); + self iPrintLn( "loaded pos ", self.jumper_pos_num, "\n" ); + } + } +} diff --git a/iw5/scripts/mp/_utility.gsh b/iw5/scripts/mp/_utility.gsh new file mode 100644 index 0000000..f3f99fd --- /dev/null +++ b/iw5/scripts/mp/_utility.gsh @@ -0,0 +1,135 @@ +/* Meaning of some macros: +* T4: Plutonium +* IW4MP: Multiplayer only +* IW4SP: Singleplayer only +* IW4: Generic +* IW5x: Reserved +* IW5: Plutonium +* TOOL: GSC-Tool mode +* Usage with a C++20 (or a later standard) compliant preprocessor may be required. +* /Zc:preprocessor is required with the MSVC compiler. +*/ + +#ifdef IW4 + #ifndef IW4MP + #define IW4MP + #endif + #ifndef IW4SP + #define IW4SP + #endif +#endif + +#define TRUE 1 +#define FALSE 0 + +#define ZERO_VEC3 ( 0, 0, 0 ) + +#define TEMP_DVAR "temp_dvar_util" + +#define GENERIC_INIT \ + init() \ + { \ + thread onPlayerConnect(); \ + } + +#define GENERIC_COROUTINE_END \ + level endon( "game_ended" ); \ + self endon( "disconnect" ); + +/* IW4x MP has printConsole Built-in. __VA_OPT__ requires C++20 compliant preprocessor */ +/* Do not use the + to concatenate strings, let the GSC VM do it for you */ +/* Other clients will have print available */ +#if defined(IW4MP) + #define PRINT_FUNC printConsole +#else + #define PRINT_FUNC print +#endif + +#if !defined(TOOL) + PRINT_FUNC( format __VA_OPT__(,) __VA_ARGS__ ) +#endif + +#ifdef _UTILITY_DEBUG +#define _VERIFY( cond, msg ) \ + assertEx(cond, msg) + +#define DEBUG_PRINT(msg) \ + PRINT_FUNC(msg) +#else +/* The following are "empty" defines with gsc-tool */ +#define _VERIFY(cond, msg) +#define DEBUG_PRINT(msg) +#endif + +/* Use Cbuf. Should use the + to concatenate strings before using this */ +#if defined(IW5) || defined(IW5x) || defined(T4) + #define CBUF_ADD_TEXT(format) cmdExec( format ) +#elif defined(IW6x) || defined(S1x) + #define CBUF_ADD_TEXT(format) executeCommand( format ) +#elif defined(IW4MP) + #define CBUF_ADD_TEXT(format) exec( format ) +#elif defined(IW4SP) + #define CBUF_ADD_TEXT(format) addDebugCommand( format ) +#endif + +#if defined(IW4MP) || defined(IW4SP) || defined(IW5) || defined(IW5x) || defined(IW6x) || defined(S1x) + #define FLOAT(num) float( num ) +#else + #define FLOAT(num) getDvarFloat( TEMP_DVAR, 0.0 ) +#endif + +#if defined(IW4MP) + #define NOCLIP(ent) ent noclip() +#else /* All clients should have it but require the following */ + #define NOCLIP(ent) \ + setDvar( "sv_cheats", 1 ); \ + ent noclip(); \ + setDvar( "sv_cheats", 0 ); +#endif + +#if defined(IW4MP) + #define UFO(ent) ent ufo() +#else /* All clients should have it but require the following */ + #define UFO(ent) \ + setDvar( "sv_cheats", 1 ); \ + ent ufo(); \ + setDvar( "sv_cheats", 0 ); +#endif + +#define WAIT_CNT(ent) level waittill ( "connected", ent ) + +#define WAIT_END(ent, msg) ent waittillmatch( msg, "end" ) + +/* defined in common_scripts\utility */ +#if !defined(TOOL) + #define WAIT_ANY_RET(ent, ...) ent waittill_any_return( __VA_ARGS__ ) +#endif + +#if !defined(TOOL) +#define PLAYER_NOTIFY_CMD(ent, str, action) ent notifyOnPlayerCommand( str, action ) +#endif + +/* Tweak as necessary. Can be return, continue or break */ +#define CHK_ACTION continue + +#if (defined(IW4MP) || defined(IW5x) || defined(IW5)) && !defined(TOOL) +#define BOT_CHK(ent) \ + if ( ent isTestClient() ) \ + { \ + DEBUG_PRINT( ent.name + " is a bot\n" ); \ + CHK_ACTION; \ + } +#else /* Valid for other clients */ +#define BOT_CHK(ent) \ + if ( isDefined( ent.pers["isBot"] ) && ent.pers["isBot"] ) \ + { \ + DEBUG_PRINT( ent.name + " is a bot\n" ); \ + CHK_ACTION; \ + } +#endif + +#define DEFINE_CHK(x) \ + if ( !isDefined( (x) ) ) \ + { \ + CHK_ACTION; \ + }