Oolite 1.91.0.7646-241128-10e222e
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 13735 of file PlayerEntity.m.

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

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

◆ contractsListForScriptingFromArray:forCargo:

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

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

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

◆ doTradeIn:forPriceFactor:

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

Extends class PlayerEntity.

Definition at line 9247 of file PlayerEntity.m.

10701 :(OOCreditsQuantity)tradeInValue forPriceFactor:(double)priceFactor
10702{
10703 if (tradeInValue != 0)
10704 {
10705 if (priceFactor < 1.0) tradeInValue *= priceFactor;
10706 credits += tradeInValue;
10707 }
10708}
uint64_t OOCreditsQuantity
Definition OOTypes.h:182

◆ fuelRequiredForJump

- (OOFuelQuantity) fuelRequiredForJump

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

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

◆ gameOverFadeToBW

- (void) gameOverFadeToBW

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

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

◆ hyperspaceJumpDistance

- (double) hyperspaceJumpDistance

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

7499{
7500 NSPoint targetCoordinates = PointFromString([[UNIVERSE systemManager] getProperty:@"coordinates" forSystem:[self nextHopTargetSystemID] inGalaxy:galaxy_number]);
7501 return distanceBetweenPlanetPositions(targetCoordinates.x,targetCoordinates.y,galaxy_coordinates.x,galaxy_coordinates.y);
7502}
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 13735 of file PlayerEntity.m.

7518{
7519 if ([[self hud] isCompassActive])
7520 {
7521 // "the compass, it says we're lost!" :)
7522 JSContext *context = OOJSAcquireContext();
7523 jsval jsmode = OOJSValueFromCompassMode(context, [self compassMode]);
7524 ShipScriptEvent(context, self, "compassTargetChanged", JSVAL_VOID, jsmode);
7525 OOJSRelinquishContext(context);
7526
7527 [[self hud] setCompassActive:NO]; // ensure a target change when returning to normal space.
7528 }
7529}
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 13735 of file PlayerEntity.m.

3609 :(OOTimeDelta)delta_t
3610{
3611 [self processBehaviour:delta_t];
3612 [self applyVelocity:delta_t];
3613 [self doBookkeeping:delta_t];
3614}
double OOTimeDelta
Definition OOTypes.h:224

◆ performDeadUpdates:

- (void) performDeadUpdates: (OOTimeDelta) delta_t

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

3965 :(OOTimeDelta)delta_t
3966{
3967 [UNIVERSE terminatePostFX:OO_POSTFX_CLOAK];
3968 if ([UNIVERSE ECMVisualFXEnabled]) [UNIVERSE terminatePostFX:OO_POSTFX_CRTBADSIGNAL];
3969
3970 [self gameOverFadeToBW];
3971
3972 if ([self shotTime] > kDeadResetTime)
3973 {
3974 BOOL was_mouse_control_on = mouse_control_on;
3975 [UNIVERSE handleGameOver]; // we restart the UNIVERSE
3976 mouse_control_on = was_mouse_control_on;
3977 }
3978}

◆ performDockingUpdates:

- (void) performDockingUpdates: (OOTimeDelta) delta_t

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

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

◆ performInFlightUpdates:

- (void) performInFlightUpdates: (OOTimeDelta) delta_t

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

