Oolite
Loading...
Searching...
No Matches
PlayerEntity(OOPrivate) Category Reference

Instance Methods

(void) - setExtraEquipmentFromFlags
 
(void) - doTradeIn:forPriceFactor:
 
(void) - updateMovementFlags
 
(void) - updateAlertCondition
 
(void) - updateFuelScoops:
 
(void) - updateClocks:
 
(void) - checkScriptsIfAppropriate
 
(void) - updateTrumbles:
 
(void) - performAutopilotUpdates:
 
(void) - performInFlightUpdates:
 
(void) - performWitchspaceCountdownUpdates:
 
(void) - performWitchspaceExitUpdates:
 
(void) - performLaunchingUpdates:
 
(void) - performDockingUpdates:
 
(void) - performDeadUpdates:
 
(void) - gameOverFadeToBW
 
(void) - updateTargeting
 
(void) - showGameOver
 
(void) - updateWormholes
 
(void) - updateAlertConditionForNearbyEntities
 
(BOOL) - checkEntityForMassLock:withScanClass:
 
(void) - showMarketScreenHeaders
 
(void) - showMarketScreenDataLine:forGood:inMarket:holdQuantity:
 
(void) - showMarketCashAndLoadLine
 
(BOOL) - tryBuyingItem:
 
(NSArray *) - contractsListForScriptingFromArray:forCargo:
 
(void) - prepareMarkedDestination:markers:
 
(void) - witchStart
 
(void) - witchJumpTo:misjump:
 
(void) - witchEnd
 
(double) - hyperspaceJumpDistance
 
