Changes to Docking Clearance functionality (Feature Request #4327):

* Now works at all stations, not just main stations
* Player ships get placed into a 'docking queue' when requesting clearance
  * Station notifies player when queue-slot expires and gives chance to extend
  * Player can cancel docking-request
* Stations not requiring docking clearance now respond with an appropriate message



git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@1790 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
Michael Werle 2008-10-08 06:58:32 +00:00
parent 18dd2b810e
commit addc42eb68
5 changed files with 232 additions and 49 deletions

View File

@ -1006,20 +1006,26 @@
"oxp-is-incompatible" = "\t“%@” is incompatible with version %@ of Oolite."; "oxp-is-incompatible" = "\t“%@” is incompatible with version %@ of Oolite.";
// Space station docking clearance // Space station docking clearance
"please-wait-until-all-ships-have-completed-their-approach" "please-wait-until-d-ships-have-completed-their-approach"
= ( = (
"Please wait until all ships have completed their approach.", "Please wait until all ships have completed their approach. Your queue position is %d",
"We have inbound traffic, commander. Please stand by.", "We have inbound traffic, commander. Please stand by. You queue position is %d.",
"We cannot clear you for docking due to prioritized incoming traffic. Please retry for clearance in a few minutes", "We cannot clear you for docking due to prioritized incoming traffic. Your queue position is %d",
"We have ships on approach to %H station. Please hold for clearance." "We have ships on approach to %H station. Please hold for clearance."
); );
"please-wait-until-launching-ships-have-cleared-H-station" "please-wait-until-d-launching-ships-have-cleared-H-station"
= ( = (
"Please wait until launching ships have cleared %H Station.", "Please wait until launching ships have cleared %H Station. Your queue position is %d.",
"We have outbound traffic, commander. Please stand by.", "We have outbound traffic, Commander. Please stand by.",
"Clearance cannot be granted at this moment, due to prioritized outgoing traffic. Please retry for clearance in a few minutes.", "Clearance cannot be granted at this moment, due to prioritized outgoing traffic. Please hold station.",
"There are ships in the launching queue. Please retry in a few minutes for docking clearance." "There are ships in the launching queue. Your queue position is %d - please hold.",
);
"H-station-does-not-require-docking-clearance"
= (
"We do not require docking clearance, Commander. Feel free to dock at any time.",
"Docking clearance not required.",
"Come on in, Commander!",
); );
"H-station-refuses-to-grant-docking-clearance" "H-station-refuses-to-grant-docking-clearance"
= ( = (
@ -1031,10 +1037,26 @@
"you-are-cleared-to-dock-please-proceed-clearance-expires-at-@" "you-are-cleared-to-dock-please-proceed-clearance-expires-at-@"
= ( = (
"You are cleared to dock. Please proceeed. Clearance expires at %@", "You are cleared to dock. Please proceeed. Clearance expires at %@",
"You have docking clearance, commander. Your window is up to %@", "You have docking clearance, Commander. Your window is up to %@",
"Docking authorized. You have an approach slot terminating at %@", "Docking authorized. You have an approach slot terminating at %@",
"Permission granted. Proceed for docking approach. Slot valid until %@" "Permission granted. Proceed for docking approach. Slot valid until %@"
); );
"your-docking-clearance-has-been-extended-until-@"
= (
"Your docking clearance extension has been approved, you now have until %@",
);
"docking-clearance-about-to-expire"
= (
"You have 20 seconds left to dock.",
"Your docking window is about to close. Hurry up!",
"Warning! Your docking clearance is about to expire.",
);
"docking-clearance-expired"
= "Your docking clearance has expired. Please clear the docking corridor.";
"docking-clearance-cancelled"
= "Docking clearance cancelled, Commander. Please leave the docking area.";
"docking-clearance-abort-cancelled"
= "Due to an emergency your docking clearance has been revoked. Please clear the station approach immediately.";
"you-have-been-fined-@-cr-for-unauthorized-docking" "you-have-been-fined-@-cr-for-unauthorized-docking"
= "You have been fined %@ for unauthorized docking."; = "You have been fined %@ for unauthorized docking.";

View File

@ -118,6 +118,18 @@ typedef enum
MISSILE_STATUS_TARGET_LOCKED MISSILE_STATUS_TARGET_LOCKED
} OOMissileStatus; } OOMissileStatus;
#ifdef DOCKING_CLEARANCE_ENABLED
typedef enum
{
// Exposed to shaders.
DOCKING_CLEARANCE_STATUS_NONE,
DOCKING_CLEARANCE_STATUS_REQUESTED,
DOCKING_CLEARANCE_STATUS_NOT_REQUIRED,
DOCKING_CLEARANCE_STATUS_GRANTED,
DOCKING_CLEARANCE_STATUS_TIMING_OUT,
} OODockingClearanceStatus;
#endif
#define WEAPON_COOLING_FACTOR 6.0f #define WEAPON_COOLING_FACTOR 6.0f
#define ENERGY_RECHARGE_FACTOR energy_recharge_rate #define ENERGY_RECHARGE_FACTOR energy_recharge_rate
#define ECM_ENERGY_DRAIN_FACTOR 20.0f #define ECM_ENERGY_DRAIN_FACTOR 20.0f
@ -261,6 +273,12 @@ typedef enum
// ...end save screen // ...end save screen
StationEntity *dockedStation; StationEntity *dockedStation;
#ifdef DOCKING_CLEARANCE_ENABLED
/* Used by the DOCKING_CLEARANCE code to implement docking at non-main
* stations. Could possibly overload use of 'dockedStation' instead
* but that needs futher investigation to ensure it doesn't break anything. */
StationEntity *targetDockStation;
#endif
HeadUpDisplay *hud; HeadUpDisplay *hud;
@ -463,7 +481,7 @@ waitingForStickCallback: 1;
NSPoint galacticHyperspaceFixedCoords; NSPoint galacticHyperspaceFixedCoords;
#ifdef DOCKING_CLEARANCE_ENABLED #ifdef DOCKING_CLEARANCE_ENABLED
BOOL clearedToDock; OODockingClearanceStatus dockingClearanceStatus;
#endif #endif
} }
@ -504,6 +522,11 @@ waitingForStickCallback: 1;
- (void) setDockedAtMainStation; - (void) setDockedAtMainStation;
- (StationEntity *) dockedStation; - (StationEntity *) dockedStation;
#ifdef DOCKING_CLEARANCE_ENABLED
- (void) setTargetDockStationTo:(StationEntity *) value;
- (StationEntity *) getTargetDockStation;
#endif
- (HeadUpDisplay *) hud; - (HeadUpDisplay *) hud;
- (void) setShowDemoShips:(BOOL) value; - (void) setShowDemoShips:(BOOL) value;
@ -677,7 +700,8 @@ waitingForStickCallback: 1;
#ifdef DOCKING_CLEARANCE_ENABLED #ifdef DOCKING_CLEARANCE_ENABLED
- (BOOL) clearedToDock; - (BOOL) clearedToDock;
- (void) setClearedToDock:(BOOL) newValue; - (void) setDockingClearanceStatus:(OODockingClearanceStatus) newValue;
- (OODockingClearanceStatus) getDockingClearanceStatus;
- (void) penaltyForUnauthorizedDocking; - (void) penaltyForUnauthorizedDocking;
#endif #endif

