cod4-sdk/raw/maps/_autosave.gsc
2008-01-19 00:00:00 +00:00

500 lines
11 KiB
Text

#include maps\_utility;
#include common_scripts\utility;
main()
{
level.lastAutoSaveTime = 0;
flag_init( "game_saving" );
flag_init( "can_save" );
flag_set( "can_save" );
}
getDescription()
{
return( &"AUTOSAVE_AUTOSAVE" );
}
getnames( num )
{
if ( num == 0 )
savedescription = &"AUTOSAVE_GAME";
else
savedescription = &"AUTOSAVE_NOGAME";
return savedescription;
}
beginningOfLevelSave()
{
// Wait for introscreen to finish
level waittill( "finished final intro screen fadein" );
if ( level.missionfailed )
return;
if ( maps\_arcademode::arcademode_complete() )
return;
if ( flag( "game_saving" ) )
return;
flag_set( "game_saving" );
imagename = "levelshots / autosave / autosave_" + level.script + "start";
// "levelstart" is recognized by the saveGame command as a special save game
// if( getdvar("credits") != 1 ) // no start game autosave on credits map. Res
saveGame( "levelstart", &"AUTOSAVE_LEVELSTART", imagename, true );
setDvar( "ui_grenade_death", "0" );
println( "Saving level start saved game" );
flag_clear( "game_saving" );
}
trigger_autosave( trigger )
{
if ( !isdefined( trigger.script_autosave ) )
trigger.script_autosave = 0;
autosaves_think( trigger );
}
autosaves_think( trigger )
{
savedescription = getnames( trigger.script_autosave );
if ( !( isdefined( savedescription ) ) )
{
println( "autosave", self.script_autosave, " with no save description in _autosave.gsc!" );
return;
}
trigger waittill( "trigger" );
num = trigger.script_autosave;
imagename = "levelshots / autosave / autosave_" + level.script + num;
tryAutoSave( num, savedescription, imagename );
thread maps\_quotes::setDeadQuote();
trigger delete();
}
autoSaveNameThink( trigger )
{
trigger waittill( "trigger" );
if ( isdefined( level.customautosavecheck ) )
if ( ![[ level.customautosavecheck ]]() )
return;
name = trigger.script_autosavename;
maps\_utility::autosave_by_name( name );
trigger delete();
}
trigger_autosave_immediate( trigger )
{
trigger waittill( "trigger" );
// saveId = saveGameNoCommit( 1, &"AUTOSAVE_LEVELSTART", "autosave_image" );
// commitSave( saveId );
}
AutoSavePrint( msg, msg2 )
{
/#
if ( getdvar( "scr_autosave_debug" ) == "" )
setdvar( "scr_autosave_debug", "0" );
if ( getdebugdvarint( "scr_autosave_debug" ) == 1 )
{
if ( isdefined( msg2 ) )
iprintln( msg + " [ localized description ]" );
else
iprintln( msg );
return;
}
#/
if ( isdefined( msg2 ) )
println( msg, msg2 );
else
println( msg );
}
autosave_timeout( timeout )
{
level endon( "trying_new_autosave" );
level endon( "autosave_complete" );
wait( timeout );
flag_clear( "game_saving" );
level notify( "autosave_timeout" );
}
_autosave_game_now( suppress_print )
{
if ( flag( "game_saving" ) )
return false;
if ( maps\_arcademode::arcademode_complete() )
return false;
if ( !isalive( level.player ) )
return false;
filename = "save_now";
descriptionString = getDescription();
if ( isdefined( suppress_print ) )
saveId = saveGameNoCommit( filename, descriptionString, "$default", true );
else
saveId = saveGameNoCommit( filename, descriptionString );
wait( 0.05 ); // code request
if ( isSaveRecentlyLoaded() )
{
level.lastAutoSaveTime = getTime();
return false;
}
/# AutoSavePrint( "Saving game " + filename + " with desc ", descriptionString ); #/
if ( saveId < 0 )
{
/# AutoSavePrint( "Savegame failed - save error.: " + filename + " with desc ", descriptionString ); #/
return false;
}
if ( !try_to_autosave_now() )
{
return false;
}
flag_set( "game_saving" );
wait 2;
// are we still healthy 2 seconds later? k save then
if ( try_to_autosave_now() )
{
if ( !isdefined( suppress_print ) )
thread maps\_arcademode::arcademode_checkpoint_print();
commitSave( saveId );
setDvar( "ui_grenade_death", "0" );
}
flag_clear( "game_saving" );
return true;
}
autosave_now_trigger( trigger )
{
trigger waittill( "trigger" );
autosave_now();
}
try_to_autosave_now()
{
if ( !issavesuccessful() )
return false;
if ( !autoSaveHealthCheck() )
return false;
if ( !flag( "can_save" ) )
{
/# AutoSavePrint( "Can_save flag was clear" ); #/
return false;
}
return true;
}
tryAutoSave( filename, description, image, timeout )
{
level.player endon( "death" );
level notify( "trying_new_autosave" );
if ( flag( "game_saving" ) )
return false;
time1 = 1.25;
time2 = 1.25;
if ( isdefined( timeout ) && timeout < time1 + time2 )
{
assertmsg( "Warning, tried to do an autosave_or_timeout with a time less than " + ( time1 + time2 ) );
}
flag_set( "game_saving" );
descriptionString = getDescription();
start_save_time = gettime();
while ( 1 )
{
if ( autoSaveCheck() )
{
saveId = saveGameNoCommit( filename, descriptionString, image );
/# AutoSavePrint( "Saving game " + filename + " with desc ", descriptionString ); #/
if ( saveId < 0 )
{
/# AutoSavePrint( "Savegame failed - save error.: " + filename + " with desc ", descriptionString ); #/
break;
}
wait( 0.05 ); // code request
if ( isSaveRecentlyLoaded() )
{
level.lastAutoSaveTime = getTime();
break;
}
wait time1;
if ( !autoSaveCheck() )
{
/# AutoSavePrint( "Savegame invalid: 1.25 second check failed" ); #/
continue;
}
wait time2;
if ( !autoSaveCheck_not_picky() )
{
/# AutoSavePrint( "Savegame invalid: 2.5 second check failed" ); #/
continue;
}
if ( isdefined( timeout ) )
{
if ( gettime() > start_save_time + timeout * 1000 )
break;
}
if ( !flag( "can_save" ) )
{
/# AutoSavePrint( "Can_save flag was clear" ); #/
break;
}
thread maps\_arcademode::arcademode_checkpoint_print();
commitSave( saveId );
level.lastSaveTime = getTime();
setDvar( "ui_grenade_death", "0" );
break;
}
wait 0.25;
}
flag_clear( "game_saving" );
return true;
}
autoSaveCheck_not_picky()
{
return autoSaveCheck( false );
}
autoSaveCheck( doPickyChecks )
{
if ( isdefined( level.special_autosavecondition ) && ![[ level.special_autosavecondition ]]() )
return false;
if ( level.missionfailed )
return false;
if ( maps\_arcademode::arcademode_complete() )
return false;
if ( !isdefined( doPickyChecks ) )
doPickyChecks = true;
// health check
if ( !autoSaveHealthCheck() )
return false;
// ammo check
if ( doPickyChecks && !autoSaveAmmoCheck() )
return false;
// ai / tank threat check
if ( !autoSaveThreatCheck( doPickyChecks ) )
return false;
// player state check
if ( !autoSavePlayerCheck( doPickyChecks ) )
return false;
// safe save check for level specific gameplay conditions
if ( isdefined( level.savehere ) && !level.savehere )
return false;
// safe save check for level specific gameplay conditions
if ( isdefined( level.canSave ) && !level.canSave )
return false;
// save was unsuccessful for internal reasons, such as lack of memory
if ( !issavesuccessful() )
{
AutoSavePrint( "autosave failed: save call was unsuccessful" );
return false;
}
return true;
}
autoSavePlayerCheck( doPickyChecks )
{
if ( level.script == "ac130" )
return true;
if ( level.player isMeleeing() && doPickyChecks )
{
AutoSavePrint( "autosave failed:player is meleeing" );
return false;
}
if ( level.player isThrowingGrenade() && doPickyChecks )
{
AutoSavePrint( "autosave failed:player is throwing a grenade" );
return false;
}
if ( level.player isFiring() && doPickyChecks )
{
AutoSavePrint( "autosave failed:player is firing" );
return false;
}
if ( isdefined( level.player.shellshocked ) && level.player.shellshocked )
{
AutoSavePrint( "autosave failed:player is in shellshock" );
return false;
}
return true;
}
autoSaveAmmoCheck()
{
if ( level.script == "ac130" )
return true;
weapons = level.player GetWeaponsListPrimaries();
for ( idx = 0; idx < weapons.size; idx++ )
{
fraction = level.player GetFractionMaxAmmo( weapons[ idx ] );
if ( fraction > 0.1 )
return( true );
}
AutoSavePrint( "autosave failed: ammo too low" );
return( false );
}
autoSaveHealthCheck()
{
if ( level.script == "ac130" )
return true;
healthFraction = level.player.health / level.player.maxhealth;
if ( healthFraction < 0.5 )
{
/# AutoSavePrint( "autosave failed: health too low" ); #/
return false;
}
if ( flag( "_radiation_poisoning" ) )
{
/# AutoSavePrint( "autosave failed: player has radiation sickness" ); #/
return false;
}
if ( flag( "player_has_red_flashing_overlay" ) )
{
/# AutoSavePrint( "autosave failed: player has red flashing overlay" ); #/
return false;
}
return true;
}
autoSaveThreatCheck( doPickyChecks )
{
if ( level.script == "ac130" )
return true;
enemies = getaispeciesarray( "axis", "all" );
for ( i = 0; i < enemies.size; i++ )
{
if ( !isdefined( enemies[ i ].enemy ) )
continue;
if ( enemies[ i ].enemy != level.player )
continue;
if ( enemies[ i ].type == "dog" )
{
if ( distance( enemies[ i ].origin, level.player.origin ) < 384 )
{
/# AutoSavePrint( "autosave failed: Dog near player" ); #/
return( false );
}
continue;
}
// recently shot at the player
if ( enemies[ i ].a.lastShootTime > gettime() - 500 )
{
if ( doPickyChecks || enemies[ i ] animscripts\utility::canShootEnemy() )
{
/# AutoSavePrint( "autosave failed: AI firing on player" ); #/
return( false );
}
}
if ( enemies[ i ].a.alertness == "aiming" && enemies[ i ] animscripts\utility::canShootEnemy() )
{
/# AutoSavePrint( "autosave failed: AI aiming at player" ); #/
return( false );
}
// is trying to melee the player
if ( isdefined( enemies[ i ].a.personImMeleeing ) && enemies[ i ].a.personImMeleeing == level.player )
{
/# AutoSavePrint( "autosave failed: AI meleeing player" ); #/
return( false );
}
}
if ( player_is_near_live_grenade() )
return false;
vehicles = getentarray( "destructible", "classname" );
for ( i = 0; i < vehicles.size; i++ )
{
if ( !isDefined( vehicles[i].healthDrain ) )
continue;
if ( distance( vehicles[i].origin, level.player.origin ) < 400 )// grenade radius is 220
{
/# AutoSavePrint( "autosave failed: burning car too close to player" ); #/
return( false );
}
}
return( true );
}