Script:Files:script/misc/objective manager.script
From Mod Wiki
void G_SetObjectiveManager( object o ); object mapObject_Base { void InitObjectives() { } void CompleteObjective( float index, entity p ) { } handle GetObjectiveMessage( float index ); void OnConstructionComplete( entity obj ) { } void OnDestructionComplete( entity obj ) { } void OnHackComplete( entity obj ) { } void OnMCPSpawned( entity obj ) { } void OnMCPDestroyed( entity obj, vector newLocation, vector newAngles ) { } void OnMCPDelivered( entity obj ) { } void OnShieldDeployed( entity obj, entity trigger ) { } void OnShieldDestroyedScud( entity trigger ) { } void OnMiningLaserDeployed( entity obj ) { } void OnMiningLaserConstructed( entity obj ) { } void OnTimeLimitHit() { } void RunBotMCPMapScript( float actionGroupOff, float actionGroupOn ) { } void OnCarryableItemStolen( string actionName ) { } void OnCarryableItemReturned( string actionName ) { } void OnSpawnCaptured( string actionName ) { } void OnSpawnLiberated( string actionName ) { } vector GetGDFBasePosition() { return g_vectorZero; } void ScudExploded( entity scud ) {} } object objectiveManager { void preinit(); void destroy(); void CountdownVO(); void OnMapStart(); void OnMapShutdown(); void OnLocalMapRestart(); void OnNetworkEvent(); void OnGameStateChange( float newState ); void OnWriteInitialReliableMessages( entity p ); void HandleCenterPrint(); void HandleObjectiveEntity(); void CompleteObjective( float index, entity p ); void SendObjectiveChangedEvent( entity ent, entity p, float index ); void SetObjectiveEntity( entity ent, float index ); void RefreshObjectiveEntity(); void OnConstructionComplete( entity obj ); void OnDestructionComplete( entity obj ); void OnHackComplete( entity obj ); void OnMCPSpawned( entity obj ); void OnMCPDestroyed( entity obj, vector newLocation, vector newAngles ); void OnMCPDelivered( entity obj ); void OnShieldDeployed( entity obj, entity trigger ); void OnShieldDestroyedScud( entity trigger ); void OnMiningLaserDeployed( entity obj ); void OnMiningLaserConstructed( entity obj ); void OnTimeLimitHit(); void RunBotMCPMapScript( float actionGroupOff, float actionGroupOn ); void OnCarryableItemStolen( string actionName ); void OnCarryableItemReturned( string actionName ); void OnSpawnCaptured( string actionName ); void OnSpawnLiberated( string actionName ); void PlaySound( string soundShader, object team ); void PlaySoundRanged( string soundShader, object team, vector org, float maxRange ); void PlaySoundForPlayer( string soundShader, entity p ); void OnNextObjectiveSet( object team, float objectiveIndex ); // initialize the limbo menu with objective information void InitObjectiveUI( float index, handle descriptionGDF, handle descriptionStrogg, handle miniDescriptionGDF, handle miniDescriptionStrogg, string materialGDF, string materialStrogg ); vector GetGDFBasePosition(); void ScudExploded( entity scud ); mapObject_Base mapObject; void PushCPrintString( string arg ); void PushCPrintHandle( handle h ); void CPrintEvent( handle h, object team ); void CPrintEventRanged( handle h, object team, vector org, float maxRange ); void SetupCPrintHUD( wstring text, float endTime ); float GetCountdownTime(); void PlayCountdownVO( string sound, float seconds ); string printArgs; float numPrintArgs; entity currentPrimaryObjective; float gameState; } objectiveManager objManager; void objectiveManager::preinit() { G_SetObjectiveManager( self ); } #define MIN2SEC( x ) ( x * 60 ) float objectiveManager::GetCountdownTime() { return sys.getMatchTimeRemaining() - 1; } void objectiveManager::CountdownVO() { sys.threadName( "CountdownThread" ); // need to wait for the time to be set in countdown mode sys.waitFrame(); // don't attempt to play all the sounds if warmup-time is really low if ( GetCountdownTime() < 6.5 ) { return; } while( GetCountdownTime() > MIN2SEC( 10 ) ) { sys.waitFrame(); } PlayCountdownVO( "snd_countdown_10m", MIN2SEC( 10 ) ); while( GetCountdownTime() > MIN2SEC( 5 ) ) { sys.waitFrame(); } PlayCountdownVO( "snd_countdown_5m", MIN2SEC( 5 ) ); while( GetCountdownTime() > MIN2SEC( 2 ) ) { sys.waitFrame(); } PlayCountdownVO( "snd_countdown_2m", MIN2SEC( 2 ) ); while( GetCountdownTime() > MIN2SEC( 1 ) ) { sys.waitFrame(); } PlayCountdownVO( "snd_countdown_1m", MIN2SEC( 1 ) ); while( GetCountdownTime() > 30 ) { sys.waitFrame(); } PlayCountdownVO( "snd_countdown_30s", 30 ); while( GetCountdownTime() > 10 ) { sys.waitFrame(); } PlayCountdownVO( "snd_countdown_10s", 10 ); while( GetCountdownTime() > 5 ) { sys.waitFrame(); } PlayCountdownVO( "snd_countdown_5s", 5 ); } void objectiveManager::OnMapStart() { delete mapObject; if ( sys.doClientSideStuff() ) { sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.successTextTime", 0.f ); } if ( !sys.isClient() ) { mapObject = createMapScript(); if ( mapObject == $null_entity ) { sys.error( "objectiveManager::OnMapStart No Map Script" ); } mapObject.InitObjectives(); } } void objectiveManager::OnMapShutdown() { delete mapObject; } void objectiveManager::OnLocalMapRestart() { entity worldspawn = sys.getEntity( "worldspawn" ); float count = worldspawn.entitiesOfCollection( "maprestartwatch" ); float i; for ( i = 0; i < count; i++ ) { entity ent = worldspawn.getBoundsCacheEntity( i ); ent.vOnLocalMapRestart(); } } void objectiveManager::OnGameStateChange( float newState ) { gameState = newState; // kill any previous countdowns sys.killThread( "CountdownThread" ); if ( newState == GS_COUNTDOWN || newState == GS_GAMEON ) { thread CountdownVO(); } if ( newState == GS_GAMEREVIEW ) { entity worldspawn = sys.getEntity( "worldspawn" ); float count = worldspawn.entitiesOfCollection( "gamereviewwatch" ); float cacheHandle = worldspawn.saveCachedEntities(); float i; for ( i = 0; i < count; i++ ) { entity ent = worldspawn.getSavedCacheEntity( cacheHandle, i ); ent.vOnEndGame(); } worldspawn.freeSavedCache( cacheHandle ); } } void objectiveManager::destroy() { OnMapShutdown(); } void objectiveManager::CompleteObjective( float index, entity p ) { if ( sys.isClient() ) { return; } logObjectiveCompletion( index ); // send a message out with the message if ( p == $null_entity ) { PushCPrintHandle( g_locStr_Someone ); } else { PushCPrintString( p.getUserName() ); } CPrintEvent( mapObject.GetObjectiveMessage( index ), $null ); mapObject.CompleteObjective( index, p ); } void objectiveManager::OnConstructionComplete( entity obj ) { if ( sys.isClient() ) { return; } mapObject.OnConstructionComplete( obj ); } void objectiveManager::OnDestructionComplete( entity obj ) { if ( sys.isClient() ) { return; } mapObject.OnDestructionComplete( obj ); } void objectiveManager::OnHackComplete( entity obj ) { if ( sys.isClient() ) { return; } mapObject.OnHackComplete( obj ); } void objectiveManager::OnMCPSpawned( entity obj ) { if ( sys.isClient() ) { return; } mapObject.OnMCPSpawned( obj ); } void objectiveManager::OnMCPDestroyed( entity obj, vector newLocation, vector newAngles ) { if ( sys.isClient() ) { return; } PlaySound( obj.getKey( "snd_vo_off_course_0_gdf" ), gdfTeam ); PlaySound( obj.getKey( "snd_vo_off_course_0_strogg" ), stroggTeam ); CPrintEvent( sys.localizeString( "maps/generic/mcp/destroyed" ), $null ); mapObject.OnMCPDestroyed( obj, newLocation, newAngles ); } void objectiveManager::OnMCPDelivered( entity obj ) { if ( sys.isClient() ) { return; } mapObject.OnMCPDelivered( obj ); } void objectiveManager::OnShieldDestroyedScud( entity trigger ) { if ( sys.isClient() ) { return; } mapObject.OnShieldDestroyedScud( trigger ); } void objectiveManager::OnShieldDeployed( entity obj, entity trigger ) { if ( sys.isClient() ) { return; } mapObject.OnShieldDeployed( obj, trigger ); } void objectiveManager::OnMiningLaserDeployed( entity obj ) { if ( sys.isClient() ) { return; } mapObject.OnMiningLaserDeployed( obj ); } void objectiveManager::OnMiningLaserConstructed( entity obj ) { if ( sys.isClient() ) { return; } mapObject.OnMiningLaserConstructed( obj ); } void objectiveManager::OnTimeLimitHit() { if ( sys.isClient() ) { return; } mapObject.OnTimeLimitHit(); } void objectiveManager::RunBotMCPMapScript( float actionGroupOff, float actionGroupOn ) { if ( sys.isClient() ) { return; } mapObject.RunBotMCPMapScript( actionGroupOff, actionGroupOn ); } void objectiveManager::OnCarryableItemStolen( string actionName ) { if ( sys.isClient() ) { return; } mapObject.OnCarryableItemStolen( actionName ); } void objectiveManager::OnCarryableItemReturned( string actionName ) { if ( sys.isClient() ) { return; } mapObject.OnCarryableItemReturned( actionName ); } void objectiveManager::OnSpawnCaptured( string actionName ) { if ( sys.isClient() ) { return; } mapObject.OnSpawnCaptured( actionName ); } void objectiveManager::OnSpawnLiberated( string actionName ) { if ( sys.isClient() ) { return; } mapObject.OnSpawnLiberated( actionName ); } void objectiveManager::PlaySound( string soundShader, object team ) { PlaySoundRanged( soundShader, team, vec3_origin, -1.f ); } void objectiveManager::PlaySoundRanged( string soundShader, object team, vector org, float maxRange ) { if ( sys.isClient() ) { // Gordon: this function really should only be called for things the client cannot predict return; } if ( soundShader == "" ) { return; } float shaderIndex = GetSoundShader( soundShader ); if ( shaderIndex == -1 ) { sys.warning( "objectiveManager::PlaySound - couldn't find shader for sound " + soundShader ); return; } entity p; if ( sys.isServer() ) { float rangeSqr = maxRange * maxRange; string message = "s " + shaderIndex; float maxClients = sys.getMaxClients(); float index; for ( index = 0; index < maxClients; index++ ) { p = sys.getClient( index ); if ( p == $null_entity ) { continue; } if ( team != $null ) { if ( team != p.getGameTeam() ) { continue; } } if ( maxRange > 0.f ) { if ( sys.vecLengthSquared( p.getWorldOrigin() - org ) > rangeSqr ) { continue; } } sendNetworkEvent( p, message ); } } p = sys.getLocalPlayer(); if ( p != $null_entity ) { if ( team == p.getGameTeam() || team == $null_entity ) { sys.startSoundDirect( soundShader, SND_PLAYER_VO ); } } } void objectiveManager::PlaySoundForPlayer( string soundShader, entity p ) { if ( sys.isClient() ) { // Gordon: this function really should only be called for things the client cannot predict return; } if ( soundShader == "" || p == $null_entity ) { return; } float index = GetSoundShader( soundShader ); if ( index == -1 ) { sys.warning( "objectiveManager::PlaySoundForPlayer: couldn't find shader for sound " + soundShader ); return; } if ( sys.getLocalPlayer() == p ) { sys.startSoundDirect( soundShader, SND_PLAYER_VO ); } else { sendNetworkEvent( p, "s " + index ); } } void objectiveManager::OnNextObjectiveSet( object team, float objectiveIndex ) { if( sys.doClientSideStuff() ) { sys.setGUIFloat( GUI_GLOBALS_HANDLE, "mapinfo.currentObjective", objectiveIndex ); sys.setGUIHandle( GUI_GLOBALS_HANDLE, "mapinfo.gdfCurrentObjective", objManager.getShortDescription( gdfTeam, objectiveIndex ) ); sys.setGUIHandle( GUI_GLOBALS_HANDLE, "mapinfo.stroggCurrentObjective", objManager.getShortDescription( stroggTeam, objectiveIndex ) ); } } void objectiveManager::HandleObjectiveEntity() { entity ent = sys.getEntityByID( sys.argv( 1 ) ); float index = sys.argvf( 2 ); G_SetPrimaryObjectiveIndex( index ); if ( currentPrimaryObjective != $null_entity ) { currentPrimaryObjective.vMakePrimaryObjective( false ); } currentPrimaryObjective = ent; if ( currentPrimaryObjective != $null_entity ) { currentPrimaryObjective.vMakePrimaryObjective( true ); } } void objectiveManager::HandleCenterPrint() { handle h = sys.stringToHandle( sys.argv( 1 ) ); float endTime = sys.argvf( 2 ); float index; float count = sys.argc() - 3; for ( index = 0; index < count; index++ ) { string ident = sys.strLeft( sys.argv( 3 + index ), 1 ); string value = sys.strSkip( sys.argv( 3 + index ), 1 ); if ( ident == "P" ) { // plain text, likely a player name sys.pushLocString( sys.toWStr( value ) ); continue; } if ( ident == "H" ) { // localisation handle sys.pushLocStringIndex( sys.stringToHandle( value ) ); continue; } } SetupCPrintHUD( sys.localizeStringIndexArgs( h ), endTime ); } void objectiveManager::OnNetworkEvent() { string message = sys.argv( 0 ); if ( message == "cp" ) { HandleCenterPrint(); return; } if ( message == "s" ) { sys.startSoundDirect( GetSoundShaderName( sys.argvf( 1 ) ), SND_PLAYER_VO ); return; } if ( message == "oe" ) { HandleObjectiveEntity(); return; } } void objectiveManager::InitObjectiveUI( float index, handle descriptionGDF, handle descriptionStrogg, handle miniDescriptionGDF, handle miniDescriptionStrogg, string materialGDF, string materialStrogg ) { if ( sys.getLocalPlayer() != $null_entity ) { sys.setGUIHandle( GUI_GLOBALS_HANDLE, "mapinfo.stroggObjective" + index, descriptionStrogg ); sys.setGUIHandle( GUI_GLOBALS_HANDLE, "mapinfo.gdfObjective" + index, descriptionGDF ); sys.setGUIString( GUI_GLOBALS_HANDLE, "mapinfo.stroggObjectiveMat" + index, materialStrogg ); sys.setGUIString( GUI_GLOBALS_HANDLE, "mapinfo.gdfObjectiveMat" + index, materialGDF ); } // tell the game what the short descriptions are objManager.setShortDescription( gdfTeam, index, miniDescriptionGDF ); objManager.setShortDescription( stroggTeam, index, miniDescriptionStrogg ); } vector objectiveManager::GetGDFBasePosition() { return mapObject.GetGDFBasePosition(); } void objectiveManager::SetupCPrintHUD( wstring text, float endTime ) { if ( sys.getLocalPlayer() != $null_entity ) { sys.setGUIFloat( GUI_GLOBALS_HANDLE, "gameHud.successTextTime", endTime ); sys.setGUIWString( GUI_GLOBALS_HANDLE, "gameHud.successText", text ); } } void objectiveManager::PushCPrintString( string arg ) { if ( sys.isClient() ) { return; } numPrintArgs = numPrintArgs + 1; printArgs = printArgs + " \"P" + arg + "\""; } void objectiveManager::PushCPrintHandle( handle h ) { if ( sys.isClient() ) { return; } numPrintArgs = numPrintArgs + 1; printArgs = printArgs + " H" + sys.handleToString( h ); } void objectiveManager::RefreshObjectiveEntity() { entity old = currentPrimaryObjective; float oldIndex = g_primaryObjectiveIndex; SetObjectiveEntity( $null_entity, -1 ); SetObjectiveEntity( old, oldIndex ); } void objectiveManager::SetObjectiveEntity( entity ent, float index ) { if ( sys.isClient() ) { return; } if ( currentPrimaryObjective == ent ) { return; } SendObjectiveChangedEvent( ent, $null_entity, index ); } void objectiveManager::SendObjectiveChangedEvent( entity ent, entity p, float index ) { string spawnId; if ( ent == $null_entity ) { spawnId = "0"; } else { spawnId = ent.getSpawnID(); } string message = "oe " + spawnId + " " + index; if ( sys.isServer() ) { sendNetworkEvent( p, message ); } if ( p == $null_entity ) { sys.setActionCommand( message ); OnNetworkEvent(); } } void objectiveManager::CPrintEvent( handle h, object team ) { CPrintEventRanged( h, team, vec3_origin, -1.f ); } void objectiveManager::CPrintEventRanged( handle h, object team, vector org, float maxRange ) { if ( sys.isClient() ) { return; } float endTime = ( sys.getTime() + 10 ) * 1000; string message = "cp\"" + sys.handleToString( h ) + "\"" + endTime + printArgs; // Gordon: printargs should always be last, as it is variable length numPrintArgs = 0.f; printArgs = ""; if ( sys.isServer() ) { float rangeSqr = maxRange * maxRange; float maxClients = sys.getMaxClients(); float index; for ( index = 0; index < maxClients; index++ ) { entity p = sys.getClient( index ); if ( p == $null_entity ) { continue; } if ( team != $null ) { if ( team != p.getGameTeam() ) { continue; } } if ( maxRange > 0.f ) { if ( sys.vecLengthSquared( p.getWorldOrigin() - org ) > rangeSqr ) { continue; } } sendNetworkEvent( p, message ); } } // this is solely for the benefit of devmap entity local = sys.getLocalPlayer(); if ( local != $null_entity ) { if ( team == $null || local.getGameTeam() == team ) { sys.setActionCommand( message ); OnNetworkEvent(); } } } void objectiveManager::ScudExploded( entity scud ) { if ( mapObject != $null_entity ) { entity team = scud.getGameTeam(); mapObject.ScudExploded( scud ); } } void objectiveManager::OnWriteInitialReliableMessages( entity p ) { if ( !p.isLocalPlayer() ) { SendObjectiveChangedEvent( currentPrimaryObjective, p, g_primaryObjectiveIndex ); } } void objectiveManager::PlayCountdownVO( string sound, float seconds ) { if ( GetCountdownTime() > seconds - 2.f ) { PlaySound( gdfTeam.getKey( sound ), gdfTeam ); PlaySound( stroggTeam.getKey( sound ), stroggTeam ); } } void G_SetObjectiveManager( object o ) { objManager = o; } handle mapObject_Base::GetObjectiveMessage( float index ) { return sys.localizeString( "maps/obj/complete_obj_generic" ); } // Gordon: putting this here sucks void team_base::PlayIntelRepairedMessage() { objManager.PlaySound( getKey( "snd_intel_repaired" ), self ); } void team_base::PlayIntelDamagedMessage() { objManager.PlaySound( getKey( "snd_intel_damaged" ), self ); }