3761 :(OOTimeDelta)delta_t
3762{
3764
3765 // do flight routines
3767 UPDATE_STAGE(@"applying newtonian drift");
3769
3770 [self applyVelocity:delta_t];
3771
3772 GLfloat thrust_factor = 1.0;
3773 if (flightSpeed > maxFlightSpeed)
3774 {
3775 if (afterburner_engaged)
3776 {
3777 thrust_factor = [self afterburnerFactor];
3778 }
3779 else
3780 {
3781 thrust_factor = HYPERSPEED_FACTOR;
3782 }
3783 }
3784
3785
3786 GLfloat velmag = magnitude(velocity);
3787 GLfloat velmag2 = velmag - (float)delta_t * thrust * thrust_factor;
3788 if (velmag > 0)
3789 {
3790 UPDATE_STAGE(@"applying power braking");
3791
3792 if (velmag > VELOCITY_CLEANUP_MIN)
3793 {
3794 GLfloat rate;
3795 // Fix up extremely ridiculous speeds that can happen in collisions or explosions
3796 if (velmag > VELOCITY_CLEANUP_FULL) rate = VELOCITY_CLEANUP_RATE;
3798 velmag2 -= velmag * rate;
3799 }
3800 if (velmag2 < 0.0f) velocity = kZeroVector;
3801 else velocity = vector_multiply_scalar(velocity, velmag2 / velmag);
3802
3803 }
3804
3805 UPDATE_STAGE(@"updating joystick");
3806 [self applyRoll:(float)delta_t*flightRoll andClimb:(float)delta_t*flightPitch];
3807 if (flightYaw != 0.0)
3808 {
3809 [self applyYaw:(float)delta_t*flightYaw];
3810 }
3811
3812 UPDATE_STAGE(@"applying para-newtonian thrust");
3813 [self moveForward:delta_t*flightSpeed];
3814
3815 UPDATE_STAGE(@"updating targeting");
3816 [self updateTargeting];
3817
3819}
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 13735 of file PlayerEntity.m.

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

◆ performWitchspaceCountdownUpdates:

- (void) performWitchspaceCountdownUpdates: (OOTimeDelta) delta_t

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

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

◆ performWitchspaceExitUpdates:

- (void) performWitchspaceExitUpdates: (OOTimeDelta) delta_t

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

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

◆ prepareMarkedDestination:markers:

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

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

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

◆ setExtraEquipmentFromFlags

- (void) setExtraEquipmentFromFlags

Extends class PlayerEntity.

◆ showGameOver

- (void) showGameOver

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

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

◆ showMarketCashAndLoadLine

- (void) showMarketCashAndLoadLine

Extends class PlayerEntity.

Definition at line 9247 of file PlayerEntity.m.

11352{
11353 GuiDisplayGen *gui = [UNIVERSE gui];
11354 OOCargoQuantity currentCargo = current_cargo;
11355 OOCargoQuantity cargoCapacity = [self maxAvailableCargoSpace];
11356 [gui setText:OOExpandKey(@"market-cash-and-load", credits, currentCargo, cargoCapacity) forRow:GUI_ROW_MARKET_CASH];
11357 [gui setColor:[gui colorFromSetting:kGuiMarketCashColor defaultValue:[OOColor yellowColor]] forRow:GUI_ROW_MARKET_CASH];
11358}
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 9247 of file PlayerEntity.m.

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

10936{
10937 GuiDisplayGen *gui = [UNIVERSE gui];
10938 OOGUITabSettings tab_stops;
10939 tab_stops[0] = 0;
10940 tab_stops[1] = 137;
10941 tab_stops[2] = 187;
10942 tab_stops[3] = 267;
10943 tab_stops[4] = 321;
10944 tab_stops[5] = 431;
10945 [gui overrideTabs:tab_stops from:kGuiMarketTabs length:6];
10946 [gui setTabStops:tab_stops];
10947
10948 [gui setColor:[gui colorFromSetting:kGuiMarketHeadingColor defaultValue:[OOColor greenColor]] forRow:GUI_ROW_MARKET_KEY];
10949 [gui setArray:[NSArray arrayWithObjects: DESC(@"commodity-column-title"), OOPadStringToEms(DESC(@"price-column-title"),3.5),
10950 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];
10951 [gui setArray:[NSArray arrayWithObjects: DESC(@"commodity-column-title"), DESC(@"oolite-extras-column-title"), OOPadStringToEms(DESC(@"price-column-title"),3.5),
10952 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];
10953
10954}
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 9247 of file PlayerEntity.m.

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

3424{
3425 [self updateAlertConditionForNearbyEntities];
3426 /* TODO: update alert condition once per frame. Tried this before, but
3427 there turned out to be complications. See mailing list archive.
3428 -- Ahruman 20070802
3429 */
3430 OOAlertCondition cond = [self alertCondition];
3431 OOTimeAbsolute t = [UNIVERSE getTime];
3432 if (cond != lastScriptAlertCondition)
3433 {
3434 ShipScriptEventNoCx(self, "alertConditionChanged", INT_TO_JSVAL(cond), INT_TO_JSVAL(lastScriptAlertCondition));
3435 lastScriptAlertCondition = cond;
3436 }
3437 /* Update heuristic assessment of whether player is fleeing */
3438 if (cond == ALERT_CONDITION_DOCKED || cond == ALERT_CONDITION_GREEN || (cond == ALERT_CONDITION_YELLOW && energy == maxEnergy))
3439 {
3440 fleeing_status = PLAYER_FLEEING_NONE;
3441 }
3442 else if (fleeing_status == PLAYER_FLEEING_UNLIKELY && (energy > maxEnergy*0.6 || cond != ALERT_CONDITION_RED))
3443 {
3444 fleeing_status = PLAYER_FLEEING_NONE;
3445 }
3446 else if ((fleeing_status == PLAYER_FLEEING_MAYBE || fleeing_status == PLAYER_FLEEING_UNLIKELY) && cargo_dump_time > last_shot_time)
3447 {
3448 fleeing_status = PLAYER_FLEEING_CARGO;
3449 }
3450 else if (fleeing_status == PLAYER_FLEEING_MAYBE && last_shot_time + 10 > t)
3451 {
3452 fleeing_status = PLAYER_FLEEING_NONE;
3453 }
3454 else if (fleeing_status == PLAYER_FLEEING_LIKELY && last_shot_time + 10 > t)
3455 {
3456 fleeing_status = PLAYER_FLEEING_UNLIKELY;
3457 }
3458 else if (fleeing_status == PLAYER_FLEEING_NONE && cond == ALERT_CONDITION_RED && last_shot_time + 10 < t && flightSpeed > 0.75*maxFlightSpeed)
3459 {
3460 fleeing_status = PLAYER_FLEEING_MAYBE;
3461 }
3462 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))
3463 {
3464 fleeing_status = PLAYER_FLEEING_LIKELY;
3465 }
3466}
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 13735 of file PlayerEntity.m.

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