View File

@ -881,7 +881,8 @@ static PlayerEntity *sSharedPlayer = nil;
[UNIVERSE clearGUIs]; [UNIVERSE clearGUIs];
#ifdef DOCKING_CLEARANCE_ENABLED #ifdef DOCKING_CLEARANCE_ENABLED
clearedToDock = YES; dockingClearanceStatus = DOCKING_CLEARANCE_STATUS_GRANTED;
targetDockStation = nil;
#endif #endif
dockedStation = [UNIVERSE station]; dockedStation = [UNIVERSE station];
@ -1794,7 +1795,7 @@ static PlayerEntity *sSharedPlayer = nil;
status = STATUS_IN_FLIGHT; status = STATUS_IN_FLIGHT;
#ifdef DOCKING_CLEARANCE_ENABLED #ifdef DOCKING_CLEARANCE_ENABLED
[self setClearedToDock:NO]; [self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
#endif #endif
[self doScriptEvent:@"shipLaunchedFromStation"]; [self doScriptEvent:@"shipLaunchedFromStation"];
} }
@ -2101,6 +2102,17 @@ static PlayerEntity *sSharedPlayer = nil;
return dockedStation; return dockedStation;
} }
#ifdef DOCKING_CLEARANCE_ENABLED
- (void) setTargetDockStationTo:(StationEntity *) value
{
targetDockStation = value;
}
- (StationEntity *) getTargetDockStation
{
return targetDockStation;
}
#endif
- (HeadUpDisplay *) hud - (HeadUpDisplay *) hud
{ {
@ -3495,12 +3507,13 @@ static PlayerEntity *sSharedPlayer = nil;
status = STATUS_DOCKING; status = STATUS_DOCKING;
[self doScriptEvent:@"shipWillDockWithStation" withArgument:station]; [self doScriptEvent:@"shipWillDockWithStation" withArgument:station];
ident_engaged = NO;
afterburner_engaged = NO; afterburner_engaged = NO;
cloaking_device_active = NO; cloaking_device_active = NO;
hyperspeed_engaged = NO; hyperspeed_engaged = NO;
hyperspeed_locked = NO; hyperspeed_locked = NO;
missile_status = MISSILE_STATUS_SAFE; [self safeAllMissiles];
[hud setScannerZoom:1.0]; [hud setScannerZoom:1.0];
scanner_zoom_rate = 0.0f; scanner_zoom_rate = 0.0f;
@ -3545,7 +3558,7 @@ static PlayerEntity *sSharedPlayer = nil;
hyperspeed_engaged = NO; hyperspeed_engaged = NO;
hyperspeed_locked = NO; hyperspeed_locked = NO;
missile_status = MISSILE_STATUS_SAFE; [self safeAllMissiles];
primaryTarget = NO_TARGET; primaryTarget = NO_TARGET;
[self clearTargetMemory]; [self clearTargetMemory];
@ -3586,8 +3599,8 @@ static PlayerEntity *sSharedPlayer = nil;
#ifdef DOCKING_CLEARANCE_ENABLED #ifdef DOCKING_CLEARANCE_ENABLED
// Did we fail to observe traffic control regulations? However, due to the state of emergency, // Did we fail to observe traffic control regulations? However, due to the state of emergency,
// apply no unauthorized docking penalties if a nova is ongoing. // apply no unauthorized docking penalties if a nova is ongoing.
if (![UNIVERSE strict] && dockedStation == [UNIVERSE station] && [dockedStation requiresDockingClearance] && if (![UNIVERSE strict] && [dockedStation requiresDockingClearance] &&
[self clearedToDock] == NO && ![[UNIVERSE sun] willGoNova]) ![self clearedToDock] && ![[UNIVERSE sun] willGoNova])
{ {
[self penaltyForUnauthorizedDocking]; [self penaltyForUnauthorizedDocking];
} }
@ -3635,7 +3648,9 @@ static PlayerEntity *sSharedPlayer = nil;
flightRoll = -flightRoll; flightRoll = -flightRoll;
[self setAlertFlag:ALERT_FLAG_DOCKED to:NO]; [self setAlertFlag:ALERT_FLAG_DOCKED to:NO];
#ifdef DOCKING_CLEARANCE_ENABLED
[self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
#endif
[hud setScannerZoom:1.0]; [hud setScannerZoom:1.0];
scanner_zoom_rate = 0.0f; scanner_zoom_rate = 0.0f;
gui_screen = GUI_SCREEN_MAIN; gui_screen = GUI_SCREEN_MAIN;
@ -6460,13 +6475,35 @@ static int last_outfitting_index;
#ifdef DOCKING_CLEARANCE_ENABLED #ifdef DOCKING_CLEARANCE_ENABLED
- (BOOL)clearedToDock - (BOOL)clearedToDock
{ {
return clearedToDock; return dockingClearanceStatus > DOCKING_CLEARANCE_STATUS_REQUESTED;
} }
- (void)setClearedToDock:(BOOL)newValue - (void)setDockingClearanceStatus:(OODockingClearanceStatus)newValue
{ {
clearedToDock = !!newValue; // Ensure yes or no. dockingClearanceStatus = newValue;
if (dockingClearanceStatus == DOCKING_CLEARANCE_STATUS_NONE)
{
targetDockStation = nil;
}
else if (dockingClearanceStatus == DOCKING_CLEARANCE_STATUS_REQUESTED)
{
if ([[self primaryTarget] isStation])
{
targetDockStation = [self primaryTarget];
}
else
{
OOLog(@"player.badDockingTarget", @"Attempt to dock at %@.", [self primaryTarget]);
targetDockStation = nil;
dockingClearanceStatus = DOCKING_CLEARANCE_STATUS_NONE;
}
}
}
- (OODockingClearanceStatus)getDockingClearanceStatus
{
return dockingClearanceStatus;
} }
@ -6476,7 +6513,7 @@ static int last_outfitting_index;
OOCreditsQuantity calculatedFine = credits * 0.05; OOCreditsQuantity calculatedFine = credits * 0.05;
OOCreditsQuantity maximumFine = 50000ULL; OOCreditsQuantity maximumFine = 50000ULL;
if ([UNIVERSE strict] || [self clearedToDock] == YES) if ([UNIVERSE strict] || [self clearedToDock])
return; return;
amountToPay = MIN(maximumFine, calculatedFine); amountToPay = MIN(maximumFine, calculatedFine);

View File

@ -804,7 +804,7 @@ static NSTimeInterval time_last_frame;
[shipAI setState:@"GLOBAL"]; // reboot the AI [shipAI setState:@"GLOBAL"]; // reboot the AI
[self playAutopilotOn]; [self playAutopilotOn];
#ifdef DOCKING_CLEARANCE_ENABLED #ifdef DOCKING_CLEARANCE_ENABLED
[self setClearedToDock:YES]; [self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_GRANTED];
#endif #endif
[UNIVERSE addMessage:ExpandDescriptionForCurrentSystem(@"[autopilot-on]") forCount:4.5]; [UNIVERSE addMessage:ExpandDescriptionForCurrentSystem(@"[autopilot-on]") forCount:4.5];
[self doScriptEvent:@"playerStartedAutoPilot"]; [self doScriptEvent:@"playerStartedAutoPilot"];
@ -842,7 +842,7 @@ static NSTimeInterval time_last_frame;
[shipAI setState:@"GLOBAL"]; // restart the AI [shipAI setState:@"GLOBAL"]; // restart the AI
[self playAutopilotOn]; [self playAutopilotOn];
#ifdef DOCKING_CLEARANCE_ENABLED #ifdef DOCKING_CLEARANCE_ENABLED
[self setClearedToDock:YES]; [self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_GRANTED];
#endif #endif
[UNIVERSE addMessage:ExpandDescriptionForCurrentSystem(@"[autopilot-on]") forCount:4.5]; [UNIVERSE addMessage:ExpandDescriptionForCurrentSystem(@"[autopilot-on]") forCount:4.5];
[self doScriptEvent:@"playerStartedAutoPilot"]; [self doScriptEvent:@"playerStartedAutoPilot"];
@ -897,7 +897,7 @@ static NSTimeInterval time_last_frame;
} }
} }
#ifdef DOCKING_CLEARANCE_ENABLED #ifdef DOCKING_CLEARANCE_ENABLED
[self setClearedToDock:YES]; [self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_GRANTED];
#endif #endif
ship_clock_adjust = 1200.0; // 20 minutes penalty to enter dock ship_clock_adjust = 1200.0; // 20 minutes penalty to enter dock
ident_engaged = NO; ident_engaged = NO;
@ -927,10 +927,10 @@ static NSTimeInterval time_last_frame;
Entity *primeTarget = [self primaryTarget]; Entity *primeTarget = [self primaryTarget];
if ((primeTarget)&&(primeTarget->isStation)&&[primeTarget isKindOfClass:[StationEntity class]]) if ((primeTarget)&&(primeTarget->isStation)&&[primeTarget isKindOfClass:[StationEntity class]])
{ {
NSString *dockingClearanceStatus = [(StationEntity*)primeTarget acceptDockingClearanceRequestFrom:self]; NSString *stationDockingClearanceStatus = [(StationEntity*)primeTarget acceptDockingClearanceRequestFrom:self];
if (dockingClearanceStatus != nil) if (stationDockingClearanceStatus != nil)
{ {
[self doScriptEvent:@"playerRequestedDockingClearance" withArgument:dockingClearanceStatus]; [self doScriptEvent:@"playerRequestedDockingClearance" withArgument:stationDockingClearanceStatus];
} }
} }
} }
@ -2617,7 +2617,7 @@ static BOOL toggling_music;
[self playAutopilotOff]; [self playAutopilotOff];
[UNIVERSE addMessage:ExpandDescriptionForCurrentSystem(@"[autopilot-off]") forCount:4.5]; [UNIVERSE addMessage:ExpandDescriptionForCurrentSystem(@"[autopilot-off]") forCount:4.5];
#ifdef DOCKING_CLEARANCE_ENABLED #ifdef DOCKING_CLEARANCE_ENABLED
[self setClearedToDock:NO]; [self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
#endif #endif
[self doScriptEvent:@"playerCancelledAutoPilot"]; [self doScriptEvent:@"playerCancelledAutoPilot"];

View File

@ -257,6 +257,17 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
[[[UNIVERSE entityForUniversalID:sid] getAI] message:@"DOCKING_ABORTED"]; [[[UNIVERSE entityForUniversalID:sid] getAI] message:@"DOCKING_ABORTED"];
} }
[shipsOnApproach removeAllObjects]; [shipsOnApproach removeAllObjects];
#ifdef DOCKING_CLEARANCE_ENABLED
PlayerEntity *player = [PlayerEntity sharedPlayer];
BOOL isDockingStation = (self == [player getTargetDockStation]);
if (isDockingStation && player && player->status == STATUS_IN_FLIGHT &&
[player getDockingClearanceStatus] >= DOCKING_CLEARANCE_STATUS_REQUESTED)
{
[self sendExpandedMessage:DESC(@"docking-clearance-abort-cancelled") toShip:player];
[player setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
}
#endif
ships = [shipsOnHold allKeys]; ships = [shipsOnHold allKeys];
for (i = 0; i < [ships count]; i++) for (i = 0; i < [ships count]; i++)
@ -342,6 +353,20 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
{ {
return instructions(universalID, ship->position, 0, 100, @"TRY_AGAIN_LATER", nil, NO); return instructions(universalID, ship->position, 0, 100, @"TRY_AGAIN_LATER", nil, NO);
} }
#ifdef DOCKING_CLEARANCE_ENABLED
// If the ship is not on its docking approach and the player has
// requested or even been granted docking clearance, then tell the
// ship to wait.
PlayerEntity *player = [PlayerEntity sharedPlayer];
BOOL isDockingStation = self == [player getTargetDockStation];
if (isDockingStation && ![shipsOnApproach objectForKey:shipID] &&
player && player->status == STATUS_IN_FLIGHT &&
[player getDockingClearanceStatus] >= DOCKING_CLEARANCE_STATUS_REQUESTED)
{
return instructions(universalID, ship->position, 0, 100, @"TRY_AGAIN_LATER", nil, NO);
}
#endif
[shipAI reactToMessage:@"DOCKING_REQUESTED"]; // react to the request [shipAI reactToMessage:@"DOCKING_REQUESTED"]; // react to the request
@ -1058,9 +1083,32 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
#ifdef DOCKING_CLEARANCE_ENABLED #ifdef DOCKING_CLEARANCE_ENABLED
PlayerEntity *player = [PlayerEntity sharedPlayer]; PlayerEntity *player = [PlayerEntity sharedPlayer];
if (isMainStation && player->status == STATUS_IN_FLIGHT && [player clearedToDock] == YES && last_launch_time < unitime) BOOL isDockingStation = (self == [player getTargetDockStation]);
if (isDockingStation && player->status == STATUS_IN_FLIGHT &&
[player getDockingClearanceStatus] >= DOCKING_CLEARANCE_STATUS_GRANTED)
{ {
[player setClearedToDock:NO]; // Docking clearance for player has expired. if (last_launch_time-20 < unitime && [player getDockingClearanceStatus] != DOCKING_CLEARANCE_STATUS_TIMING_OUT)
{
[self sendExpandedMessage:DESC(@"docking-clearance-about-to-expire") toShip:player];
[player setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_TIMING_OUT];
}
else if (last_launch_time < unitime)
{
[self sendExpandedMessage:DESC(@"docking-clearance-expired") toShip:player];
[player setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE]; // Docking clearance for player has expired.
}
}
// TODO: If player is waiting for docking clearance, send him an update
// every X seconds telling him where he's at in the queue.
if (isDockingStation && [player getDockingClearanceStatus] == DOCKING_CLEARANCE_STATUS_REQUESTED &&
[shipsOnApproach count] == 0 && [launchQueue count] == 0)
{
last_launch_time = unitime + DOCKING_CLEARANCE_WINDOW;
[self sendExpandedMessage:[NSString stringWithFormat:
DESC(@"you-are-cleared-to-dock-please-proceed-clearance-expires-at-@"),
ClockToString([player clockTime] + DOCKING_CLEARANCE_WINDOW, NO)]
toShip:player];
[player setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_GRANTED];
} }
#endif #endif
@ -1810,44 +1858,96 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
PlayerEntity *player = [PlayerEntity sharedPlayer]; PlayerEntity *player = [PlayerEntity sharedPlayer];
[UNIVERSE clearPreviousMessage]; [UNIVERSE clearPreviousMessage];
// We do not do [player setClearedToDock:NO] if the station is not the main one. The player could // Docking clearance not required - clear it just in case it's been
// have already acquired clearance, which could still be valid. // set for another nearby station.
if (self != [UNIVERSE station]) if (![self requiresDockingClearance])
{
result = @"DOCKING_CLEARANCE_DENIED_NOT_MAIN_STATION";
}
if (result == nil && ![self requiresDockingClearance])
{ {
// TODO: We're potentially cancelling docking at another station, so
// ensure we clear the timer to allow NPC traffic. If we
// don't, normal traffic will resume once the timer runs out.
[self sendExpandedMessage:DESC(@"H-station-does-not-require-docking-clearance") toShip:other];
if ([other isPlayer])
[player setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
result = @"DOCKING_CLEARANCE_NOT_REQUIRED"; result = @"DOCKING_CLEARANCE_NOT_REQUIRED";
} }
// Main station and requires docking clearance. Perform necessary checks.
if (result == nil && [other bounty] > 50) // do not grant docking clearance to fugitives // Docking clearance already granted for this station - check for
// time-out or cancellation (but only for the Player).
if( result == nil && [other isPlayer] && self == [player getTargetDockStation])
{
if ([player getDockingClearanceStatus] == DOCKING_CLEARANCE_STATUS_TIMING_OUT)
{
last_launch_time = timeNow + DOCKING_CLEARANCE_WINDOW;
[self sendExpandedMessage:[NSString stringWithFormat:
DESC(@"your-docking-clearance-has-been-extended-until-@"),
ClockToString([player clockTime] + DOCKING_CLEARANCE_WINDOW, NO)]
toShip:other];
[player setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_GRANTED];
result = @"DOCKING_CLEARANCE_EXTENDED";
}
else if ([player getDockingClearanceStatus] > DOCKING_CLEARANCE_STATUS_NONE)
{
last_launch_time = timeNow;
[self sendExpandedMessage:DESC(@"docking-clearance-cancelled") toShip:other];
[player setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
result = @"DOCKING_CLEARANCE_CANCELLED";
}
}
// First we must set the status to REQUESTED to avoid problems when
// switching docking targets - even if we later set it back to NONE.
if (result == nil && [other isPlayer] && self != [player getTargetDockStation])
{
[player setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_REQUESTED];
}
// Deny docking for fugitives at the main station
// TODO: Should this be another key in shipdata.plist and/or should this
// apply to all stations?
if (result == nil && self == [UNIVERSE station] && [other bounty] > 50) // do not grant docking clearance to fugitives
{ {
[self sendExpandedMessage:DESC(@"H-station-refuses-to-grant-docking-clearance") toShip:other]; [self sendExpandedMessage:DESC(@"H-station-refuses-to-grant-docking-clearance") toShip:other];
[player setClearedToDock:NO]; if ([other isPlayer])
[player setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
result = @"DOCKING_CLEARANCE_DENIED_SHIP_FUGITIVE"; result = @"DOCKING_CLEARANCE_DENIED_SHIP_FUGITIVE";
} }
// Put ship in queue if we've got incoming or outgoing traffic
if (result == nil && [shipsOnApproach count] && last_launch_time < timeNow) if (result == nil && [shipsOnApproach count] && last_launch_time < timeNow)
{ {
[self sendExpandedMessage:DESC(@"please-wait-until-all-ships-have-completed-their-approach") toShip:other]; [self sendExpandedMessage:[NSString stringWithFormat:
[player setClearedToDock:NO]; DESC(@"please-wait-until-d-ships-have-completed-their-approach"),
[shipsOnApproach count]+1] toShip:other];
//[self sendExpandedMessage:[NSString stringWithFormat:@"You are in queue position %d.", [shipsOnApproach count]+1] toShip:other];
// No need to set status to REQUESTED as we've already done that earlier.
result = @"DOCKING_CLEARANCE_DENIED_TRAFFIC_INBOUND"; result = @"DOCKING_CLEARANCE_DENIED_TRAFFIC_INBOUND";
} }
if (result == nil && [launchQueue count] && last_launch_time < timeNow) if (result == nil && [launchQueue count] && last_launch_time < timeNow)
{ {
[self sendExpandedMessage:DESC(@"please-wait-until-launching-ships-have-cleared-H-station") toShip:other]; //[self sendExpandedMessage:DESC(@"please-wait-until-launching-ships-have-cleared-H-station") toShip:other];
[player setClearedToDock:NO]; //[self sendExpandedMessage:[NSString stringWithFormat:@"You are in queue position %d.", [launchQueue count]+1] toShip:other];
[self sendExpandedMessage:[NSString stringWithFormat:
DESC(@"please-wait-until-d-launching-ships-have-cleared-H-station"),
[launchQueue count]+1] toShip:other];
//[self sendExpandedMessage:[NSString stringWithFormat:@"You are in queue position %d.", [launchQueue count]+1] toShip:other];
// No need to set status to REQUESTED as we've already done that earlier.
result = @"DOCKING_CLEARANCE_DENIED_TRAFFIC_OUTBOUND"; result = @"DOCKING_CLEARANCE_DENIED_TRAFFIC_OUTBOUND";
} }
if (result == nil && last_launch_time < timeNow)
// Ship has passed all checks - grant docking!
// TODO: We probably don't need to test against last_launch_time anymore,
// since we cancel existing launch requests above.
//if (result == nil && last_launch_time < timeNow)
if (result == nil)
{ {
last_launch_time = timeNow + DOCKING_CLEARANCE_WINDOW; last_launch_time = timeNow + DOCKING_CLEARANCE_WINDOW;
[self sendExpandedMessage:[NSString stringWithFormat: [self sendExpandedMessage:[NSString stringWithFormat:
DESC(@"you-are-cleared-to-dock-please-proceed-clearance-expires-at-@"), DESC(@"you-are-cleared-to-dock-please-proceed-clearance-expires-at-@"),
ClockToString([player clockTime] + DOCKING_CLEARANCE_WINDOW, NO)] ClockToString([player clockTime] + DOCKING_CLEARANCE_WINDOW, NO)]
toShip:other]; toShip:other];
[player setClearedToDock:YES]; if ([other isPlayer])
[player setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_GRANTED];
result = @"DOCKING_CLEARANCE_GRANTED"; result = @"DOCKING_CLEARANCE_GRANTED";
} }
return result; return result;