54static void DrawWormholeCorona(GLfloat inner_radius, GLfloat outer_radius,
int step, GLfloat z_distance, GLfloat *col4v1);
57@implementation WormholeEntity (Private)
61 if ((
self = [super
init]))
64 shipsInTransit = [[NSMutableArray arrayWithCapacity:4] retain];
65 collision_radius = 0.0;
67 scanClass = CLASS_WORMHOLE;
91 if ((
self = [
self init]))
93 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
97 origin = [dict oo_intForKey:@"origin_id" defaultValue:0];
98 destination = [dict oo_intForKey:@"dest_id" defaultValue:255];
100 originCoords = [[UNIVERSE systemManager] getCoordinatesForSystem:origin inGalaxy:[PLAYER galaxyNumber]];
101 destinationCoords = [[UNIVERSE systemManager] getCoordinatesForSystem:destination inGalaxy:[PLAYER galaxyNumber]];
109 expiry_time = [dict oo_doubleForKey:@"expiry_time"];
110 arrival_time = [dict oo_doubleForKey:@"arrival_time"];
112 if (expiry_time > arrival_time)
114 expiry_time = arrival_time - 1.0;
118 estimated_arrival_time = [dict oo_doubleForKey:@"estimated_arrival_time" defaultValue:arrival_time];
119 position = [dict oo_hpvectorForKey:@"position"];
120 _misjump = [dict oo_boolForKey:@"misjump" defaultValue:NO];
124 NSArray * shipDictsArray = [dict oo_arrayForKey:@"ships"];
125 NSDictionary *currShipDict =
nil;
126 [shipsInTransit removeAllObjects];
127 NSMutableDictionary *restoreContext = [NSMutableDictionary dictionary];
129 foreach (currShipDict, shipDictsArray)
131 NSDictionary *shipInfo = [currShipDict oo_dictionaryForKey:@"ship_info"];
139 [shipsInTransit addObject:[NSDictionary dictionaryWithObjectsAndKeys:
141 [currShipDict objectForKey:@"time_delta"], @"time",
146 OOLog(
@"wormhole.load.warning",
@"Wormhole ship \"%@\
" failed to initialize - missing OXP or old-style saved wormhole data.", [shipInfo oo_stringForKey:
@"ship_key"]);
159 if ((
self = [
self init]))
161 double now = [PLAYER clockTimeAdjusted];
166 origin = [UNIVERSE currentSystemID];
168 originCoords = [PLAYER galaxy_coordinates];
169 destinationCoords = [[UNIVERSE systemManager] getCoordinatesForSystem:destination inGalaxy:[PLAYER galaxyNumber]];
171 distance = fmax(distance, 0.1);
172 witch_mass = 200000.0;
174 witch_mass += [ship mass];
176 if (sun && ([sun willGoNova] || [sun goneNova]) && [ship mass] > 240000)
177 shrink_factor = [ship
mass] / 240000;
181 collision_radius = 0.5 *
M_PI * pow(witch_mass, 1.0/3.0);
183 travel_time = (distance * distance * 3600);
184 arrival_time = now + travel_time;
185 estimated_arrival_time = arrival_time;
192 if (expiry_time > arrival_time)
194 expiry_time = arrival_time - 1.0;
197 zero_distance = HPdistance2([
PLAYER position], position);
210 double time_adjust = distance * distance * (3600 - 2700);
211 arrival_time -= time_adjust;
212 travel_time -= time_adjust;
213 destinationCoords.x = (originCoords.x + destinationCoords.
x) / 2;
214 destinationCoords.y = (originCoords.y + destinationCoords.
y) / 2;
220- (void) setMisjumpWithRange:(GLfloat)range
222 if (range <= 0.0 || range >= 1.0)
226 _misjumpRange = range;
232 double time_adjust = (distance * (1-_misjumpRange))*(distance * (1-_misjumpRange))*3600.0;
235 arrival_time -= time_adjust;
236 travel_time -= time_adjust;
238 destinationCoords.x = (originCoords.x * (1-_misjumpRange)) + (destinationCoords.
x * _misjumpRange);
239 destinationCoords.y = (originCoords.y * (1-_misjumpRange)) + (destinationCoords.
y * _misjumpRange);
251- (GLfloat) misjumpRange
253 return _misjumpRange;
259 if (!ship || [ship status] == STATUS_ENTERING_WITCHSPACE)
268 if ([
PLAYER galaxy_coordinates].
x != originCoords.x || [
PLAYER galaxy_coordinates].y != originCoords.y)
273 double now = [PLAYER clockTimeAdjusted];
278 if( now > expiry_time )
283 float d = HPdistance(position, [ship position]);
284 d -= [ship collisionRadius] + [
self collisionRadius];
292 if (leader && (leader != ship))
295 float leaderShipSpeed = [leader
maxFlightSpeed] * afterburnerFactor;
296 if (leaderShipSpeed < shipSpeed ) shipSpeed = leaderShipSpeed;
298 if (shipSpeed <= 0.0f ) shipSpeed = 0.1f;
299 now += d / shipSpeed;
300 if( now > expiry_time )
306 [shipsInTransit addObject:[NSDictionary dictionaryWithObjectsAndKeys:
308 [NSNumber numberWithDouble: now + travel_time - arrival_time], @"time",
311 witch_mass += [ship mass];
314 if (expiry_time > arrival_time)
316 expiry_time = arrival_time - 1.0;
319 collision_radius = 0.5 *
M_PI * pow(witch_mass, 1.0/3.0);
321 [UNIVERSE addWitchspaceJumpEffectForShip:ship];
324 [ship
setStatus:STATUS_ENTERING_WITCHSPACE];
328 [UNIVERSE removeEntity:ship];
331 if ([ship isStation])
337 [UNIVERSE carryPlayerOn:(StationEntity*)ship inWormhole:self];
346- (void) disgorgeShips
348 double now = [PLAYER clockTimeAdjusted];
349 NSMutableArray* shipsStillInTransit = [[NSMutableArray alloc] initWithCapacity:[shipsInTransit count]];
350 BOOL hasShiftedExitPosition = NO;
351 BOOL useExitXYScatter = NO;
353 NSDictionary *shipInfo =
nil;
354 foreach (shipInfo, shipsInTransit)
356 ShipEntity *ship = [shipInfo objectForKey:@"ship"];
357 NSString *shipBeacon = [shipInfo objectForKey:@"shipBeacon"];
358 double ship_arrival_time = arrival_time + [shipInfo oo_doubleForKey:
@"time"];
359 double time_passed = now - ship_arrival_time;
361 if ([ship status] == STATUS_DEAD)
continue;
363 if (ship_arrival_time > now)
365 [shipsStillInTransit addObject:shipInfo];
370 if (!hasExitPosition)
372 position = [UNIVERSE getWitchspaceExitPosition];
373 GLfloat min_d1 = [UNIVERSE safeWitchspaceExitDistance];
384 if (fabs(d1) < min_d1)
386 d1 += ((d1 > 0.0)? min_d1: -min_d1);
388 position.x += v1.
x * d1;
389 position.y += v1.
y * d1;
390 position.z += v1.z * d1;
393 if (hasExitPosition && (!containsPlayer || useExitXYScatter))
401 double offset_x =
randf()*150.0-75.0;
402 double offset_y =
randf()*150.0-75.0;
403 shippos.x = position.x + (offset_x*exit_vector_x.
x)+(offset_y*exit_vector_y.
x);
404 shippos.y = position.y + (offset_x*exit_vector_x.
y)+(offset_y*exit_vector_y.
y);
405 shippos.z = position.z + (offset_x*exit_vector_x.z)+(offset_y*exit_vector_y.z);
411 [
self setExitSpeed:[ship
maxFlightSpeed]*WORMHOLE_LEADER_SPEED_FACTOR];
414 [PLAYER setSpeed:exit_speed];
416 useExitXYScatter = YES;
420 if (shipBeacon !=
nil)
435 if (time_passed < 2.0)
446 [UNIVERSE addEntity:ship];
458 if (!hasExitPosition)
460 hasExitPosition = YES;
461 hasShiftedExitPosition = YES;
462 [ship
update: time_passed];
465 else if (time_passed > 1)
467 if (hasShiftedExitPosition)
470 [ship
update: (ship_arrival_time - arrival_time)];
476 [ship
update:time_passed];
481 [shipsInTransit release];
482 shipsInTransit = shipsStillInTransit;
488 position = HPvector_add([
PLAYER position], vectorToHPVector(vector_multiply_scalar([
PLAYER forwardVector], -500.0f)));
496- (void) setContainsPlayer:(BOOL)val
498 containsPlayer = val;
502- (void) setExitPosition:(HPVector)pos
504 [
self setPosition: pos];
505 hasExitPosition = YES;
518- (NSPoint) originCoordinates
523- (NSPoint) destinationCoordinates
525 return destinationCoords;
534- (void) setExitSpeed:(
double) speed
545- (double) arrivalTime