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 NSEnumerator *shipDicts = [shipDictsArray objectEnumerator];
126 NSDictionary *currShipDict =
nil;
127 [shipsInTransit removeAllObjects];
128 NSMutableDictionary *restoreContext = [NSMutableDictionary dictionary];
130 while ((currShipDict = [shipDicts nextObject]) !=
nil)
132 NSDictionary *shipInfo = [currShipDict oo_dictionaryForKey:@"ship_info"];
140 [shipsInTransit addObject:[NSDictionary dictionaryWithObjectsAndKeys:
142 [currShipDict objectForKey:@"time_delta"], @"time",
147 OOLog(
@"wormhole.load.warning",
@"Wormhole ship \"%@\
" failed to initialize - missing OXP or old-style saved wormhole data.", [shipInfo oo_stringForKey:
@"ship_key"]);
160 if ((
self = [
self init]))
162 double now = [PLAYER clockTimeAdjusted];
167 origin = [UNIVERSE currentSystemID];
169 originCoords = [PLAYER galaxy_coordinates];
170 destinationCoords = [[UNIVERSE systemManager] getCoordinatesForSystem:destination inGalaxy:[PLAYER galaxyNumber]];
172 distance = fmax(distance, 0.1);
173 witch_mass = 200000.0;
175 witch_mass += [ship mass];
177 if (sun && ([sun willGoNova] || [sun goneNova]) && [ship mass] > 240000)
178 shrink_factor = [ship
mass] / 240000;
182 collision_radius = 0.5 *
M_PI * pow(witch_mass, 1.0/3.0);
184 travel_time = (distance * distance * 3600);
185 arrival_time = now + travel_time;
186 estimated_arrival_time = arrival_time;
193 if (expiry_time > arrival_time)
195 expiry_time = arrival_time - 1.0;
198 zero_distance = HPdistance2([
PLAYER position], position);
211 double time_adjust = distance * distance * (3600 - 2700);
212 arrival_time -= time_adjust;
213 travel_time -= time_adjust;
214 destinationCoords.x = (originCoords.x + destinationCoords.
x) / 2;
215 destinationCoords.y = (originCoords.y + destinationCoords.
y) / 2;
221- (void) setMisjumpWithRange:(GLfloat)range
223 if (range <= 0.0 || range >= 1.0)
227 _misjumpRange = range;
233 double time_adjust = (distance * (1-_misjumpRange))*(distance * (1-_misjumpRange))*3600.0;
236 arrival_time -= time_adjust;
237 travel_time -= time_adjust;
239 destinationCoords.x = (originCoords.x * (1-_misjumpRange)) + (destinationCoords.
x * _misjumpRange);
240 destinationCoords.y = (originCoords.y * (1-_misjumpRange)) + (destinationCoords.
y * _misjumpRange);
252- (GLfloat) misjumpRange
254 return _misjumpRange;
260 if (!ship || [ship status] == STATUS_ENTERING_WITCHSPACE)
269 if ([
PLAYER galaxy_coordinates].
x != originCoords.x || [
PLAYER galaxy_coordinates].y != originCoords.y)
274 double now = [
PLAYER clockTimeAdjusted];
279 if( now > expiry_time )
284 float d = HPdistance(position, [ship position]);
285 d -= [ship collisionRadius] + [
self collisionRadius];
293 if (leader && (leader != ship))
296 float leaderShipSpeed = [leader
maxFlightSpeed] * afterburnerFactor;
297 if (leaderShipSpeed < shipSpeed ) shipSpeed = leaderShipSpeed;
299 if (shipSpeed <= 0.0f ) shipSpeed = 0.1f;
300 now += d / shipSpeed;
301 if( now > expiry_time )
307 [shipsInTransit addObject:[NSDictionary dictionaryWithObjectsAndKeys:
309 [NSNumber numberWithDouble: now + travel_time - arrival_time], @"time",
312 witch_mass += [ship mass];
315 if (expiry_time > arrival_time)
317 expiry_time = arrival_time - 1.0;
320 collision_radius = 0.5 *
M_PI * pow(witch_mass, 1.0/3.0);
322 [UNIVERSE addWitchspaceJumpEffectForShip:ship];
325 [ship
setStatus:STATUS_ENTERING_WITCHSPACE];
329 [UNIVERSE removeEntity:ship];
332 if ([ship isStation])
338 [UNIVERSE carryPlayerOn:(StationEntity*)ship inWormhole:self];
347- (void) disgorgeShips
349 double now = [PLAYER clockTimeAdjusted];
350 NSMutableArray* shipsStillInTransit = [[NSMutableArray alloc] initWithCapacity:[shipsInTransit count]];
351 BOOL hasShiftedExitPosition = NO;
352 BOOL useExitXYScatter = NO;
354 NSDictionary *shipInfo =
nil;
355 foreach (shipInfo, shipsInTransit)
357 ShipEntity *ship = [shipInfo objectForKey:@"ship"];
358 NSString *shipBeacon = [shipInfo objectForKey:@"shipBeacon"];
359 double ship_arrival_time = arrival_time + [shipInfo oo_doubleForKey:
@"time"];
360 double time_passed = now - ship_arrival_time;
362 if ([ship status] == STATUS_DEAD)
continue;
364 if (ship_arrival_time > now)
366 [shipsStillInTransit addObject:shipInfo];
371 if (!hasExitPosition)
373 position = [UNIVERSE getWitchspaceExitPosition];
374 GLfloat min_d1 = [UNIVERSE safeWitchspaceExitDistance];
385 if (fabs(d1) < min_d1)
387 d1 += ((d1 > 0.0)? min_d1: -min_d1);
389 position.x += v1.
x * d1;
390 position.y += v1.
y * d1;
391 position.z += v1.z * d1;
394 if (hasExitPosition && (!containsPlayer || useExitXYScatter))
402 double offset_x =
randf()*150.0-75.0;
403 double offset_y =
randf()*150.0-75.0;
404 shippos.x = position.x + (offset_x*exit_vector_x.
x)+(offset_y*exit_vector_y.
x);
405 shippos.y = position.y + (offset_x*exit_vector_x.
y)+(offset_y*exit_vector_y.
y);
406 shippos.z = position.z + (offset_x*exit_vector_x.z)+(offset_y*exit_vector_y.z);
412 [
self setExitSpeed:[ship
maxFlightSpeed]*WORMHOLE_LEADER_SPEED_FACTOR];
415 [PLAYER setSpeed:exit_speed];
417 useExitXYScatter = YES;
421 if (shipBeacon !=
nil)
428 if (!_misjump) [ship setBounty:[ship bounty]/2 withReason:kOOLegalStatusReasonNewSystem];
436 if (time_passed < 2.0)
447 [UNIVERSE addEntity:ship];
459 if (!hasExitPosition)
461 hasExitPosition = YES;
462 hasShiftedExitPosition = YES;
463 [ship
update: time_passed];
466 else if (time_passed > 1)
468 if (hasShiftedExitPosition)
471 [ship
update: (ship_arrival_time - arrival_time)];
477 [ship
update:time_passed];
482 [shipsInTransit release];
483 shipsInTransit = shipsStillInTransit;
489 position = HPvector_add([
PLAYER position], vectorToHPVector(vector_multiply_scalar([
PLAYER forwardVector], -500.0f)));
497- (void) setContainsPlayer:(BOOL)val
499 containsPlayer = val;
503- (void) setExitPosition:(HPVector)pos
505 [
self setPosition: pos];
506 hasExitPosition = YES;
519- (NSPoint) originCoordinates
524- (NSPoint) destinationCoordinates
526 return destinationCoords;
535- (void) setExitSpeed:(
double) speed
546- (double) arrivalTime