diff --git a/Resources/Scripts/oolite-contracts-parcels.js b/Resources/Scripts/oolite-contracts-parcels.js index df7a93a2..623e6efe 100644 --- a/Resources/Scripts/oolite-contracts-parcels.js +++ b/Resources/Scripts/oolite-contracts-parcels.js @@ -259,7 +259,8 @@ this._parcelContractsDisplay = function(summary) { { mission.runScreen({titleKey: "oolite-contracts-parcels-none-available-title", messageKey: "oolite-contracts-parcels-none-available-message", - allowInterrupt: true }); + allowInterrupt: true, + exitScreen: "GUI_SCREEN_INTERFACES"}); // no callback, just exits contracts system return; } @@ -362,6 +363,7 @@ this._parcelContractSummaryPage = function() var missionConfig = {titleKey: "oolite-contracts-parcels-title-summary", message: headline, allowInterrupt: true, + exitScreen: "GUI_SCREEN_INTERFACES", choices: options, initialChoicesKey: initialChoice}; if (this.$parcelSummaryPageBackground != "") { @@ -474,6 +476,7 @@ this._parcelContractSinglePage = function() title: title, message: message, allowInterrupt: true, + exitScreen: "GUI_SCREEN_INTERFACES", backgroundSpecial: backgroundSpecial, choices: options, initialChoicesKey: this.$lastChoice diff --git a/src/Core/Entities/PlayerEntity.h b/src/Core/Entities/PlayerEntity.h index a33e0b23..681822ff 100644 --- a/src/Core/Entities/PlayerEntity.h +++ b/src/Core/Entities/PlayerEntity.h @@ -269,6 +269,7 @@ typedef enum NSString *missionChoice; BOOL _missionWithCallback; BOOL _missionAllowInterrupt; + OOGUIScreenID _missionExitScreen; NSString *specialCargo; @@ -829,7 +830,7 @@ typedef enum - (void) setMissionBackgroundDescriptor:(NSDictionary *)descriptor; - (OOGUIBackgroundSpecial) missionBackgroundSpecial; - (void) setMissionBackgroundSpecial:(NSString *)special; - +- (void) setMissionExitScreen:(OOGUIScreenID)screen; // Nasty hack to keep background textures around while on equip screens. - (NSDictionary *) equipScreenBackgroundDescriptor; diff --git a/src/Core/Entities/PlayerEntity.m b/src/Core/Entities/PlayerEntity.m index 0535f3db..6f51112e 100644 --- a/src/Core/Entities/PlayerEntity.m +++ b/src/Core/Entities/PlayerEntity.m @@ -9102,6 +9102,12 @@ static NSString *last_outfitting_key=nil; } +- (void) setMissionExitScreen:(OOGUIScreenID)screen +{ + _missionExitScreen = screen; +} + + - (NSDictionary *) equipScreenBackgroundDescriptor { return _equipScreenBackgroundDescriptor; diff --git a/src/Core/Entities/PlayerEntityControls.m b/src/Core/Entities/PlayerEntityControls.m index 791edf3f..886c1038 100644 --- a/src/Core/Entities/PlayerEntityControls.m +++ b/src/Core/Entities/PlayerEntityControls.m @@ -144,6 +144,7 @@ static NSTimeInterval time_last_frame; - (void) pollDockedControls:(double) delta_t; - (void) pollDemoControls:(double) delta_t; - (void) handleMissionCallback; +- (void) setGuiToMissionEndScreen; - (void) switchToThisView:(OOViewID)viewDirection; - (void) switchToThisView:(OOViewID)viewDirection andProcessWeaponFacing:(BOOL)processWeaponFacing; - (void) switchToThisView:(OOViewID)viewDirection fromView:(OOViewID)oldViewDirection andProcessWeaponFacing:(BOOL)processWeaponFacing justNotify:(BOOL)justNotify; @@ -3518,7 +3519,18 @@ static BOOL autopilot_pause; spacePressed = YES; } else + { spacePressed = NO; + if (_missionAllowInterrupt) + { + [self pollGuiScreenControls]; + if (gui_screen != GUI_SCREEN_MISSION) + { + [UNIVERSE removeDemoShips]; + [self endMissionScreenAndNoteOpportunity]; + } + } + } } else { @@ -3565,7 +3577,7 @@ static BOOL autopilot_pause; [UNIVERSE removeDemoShips]; [[UNIVERSE gui] clearBackground]; - [self setGuiToStatusScreen]; // need this to find out if we call a new mission screen inside callback. + [self setGuiToMissionEndScreen]; // need this to find out if we call a new mission screen inside callback. if ([self status] != STATUS_DOCKED) [self switchToThisView:VIEW_FORWARD]; @@ -3583,13 +3595,82 @@ static BOOL autopilot_pause; { if (gui_screen != GUI_SCREEN_MISSION) // did we call a new mission screen inside callback? { - [self setGuiToStatusScreen]; // if not, update status screen with callback changes, if any. + [self setGuiToMissionEndScreen]; // if not, update status screen with callback changes, if any. [self endMissionScreenAndNoteOpportunity]; // missionScreenEnded, plus opportunity events. } } } +- (void) setGuiToMissionEndScreen +{ + if ([self status] != STATUS_DOCKED) + { + // this setting is only applied when not docked + [self setGuiToStatusScreen]; + return; + } + switch (_missionExitScreen) + { + case GUI_SCREEN_MANIFEST: + [self noteGUIWillChangeTo:GUI_SCREEN_MANIFEST]; + [self setGuiToManifestScreen]; + break; + case GUI_SCREEN_EQUIP_SHIP: + [self noteGUIWillChangeTo:GUI_SCREEN_EQUIP_SHIP]; + [self setGuiToEquipShipScreen:0]; + break; + case GUI_SCREEN_SHIPYARD: + if ([dockedStation hasShipyard]) + { + [self noteGUIWillChangeTo:GUI_SCREEN_SHIPYARD]; + [self setGuiToShipyardScreen:0]; + [[UNIVERSE gui] setSelectedRow:GUI_ROW_SHIPYARD_START]; + [self showShipyardInfoForSelection]; + } + else + { + // that doesn't work here + [self setGuiToStatusScreen]; + } + break; + case GUI_SCREEN_SHORT_RANGE_CHART: + [self setGuiToShortRangeChartScreen]; + break; + case GUI_SCREEN_LONG_RANGE_CHART: + [self setGuiToLongRangeChartScreen]; + break; + case GUI_SCREEN_SYSTEM_DATA: + [self noteGUIWillChangeTo:GUI_SCREEN_SYSTEM_DATA]; + [self setGuiToSystemDataScreen]; + break; + case GUI_SCREEN_MARKET: + [self noteGUIWillChangeTo:GUI_SCREEN_MARKET]; + [self setGuiToMarketScreen]; + [[UNIVERSE gui] setSelectedRow:GUI_ROW_MARKET_START]; + break; + case GUI_SCREEN_CONTRACTS: + if (dockedStation == [UNIVERSE station] && [self hasHyperspaceMotor]) + { + [self setGuiToContractsScreen]; + [[UNIVERSE gui] setSelectedRow:GUI_ROW_PASSENGERS_START]; + } + else + { + // can't get to contracts screen from here + [self setGuiToStatusScreen]; + } + break; + case GUI_SCREEN_INTERFACES: + [self setGuiToInterfacesScreen:0]; + break; + case GUI_SCREEN_STATUS: + default: // invalid screen specifications + [self setGuiToStatusScreen]; + } +} + + - (void) switchToThisView:(OOViewID)viewDirection { [self switchToThisView:viewDirection andProcessWeaponFacing:YES]; diff --git a/src/Core/Entities/PlayerEntityLegacyScriptEngine.m b/src/Core/Entities/PlayerEntityLegacyScriptEngine.m index 1aba55ea..790cb79a 100644 --- a/src/Core/Entities/PlayerEntityLegacyScriptEngine.m +++ b/src/Core/Entities/PlayerEntityLegacyScriptEngine.m @@ -2345,6 +2345,8 @@ static int scriptRandomSeed = -1; // ensure proper random function // reset special background as legacy scripts can't use it, and this // is only called by legacy scripts [self setMissionBackgroundSpecial:nil]; + // likewise exit screen target + [self setMissionExitScreen:GUI_SCREEN_STATUS]; [self setGuiToMissionScreenWithCallback:NO]; } diff --git a/src/Core/Scripting/OOJSMission.m b/src/Core/Scripting/OOJSMission.m index f46f9b66..772e9bb4 100644 --- a/src/Core/Scripting/OOJSMission.m +++ b/src/Core/Scripting/OOJSMission.m @@ -26,6 +26,7 @@ MA 02110-1301, USA. #import "OOJSMission.h" #import "OOJavaScriptEngine.h" #import "OOJSScript.h" +#import "OOConstToJSString.h" #import "OOJSPlayer.h" #import "PlayerEntityScriptMethods.h" @@ -543,6 +544,15 @@ static JSBool MissionRunScreen(JSContext *context, uintN argc, jsval *vp) JS_ValueToBoolean(context, value, &allowInterrupt); } + if (JS_GetProperty(context, params, "exitScreen", &value) && !JSVAL_IS_VOID(value)) + { + [player setMissionExitScreen:OOGUIScreenIDFromJSValue(context, value)]; + } + else + { + [player setMissionExitScreen:GUI_SCREEN_STATUS]; + } + // Start the mission screen. sCallbackFunction = function; [player setGuiToMissionScreenWithCallback:!JSVAL_IS_NULL(sCallbackFunction)];