(OOFuelQuantity- fuelRequiredForJump
 
(void) - noteCompassLostTarget
 

Detailed Description

Definition at line 113 of file PlayerEntity.m.

Method Documentation

◆ checkEntityForMassLock:withScanClass:

- (BOOL) checkEntityForMassLock: (Entity *)  ent
withScanClass: (int scanClass 

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3364 :(Entity *)ent withScanClass:(int)theirClass
3365{
3366 BOOL massLocked = NO;
3367 BOOL entIsCloakedShip = [ent isShip] && [(ShipEntity *)ent isCloaked];
3368
3369 if (EXPECT_NOT([ent isStellarObject]))
3370 {
3372 if (EXPECT([stellar planetType] != STELLAR_TYPE_MINIATURE))
3373 {
3374 double dist = stellar->zero_distance;
3375 double rad = stellar->collision_radius;
3376 double factor = ([stellar isSun]) ? 2.0 : 4.0;
3377 // plus ensure mass lock when 25 km or less from the surface of small stellar bodies
3378 // dist is a square distance so it needs to be compared to (rad+25000) * (rad+25000)!
3379 if (dist < rad*rad*factor || dist < rad*rad + 50000*rad + 625000000 )
3380 {
3381 massLocked = YES;
3382 }
3383 }
3384 }
3385 else if (theirClass != CLASS_NO_DRAW)
3386 {
3387 if (EXPECT_NOT (entIsCloakedShip))
3388 {
3389 theirClass = CLASS_NO_DRAW;
3390 }
3391 }
3392
3393 if (!massLocked && ent->zero_distance <= SCANNER_MAX_RANGE2)
3394 {
3395 switch (theirClass)
3396 {
3397 case CLASS_NO_DRAW:
3398 // cloaked ships do mass lock! - Nikos 20200718
3399 if (entIsCloakedShip && ![ent isPlayer])
3400 {
3401 massLocked = YES;
3402 }
3403 break;
3404 case CLASS_PLAYER:
3405 case CLASS_BUOY:
3406 case CLASS_ROCK:
3407 case CLASS_CARGO:
3408 case CLASS_MINE:
3409 case CLASS_VISUAL_EFFECT:
3410 break;
3411
3412 case CLASS_THARGOID:
3413 case CLASS_MISSILE:
3414 case CLASS_STATION:
3415 case CLASS_POLICE:
3416 case CLASS_MILITARY:
3417 case CLASS_WORMHOLE:
3418 default:
3419 massLocked = YES;
3420 break;
3421 }
3422 }
3423
3424 return massLocked;
3425}
#define SCANNER_MAX_RANGE2
Definition Entity.h:52
#define EXPECT_NOT(x)
#define EXPECT(x)
@ STELLAR_TYPE_MINIATURE
GLfloat collision_radius
Definition Entity.h:111
BOOL isSun()
Definition Entity.m:168
GLfloat zero_distance
Definition Entity.h:108
unsigned isShip
Definition Entity.h:91
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque

◆ checkScriptsIfAppropriate

- (void) checkScriptsIfAppropriate

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3549{
3550 if (script_time <= script_time_check) return;
3551
3552 if ([self status] != STATUS_IN_FLIGHT)
3553 {
3554 switch (gui_screen)
3555 {
3556 // Screens where no world script tickles are performed
3557 case GUI_SCREEN_MAIN:
3558 case GUI_SCREEN_INTRO1:
3559 case GUI_SCREEN_SHIPLIBRARY:
3560 case GUI_SCREEN_KEYBOARD:
3561 case GUI_SCREEN_NEWGAME:
3562 case GUI_SCREEN_OXZMANAGER:
3563 case GUI_SCREEN_MARKET:
3564 case GUI_SCREEN_MARKETINFO:
3565 case GUI_SCREEN_OPTIONS:
3566 case GUI_SCREEN_GAMEOPTIONS:
3567 case GUI_SCREEN_LOAD:
3568 case GUI_SCREEN_SAVE:
3569 case GUI_SCREEN_SAVE_OVERWRITE:
3570 case GUI_SCREEN_STICKMAPPER:
3571 case GUI_SCREEN_STICKPROFILE:
3572 case GUI_SCREEN_MISSION:
3573 case GUI_SCREEN_REPORT:
3574 case GUI_SCREEN_KEYBOARD_CONFIRMCLEAR:
3575 case GUI_SCREEN_KEYBOARD_CONFIG:
3576 case GUI_SCREEN_KEYBOARD_ENTRY:
3577 case GUI_SCREEN_KEYBOARD_LAYOUT:
3578 return;
3579
3580 // Screens from which it's safe to jump to the mission screen
3581// case GUI_SCREEN_CONTRACTS:
3582 case GUI_SCREEN_EQUIP_SHIP:
3583 case GUI_SCREEN_INTERFACES:
3584 case GUI_SCREEN_MANIFEST:
3585 case GUI_SCREEN_SHIPYARD:
3586 case GUI_SCREEN_LONG_RANGE_CHART:
3587 case GUI_SCREEN_SHORT_RANGE_CHART:
3588 case GUI_SCREEN_STATUS:
3589 case GUI_SCREEN_SYSTEM_DATA:
3590 // Test passed, we can run scripts. Nothing to do here.
3591 break;
3592 }
3593 }
3594
3595 // Test either passed or never ran, run scripts.
3596 [self checkScript];
3597 script_time_check += script_time_interval;
3598}

◆ contractsListForScriptingFromArray:forCargo:

- (NSArray *) contractsListForScriptingFromArray: (NSArray *)  contractsArray
forCargo: (BOOL)  forCargo 

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

8437 :(NSArray *) contracts_array forCargo:(BOOL)forCargo
8438{
8439 NSMutableArray *result = [NSMutableArray array];
8440 NSUInteger i;
8441
8442 for (i = 0; i < [contracts_array count]; i++)
8443 {
8444 NSMutableDictionary *contract = [NSMutableDictionary dictionaryWithCapacity:10];
8445 NSDictionary *dict = [contracts_array oo_dictionaryAtIndex:i];
8446 if (forCargo)
8447 {
8448 // commodity, quantity - keep consistency between .manifest and .contracts
8449 [contract setObject:[dict oo_stringForKey:CARGO_KEY_TYPE] forKey:@"commodity"];
8450 [contract setObject:[NSNumber numberWithUnsignedInt:[dict oo_intForKey:CARGO_KEY_AMOUNT]] forKey:@"quantity"];
8451 [contract setObject:[dict oo_stringForKey:CARGO_KEY_DESCRIPTION] forKey:@"description"];
8452 }
8453 else
8454 {
8455 [contract setObject:[dict oo_stringForKey:PASSENGER_KEY_NAME] forKey:PASSENGER_KEY_NAME];
8456 [contract setObject:[NSNumber numberWithUnsignedInt:[dict oo_unsignedIntForKey:CONTRACT_KEY_RISK]] forKey:CONTRACT_KEY_RISK];
8457 }
8458
8459 OOSystemID planet = [dict oo_intForKey:CONTRACT_KEY_DESTINATION];
8460 NSString *planetName = [UNIVERSE getSystemName:planet];
8461 [contract setObject:[NSNumber numberWithUnsignedInt:planet] forKey:CONTRACT_KEY_DESTINATION];
8462 [contract setObject:planetName forKey:@"destinationName"];
8463 planet = [dict oo_intForKey:CONTRACT_KEY_START];
8464 planetName = [UNIVERSE getSystemName: planet];
8465 [contract setObject:[NSNumber numberWithUnsignedInt:planet] forKey:CONTRACT_KEY_START];
8466 [contract setObject:planetName forKey:@"startName"];
8467
8468 int dest_eta = [dict oo_doubleForKey:CONTRACT_KEY_ARRIVAL_TIME] - ship_clock;
8469 [contract setObject:[NSNumber numberWithInt:dest_eta] forKey:@"eta"];
8470 [contract setObject:[UNIVERSE shortTimeDescription:dest_eta] forKey:@"etaDescription"];
8471 [contract setObject:[NSNumber numberWithInt:[dict oo_intForKey:CONTRACT_KEY_PREMIUM]] forKey:CONTRACT_KEY_PREMIUM];
8472 [contract setObject:[NSNumber numberWithInt:[dict oo_intForKey:CONTRACT_KEY_FEE]] forKey:CONTRACT_KEY_FEE];
8473 [result addObject:contract];
8474 }
8475
8476 return [[result copy] autorelease]; // return an immutable copy
8477}
int16_t OOSystemID
Definition OOTypes.h:211

◆ doTradeIn:forPriceFactor:

- (void) doTradeIn: (OOCreditsQuantity tradeInValue
forPriceFactor: (double)  priceFactor 

Extends class PlayerEntity.

Definition at line 9242 of file PlayerEntity.m.

10696 :(OOCreditsQuantity)tradeInValue forPriceFactor:(double)priceFactor
10697{
10698 if (tradeInValue != 0)
10699 {
10700 if (priceFactor < 1.0) tradeInValue *= priceFactor;
10701 credits += tradeInValue;
10702 }
10703}
uint64_t OOCreditsQuantity
Definition OOTypes.h:182

◆ fuelRequiredForJump

- (OOFuelQuantity) fuelRequiredForJump

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

7511{
7512 return 10.0 * MAX(0.1, [self hyperspaceJumpDistance]);
7513}
#define MAX(A, B)
Definition OOMaths.h:114

◆ gameOverFadeToBW

- (void) gameOverFadeToBW

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3987{
3988 float secondsToBWFadeOut = [[NSUserDefaults standardUserDefaults] oo_floatForKey:@"gameover-seconds-to-bw-fadeout" defaultValue:5.0f];
3989 if ([UNIVERSE detailLevel] >= DETAIL_LEVEL_SHADERS && secondsToBWFadeOut > 0.0f)
3990 {
3991 MyOpenGLView *gameView = [UNIVERSE gameView];
3992 static float originalColorSaturation = -1.0f;
3993 if (originalColorSaturation == -1.0f) originalColorSaturation = [gameView colorSaturation];
3994 if ([self shotTime] < secondsToBWFadeOut)
3995 {
3996 // fade to black & white within secondsToBWFadeOut, independently of
3997 // frame rate and original color saturation
3998 if (fps_counter != 0)
3999 {
4000 [gameView adjustColorSaturation:-(originalColorSaturation * (1.0f / secondsToBWFadeOut) * [UNIVERSE timeAccelerationFactor] / fps_counter)];
4001 }
4002 }
4003
4004 if ([self shotTime] > kDeadResetTime)
4005 {
4006 // make sure to subtract the current saturation because if the user presses space to skip
4007 // the game over screen before the transition to b/w has been completed, whatever is left
4008 // will be added to the original saturation, resulting in an oversaturated image
4009 [gameView adjustColorSaturation:originalColorSaturation - [gameView colorSaturation]];
4010 originalColorSaturation = -1.0f;
4011 }
4012 }
4013}
@ DETAIL_LEVEL_SHADERS
Definition OOTypes.h:246
static float const kDeadResetTime
#define UNIVERSE
Definition Universe.h:842
void adjustColorSaturation:(float colorSaturationAdjustment)
float colorSaturation()

◆ hyperspaceJumpDistance

- (double) hyperspaceJumpDistance

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

7504{
7505 NSPoint targetCoordinates = PointFromString([[UNIVERSE systemManager] getProperty:@"coordinates" forSystem:[self nextHopTargetSystemID] inGalaxy:galaxy_number]);
7506 return distanceBetweenPlanetPositions(targetCoordinates.x,targetCoordinates.y,galaxy_coordinates.x,galaxy_coordinates.y);
7507}
return self
NSPoint PointFromString(NSString *xyString)
OOINLINE double distanceBetweenPlanetPositions(int x1, int y1, int x2, int y2) INLINE_CONST_FUNC

◆ noteCompassLostTarget

- (void) noteCompassLostTarget

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

7523{
7524 if ([[self hud] isCompassActive])
7525 {
7526 // "the compass, it says we're lost!" :)
7527 JSContext *context = OOJSAcquireContext();
7528 jsval jsmode = OOJSValueFromCompassMode(context, [self compassMode]);
7529 ShipScriptEvent(context, self, "compassTargetChanged", JSVAL_VOID, jsmode);
7530 OOJSRelinquishContext(context);
7531
7532 [[self hud] setCompassActive:NO]; // ensure a target change when returning to normal space.
7533 }
7534}
OOINLINE jsval OOJSValueFromCompassMode(JSContext *context, OOCompassMode value)
OOINLINE JSContext * OOJSAcquireContext(void)
OOINLINE void OOJSRelinquishContext(JSContext *context)
#define ShipScriptEvent(context, ship, event,...)

◆ performAutopilotUpdates:

- (void) performAutopilotUpdates: (OOTimeDelta delta_t

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3614 :(OOTimeDelta)delta_t
3615{
3616 [self processBehaviour:delta_t];
3617 [self applyVelocity:delta_t];
3618 [self doBookkeeping:delta_t];
3619}
double OOTimeDelta
Definition OOTypes.h:224

◆ performDeadUpdates:

- (void) performDeadUpdates: (OOTimeDelta delta_t

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3970 :(OOTimeDelta)delta_t
3971{
3972 [UNIVERSE terminatePostFX:OO_POSTFX_CLOAK];
3973 if ([UNIVERSE ECMVisualFXEnabled]) [UNIVERSE terminatePostFX:OO_POSTFX_CRTBADSIGNAL];
3974
3975 [self gameOverFadeToBW];
3976
3977 if ([self shotTime] > kDeadResetTime)
3978 {
3979 BOOL was_mouse_control_on = mouse_control_on;
3980 [UNIVERSE handleGameOver]; // we restart the UNIVERSE
3981 mouse_control_on = was_mouse_control_on;
3982 }
3983}

◆ performDockingUpdates:

- (void) performDockingUpdates: (OOTimeDelta delta_t

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3957 :(OOTimeDelta)delta_t
3958{
3959 if ([UNIVERSE breakPatternOver])
3960 {
3961 [self docked]; // bookkeeping for docking
3962 }
3963
3964 // if cloak or ecm visual effects are playing while docking, terminate them
3965 [UNIVERSE terminatePostFX:OO_POSTFX_CLOAK];
3966 if ([UNIVERSE ECMVisualFXEnabled]) [UNIVERSE terminatePostFX:OO_POSTFX_CRTBADSIGNAL];
3967}

◆ performInFlightUpdates:

- (void) performInFlightUpdates: (OOTimeDelta delta_t

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3766 :(OOTimeDelta)delta_t
3767{
3769
3770 // do flight routines
3772 UPDATE_STAGE(@"applying newtonian drift");
3774
3775 [self applyVelocity:delta_t];
3776
3777 GLfloat thrust_factor = 1.0;
3778 if (flightSpeed > maxFlightSpeed)
3779 {
3780 if (afterburner_engaged)
3781 {
3782 thrust_factor = [self afterburnerFactor];
3783 }
3784 else
3785 {
3786 thrust_factor = HYPERSPEED_FACTOR;
3787 }
3788 }
3789
3790
3791 GLfloat velmag = magnitude(velocity);
3792 GLfloat velmag2 = velmag - (float)delta_t * thrust * thrust_factor;
3793 if (velmag > 0)
3794 {
3795 UPDATE_STAGE(@"applying power braking");
3796
3797 if (velmag > VELOCITY_CLEANUP_MIN)
3798 {
3799 GLfloat rate;
3800 // Fix up extremely ridiculous speeds that can happen in collisions or explosions
3801 if (velmag > VELOCITY_CLEANUP_FULL) rate = VELOCITY_CLEANUP_RATE;
3803 velmag2 -= velmag * rate;
3804 }
3805 if (velmag2 < 0.0f) velocity = kZeroVector;
3806 else velocity = vector_multiply_scalar(velocity, velmag2 / velmag);
3807
3808 }
3809
3810 UPDATE_STAGE(@"updating joystick");
3811 [self applyRoll:(float)delta_t*flightRoll andClimb:(float)delta_t*flightPitch];
3812 if (flightYaw != 0.0)
3813 {
3814 [self applyYaw:(float)delta_t*flightYaw];
3815 }
3816
3817 UPDATE_STAGE(@"applying para-newtonian thrust");
3818 [self moveForward:delta_t*flightSpeed];
3819
3820 UPDATE_STAGE(@"updating targeting");
3821 [self updateTargeting];
3822
3824}
const Vector kZeroVector
Definition OOVector.m:28
#define HYPERSPEED_FACTOR
#define VELOCITY_CLEANUP_MIN
#define STAGE_TRACKING_END
#define UPDATE_STAGE(x)
#define VELOCITY_CLEANUP_RATE
#define STAGE_TRACKING_BEGIN
#define VELOCITY_CLEANUP_FULL

◆ performLaunchingUpdates:

- (void) performLaunchingUpdates: (OOTimeDelta delta_t

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3934 :(OOTimeDelta)delta_t
3935{
3936 if (![UNIVERSE breakPatternHide])
3937 {
3938 flightRoll = launchRoll; // synchronise player's & launching station's spins.
3939 [self doBookkeeping:delta_t]; // don't show ghost exhaust plumes from previous docking!
3940 }
3941
3942 if ([UNIVERSE breakPatternOver])
3943 {
3944 // time to check the legacy scripts!
3945 [self checkScript];
3946 // next check in 10s
3947
3948 [self setStatus:STATUS_IN_FLIGHT];
3949
3950 [self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
3951 StationEntity *stationLaunchedFrom = [UNIVERSE nearestEntityMatchingPredicate:IsStationPredicate parameter:NULL relativeToEntity:self];
3952 [self doScriptEvent:OOJSID("shipLaunchedFromStation") withArgument:stationLaunchedFrom];
3953 }
3954}

◆ performWitchspaceCountdownUpdates:

- (void) performWitchspaceCountdownUpdates: (OOTimeDelta delta_t

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3827 :(OOTimeDelta)delta_t
3828{
3830
3831 UPDATE_STAGE(@"doing bookkeeping");
3832 [self doBookkeeping:delta_t];
3833
3834 UPDATE_STAGE(@"updating countdown timer");
3835 witchspaceCountdown = fdim(witchspaceCountdown, delta_t);
3836
3837 // damaged gal drive? abort!
3838 /* TODO: this check should possibly be hasEquipmentItemProviding:,
3839 * but if it was we'd need to know which item was actually doing
3840 * the providing so it could be removed. */
3841 if (EXPECT_NOT(galactic_witchjump && ![self hasEquipmentItem:@"EQ_GAL_DRIVE"]))
3842 {
3843 galactic_witchjump = NO;
3844 [self setStatus:STATUS_IN_FLIGHT];
3845 [self playHyperspaceAborted];
3846 ShipScriptEventNoCx(self, "playerJumpFailed", OOJSSTR("malfunction"));
3847 return;
3848 }
3849
3850 int seconds = round(witchspaceCountdown);
3851 if (galactic_witchjump)
3852 {
3853 [UNIVERSE displayCountdownMessage:OOExpandKey(@"witch-galactic-in-x-seconds", seconds) forCount:1.0];
3854 }
3855 else
3856 {
3857 NSString *destination = [UNIVERSE getSystemName:[self nextHopTargetSystemID]];
3858 [UNIVERSE displayCountdownMessage:OOExpandKey(@"witch-to-x-in-y-seconds", seconds, destination) forCount:1.0];
3859 }
3860
3861 if (witchspaceCountdown == 0.0)
3862 {
3863 UPDATE_STAGE(@"preloading planet textures");
3864 if (!galactic_witchjump)
3865 {
3866 /* Note: planet texture preloading is done twice for hyperspace jumps:
3867 once when starting the countdown and once at the beginning of the
3868 jump. The reason is that the preloading may have been skipped the
3869 first time because of rate limiting (see notes at
3870 -preloadPlanetTexturesForSystem:). There is no significant overhead
3871 from doing it twice thanks to the texture cache.
3872 -- Ahruman 2009-12-19
3873 */
3874 [UNIVERSE preloadPlanetTexturesForSystem:target_system_id];
3875 }
3876 else
3877 {
3878 // FIXME: preload target system for galactic jump?
3879 }
3880
3881 UPDATE_STAGE(@"JUMP!");
3882 if (galactic_witchjump) [self enterGalacticWitchspace];
3883 else [self enterWitchspace];
3884 galactic_witchjump = NO;
3885 }
3886
3888}
#define OOJSSTR(str)
#define ShipScriptEventNoCx(ship, event,...)

◆ performWitchspaceExitUpdates:

- (void) performWitchspaceExitUpdates: (OOTimeDelta delta_t

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3891 :(OOTimeDelta)delta_t
3892{
3893 if ([UNIVERSE breakPatternOver])
3894 {
3895 [self resetExhaustPlumes];
3896 // time to check the script!
3897 [self checkScript];
3898 // next check in 10s
3899 [self resetScriptTimer]; // reset the in-system timer
3900
3901 // announce arrival
3902 if ([UNIVERSE planet])
3903 {
3904 [UNIVERSE addMessage:[NSString stringWithFormat:@" %@. ",[UNIVERSE getSystemName:system_id]] forCount:3.0];
3905 // and reset the compass
3906 if ([self hasEquipmentItemProviding:@"EQ_ADVANCED_COMPASS"])
3907 compassMode = COMPASS_MODE_PLANET;
3908 else
3909 compassMode = COMPASS_MODE_BASIC;
3910 }
3911 else
3912 {
3913 if ([UNIVERSE inInterstellarSpace]) [UNIVERSE addMessage:DESC(@"witch-engine-malfunction") forCount:3.0]; // if sun gone nova, print nothing
3914 }
3915
3916 [self setStatus:STATUS_IN_FLIGHT];
3917
3918 // If we are exiting witchspace after a scripted misjump. then make sure it gets reset now.
3919 // Scripted misjump situations should have a lifespan of one jump only, to keep things
3920 // simple - Nikos 20090728
3921 if ([self scriptedMisjump]) [self setScriptedMisjump:NO];
3922 // similarly reset the misjump range to the traditional 0.5
3923 [self setScriptedMisjumpRange:0.5];
3924
3925 [self doScriptEvent:OOJSID("shipExitedWitchspace") withArgument:[self jumpCause]];
3926
3927 [self doBookkeeping:delta_t]; // arrival frame updates
3928
3929 suppressAegisMessages=NO;
3930 }
3931}

◆ prepareMarkedDestination:markers:

- (void) prepareMarkedDestination: (NSMutableDictionary *) 
markers: (NSDictionary *)  marker 

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

8728 :(NSMutableDictionary *)markers :(NSDictionary *)marker
8729{
8730 NSNumber *key = [NSNumber numberWithInt:[marker oo_intForKey:@"system"]];
8731 NSMutableArray *list = [markers objectForKey:key];
8732 if (list == nil)
8733 {
8734 list = [NSMutableArray arrayWithObject:marker];
8735 }
8736 else
8737 {
8738 [list addObject:marker];
8739 }
8740 [markers setObject:list forKey:key];
8741}
return nil

◆ setExtraEquipmentFromFlags

- (void) setExtraEquipmentFromFlags

◆ showGameOver

- (void) showGameOver

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

4059{
4060 [hud resetGuis:[NSDictionary dictionaryWithObject:[NSDictionary dictionary] forKey:@"message_gui"]];
4061 NSString *scoreMS = [NSString stringWithFormat:OOExpandKey(@"gameoverscreen-score-@"),
4062 KillCountToRatingAndKillString(ship_kills)];
4063
4064 [UNIVERSE displayMessage:OOExpandKey(@"gameoverscreen-game-over") forCount:kDeadResetTime];
4065 [UNIVERSE displayMessage:@"" forCount:kDeadResetTime];
4066 [UNIVERSE displayMessage:scoreMS forCount:kDeadResetTime];
4067 [UNIVERSE displayMessage:@"" forCount:kDeadResetTime];
4068 [UNIVERSE displayMessage:OOExpandKey(@"gameoverscreen-press-space") forCount:kDeadResetTime];
4069 [UNIVERSE displayMessage:@" " forCount:kDeadResetTime];
4070 [UNIVERSE displayMessage:@"" forCount:kDeadResetTime];
4071 [self resetShotTime];
4072}

◆ showMarketCashAndLoadLine

- (void) showMarketCashAndLoadLine

Extends class PlayerEntity.

Definition at line 9242 of file PlayerEntity.m.

11347{
11348 GuiDisplayGen *gui = [UNIVERSE gui];
11349 OOCargoQuantity currentCargo = current_cargo;
11350 OOCargoQuantity cargoCapacity = [self maxAvailableCargoSpace];
11351 [gui setText:OOExpandKey(@"market-cash-and-load", credits, currentCargo, cargoCapacity) forRow:GUI_ROW_MARKET_CASH];
11352 [gui setColor:[gui colorFromSetting:kGuiMarketCashColor defaultValue:[OOColor yellowColor]] forRow:GUI_ROW_MARKET_CASH];
11353}
uint32_t OOCargoQuantity
Definition OOTypes.h:176
OOColor * colorFromSetting:defaultValue:(NSString *setting,[defaultValue] OOColor *def)
void setText:forRow:(NSString *str,[forRow] OOGUIRow row)
void setColor:forRow:(OOColor *color,[forRow] OOGUIRow row)
OOColor * yellowColor()
Definition OOColor.m:292

◆ showMarketScreenDataLine:forGood:inMarket:holdQuantity:

- (void) showMarketScreenDataLine: (OOGUIRow row
forGood: (OOCommodityType good
inMarket: (OOCommodityMarket *)  localMarket
holdQuantity: (OOCargoQuantity quantity 

Extends class PlayerEntity.

Definition at line 9242 of file PlayerEntity.m.

10952 :(OOGUIRow)row forGood:(OOCommodityType)good inMarket:(OOCommodityMarket *)localMarket holdQuantity:(OOCargoQuantity)quantity
10953{
10954 GuiDisplayGen *gui = [UNIVERSE gui];
10955 NSString* desc = [NSString stringWithFormat:@" %@ ", [shipCommodityData nameForGood:good]];
10956 OOCargoQuantity available_units = [localMarket quantityForGood:good];
10957 OOCargoQuantity units_in_hold = quantity;
10958 OOCreditsQuantity pricePerUnit = [localMarket priceForGood:good];
10959 OOMassUnit unit = [shipCommodityData massUnitForGood:good];
10960
10961 NSString *available = OOPadStringToEms(((available_units > 0) ? (NSString *)[NSString stringWithFormat:@"%d",available_units] : DESC(@"commodity-quantity-none")), 2.5);
10962
10963 NSUInteger priceDecimal = pricePerUnit % 10;
10964 NSString *price = [NSString stringWithFormat:@" %@.%llu ",OOPadStringToEms([NSString stringWithFormat:@"%lu",(unsigned long)(pricePerUnit/10)],2.5),priceDecimal];
10965
10966 // this works with up to 9999 tons of gemstones. Any more than that, they deserve the formatting they get! :)
10967
10968 NSString *owned = OOPadStringToEms((units_in_hold > 0) ? (NSString *)[NSString stringWithFormat:@"%d",units_in_hold] : DESC(@"commodity-quantity-none"), 4.5);
10969 NSString *units = DisplayStringForMassUnit(unit);
10970 NSString *units_available = [NSString stringWithFormat:@" %@ %@ ",available, units];
10971 NSString *units_owned = [NSString stringWithFormat:@" %@ %@ ",owned, units];
10972
10973 NSUInteger import_legality = [localMarket importLegalityForGood:good];
10974 NSUInteger export_legality = [localMarket exportLegalityForGood:good];
10975 NSString *legaldesc = nil;
10976 if (import_legality == 0)
10977 {
10978 if (export_legality == 0)
10979 {
10980 legaldesc = DESC(@"oolite-legality-clear");
10981 }
10982 else
10983 {
10984 legaldesc = DESC(@"oolite-legality-import");
10985 }
10986 }
10987 else
10988 {
10989 if (export_legality == 0)
10990 {
10991 legaldesc = DESC(@"oolite-legality-export");
10992 }
10993 else
10994 {
10995 legaldesc = DESC(@"oolite-legality-neither");
10996 }
10997 }
10998 legaldesc = [NSString stringWithFormat:@" %@ ",legaldesc];
10999
11000 NSString *extradesc = [shipCommodityData shortCommentForGood:good];
11001
11002 [gui setKey:good forRow:row];
11003 [gui setColor:[gui colorFromSetting:kGuiMarketCommodityColor defaultValue:nil] forRow:row];
11004 [gui setArray:[NSArray arrayWithObjects: desc, extradesc, price, units_available, units_owned, legaldesc, nil] forRow:row++];
11005
11006}
NSInteger OOGUIRow
NSString * DisplayStringForMassUnit(OOMassUnit unit)
NSString * OOPadStringToEms(NSString *string, float numEms)
NSString * OOCommodityType
Definition OOTypes.h:106
OOMassUnit
Definition OOTypes.h:123
#define DESC(key)
Definition Universe.h:848
void setArray:forRow:(NSArray *arr,[forRow] OOGUIRow row)
void setKey:forRow:(NSString *str,[forRow] OOGUIRow row)
NSUInteger exportLegalityForGood:(OOCommodityType good)
NSUInteger importLegalityForGood:(OOCommodityType good)
OOCargoQuantity quantityForGood:(OOCommodityType good)
OOCreditsQuantity priceForGood:(OOCommodityType good)

◆ showMarketScreenHeaders

- (void) showMarketScreenHeaders

Extends class PlayerEntity.

Definition at line 9242 of file PlayerEntity.m.

10931{
10932 GuiDisplayGen *gui = [UNIVERSE gui];
10933 OOGUITabSettings tab_stops;
10934 tab_stops[0] = 0;
10935 tab_stops[1] = 137;
10936 tab_stops[2] = 187;
10937 tab_stops[3] = 267;
10938 tab_stops[4] = 321;
10939 tab_stops[5] = 431;
10940 [gui overrideTabs:tab_stops from:kGuiMarketTabs length:6];
10941 [gui setTabStops:tab_stops];
10942
10943 [gui setColor:[gui colorFromSetting:kGuiMarketHeadingColor defaultValue:[OOColor greenColor]] forRow:GUI_ROW_MARKET_KEY];
10944 [gui setArray:[NSArray arrayWithObjects: DESC(@"commodity-column-title"), OOPadStringToEms(DESC(@"price-column-title"),3.5),
10945 OOPadStringToEms(DESC(@"for-sale-column-title"),3.75), OOPadStringToEms(DESC(@"in-hold-column-title"),5.75), DESC(@"oolite-legality-column-title"), DESC(@"oolite-extras-column-title"), nil] forRow:GUI_ROW_MARKET_KEY];
10946 [gui setArray:[NSArray arrayWithObjects: DESC(@"commodity-column-title"), DESC(@"oolite-extras-column-title"), OOPadStringToEms(DESC(@"price-column-title"),3.5),
10947 OOPadStringToEms(DESC(@"for-sale-column-title"),3.75), OOPadStringToEms(DESC(@"in-hold-column-title"),5.75), DESC(@"oolite-legality-column-title"), nil] forRow:GUI_ROW_MARKET_KEY];
10948
10949}
OOGUITabStop OOGUITabSettings[GUI_MAX_COLUMNS]
void overrideTabs:from:length:(OOGUITabSettings stops,[from] NSString *setting,[length] NSUInteger len)
void setTabStops:(OOGUITabSettings stops)
OOColor * greenColor()
Definition OOColor.m:274

◆ tryBuyingItem:

- (BOOL) tryBuyingItem: (NSString *)  eqKey

Extends class PlayerEntity.

Definition at line 9242 of file PlayerEntity.m.

10336 :(NSString *)eqKey
10337{
10338 // note this doesn't check the availability by tech-level
10340 OOCreditsQuantity pricePerUnit = [eqType price];
10341 NSString *eqKeyDamaged = [eqType damagedIdentifier];
10342 double price = pricePerUnit;
10343 double priceFactor = 1.0;
10344 OOCreditsQuantity tradeIn = 0;
10345 BOOL isRepair = NO;
10346
10347 // repairs cost 50%
10348 if ([self hasEquipmentItem:eqKeyDamaged])
10349 {
10350 price /= 2.0;
10351 isRepair = YES;
10352 }
10353
10354 if ([eqKey isEqualToString:@"EQ_RENOVATION"])
10355 {
10356 price = [self renovationCosts];
10357 }
10358
10359 price = [self adjustPriceByScriptForEqKey:eqKey withCurrent:price];
10360
10361 StationEntity *dockedStation = [self dockedStation];
10362 if (dockedStation)
10363 {
10364 priceFactor = [dockedStation equipmentPriceFactor];
10365 }
10366
10367 price *= priceFactor; // increased prices at some stations
10368
10369 if (price > credits)
10370 {
10371 return NO;
10372 }
10373
10374 if ([eqType isPrimaryWeapon])
10375 {
10376 if (chosen_weapon_facing == WEAPON_FACING_NONE)
10377 {
10378 [self setGuiToEquipShipScreen:0 selectingFacingFor:eqKey]; // reset
10379 return YES;
10380 }
10381
10383 OOWeaponType current_weapon = nil;
10384
10385 NSUInteger multiplier = 1;
10386
10387 switch (chosen_weapon_facing)
10388 {
10390 current_weapon = forward_weapon_type;
10391 forward_weapon_type = chosen_weapon;
10392 if (_multiplyWeapons)
10393 {
10394 multiplier = [forwardWeaponOffset count];
10395 }
10396 break;
10397
10398 case WEAPON_FACING_AFT:
10399 current_weapon = aft_weapon_type;
10400 aft_weapon_type = chosen_weapon;
10401 if (_multiplyWeapons)
10402 {
10403 multiplier = [aftWeaponOffset count];
10404 }
10405 break;
10406
10407 case WEAPON_FACING_PORT:
10408 current_weapon = port_weapon_type;
10409 port_weapon_type = chosen_weapon;
10410 if (_multiplyWeapons)
10411 {
10412 multiplier = [portWeaponOffset count];
10413 }
10414 break;
10415
10417 current_weapon = starboard_weapon_type;
10418 starboard_weapon_type = chosen_weapon;
10419 if (_multiplyWeapons)
10420 {
10421 multiplier = [starboardWeaponOffset count];
10422 }
10423 break;
10424
10425 case WEAPON_FACING_NONE:
10426 break;
10427 }
10428
10429 price *= multiplier;
10430
10431 if (price > credits)
10432 {
10433 // not enough money - ensure that weapon
10434 // type is reset to what it was before
10435 // the attempt to buy took place
10436 switch (chosen_weapon_facing)
10437 {
10439 forward_weapon_type = current_weapon;
10440 break;
10441 case WEAPON_FACING_AFT:
10442 aft_weapon_type = current_weapon;
10443 break;
10444 case WEAPON_FACING_PORT:
10445 port_weapon_type = current_weapon;
10446 break;
10448 starboard_weapon_type = current_weapon;
10449 break;
10450 case WEAPON_FACING_NONE:
10451 break;
10452 }
10453 return NO;
10454 }
10455 credits -= price;
10456
10457 // Refund current_weapon
10458 if (current_weapon != nil)
10459 {
10460 tradeIn = [UNIVERSE getEquipmentPriceForKey:OOEquipmentIdentifierFromWeaponType(current_weapon)] * multiplier;
10461 }
10462
10463 [self doTradeIn:tradeIn forPriceFactor:priceFactor];
10464 // If equipped, remove damaged weapon after repairs. -- But there's no way we should get a damaged weapon. Ever.
10465 [self removeEquipmentItem:eqKeyDamaged];
10466 return YES;
10467 }
10468
10469 if ([eqType isMissileOrMine] && missiles >= max_missiles)
10470 {
10471 OOLog(@"equip.buy.mounted.failed.full", @"%@", @"rejecting missile because already full");
10472 return NO;
10473 }
10474
10475 // NSFO!
10476 //unsigned passenger_space = [[OOEquipmentType equipmentTypeWithIdentifier:@"EQ_PASSENGER_BERTH"] requiredCargoSpace];
10477 //if (passenger_space == 0) passenger_space = PASSENGER_BERTH_SPACE;
10478
10479 if ([eqKey isEqualToString:@"EQ_PASSENGER_BERTH"] && [self availableCargoSpace] < PASSENGER_BERTH_SPACE)
10480 {
10481 return NO;
10482 }
10483
10484 if ([eqKey isEqualToString:@"EQ_FUEL"])
10485 {
10486#if MASS_DEPENDENT_FUEL_PRICES
10487 OOCreditsQuantity creditsForRefuel = ([self fuelCapacity] - [self fuel]) * pricePerUnit * [self fuelChargeRate];
10488#else
10489 OOCreditsQuantity creditsForRefuel = ([self fuelCapacity] - [self fuel]) * pricePerUnit;
10490#endif
10491 if (credits >= creditsForRefuel) // Ensure we don't overflow
10492 {
10493 credits -= creditsForRefuel;
10494 fuel = [self fuelCapacity];
10495 return YES;
10496 }
10497 else
10498 {
10499 return NO;
10500 }
10501 }
10502
10503 // check energy unit replacement
10504 if ([eqKey hasSuffix:@"ENERGY_UNIT"] && [self energyUnitType] != ENERGY_UNIT_NONE)
10505 {
10506 switch ([self energyUnitType])
10507 {
10508 case ENERGY_UNIT_NAVAL :
10509 [self removeEquipmentItem:@"EQ_NAVAL_ENERGY_UNIT"];
10510 tradeIn = [UNIVERSE getEquipmentPriceForKey:@"EQ_NAVAL_ENERGY_UNIT"] / 2; // 50 % refund
10511 break;
10513 [self removeEquipmentItem:@"EQ_NAVAL_ENERGY_UNIT_DAMAGED"];
10514 tradeIn = [UNIVERSE getEquipmentPriceForKey:@"EQ_NAVAL_ENERGY_UNIT"] / 4; // half of the working one
10515 break;
10516 case ENERGY_UNIT_NORMAL :
10517 [self removeEquipmentItem:@"EQ_ENERGY_UNIT"];
10518 tradeIn = [UNIVERSE getEquipmentPriceForKey:@"EQ_ENERGY_UNIT"] * 3 / 4; // 75 % refund
10519 break;
10521 [self removeEquipmentItem:@"EQ_ENERGY_UNIT_DAMAGED"];
10522 tradeIn = [UNIVERSE getEquipmentPriceForKey:@"EQ_ENERGY_UNIT"] * 3 / 8; // half of the working one
10523 break;
10524
10525 default:
10526 break;
10527 }
10528 [self doTradeIn:tradeIn forPriceFactor:priceFactor];
10529 }
10530
10531 // maintain ship
10532 if ([eqKey isEqualToString:@"EQ_RENOVATION"])
10533 {
10534 OOTechLevelID techLevel = NSNotFound;
10535 if (dockedStation != nil) techLevel = [dockedStation equivalentTechLevel];
10536 if (techLevel == NSNotFound) techLevel = [[UNIVERSE currentSystemData] oo_unsignedIntForKey:KEY_TECHLEVEL];
10537
10538 credits -= price;
10539 ship_trade_in_factor += 5 + techLevel; // you get better value at high-tech repair bases
10540 if (ship_trade_in_factor > 100) ship_trade_in_factor = 100;
10541
10542 [self clearSubEntities];
10543 [self setUpSubEntities];
10544
10545 return YES;
10546 }
10547
10548 if ([eqKey hasSuffix:@"MISSILE"] || [eqKey hasSuffix:@"MINE"])
10549 {
10550 ShipEntity* weapon = [[UNIVERSE newShipWithRole:eqKey] autorelease];
10551 if (weapon) OOLog(kOOLogBuyMountedOK, @"Got ship for mounted weapon role %@", eqKey);
10552 else OOLog(kOOLogBuyMountedFailed, @"Could not find ship for mounted weapon role %@", eqKey);
10553
10554 BOOL mounted_okay = [self mountMissile:weapon];
10555 if (mounted_okay)
10556 {
10557 credits -= price;
10558 [self safeAllMissiles];
10559 [self tidyMissilePylons];
10560 [self setActiveMissile:0];
10561 }
10562 return mounted_okay;
10563 }
10564
10565 if ([eqKey isEqualToString:@"EQ_PASSENGER_BERTH"])
10566 {
10567 [self changePassengerBerths:+1];
10568 credits -= price;
10569 return YES;
10570 }
10571
10572 if ([eqKey isEqualToString:@"EQ_PASSENGER_BERTH_REMOVAL"])
10573 {
10574 [self changePassengerBerths:-1];
10575 credits -= price;
10576 return YES;
10577 }
10578
10579 if ([eqKey isEqualToString:@"EQ_MISSILE_REMOVAL"])
10580 {
10581 credits -= price;
10582 tradeIn += [self removeMissiles];
10583 [self doTradeIn:tradeIn forPriceFactor:priceFactor];
10584 return YES;
10585 }
10586
10587 if ([self canAddEquipment:eqKey inContext:@"purchase"])
10588 {
10589 credits -= price;
10590 [self addEquipmentItem:eqKey withValidation:NO inContext:@"purchase"]; // no need to validate twice.
10591 if (isRepair)
10592 {
10593 [self doScriptEvent:OOJSID("equipmentRepaired") withArgument:eqKey];
10594 }
10595 return YES;
10596 }
10597
10598 return NO;
10599}
#define OOLog(class, format,...)
Definition OOLogging.h:88
NSUInteger OOTechLevelID
Definition OOTypes.h:204
@ WEAPON_FACING_FORWARD
Definition OOTypes.h:229
@ WEAPON_FACING_NONE
Definition OOTypes.h:234
@ WEAPON_FACING_AFT
Definition OOTypes.h:230
@ WEAPON_FACING_PORT
Definition OOTypes.h:231
@ WEAPON_FACING_STARBOARD
Definition OOTypes.h:232
@ ENERGY_UNIT_NORMAL
Definition OOTypes.h:137
@ ENERGY_UNIT_NAVAL_DAMAGED
Definition OOTypes.h:134
@ ENERGY_UNIT_NAVAL
Definition OOTypes.h:138
@ ENERGY_UNIT_NONE
Definition OOTypes.h:132
@ ENERGY_UNIT_NORMAL_DAMAGED
Definition OOTypes.h:133
static NSString *const kOOLogBuyMountedOK
static NSString *const kOOLogBuyMountedFailed
OOWeaponType OOWeaponTypeFromEquipmentIdentifierStrict(NSString *string) PURE_FUNC
#define PASSENGER_BERTH_SPACE
Definition Universe.h:152
NSString * damagedIdentifier()
OOEquipmentType * equipmentTypeWithIdentifier:(NSString *identifier)
OOCreditsQuantity price()
OOTechLevelID equivalentTechLevel
float equipmentPriceFactor

◆ updateAlertCondition

- (void) updateAlertCondition

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3429{
3430 [self updateAlertConditionForNearbyEntities];
3431 /* TODO: update alert condition once per frame. Tried this before, but
3432 there turned out to be complications. See mailing list archive.
3433 -- Ahruman 20070802
3434 */
3435 OOAlertCondition cond = [self alertCondition];
3436 OOTimeAbsolute t = [UNIVERSE getTime];
3437 if (cond != lastScriptAlertCondition)
3438 {
3439 ShipScriptEventNoCx(self, "alertConditionChanged", INT_TO_JSVAL(cond), INT_TO_JSVAL(lastScriptAlertCondition));
3440 lastScriptAlertCondition = cond;
3441 }
3442 /* Update heuristic assessment of whether player is fleeing */
3443 if (cond == ALERT_CONDITION_DOCKED || cond == ALERT_CONDITION_GREEN || (cond == ALERT_CONDITION_YELLOW && energy == maxEnergy))
3444 {
3445 fleeing_status = PLAYER_FLEEING_NONE;
3446 }
3447 else if (fleeing_status == PLAYER_FLEEING_UNLIKELY && (energy > maxEnergy*0.6 || cond != ALERT_CONDITION_RED))
3448 {
3449 fleeing_status = PLAYER_FLEEING_NONE;
3450 }
3451 else if ((fleeing_status == PLAYER_FLEEING_MAYBE || fleeing_status == PLAYER_FLEEING_UNLIKELY) && cargo_dump_time > last_shot_time)
3452 {
3453 fleeing_status = PLAYER_FLEEING_CARGO;
3454 }
3455 else if (fleeing_status == PLAYER_FLEEING_MAYBE && last_shot_time + 10 > t)
3456 {
3457 fleeing_status = PLAYER_FLEEING_NONE;
3458 }
3459 else if (fleeing_status == PLAYER_FLEEING_LIKELY && last_shot_time + 10 > t)
3460 {
3461 fleeing_status = PLAYER_FLEEING_UNLIKELY;
3462 }
3463 else if (fleeing_status == PLAYER_FLEEING_NONE && cond == ALERT_CONDITION_RED && last_shot_time + 10 < t && flightSpeed > 0.75*maxFlightSpeed)
3464 {
3465 fleeing_status = PLAYER_FLEEING_MAYBE;
3466 }
3467 else if ((fleeing_status == PLAYER_FLEEING_MAYBE || fleeing_status == PLAYER_FLEEING_CARGO) && cond == ALERT_CONDITION_RED && last_shot_time + 10 < t && flightSpeed > 0.75*maxFlightSpeed && energy < maxEnergy * 0.5 && (forward_shield < [self maxForwardShieldLevel]*0.25 || aft_shield < [self maxAftShieldLevel]*0.25))
3468 {
3469 fleeing_status = PLAYER_FLEEING_LIKELY;
3470 }
3471}
double OOTimeAbsolute
Definition OOTypes.h:223
@ PLAYER_FLEEING_MAYBE
@ PLAYER_FLEEING_LIKELY
@ PLAYER_FLEEING_NONE
@ PLAYER_FLEEING_CARGO
@ PLAYER_FLEEING_UNLIKELY
OOAlertCondition
Definition ShipEntity.h:172
@ ALERT_CONDITION_GREEN
Definition ShipEntity.h:176
@ ALERT_CONDITION_RED
Definition ShipEntity.h:178
@ ALERT_CONDITION_YELLOW
Definition ShipEntity.h:177
@ ALERT_CONDITION_DOCKED
Definition ShipEntity.h:175

◆ updateAlertConditionForNearbyEntities

- (void) updateAlertConditionForNearbyEntities

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3218{
3219 if (![self isInSpace] || [self status] == STATUS_DOCKING)
3220 {
3221 [self clearAlertFlags];
3222 // not needed while docked
3223 return;
3224 }
3225
3226 int i, ent_count = UNIVERSE->n_entities;
3227 Entity **uni_entities = UNIVERSE->sortedEntities; // grab the public sorted list
3228 Entity *my_entities[ent_count];
3229 Entity *scannedEntity = nil;
3230 for (i = 0; i < ent_count; i++)
3231 {
3232 my_entities[i] = [uni_entities[i] retain]; // retained
3233 }
3234 BOOL massLocked = NO;
3235 BOOL foundHostiles = NO;
3236#if OO_VARIABLE_TORUS_SPEED
3237 BOOL needHyperspeedNearest = YES;
3238 double hsnDistance = 0;
3239#endif
3240 for (i = 0; i < ent_count; i++) // scanner lollypops
3241 {
3242 scannedEntity = my_entities[i];
3243
3244#if OO_VARIABLE_TORUS_SPEED
3245 if (EXPECT_NOT(needHyperspeedNearest))
3246 {
3247 // not visual effects, waypoints, ships, etc.
3248 if (scannedEntity != self && [scannedEntity canCollide] && (![scannedEntity isShip] || ![self collisionExceptedFor:(ShipEntity *) scannedEntity]))
3249 {
3250 hsnDistance = sqrt(scannedEntity->zero_distance)-[scannedEntity collisionRadius];
3251 needHyperspeedNearest = NO;
3252 }
3253 }
3254 else if ([scannedEntity isStellarObject])
3255 {
3256 // planets, stars might be closest surface even if not
3257 // closest centre. That could be true of others, but the
3258 // error is negligible there.
3259 double thisHSN = sqrt(scannedEntity->zero_distance)-[scannedEntity collisionRadius];
3260 if (thisHSN < hsnDistance)
3261 {
3262 hsnDistance = thisHSN;
3263 }
3264 }
3265#endif
3266
3267 if (scannedEntity->zero_distance < SCANNER_MAX_RANGE2 || !scannedEntity->isShip)
3268 {
3269 int theirClass = [scannedEntity scanClass];
3270 // here we could also force masslock for higher than yellow alert, but
3271 // if we are going to hand over masslock control to scripting, might as well
3272 // hand it over fully
3273 if ([self massLockable] /*|| alertFlags > ALERT_FLAG_YELLOW_LIMIT*/)
3274 {
3275 massLocked |= [self checkEntityForMassLock:scannedEntity withScanClass:theirClass]; // we just need one masslocker..
3276 }
3277 if (theirClass != CLASS_NO_DRAW)
3278 {
3279 if (theirClass == CLASS_THARGOID || [scannedEntity isCascadeWeapon])
3280 {
3281 foundHostiles = YES;
3282 }
3283 else if ([scannedEntity isShip])
3284 {
3285 ShipEntity *ship = (ShipEntity *)scannedEntity;
3286 foundHostiles |= (([ship hasHostileTarget])&&([ship primaryTarget] == self));
3287 }
3288 }
3289 }
3290 }
3291#if OO_VARIABLE_TORUS_SPEED
3292 if (EXPECT_NOT(needHyperspeedNearest))
3293 {
3294 // this case should only occur in an otherwise empty
3295 // interstellar space - unlikely but possible
3296 hyperspeedFactor = MIN_HYPERSPEED_FACTOR;
3297 }
3298 else
3299 {
3300 // once nearest object is >4x scanner range
3301 // start increasing torus speed
3302 double factor = hsnDistance/(4*SCANNER_MAX_RANGE);
3303 if (factor < 1.0)
3304 {
3305 hyperspeedFactor = MIN_HYPERSPEED_FACTOR;
3306 }
3307 else
3308 {
3309 hyperspeedFactor = MIN_HYPERSPEED_FACTOR * sqrt(factor);
3310 if (hyperspeedFactor > MAX_HYPERSPEED_FACTOR)
3311 {
3312 // caps out at ~10^8m from nearest object
3313 // which takes ~10 minutes of flying
3314 hyperspeedFactor = MAX_HYPERSPEED_FACTOR;
3315 }
3316 }
3317 }
3318#endif
3319
3320 [self setAlertFlag:ALERT_FLAG_MASS_LOCK to:massLocked];
3321
3322 [self setAlertFlag:ALERT_FLAG_HOSTILES to:foundHostiles];
3323
3324 for (i = 0; i < ent_count; i++)
3325 {
3326 [my_entities[i] release]; // released
3327 }
3328
3329 BOOL energyCritical = NO;
3330 if (energy < 64 && energy < maxEnergy * 0.8)
3331 {
3332 energyCritical = YES;
3333 }
3334 [self setAlertFlag:ALERT_FLAG_ENERGY to:energyCritical];
3335
3336 [self setAlertFlag:ALERT_FLAG_TEMP to:([self hullHeatLevel] > .90)];
3337
3338 [self setAlertFlag:ALERT_FLAG_ALT to:([self dialAltitude] < .10)];
3339
3340}
#define SCANNER_MAX_RANGE
Definition Entity.h:51
#define MAX_HYPERSPEED_FACTOR
#define MIN_HYPERSPEED_FACTOR
OOScanClass scanClass
Definition Entity.h:106
BOOL hasHostileTarget()

◆ updateClocks:

- (void) updateClocks: (OOTimeDelta delta_t

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3488 :(OOTimeDelta)delta_t
3489{
3490 // shot time updates are still needed here for STATUS_DEAD!
3491 shot_time += delta_t;
3492 script_time += delta_t;
3493 unsigned prev_day = floor(ship_clock / 86400);
3494 ship_clock += delta_t;
3495 if (ship_clock_adjust > 0.0) // adjust for coming out of warp (add LY * LY hrs)
3496 {
3497 double fine_adjust = delta_t * 7200.0;
3498 if (ship_clock_adjust > 86400) // more than a day
3499 fine_adjust = delta_t * 115200.0; // 16 times faster
3500 if (ship_clock_adjust > 0)
3501 {
3502 if (fine_adjust > ship_clock_adjust)
3503 fine_adjust = ship_clock_adjust;
3504 ship_clock += fine_adjust;
3505 ship_clock_adjust -= fine_adjust;
3506 }
3507 else
3508 {
3509 if (fine_adjust < ship_clock_adjust)
3510 fine_adjust = ship_clock_adjust;
3511 ship_clock -= fine_adjust;
3512 ship_clock_adjust += fine_adjust;
3513 }
3514 }
3515 else
3516 ship_clock_adjust = 0.0;
3517
3518 unsigned now_day = floor(ship_clock / 86400.0);
3519 while (prev_day < now_day)
3520 {
3521 prev_day++;
3522 [self doScriptEvent:OOJSID("dayChanged") withArgument:[NSNumber numberWithUnsignedInt:prev_day]];
3523 // not impossible that at ultra-low frame rates two of these will
3524 // happen in a single update.
3525 }
3526
3527 //fps
3528 if (ship_clock > fps_check_time)
3529 {
3530 if (![self clockAdjusting])
3531 {
3532 fps_counter = (int)([UNIVERSE timeAccelerationFactor] * floor([UNIVERSE framesDoneThisUpdate] / (fps_check_time - last_fps_check_time)));
3533 last_fps_check_time = fps_check_time;
3534 fps_check_time = ship_clock + MINIMUM_GAME_TICK;
3535 }
3536 else
3537 {
3538 // Good approximation for when the clock is adjusting and proper fps calculation
3539 // cannot be performed.
3540 fps_counter = (int)([UNIVERSE timeAccelerationFactor] * floor(1.0 / delta_t));
3541 fps_check_time = ship_clock + MINIMUM_GAME_TICK;
3542 }
3543 [UNIVERSE resetFramesDoneThisUpdate]; // Reset frame counter
3544 }
3545}
#define MINIMUM_GAME_TICK

◆ updateFuelScoops:

- (void) updateFuelScoops: (OOTimeDelta delta_t

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3474 :(OOTimeDelta)delta_t
3475{
3476 if (scoopsActive)
3477 {
3478 [self updateFuelScoopSoundWithInterval:delta_t];
3479 if (![self scoopOverride])
3480 {
3481 scoopsActive = NO;
3482 [self updateFuelScoopSoundWithInterval:delta_t];
3483 }
3484 }
3485}

◆ updateMovementFlags

- (void) updateMovementFlags

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3209{
3210 hasMoved = !HPvector_equal(position, lastPosition);
3211 hasRotated = !quaternion_equal(orientation, lastOrientation);
3212 lastPosition = position;
3213 lastOrientation = orientation;
3214}

◆ updateTargeting

- (void) updateTargeting

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

4149{
4151
4152 // check for lost ident target and ensure the ident system is actually scanning
4153 UPDATE_STAGE(@"checking ident target");
4154 if (ident_engaged && [self primaryTarget] != nil)
4155 {
4156 if (![self isValidTarget:[self primaryTarget]])
4157 {
4158 if (!suppressTargetLost)
4159 {
4160 [UNIVERSE addMessage:DESC(@"target-lost") forCount:3.0];
4161 [self playTargetLost];
4162 [self noteLostTarget];
4163 }
4164 else
4165 {
4166 suppressTargetLost = NO;
4167 }
4168
4169 DESTROY(_primaryTarget);
4170 }
4171 }
4172
4173 // check each unlaunched missile's target still exists and is in-range
4174 UPDATE_STAGE(@"checking missile targets");
4175 if (missile_status != MISSILE_STATUS_SAFE)
4176 {
4177 unsigned i;
4178 for (i = 0; i < max_missiles; i++)
4179 {
4180 if ([missile_entity[i] primaryTarget] != nil &&
4181 ![self isValidTarget:[missile_entity[i] primaryTarget]])
4182 {
4183 [UNIVERSE addMessage:DESC(@"target-lost") forCount:3.0];
4184 [self playTargetLost];
4185 [missile_entity[i] removeTarget:nil];
4186 if (i == activeMissile)
4187 {
4188 [self noteLostTarget];
4189 DESTROY(_primaryTarget);
4190 missile_status = MISSILE_STATUS_ARMED;
4191 }
4192 } else if (i == activeMissile && [missile_entity[i] primaryTarget] == nil) {
4193 missile_status = MISSILE_STATUS_ARMED;
4194 }
4195 }
4196 }
4197
4198 // if we don't have a primary target, and we're scanning, then check for a new
4199 // target to lock on to
4200 UPDATE_STAGE(@"looking for new target");
4201 if ([self primaryTarget] == nil &&
4202 (ident_engaged || missile_status != MISSILE_STATUS_SAFE) &&
4203 ([self status] == STATUS_IN_FLIGHT || [self status] == STATUS_WITCHSPACE_COUNTDOWN))
4204 {
4205 Entity *target = [UNIVERSE firstEntityTargetedByPlayer];
4206 if ([self isValidTarget:target])
4207 {
4208 [self addTarget:target];
4209 }
4210 }
4211
4212 // If our primary target is a wormhole, check to see if we have additional
4213 // information
4214 UPDATE_STAGE(@"checking for additional wormhole information");
4215 if ([[self primaryTarget] isWormhole])
4216 {
4217 WormholeEntity *wh = [self primaryTarget];
4218 switch ([wh scanInfo])
4219 {
4220 case WH_SCANINFO_NONE:
4221 OOLog(kOOLogInconsistentState, @"%@", @"Internal Error - WH_SCANINFO_NONE reached in [PlayerEntity updateTargeting:]");
4222 [self dumpState];
4223 [wh dumpState];
4224 // Workaround a reported hit of the assert here. We really
4225 // should work out how/why this could happen though and fix
4226 // the underlying cause.
4227 // - MKW 2011.03.11
4228 //assert([wh scanInfo] != WH_SCANINFO_NONE);
4229 [wh setScannedAt:[self clockTimeAdjusted]];
4230 break;
4232 if ([self clockTimeAdjusted] > [wh scanTime] + 2)
4233 {
4234 [wh setScanInfo:WH_SCANINFO_COLLAPSE_TIME];
4235 //[UNIVERSE addCommsMessage:[NSString stringWithFormat:DESC(@"wormhole-collapse-time-computed"),
4236 // [UNIVERSE getSystemName:[wh destination]]] forCount:5.0];
4237 }
4238 break;
4240 if([self clockTimeAdjusted] > [wh scanTime] + 4)
4241 {
4242 [wh setScanInfo:WH_SCANINFO_ARRIVAL_TIME];
4243 [UNIVERSE addCommsMessage:[NSString stringWithFormat:DESC(@"wormhole-arrival-time-computed-@"),
4244 ClockToString([wh estimatedArrivalTime], NO)] forCount:5.0];
4245 }
4246 break;
4248 if ([self clockTimeAdjusted] > [wh scanTime] + 7)
4249 {
4250 [wh setScanInfo:WH_SCANINFO_DESTINATION];
4251 [UNIVERSE addCommsMessage:[NSString stringWithFormat:DESC(@"wormhole-destination-computed-@"),
4252 [UNIVERSE getSystemName:[wh destination]]] forCount:5.0];
4253 }
4254 break;
4256 if ([self clockTimeAdjusted] > [wh scanTime] + 10)
4257 {
4258 [wh setScanInfo:WH_SCANINFO_SHIP];
4259 // TODO: Extract last ship from wormhole and display its name
4260 }
4261 break;
4262 case WH_SCANINFO_SHIP:
4263 break;
4264 }
4265 }
4266
4268}
#define DESTROY(x)
Definition OOCocoa.h:75
NSString *const kOOLogInconsistentState
Definition OOLogging.m:650
@ MISSILE_STATUS_ARMED
@ MISSILE_STATUS_SAFE
@ WH_SCANINFO_NONE
@ WH_SCANINFO_SCANNED
@ WH_SCANINFO_SHIP
@ WH_SCANINFO_ARRIVAL_TIME
@ WH_SCANINFO_DESTINATION
@ WH_SCANINFO_COLLAPSE_TIME
void dumpState()
Definition Entity.m:997
double estimatedArrivalTime()
OOSystemID destination
void setScannedAt:(double time)
void setScanInfo:(WORMHOLE_SCANINFO scanInfo)

◆ updateTrumbles:

- (void) updateTrumbles: (OOTimeDelta delta_t

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

3601 :(OOTimeDelta)delta_t
3602{
3603 OOTrumble **trumbles = [self trumbleArray];
3604 NSUInteger i;
3605
3606 for (i = [self trumbleCount] ; i > 0; i--)
3607 {
3608 OOTrumble* trum = trumbles[i - 1];
3609 [trum updateTrumble:delta_t];
3610 }
3611}
void updateTrumble:(double delta_t)
Definition OOTrumble.m:494

◆ updateWormholes

- (void) updateWormholes

Extends class PlayerEntity.

Definition at line 9242 of file PlayerEntity.m.

13234{
13235 assert(scannedWormholes != nil);
13236
13237 if ([scannedWormholes count] == 0)
13238 return;
13239
13240 double now = [self clockTimeAdjusted];
13241
13242 NSMutableArray * savedWormholes = [[NSMutableArray alloc] initWithCapacity:[scannedWormholes count]];
13243 WormholeEntity *wh;
13244
13245 foreach (wh, scannedWormholes)
13246 {
13247 // TODO: Start drawing wormhole exit a few seconds before the first
13248 // ship is disgorged.
13249 if ([wh arrivalTime] > now)
13250 {
13251 [savedWormholes addObject:wh];
13252 }
13253 else if (NSEqualPoints(galaxy_coordinates, [wh destinationCoordinates]))
13254 {
13255 [wh disgorgeShips];
13256 if ([[wh shipsInTransit] count] > 0)
13257 {
13258 [savedWormholes addObject:wh];
13259 }
13260 }
13261 // Else wormhole has expired in another system, let it expire
13262 }
13263
13264 [scannedWormholes release];
13265 scannedWormholes = savedWormholes;
13266}
unsigned count

◆ witchEnd

- (void) witchEnd

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

7396{
7397 [UNIVERSE setSystemTo:system_id];
7398 galaxy_coordinates = [[UNIVERSE systemManager] getCoordinatesForSystem:system_id inGalaxy:galaxy_number];
7399
7400 [UNIVERSE setUpUniverseFromWitchspace];
7401 [[UNIVERSE planet] update: 2.34375 * market_rnd]; // from 0..10 minutes
7402 [[UNIVERSE station] update: 2.34375 * market_rnd]; // from 0..10 minutes
7403
7404 chart_centre_coordinates = galaxy_coordinates;
7405 target_chart_centre = chart_centre_coordinates;
7406}

◆ witchJumpTo:misjump:

- (void) witchJumpTo: (OOSystemID sTo
misjump: (BOOL)  misjump 

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

7777 :(OOSystemID)sTo misjump:(BOOL)misjump
7778{
7779 [self witchStart];
7780 if (info_system_id == system_id)
7781 {
7782 [self setInfoSystemID: sTo moveChart: YES];
7783 }
7784 //wear and tear on all jumps (inc misjumps, failures, and wormholes)
7785 if (2 * market_rnd < ship_trade_in_factor)
7786 {
7787 // every eight jumps or so drop the price down towards 75%
7788 [self adjustTradeInFactorBy:-(1 + (market_rnd & 3))];
7789 }
7790
7791 // set clock after "playerWillEnterWitchspace" and before removeAllEntitiesExceptPlayer, to allow escorts time to follow their mother.
7792 NSPoint destCoords = PointFromString([[UNIVERSE systemManager] getProperty:@"coordinates" forSystem:sTo inGalaxy:galaxy_number]);
7793 double distance = distanceBetweenPlanetPositions(destCoords.x,destCoords.y,galaxy_coordinates.x,galaxy_coordinates.y);
7794
7795 // if we just escaped a system gone nova, make sure all nova parameters are reset
7796 OOSunEntity *theSun = [UNIVERSE sun];
7797 if (theSun && [theSun goneNova])
7798 {
7799 [theSun resetNova];
7800 }
7801
7802 [UNIVERSE removeAllEntitiesExceptPlayer];
7803 if (!misjump)
7804 {
7805 ship_clock_adjust += distance * distance * 3600.0;
7806 [self setSystemID:sTo];
7807 [self setBounty:(legalStatus/2) withReason:kOOLegalStatusReasonNewSystem]; // 'another day, another system'
7808 [self witchEnd];
7809 if (market_rnd < 8) [self erodeReputation]; // every 32 systems or so, drop back towards 'unknown'
7810 }
7811 else
7812 {
7813 // Misjump: move halfway there!
7814 // misjumps do not change legal status.
7815 if (randf() < 0.1) [self erodeReputation]; // once every 10 misjumps - should be much rarer than successful jumps!
7816
7817 [wormhole setMisjump];
7818 // just in case, but this has usually been set already
7819
7820 // and now the wormhole has travel time and coordinates calculated
7821 // so rather than duplicate the calculation we'll just ask it...
7822 NSPoint dest = [wormhole destinationCoordinates];
7823 galaxy_coordinates.x = dest.x;
7824 galaxy_coordinates.y = dest.y;
7825
7826 ship_clock_adjust += [wormhole travelTime];
7827
7828 [self playWitchjumpMisjump];
7829 [UNIVERSE setUpUniverseFromMisjump];
7830 }
7831}
float randf(void)

◆ witchStart

- (void) witchStart

Extends class PlayerEntity.

Definition at line 13727 of file PlayerEntity.m.

7351{
7352 // chances of entering witchspace with autopilot on are very low, but as Berlios bug #18307 has shown us, entirely possible
7353 // so in such cases we need to ensure that at least the docking music stops playing
7354 if (autopilot_engaged) [self disengageAutopilot];
7355
7356 if (![hud nonlinearScanner])
7357 {
7358 [hud setScannerZoom: 1.0];
7359 }
7360 [self safeAllMissiles];
7361
7362 OOViewID previousViewDirection = [UNIVERSE viewDirection];
7363 [UNIVERSE setViewDirection:VIEW_FORWARD];
7364 [self noteSwitchToView:VIEW_FORWARD fromView:previousViewDirection]; // notifies scripts of the switch
7365
7366 currentWeaponFacing = WEAPON_FACING_FORWARD;
7367 [self currentWeaponStats];
7368
7369 [self transitionToAegisNone];
7370 suppressAegisMessages=YES;
7371 hyperspeed_engaged = NO;
7372
7373 if ([self primaryTarget] != nil)
7374 {
7375 [self noteLostTarget]; // losing target? Fire lost target event!
7376 DESTROY(_primaryTarget);
7377 }
7378
7379 scanner_zoom_rate = 0.0f;
7380 [UNIVERSE setDisplayText:NO];
7381
7382 if ( ![self wormhole] && !galactic_witchjump) // galactic hyperspace does not generate a wormhole
7383 {
7384 OOLog(kOOLogInconsistentState, @"%@", @"Internal Error : Player entering witchspace with no wormhole.");
7385 }
7386 [UNIVERSE allShipsDoScriptEvent:OOJSID("playerWillEnterWitchspace") andReactToAIMessage:@"PLAYER WITCHSPACE"];
7387
7388 // set the new market seed now!
7389 // reseeding the RNG should be completely unnecessary here
7390// ranrot_srand((uint32_t)[[NSDate date] timeIntervalSince1970]); // seed randomiser by time
7391 market_rnd = ranrot_rand() & 255; // random factor for market values is reset
7392}
OOViewID
Definition OOTypes.h:43
#define ranrot_rand()

The documentation for this category was generated from the following file: