49@interface DockEntity (OOPrivate)
53- (void) autoDockShipsInQueue:(NSMutableDictionary *)queue;
54- (void) addShipToShipsOnApproach:(
ShipEntity *)ship;
55- (void) pullInShipIfPermitted:(
ShipEntity *)ship;
66 NSNumber *idObj =
nil;
69 ShipEntity *ship = [UNIVERSE entityForUniversalID:[
idObj unsignedIntValue]];
75 [shipsOnApproach removeObjectForKey:idObj];
92 return [shipsOnApproach count];
98 double playerExtraTime = 0;
102 NSNumber *idObj =
nil;
105 ShipEntity *ship = [UNIVERSE entityForUniversalID:[
idObj unsignedIntValue]];
112 [shipsOnApproach removeAllObjects];
117 if (isDockingStation && [player
status] == STATUS_IN_FLIGHT &&
128 playerExtraTime = 10;
129 int seconds = round(playerExtraTime);
146 [launchQueue removeAllObjects];
150- (void) autoDockShipsInQueue:(NSMutableDictionary *)queue
152 NSNumber *idObj =
nil;
153 foreach (idObj, [queue allKeys])
155 ShipEntity *ship = [UNIVERSE entityForUniversalID:[
idObj unsignedIntValue]];
162 [
queue removeAllObjects];
150- (void) autoDockShipsInQueue:(NSMutableDictionary *)queue {
…}
178- (void) setAllowsDocking:(BOOL)allowed
178- (void) setAllowsDocking:(BOOL)allowed {
…}
200- (void) setAllowsLaunching:(BOOL)allowed
200- (void) setAllowsLaunching:(BOOL)allowed {
…}
210- (void) setDisallowedDockingCollides:(BOOL)ddc
210- (void) setDisallowedDockingCollides:(BOOL)ddc {
…}
227 return @"DOCK_CLOSED";
233 return @"TOO_BIG_TO_DOCK";
238 jsval rval = JSVAL_VOID;
243 if (OK) OK = JS_ValueToBoolean(context, rval, &accept);
244 if (!OK) accept = YES;
249 return @"TOO_BIG_TO_DOCK";
255 return @"TRY_AGAIN_LATER";
260 return @"TRY_AGAIN_LATER";
263 return @"DOCKING_POSSIBLE";
274 if (fabs(dir.x) + fabs(dir.y) > 0.1)
282- (NSDictionary *) dockingInstructionsForShip:(
ShipEntity *)ship
284 if (ship ==
nil)
return nil;
287 NSNumber *shipID = [
NSNumber numberWithUnsignedShort:ship_id];
291 HPVector temp = (fabs(launchVector.x) < 0.8)? make_HPvector(1,0,0) : make_HPvector(0,1,0);
292 temp = HPcross_product(launchVector, temp);
293 HPVector vi = HPcross_product(launchVector, temp);
294 HPVector vj = HPcross_product(launchVector, vi);
295 HPVector vk = launchVector;
302 float ship_distance = HPmagnitude(delta);
315 float dot = HPdot_product(launchVector, delta);
318 HPVector approachVector = HPcross_product(HPvector_normal(delta), launchVector);
319 approachVector = HPcross_product(launchVector, approachVector);
323 if (ship_distance > 12500.0)
333 OOLogERR(
@"station.issueDockingInstructions.failed",
@"couldn't addShipToShipsOnApproach:%@ in %@, retrying later -- shipsOnApproach:\n%@", ship,
self,
shipsOnApproach);
341 NSMutableArray* coordinatesStack = [shipsOnApproach objectForKey:shipID];
343 if ([coordinatesStack
count] == 0)
345 OOLogERR(
@"station.issueDockingInstructions.failed",
@" -- coordinatesStack = %@", coordinatesStack);
351 NSMutableDictionary *nextCoords = (NSMutableDictionary *)[coordinatesStack objectAtIndex:0];
352 int docking_stage = [
nextCoords oo_intForKey:@"docking_stage"];
353 float speedAdvised = [
nextCoords oo_floatForKey:@"speed"];
354 float rangeAdvised = [
nextCoords oo_floatForKey:@"range"];
358 rel_coords.x = [
nextCoords oo_doubleForKey:@"rx"];
359 rel_coords.y = [
nextCoords oo_doubleForKey:@"ry"];
360 rel_coords.z = [
nextCoords oo_doubleForKey:@"rz"];
362 coords.x += rel_coords.x * vi.x + rel_coords.y * vj.x + rel_coords.z * vk.x;
363 coords.y += rel_coords.x * vi.y + rel_coords.y * vj.y + rel_coords.z * vk.y;
364 coords.z += rel_coords.x * vi.z + rel_coords.y * vj.z + rel_coords.z * vk.z;
368 HPVector delta = HPvector_subtract(ship->
position, coords);
370 if (HPmagnitude2(delta) > max_allowed_range * max_allowed_range)
372 if ((docking_stage == 1) &&(HPmagnitude2(delta) < 1000000.0))
381 nextCoords = (NSMutableDictionary *)[coordinatesStack oo_dictionaryAtIndex:1];
382 if (nextCoords ==
nil)
387 docking_stage = [
nextCoords oo_intForKey:@"docking_stage"];
388 speedAdvised = [
nextCoords oo_floatForKey:@"speed"];
389 rangeAdvised = [
nextCoords oo_floatForKey:@"range"];
390 BOOL match_rotation = [
nextCoords oo_boolForKey:@"match_rotation"];
391 NSString *comms_message = [
nextCoords oo_stringForKey:@"comms_message"];
399 rel_coords.x = [
nextCoords oo_doubleForKey:@"rx"];
400 rel_coords.y = [
nextCoords oo_doubleForKey:@"ry"];
401 rel_coords.z = [
nextCoords oo_doubleForKey:@"rz"];
403 coords.x += rel_coords.x * vi.x + rel_coords.y * vj.x + rel_coords.z * vk.x;
404 coords.y += rel_coords.x * vi.y + rel_coords.y * vj.y + rel_coords.z * vk.y;
405 coords.z += rel_coords.x * vi.z + rel_coords.y * vj.z + rel_coords.z * vk.z;
407 if([
id_lock[docking_stage] weakRefUnderlyingObject] ==
nil &&
408 [
id_lock[docking_stage + 1] weakRefUnderlyingObject] ==
nil &&
409 [
id_lock[docking_stage + 2] weakRefUnderlyingObject] ==
nil)
417 if (docking_stage > 1)
426 return OOMakeDockingInstructions(station, coords, speedAdvised, rangeAdvised,
@"APPROACH_COORDINATES",
nil, match_rotation, docking_stage);
433 if (![nextCoords objectForKey:
@"hold_message_given"])
436 [UNIVERSE clearPreviousMessage];
438 [
nextCoords setObject:@"YES" forKey:@"hold_message_given"];
282- (NSDictionary *) dockingInstructionsForShip:(
ShipEntity *)ship {
…}
447 int corridor_distance[] = { -1, 1, 3, 5, 7, 9, 11, 12, 12};
448 int corridor_offset[] = { 0, 0, 0, 0, 0, 0, 1, 3, 12};
454 int corridor_speed[] = { 96, 96, 128, 128, 96, 128, 128, 256, 512};
455 int corridor_range[] = { 24, 12, 6, 4, 4, 6, 15, 38, 96};
456 int corridor_rotate[] = { 1, 1, 1, 1, 0, 0, 0, 0, 0};
457 int corridor_count = 9;
458 int corridor_final_approach = 3;
464 HPVector temp = (fabs(launchVector.x) < 0.8)? make_HPvector(1,0,0) : make_HPvector(0,1,0);
465 temp = HPcross_product(launchVector, temp);
466 HPVector rightVector = HPcross_product(launchVector, temp);
467 HPVector upVector = HPcross_product(launchVector, rightVector);
479 HPVector alt1 = point1;
486 if (HPdistance2(alt1, ship->
position) < HPdistance2(point1, ship->
position))
493 NSMutableArray *coordinatesStack = [
NSMutableArray arrayWithCapacity: MAX_DOCKING_STAGES];
494 float port_depth = port_dimensions.z;
497 for (i = corridor_count - 1; i >= 0; i--)
500 int offset = corridor_offset[
i];
501 float corridor_length = port_depth * corridor_distance[
i];
503 float rx = s * port_depth *
offset;
504 float ry = c * port_depth *
offset;
505 float rz = corridor_length;
507 if ((i == corridor_count - 1) && [
self countOfShipsInDockingQueue])
526 float ssize =
MAX(port_depth,1500.0);
529 rz += ssize * ((float)offset_id3 / 4.0);
535 if (corridor_distance[i] > 0) corridor_length += port_corridor;
537 [
nextCoords oo_setInteger:corridor_count - i forKey:@"docking_stage"];
541 [
nextCoords oo_setFloat:corridor_speed[
i] forKey:@"speed"];
542 [
nextCoords oo_setFloat:corridor_range[
i] forKey:@"range"];
544 if (corridor_rotate[i])
546 [
nextCoords setObject:@"YES" forKey:@"match_rotation"];
549 if (i == corridor_final_approach)
553 [
nextCoords setObject:@"[station-begin-final-aproach]" forKey:@"comms_message"];
557 [
nextCoords setObject:@"[docking-begin-final-aproach]" forKey:@"comms_message"];
592 NSNumber *shipID = [
NSNumber numberWithUnsignedShort:ship_id];
596 [shipsOnApproach removeObjectForKey:shipID];
602 if ([player
status] == STATUS_IN_FLIGHT &&
624- (Vector) portUpVectorForShipsBoundingBox:(BoundingBox)bb
624- (Vector) portUpVectorForShipsBoundingBox:(BoundingBox)bb {
…}
641 if (![ship
isShip])
return NO;
645 NSNumber *shipID = [
NSNumber numberWithUnsignedShort:ship_id];
652 if ([ship
isPlayer] && [[
self owner] playerReservedDock] ==
self)
662 return [shipsOnApproach count];
668 return [launchQueue count];
674 if (![ship
isShip])
return NO;
683 if ([station
status] == STATUS_DEAD)
696 BoundingBox arbb = [
ship findBoundingBoxRelativeToPosition: port_pos InVectors: vi : vj : vk];
703 BOOL rotatedPort = (ww >= hh) ? NO : YES;
704 BOOL rotatedShip = ((shipbb.max.x - shipbb.min.x) >= (shipbb.max.y - shipbb.min.y)) ? NO : YES;
705 BOOL rotationsMatch = (rotatedShip == rotatedPort);
709 while (shipbb.max.x - shipbb.min.x > ww * 0.90) ww *= 1.25;
710 while (shipbb.max.y - shipbb.min.y > hh * 0.90) hh *= 1.25;
715 while (shipbb.max.y - shipbb.min.y > ww * 0.90) ww *= 1.25;
716 while (shipbb.max.x - shipbb.min.x > hh * 0.90) hh *= 1.25;
727 unsigned laneFlags = 0;
729 if (arbb.max.x < ww) laneFlags |= 1;
730 if (arbb.min.x > -ww) laneFlags |= 2;
731 if (arbb.max.y < hh) laneFlags |= 4;
732 if (arbb.min.y > -hh) laneFlags |= 8;
733 inLane = laneFlags == 0xF;
734 range = 0.90 * arbb.max.z + 0.10 * arbb.min.z;
736 OOLog(
@"docking.debug",
@"Normalised port dimensions are %g x %g x %g. Player bounding box is at %@-%@ -- %s (%X), range: %g",
737 ww * 2.0, hh * 2.0, dd,
738 VectorDescription(arbb.min), VectorDescription(arbb.max),
739 inLane ?
"in lane" :
"out of lane", laneFlags,
744 if ((arbb.max.x < ww * 3.0)&&(arbb.min.x > -ww * 3.0)&&(arbb.max.y < hh * 3.0)&&(arbb.min.y > -hh * 3.0))
748 if ((0.90 * arbb.max.z + 0.10 * arbb.min.z < 3000) && (dot_product(vk,[ship
forwardVector]) < -0.9))
752 [UNIVERSE addMessage:DESC(@"oolite-station-docking-requires-clearance") forCount:3];
757 if (arbb.max.z < -dd)
762 if ((arbb.max.x < ww)&&(arbb.min.x > -ww)&&(arbb.max.y < hh)&&(arbb.min.y > -hh))
764 if ([ship
status] != STATUS_LAUNCHING && !allow_docking_thisship)
770 HPVector rel = HPvector_subtract([ship
position],port_pos);
771 rel = HPvector_multiply_scalar(HPvector_normal(rel),[ship
flightSpeed]*0.4);
775 if (arbb.max.z < 0.0)
782 if (0.90 * arbb.max.z + 0.10 * arbb.min.z < 0.0)
789 if ([ship
status] == STATUS_LAUNCHING)
796 GLfloat safety = 1.0+(50.0/100.0);
798 if ((arbb.min.x > -safety * ww)&&(arbb.max.x < safety * ww)&&(arbb.min.y > -safety * hh)&&(arbb.max.y < safety * hh))
800 if (arbb.min.z < 0.0)
803 if ((arbb.min.x < -ww && arbb.max.x > ww) || (arbb.min.y < -hh && arbb.max.y > hh))
811 GLfloat correction_factor = -arbb.min.z / (arbb.max.z - arbb.min.z);
819 delta.x = 0.5f * (arbb.max.x + arbb.min.x) * correction_factor;
820 delta.y = 0.5f * (arbb.max.y + arbb.min.y) * correction_factor;
822 if (arbb.max.x < ww && arbb.min.x > -ww)
827 if (arbb.max.y > hh && arbb.min.y > -hh)
835 pos.x -= delta.y * vj.x + delta.x * vi.x;
836 pos.y -= delta.y * vj.y + delta.x * vi.y;
837 pos.z -= delta.y * vj.z + delta.x * vi.z;
842 if (0.90f * arbb.max.z + 0.10f * arbb.min.z < 0.0f)
858 if (allow_docking || !disallowed_docking_collides)
865- (void) addShipToLaunchQueue:(
ShipEntity *)ship withPriority:(BOOL)priority
869 if (ship ==
nil)
return;
879 [launchQueue insertObject:ship atIndex:0];
883 [launchQueue addObject:ship];
865- (void) addShipToLaunchQueue:(
ShipEntity *)ship withPriority:(BOOL)priority {
…}
890 if (![ship
isShip])
return;
917 launchVel = vector_add(launchVel, vector_multiply_scalar(launchVector, launchSpeed));
918 launchSpeed = magnitude(launchVel);
925 [UNIVERSE addEntity:ship];
940- (NSUInteger) countOfShipsInLaunchQueueWithPrimaryRole:(NSString *)role
942 NSUInteger
count = 0;
946 if ([ship hasPrimaryRole:role])
count++;
940- (NSUInteger) countOfShipsInLaunchQueueWithPrimaryRole:(NSString *)role {
…}
954 if (![ship
isShip])
return NO;
965 jsval rval = JSVAL_VOID;
970 if (OK) OK = JS_ValueToBoolean(context, rval, &accept);
971 if (!OK) accept = YES;
984 [launchQueue removeAllObjects];
985 [shipsOnApproach removeAllObjects];
991 double unitime = [UNIVERSE getTime];
1001 if ([station playerReservedDock] ==
self)
1009 int ent_count =
UNIVERSE->n_entities;
1015 for (i = 0; i < ent_count; i++)
1024 for (i = 0; (i < ship_count)&&(isEmpty); i++)
1028 if ((ship != station) && (d2 < 25000000)&&([ship
status] != STATUS_DOCKED))
1031 d2 = HPdistance2(ppos, ship->
position);
1039 if (r_pos.x||r_pos.y||r_pos.z)
1040 r_pos = HPvector_normal(r_pos);
1044 double vdp = HPdot_product(v_out, r_pos);
1055 for (i = 0; i < ship_count; i++)
1069 int ent_count =
UNIVERSE->n_entities;
1075 for (i = 0; i < ent_count; i++)
1077 if (uni_entities[i]->
isShip)
1083 for (i = 0; i < ship_count; i++)
1087 if ((ship != station)&&(d2 < 25000000)&&([ship
status] != STATUS_DOCKED))
1090 float time_out = -15.00;
1094 d2 = HPdistance2(ppos, ship->
position);
1102 if (r_pos.x||r_pos.y||r_pos.z)
1103 r_pos = vector_normal(r_pos);
1107 float vdp = dot_product(v_out, r_pos);
1121 spos.x += 3000.0 * v1.x; spos.y += 3000.0 * v1.y; spos.z += 3000.0 * v1.z;
1129 for (i = 0; i < ship_count; i++)
1137- (void)setDimensionsAndCorridor:(BOOL)docking :(BOOL)ddc :(BOOL)launching
1147 port_dimensions = make_vector(bb.max.x - bb.min.x, bb.max.y - bb.min.y, bb.max.z - bb.min.z);
1154 while ((start.x > stbb.min.x)&&(start.x < stbb.max.x) &&
1155 (start.y > stbb.min.y)&&(start.y < stbb.max.y) &&
1156 (start.z > stbb.min.z)&&(start.z < stbb.max.z) )
1158 start = HPvector_add(start, HPvector_multiply_scalar(vk,
port_dimensions.z));
1137- (void)setDimensionsAndCorridor:(BOOL)docking :(BOOL)ddc :(BOOL)launching {
…}
1177- (id)initWithKey:(NSString *)key definition:(NSDictionary *)dict
1177- (id)initWithKey:(NSString *)key definition:(NSDictionary *)dict {
…}
1213 if (ship ==
nil || ship == [id_lock[i] weakRefUnderlyingObject])
1231- (BOOL) setUpShipFromDictionary:(NSDictionary *) dict
1238 if (![super setUpShipFromDictionary:dict])
return NO;
1231- (BOOL) setUpShipFromDictionary:(NSDictionary *) dict {
…}
1254 if ([se
status] == STATUS_DOCKED)
1258 [launchQueue removeObjectAtIndex:0];
1279- (void) takeEnergyDamage:(
double)amount from:(
Entity *)ent becauseOf:(
Entity *)other weaponIdentifier:(NSString *)weaponIdentifier
1279- (void) takeEnergyDamage:(
double)amount from:(
Entity *)ent becauseOf:(
Entity *)other weaponIdentifier:(NSString *)weaponIdentifier {
…}
1290- (void) drawImmediate:(
bool)immediate translucent:(
bool)translucent
1290- (void) drawImmediate:(
bool)immediate translucent:(
bool)translucent {
…}
#define SCANNER_MAX_RANGE
#define SCANNER_MAX_RANGE2
#define OOJS_PROFILE_EXIT
#define OOJS_PROFILE_ENTER
OOINLINE jsval OOJSValueFromNativeObject(JSContext *context, id object)
OOINLINE JSContext * OOJSAcquireContext(void)
OOINLINE void OOJSRelinquishContext(JSContext *context)
#define OOLogERR(class, format,...)
#define OOLog(class, format,...)
Vector vector_up_from_quaternion(Quaternion quat)
HPVector HPvector_forward_from_quaternion(Quaternion quat)
Vector vector_right_from_quaternion(Quaternion quat)
Vector vector_forward_from_quaternion(Quaternion quat)
void quaternion_rotate_about_axis(Quaternion *quat, Vector axis, OOScalar angle)
Quaternion quaternion_multiply(Quaternion q1, Quaternion q2)
@ DOCKING_CLEARANCE_STATUS_GRANTED
@ DOCKING_CLEARANCE_STATUS_REQUESTED
#define STATION_LAUNCH_RETRY_INTERVAL
NSDictionary * OOMakeDockingInstructions(StationEntity *station, HPVector coords, float speed, float range, NSString *ai_message, NSString *comms_message, BOOL match_rotation, int docking_stage)
@ STATION_ALERT_LEVEL_RED
#define MAX_DOCKING_STAGES
#define STATION_DELAY_BETWEEN_LAUNCHES
void setNextThinkTime:(OOTimeAbsolute ntt)
void message:(NSString *ms)
void launchShip:(ShipEntity *ship)
NSMutableDictionary * shipsOnApproach
BOOL dockingCorridorIsEmpty()
void autoDockShipsInQueue:(NSMutableDictionary *queue)
NSUInteger countOfShipsInLaunchQueue()
void pullInShipIfPermitted:(ShipEntity *ship)
NSUInteger countOfShipsInDockingQueue()
NSUInteger pruneAndCountShipsOnApproach()
void autoDockShipsOnApproach()
void abortDockingForShip:(ShipEntity *ship)
ShipEntity * id_lock[MAX_DOCKING_STAGES]
void addShipToShipsOnApproach:(ShipEntity *ship)
void clearIdLocks:(ShipEntity *ship)
BOOL no_docking_while_launching
BOOL disallowed_docking_collides
NSMutableArray * launchQueue
BOOL disallowedDockingCollides()
void clearDockingCorridor()
OOUniversalID universalID
HPVector absolutePositionForSubentity()
void setVelocity:(Vector vel)
GLfloat collisionRadius()
void setNormalOrientation:(Quaternion quat)
ShipEntity * parentEntity()
void setPosition:(HPVector posn)
BOOL callMethod:inContext:withArguments:count:result:(jsid methodID,[inContext] JSContext *context,[withArguments] jsval *argv,[count] intN argc,[result] jsval *outResult)
StationEntity * getTargetDockStation()
void setDockingClearanceStatus:(OODockingClearanceStatus newValue)
void doScriptEvent:withArgument:andReactToAIMessage:(jsid scriptEvent,[withArgument] id argument,[andReactToAIMessage] NSString *aiMessage)
void setDesiredSpeed:(double amount)
void takeEnergyDamage:from:becauseOf:weaponIdentifier:(double amount, [from] Entity *ent, [becauseOf] Entity *other, [weaponIdentifier] NSString *weaponIdentifier)
void setStatus:(OOEntityStatus stat)
id initWithKey:definition:(NSString *key,[definition] NSDictionary *dict)
void setRoll:(double amount)
void setSpeed:(double amount)
void takeScrapeDamage:from:(double amount,[from] Entity *ent)
void doScriptEvent:(jsid message)
GLint entityPersonalityInt()
BoundingBox totalBoundingBox
void drawImmediate:translucent:(bool immediate, [translucent] bool translucent)
void resetExhaustPlumes()
void setPitch:(double amount)
void setYaw:(double amount)
void setLaunchDelay:(double delay)
void adjustVelocity:(Vector xVel)
void setPendingEscortCount:(uint8_t count)
void sendExpandedMessage:toShip:(NSString *message_text,[toShip] ShipEntity *other_ship)
void update:(OOTimeDelta delta_t)
uint8_t pendingEscortCount()
void noteTakingDamage:from:type:(double amount,[from] Entity *entity,[type] OOShipDamageType type)
void doScriptEvent:withArgument:(jsid message,[withArgument] id argument)
void sendAIMessage:(NSString *message)
void enterDock:(StationEntity *station)
Vector virtualPortDimensions()