◆ updateClocks:

- (void) updateClocks: (OOTimeDelta) delta_t

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

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

◆ updateFuelScoops:

- (void) updateFuelScoops: (OOTimeDelta) delta_t

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

3469 :(OOTimeDelta)delta_t
3470{
3471 if (scoopsActive)
3472 {
3473 [self updateFuelScoopSoundWithInterval:delta_t];
3474 if (![self scoopOverride])
3475 {
3476 scoopsActive = NO;
3477 [self updateFuelScoopSoundWithInterval:delta_t];
3478 }
3479 }
3480}

◆ updateMovementFlags

- (void) updateMovementFlags

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

3204{
3205 hasMoved = !HPvector_equal(position, lastPosition);
3206 hasRotated = !quaternion_equal(orientation, lastOrientation);
3207 lastPosition = position;
3208 lastOrientation = orientation;
3209}

◆ updateTargeting

- (void) updateTargeting

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

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

3596 :(OOTimeDelta)delta_t
3597{
3598 OOTrumble **trumbles = [self trumbleArray];
3599 NSUInteger i;
3600
3601 for (i = [self trumbleCount] ; i > 0; i--)
3602 {
3603 OOTrumble* trum = trumbles[i - 1];
3604 [trum updateTrumble:delta_t];
3605 }
3606}
void updateTrumble:(double delta_t)
Definition OOTrumble.m:494

◆ updateWormholes

- (void) updateWormholes

Extends class PlayerEntity.

Definition at line 9247 of file PlayerEntity.m.

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

◆ witchEnd

- (void) witchEnd

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

7391{
7392 [UNIVERSE setSystemTo:system_id];
7393 galaxy_coordinates = [[UNIVERSE systemManager] getCoordinatesForSystem:system_id inGalaxy:galaxy_number];
7394
7395 [UNIVERSE setUpUniverseFromWitchspace];
7396 [[UNIVERSE planet] update: 2.34375 * market_rnd]; // from 0..10 minutes
7397 [[UNIVERSE station] update: 2.34375 * market_rnd]; // from 0..10 minutes
7398
7399 chart_centre_coordinates = galaxy_coordinates;
7400 target_chart_centre = chart_centre_coordinates;
7401}

◆ witchJumpTo:misjump:

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

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

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

◆ witchStart

- (void) witchStart

Extends class PlayerEntity.

Definition at line 13735 of file PlayerEntity.m.

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

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