49#import "MyOpenGLView.h"
90#define PLAYER_DEFAULT_NAME @"Jameson"
113@interface PlayerEntity (OOPrivate)
116- (void) doTradeIn:(
OOCreditsQuantity)tradeInValue forPriceFactor:(
double)priceFactor;
125- (void) performAutopilotUpdates:(
OOTimeDelta)delta_t;
126- (void) performInFlightUpdates:(
OOTimeDelta)delta_t;
127- (void) performWitchspaceCountdownUpdates:(
OOTimeDelta)delta_t;
128- (void) performWitchspaceExitUpdates:(
OOTimeDelta)delta_t;
129- (void) performLaunchingUpdates:(
OOTimeDelta)delta_t;
130- (void) performDockingUpdates:(
OOTimeDelta)delta_t;
138- (BOOL) checkEntityForMassLock:(
Entity *)ent withScanClass:(
int)scanClass;
147- (BOOL) tryBuyingItem:(NSString *)eqKey;
150- (NSArray*) contractsListForScriptingFromArray:(NSArray *)contractsArray forCargo:(BOOL)forCargo;
153- (void) prepareMarkedDestination:(NSMutableDictionary *)markers :(NSDictionary *)marker;
156- (void) witchJumpTo:(
OOSystemID)sTo misjump:(BOOL)misjump;
170@interface ShipEntity (Hax)
172- (id) initBypassForPlayer;
189- (void) setName:(NSString *)inName
200 if ([
self mass] > 0.0)
202 OOLog(
@"fuelPrices",
@"Setting Cobra3 base mass to: %.2f ", [
self mass]);
208 OOLog(
@"fuelPrices",
@"%@",
@"Player ship not initialised properly yet, using precalculated base mass.");
219 NSInteger i, cargoCount = [cargo count];
220 if (cargoCount == 0)
return;
223 for (i = cargoCount - 1; i >= 0 ; i--)
225 ShipEntity *cargoItem = [cargo objectAtIndex:i];
227 if (commodityType ==
nil || [commodityType isEqualToString:type])
229 if ([commodityType isEqualToString:type])
236 OOLog(
@"player.badCargoPod",
@"Cargo pod %@ has bad commodity type, rejecting.", cargoItem);
239 [cargo removeObjectAtIndex:i];
247 NSInteger i, n_cargo = [cargo count];
248 if (n_cargo == 0)
return;
256 for (i = n_cargo - 1; (i >= 0 && cargoToGo > 0) ; i--)
258 cargoItem = [cargo objectAtIndex:i];
260 if (co_type ==
nil || [co_type isEqualToString:type])
262 if ([co_type isEqualToString:type])
265 if (amount <= cargoToGo)
267 [cargo removeObjectAtIndex:i];
280 OOLog(
@"player.badCargoPod",
@"Cargo pod %@ has bad commodity type (COMMODITY_UNDEFINED), rejecting.", cargoItem);
289 [shipCommodityData removeQuantity:cargoToGo forGood:type];
294- (void) unloadCargoPods
296 NSAssert([
self isDocked],
@"Cannot unload cargo pods unless docked.");
299 NSString *good =
nil;
300 foreach (good, [shipCommodityData goods])
302 [
self unloadAllCargoPodsForType:good toManifest:shipCommodityData];
305 if ([cargo
count] > 0)
307 OOLog(
@"player.unloadCargo",
@"Cargo remains in pods after unloading - %@",cargo);
311 [
self calculateCurrentCargo];
318 ShipEntity *container = [UNIVERSE newShipWithRole:@"1t-cargopod"];
324 [cargo addObject:container];
329 OOLogERR(
@"player.loadCargoPods.noContainer",
@"%@",
@"couldn't create a container in [PlayerEntity loadCargoPods]");
331 [NSException raise:OOLITE_EXCEPTION_FATAL
332 format:@"[PlayerEntity loadCargoPods] failed to create a container for cargo with role 'cargopod'"];
350 for (j = 0; j < quantity; j++)
352 [
self createCargoPodWithType:type andAmount:1];
358 OOCargoQuantity podsRequiredForQuantity, amountToLoadInCargopod, tmpQuantity;
364 tmpQuantity = quantity;
370 quantity -= tmpQuantity;
377 tmpQuantity = quantity;
383 quantity -= tmpQuantity;
389 podsRequiredForQuantity = 1 + (quantity/amountToLoadInCargopod);
392 if (quantity % amountToLoadInCargopod == 0) podsRequiredForQuantity--;
395 for (j = 0; j < podsRequiredForQuantity; j++)
397 if (amountToLoadInCargopod > quantity)
400 amountToLoadInCargopod = quantity;
402 [
self createCargoPodWithType:type andAmount:amountToLoadInCargopod];
403 quantity -= amountToLoadInCargopod;
415 OOMassUnit unit = [shipCommodityData massUnitForGood:type];
424 int smaller_quantity = 1 + ((quantity - 1) % amount_per_container);
425 if ([cargo
count] < [
self maxAvailableCargoSpace])
427 ShipEntity* container = [UNIVERSE newShipWithRole:@"1t-cargopod"];
434 [cargo addObject:container];
441 int amount = [shipCommodityData quantityForGood:type] + smaller_quantity;
445 [shipCommodityData setQuantity:amount forGood:type];
447 quantity -= smaller_quantity;
455 if ([cargo
count] < [
self maxAvailableCargoSpace])
457 ShipEntity* container = [UNIVERSE newShipWithRole:@"1t-cargopod"];
464 [cargo addObject:container];
475- (void) loadCargoPods
478 NSString *good =
nil;
479 foreach (good, [shipCommodityData goods])
481 [
self loadCargoPodsForType:good fromManifest:shipCommodityData];
483 [
self calculateCurrentCargo];
490 return shipCommodityData;
506- (void) setRandom_factor:(
int)rf
514 return galaxy_number;
518- (NSPoint) galaxy_coordinates
520 return galaxy_coordinates;
524- (void) setGalaxyCoordinates:(NSPoint)newPosition
526 galaxy_coordinates.x = newPosition.x;
527 galaxy_coordinates.y = newPosition.y;
531- (NSPoint) cursor_coordinates
533 return cursor_coordinates;
537- (NSPoint) chart_centre_coordinates
539 return chart_centre_coordinates;
561 return custom_chart_zoom;
568 return custom_chart_zoom;
571- (void) setCustomChartZoom:(
OOScalar)zoom
573 custom_chart_zoom = zoom;
577- (NSPoint) custom_chart_centre_coordinates
579 return custom_chart_centre_coordinates;
583- (void) setCustomChartCentre:(NSPoint)coords
585 custom_chart_centre_coordinates.x = coords.x;
586 custom_chart_centre_coordinates.y = coords.y;
590- (NSPoint) adjusted_chart_centre
600 return galaxy_coordinates;
606 return NSMakePoint(128.0, 128.0);
612 return custom_chart_centre_coordinates;
616 acc.x = chart_centre_coordinates.x + (128.0 - chart_centre_coordinates.
x) * (chart_zoom - 1.0) / (
CHART_MAX_ZOOM - 1.0);
617 acc.y = chart_centre_coordinates.y + (128.0 - chart_centre_coordinates.
y) * (chart_zoom - 1.0) / (
CHART_MAX_ZOOM - 1.0);
632 acc.x = ((scroll_pos-chart_focus_coordinates.
x)*ecc + chart_focus_coordinates.
x*acc.
x)/scroll_pos;
639 if (scroll_pos >= 256.0)
645 acc.x = ((chart_focus_coordinates.x-scroll_pos)*ecc + (256.0 - chart_focus_coordinates.
x)*acc.
x)/(256.0 - scroll_pos);
658 acc.y = ((scroll_pos-chart_focus_coordinates.
y)*ecc + chart_focus_coordinates.
y*acc.
y)/scroll_pos;
665 if (scroll_pos >= 256.0)
671 acc.y = ((chart_focus_coordinates.y-scroll_pos)*ecc + (256.0 - chart_focus_coordinates.
y)*acc.
y)/(256.0 - scroll_pos);
693 galaxy_coordinates =
PointFromString([[
UNIVERSE systemManager] getProperty:
@"coordinates" forSystem:sid inGalaxy:galaxy_number]);
694 chart_centre_coordinates = galaxy_coordinates;
695 target_chart_centre = chart_centre_coordinates;
701 return previous_system_id;
707 previous_system_id = sid;
713 return target_system_id;
719 target_system_id = sid;
720 cursor_coordinates =
PointFromString([[
UNIVERSE systemManager] getProperty:
@"coordinates" forSystemKey:[
UNIVERSE keyForPlanetOverridesForSystem:sid inGalaxy:galaxy_number]]);
728 if (![
self hasEquipmentItemProviding:
@"EQ_ADVANCED_NAVIGATIONAL_ARRAY"])
730 return target_system_id;
735 return target_system_id;
738 if (system_id == target_system_id)
742 NSDictionary *routeInfo =
nil;
743 routeInfo = [UNIVERSE routeFromSystem:system_id toSystem:target_system_id optimizedBy:ANA_mode];
745 if (routeInfo ==
nil)
747 return target_system_id;
749 return [[routeInfo oo_arrayForKey:@"route"] oo_intAtIndex:1];
755 return info_system_id;
759- (void) setInfoSystemID: (
OOSystemID) sid moveChart: (BOOL) moveChart
761 if (sid != info_system_id)
764 info_system_id = sid;
766 ShipScriptEvent(context,
self,
"infoSystemWillChange", INT_TO_JSVAL(info_system_id), INT_TO_JSVAL(old));
767 if (gui_screen == GUI_SCREEN_LONG_RANGE_CHART || gui_screen == GUI_SCREEN_SHORT_RANGE_CHART)
771 target_chart_focus = [[UNIVERSE systemManager] getCoordinatesForSystem:info_system_id inGalaxy:galaxy_number];
776 if(gui_screen == GUI_SCREEN_SYSTEM_DATA)
778 [
self setGuiToSystemDataScreenRefreshBackground: YES];
782 chart_centre_coordinates = [[UNIVERSE systemManager] getCoordinatesForSystem:info_system_id inGalaxy:galaxy_number];
783 target_chart_centre = chart_centre_coordinates;
784 chart_focus_coordinates = chart_centre_coordinates;
785 target_chart_focus = chart_focus_coordinates;
788 ShipScriptEvent(context,
self,
"infoSystemChanged", INT_TO_JSVAL(info_system_id), INT_TO_JSVAL(old));
794- (void) nextInfoSystem
798 [
self setInfoSystemID: target_system_id moveChart: YES];
801 NSArray *route = [[[UNIVERSE routeFromSystem:system_id toSystem:target_system_id optimizedBy:ANA_mode] oo_arrayForKey: @"route"] retain];
805 [
self setInfoSystemID: target_system_id moveChart: YES];
808 for (i = 0; i < [route count]; i++)
810 if ([[route objectAtIndex: i] intValue] == info_system_id)
812 if (i + 1 < [route
count])
814 [
self setInfoSystemID:[[route objectAtIndex:i + 1] unsignedIntValue] moveChart: YES];
822 [
self setInfoSystemID: target_system_id moveChart: YES];
827- (void) previousInfoSystem
831 [
self setInfoSystemID: system_id moveChart: YES];
834 NSArray *route = [[[UNIVERSE routeFromSystem:system_id toSystem:target_system_id optimizedBy:ANA_mode] oo_arrayForKey: @"route"] retain];
838 [
self setInfoSystemID: system_id moveChart: YES];
841 for (i = 0; i < [route count]; i++)
843 if ([[route objectAtIndex: i] intValue] == info_system_id)
847 [
self setInfoSystemID: [[route objectAtIndex: i - 1] unsignedIntValue] moveChart: YES];
855 [
self setInfoSystemID: system_id moveChart: YES];
860- (void) homeInfoSystem
862 [
self setInfoSystemID: system_id moveChart: YES];
867- (void) targetInfoSystem
869 [
self setInfoSystemID: target_system_id moveChart: YES];
874- (BOOL) infoSystemOnRoute
876 NSArray *route = [[UNIVERSE routeFromSystem:system_id toSystem:target_system_id optimizedBy:ANA_mode] oo_arrayForKey: @"route"];
882 for (i = 0; i < [route count]; i++)
884 if ([[route objectAtIndex: i] intValue] == info_system_id)
902 if (newWormhole !=
nil)
904 wormhole = [newWormhole retain];
913- (NSDictionary *) commanderDataDictionary
917 NSMutableDictionary *result = [NSMutableDictionary dictionary];
919 [result setObject:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] forKey:@"written_by_version"];
921 NSString *gal_id = [NSString stringWithFormat:@"%u", galaxy_number];
922 NSString *sys_id = [NSString stringWithFormat:@"%d", system_id];
923 NSString *tgt_id = [NSString stringWithFormat:@"%d", target_system_id];
924 NSString *prv_id = [NSString stringWithFormat:@"%d", previous_system_id];
930 [result setObject:gal_id forKey:@"galaxy_id"];
931 [result setObject:sys_id forKey:@"system_id"];
932 [result setObject:tgt_id forKey:@"target_id"];
933 [result setObject:prv_id forKey:@"previous_system_id"];
934 [result setObject:[NSNumber numberWithFloat:saved_chart_zoom] forKey:@"chart_zoom"];
935 [result setObject:[NSNumber numberWithInt:ANA_mode] forKey:@"chart_ana_mode"];
936 [result setObject:[NSNumber numberWithInt:longRangeChartMode] forKey:@"chart_colour_mode"];
939 if (found_system_id >= 0)
941 NSString *found_id = [NSString stringWithFormat:@"%d", found_system_id];
942 [result setObject:found_id forKey:@"found_system_id"];
946 if (![
UNIVERSE inInterstellarSpace])
948 [result setObject:[UNIVERSE getSystemName:[
self currentSystemID]] forKey:@"current_system_name"];
949 OOGovernmentID government = [[UNIVERSE currentSystemData] oo_intForKey:KEY_GOVERNMENT];
950 OOTechLevelID techlevel = [[UNIVERSE currentSystemData] oo_intForKey:KEY_TECHLEVEL];
951 OOEconomyID economy = [[UNIVERSE currentSystemData] oo_intForKey:KEY_ECONOMY];
952 [result setObject:[NSNumber numberWithUnsignedShort:government] forKey:@"current_system_government"];
953 [result setObject:[NSNumber numberWithUnsignedInteger:techlevel] forKey:@"current_system_techlevel"];
954 [result setObject:[NSNumber numberWithUnsignedShort:economy] forKey:@"current_system_economy"];
957 [result setObject:[
self commanderName] forKey:@"player_name"];
958 [result setObject:[
self lastsaveName] forKey:@"player_save_name"];
959 [result setObject:[
self shipUniqueName] forKey:@"ship_unique_name"];
960 [result setObject:[
self shipClassName] forKey:@"ship_class_name"];
969 [result oo_setFloat:credits forKey:@"credits"];
970 [result oo_setUnsignedInteger:fuel forKey:@"fuel"];
972 [result oo_setInteger:galaxy_number forKey:@"galaxy_number"];
974 [result oo_setBool:[
self weaponsOnline] forKey:@"weapons_online"];
976 if (forward_weapon_type !=
nil)
978 [result setObject:[forward_weapon_type identifier] forKey:@"forward_weapon"];
980 if (aft_weapon_type !=
nil)
982 [result setObject:[aft_weapon_type identifier] forKey:@"aft_weapon"];
984 if (port_weapon_type !=
nil)
986 [result setObject:[port_weapon_type identifier] forKey:@"port_weapon"];
988 if (starboard_weapon_type !=
nil)
990 [result setObject:[starboard_weapon_type identifier] forKey:@"starboard_weapon"];
992 [result setObject:[
self serializeShipSubEntities] forKey:@"subentities_status"];
993 if (hud !=
nil && [hud nonlinearScanner])
995 [result oo_setFloat: [hud scannerZoom] forKey:@"ship_scanner_zoom"];
998 [result oo_setInteger:max_cargo + PASSENGER_BERTH_SPACE * max_passengers forKey:@"max_cargo"];
1000 [result setObject:[shipCommodityData savePlayerAmounts] forKey:@"shipCommodityData"];
1003 NSMutableArray *missileRoles = [NSMutableArray arrayWithCapacity:max_missiles];
1005 for (i = 0; i < (
int)max_missiles; i++)
1007 if (missile_entity[i])
1009 [missileRoles addObject:[missile_entity[i] primaryRole]];
1013 [missileRoles addObject:@"NONE"];
1016 [result setObject:missileRoles forKey:@"missile_roles"];
1018 [result oo_setInteger:missiles forKey:@"missiles"];
1020 [result oo_setInteger:legalStatus forKey:@"legal_status"];
1021 [result oo_setInteger:market_rnd forKey:@"market_rnd"];
1022 [result oo_setInteger:ship_kills forKey:@"ship_kills"];
1025 [result oo_setInteger:ship_trade_in_factor forKey:@"ship_trade_in_factor"];
1028 if (mission_variables !=
nil)
1030 [result setObject:[NSDictionary dictionaryWithDictionary:mission_variables] forKey:@"mission_variables"];
1034 NSArray *log = [
self commLog];
1035 if (log !=
nil) [result setObject:log forKey:@"comm_log"];
1037 [result oo_setUnsignedInteger:entity_personality forKey:@"entity_personality"];
1040 NSMutableDictionary *equipment = [NSMutableDictionary dictionary];
1041 NSEnumerator *eqEnum =
nil;
1042 NSString *eqDesc =
nil;
1043 for (eqEnum = [
self equipmentEnumerator]; (eqDesc = [eqEnum nextObject]); )
1045 [equipment oo_setInteger:[
self countEquipmentItem:eqDesc] forKey:eqDesc];
1047 if ([equipment
count] != 0)
1049 [result setObject:equipment forKey:@"extra_equipment"];
1051 if (primedEquipment < [eqScripts
count]) [result setObject:[[eqScripts oo_arrayAtIndex:primedEquipment] oo_stringAtIndex:0] forKey:@"primed_equipment"];
1053 [result setObject:[
self fastEquipmentA] forKey:@"primed_equipment_a"];
1054 [result setObject:[
self fastEquipmentB] forKey:@"primed_equipment_b"];
1057 [result setObject:roleWeights forKey:@"role_weights"];
1060 [result setObject:roleWeightFlags forKey:@"role_weight_flags"];
1063 [result setObject:roleSystemList forKey:@"role_system_memory"];
1066 [result setObject:reputation forKey:@"reputation"];
1069 int pGood = [reputation oo_intForKey:PARCEL_GOOD_KEY];
1070 int pBad = [reputation oo_intForKey:PARCEL_BAD_KEY];
1071 int pUnknown = [reputation oo_intForKey:PARCEL_UNKNOWN_KEY];
1074 [reputation oo_setInteger:0 forKey:PARCEL_GOOD_KEY];
1075 [reputation oo_setInteger:0 forKey:PARCEL_BAD_KEY];
1076 [reputation oo_setInteger:MAX_CONTRACT_REP forKey:PARCEL_UNKNOWN_KEY];
1080 [result oo_setInteger:max_passengers forKey:@"max_passengers"];
1081 [result setObject:passengers forKey:@"passengers"];
1082 [result setObject:passenger_record forKey:@"passenger_record"];
1085 [result setObject:parcels forKey:@"parcels"];
1086 [result setObject:parcel_record forKey:@"parcel_record"];
1089 if (specialCargo) [result setObject:specialCargo forKey:@"special_cargo"];
1092 [result setObject:contracts forKey:@"contracts"];
1093 [result setObject:contract_record forKey:@"contract_record"];
1095 [result setObject:missionDestinations forKey:@"mission_destinations"];
1098 [result setObject:shipyard_record forKey:@"shipyard_record"];
1101 [result setObject:[NSNumber numberWithDouble:ship_clock] forKey:@"ship_clock"];
1104 [result setObject:[NSNumber numberWithInt:isSpeechOn] forKey:@"speech_on"];
1106 [result setObject:[UNIVERSE voiceName:voice_no] forKey:@"speech_voice"];
1107 [result setObject:[NSNumber numberWithBool:voice_gender_m] forKey:@"speech_gender"];
1111 [result setObject:[NSNumber numberWithBool:[UNIVERSE dockingClearanceProtocolActive]] forKey:@"docking_clearance_protocol"];
1114 [result setObject:[
self shipDataKey] forKey:@"ship_desc"];
1115 [result setObject:[[
self shipInfoDictionary] oo_stringForKey:KEY_NAME] forKey:@"ship_name"];
1118 [result oo_setUnsignedInteger:_customViewIndex forKey:@"custom_view_index"];
1121 [result oo_setFloat:[
self escapePodRescueTime] forKey:@"escape_pod_rescue_time"];
1124 if ([[
UNIVERSE station] localMarket]) [result setObject:[[[UNIVERSE station] localMarket] saveStationAmounts] forKey:@"localMarket"];
1127 [result setObject:[UNIVERSE useAddOns] forKey:@"scenario_restriction"];
1129 [result setObject:[[UNIVERSE systemManager] exportScriptedChanges] forKey:@"scripted_planetinfo_overrides"];
1132 [result setObject:[
self trumbleValue] forKey:@"trumbles"];
1135 NSMutableArray *wormholeDicts = [NSMutableArray arrayWithCapacity:[scannedWormholes count]];
1136 NSEnumerator *wormholes = [scannedWormholes objectEnumerator];
1138 foreach(wh, wormholes)
1140 [wormholeDicts addObject:[wh
getDict]];
1142 [result setObject:wormholeDicts forKey:@"wormholes"];
1146 [result setObject:dockedStation != nil ? [dockedStation
primaryRole]:(NSString *)@"" forKey:@"docked_station_role"];
1149 HPVector dpos = [dockedStation
position];
1150 [result setObject:ArrayFromHPVector(dpos) forKey:@"docked_station_position"];
1154 [result setObject:[NSArray array] forKey:@"docked_station_position"];
1156 [result setObject:[UNIVERSE getStationMarkets] forKey:@"station_markets"];
1159 if (scenarioKey !=
nil)
1161 [result setObject:scenarioKey forKey:@"scenario"];
1174 if (mission_variables !=
nil)
1178 if (equipment !=
nil)
1183 int final_checksum =
munge_checksum([[
self shipDataKey] length]);
1186 [result oo_setInteger:final_checksum forKey:@"checksum"];
1192- (BOOL)setCommanderDataFromDictionary:(NSDictionary *) dict
1196 [multiFunctionDisplayText release];
1197 multiFunctionDisplayText = [[NSMutableDictionary alloc] init];
1199 [multiFunctionDisplaySettings release];
1200 multiFunctionDisplaySettings = [[NSMutableArray alloc] init];
1202 [customDialSettings release];
1203 customDialSettings = [[NSMutableDictionary alloc] init];
1205 [[UNIVERSE gameView] resetTypedString];
1208 if ([dict oo_stringForKey:
@"ship_desc"] ==
nil) return NO;
1210 if ([dict oo_stringForKey:
@"galaxy_seed"] ==
nil && [dict oo_stringForKey:
@"galaxy_id"] ==
nil) return NO;
1212 if ([dict oo_stringForKey:
@"galaxy_coordinates"] ==
nil && [dict oo_stringForKey:
@"system_id"] ==
nil) return NO;
1214 NSString *scenarioRestrict = [dict oo_stringForKey:@"scenario_restriction" defaultValue:nil];
1215 if (scenarioRestrict ==
nil)
1218 BOOL strict = [dict oo_boolForKey:@"strict" defaultValue:NO];
1229 if (![
UNIVERSE setUseAddOns:scenarioRestrict fromSaveGame:YES])
1236 [
self setShipDataKey:[dict oo_stringForKey:@"ship_desc"]];
1239 if (shipDict ==
nil)
return NO;
1240 if (![
self setUpShipFromDictionary:shipDict]) return NO;
1241 OOLog(
@"fuelPrices",
@"Got \"%@\
", fuel charge rate: %.2f", [
self shipDataKey],[
self fuelChargeRate]);
1244 ship_trade_in_factor = [dict oo_intForKey:@"ship_trade_in_factor" defaultValue:95];
1247 if ([dict oo_stringForKey:
@"galaxy_id"] !=
nil)
1249 galaxy_number = [dict oo_unsignedIntegerForKey:@"galaxy_id"];
1254 [UNIVERSE setGalaxyTo:galaxy_number andReinit:YES];
1256 system_id = [dict oo_intForKey:@"system_id"];
1262 [UNIVERSE setSystemTo:system_id];
1264 NSArray *coord_vals =
ScanTokensFromString([[
UNIVERSE systemManager] getProperty:
@"coordinates" forSystem:system_id inGalaxy:galaxy_number]);
1265 galaxy_coordinates.x = [coord_vals oo_unsignedCharAtIndex:0];
1266 galaxy_coordinates.y = [coord_vals oo_unsignedCharAtIndex:1];
1267 chart_centre_coordinates = galaxy_coordinates;
1268 target_chart_centre = chart_centre_coordinates;
1269 cursor_coordinates = galaxy_coordinates;
1270 chart_zoom = [dict oo_floatForKey:@"chart_zoom" defaultValue:1.0];
1271 target_chart_zoom = chart_zoom;
1272 saved_chart_zoom = chart_zoom;
1273 ANA_mode = [dict oo_intForKey:@"chart_ana_mode" defaultValue:OPTIMIZED_BY_NONE];
1274 longRangeChartMode = [dict oo_intForKey:@"chart_colour_mode" defaultValue:OOLRC_MODE_SUNCOLOR];
1275 if (longRangeChartMode == OOLRC_MODE_UNKNOWN) longRangeChartMode = OOLRC_MODE_SUNCOLOR;
1277 target_system_id = [dict oo_intForKey:@"target_id" defaultValue:system_id];
1278 previous_system_id = [dict oo_intForKey:@"previous_system_id" defaultValue:system_id];
1279 info_system_id = target_system_id;
1280 coord_vals =
ScanTokensFromString([[
UNIVERSE systemManager] getProperty:
@"coordinates" forSystem:target_system_id inGalaxy:galaxy_number]);
1281 cursor_coordinates.x = [coord_vals oo_unsignedCharAtIndex:0];
1282 cursor_coordinates.y = [coord_vals oo_unsignedCharAtIndex:1];
1284 chart_focus_coordinates = chart_centre_coordinates;
1285 target_chart_focus = chart_focus_coordinates;
1287 found_system_id = [dict oo_intForKey:@"found_system_id" defaultValue:-1];
1292 galaxy_number = [dict oo_unsignedIntegerForKey:@"galaxy_number"];
1294 [UNIVERSE setGalaxyTo: galaxy_number andReinit:YES];
1297 galaxy_coordinates.x = [coord_vals oo_unsignedCharAtIndex:0];
1298 galaxy_coordinates.y = [coord_vals oo_unsignedCharAtIndex:1];
1299 chart_centre_coordinates = galaxy_coordinates;
1300 target_chart_centre = chart_centre_coordinates;
1301 cursor_coordinates = galaxy_coordinates;
1303 target_chart_zoom = 1.0;
1304 saved_chart_zoom = 1.0;
1307 NSString *keyStringValue = [dict oo_stringForKey:@"target_coordinates"];
1309 if (keyStringValue !=
nil)
1312 cursor_coordinates.x = [coord_vals oo_unsignedCharAtIndex:0];
1313 cursor_coordinates.y = [coord_vals oo_unsignedCharAtIndex:1];
1315 chart_focus_coordinates = chart_centre_coordinates;
1316 target_chart_focus = chart_focus_coordinates;
1319 if ([dict objectForKey:
@"current_system_name"])
1321 system_id = [UNIVERSE findSystemFromName:[dict oo_stringForKey:@"current_system_name"]];
1322 if (system_id == -1) system_id = [UNIVERSE findSystemNumberAtCoords:galaxy_coordinates withGalaxy:galaxy_number includingHidden:YES];
1328 system_id = [UNIVERSE findSystemNumberAtCoords:galaxy_coordinates withGalaxy:galaxy_number includingHidden:YES];
1332 if ([dict objectForKey:
@"target_system_name"])
1334 target_system_id = [UNIVERSE findSystemFromName:[dict oo_stringForKey:@"target_system_name"]];
1335 if (target_system_id == -1) target_system_id = [UNIVERSE findSystemNumberAtCoords:cursor_coordinates withGalaxy:galaxy_number includingHidden:YES];
1339 target_system_id = [UNIVERSE findSystemNumberAtCoords:cursor_coordinates withGalaxy:galaxy_number includingHidden:YES];
1341 info_system_id = target_system_id;
1342 found_system_id = -1;
1345 NSString *cname = [dict oo_stringForKey:@"player_name" defaultValue:PLAYER_DEFAULT_NAME];
1346 [
self setCommanderName:cname];
1347 [
self setLastsaveName:[dict oo_stringForKey:@"player_save_name" defaultValue:cname]];
1349 [
self setShipUniqueName:[dict oo_stringForKey:@"ship_unique_name" defaultValue:@""]];
1350 [
self setShipClassName:[dict oo_stringForKey:@"ship_class_name" defaultValue:[shipDict oo_stringForKey:@"name"]]];
1352 [shipCommodityData loadPlayerAmounts:[dict oo_arrayForKey:@"shipCommodityData"]];
1355 [
self removeAllEquipment];
1356 NSMutableDictionary *equipment = [NSMutableDictionary dictionaryWithDictionary:[dict oo_dictionaryForKey:@"extra_equipment"]];
1359 if ([dict oo_boolForKey:
@"has_docking_computer"]) [equipment oo_setInteger:1 forKey:
@"EQ_DOCK_COMP"];
1360 if ([dict oo_boolForKey:
@"has_galactic_hyperdrive"]) [equipment oo_setInteger:1 forKey:
@"EQ_GAL_DRIVE"];
1361 if ([dict oo_boolForKey:
@"has_escape_pod"]) [equipment oo_setInteger:1 forKey:
@"EQ_ESCAPE_POD"];
1362 if ([dict oo_boolForKey:
@"has_ecm"]) [equipment oo_setInteger:1 forKey:
@"EQ_ECM"];
1363 if ([dict oo_boolForKey:
@"has_scoop"]) [equipment oo_setInteger:1 forKey:
@"EQ_FUEL_SCOOPS"];
1364 if ([dict oo_boolForKey:
@"has_energy_bomb"]) [equipment oo_setInteger:1 forKey:
@"EQ_ENERGY_BOMB"];
1365 if ([dict oo_boolForKey:
@"has_fuel_injection"]) [equipment oo_setInteger:1 forKey:
@"EQ_FUEL_INJECTION"];
1369 if ([dict oo_boolForKey:
@"has_energy_unit"] && [
self installedEnergyUnitType] ==
ENERGY_UNIT_NONE)
1371 OOEnergyUnitType eType = [dict oo_intForKey:@"energy_unit" defaultValue:ENERGY_UNIT_NORMAL];
1376 [equipment oo_setInteger:1 forKey:@"EQ_NAVAL_ENERGY_UNIT"];
1380 [equipment oo_setInteger:1 forKey:@"EQ_ENERGY_UNIT"];
1388 custom_chart_zoom = 1.0;
1389 custom_chart_centre_coordinates = NSMakePoint(galaxy_coordinates.y, galaxy_coordinates.y);
1395 BOOL energyBombCompensation = NO;
1396 if ([equipment oo_boolForKey:
@"EQ_ENERGY_BOMB"] && [
OOEquipmentType equipmentTypeWithIdentifier:
@"EQ_ENERGY_BOMB"] ==
nil)
1398 energyBombCompensation = YES;
1399 [equipment removeObjectForKey:@"EQ_ENERGY_BOMB"];
1402 eqScripts = [[NSMutableArray alloc] init];
1403 [
self addEquipmentFromCollection:equipment];
1404 primedEquipment = [
self eqScriptIndexForKey:[dict oo_stringForKey:@"primed_equipment"]];
1406 [
self setFastEquipmentA:[dict oo_stringForKey:@"primed_equipment_a" defaultValue:@"EQ_CLOAKING_DEVICE"]];
1407 [
self setFastEquipmentB:[dict oo_stringForKey:@"primed_equipment_b" defaultValue:@"EQ_ENERGY_BOMB"]];
1409 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_COMPASS"]) compassMode = COMPASS_MODE_PLANET;
1410 else compassMode = COMPASS_MODE_BASIC;
1414 isSpeechOn = [dict oo_intForKey:@"speech_on"];
1416 voice_gender_m = [dict oo_boolForKey:@"speech_gender" defaultValue:YES];
1417 voice_no = [UNIVERSE setVoice:[UNIVERSE voiceNumber:[dict oo_stringForKey:@"speech_voice" defaultValue:nil]] withGenderM:voice_gender_m];
1421 [reputation release];
1422 reputation = [[dict oo_dictionaryForKey:@"reputation"] mutableCopy];
1423 if (reputation ==
nil) reputation = [[NSMutableDictionary alloc] init];
1424 [
self normaliseReputation];
1428 [parcel_record release];
1429 [passengers release];
1430 [passenger_record release];
1431 [contracts release];
1432 [contract_record release];
1434 max_passengers = [dict oo_intForKey:@"max_passengers" defaultValue:0];
1435 passengers = [[dict oo_arrayForKey:@"passengers"] mutableCopy];
1436 passenger_record = [[dict oo_dictionaryForKey:@"passenger_record"] mutableCopy];
1439 contracts = [[dict oo_arrayForKey:@"contracts"] mutableCopy];
1440 NSMutableDictionary *contractInfo =
nil;
1443 for (NSInteger i = (NSInteger)[contracts
count] - 1; i >= 0; i--)
1445 contractInfo = [[[contracts oo_dictionaryAtIndex:i] mutableCopy] autorelease];
1447 if ([[contractInfo objectForKey:
CARGO_KEY_TYPE] isKindOfClass:[NSNumber class]])
1450 NSUInteger legacy_type = [contractInfo oo_unsignedIntegerForKey:CARGO_KEY_TYPE];
1452 [contracts replaceObjectAtIndex:i withObject:[[contractInfo copy] autorelease]];
1456 OOCommodityType new_type = [contractInfo oo_stringForKey:CARGO_KEY_TYPE];
1458 if (![[
UNIVERSE commodities] goodDefined:new_type])
1460 OOLog(
@"setCommanderDataFromDictionary.warning.contract",
@"Cargo contract to deliver %@ could not be loaded from the saved game, as the commodity is no longer defined",new_type);
1461 [contracts removeObjectAtIndex:i];
1466 contract_record = [[dict oo_dictionaryForKey:@"contract_record"] mutableCopy];
1467 parcels = [[dict oo_arrayForKey:@"parcels"] mutableCopy];
1468 parcel_record = [[dict oo_dictionaryForKey:@"parcel_record"] mutableCopy];
1472 if (passengers ==
nil) passengers = [[NSMutableArray alloc] init];
1473 if (passenger_record ==
nil) passenger_record = [[NSMutableDictionary alloc] init];
1474 if (contracts ==
nil) contracts = [[NSMutableArray alloc] init];
1475 if (contract_record ==
nil) contract_record = [[NSMutableDictionary alloc] init];
1476 if (parcels ==
nil) parcels = [[NSMutableArray alloc] init];
1477 if (parcel_record ==
nil) parcel_record = [[NSMutableDictionary alloc] init];
1480 [specialCargo release];
1481 specialCargo = [[dict oo_stringForKey:@"special_cargo"] copy];
1484 NSArray *legacyDestinations = [dict oo_arrayForKey:@"missionDestinations"];
1486 NSDictionary *newDestinations = [dict oo_dictionaryForKey:@"mission_destinations"];
1487 [
self initialiseMissionDestinations:newDestinations andLegacy:legacyDestinations];
1491 shipyard_record = [[dict oo_dictionaryForKey:@"shipyard_record"] mutableCopy];
1492 if (shipyard_record ==
nil) shipyard_record = [[NSMutableDictionary alloc] init];
1495 unsigned original_hold_size = [UNIVERSE maxCargoForShip:[
self shipDataKey]];
1500 max_cargo = [dict oo_unsignedIntForKey:@"max_cargo" defaultValue:max_cargo];
1501 if (max_cargo > original_hold_size) [
self addEquipmentItem:@"EQ_CARGO_BAY" inContext:@"loading"];
1502 max_cargo = original_hold_size + ([
self hasExpandedCargoBay] ? extra_cargo : 0);
1506 unsigned originalMaxPassengers = max_passengers;
1508 OOLogWARN(
@"setCommanderDataFromDictionary.inconsistency.max_passengers",
@"player ship %@ had max_passengers set to a value requiring more cargo space than currently available (%u). Setting max_passengers to maximum possible value (%u).", [
self name], originalMaxPassengers, max_passengers);
1513 if (passengers && ([passengers
count] > max_passengers))
1515 OOLogWARN(
@"setCommanderDataFromDictionary.inconsistency.passengers",
@"player ship %@ had more passengers (%lu) than passenger berths (%u). Removing extra passengers.", [
self name], [passengers
count], max_passengers);
1516 for (NSInteger i = (NSInteger)[passengers
count] - 1; i >= max_passengers; i--)
1518 [passenger_record removeObjectForKey:[[passengers oo_dictionaryAtIndex:i] oo_stringForKey:PASSENGER_KEY_NAME]];
1519 [passengers removeObjectAtIndex:i];
1524 NSInteger excessCargo = (NSInteger)[
self cargoQuantityOnBoard] - (NSInteger)[
self maxAvailableCargoSpace];
1525 if (excessCargo > 0)
1527 OOLogWARN(
@"setCommanderDataFromDictionary.inconsistency.cargo",
@"player ship %@ had more cargo (%i) than it can hold (%u). Removing extra cargo.", [
self name], [
self cargoQuantityOnBoard], [
self maxAvailableCargoSpace]);
1536 foreach (type, [shipCommodityData goods])
1538 units = [shipCommodityData massUnitForGood:type];
1540 oldAmount = [shipCommodityData quantityForGood:type];
1542 if (roundedTon || (units ==
UNITS_TONS && oldAmount > 0))
1547 while (remainingExcess > 0 && partAmount > 0)
1553 partAmount = oldAmount - toRemove;
1556 else if (!roundedTon)
1567 [shipCommodityData removeQuantity:toRemove forGood:type];
1574 fuel = [dict oo_unsignedIntForKey:@"fuel" defaultValue:fuel];
1575 galaxy_number = [dict oo_intForKey:@"galaxy_number"];
1578 OOWeaponFacingSet available_facings = [shipyard_info oo_unsignedIntForKey:KEY_WEAPON_FACINGS defaultValue:[
self weaponFacings]];
1600 [
self setWeaponDataFromType:forward_weapon_type];
1602 if (hud !=
nil && [hud nonlinearScanner])
1604 [hud setScannerZoom: [dict oo_floatForKey:@"ship_scanner_zoom" defaultValue: 1.0]];
1607 weapons_online = [dict oo_boolForKey:@"weapons_online" defaultValue:YES];
1609 legalStatus = [dict oo_intForKey:@"legal_status"];
1610 market_rnd = [dict oo_intForKey:@"market_rnd"];
1611 ship_kills = [dict oo_intForKey:@"ship_kills"];
1613 ship_clock = [dict oo_doubleForKey:@"ship_clock" defaultValue:PLAYER_SHIP_CLOCK_START];
1614 fps_check_time = ship_clock;
1616 escape_pod_rescue_time = [dict oo_doubleForKey:@"escape_pod_rescue_time" defaultValue:0.0];
1619 [roleWeights release];
1620 roleWeights = [[dict oo_arrayForKey:@"role_weights"] mutableCopy];
1621 NSUInteger rc = [
self maxPlayerRoles];
1622 if (roleWeights ==
nil)
1624 roleWeights = [[NSMutableArray alloc] initWithCapacity:rc];
1627 [roleWeights addObject:@"player-unknown"];
1632 if ([roleWeights
count] > rc)
1634 [roleWeights removeObjectsInRange:(NSRange) {rc,[roleWeights count]-rc}];
1638 roleWeightFlags = [[dict oo_dictionaryForKey:@"role_weight_flags"] mutableCopy];
1639 if (roleWeightFlags ==
nil)
1641 roleWeightFlags = [[NSMutableDictionary alloc] init];
1644 roleSystemList = [[dict oo_arrayForKey:@"role_system_memory"] mutableCopy];
1645 if (roleSystemList ==
nil)
1647 roleSystemList = [[NSMutableArray alloc] initWithCapacity:32];
1652 [mission_variables release];
1653 mission_variables = [[dict oo_dictionaryForKey:@"mission_variables"] mutableCopy];
1654 if (mission_variables ==
nil) mission_variables = [[NSMutableDictionary alloc] init];
1657 NSDictionary *planetInfoOverrides = [dict oo_dictionaryForKey:@"scripted_planetinfo_overrides"];
1658 if (planetInfoOverrides !=
nil)
1660 [[UNIVERSE systemManager] importScriptedChanges:planetInfoOverrides];
1665 planetInfoOverrides = [dict oo_dictionaryForKey:@"local_planetinfo_overrides"];
1666 if (planetInfoOverrides !=
nil)
1668 [[UNIVERSE systemManager] importLegacyScriptedChanges:planetInfoOverrides];
1674 commLog = [[NSMutableArray alloc] initWithCapacity:kCommLogTrimThreshold];
1676 NSArray *savedCommLog = [dict oo_arrayForKey:@"comm_log"];
1677 NSUInteger commCount = [savedCommLog count];
1678 for (NSUInteger i = 0; i < commCount; i++)
1680 [UNIVERSE addCommsMessage:[savedCommLog objectAtIndex:i] forCount:0 andShowComms:NO logOnly:YES];
1688 entity_personality = [dict oo_unsignedShortForKey:@"entity_personality" defaultValue:entity_personality];
1691 [
self setActiveMissile:0];
1694 [missile_entity[i] release];
1695 missile_entity[i] =
nil;
1697 NSArray *missileRoles = [dict oo_arrayForKey:@"missile_roles"];
1698 if (missileRoles !=
nil)
1700 unsigned missileCount = 0;
1701 for (NSUInteger roleIndex = 0; roleIndex < [missileRoles count] && missileCount < max_missiles; roleIndex++)
1703 NSString *missile_desc = [missileRoles oo_stringAtIndex:roleIndex];
1704 if (missile_desc !=
nil && ![missile_desc isEqualToString:
@"NONE"])
1706 ShipEntity *amiss = [UNIVERSE newShipWithRole:missile_desc];
1710 missile_entity[missileCount] = amiss;
1715 OOLogWARN(
@"load.failed.missileNotFound",
@"couldn't find missile with role '%@' in [PlayerEntity setCommanderDataFromDictionary:], missile entry discarded.", missile_desc);
1718 missiles = missileCount;
1723 for (NSUInteger i = 0; i < missiles; i++)
1726 missile_entity[i] = [UNIVERSE newShipWithRole:@"EQ_MISSILE"];
1731 if (energyBombCompensation)
1738 if ([
self mountMissileWithRole:
@"EQ_QC_MINE"])
1740 OOLog(
@"load.upgrade.replacedEnergyBomb",
@"%@",
@"Replaced legacy energy bomb with Quirium cascade mine.");
1745 OOLog(
@"load.upgrade.replacedEnergyBomb",
@"%@",
@"Compensated legacy energy bomb with 900 credits.");
1749 [
self setActiveMissile:0];
1751 [
self setHeatInsulation:1.0];
1756 forward_shield_recharge_rate = 2.0;
1757 aft_shield_recharge_rate = 2.0;
1759 forward_shield = [
self maxForwardShieldLevel];
1760 aft_shield = [
self maxAftShieldLevel];
1766 [
self deserializeShipSubEntitiesFrom:[dict oo_stringForKey:@"subentities_status"]];
1770 whArray = [dict objectForKey:@"wormholes"];
1771 NSEnumerator * whDicts = [whArray objectEnumerator];
1772 NSDictionary * whCurrDict;
1773 [scannedWormholes release];
1774 scannedWormholes = [[NSMutableArray alloc] initWithCapacity:[whArray count]];
1775 while ((whCurrDict = [whDicts nextObject]) !=
nil)
1778 [scannedWormholes addObject:wh];
1790 if (_customViews !=
nil)
1791 _customViewIndex = [dict oo_unsignedIntForKey:@"custom_view_index"] % [_customViews count];
1795 [UNIVERSE setDockingClearanceProtocolActive:[dict oo_boolForKey:@"docking_clearance_protocol" defaultValue:NO]];
1798 [
self setUpTrumbles];
1799 [
self setTrumbleValueFrom:[dict objectForKey:@"trumbles"]];
1823 NSAssert(
gOOPlayer ==
nil,
@"Expected only one PlayerEntity to exist at a time.");
1824 return [
super initBypassForPlayer];
1828- (void) deferredInit
1830 NSAssert(
gOOPlayer ==
self,
@"Expected only one PlayerEntity to exist at a time.");
1831 NSAssert([super initWithKey:
PLAYER_SHIP_DESC definition:[NSDictionary dictionary]] ==
self,
@"PlayerEntity requires -[ShipEntity initWithKey:definition:] to return unmodified self.");
1834#if OO_FOV_INFLIGHT_CONTROL_ENABLED
1838 compassMode = COMPASS_MODE_BASIC;
1840 afterburnerSoundLooping = NO;
1844 [
self setStatus:STATUS_START_GAME];
1849 missile_entity[i] =
nil;
1851 [
self setUpAndConfirmOK:NO];
1857 target_memory_index = 0;
1860 dockingReport = [[NSMutableString alloc] init];
1861 [hud resetGuis:[NSDictionary dictionaryWithObjectsAndKeys:[NSDictionary dictionary], @"message_gui",
1862 [NSDictionary dictionary], @"comm_log_gui", nil]];
1864 [
self initControls];
1868- (BOOL) setUpAndConfirmOK:(BOOL)stopOnError
1870 return [
self setUpAndConfirmOK:stopOnError saveGame:NO];
1874- (BOOL) setUpAndConfirmOK:(BOOL)stopOnError saveGame:(BOOL)saveGame
1876 fieldOfView = [[UNIVERSE gameView] fov:YES];
1880 show_info_flag = NO;
1881 DESTROY(marketSelectedCommodity);
1912 [
self setDockedStation:nil];
1913 [
self setStatus:STATUS_DEAD];
1914 OOLog(
@"script.javascript.init.error",
@"%@",
@"Scheduling new JavaScript reset.");
1930 [UNIVERSE setBlockJSPlayerShipProps:NO];
1932 DESTROY(worldScriptsRequiringTickle);
1938 [UNIVERSE preloadSounds];
1941 [UNIVERSE loadConditionScripts];
1942 commodityScripts = [[NSMutableDictionary alloc] init];
1947 [UNIVERSE preloadSounds];
1952 [UNIVERSE loadConditionScripts];
1953 commodityScripts = [[NSMutableDictionary alloc] init];
1960 if ([
self cargoList] !=
nil)
1962 [
self removeAllCargo:YES];
1965 [
self setShipDataKey:PLAYER_SHIP_DESC];
1966 ship_trade_in_factor = 95;
1969 [UNIVERSE setAutoCommLog:YES];
1970 [UNIVERSE setPermanentCommLog:NO];
1972 [multiFunctionDisplayText release];
1973 multiFunctionDisplayText = [[NSMutableDictionary alloc] init];
1975 [multiFunctionDisplaySettings release];
1976 multiFunctionDisplaySettings = [[NSMutableArray alloc] init];
1978 [customDialSettings release];
1979 customDialSettings = [[NSMutableDictionary alloc] init];
1981 [
self switchHudTo:@"hud.plist"];
1982 scanner_zoom_rate = 0.0f;
1983 longRangeChartMode = OOLRC_MODE_SUNCOLOR;
1985 [mission_variables release];
1986 mission_variables = [[NSMutableDictionary alloc] init];
1988 [localVariables release];
1989 localVariables = [[NSMutableDictionary alloc] init];
1991 [
self setScriptTarget:nil];
1992 [
self resetMissionChoice];
1993 [[UNIVERSE gameView] resetTypedString];
1994 found_system_id = -1;
1996 [reputation release];
1997 reputation = [[NSMutableDictionary alloc] initWithCapacity:6];
1998 [reputation oo_setInteger:0 forKey:CONTRACTS_GOOD_KEY];
1999 [reputation oo_setInteger:0 forKey:CONTRACTS_BAD_KEY];
2000 [reputation oo_setInteger:MAX_CONTRACT_REP forKey:CONTRACTS_UNKNOWN_KEY];
2001 [reputation oo_setInteger:0 forKey:PASSAGE_GOOD_KEY];
2002 [reputation oo_setInteger:0 forKey:PASSAGE_BAD_KEY];
2003 [reputation oo_setInteger:MAX_CONTRACT_REP forKey:PASSAGE_UNKNOWN_KEY];
2004 [reputation oo_setInteger:0 forKey:PARCEL_GOOD_KEY];
2005 [reputation oo_setInteger:0 forKey:PARCEL_BAD_KEY];
2006 [reputation oo_setInteger:MAX_CONTRACT_REP forKey:PARCEL_UNKNOWN_KEY];
2009 roleWeights = [[NSMutableArray alloc] initWithCapacity:8];
2010 for (i = 0 ; i < 8 ; i++)
2012 [roleWeights addObject:@"player-unknown"];
2015 roleWeightFlags = [[NSMutableDictionary alloc] init];
2018 roleSystemList = [[NSMutableArray alloc] initWithCapacity:32];
2022 forward_weapon_temp = 0.0f;
2023 aft_weapon_temp = 0.0f;
2024 port_weapon_temp = 0.0f;
2025 starboard_weapon_temp = 0.0f;
2031 ship_temperature = 60.0f;
2033 hyperspeed_engaged = NO;
2034 autopilot_engaged = NO;
2042 [passengers release];
2043 passengers = [[NSMutableArray alloc] init];
2044 [passenger_record release];
2045 passenger_record = [[NSMutableDictionary alloc] init];
2047 [contracts release];
2048 contracts = [[NSMutableArray alloc] init];
2049 [contract_record release];
2050 contract_record = [[NSMutableDictionary alloc] init];
2053 parcels = [[NSMutableArray alloc] init];
2054 [parcel_record release];
2055 parcel_record = [[NSMutableDictionary alloc] init];
2057 [missionDestinations release];
2058 missionDestinations = [[NSMutableDictionary alloc] init];
2060 [shipyard_record release];
2061 shipyard_record = [[NSMutableDictionary alloc] init];
2063 [target_memory release];
2064 target_memory = [[NSMutableArray alloc] initWithCapacity:PLAYER_TARGET_MEMORY_SIZE];
2065 [
self clearTargetMemory];
2067 [
self setMissionOverlayDescriptor:nil];
2068 [
self setMissionBackgroundDescriptor:nil];
2069 [
self setMissionBackgroundSpecial:nil];
2070 [
self setEquipScreenBackgroundDescriptor:nil];
2072 DESTROY(marketSelectedCommodity);
2078 NSCalendarDate *nowDate = [NSCalendarDate calendarDate];
2080 ship_clock += [nowDate hourOfDay] * 3600.0;
2081 ship_clock += [nowDate minuteOfHour] * 60.0;
2082 ship_clock += [nowDate secondOfMinute];
2083 fps_check_time = ship_clock;
2084 ship_clock_adjust = 0.0;
2085 escape_pod_rescue_time = 0.0;
2089 voice_gender_m = YES;
2090 voice_no = [UNIVERSE setVoice:-1 withGenderM:voice_gender_m];
2093 [_customViews release];
2095 _customViewIndex = 0;
2097 mouse_control_on = NO;
2102 [
self setCommanderName:PLAYER_DEFAULT_NAME];
2103 [
self setLastsaveName:PLAYER_DEFAULT_NAME];
2105 galaxy_coordinates = NSMakePoint(0x14,0xAD);
2109 fuel_accumulator = 0.0f;
2110 fuel_leak_rate = 0.0f;
2114 forward_weapon_type =
nil;
2115 aft_weapon_type =
nil;
2116 port_weapon_type =
nil;
2117 starboard_weapon_type =
nil;
2120 weapons_online = YES;
2122 ecm_in_operation = NO;
2123 last_ecm_time = [UNIVERSE getTime];
2124 compassMode = COMPASS_MODE_BASIC;
2131 shipCommodityData = [[[UNIVERSE commodities] generateManifestForPlayer] retain];
2137 [eqScripts release];
2138 eqScripts = [[NSMutableArray alloc] init];
2139 primedEquipment = 0;
2140 [
self setFastEquipmentA:@"EQ_CLOAKING_DEVICE"];
2141 [
self setFastEquipmentB:@"EQ_ENERGY_BOMB"];
2143 [
self setActiveMissile:0];
2144 for (i = 0; i < missiles; i++)
2146 [missile_entity[i] release];
2147 missile_entity[i] =
nil;
2149 [
self safeAllMissiles];
2151 [
self clearSubEntities];
2157 chart_centre_coordinates = galaxy_coordinates;
2158 target_chart_centre = chart_centre_coordinates;
2159 cursor_coordinates = galaxy_coordinates;
2160 chart_focus_coordinates = cursor_coordinates;
2161 target_chart_focus = chart_focus_coordinates;
2163 target_chart_zoom = 1.0;
2164 saved_chart_zoom = 1.0;
2168 scripted_misjump = NO;
2169 _scriptedMisjumpRange = 0.5;
2175 forward_shield_recharge_rate = 2.0;
2176 aft_shield_recharge_rate = 2.0;
2178 forward_shield = [
self maxForwardShieldLevel];
2179 aft_shield = [
self maxAftShieldLevel];
2181 scanClass = CLASS_PLAYER;
2183 [UNIVERSE clearGUIs];
2186 targetDockStation =
nil;
2188 [
self setDockedStation:[UNIVERSE station]];
2193 [specialCargo release];
2204 [
self currentWeaponStats];
2206 [save_path autorelease];
2209 [scannedWormholes release];
2210 scannedWormholes = [[NSMutableArray alloc] init];
2212 [
self setUpTrumbles];
2214 suppressTargetLost = NO;
2218 [dockingReport release];
2219 dockingReport = [[NSMutableString alloc] init];
2222 shipAI = [[
AI alloc] initWithStateMachine:PLAYER_DOCKING_AI_NAME andState:@"GLOBAL"];
2223 [
self resetAutopilotAI];
2225 lastScriptAlertCondition = [
self alertCondition];
2229 [
self setSystemID:[UNIVERSE findSystemNumberAtCoords:[
self galaxy_coordinates] withGalaxy:galaxy_number includingHidden:YES]];
2230 [UNIVERSE setGalaxyTo:galaxy_number];
2231 [UNIVERSE setSystemTo:system_id];
2233 [
self setUpWeaponSounds];
2235 [
self setGalacticHyperspaceBehaviourTo:[[UNIVERSE globalSettings] oo_stringForKey:@"galactic_hyperspace_behaviour" defaultValue:@"BEHAVIOUR_STANDARD"]];
2236 [
self setGalacticHyperspaceFixedCoordsTo:[[UNIVERSE globalSettings] oo_stringForKey:@"galactic_hyperspace_fixed_coords" defaultValue:@"96 96"]];
2238 cloaking_device_active = NO;
2243 [stickProfileScreen release];
2249- (void) completeSetUp
2251 [
self completeSetUpAndSetTarget:YES];
2255- (void) completeSetUpAndSetTarget:(BOOL)setTarget
2259 [
self setDockedStation:[UNIVERSE station]];
2260 [
self setLastAegisLock:[UNIVERSE planet]];
2261 [
self validateCustomEquipActivationArray];
2264 [
self doWorldScriptEvent:OOJSID("startUp") inContext:context withArguments:NULL count:0 timeLimit:MAX(0.0, [[NSUserDefaults standardUserDefaults] oo_floatForKey:@"start-script-limit-value" defaultValue:kOOJSLongTimeLimit])];
2269- (void) startUpComplete
2272 [
self doWorldScriptEvent:OOJSID("startUpComplete") inContext:context withArguments:NULL count:0 timeLimit:kOOJSLongTimeLimit];
2277- (BOOL) setUpShipFromDictionary:(NSDictionary *)shipDict
2280 [UNIVERSE setBlockJSPlayerShipProps:NO];
2282 if (![super setUpFromDictionary:shipDict]) return NO;
2285 cargo = [[NSMutableArray alloc] initWithCapacity:max_cargo];
2290 roll_delta = 2.0f * max_flight_roll;
2291 pitch_delta = 2.0f * max_flight_pitch;
2292 yaw_delta = 2.0f * max_flight_yaw;
2300 [
self setPrimaryRole:@"player"];
2302 [
self removeAllEquipment];
2303 [
self addEquipmentFromCollection:[shipDict objectForKey:@"extra_equipment"]];
2311 if (missiles > max_missiles) missiles = max_missiles;
2317 [missile_entity[i] release];
2318 missile_entity[i] =
nil;
2320 for (i = 0; i < missiles; i++)
2323 missile_entity[i] = [UNIVERSE newShipWithRole:@"EQ_MISSILE"];
2327 [
self safeAllMissiles];
2328 [
self setActiveMissile:0];
2331 [
self setDefaultViewOffsets];
2333 if (
EXPECT(_scaleFactor == 1.0f))
2335 forwardViewOffset = [shipDict oo_vectorForKey:@"view_position_forward" defaultValue:forwardViewOffset];
2336 aftViewOffset = [shipDict oo_vectorForKey:@"view_position_aft" defaultValue:aftViewOffset];
2337 portViewOffset = [shipDict oo_vectorForKey:@"view_position_port" defaultValue:portViewOffset];
2338 starboardViewOffset = [shipDict oo_vectorForKey:@"view_position_starboard" defaultValue:starboardViewOffset];
2342 forwardViewOffset = vector_multiply_scalar([shipDict oo_vectorForKey:
@"view_position_forward" defaultValue:forwardViewOffset],_scaleFactor);
2343 aftViewOffset = vector_multiply_scalar([shipDict oo_vectorForKey:
@"view_position_aft" defaultValue:aftViewOffset],_scaleFactor);
2344 portViewOffset = vector_multiply_scalar([shipDict oo_vectorForKey:
@"view_position_port" defaultValue:portViewOffset],_scaleFactor);
2345 starboardViewOffset = vector_multiply_scalar([shipDict oo_vectorForKey:
@"view_position_starboard" defaultValue:starboardViewOffset],_scaleFactor);
2348 [
self setDefaultCustomViews];
2350 NSArray *customViews = [shipDict oo_arrayForKey:@"custom_views"];
2351 if (customViews !=
nil)
2353 [_customViews release];
2354 _customViews = [customViews retain];
2355 _customViewIndex = 0;
2358 massLockable = [shipDict oo_boolForKey:@"mass_lockable" defaultValue:YES];
2361 [script autorelease];
2362 NSDictionary *scriptProperties = [NSDictionary dictionaryWithObject:self forKey:@"ship"];
2380 DESTROY(multiFunctionDisplayText);
2381 DESTROY(multiFunctionDisplaySettings);
2393 DESTROY(worldScriptsRequiringTickle);
2401 DESTROY(marketSelectedCommodity);
2415 DESTROY(_missionOverlayDescriptor);
2416 DESTROY(_missionBackgroundDescriptor);
2417 DESTROY(_equipScreenBackgroundDescriptor);
2435 [
self destroySound];
2451 DESTROY(customEquipActivation);
2452 DESTROY(customActivatePressed);
2461- (NSUInteger) sessionID
2464 return [UNIVERSE sessionID];
2468- (void) warnAboutHostiles
2470 [
self playHostileWarning];
2476 switch ([
self status])
2478 case STATUS_START_GAME:
2479 case STATUS_DOCKING:
2482 case STATUS_ESCAPE_SEQUENCE:
2491- (NSComparisonResult) compareZeroDistance:(
Entity *)otherEntity
2493 return NSOrderedDescending;
2497- (BOOL) validForAddToUniverse
2503- (GLfloat) lookingAtSunWithThresholdAngleCos:(GLfloat) thresholdAngleCos
2506 GLfloat measuredCos = 999.0f, measuredCosAbs;
2507 GLfloat sunBrightness = 0.0f;
2508 Vector relativePosition, unitRelativePosition;
2513 OOViewID vdir = [UNIVERSE viewDirection];
2515 unsigned ent_count =
UNIVERSE->n_entities;
2517 for (i = 0; i < ent_count; i++)
2519 if (uni_entities[i]->isSunlit)
2521 if ([uni_entities[i] isPlanet] ||
2522 ([uni_entities[i] isShip] &&
2523 [uni_entities[i] isVisible]))
2526 if (
EXPECT(vdir > VIEW_STARBOARD || ![uni_entities[i] isPlayer]))
2528 float shadow = 1.5f;
2540 relativePosition = HPVectorToVector(HPvector_subtract([
self viewpointPosition], [sun position]));
2541 unitRelativePosition = vector_normal_or_zbasis(relativePosition);
2545 measuredCos = -dot_product(unitRelativePosition, v_forward);
2548 measuredCos = +dot_product(unitRelativePosition, v_forward);
2551 measuredCos = +dot_product(unitRelativePosition, v_right);
2553 case VIEW_STARBOARD:
2554 measuredCos = -dot_product(unitRelativePosition, v_right);
2558 Vector relativeView = [
self customViewForwardVector];
2560 measuredCos = -dot_product(unitRelativePosition, absoluteView);
2567 measuredCosAbs = fabs(measuredCos);
2574 if (thresholdAngleCos <= measuredCosAbs && measuredCosAbs <= 1.1f)
2576 sunBrightness = (measuredCos - thresholdAngleCos) / (1.0f - thresholdAngleCos);
2578 if (sunBrightness < 0.0f) sunBrightness = 0.0f;
2579 else if (sunBrightness > 1.0f) sunBrightness = 1.0f;
2582 return sunBrightness * sunBrightness * sunBrightness;
2586- (GLfloat) insideAtmosphereFraction
2588 GLfloat insideAtmoFrac = 0.0f;
2590 if ([
UNIVERSE airResistanceFactor] > 0.01)
2595 return insideAtmoFrac;
2600#define STAGE_TRACKING_BEGIN { \
2601 NSString * volatile updateStage = @"initialisation"; \
2603#define STAGE_TRACKING_END } \
2604 @catch (NSException *exception) \
2606 OOLog(kOOLogException, @"***** Exception during [%@] in %s : %@ : %@ *****", updateStage, __PRETTY_FUNCTION__, [exception name], [exception reason]); \
2610#define UPDATE_STAGE(x) do { updateStage = (x); } while (0)
2612#define STAGE_TRACKING_BEGIN {
2613#define STAGE_TRACKING_END }
2614#define UPDATE_STAGE(x) do { (void) (x); } while (0);
2623 [
self updateMovementFlags];
2625 [
self updateAlertCondition];
2627 [
self updateFuelScoops:delta_t];
2630 [
self updateClocks:delta_t];
2636 [
self checkScriptsIfAppropriate];
2640 [
self manageCollisions];
2643 [
self pollControls:delta_t];
2646 [
self updateTrumbles:delta_t];
2651 if (
EXPECT_NOT(status == STATUS_START_GAME &&
2652 gui_screen != GUI_SCREEN_INTRO1 &&
2653 gui_screen != GUI_SCREEN_SHIPLIBRARY &&
2654 gui_screen != GUI_SCREEN_GAMEOPTIONS &&
2655 gui_screen != GUI_SCREEN_STICKMAPPER &&
2656 gui_screen != GUI_SCREEN_STICKPROFILE &&
2657 gui_screen != GUI_SCREEN_NEWGAME &&
2658 gui_screen != GUI_SCREEN_OXZMANAGER &&
2659 gui_screen != GUI_SCREEN_LOAD &&
2660 gui_screen != GUI_SCREEN_KEYBOARD &&
2661 gui_screen != GUI_SCREEN_KEYBOARD_CONFIRMCLEAR &&
2662 gui_screen != GUI_SCREEN_KEYBOARD_CONFIG &&
2663 gui_screen != GUI_SCREEN_KEYBOARD_ENTRY &&
2664 gui_screen != GUI_SCREEN_KEYBOARD_LAYOUT))
2668 [
self setGuiToIntroFirstGo:YES];
2671 if (status == STATUS_AUTOPILOT_ENGAGED || status == STATUS_ESCAPE_SEQUENCE)
2674 [
self performAutopilotUpdates:delta_t];
2676 else if (![
self isDocked])
2679 [
self performInFlightUpdates:delta_t];
2685 if (status == STATUS_IN_FLIGHT)
2688 [
self doBookkeeping:delta_t];
2690 if (status == STATUS_WITCHSPACE_COUNTDOWN)
2693 [
self performWitchspaceCountdownUpdates:delta_t];
2695 if (status == STATUS_EXITING_WITCHSPACE)
2698 [
self performWitchspaceExitUpdates:delta_t];
2700 if (status == STATUS_LAUNCHING)
2703 [
self performLaunchingUpdates:delta_t];
2705 if (status == STATUS_DOCKING)
2708 [
self performDockingUpdates:delta_t];
2710 if (status == STATUS_DEAD)
2713 [
self performDeadUpdates:delta_t];
2717 [
self updateWormholes];
2723- (void) doBookkeeping:(
double) delta_t
2730 double external_temp = 0;
2731 GLfloat air_friction = 0.0f;
2732 air_friction = 0.5f * [UNIVERSE airResistanceFactor];
2733 if (air_friction < 0.005f)
2739 UPDATE_STAGE(
@"updating weapon temperatures and shot times");
2742 forward_weapon_temp = fdim(forward_weapon_temp, coolAmount);
2743 aft_weapon_temp = fdim(aft_weapon_temp, coolAmount);
2744 port_weapon_temp = fdim(port_weapon_temp, coolAmount);
2745 starboard_weapon_temp = fdim(starboard_weapon_temp, coolAmount);
2748 forward_shot_time += delta_t;
2749 aft_shot_time += delta_t;
2750 port_shot_time += delta_t;
2751 starboard_shot_time += delta_t;
2754 switch (currentWeaponFacing)
2757 weapon_temp = forward_weapon_temp;
2758 shot_time = forward_shot_time;
2761 weapon_temp = aft_weapon_temp;
2762 shot_time = aft_shot_time;
2765 weapon_temp = port_weapon_temp;
2766 shot_time = port_shot_time;
2769 weapon_temp = starboard_weapon_temp;
2770 shot_time = starboard_shot_time;
2778 if ([
self hasCloakingDevice] && cloaking_device_active)
2784 [
self deactivateCloakingDevice];
2788 if ([
self hasMilitaryJammer])
2792 if (military_jammer_active)
2796 military_jammer_active = NO;
2801 military_jammer_active = YES;
2806 if (ecm_in_operation)
2814 ecm_in_operation = NO;
2815 [UNIVERSE addMessage:DESC(@"ecm-out-of-juice") forCount:3.0];
2819 ecm_in_operation = NO;
2833 energy += [
self energyRechargeRate] * delta_t;
2836 float fwdMax = [
self maxForwardShieldLevel];
2837 float aftMax = [
self maxAftShieldLevel];
2838 float shieldRechargeFwd = [
self forwardShieldRechargeRate] * delta_t;
2839 float shieldRechargeAft = [
self aftShieldRechargeRate] * delta_t;
2848 float rechargeFwd =
MIN(shieldRechargeFwd, fwdMax - forward_shield);
2849 float rechargeAft =
MIN(shieldRechargeAft, aftMax - aft_shield);
2855 float energyForShields = energy;
2856 if( (forward_shield > fwdMax * 0.25) && (aft_shield > aftMax * 0.25) )
2859 float minEnergyBankLevel = [[UNIVERSE globalSettings] oo_floatForKey:@"shield_charge_energybank_threshold" defaultValue:0.25];
2860 energyForShields =
MAX(0.0, energy -0.1 - (maxEnergy * minEnergyBankLevel));
2863 if( forward_shield < aft_shield )
2865 rechargeFwd =
MIN(rechargeFwd, energyForShields);
2866 rechargeAft =
MIN(rechargeAft, energyForShields - rechargeFwd);
2870 rechargeAft =
MIN(rechargeAft, energyForShields);
2871 rechargeFwd =
MIN(rechargeFwd, energyForShields - rechargeAft);
2875 forward_shield += rechargeFwd;
2876 aft_shield += rechargeAft;
2877 energy -= rechargeFwd + rechargeAft;
2879 forward_shield = OOClamp_0_max_f(forward_shield, fwdMax);
2880 aft_shield = OOClamp_0_max_f(aft_shield, aftMax);
2881 energy = OOClamp_0_max_f(energy, maxEnergy);
2890 double alt1 = sun_cr * sun_cr / sun_zd;
2894 external_temp *= 100;
2896 if ([sun willGoNova])
2900 if ([
self hasFuelScoop] && alt1 > 0.75 && [
self fuel] < [
self fuelCapacity])
2902 fuel_accumulator += (float)(delta_t * flightSpeed * 0.010 / [
self fuelChargeRate]);
2904 scoopsActive = YES && flightSpeed > 0.1f;
2905 while (fuel_accumulator > 1.0f)
2907 [
self setFuel:[
self fuel] + 1];
2908 fuel_accumulator -= 1.0f;
2909 [
self doScriptEvent:OOJSID("shipScoopedFuel")];
2911 [UNIVERSE displayCountdownMessage:DESC(@"fuel-scoop-active") forCount:1.0];
2917 if ((status != STATUS_ESCAPE_SEQUENCE) && (status != STATUS_ENTERING_WITCHSPACE))
2922 float heatInsulation = [
self heatInsulation];
2923 float deltaInsulation = delta_t/heatInsulation;
2924 float heatThreshold = heatInsulation * 100.0f;
2925 ship_temperature += (float)( flightSpeed * air_friction * deltaInsulation);
2927 if (external_temp > heatThreshold && external_temp > ship_temperature)
2928 ship_temperature += (float)((external_temp - ship_temperature) *
SHIP_INSULATION_FACTOR * deltaInsulation);
2932 ship_temperature += (float)((external_temp - heatThreshold - ship_temperature) *
SHIP_COOLING_FACTOR * deltaInsulation);
2936 [
self takeHeatDamage: delta_t * ship_temperature];
2944 [
self setBounty:0 withReason:kOOLegalStatusReasonEscapePod];
2946 thrust = max_thrust;
2949 [
self doScriptEvent:OOJSID("escapePodSequenceOver")];
2954 if (
EXPECT_NOT(target_system_id != system_id))
2956 system_id = target_system_id;
2957 info_system_id = target_system_id;
2958 [UNIVERSE setSystemTo:system_id];
2959 galaxy_coordinates =
PointFromString([[
UNIVERSE systemManager] getProperty:
@"coordinates" forSystem:system_id inGalaxy:galaxy_number]);
2961 [UNIVERSE setUpSpace];
2963 [UNIVERSE populateNormalSpace];
2965 [
self setDockTarget:[UNIVERSE station]];
2968 [UNIVERSE setWitchspaceBreakPattern:YES];
2969 [
self doScriptEvent:OOJSID("shipWillExitWitchspace")];
2970 [
self doScriptEvent:OOJSID("shipExitedWitchspace")];
2972 [[UNIVERSE planet] update: 2.34375 * market_rnd];
2973 [[UNIVERSE station] update: 2.34375 * market_rnd];
2976 Entity *dockTargetEntity = [UNIVERSE entityForUniversalID:_dockTarget];
2977 if ([dockTargetEntity isStation])
2981 ShipEntity *player_ship = [UNIVERSE newShipWithName:[
self shipDataKey]];
2985 [
self setMesh:[player_ship
mesh]];
2986 [player_ship release];
2988 [UNIVERSE setViewDirection:VIEW_FORWARD];
2989 [UNIVERSE setBlockJSPlayerShipProps:NO];
2990 [
self enterDock:(StationEntity *)dockTargetEntity];
2994 [
self setStatus:STATUS_DEAD];
2997 [UNIVERSE displayMessage:DESC(@"gameoverscreen-escape-pod") forCount:kDeadResetTime];
2998 [UNIVERSE displayMessage:@"" forCount:kDeadResetTime];
2999 [
self showGameOver];
3005 travelling_at_hyperspeed = (flightSpeed > maxFlightSpeed);
3006 if (hyperspeed_engaged)
3017 hyperspeed_locked = [
self massLocked];
3021 if (hyperspeed_locked)
3023 [
self playJumpMassLocked];
3024 [UNIVERSE addMessage:DESC(@"jump-mass-locked") forCount:4.5];
3025 hyperspeed_engaged = NO;
3030 if (afterburner_engaged)
3034 float abFactor = [
self afterburnerFactor];
3035 float maxInjectionSpeed = maxFlightSpeed * abFactor;
3036 if (flightSpeed > maxInjectionSpeed)
3039 flightSpeed -= (float)(speed_delta * delta_t * abFactor);
3043 if (flightSpeed < maxInjectionSpeed)
3044 flightSpeed += (float)(speed_delta * delta_t * abFactor);
3045 if (flightSpeed > maxInjectionSpeed)
3046 flightSpeed = maxInjectionSpeed;
3048 fuel_accumulator -= (float)(delta_t * afterburner_rate);
3049 while ((fuel_accumulator < 0)&&(fuel > 0))
3051 fuel_accumulator += 1.0f;
3053 afterburner_engaged = NO;
3061 if (travelling_at_hyperspeed)
3072 flightSpeed -= deceleration;
3073 if (flightSpeed < maxFlightSpeed)
3074 flightSpeed = maxFlightSpeed;
3082 if ((fuel_leak_rate > 0.0)&&(fuel > 0))
3086 fuel_accumulator -= (float)(fuel_leak_rate * delta_t);
3087 while ((fuel_accumulator < 0)&&(fuel > 0))
3089 fuel_accumulator += 1.0f;
3098 if (scanner_zoom_rate)
3100 double z = [hud scannerZoom];
3101 double z1 = z + scanner_zoom_rate * delta_t;
3102 if (scanner_zoom_rate > 0.0)
3104 if (floor(z1) > floor(z))
3107 scanner_zoom_rate = 0.0f;
3115 scanner_zoom_rate = 0.0f;
3118 [hud setScannerZoom:z1];
3121 [[UNIVERSE gameView] setFov:fieldOfView fromFraction:YES];
3124 ShipEntity *primeTarget = [
self primaryTarget];
3125 if (primeTarget && HPdistance2([primeTarget position], [
self position]) >
SCANNER_MAX_RANGE2 && !autopilot_engaged)
3127 [UNIVERSE addMessage:DESC(@"target-lost") forCount:3.0];
3128 [
self removeTarget:primeTarget];
3131 [
self validateCompassTarget];
3135 totalBoundingBox = boundingBox;
3137 foreach (se, [
self subEntities])
3143 bounding_box_add_vector(&totalBoundingBox, sebb.max);
3144 bounding_box_add_vector(&totalBoundingBox, sebb.min);
3149 if (lastShot !=
nil)
3152 foreach (lse, lastShot)
3163 if (mouseWheelDelta > 0.0f)
3168 else if (mouseWheelDelta < 0.0f)
3178- (void) updateMovementFlags
3180 hasMoved = !HPvector_equal(position, lastPosition);
3181 hasRotated = !quaternion_equal(orientation, lastOrientation);
3182 lastPosition = position;
3183 lastOrientation = orientation;
3187- (void) updateAlertConditionForNearbyEntities
3189 if (![
self isInSpace] || [
self status] == STATUS_DOCKING)
3191 [
self clearAlertFlags];
3196 int i, ent_count =
UNIVERSE->n_entities;
3198 Entity *my_entities[ent_count];
3200 for (i = 0; i < ent_count; i++)
3202 my_entities[i] = [uni_entities[i] retain];
3204 BOOL massLocked = NO;
3205 BOOL foundHostiles = NO;
3206#if OO_VARIABLE_TORUS_SPEED
3207 BOOL needHyperspeedNearest = YES;
3208 double hsnDistance = 0;
3210 for (i = 0; i < ent_count; i++)
3212 scannedEntity = my_entities[i];
3214#if OO_VARIABLE_TORUS_SPEED
3218 if (scannedEntity !=
self && [scannedEntity canCollide] && (![scannedEntity isShip] || ![
self collisionExceptedFor:(
ShipEntity *) scannedEntity]))
3220 hsnDistance = sqrt(scannedEntity->
zero_distance)-[scannedEntity collisionRadius];
3221 needHyperspeedNearest = NO;
3224 else if ([scannedEntity isStellarObject])
3229 double thisHSN = sqrt(scannedEntity->
zero_distance)-[scannedEntity collisionRadius];
3230 if (thisHSN < hsnDistance)
3232 hsnDistance = thisHSN;
3239 int theirClass = [scannedEntity
scanClass];
3243 if ([
self massLockable] )
3245 massLocked |= [
self checkEntityForMassLock:scannedEntity withScanClass:theirClass];
3247 if (theirClass != CLASS_NO_DRAW)
3249 if (theirClass == CLASS_THARGOID || [scannedEntity isCascadeWeapon])
3251 foundHostiles = YES;
3253 else if ([scannedEntity isShip])
3256 foundHostiles |= (([ship
hasHostileTarget])&&([ship primaryTarget] ==
self));
3261#if OO_VARIABLE_TORUS_SPEED
3290 [
self setAlertFlag:ALERT_FLAG_MASS_LOCK to:massLocked];
3292 [
self setAlertFlag:ALERT_FLAG_HOSTILES to:foundHostiles];
3294 for (i = 0; i < ent_count; i++)
3296 [my_entities[i] release];
3299 BOOL energyCritical = NO;
3300 if (energy < 64 && energy < maxEnergy * 0.8)
3302 energyCritical = YES;
3304 [
self setAlertFlag:ALERT_FLAG_ENERGY to:energyCritical];
3306 [
self setAlertFlag:ALERT_FLAG_TEMP to:([
self hullHeatLevel] > .90)];
3308 [
self setAlertFlag:ALERT_FLAG_ALT to:([
self dialAltitude] < .10)];
3313- (void) setMaxFlightPitch:(GLfloat)new
3315 max_flight_pitch =
new;
3316 pitch_delta = 2.0 *
new;
3320- (void) setMaxFlightRoll:(GLfloat)new
3322 max_flight_roll =
new;
3323 roll_delta = 2.0 *
new;
3327- (void) setMaxFlightYaw:(GLfloat)new
3329 max_flight_yaw =
new;
3330 yaw_delta = 2.0 *
new;
3334- (BOOL) checkEntityForMassLock:(
Entity *)ent withScanClass:(
int)theirClass
3336 BOOL massLocked = NO;
3346 double factor = ([stellar
isSun]) ? 2.0 : 4.0;
3349 if (dist < rad*rad*factor || dist < rad*rad + 50000*rad + 625000000 )
3355 else if (theirClass != CLASS_NO_DRAW)
3359 theirClass = CLASS_NO_DRAW;
3369 if (entIsCloakedShip && ![ent isPlayer])
3379 case CLASS_VISUAL_EFFECT:
3382 case CLASS_THARGOID:
3386 case CLASS_MILITARY:
3387 case CLASS_WORMHOLE:
3398- (void) updateAlertCondition
3400 [
self updateAlertConditionForNearbyEntities];
3407 if (cond != lastScriptAlertCondition)
3409 ShipScriptEventNoCx(
self,
"alertConditionChanged", INT_TO_JSVAL(cond), INT_TO_JSVAL(lastScriptAlertCondition));
3410 lastScriptAlertCondition = cond;
3437 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))
3448 [
self updateFuelScoopSoundWithInterval:delta_t];
3449 if (![
self scoopOverride])
3452 [
self updateFuelScoopSoundWithInterval:delta_t];
3461 shot_time += delta_t;
3462 script_time += delta_t;
3463 unsigned prev_day = floor(ship_clock / 86400);
3464 ship_clock += delta_t;
3465 if (ship_clock_adjust > 0.0)
3467 double fine_adjust = delta_t * 7200.0;
3468 if (ship_clock_adjust > 86400)
3469 fine_adjust = delta_t * 115200.0;
3470 if (ship_clock_adjust > 0)
3472 if (fine_adjust > ship_clock_adjust)
3473 fine_adjust = ship_clock_adjust;
3474 ship_clock += fine_adjust;
3475 ship_clock_adjust -= fine_adjust;
3479 if (fine_adjust < ship_clock_adjust)
3480 fine_adjust = ship_clock_adjust;
3481 ship_clock -= fine_adjust;
3482 ship_clock_adjust += fine_adjust;
3486 ship_clock_adjust = 0.0;
3488 unsigned now_day = floor(ship_clock / 86400.0);
3489 while (prev_day < now_day)
3492 [
self doScriptEvent:OOJSID("dayChanged") withArgument:[NSNumber numberWithUnsignedInt:prev_day]];
3498 if (ship_clock > fps_check_time)
3500 if (![
self clockAdjusting])
3502 fps_counter = (
int)([
UNIVERSE timeAccelerationFactor] * floor([
UNIVERSE framesDoneThisUpdate] / (fps_check_time - last_fps_check_time)));
3503 last_fps_check_time = fps_check_time;
3510 fps_counter = (
int)([
UNIVERSE timeAccelerationFactor] * floor(1.0 / delta_t));
3513 [UNIVERSE resetFramesDoneThisUpdate];
3518- (void) checkScriptsIfAppropriate
3520 if (script_time <= script_time_check)
return;
3522 if ([
self status] != STATUS_IN_FLIGHT)
3527 case GUI_SCREEN_MAIN:
3528 case GUI_SCREEN_INTRO1:
3529 case GUI_SCREEN_SHIPLIBRARY:
3530 case GUI_SCREEN_KEYBOARD:
3531 case GUI_SCREEN_NEWGAME:
3532 case GUI_SCREEN_OXZMANAGER:
3533 case GUI_SCREEN_MARKET:
3534 case GUI_SCREEN_MARKETINFO:
3535 case GUI_SCREEN_OPTIONS:
3536 case GUI_SCREEN_GAMEOPTIONS:
3537 case GUI_SCREEN_LOAD:
3538 case GUI_SCREEN_SAVE:
3539 case GUI_SCREEN_SAVE_OVERWRITE:
3540 case GUI_SCREEN_STICKMAPPER:
3541 case GUI_SCREEN_STICKPROFILE:
3542 case GUI_SCREEN_MISSION:
3543 case GUI_SCREEN_REPORT:
3544 case GUI_SCREEN_KEYBOARD_CONFIRMCLEAR:
3545 case GUI_SCREEN_KEYBOARD_CONFIG:
3546 case GUI_SCREEN_KEYBOARD_ENTRY:
3547 case GUI_SCREEN_KEYBOARD_LAYOUT:
3552 case GUI_SCREEN_EQUIP_SHIP:
3553 case GUI_SCREEN_INTERFACES:
3554 case GUI_SCREEN_MANIFEST:
3555 case GUI_SCREEN_SHIPYARD:
3556 case GUI_SCREEN_LONG_RANGE_CHART:
3557 case GUI_SCREEN_SHORT_RANGE_CHART:
3558 case GUI_SCREEN_STATUS:
3559 case GUI_SCREEN_SYSTEM_DATA:
3567 script_time_check += script_time_interval;
3573 OOTrumble **trumbles = [
self trumbleArray];
3576 for (i = [
self trumbleCount] ; i > 0; i--)
3584- (void) performAutopilotUpdates:(
OOTimeDelta)delta_t
3586 [
self processBehaviour:delta_t];
3587 [
self applyVelocity:delta_t];
3588 [
self doBookkeeping:delta_t];
3591- (void) performDockingRequest:(
StationEntity *)stationForDocking
3593 if (stationForDocking ==
nil)
return;
3594 if (![stationForDocking isStation] || ![stationForDocking isKindOfClass:[
StationEntity class]]) return;
3595 if ([
self isDocked])
return;
3596 if (autopilot_engaged && [
self targetStation] == stationForDocking)
return;
3597 if (autopilot_engaged && [
self targetStation] != stationForDocking)
3599 [
self disengageAutopilot];
3602 if (stationDockingClearanceStatus !=
nil)
3604 [
self doScriptEvent:OOJSID("playerRequestedDockingClearance") withArgument:stationDockingClearanceStatus];
3605 if ([stationDockingClearanceStatus isEqualToString:
@"DOCKING_CLEARANCE_GRANTED"])
3607 [
self doScriptEvent:OOJSID("playerDockingClearanceGranted")];
3612- (void) requestDockingClearance:(
StationEntity *)stationForDocking
3616 [
self performDockingRequest:stationForDocking];
3620- (void) cancelDockingRequest:(
StationEntity *)stationForDocking
3622 if (stationForDocking ==
nil)
return;
3623 if (![stationForDocking isStation] || ![stationForDocking isKindOfClass:[
StationEntity class]]) return;
3624 if ([
self isDocked])
return;
3625 if (autopilot_engaged && [
self targetStation] == stationForDocking)
return;
3626 if (autopilot_engaged && [
self targetStation] != stationForDocking)
3628 [
self disengageAutopilot];
3633 if (stationDockingClearanceStatus !=
nil && [stationDockingClearanceStatus isEqualToString:
@"DOCKING_CLEARANCE_CANCELLED"])
3635 [
self doScriptEvent:OOJSID("playerDockingClearanceCancelled")];
3640- (BOOL) engageAutopilotToStation:(
StationEntity *)stationForDocking
3642 if (stationForDocking ==
nil)
return NO;
3643 if ([
self isDocked])
return NO;
3645 if (autopilot_engaged && [
self targetStation] == stationForDocking)
3650 [
self setTargetStation:stationForDocking];
3652 autopilot_engaged = YES;
3654 [
self safeAllMissiles];
3656 if ([
self status] == STATUS_WITCHSPACE_COUNTDOWN) [
self cancelWitchspaceCountdown];
3657 [
self setStatus:STATUS_AUTOPILOT_ENGAGED];
3658 [
self resetAutopilotAI];
3659 [shipAI setState:@"BEGIN_DOCKING"];
3660 [
self playAutopilotOn];
3662 [
self doScriptEvent:OOJSID("playerStartedAutoPilot") withArgument:stationForDocking];
3663 [
self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_GRANTED];
3665 if (afterburner_engaged)
3667 afterburner_engaged = NO;
3668 if (afterburnerSoundLooping) [
self stopAfterburnerSound];
3675- (void) disengageAutopilot
3677 if (autopilot_engaged)
3679 [
self abortDocking];
3680 behaviour = BEHAVIOUR_IDLE;
3682 autopilot_engaged = NO;
3684 [
self setTargetStation:nil];
3685 [
self setStatus:STATUS_IN_FLIGHT];
3686 [
self playAutopilotOff];
3687 [
self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
3689 [
self doScriptEvent:OOJSID("playerCancelledAutoPilot")];
3691 [
self resetAutopilotAI];
3696- (void) resetAutopilotAI
3698 AI *myAI = [
self getAI];
3702 [
self setAITo:PLAYER_DOCKING_AI_NAME ];
3711#define VELOCITY_CLEANUP_MIN 2000.0f
3712#define VELOCITY_CLEANUP_FULL 5000.0f
3713#define VELOCITY_CLEANUP_RATE 0.001f
3716#if OO_VARIABLE_TORUS_SPEED
3717- (GLfloat) hyperspeedFactor
3719 return hyperspeedFactor;
3724- (BOOL) injectorsEngaged
3726 return afterburner_engaged;
3730- (BOOL) hyperspeedEngaged
3732 return hyperspeed_engaged;
3736- (void) performInFlightUpdates:(
OOTimeDelta)delta_t
3745 [
self applyVelocity:delta_t];
3747 GLfloat thrust_factor = 1.0;
3748 if (flightSpeed > maxFlightSpeed)
3750 if (afterburner_engaged)
3752 thrust_factor = [
self afterburnerFactor];
3761 GLfloat velmag = magnitude(velocity);
3762 GLfloat velmag2 = velmag - (float)delta_t * thrust * thrust_factor;
3773 velmag2 -= velmag * rate;
3776 else velocity = vector_multiply_scalar(velocity, velmag2 / velmag);
3781 [
self applyRoll:(float)delta_t*flightRoll andClimb:(float)delta_t*flightPitch];
3782 if (flightYaw != 0.0)
3784 [
self applyYaw:(float)delta_t*flightYaw];
3788 [
self moveForward:delta_t*flightSpeed];
3791 [
self updateTargeting];
3797- (void) performWitchspaceCountdownUpdates:(
OOTimeDelta)delta_t
3802 [
self doBookkeeping:delta_t];
3805 witchspaceCountdown = fdim(witchspaceCountdown, delta_t);
3811 if (
EXPECT_NOT(galactic_witchjump && ![
self hasEquipmentItem:
@"EQ_GAL_DRIVE"]))
3813 galactic_witchjump = NO;
3814 [
self setStatus:STATUS_IN_FLIGHT];
3815 [
self playHyperspaceAborted];
3820 int seconds = round(witchspaceCountdown);
3821 if (galactic_witchjump)
3823 [UNIVERSE displayCountdownMessage:OOExpandKey(@"witch-galactic-in-x-seconds", seconds) forCount:1.0];
3827 NSString *destination = [UNIVERSE getSystemName:[
self nextHopTargetSystemID]];
3828 [UNIVERSE displayCountdownMessage:OOExpandKey(@"witch-to-x-in-y-seconds", seconds, destination) forCount:1.0];
3831 if (witchspaceCountdown == 0.0)
3834 if (!galactic_witchjump)
3844 [UNIVERSE preloadPlanetTexturesForSystem:target_system_id];
3852 if (galactic_witchjump) [
self enterGalacticWitchspace];
3853 else [
self enterWitchspace];
3854 galactic_witchjump = NO;
3861- (void) performWitchspaceExitUpdates:(
OOTimeDelta)delta_t
3865 [
self resetExhaustPlumes];
3869 [
self resetScriptTimer];
3874 [UNIVERSE addMessage:[NSString stringWithFormat:@" %@. ",[UNIVERSE getSystemName:system_id]] forCount:3.0];
3876 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_COMPASS"])
3877 compassMode = COMPASS_MODE_PLANET;
3879 compassMode = COMPASS_MODE_BASIC;
3883 if ([
UNIVERSE inInterstellarSpace]) [UNIVERSE addMessage:DESC(@"witch-engine-malfunction") forCount:3.0];
3886 [
self setStatus:STATUS_IN_FLIGHT];
3891 if ([
self scriptedMisjump]) [
self setScriptedMisjump:NO];
3893 [
self setScriptedMisjumpRange:0.5];
3895 [
self doScriptEvent:OOJSID("shipExitedWitchspace") withArgument:[
self jumpCause]];
3897 [
self doBookkeeping:delta_t];
3899 suppressAegisMessages=NO;
3904- (void) performLaunchingUpdates:(
OOTimeDelta)delta_t
3908 flightRoll = launchRoll;
3909 [
self doBookkeeping:delta_t];
3918 [
self setStatus:STATUS_IN_FLIGHT];
3920 [
self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
3921 StationEntity *stationLaunchedFrom = [UNIVERSE nearestEntityMatchingPredicate:IsStationPredicate parameter:NULL relativeToEntity:self];
3922 [
self doScriptEvent:OOJSID("shipLaunchedFromStation") withArgument:stationLaunchedFrom];
3927- (void) performDockingUpdates:(
OOTimeDelta)delta_t
3938 [
self gameOverFadeToBW];
3942 BOOL was_mouse_control_on = mouse_control_on;
3943 [UNIVERSE handleGameOver];
3944 mouse_control_on = was_mouse_control_on;
3949- (void) gameOverFadeToBW
3951 float secondsToBWFadeOut = [[NSUserDefaults standardUserDefaults] oo_floatForKey:@"gameover-seconds-to-bw-fadeout" defaultValue:5.0f];
3955 static float originalColorSaturation = -1.0f;
3956 if (originalColorSaturation == -1.0f) originalColorSaturation = [gameView
colorSaturation];
3957 if ([
self shotTime] < secondsToBWFadeOut)
3961 if (fps_counter != 0)
3963 [gameView
adjustColorSaturation:-(originalColorSaturation * (1.0f / secondsToBWFadeOut) * [UNIVERSE timeAccelerationFactor] / fps_counter)];
3973 originalColorSaturation = -1.0f;
3982- (BOOL)isValidTarget:(
Entity*)target
3993 if ([target isShip])
3996 if ([targetShip isCloaked] ||
3997 ([targetShip isJammingScanning] && ![
self hasMilitaryScannerFilter]))
4002 if (tstatus == STATUS_ENTERING_WITCHSPACE || tstatus == STATUS_IN_HOLD || tstatus == STATUS_DOCKED)
4010 if ([target isWormhole] && [target scanClass] != CLASS_NO_DRAW &&
4011 [
self hasEquipmentItemProviding:
@"EQ_WORMHOLE_SCANNER"] && ident_engaged)
4021- (void) showGameOver
4023 [hud resetGuis:[NSDictionary dictionaryWithObject:[NSDictionary dictionary] forKey:@"message_gui"]];
4024 NSString *scoreMS = [NSString stringWithFormat:OOExpandKey(@"gameoverscreen-score-@"),
4025 KillCountToRatingAndKillString(ship_kills)];
4027 [UNIVERSE displayMessage:OOExpandKey(@"gameoverscreen-game-over") forCount:kDeadResetTime];
4028 [UNIVERSE displayMessage:@"" forCount:kDeadResetTime];
4029 [UNIVERSE displayMessage:scoreMS forCount:kDeadResetTime];
4030 [UNIVERSE displayMessage:@"" forCount:kDeadResetTime];
4031 [UNIVERSE displayMessage:OOExpandKey(@"gameoverscreen-press-space") forCount:kDeadResetTime];
4032 [UNIVERSE displayMessage:@" " forCount:kDeadResetTime];
4033 [UNIVERSE displayMessage:@"" forCount:kDeadResetTime];
4034 [
self resetShotTime];
4038- (void) showShipModelWithKey:(NSString *)shipKey shipData:(NSDictionary *)shipData personality:(uint16_t)personality factorX:(GLfloat)factorX factorY:(GLfloat)factorY factorZ:(GLfloat)factorZ inContext:(NSString *)context
4040 if (shipKey ==
nil)
return;
4042 if (shipData ==
nil)
return;
4044 Quaternion q2 = { (GLfloat)
M_SQRT1_2, (GLfloat)
M_SQRT1_2, (GLfloat)0.0f, (GLfloat)0.0f };
4046 if( demoShip !=
nil )
4048 q2 = [demoShip orientation];
4057 if (context)
OOLog(
@"script.debug.note.showShipModel",
@"::::: showShipModel:'%@' in context: %@.", [ship name], context);
4066 [ship
setAITo: @"nullAI.plist"];
4067 id subEntStatus = [shipData objectForKey:@"subentities_status"];
4070 [UNIVERSE addEntity: ship];
4072 demoShip = [ship retain];
4074 [ship
setStatus: STATUS_COCKPIT_DISPLAY];
4083- (void) doGuiScreenResizeUpdates
4085 switch ([
self guiScreen])
4087 case GUI_SCREEN_GAMEOPTIONS:
4089 [
self setGuiToGameOptionsScreen];
4091 case GUI_SCREEN_STATUS:
4094 [
self setGuiToStatusScreen];
4101 [hud resetGuiPositions];
4111- (void) updateTargeting
4117 if (ident_engaged && [
self primaryTarget] !=
nil)
4119 if (![
self isValidTarget:[
self primaryTarget]])
4121 if (!suppressTargetLost)
4123 [UNIVERSE addMessage:DESC(@"target-lost") forCount:3.0];
4124 [
self playTargetLost];
4125 [
self noteLostTarget];
4129 suppressTargetLost = NO;
4141 for (i = 0; i < max_missiles; i++)
4143 if ([missile_entity[i] primaryTarget] !=
nil &&
4144 ![
self isValidTarget:[missile_entity[i] primaryTarget]])
4146 [UNIVERSE addMessage:DESC(@"target-lost") forCount:3.0];
4147 [
self playTargetLost];
4148 [missile_entity[i] removeTarget:nil];
4149 if (i == activeMissile)
4151 [
self noteLostTarget];
4155 }
else if (i == activeMissile && [missile_entity[i] primaryTarget] ==
nil) {
4164 if ([
self primaryTarget] ==
nil &&
4166 ([
self status] == STATUS_IN_FLIGHT || [
self status] == STATUS_WITCHSPACE_COUNTDOWN))
4168 Entity *target = [UNIVERSE firstEntityTargetedByPlayer];
4169 if ([
self isValidTarget:target])
4171 [
self addTarget:target];
4177 UPDATE_STAGE(
@"checking for additional wormhole information");
4178 if ([[
self primaryTarget] isWormhole])
4181 switch ([wh scanInfo])
4195 if ([
self clockTimeAdjusted] > [wh scanTime] + 2)
4203 if([
self clockTimeAdjusted] > [wh scanTime] + 4)
4206 [UNIVERSE addCommsMessage:[NSString stringWithFormat:DESC(@"wormhole-arrival-time-computed-@"),
4211 if ([
self clockTimeAdjusted] > [wh scanTime] + 7)
4214 [UNIVERSE addCommsMessage:[NSString stringWithFormat:DESC(@"wormhole-destination-computed-@"),
4215 [UNIVERSE getSystemName:[wh
destination]]] forCount:5.0];
4219 if ([
self clockTimeAdjusted] > [wh scanTime] + 10)
4234- (void) orientationChanged
4236 quaternion_normalize(&orientation);
4238 OOMatrixGetBasisVectors(rotMatrix, &v_right, &v_up, &v_forward);
4240 orientation.w = -orientation.w;
4242 orientation.w = -orientation.w;
4246- (void) applyAttitudeChanges:(
double) delta_t
4248 [
self applyRoll:flightRoll*delta_t andClimb:flightPitch*delta_t];
4249 [
self applyYaw:flightYaw*delta_t];
4253- (void) applyRoll:(GLfloat) roll1 andClimb:(GLfloat) climb1
4255 if (roll1 == 0.0 && climb1 == 0.0 && hasRotated == NO)
4270 orientation = lastOrientation;
4278 [
self orientationChanged];
4286- (void) applyYaw:(GLfloat) yaw
4290 [
self orientationChanged];
4294- (OOMatrix) drawRotationMatrix
4296 return playerRotMatrix;
4300- (OOMatrix) drawTransformationMatrix
4302 OOMatrix result = playerRotMatrix;
4304 return OOMatrixTranslate(result, HPVectorToVector(position));
4308- (Quaternion) normalOrientation
4310 return make_quaternion(-orientation.w, orientation.x, orientation.y, orientation.z);
4314- (void) setNormalOrientation:(Quaternion) quat
4316 [
self setOrientation:make_quaternion(-quat.w, quat.x, quat.y, quat.z)];
4320- (void) moveForward:(
double) amount
4322 distanceTravelled += (float)amount;
4323 [
self setPosition:HPvector_add(position, vectorToHPVector(vector_multiply_scalar(v_forward, (float)amount)))];
4327- (HPVector) breakPatternPosition
4329 return HPvector_add(position,vectorToHPVector(
quaternion_rotate_vector(quaternion_conjugate(orientation),forwardViewOffset)));
4333- (Vector) viewpointOffset
4342 return forwardViewOffset;
4344 return aftViewOffset;
4346 return portViewOffset;
4347 case VIEW_STARBOARD:
4348 return starboardViewOffset;
4351 return customViewOffset;
4362- (Vector) viewpointOffsetAft
4364 return aftViewOffset;
4367- (Vector) viewpointOffsetForward
4369 return forwardViewOffset;
4372- (Vector) viewpointOffsetPort
4374 return portViewOffset;
4377- (Vector) viewpointOffsetStarboard
4379 return starboardViewOffset;
4385- (HPVector) viewpointPosition
4387 HPVector viewpoint = position;
4392 Vector
offset = [
self viewpointOffset];
4395 OOMatrix r = rotMatrix;
4397 viewpoint.x +=
offset.
x * r.m[0][0]; viewpoint.y +=
offset.
x * r.m[1][0]; viewpoint.z +=
offset.
x * r.m[2][0];
4398 viewpoint.x +=
offset.
y * r.m[0][1]; viewpoint.y +=
offset.
y * r.m[1][1]; viewpoint.z +=
offset.
y * r.m[2][1];
4399 viewpoint.x +=
offset.z * r.m[0][2]; viewpoint.y +=
offset.z * r.m[1][2]; viewpoint.z +=
offset.z * r.m[2][2];
4405- (void) drawImmediate:(
bool)immediate translucent:(
bool)translucent
4407 switch ([
self status])
4410 case STATUS_COCKPIT_DISPLAY:
4412 case STATUS_START_GAME:
4416 if ([
UNIVERSE breakPatternHide])
return;
4419 [
super drawImmediate:immediate translucent:translucent];
4423- (void) setMassLockable:(BOOL)newValue
4425 massLockable = !!newValue;
4426 [
self updateAlertCondition];
4430- (BOOL) massLockable
4432 return massLockable;
4442- (BOOL) atHyperspeed
4444 return travelling_at_hyperspeed;
4448- (float) occlusionLevel
4450 return occlusion_dial;
4454- (void) setOcclusionLevel:(
float)level
4456 occlusion_dial = level;
4460- (void) setDockedAtMainStation
4462 [
self setDockedStation:[UNIVERSE station]];
4463 if (_dockedStation !=
nil) [
self setStatus:STATUS_DOCKED];
4469 return [_dockedStation weakRefUnderlyingObject];
4475 [_dockedStation release];
4482 targetDockStation = value;
4488 return targetDockStation;
4502 NSString *hud_desc = [shipDict oo_stringForKey:@"hud" defaultValue:@"hud.plist"];
4503 if (![
self switchHudTo:hud_desc]) [
self switchHudTo:
@"hud.plist"];
4507- (BOOL) switchHudTo:(NSString *)hudFileName
4509 NSDictionary *hudDict =
nil;
4510 BOOL wasHidden = NO;
4511 BOOL wasCompassActive = YES;
4512 double scannerZoom = 1.0;
4513 NSUInteger lastMFD = 0;
4516 if (!hudFileName)
return NO;
4519 if (hud !=
nil && [hud isUpdating])
4521 [hud setDeferredHudName:hudFileName];
4529 OOLog(
@"PlayerEntity.switchHudTo.failed",
@"HUD dictionary file %@ to switch to not found or invalid.", hudFileName);
4536 wasHidden = [hud isHidden];
4537 wasCompassActive = [hud isCompassActive];
4538 scannerZoom = [hud scannerZoom];
4539 lastMFD = activeMFD;
4545 [hud setHidden:YES];
4547 hud = [[
HeadUpDisplay alloc] initWithDictionary:hudDict inFile:hudFileName];
4548 [hud resetGuis:hudDict];
4550 [hud setScannerZoom:scannerZoom];
4551 [hud setCompassActive:wasCompassActive];
4552 [hud setHidden:wasHidden];
4554 NSArray *savedMFDs = [NSArray arrayWithArray:multiFunctionDisplaySettings];
4555 [multiFunctionDisplaySettings removeAllObjects];
4556 for (i = 0; i < [hud mfdCount] ; i++)
4558 if ([savedMFDs
count] > i)
4560 [multiFunctionDisplaySettings addObject:[savedMFDs objectAtIndex:i]];
4564 [multiFunctionDisplaySettings addObject:[NSNull null]];
4567 if (lastMFD < [hud mfdCount]) activeMFD = lastMFD;
4574- (float) dialCustomFloat:(NSString *)dialKey
4576 return [customDialSettings oo_floatForKey:dialKey defaultValue:0.0];
4580- (NSString *) dialCustomString:(NSString *)dialKey
4582 return [customDialSettings oo_stringForKey:dialKey defaultValue:@""];
4586- (
OOColor *) dialCustomColor:(NSString *)dialKey
4592- (void) setDialCustom:(
id)value forKey:(NSString *)dialKey
4594 [customDialSettings setObject:value forKey:dialKey];
4598- (void) setShowDemoShips:(BOOL)value
4600 showDemoShips = value;
4604- (BOOL) showDemoShips
4606 return showDemoShips;
4610- (float) maxForwardShieldLevel
4612 return max_forward_shield;
4616- (float) maxAftShieldLevel
4618 return max_aft_shield;
4622- (float) forwardShieldRechargeRate
4624 return forward_shield_recharge_rate;
4628- (float) aftShieldRechargeRate
4630 return aft_shield_recharge_rate;
4634- (void) setMaxForwardShieldLevel:(
float)new
4636 max_forward_shield =
new;
4640- (void) setMaxAftShieldLevel:(
float)new
4642 max_aft_shield =
new;
4646- (void) setForwardShieldRechargeRate:(
float)new
4648 forward_shield_recharge_rate =
new;
4652- (void) setAftShieldRechargeRate:(
float)new
4654 aft_shield_recharge_rate =
new;
4658- (GLfloat) forwardShieldLevel
4660 return forward_shield;
4664- (GLfloat) aftShieldLevel
4670- (void) setForwardShieldLevel:(GLfloat)level
4672 forward_shield = OOClamp_0_max_f(level, [
self maxForwardShieldLevel]);
4676- (void) setAftShieldLevel:(GLfloat)level
4678 aft_shield = OOClamp_0_max_f(level, [
self maxAftShieldLevel]);
4682- (NSDictionary *) keyConfig
4685 return keyconfig2_settings;
4689- (BOOL) isMouseControlOn
4691 return mouse_control_on;
4697 GLfloat result = flightRoll / max_flight_roll;
4698 if ((result < 1.0f)&&(result > -1.0f))
4706- (GLfloat) dialPitch
4708 GLfloat result = flightPitch / max_flight_pitch;
4709 if ((result < 1.0f)&&(result > -1.0f))
4719 GLfloat result = -flightYaw / max_flight_yaw;
4720 if ((result < 1.0f)&&(result > -1.0f))
4728- (GLfloat) dialSpeed
4730 GLfloat result = flightSpeed / maxFlightSpeed;
4731 return OOClamp_0_1_f(result);
4735- (GLfloat) dialHyperSpeed
4737 return flightSpeed / maxFlightSpeed;
4741- (GLfloat) dialForwardShield
4743 if (
EXPECT_NOT([
self maxForwardShieldLevel] <= 0))
4747 GLfloat result = forward_shield / [
self maxForwardShieldLevel];
4748 return OOClamp_0_1_f(result);
4752- (GLfloat) dialAftShield
4754 if (
EXPECT_NOT([
self maxAftShieldLevel] <= 0))
4758 GLfloat result = aft_shield / [
self maxAftShieldLevel];
4759 return OOClamp_0_1_f(result);
4763- (GLfloat) dialEnergy
4765 GLfloat result = energy / maxEnergy;
4766 return OOClamp_0_1_f(result);
4770- (GLfloat) dialMaxEnergy
4780 if (fuel > [
self fuelCapacity])
4782 return (GLfloat)fuel / (GLfloat)[
self fuelCapacity];
4786- (GLfloat) dialHyperRange
4788 if (target_system_id == system_id && ![
UNIVERSE inInterstellarSpace])
return 0.0f;
4793- (GLfloat) laserHeatLevel
4796 return OOClamp_0_1_f(result);
4800- (GLfloat)laserHeatLevelAft
4803 return OOClamp_0_1_f(result);
4807- (GLfloat)laserHeatLevelForward
4811 return OOClamp_0_1_f(result);
4815- (GLfloat)laserHeatLevelPort
4818 return OOClamp_0_1_f(result);
4822- (GLfloat)laserHeatLevelStarboard
4825 return OOClamp_0_1_f(result);
4831- (GLfloat) dialAltitude
4833 if ([
self isDocked])
return 0.0f;
4838 Entity *nearestPlanet = [
self findNearestStellarBody];
4839 if (nearestPlanet ==
nil)
return 1.0f;
4843 GLfloat alt = sqrt(zd) - cr;
4855- (double) clockTimeAdjusted
4857 return ship_clock + ship_clock_adjust;
4861- (BOOL) clockAdjusting
4863 return ship_clock_adjust > 0;
4867- (void) addToAdjustTime:(
double)seconds
4869 ship_clock_adjust += seconds;
4873- (double) escapePodRescueTime
4875 return escape_pod_rescue_time;
4879- (void) setEscapePodRescueTime:(
double)seconds
4881 escape_pod_rescue_time = seconds;
4884- (NSString *) dial_clock
4890- (NSString *) dial_clock_adjusted
4896- (NSString *) dial_fpsinfo
4898 unsigned fpsVal = fps_counter;
4899 return [NSString stringWithFormat:@"FPS: %3d", fpsVal];
4903- (NSString *) dial_objinfo
4905 NSString *result = [NSString stringWithFormat:@"Entities: %3ld", [UNIVERSE entityCount]];
4907 result = [NSString stringWithFormat:@"%@ (%d, %zu KiB, avg %lu bytes)", result, gLiveEntityCount, gTotalEntityMemory >> 10, gTotalEntityMemory / gLiveEntityCount];
4914- (unsigned) countMissiles
4916 unsigned n_missiles = 0;
4918 for (i = 0; i < max_missiles; i++)
4920 if (missile_entity[i])
4929 if ([
self weaponsOnline])
4931 return missile_status;
4938 OOLogERR(
@"player.missilesUnsafe",
@"%@",
@"Missile state is not SAFE when weapons are offline. This is a bug, please report it.");
4939 [
self safeAllMissiles];
4948 if (specialCargo)
return NO;
4949 return [
super canScoop:other];
4957 if ([
self hasScoop])
4961 if (cargoOnBoard >= [
self maxAvailableCargoSpace] || specialCargo)
4972- (float) fuelLeakRate
4974 return fuel_leak_rate;
4978- (void) setFuelLeakRate:(
float)value
4980 fuel_leak_rate = fmax(value, 0.0f);
4984- (NSMutableArray *) commLog
4990 NSUInteger
count = [commLog count];
4993 [commLog removeObjectsInRange:NSMakeRange(0, count - kCommLogTrimSize)];
4998 commLog = [[NSMutableArray alloc] init];
5005- (NSMutableArray *) roleWeights
5011- (void) addRoleForAggression:(
ShipEntity *)victim
5013 if ([victim isExplicitlyUnpiloted] || [victim isHulk] || [victim hasHostileTarget] || [[victim primaryAggressor] isPlayer])
5017 NSString *role =
nil;
5018 if ([[victim primaryRole] isEqualToString:
@"escape-capsule"])
5020 role =
@"assassin-player";
5022 else if ([victim bounty] > 0)
5026 else if ([victim isPirateVictim])
5030 else if ([
UNIVERSE role:[
self primaryRole] isInCategory:
@"oolite-hunter"] || [victim scanClass] == CLASS_POLICE)
5032 role =
@"pirate-interceptor";
5038 NSUInteger times = [roleWeightFlags oo_intForKey:role defaultValue:0];
5040 [roleWeightFlags setObject:[NSNumber numberWithUnsignedInteger:times] forKey:role];
5041 if ((times & (times-1)) == 0)
5043 [
self addRoleToPlayer:role];
5048- (void) addRoleForMining
5050 NSString *role =
@"miner";
5051 NSUInteger times = [roleWeightFlags oo_intForKey:role defaultValue:0];
5053 [roleWeightFlags setObject:[NSNumber numberWithUnsignedInteger:times] forKey:role];
5054 if ((times & (times-1)) == 0)
5056 [
self addRoleToPlayer:role];
5061- (void) addRoleToPlayer:(NSString *)role
5063 NSUInteger slot =
Ranrot() & ([
self maxPlayerRoles]-1);
5064 [
self addRoleToPlayer:role inSlot:slot];
5068- (void) addRoleToPlayer:(NSString *)role inSlot:(NSUInteger)slot
5070 if (slot >= [
self maxPlayerRoles])
5072 slot = [
self maxPlayerRoles]-1;
5074 if (slot >= [roleWeights
count])
5076 [roleWeights addObject:role];
5080 [roleWeights replaceObjectAtIndex:slot withObject:role];
5085- (void) clearRoleFromPlayer:(BOOL)includingLongRange
5087 NSUInteger slot =
Ranrot() % [roleWeights count];
5088 if (!includingLongRange)
5090 NSString *role = [roleWeights objectAtIndex:slot];
5092 if ([role hasSuffix:
@"+"] &&
randf() > 0.5)
5097 [roleWeights replaceObjectAtIndex:slot withObject:@"player-unknown"];
5101- (void) clearRolesFromPlayer:(
float)chance
5103 NSUInteger i,
count=[roleWeights count];
5104 for (i = 0; i <
count; i++)
5106 if (
randf() < chance)
5108 [roleWeights replaceObjectAtIndex:i withObject:@"player-unknown"];
5114- (NSUInteger) maxPlayerRoles
5116 if (ship_kills >= 6400)
5120 else if (ship_kills >= 128)
5131- (void) updateSystemMemory
5138 NSUInteger memory = 4;
5139 if (ship_kills >= 6400)
5143 else if (ship_kills >= 256)
5147 else if (ship_kills >= 64)
5151 if ([roleSystemList
count] >= memory)
5153 [roleSystemList removeObjectAtIndex:0];
5155 [roleSystemList addObject:[NSNumber numberWithInt:sys]];
5159- (
Entity *) compassTarget
5161 Entity *result = [compassTarget weakRefUnderlyingObject];
5171- (void) setCompassTarget:(
Entity *)value
5173 [compassTarget release];
5178- (void) validateCompassTarget
5181 OOPlanetEntity *the_planet = [UNIVERSE planet];
5183 Entity *the_target = [
self primaryTarget];
5184 Entity <OOBeaconEntity> *beacon = [
self nextBeacon];
5185 if ([
self isInSpace] && the_sun && the_planet
5186 && ![the_sun goneNova])
5191 switch ([
self compassMode])
5193 case COMPASS_MODE_INACTIVE:
5196 case COMPASS_MODE_BASIC:
5199 new_target = the_station;
5203 new_target = the_planet;
5207 case COMPASS_MODE_PLANET:
5208 new_target = the_planet;
5211 case COMPASS_MODE_STATION:
5212 new_target = the_station;
5215 case COMPASS_MODE_SUN:
5216 new_target = the_sun;
5219 case COMPASS_MODE_TARGET:
5220 new_target = the_target;
5223 case COMPASS_MODE_BEACONS:
5224 new_target = beacon;
5228 if (new_target ==
nil || [new_target status] < STATUS_ACTIVE || [new_target status] == STATUS_IN_HOLD)
5230 [
self setCompassMode:COMPASS_MODE_PLANET];
5231 new_target = the_planet;
5234 if (
EXPECT_NOT(new_target != [
self compassTarget]))
5236 [
self setCompassTarget:new_target];
5237 [
self doScriptEvent:OOJSID("compassTargetChanged") withArguments:[NSArray arrayWithObjects:new_target, OOStringFromCompassMode([
self compassMode]), nil]];
5243- (NSString *) compassTargetLabel
5245 switch (compassMode)
5247 case COMPASS_MODE_INACTIVE:
5249 case COMPASS_MODE_BASIC:
5251 case COMPASS_MODE_BEACONS:
5253 Entity *target = [
self compassTarget];
5260 case COMPASS_MODE_PLANET:
5261 return [[UNIVERSE planet] name];
5262 case COMPASS_MODE_SUN:
5263 return [[UNIVERSE sun] name];
5264 case COMPASS_MODE_STATION:
5265 return [[UNIVERSE station] displayName];
5266 case COMPASS_MODE_TARGET:
5267 return DESC(
@"oolite-beacon-label-target");
5281 compassMode = value;
5285- (void) setPrevCompassMode
5288 Entity <OOBeaconEntity> *beacon =
nil;
5290 switch (compassMode)
5292 case COMPASS_MODE_INACTIVE:
5293 case COMPASS_MODE_BASIC:
5294 case COMPASS_MODE_PLANET:
5295 beacon = [UNIVERSE lastBeacon];
5296 while (beacon !=
nil && [beacon isJammingScanning])
5298 beacon = [beacon prevBeacon];
5300 [
self setNextBeacon:beacon];
5304 [
self setCompassMode:COMPASS_MODE_BEACONS];
5309 case COMPASS_MODE_BEACONS:
5310 beacon = [
self nextBeacon];
5313 beacon = [beacon prevBeacon];
5314 }
while (beacon !=
nil && [beacon isJammingScanning]);
5315 [
self setNextBeacon:beacon];
5319 if ([
self primaryTarget])
5321 [
self setCompassMode:COMPASS_MODE_TARGET];
5325 [
self setCompassMode:COMPASS_MODE_SUN];
5331 case COMPASS_MODE_TARGET:
5332 [
self setCompassMode:COMPASS_MODE_SUN];
5335 case COMPASS_MODE_SUN:
5336 aegis = [
self checkForAegis];
5339 [
self setCompassMode:COMPASS_MODE_STATION];
5343 [
self setCompassMode:COMPASS_MODE_PLANET];
5347 case COMPASS_MODE_STATION:
5348 [
self setCompassMode:COMPASS_MODE_PLANET];
5354- (void) setNextCompassMode
5357 Entity <OOBeaconEntity> *beacon =
nil;
5359 switch (compassMode)
5361 case COMPASS_MODE_INACTIVE:
5362 case COMPASS_MODE_BASIC:
5363 case COMPASS_MODE_PLANET:
5364 aegis = [
self checkForAegis];
5367 [
self setCompassMode:COMPASS_MODE_STATION];
5371 [
self setCompassMode:COMPASS_MODE_SUN];
5375 case COMPASS_MODE_STATION:
5376 [
self setCompassMode:COMPASS_MODE_SUN];
5379 case COMPASS_MODE_SUN:
5380 if ([
self primaryTarget])
5382 [
self setCompassMode:COMPASS_MODE_TARGET];
5387 case COMPASS_MODE_TARGET:
5388 beacon = [UNIVERSE firstBeacon];
5389 while (beacon !=
nil && [beacon isJammingScanning])
5391 beacon = [beacon nextBeacon];
5393 [
self setNextBeacon:beacon];
5395 if (beacon !=
nil) [
self setCompassMode:COMPASS_MODE_BEACONS];
5396 else [
self setCompassMode:COMPASS_MODE_PLANET];
5399 case COMPASS_MODE_BEACONS:
5400 beacon = [
self nextBeacon];
5403 beacon = [beacon nextBeacon];
5404 }
while (beacon !=
nil && [beacon isJammingScanning]);
5405 [
self setNextBeacon:beacon];
5409 [
self setCompassMode:COMPASS_MODE_PLANET];
5416- (NSUInteger) activeMissile
5418 return activeMissile;
5422- (void) setActiveMissile:(NSUInteger)value
5424 activeMissile = value;
5428- (NSUInteger) dialMaxMissiles
5430 return max_missiles;
5434- (BOOL) dialIdentEngaged
5436 return ident_engaged;
5440- (void) setDialIdentEngaged:(BOOL)newValue
5442 ident_engaged = !!newValue;
5446- (NSString *) specialCargo
5448 return specialCargo;
5452- (NSString *) dialTargetName
5454 Entity *target_entity = [
self primaryTarget];
5455 NSString *result =
nil;
5457 if (target_entity ==
nil)
5459 result =
DESC(
@"no-target-string");
5462 if ([target_entity respondsToSelector:@selector(identFromShip:)])
5467 if (result ==
nil) result =
DESC(
@"unknown-target");
5473- (NSArray *) multiFunctionDisplayList
5475 return multiFunctionDisplaySettings;
5479- (NSString *) multiFunctionText:(NSUInteger)i
5481 NSString *key = [multiFunctionDisplaySettings oo_stringAtIndex:i defaultValue:nil];
5486 NSString *text = [multiFunctionDisplayText oo_stringForKey:key defaultValue:nil];
5491- (void) setMultiFunctionText:(NSString *)text forKey:(NSString *)key
5495 [multiFunctionDisplayText setObject:text forKey:key];
5497 else if (key !=
nil)
5499 [multiFunctionDisplayText removeObjectForKey:key];
5502 while ((index = [multiFunctionDisplaySettings indexOfObject:key]) != NSNotFound)
5504 [multiFunctionDisplaySettings replaceObjectAtIndex:index withObject:[NSNull null]];
5510- (BOOL) setMultiFunctionDisplay:(NSUInteger)index toKey:(NSString *)key
5512 if (index >= [hud mfdCount])
5515 index = [multiFunctionDisplaySettings indexOfObject:[NSNull null]];
5516 if (index == NSNotFound)
5522 if (index < [hud mfdCount])
5526 [multiFunctionDisplaySettings replaceObjectAtIndex:index withObject:[NSNull null]];
5530 [multiFunctionDisplaySettings replaceObjectAtIndex:index withObject:key];
5541- (void) cycleNextMultiFunctionDisplay:(NSUInteger) index
5543 if ([[
self hud] mfdCount] == 0)
return;
5544 NSArray *keys = [multiFunctionDisplayText allKeys];
5545 NSString *key =
nil;
5546 if ([keys
count] == 0)
5548 [
self setMultiFunctionDisplay:index toKey:nil];
5551 id current = [multiFunctionDisplaySettings objectAtIndex:index];
5552 if (current == [NSNull
null])
5554 key = [keys objectAtIndex:0];
5555 [
self setMultiFunctionDisplay:index toKey:key];
5559 NSUInteger cIndex = [keys indexOfObject:current];
5560 if (cIndex == NSNotFound || cIndex + 1 >= [keys
count])
5563 [
self setMultiFunctionDisplay:index toKey:nil];
5567 key = [keys objectAtIndex:(cIndex+1)];
5568 [
self setMultiFunctionDisplay:index toKey:key];
5573 ShipScriptEvent(context,
self,
"mfdKeyChanged", INT_TO_JSVAL(activeMFD), keyVal);
5578- (void) cyclePreviousMultiFunctionDisplay:(NSUInteger) index
5580 if ([[
self hud] mfdCount] == 0)
return;
5581 NSArray *keys = [multiFunctionDisplayText allKeys];
5582 NSString *key =
nil;
5583 if ([keys
count] == 0)
5585 [
self setMultiFunctionDisplay:index toKey:nil];
5588 id current = [multiFunctionDisplaySettings objectAtIndex:index];
5589 if (current == [NSNull
null])
5591 key = [keys objectAtIndex:([keys count]-1)];
5592 [
self setMultiFunctionDisplay:index toKey:key];
5596 NSUInteger cIndex = [keys indexOfObject:current];
5597 if (cIndex == NSNotFound || cIndex == 0)
5600 [
self setMultiFunctionDisplay:index toKey:nil];
5604 key = [keys objectAtIndex:(cIndex-1)];
5605 [
self setMultiFunctionDisplay:index toKey:key];
5610 ShipScriptEvent(context,
self,
"mfdKeyChanged", INT_TO_JSVAL(activeMFD), keyVal);
5615- (void) selectNextMultiFunctionDisplay
5617 if ([[
self hud] mfdCount] == 0)
return;
5618 activeMFD = (activeMFD + 1) % [[
self hud] mfdCount];
5619 NSUInteger mfdID = activeMFD + 1;
5620 [UNIVERSE addMessage:OOExpandKey(@"mfd-N-selected", mfdID) forCount:3.0 ];
5622 ShipScriptEvent(context,
self,
"selectedMFDChanged", INT_TO_JSVAL(activeMFD));
5627- (void) selectPreviousMultiFunctionDisplay
5629 if ([[
self hud] mfdCount] == 0)
return;
5632 activeMFD = ([[
self hud] mfdCount] - 1);
5636 activeMFD = (activeMFD - 1);
5638 NSUInteger mfdID = activeMFD + 1;
5639 [UNIVERSE addMessage:OOExpandKey(@"mfd-N-selected", mfdID) forCount:3.0 ];
5641 ShipScriptEvent(context,
self,
"selectedMFDChanged", INT_TO_JSVAL(activeMFD));
5646- (NSUInteger) activeMFD
5652- (
ShipEntity *) missileForPylon:(NSUInteger)value
5654 if (value < max_missiles)
return missile_entity[value];
5660- (void) safeAllMissiles
5665 for (i = 0; i < max_missiles; i++)
5667 if (missile_entity[i] && [missile_entity[i] primaryTarget] !=
nil)
5668 [missile_entity[i] removeTarget:
nil];
5674- (void) tidyMissilePylons
5681 OOLog(
@"missile.tidying.debug",
@"%d %@ %@",i,missile_entity[i],missile_list[i]);
5682 if(missile_entity[i] !=
nil)
5684 missile_entity[pylon] = missile_entity[i];
5693 missile_entity[i] =
nil;
5695 missile_list[i] =
nil;
5700- (void) selectNextMissile
5702 if (![
self weaponsOnline])
return;
5705 for (i = 1; i < max_missiles; i++)
5707 int next_missile = (activeMissile + i) % max_missiles;
5708 if (missile_entity[next_missile])
5711 if( ![
self hasEquipmentItemProviding:
@"EQ_MULTI_TARGET"] && [missile_entity[activeMissile] isMissile] )
5713 [missile_entity[activeMissile] removeTarget:nil];
5717 [
self setActiveMissile:next_missile];
5724 if( [missile_entity[activeMissile] isMissile] )
5726 if( [
self hasEquipmentItemProviding:
@"EQ_MULTI_TARGET"] &&
5727 ([missile_entity[next_missile] primaryTarget] !=
nil))
5730 [
self addTarget:[missile_entity[next_missile] primaryTarget]];
5733 else if ([
self primaryTarget] !=
nil)
5739 if([
self hasEquipmentItemProviding:
@"EQ_MULTI_TARGET"] && !launchingMissile)
5741 [
self noteLostTarget];
5746 [missile_entity[activeMissile] addTarget:[
self primaryTarget]];
5758- (void) clearAlertFlags
5770- (void) setAlertFlag:(
int)flag to:(BOOL)value
5787 return [
self alertCondition];
5796 [
self setAlertFlag:ALERT_FLAG_DOCKED to:[
self status] == STATUS_DOCKED];
5804 if (alertFlags != 0)
5815 [
self playAlertConditionRed];
5818 return alertCondition;
5824 return fleeing_status;
5830- (void) interpretAIMessage:(NSString *)ms
5832 if ([ms isEqual:
@"HOLD_FULL"])
5834 [
self playHoldFull];
5835 [UNIVERSE addMessage:DESC(@"hold-full") forCount:4.5];
5838 if ([ms isEqual:
@"INCOMING_MISSILE"])
5840 if ([
self primaryAggressor] !=
nil)
5842 [
self playIncomingMissile:HPVectorToVector([[
self primaryAggressor] position])];
5846 [
self playIncomingMissile:kZeroVector];
5848 [UNIVERSE addMessage:DESC(@"incoming-missile") forCount:4.5];
5851 if ([ms isEqual:
@"ENERGY_LOW"])
5853 [UNIVERSE addMessage:DESC(@"energy-low") forCount:6.0];
5856 if ([ms isEqual:
@"ECM"] && ![
self isDocked]) [
self playHitByECMSound];
5858 if ([ms isEqual:
@"DOCKING_REFUSED"] && [
self status] == STATUS_AUTOPILOT_ENGAGED)
5860 [
self playDockingDenied];
5861 [UNIVERSE addMessage:DESC(@"autopilot-denied") forCount:4.5];
5862 autopilot_engaged = NO;
5863 [
self resetAutopilotAI];
5865 [
self setStatus:STATUS_IN_FLIGHT];
5867 [
self doScriptEvent:OOJSID("playerDockingRefused")];
5871 if (compassMode != COMPASS_MODE_BASIC)
5873 if ([ms isEqual:
@"AEGIS_CLOSE_TO_MAIN_PLANET"]&&(compassMode == COMPASS_MODE_PLANET))
5875 [
self playAegisCloseToPlanet];
5876 [
self setCompassMode:COMPASS_MODE_STATION];
5878 if ([ms isEqual:
@"AEGIS_IN_DOCKING_RANGE"]&&(compassMode == COMPASS_MODE_PLANET))
5880 [
self playAegisCloseToStation];
5881 [
self setCompassMode:COMPASS_MODE_STATION];
5883 if ([ms isEqual:
@"AEGIS_NONE"]&&(compassMode == COMPASS_MODE_STATION))
5885 [
self setCompassMode:COMPASS_MODE_PLANET];
5893 if (missile ==
nil)
return NO;
5896 for (i = 0; i < max_missiles; i++)
5898 if (missile_entity[i] ==
nil)
5900 missile_entity[i] = [missile retain];
5903 if (missiles == 1) [
self setActiveMissile:0];
5912- (BOOL) mountMissileWithRole:(NSString *)role
5914 if ([
self missileCount] >= [
self missileCapacity])
return NO;
5915 return [
self mountMissile:[[UNIVERSE newShipWithRole:role] autorelease]];
5921 ShipEntity *missile = missile_entity[activeMissile];
5925 if (missile ==
nil)
return nil;
5927 if (![
self weaponsOnline])
return nil;
5932 BOOL cloakedPriorToFiring = cloaking_device_active;
5934 launchingMissile = YES;
5935 replacingMissile = NO;
5939 firedMissile = [
self launchMine:missile];
5940 if (!replacingMissile) [
self removeFromPylon:activeMissile];
5941 if (firedMissile !=
nil) [
self playMineLaunched:[
self missileLaunchPosition] weaponIdentifier:identifier];
5947 firedMissile = [
self fireMissileWithIdentifier:identifier andTarget:[missile
primaryTarget]];
5949 if (firedMissile !=
nil)
5951 if (!replacingMissile) [
self removeFromPylon:activeMissile];
5952 [
self playMissileLaunched:[
self missileLaunchPosition] weaponIdentifier:identifier];
5956 if (cloakedPriorToFiring && cloakPassive)
5961 [
self deactivateCloakingDevice];
5964 replacingMissile = NO;
5965 launchingMissile = NO;
5967 return firedMissile;
5976 if (![
self weaponsOnline])
5981 [
self dumpItem: mine];
5984 float mine_speed = 500.0f;
5985 Vector mvel = vector_subtract([mine velocity], vector_multiply_scalar(v_forward, mine_speed));
5987 [
self doScriptEvent:OOJSID("shipReleasedEquipment") withArgument:mine];
5992- (BOOL) assignToActivePylon:(NSString *)equipmentKey
5994 if (!launchingMissile)
return NO;
5998 if ([equipmentKey hasSuffix:
@"_DAMAGED"])
6013 ShipEntity *amiss = [UNIVERSE newShipWithRole:equipmentKey];
6015 if (!amiss)
return NO;
6018 [missile_entity[activeMissile] release];
6019 missile_entity[activeMissile] = amiss;
6020 missile_list[activeMissile] = eqType;
6023 if (activeMissile > 0) activeMissile--;
6024 else activeMissile = max_missiles - 1;
6025 [
self selectNextMissile];
6027 replacingMissile = YES;
6033- (BOOL) activateCloakingDevice
6035 if (![
self hasCloakingDevice])
return NO;
6037 if ([super activateCloakingDevice])
6039 [UNIVERSE setCurrentPostFX:OO_POSTFX_CLOAK];
6040 [UNIVERSE addMessage:DESC(@"cloak-on") forCount:2];
6041 [
self playCloakingDeviceOn];
6046 [UNIVERSE addMessage:DESC(@"cloak-low-juice") forCount:3];
6047 [
self playCloakingDeviceInsufficientEnergy];
6053- (void) deactivateCloakingDevice
6055 if (![
self hasCloakingDevice])
return;
6057 [
super deactivateCloakingDevice];
6058 [UNIVERSE setCurrentPostFX:[UNIVERSE colorblindMode]];
6059 [UNIVERSE addMessage:DESC(@"cloak-off") forCount:2];
6060 [
self playCloakingDeviceOff];
6066- (double) scannerFuzziness
6070 double since = [UNIVERSE getTime] - last_ecm_time;
6083 last_ecm_time = [UNIVERSE getTime];
6089 if ([super fireECM])
6091 ecm_in_operation = YES;
6092 ecm_start_time = [UNIVERSE getTime];
6120- (void) currentWeaponStats
6126 [
self setWeaponDataFromType:currentWeapon];
6130- (BOOL) weaponsOnline
6132 return weapons_online;
6136- (void) setWeaponsOnline:(BOOL)newValue
6138 weapons_online = !!newValue;
6139 if (!weapons_online) [
self safeAllMissiles];
6143- (NSArray *) currentLaserOffset
6145 return [
self laserPortOffset:currentWeaponFacing];
6149- (BOOL) fireMainWeapon
6151 OOWeaponType weapon_to_be_fired = [
self currentWeapon];
6153 if (![
self weaponsOnline])
6160 [
self playWeaponOverheated:[[
self currentLaserOffset] oo_vectorAtIndex:0]];
6161 [UNIVERSE addMessage:DESC(@"weapon-overheat") forCount:3.0];
6170 [
self currentWeaponStats];
6172 NSUInteger multiplier = 1;
6173 if (_multiplyWeapons)
6176 multiplier = [[
self laserPortOffset:currentWeaponFacing] count];
6179 if (energy <= weapon_energy_use * multiplier)
6181 [UNIVERSE addMessage:DESC(@"weapon-out-of-juice") forCount:3.0];
6187 energy -= weapon_energy_use * multiplier;
6189 switch (currentWeaponFacing)
6192 forward_weapon_temp += weapon_shot_temperature * multiplier;
6193 forward_shot_time = 0.0;
6197 aft_weapon_temp += weapon_shot_temperature * multiplier;
6198 aft_shot_time = 0.0;
6202 port_weapon_temp += weapon_shot_temperature * multiplier;
6203 port_shot_time = 0.0;
6207 starboard_weapon_temp += weapon_shot_temperature * multiplier;
6208 starboard_shot_time = 0.0;
6215 BOOL weaponFired = NO;
6218 if (![weapon_to_be_fired isTurretLaser])
6220 [
self fireLaserShotInDirection:currentWeaponFacing weaponIdentifier:[[
self currentWeapon] identifier]];
6229 if (weaponFired && cloaking_device_active && cloakPassive)
6231 [
self deactivateCloakingDevice];
6243 return forward_weapon_type;
6246 return aft_weapon_type;
6249 return port_weapon_type;
6252 return starboard_weapon_type;
6263 return [
self weaponForFacing:currentWeaponFacing];
6270- (GLfloat) doesHitLine:(HPVector)v0 :(HPVector)v1 :(
ShipEntity **)hitEntity
6274 Vector u0 = HPVectorToVector(HPvector_between(position, v0));
6275 Vector u1 = HPVectorToVector(HPvector_between(position, v1));
6276 Vector w0 = make_vector(dot_product(u0, v_right), dot_product(u0, v_up), dot_product(u0, v_forward));
6277 Vector w1 = make_vector(dot_product(u1, v_right), dot_product(u1, v_up), dot_product(u1, v_forward));
6278 GLfloat hit_distance = [octree isHitByLine:w0 :w1];
6282 hitEntity[0] =
self;
6285 bool shields =
false;
6286 if ((w0.z >= 0 && forward_shield > 1) || (w0.z <= 0 && aft_shield > 1))
6291 NSEnumerator *subEnum =
nil;
6293 for (subEnum = [
self shipSubEntityEnumerator]; (se = [subEnum nextObject]); )
6297 u0 = HPVectorToVector(HPvector_between(p0, v0));
6298 u1 = HPVectorToVector(HPvector_between(p0, v1));
6299 w0 = resolveVectorInIJK(u0, ijk);
6300 w1 = resolveVectorInIJK(u1, ijk);
6302 GLfloat hitSub = [se->octree isHitByLine:w0 :w1];
6303 if (hitSub && (hit_distance == 0 || hit_distance > hitSub))
6305 hit_distance = hitSub;
6306 if (hitEntity && !shields)
6313 return hit_distance;
6318- (void) takeEnergyDamage:(
double)amount from:(
Entity *)ent becauseOf:(
Entity *)other weaponIdentifier:(NSString *)weaponIdentifier
6322 BOOL internal_damage = NO;
6324 OOLog(
@"player.ship.damage",
@"Player took damage from %@ becauseOf %@", ent, other);
6326 if ([
self status] == STATUS_DEAD)
return;
6327 if ([
self status] == STATUS_ESCAPE_SEQUENCE)
return;
6328 if (amount == 0.0)
return;
6331 BOOL cascading = NO;
6334 cascading = [
self cascadeIfAppropriateWithDamageAmount:amount cascadeOwner:[ent
owner]];
6338 if (ent && [ent isSubEntity]) ent = [ent
owner];
6340 [[ent retain] autorelease];
6341 [[other retain] autorelease];
6344 rel_pos = HPvector_subtract(rel_pos, position);
6346 [
self doScriptEvent:OOJSID("shipBeingAttacked") withArgument:ent];
6347 if ([ent isShip]) [(
ShipEntity *)
ent doScriptEvent:OOJSID("shipAttackedOther") withArgument:self];
6349 d_forward = dot_product(HPVectorToVector(rel_pos), v_forward);
6350 d_right = dot_product(HPVectorToVector(rel_pos), v_right);
6351 d_up = dot_product(HPVectorToVector(rel_pos), v_up);
6352 Vector relative = make_vector(d_right,d_up,d_forward);
6354 [
self playShieldHit:relative weaponIdentifier:weaponIdentifier];
6359 [
self broadcastHitByLaserFrom:(ShipEntity*) other];
6364 forward_shield -= amount;
6365 if (forward_shield < 0.0)
6367 amount = -forward_shield;
6368 forward_shield = 0.0f;
6377 aft_shield -= amount;
6378 if (aft_shield < 0.0)
6380 amount = -aft_shield;
6389 OOShipDamageType damageType = cascadeWeapon ? kOODamageTypeCascadeWeapon : kOODamageTypeEnergy;
6394 [
self playDirectHit:relative weaponIdentifier:weaponIdentifier];
6407 [
self noteTakingDamage:amount from:other type:damageType];
6408 if (cascading) energy = 0.0;
6417 [
self getDestroyedBy:other damageType:damageType];
6421 while (amount > 0.0)
6424 if (internal_damage)
6426 [
self takeInternalDamage];
6434- (void) takeScrapeDamage:(
double) amount from:(
Entity *) ent
6438 BOOL internal_damage = NO;
6440 if ([
self status] == STATUS_DEAD)
return;
6444 OOLog(
@"player.ship.damage",
@"Player took negative scrape damage %.3f so we made it positive", amount);
6447 OOLog(
@"player.ship.damage",
@"Player took %.3f scrape damage from %@", amount, ent);
6449 [[ent retain] autorelease];
6451 rel_pos = HPvector_subtract(rel_pos, position);
6453 d_forward = dot_product(HPVectorToVector(rel_pos), v_forward);
6454 d_right = dot_product(HPVectorToVector(rel_pos), v_right);
6455 d_up = dot_product(HPVectorToVector(rel_pos), v_up);
6456 Vector relative = make_vector(d_right,d_up,d_forward);
6458 [
self playScrapeDamage:relative];
6461 forward_shield -= amount;
6462 if (forward_shield < 0.0)
6464 amount = -forward_shield;
6465 forward_shield = 0.0f;
6474 aft_shield -= amount;
6475 if (aft_shield < 0.0)
6477 amount = -aft_shield;
6486 [
super takeScrapeDamage:amount from:ent];
6488 while (amount > 0.0)
6491 if (internal_damage)
6493 [
self takeInternalDamage];
6500- (void) takeHeatDamage:(
double) amount
6502 if ([
self status] == STATUS_DEAD || amount < 0)
return;
6505 float fwd_amount = (float)(0.5 * amount);
6506 float aft_amount = (float)(0.5 * amount);
6508 forward_shield -= fwd_amount;
6509 if (forward_shield < 0.0)
6511 fwd_amount = -forward_shield;
6512 forward_shield = 0.0f;
6519 aft_shield -= aft_amount;
6520 if (aft_shield < 0.0)
6522 aft_amount = -aft_shield;
6530 double residual_amount = fwd_amount + aft_amount;
6532 [
super takeHeatDamage:residual_amount];
6546 [result
setSpeed:[
self flightSpeed]];
6564 if ([
UNIVERSE displayGUI]) [
self switchToMainView];
6565 [UNIVERSE setViewDirection:VIEW_FORWARD];
6567 if ([
self status] == STATUS_DEAD)
return nil;
6574 [UNIVERSE setBlockJSPlayerShipProps:YES];
6576 if (escape_pod_rescue_time > 0)
6578 ship_clock_adjust += escape_pod_rescue_time;
6579 escape_pod_rescue_time = 0;
6584 ship_clock_adjust += 43200 + 5400 * (
ranrot_rand() & 127);
6587 flightSpeed = fmin(flightSpeed, maxFlightSpeed);
6589 doppelganger = [
self createDoppelganger];
6592 [doppelganger
setVelocity:vector_multiply_scalar(v_forward, flightSpeed)];
6595 [doppelganger
setRoll:0.2 * (randf() - 0.5)];
6598 [UNIVERSE addEntity:doppelganger];
6601 [
self setFoundTarget:doppelganger];
6602 [
self setStatus:STATUS_ESCAPE_SEQUENCE];
6606 float sheight = (float)(boundingBox.max.y - boundingBox.min.y);
6607 position = HPvector_subtract(position, vectorToHPVector(vector_multiply_scalar(v_up, sheight)));
6608 float sdepth = (float)(boundingBox.max.z - boundingBox.min.z);
6609 position = HPvector_subtract(position, vectorToHPVector(vector_multiply_scalar(v_forward, sdepth/2.0)));
6612 escapePod = [UNIVERSE newShipWithName:@"escape-capsule"];
6613 if (escapePod !=
nil)
6616 [
self setMesh:[escapePod
mesh]];
6635 Vector launchVector = vector_add([doppelganger velocity],
6636 vector_add(vector_multiply_scalar(v_up, 15.0f),
6637 vector_multiply_scalar(v_forward, -90.0f)));
6638 [
self setVelocity:launchVector];
6643 [
self removeEquipmentItem:[
self equipmentItemProviding:@"EQ_ESCAPE_POD"]];
6647 target_system_id = system_id;
6648 info_system_id = system_id;
6649 [
self setDockTarget:[UNIVERSE station]];
6651 [
self doScriptEvent:OOJSID("shipLaunchedEscapePod") withArgument:escapePod];
6654 [
self setBounty:0 withReason:kOOLegalStatusReasonEscapePod];
6658 if (ship_kills >= 6400)
6660 [
self clearRolesFromPlayer:0.1];
6662 else if (ship_kills >= 2560)
6664 [
self clearRolesFromPlayer:0.25];
6668 [
self clearRolesFromPlayer:0.5];
6672 if (trumbleCount != 0) trumbleCount = 1;
6675 [cargo removeAllObjects];
6678 [UNIVERSE addMessage:DESC(@"escape-sequence") forCount:4.5];
6679 [
self resetShotTime];
6683 forward_shot_time = 0.0;
6684 aft_shot_time = 0.0;
6685 port_shot_time = 0.0;
6686 starboard_shot_time = 0.0;
6688 [escapePod release];
6690 return doppelganger;
6696 if (flightSpeed > 4.0 * maxFlightSpeed)
6698 [UNIVERSE addMessage:OOExpandKey(@"hold-locked") forCount:3.0];
6705 NSString *commodity = [UNIVERSE displayNameForCommodity:result];
6706 [UNIVERSE addMessage:OOExpandKey(@"commodity-ejected", commodity) forCount:3.0 forceDisplay:YES];
6707 [
self playCargoJettisioned];
6715 NSInteger i, n_cargo = [cargo count];
6716 if (n_cargo == 0)
return;
6721 NSInteger rotates = 0;
6725 [cargo removeObjectAtIndex:0];
6726 [cargo addObject:pod];
6728 pod = (
ShipEntity*)[[cargo objectAtIndex:0] retain];
6731 }
while ([contents isEqualToString:current_contents]&&(rotates < n_cargo));
6734 NSString *commodity = [UNIVERSE displayNameForCommodity:contents];
6735 [UNIVERSE addMessage:OOExpandKey(@"ready-to-eject-commodity", commodity) forCount:3.0];
6739 for (i = 1; i < (n_cargo - rotates); i++)
6741 pod = [cargo objectAtIndex:i];
6742 if ([[pod commodityType] isEqualToString:current_contents])
6745 [cargo removeObjectAtIndex:i--];
6746 [cargo addObject:pod];
6756 [
self setBounty:amount withReason:kOOLegalStatusReasonUnknown];
6763 [
self setBounty:amount withReasonAsString:nReason];
6767- (void) setBounty:(
OOCreditsQuantity)amount withReasonAsString:(NSString *)reason
6771 jsval amountVal = JSVAL_VOID;
6772 int amountVal2 = (
int)amount-(
int)legalStatus;
6773 JS_NewNumberValue(context, amountVal2, &amountVal);
6775 legalStatus = (
int)amount;
6779 ShipScriptEvent(context,
self,
"shipBountyChanged", amountVal, reasonVal);
6797- (void) markAsOffender:(
int)offence_value
6799 [
self markAsOffender:offence_value withReason:kOOLegalStatusReasonUnknown];
6805 if (![
self isCloaked])
6809 jsval amountVal = JSVAL_VOID;
6810 int amountVal2 = (legalStatus | offence_value) - legalStatus;
6811 JS_NewNumberValue(context, amountVal2, &amountVal);
6813 legalStatus |= offence_value;
6817 ShipScriptEvent(context,
self,
"shipBountyChanged", amountVal, reasonVal);
6827 if ([
self status] == STATUS_DEAD)
return;
6829 if (other ==
nil || [other isSubEntity])
return;
6839 if ([
self isCloaked])
6849 if ([other isPolice])
6851 [
self markAsOffender:64 withReason:kOOLegalStatusReasonAttackedPolice];
6854 BOOL killIsCargo = ((killClass == CLASS_CARGO) && ([other commodityAmount] > 0) && ![other
isHulk]);
6855 if ((killIsCargo) || (killClass == CLASS_BUOY) || (killClass == CLASS_ROCK))
6858 if (![other hasRole:
@"tharglet"])
6869 NSString *bonusMessage =
OOExpandKey(
@"bounty-awarded", score, credits);
6870 [UNIVERSE addDelayedMessage:bonusMessage forCount:6 afterDelay:0.15];
6876 if ((ship_kills % 256) == 0)
6879 [UNIVERSE addDelayedMessage:DESC(@"right-on-commander") forCount:4 afterDelay:0.2];
6885- (BOOL) takeInternalDamage
6887 unsigned n_cargo = [
self maxAvailableCargoSpace];
6888 unsigned n_mass = [
self mass] / 10000;
6889 unsigned n_considered = (n_cargo + n_mass) * ship_trade_in_factor / 100;
6890 unsigned damage_to = n_considered ? (
ranrot_rand() % n_considered) : 0;
6893 if (damage_to < [cargo
count])
6896 NSString* cargo_desc = [UNIVERSE displayNameForCommodity:[pod
commodityType]];
6899 [UNIVERSE clearPreviousMessage];
6900 [UNIVERSE addMessage:[NSString stringWithFormat:DESC(@"@-destroyed"), cargo_desc] forCount:4.5];
6901 [cargo removeObject:pod];
6906 damage_to = n_considered - (damage_to + 1);
6909 NSEnumerator *eqEnum = [
self equipmentEnumerator];
6911 NSString *system_key;
6912 unsigned damageableCounter = 0;
6913 GLfloat damageableOdds = 0.0;
6914 while ((system_key = [eqEnum nextObject]) !=
nil)
6917 if ([eqType canBeDamaged])
6919 damageableCounter++;
6920 damageableOdds += [eqType damageProbability];
6924 if (damage_to < damageableCounter)
6926 GLfloat target =
randf() * damageableOdds;
6927 GLfloat accumulator = 0.0;
6928 eqEnum = [
self equipmentEnumerator];
6929 while ((system_key = [eqEnum nextObject]) !=
nil)
6932 accumulator += [eqType damageProbability];
6933 if (accumulator > target)
6935 [system_key retain];
6939 if (system_key ==
nil)
6941 [system_key release];
6945 NSString *system_name = [eqType
name];
6946 if (![eqType canBeDamaged] || system_name ==
nil)
6948 [system_key release];
6953 [
self setScriptTarget:self];
6954 [UNIVERSE clearPreviousMessage];
6955 [
self removeEquipmentItem:system_key];
6957 NSString *damagedKey = [NSString stringWithFormat:@"%@_DAMAGED", system_key];
6958 [
self addEquipmentItem:damagedKey withValidation: NO inContext:@"damage"];
6959 [
self doScriptEvent:OOJSID("equipmentDamaged") withArgument:system_key];
6961 if (![
self hasEquipmentItem:system_name] && [
self hasEquipmentItem:damagedKey])
6969 [UNIVERSE addMessage:[NSString stringWithFormat:DESC(@"@-damaged"), system_name] forCount:4.5];
6975 [system_key release];
6979 if (((damage_to & 7) == 7)&&(ship_trade_in_factor > 75))
6981 ship_trade_in_factor--;
6990 if ([
self isDocked])
return;
6994 if (![[
UNIVERSE gameController] playerFileToLoad])
6996 [[UNIVERSE gameController] setPlayerFileToLoad: save_path];
7000 afterburner_engaged = NO;
7001 [
self disengageAutopilot];
7003 [UNIVERSE setDisplayText:NO];
7004 [UNIVERSE setViewDirection:VIEW_AFT];
7007 [
self noteKilledBy:whom damageType:type];
7009 [
self becomeLargeExplosion:4.0];
7010 [
self moveForward:100.0];
7012 flightSpeed = 160.0f;
7017 [[UNIVERSE messageGUI] clear];
7018 [
self suppressTargetLost];
7019 [
self playGameOver];
7020 [UNIVERSE setBlockJSPlayerShipProps:YES];
7021 [
self removeAllEquipment];
7022 [
self loseTargetStatus];
7023 [
self showGameOver];
7027- (void) loseTargetStatus
7031 int ent_count =
UNIVERSE->n_entities;
7033 Entity* my_entities[ent_count];
7035 for (i = 0; i < ent_count; i++)
7036 my_entities[i] = [uni_entities[i] retain];
7037 for (i = 0; i < ent_count ; i++)
7039 Entity* thing = my_entities[i];
7042 ShipEntity* ship = (ShipEntity *)thing;
7043 if (self == [ship primaryTarget])
7045 [ship noteLostTarget];
7049 for (i = 0; i < ent_count; i++)
7051 [my_entities[i] release];
7056- (BOOL) endScenario:(NSString *)key
7058 if (scenarioKey !=
nil && [key isEqualToString:scenarioKey])
7060 [
self setStatus:STATUS_RESTART_GAME];
7069 NSParameterAssert(station !=
nil);
7070 if ([
self status] == STATUS_DEAD)
return;
7072 [
self setStatus:STATUS_DOCKING];
7073 [
self setDockedStation:station];
7074 [
self doScriptEvent:OOJSID("shipWillDockWithStation") withArgument:station];
7076 if (![hud nonlinearScanner])
7078 [hud setScannerZoom: 1.0];
7081 afterburner_engaged = NO;
7082 autopilot_engaged = NO;
7083 [
self resetAutopilotAI];
7085 cloaking_device_active = NO;
7086 hyperspeed_engaged = NO;
7087 hyperspeed_locked = NO;
7088 [
self safeAllMissiles];
7090 [
self clearTargetMemory];
7092 scanner_zoom_rate = 0.0f;
7093 [UNIVERSE setDisplayText:NO];
7094 [[UNIVERSE gameController] setMouseInteractionModeForFlight];
7095 if ([
self status] == STATUS_LAUNCHING)
return;
7097 [
self setOrientation: kIdentityQuaternion];
7098 [UNIVERSE setUpBreakPattern:[
self breakPatternPosition] orientation:orientation forDocking:YES];
7099 [
self playDockWithStation];
7102 [[UNIVERSE gameView] clearKeys];
7109 if (dockedStation ==
nil)
7111 [
self setStatus:STATUS_IN_FLIGHT];
7115 [
self setStatus:STATUS_DOCKED];
7116 [UNIVERSE enterGUIViewModeWithMouseInteraction:NO];
7118 [
self loseTargetStatus];
7120 [
self setPosition:[dockedStation
position]];
7121 [
self setOrientation:kIdentityQuaternion];
7128 hyperspeed_engaged = NO;
7129 hyperspeed_locked = NO;
7131 forward_shield = [
self maxForwardShieldLevel];
7132 aft_shield = [
self maxAftShieldLevel];
7135 ship_temperature = 60.0f;
7137 [
self setAlertFlag:ALERT_FLAG_DOCKED to:YES];
7139 if ([dockedStation localMarket] ==
nil)
7144 NSString *escapepodReport = [
self processEscapePods];
7145 [
self addMessageToReport:escapepodReport];
7147 [
self unloadCargoPods];
7151 if ([dockedStation marketMonitored])
7154 [
self markAsOffender:[dockedStation
legalStatusOfManifest:shipCommodityData
export:NO] withReason:kOOLegalStatusReasonIllegalImports];
7155 if ([
self bounty] > oldbounty)
7157 [
self addRoleToPlayer:@"trader-smuggler"];
7162 NSString *passengerAndCargoReport = [
self checkPassengerContracts];
7163 [
self addMessageToReport:passengerAndCargoReport];
7165 [UNIVERSE setDisplayText:YES];
7172 if ([dockedStation requiresDockingClearance] &&
7173 ![
self clearedToDock] && ![[
UNIVERSE sun] willGoNova])
7175 [
self penaltyForUnauthorizedDocking];
7179 if (dockedStation == [
UNIVERSE station])
7183 if (being_fined && ![[
UNIVERSE sun] willGoNova] && ![dockedStation suppressArrivalReports]) [
self getFined];
7187 if (gui_screen != GUI_SCREEN_MISSION) [
self checkScript];
7190 [
self doScriptEvent:OOJSID("shipDockedWithStation") withArgument:dockedStation];
7192 if ([
self status] == STATUS_LAUNCHING)
return;
7195 if (gui_screen != GUI_SCREEN_MISSION)
7197 [
self setGuiToStatusScreen];
7203 [
self doWorldEventUntilMissionScreen:OOJSID("missionScreenOpportunity")];
7209 if (station ==
nil)
return;
7210 NSParameterAssert(station == [
self dockedStation]);
7213 [[UNIVERSE gameView] allowStringInput: NO];
7215 if (gui_screen == GUI_SCREEN_MISSION)
7217 [[UNIVERSE gui] clearBackground];
7218 if (_missionWithCallback)
7220 [
self doMissionCallback];
7223 [
self doWorldEventUntilMissionScreen:OOJSID("missionScreenEnded")];
7226 if ([station marketMonitored])
7231 if ([
self bounty] > oldbounty)
7233 [
self addRoleToPlayer:@"trader-smuggler"];
7237 gui_screen = GUI_SCREEN_MAIN;
7238 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen];
7240 if (![hud nonlinearScanner])
7242 [hud setScannerZoom: 1.0];
7244 [
self loadCargoPods];
7254 [
self clearAlertFlags];
7255 [
self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
7257 scanner_zoom_rate = 0.0f;
7259 [
self currentWeaponStats];
7261 forward_weapon_temp = 0.0f;
7262 aft_weapon_temp = 0.0f;
7263 port_weapon_temp = 0.0f;
7264 starboard_weapon_temp = 0.0f;
7266 forward_shield = [
self maxForwardShieldLevel];
7267 aft_shield = [
self maxAftShieldLevel];
7269 [
self clearTargetMemory];
7270 [
self setShowDemoShips:NO];
7271 [UNIVERSE setDisplayText:NO];
7272 [[UNIVERSE gameController] setMouseInteractionModeForFlight];
7274 [[UNIVERSE gameView] clearKeys];
7276 if ([
self isMouseControlOn])
7278 [[UNIVERSE gameView] resetMouse];
7283 [UNIVERSE forceWitchspaceEntries];
7284 ship_clock_adjust += 600.0;
7289 launchRoll = -flightRoll;
7291 [UNIVERSE setUpBreakPattern:[
self breakPatternPosition] orientation:orientation forDocking:YES];
7293 [
self setDockedStation:nil];
7295 suppressAegisMessages = YES;
7296 [
self checkForAegis];
7297 suppressAegisMessages = NO;
7300 [UNIVERSE removeDemoShips];
7305 [
self playLaunchFromStation];
7313 if (autopilot_engaged) [
self disengageAutopilot];
7315 if (![hud nonlinearScanner])
7317 [hud setScannerZoom: 1.0];
7319 [
self safeAllMissiles];
7321 OOViewID previousViewDirection = [UNIVERSE viewDirection];
7322 [UNIVERSE setViewDirection:VIEW_FORWARD];
7323 [
self noteSwitchToView:VIEW_FORWARD fromView:previousViewDirection];
7326 [
self currentWeaponStats];
7328 [
self transitionToAegisNone];
7329 suppressAegisMessages=YES;
7330 hyperspeed_engaged = NO;
7332 if ([
self primaryTarget] !=
nil)
7334 [
self noteLostTarget];
7338 scanner_zoom_rate = 0.0f;
7339 [UNIVERSE setDisplayText:NO];
7341 if ( ![
self wormhole] && !galactic_witchjump)
7345 [UNIVERSE allShipsDoScriptEvent:OOJSID("playerWillEnterWitchspace") andReactToAIMessage:@"PLAYER WITCHSPACE"];
7356 [UNIVERSE setSystemTo:system_id];
7357 galaxy_coordinates = [[UNIVERSE systemManager] getCoordinatesForSystem:system_id inGalaxy:galaxy_number];
7359 [UNIVERSE setUpUniverseFromWitchspace];
7360 [[UNIVERSE planet] update: 2.34375 * market_rnd];
7361 [[UNIVERSE station] update: 2.34375 * market_rnd];
7363 chart_centre_coordinates = galaxy_coordinates;
7364 target_chart_centre = chart_centre_coordinates;
7368- (BOOL) witchJumpChecklist:(BOOL)isGalacticJump
7371 if ([
self status] == STATUS_WITCHSPACE_COUNTDOWN)
7375 ShipEntity* blocker = [UNIVERSE entityForUniversalID:[
self checkShipsInVicinityForWitchJumpExit]];
7378 [UNIVERSE clearPreviousMessage];
7379 NSString *blockerName = [blocker
name];
7380 [UNIVERSE addMessage:OOExpandKey(@"witch-blocked", blockerName) forCount:4.5];
7381 [
self playWitchjumpBlocked];
7382 [
self setStatus:STATUS_IN_FLIGHT];
7395 if (![
UNIVERSE inInterstellarSpace] && system_id == target_system_id)
7399 [UNIVERSE clearPreviousMessage];
7400 [UNIVERSE addMessage:OOExpandKey(@"witch-no-target") forCount: 4.5];
7401 if ([
self status] == STATUS_WITCHSPACE_COUNTDOWN)
7403 [
self playWitchjumpInsufficientFuel];
7404 [
self setStatus:STATUS_IN_FLIGHT];
7407 else [
self playHyperspaceNoTarget];
7413 if ([
self hyperspaceJumpDistance] > [
self maxHyperspaceDistance])
7415 [UNIVERSE clearPreviousMessage];
7416 [UNIVERSE addMessage:DESC(@"witch-too-far") forCount: 4.5];
7417 if ([
self status] == STATUS_WITCHSPACE_COUNTDOWN)
7419 [
self playWitchjumpDistanceTooGreat];
7420 [
self setStatus:STATUS_IN_FLIGHT];
7423 else [
self playHyperspaceDistanceTooGreat];
7429 if (![
self hasSufficientFuelForJump])
7431 [UNIVERSE clearPreviousMessage];
7432 [UNIVERSE addMessage:DESC(@"witch-no-fuel") forCount: 4.5];
7433 if ([
self status] == STATUS_WITCHSPACE_COUNTDOWN)
7435 [
self playWitchjumpInsufficientFuel];
7436 [
self setStatus:STATUS_IN_FLIGHT];
7439 else [
self playHyperspaceNoFuel];
7448- (void) setJumpType:(BOOL)isGalacticJump
7452 galactic_witchjump = YES;
7456 galactic_witchjump = NO;
7464 NSPoint targetCoordinates =
PointFromString([[
UNIVERSE systemManager] getProperty:
@"coordinates" forSystem:[
self nextHopTargetSystemID] inGalaxy:galaxy_number]);
7471 return 10.0 *
MAX(0.1, [
self hyperspaceJumpDistance]);
7475- (BOOL) hasSufficientFuelForJump
7477 return fuel >= [
self fuelRequiredForJump];
7483 if ([[
self hud] isCompassActive])
7488 ShipScriptEvent(context,
self,
"compassTargetChanged", JSVAL_VOID, jsmode);
7491 [[
self hud] setCompassActive:NO];
7496- (void) enterGalacticWitchspace
7498 if (![
self witchJumpChecklist:true])
7509 [
self setStatus:STATUS_ENTERING_WITCHSPACE];
7511 [
self setJumpCause:@"galactic jump"];
7512 [
self setPreviousSystemID:[
self currentSystemID]];
7513 ShipScriptEvent(context,
self,
"shipWillEnterWitchspace", STRING_TO_JSVAL(JS_InternString(context, [[
self jumpCause] UTF8String])), INT_TO_JSVAL(destGalaxy));
7516 [
self noteCompassLostTarget];
7520 [UNIVERSE removeAllEntitiesExceptPlayer];
7524 [contracts removeAllObjects];
7527 [parcels removeAllObjects];
7530 if (missionDestinations)
7531 [missionDestinations removeAllObjects];
7537 for (i = 0; i < [passengers count]; i++)
7540 NSMutableDictionary* passenger_info = [NSMutableDictionary dictionaryWithDictionary:[passengers oo_dictionaryAtIndex:i]];
7541 [passenger_info setObject:[NSNumber numberWithDouble:ship_clock] forKey:CONTRACT_KEY_ARRIVAL_TIME];
7542 [passengers replaceObjectAtIndex:i withObject:passenger_info];
7547 if (ship_kills >= 6400)
7549 [
self clearRolesFromPlayer:0.25];
7551 else if (ship_kills >= 2560)
7553 [
self clearRolesFromPlayer:0.5];
7557 [
self clearRolesFromPlayer:0.9];
7559 [roleWeightFlags removeAllObjects];
7560 [roleSystemList removeAllObjects];
7563 [
self removeEquipmentItem:[
self equipmentItemProviding:@"EQ_GAL_DRIVE"]];
7565 galaxy_number = destGalaxy;
7567 [UNIVERSE setGalaxyTo:galaxy_number];
7574 switch (galacticHyperspaceBehaviour)
7576 case GALACTIC_HYPERSPACE_BEHAVIOUR_FIXED_COORDINATES:
7577 system_id = [UNIVERSE findSystemNumberAtCoords:galacticHyperspaceFixedCoords withGalaxy:galaxy_number includingHidden:YES];
7579 case GALACTIC_HYPERSPACE_BEHAVIOUR_ALL_SYSTEMS_REACHABLE:
7580 system_id = [UNIVERSE findSystemNumberAtCoords:galaxy_coordinates withGalaxy:galaxy_number includingHidden:YES];
7582 case GALACTIC_HYPERSPACE_BEHAVIOUR_STANDARD:
7585 system_id = [UNIVERSE findConnectedSystemAtCoords:galaxy_coordinates withGalaxy:galaxy_number];
7588 target_system_id = system_id;
7589 info_system_id = system_id;
7591 [
self setBounty:0 withReason:kOOLegalStatusReasonNewGalaxy];
7592 cursor_coordinates =
PointFromString([[
UNIVERSE systemManager] getProperty:
@"coordinates" forSystem:system_id inGalaxy:galaxy_number]);
7602 if ([
self status] == STATUS_ENTERING_WITCHSPACE
7603 || [
self status] == STATUS_EXITING_WITCHSPACE)
7607 BOOL misjump = [
self scriptedMisjump] || [w_hole
withMisjump] || flightPitch == max_flight_pitch ||
randf() > 0.995;
7608 wormhole = [w_hole retain];
7609 [
self addScannedWormhole:wormhole];
7610 [
self setStatus:STATUS_ENTERING_WITCHSPACE];
7612 [
self setJumpCause:@"wormhole"];
7613 [
self setPreviousSystemID:[
self currentSystemID]];
7614 ShipScriptEvent(context,
self,
"shipWillEnterWitchspace", STRING_TO_JSVAL(JS_InternString(context, [[
self jumpCause] UTF8String])), INT_TO_JSVAL([w_hole destination]));
7616 if ([
self scriptedMisjump])
7620#ifdef OO_DUMP_PLANETINFO
7623 if (misjump && [
self scriptedMisjumpRange] != 0.5)
7627 [
self witchJumpTo:[w_hole
destination] misjump:misjump];
7631- (void) enterWitchspace
7633 if (![
self witchJumpChecklist:false]) return;
7635 OOSystemID jumpTarget = [
self nextHopTargetSystemID];
7638 unsigned malfunc_chance = 253;
7639 if (ship_trade_in_factor < 80)
7641 malfunc_chance -= (1 +
ranrot_rand() % (81-ship_trade_in_factor)) / 2;
7643 else if (ship_trade_in_factor >= 100)
7645 malfunc_chance = 256;
7648#ifdef OO_DUMP_PLANETINFO
7651 BOOL malfunc = ((
ranrot_rand() & 0xff) > malfunc_chance);
7653 BOOL misjump = [
self scriptedMisjump] || (flightPitch == max_flight_pitch) || (malfunc && (
randf() > 0.75));
7655 if (malfunc && !misjump)
7658 if ([
self takeInternalDamage])
7660 [
self playWitchjumpFailure];
7661 [
self setStatus:STATUS_IN_FLIGHT];
7667 [
self setFuelLeak:[NSString stringWithFormat:@"%f", (randf() + randf()) * 5.0]];
7675 fuel -= [
self fuelRequiredForJump];
7678 wormhole = [[
WormholeEntity alloc] initWormholeTo:jumpTarget fromShip:self];
7679 [UNIVERSE addEntity:wormhole];
7680 [
self addScannedWormhole:wormhole];
7682 [
self setStatus:STATUS_ENTERING_WITCHSPACE];
7684 [
self setJumpCause:@"standard jump"];
7685 [
self setPreviousSystemID:[
self currentSystemID]];
7686 ShipScriptEvent(context,
self,
"shipWillEnterWitchspace", STRING_TO_JSVAL(JS_InternString(context, [[
self jumpCause] UTF8String])), INT_TO_JSVAL(jumpTarget));
7689 [
self updateSystemMemory];
7690 NSUInteger legality = [
self legalStatusOfCargoList];
7693 if ([roleWeightFlags objectForKey:
@"bought-legal"])
7695 if (maxSpace != availSpace)
7697 [
self addRoleToPlayer:@"trader"];
7698 if (maxSpace - availSpace > 20 || availSpace == 0)
7702 [
self addRoleToPlayer:@"trader"];
7707 if ([roleWeightFlags objectForKey:
@"bought-illegal"])
7709 if (maxSpace != availSpace && legality > 0)
7711 [
self addRoleToPlayer:@"trader-smuggler"];
7712 if (maxSpace - availSpace > 20 || availSpace == 0)
7714 if (legality >= 20 || legality >= maxSpace)
7716 [
self addRoleToPlayer:@"trader-smuggler"];
7721 [roleWeightFlags removeAllObjects];
7723 [
self noteCompassLostTarget];
7724 if ([
self scriptedMisjump])
7730 [wormhole setMisjumpWithRange:[
self scriptedMisjumpRange]];
7732 [
self witchJumpTo:jumpTarget misjump:misjump];
7736- (void) witchJumpTo:(
OOSystemID)sTo misjump:(BOOL)misjump
7739 if (info_system_id == system_id)
7741 [
self setInfoSystemID: sTo moveChart: YES];
7744 if (2 * market_rnd < ship_trade_in_factor)
7747 [
self adjustTradeInFactorBy:-(1 + (market_rnd & 3))];
7751 NSPoint destCoords =
PointFromString([[
UNIVERSE systemManager] getProperty:
@"coordinates" forSystem:sTo inGalaxy:galaxy_number]);
7756 if (theSun && [theSun goneNova])
7761 [UNIVERSE removeAllEntitiesExceptPlayer];
7764 ship_clock_adjust += distance * distance * 3600.0;
7765 [
self setSystemID:sTo];
7766 [
self setBounty:(legalStatus/2) withReason:kOOLegalStatusReasonNewSystem];
7768 if (market_rnd < 8) [
self erodeReputation];
7774 if (
randf() < 0.1) [
self erodeReputation];
7776 [wormhole setMisjump];
7781 NSPoint dest = [wormhole destinationCoordinates];
7782 galaxy_coordinates.x = dest.x;
7783 galaxy_coordinates.y = dest.y;
7785 ship_clock_adjust += [wormhole travelTime];
7787 [
self playWitchjumpMisjump];
7788 [UNIVERSE setUpUniverseFromMisjump];
7793- (void) leaveWitchspace
7796 HPVector pos = [UNIVERSE getWitchspaceExitPosition];
7798 HPVector whpos, exitpos;
7800 double min_d1 = [UNIVERSE safeWitchspaceExitDistance];
7802 if (abs((
int)d1) < min_d1)
7804 d1 += ((d1 > 0.0)? min_d1: -min_d1);
7807 exitpos = HPvector_add(pos, HPvector_multiply_scalar(v1, d1));
7809 [
self setOrientation:[UNIVERSE getWitchspaceExitRotation]];
7817 if ([[wormhole shipsInTransit]
count] > 0)
7820 double wh_arrival_time = ([PLAYER clockTimeAdjusted] - [wormhole arrivalTime]);
7821 if (wh_arrival_time > 0)
7824 whpos = HPvector_add(exitpos, vectorToHPVector(vector_multiply_scalar([
self forwardVector], 1000.0f)));
7825 [wormhole setContainsPlayer:YES];
7830 whpos = HPvector_add(exitpos, vectorToHPVector(vector_multiply_scalar([
self forwardVector], -500.0f)));
7832 [wormhole setExitSpeed:maxFlightSpeed*WORMHOLE_LEADER_SPEED_FACTOR];
7835 HPVector distance = HPvector_subtract(whpos, pos);
7836 if (HPmagnitude2(distance) < min_d1*min_d1 )
7840 distance = HPvector_multiply_scalar(HPvector_normal(distance), min_d1);
7841 whpos = HPvector_add(whpos, distance);
7842 position = HPvector_add(position, distance);
7844 [wormhole setExitPosition: whpos];
7849 [wormhole setExitSpeed:maxFlightSpeed*WORMHOLE_LEADER_SPEED_FACTOR];
7856 flightSpeed = wormhole ? [wormhole exitSpeed] : fmin(maxFlightSpeed,50.0f);
7865 [
self setStatus:STATUS_EXITING_WITCHSPACE];
7866 gui_screen = GUI_SCREEN_MAIN;
7868 [
self clearTargetMemory];
7869 [
self setShowDemoShips:NO];
7870 [[UNIVERSE gameController] setMouseInteractionModeForFlight];
7871 [UNIVERSE setDisplayText:NO];
7872 [UNIVERSE setWitchspaceBreakPattern:YES];
7873 [
self playExitWitchspace];
7874 if ([
self currentSystemID] >= 0)
7876 if (![roleSystemList containsObject:[NSNumber numberWithInt:[
self currentSystemID]]])
7879 [
self clearRoleFromPlayer:NO];
7883 if (galactic_witchjump)
7885 [
self doScriptEvent:OOJSID("playerEnteredNewGalaxy") withArgument:[NSNumber numberWithUnsignedInt:galaxy_number]];
7888 [
self doScriptEvent:OOJSID("shipWillExitWitchspace") withArgument:[
self jumpCause]];
7889 [UNIVERSE setUpBreakPattern:[
self breakPatternPosition] orientation:orientation forDocking:NO];
7895- (void) setGuiToStatusScreen
7897 NSString *systemName =
nil;
7898 NSString *targetSystemName =
nil;
7899 NSString *text =
nil;
7903 if (oldScreen != GUI_SCREEN_STATUS)
7905 [
self noteGUIWillChangeTo:GUI_SCREEN_STATUS];
7908 gui_screen = GUI_SCREEN_STATUS;
7909 BOOL guiChanged = (oldScreen != gui_screen);
7911 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:NO];
7915 systemName = [UNIVERSE inInterstellarSpace] ?
DESC(
@"interstellar-space") : [
UNIVERSE getSystemName:system_id];
7916 if ([
self isDocked] && [
self dockedStation] != [
UNIVERSE station])
7918 systemName = [NSString stringWithFormat:@"%@ : %@", systemName, [[
self dockedStation] displayName]];
7921 targetSystemName = [UNIVERSE getSystemName:target_system_id];
7922 NSDictionary *systemInfo = [[UNIVERSE systemManager] getPropertiesForSystem:target_system_id inGalaxy:galaxy_number];
7923 NSInteger concealment = [systemInfo oo_intForKey:@"concealment" defaultValue:OO_SYSTEMCONCEALMENT_NONE];
7924 if (concealment >= 200) targetSystemName =
DESC(
@"status-unknown-system");
7926 OOSystemID nextHop = [
self nextHopTargetSystemID];
7927 if (nextHop != target_system_id) {
7928 NSString *nextHopSystemName = [UNIVERSE getSystemName:nextHop];
7929 systemInfo = [[UNIVERSE systemManager] getPropertiesForSystem:nextHop inGalaxy:galaxy_number];
7930 concealment = [systemInfo oo_intForKey:@"concealment" defaultValue:OO_SYSTEMCONCEALMENT_NONE];
7931 if (concealment >= 200) nextHopSystemName =
DESC(
@"status-unknown-system");
7932 targetSystemName =
OOExpandKey(
@"status-hyperspace-system-multi", targetSystemName, nextHopSystemName);
7937 NSString *shipName = [
self displayName];
7938 NSString *legal_desc =
nil, *rating_desc =
nil,
7939 *alert_desc =
nil, *fuel_desc =
nil,
7940 *credits_desc =
nil;
7950 NSString *lightYearsDesc =
DESC(
@"status-light-years-desc");
7955 fuel_desc = [NSString stringWithFormat:@"%.1f %@", fuel/10.0, lightYearsDesc];
7959 text =
DESC(
@"status-commander-@");
7960 [gui
setTitle:[NSString stringWithFormat:text, [
self commanderName]]];
7964 [gui
setArray:[NSArray arrayWithObjects:DESC(@"status-present-system"), systemName, nil]
forRow:1];
7965 if ([
self hasHyperspaceMotor]) [gui
setArray:[NSArray arrayWithObjects:DESC(@"status-hyperspace-system"), targetSystemName, nil]
forRow:2];
7966 [gui
setArray:[NSArray arrayWithObjects:DESC(@"status-condition"), alert_desc, nil]
forRow:3];
7967 [gui
setArray:[NSArray arrayWithObjects:DESC(@"status-fuel"), fuel_desc, nil]
forRow:4];
7968 [gui
setArray:[NSArray arrayWithObjects:DESC(@"status-cash"), credits_desc, nil]
forRow:5];
7969 [gui
setArray:[NSArray arrayWithObjects:DESC(@"status-legal-status"), legal_desc, nil]
forRow:6];
7970 [gui
setArray:[NSArray arrayWithObjects:DESC(@"status-rating"), rating_desc, nil]
forRow:7];
7974 for (i = 1 ; i <= 7 ; ++i)
7990 [lastTextKey release];
7994 [[UNIVERSE gameView] clearMouse];
7997 if (
EXPECT_NOT([[NSUserDefaults standardUserDefaults] boolForKey:
@"show-ship-model-in-status-screen"]))
7999 [UNIVERSE removeDemoShips];
8000 [
self showShipModelWithKey:[
self shipDataKey] shipData:nil personality:[
self entityPersonalityInt]
8001 factorX:2.5 factorY:1.7 factorZ:8.0 inContext:@"GUI_SCREEN_STATUS"];
8002 [
self setShowDemoShips:YES];
8006 [
self setShowDemoShips:NO];
8009 [UNIVERSE enterGUIViewModeWithMouseInteraction:NO];
8013 NSDictionary *fgDescriptor =
nil, *bgDescriptor =
nil;
8014 if ([
self status] == STATUS_DOCKED)
8016 fgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"docked_overlay"];
8017 bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"status_docked"];
8021 fgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"overlay"];
8022 if (alertCondition ==
ALERT_CONDITION_RED) bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"status_red_alert"];
8023 else bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"status_in_flight"];
8028 if (bgDescriptor ==
nil) bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"status"];
8032 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen];
8037- (NSArray *) equipmentList
8040 NSMutableArray *quip1 = [NSMutableArray array];
8041 NSMutableArray *quip2 = [NSMutableArray array];
8042 NSEnumerator *eqTypeEnum =
nil;
8044 NSString *desc =
nil;
8045 NSString *alldesc =
nil;
8047 BOOL prioritiseDamaged = [[gui
userSettings] oo_boolForKey:kGuiStatusPrioritiseDamaged defaultValue:YES];
8049 for (eqTypeEnum = [
OOEquipmentType reverseEquipmentEnumerator]; (eqType = [eqTypeEnum nextObject]); )
8051 if ([eqType isVisible])
8053 if ([eqType canCarryMultiple] && ![eqType isMissileOrMine])
8055 NSString *damagedIdentifier = [[eqType
identifier] stringByAppendingString:@"_DAMAGED"];
8056 NSUInteger
count = 0, okcount = 0;
8057 okcount = [
self countEquipmentItem:[eqType
identifier]];
8058 count = okcount + [
self countEquipmentItem:damagedIdentifier];
8064 else if (
count == okcount)
8069 [quip2 addObject:[NSArray arrayWithObjects:[eqType
name], [NSNumber numberWithBool:YES], [eqType
displayColor], nil]];
8074 NSString *equipmentName = [eqType
name];
8076 [quip2 addObject:[NSArray arrayWithObjects:alldesc, [NSNumber numberWithBool:YES], [eqType
displayColor], nil]];
8080 else if (
count == 1 && okcount == 0)
8082 desc = [NSString stringWithFormat:DESC(@"equipment-@-not-available"), [eqType
name]];
8083 if (prioritiseDamaged)
8085 [quip1 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:NO], [eqType
displayColor], nil]];
8089 [quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:NO], [eqType
displayColor], nil]];
8095 NSString *equipmentName = [eqType
name];
8096 alldesc =
OOExpandKey(
@"equipment-plural-some-na", okcount,
count, equipmentName);
8097 if (prioritiseDamaged)
8099 [quip1 addObject:[NSArray arrayWithObjects:alldesc, [NSNumber numberWithBool:NO], [eqType
displayColor], nil]];
8103 [quip2 addObject:[NSArray arrayWithObjects:alldesc, [NSNumber numberWithBool:NO], [eqType
displayColor], nil]];
8107 else if ([
self hasEquipmentItem:[eqType identifier]])
8109 [quip2 addObject:[NSArray arrayWithObjects:[eqType
name], [NSNumber numberWithBool:YES], [eqType
displayColor], nil]];
8114 if ([
self hasEquipmentItem:[[eqType identifier] stringByAppendingString:
@"_DAMAGED"]])
8116 desc = [NSString stringWithFormat:DESC(@"equipment-@-not-available"), [eqType
name]];
8118 if (prioritiseDamaged)
8120 [quip1 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:NO], [eqType
displayColor], nil]];
8125 [quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:NO], [eqType
displayColor], nil]];
8132 if (max_passengers > 0)
8134 desc = [NSString stringWithFormat:DESC_PLURAL(@"equipment-pass-berth-@", max_passengers), max_passengers];
8140 desc = [NSString stringWithFormat:DESC(@"equipment-fwd-weapon-@"),[forward_weapon_type name]];
8141 [quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:YES], [forward_weapon_type displayColor], nil]];
8145 desc = [NSString stringWithFormat:DESC(@"equipment-aft-weapon-@"),[aft_weapon_type name]];
8146 [quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:YES], [aft_weapon_type displayColor], nil]];
8150 desc = [NSString stringWithFormat:DESC(@"equipment-port-weapon-@"),[port_weapon_type name]];
8151 [quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:YES], [port_weapon_type displayColor], nil]];
8155 desc = [NSString stringWithFormat:DESC(@"equipment-stb-weapon-@"),[starboard_weapon_type name]];
8156 [quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:YES], [starboard_weapon_type displayColor], nil]];
8160 [quip1 addObjectsFromArray:quip2];
8165- (NSUInteger) primedEquipmentCount
8167 return [eqScripts count];
8171- (NSString *) primedEquipmentName:(NSInteger)offset
8173 NSUInteger c = [
self primedEquipmentCount];
8174 NSUInteger idx = (primedEquipment+(c+1)+
offset)%(c+1);
8177 return DESC(
@"equipment-primed-none-hud-label");
8186- (NSString *) currentPrimedEquipment
8188 NSString *result =
@"";
8189 NSUInteger c = [eqScripts count];
8190 if (primedEquipment != c)
8192 result = [[eqScripts oo_arrayAtIndex:primedEquipment] oo_stringAtIndex:0];
8198- (BOOL) setPrimedEquipment:(NSString *)eqKey showMessage:(BOOL)showMsg
8200 NSUInteger c = [eqScripts count];
8201 NSUInteger current = primedEquipment;
8202 primedEquipment = [
self eqScriptIndexForKey:eqKey];
8203 BOOL unprimeEq = [eqKey isEqualToString:@""];
8206 if (primedEquipment == c && !unprimeEq)
8208 primedEquipment = current;
8213 if (primedEquipment != current && showMsg == YES)
8216 [UNIVERSE addMessage:unprimeEq ? OOExpandKey(@"equipment-primed-none") : OOExpandKey(@"equipment-primed", equipmentName) forCount:2.0];
8226 if(index < [eqScripts
count])
8228 OOJSScript *eqScript = [[eqScripts oo_arrayAtIndex:index] objectAtIndex:1];
8247- (NSString *) fastEquipmentA
8249 return _fastEquipmentA;
8253- (NSString *) fastEquipmentB
8255 return _fastEquipmentB;
8259- (void) setFastEquipmentA:(NSString *)eqKey
8261 [_fastEquipmentA release];
8262 _fastEquipmentA = [eqKey copy];
8266- (void) setFastEquipmentB:(NSString *)eqKey
8268 [_fastEquipmentB release];
8269 _fastEquipmentB = [eqKey copy];
8280 weaponType = forward_weapon_type;
8284 weaponType = aft_weapon_type;
8288 weaponType = port_weapon_type;
8292 weaponType = starboard_weapon_type;
8303- (NSArray *) missilesList
8305 [
self tidyMissilePylons];
8306 return [
super missilesList];
8310- (NSArray *) cargoList
8312 NSMutableArray *manifest = [NSMutableArray array];
8313 NSArray *list = [
self cargoListForScripting];
8314 NSEnumerator *cargoEnum =
nil;
8315 NSDictionary *commodity;
8317 if (specialCargo) [manifest addObject:specialCargo];
8319 for (cargoEnum = [list objectEnumerator]; (commodity = [cargoEnum nextObject]); )
8321 NSInteger quantity = [commodity oo_integerForKey:@"quantity"];
8322 NSString *units = [commodity oo_stringForKey:@"unit"];
8323 NSString *commodityName = [commodity oo_stringForKey:@"displayName"];
8324 NSInteger containers = [commodity oo_intForKey:@"containers"];
8325 BOOL extended = ![units isEqualToString:DESC(@"cargo-tons-symbol")] && containers > 0;
8328 [manifest addObject:OOExpandKey(@"manifest-cargo-quantity-extended", quantity, units, commodityName, containers)];
8330 [manifest addObject:OOExpandKey(@"manifest-cargo-quantity", quantity, units, commodityName)];
8338- (NSArray *) cargoListForScripting
8340 NSMutableArray *list = [NSMutableArray array];
8342 NSUInteger i, j, commodityCount = [shipCommodityData count];
8345 NSArray *goods = [shipCommodityData goods];
8348 for (i = 0; i < commodityCount; i++)
8350 quantityInHold[i] = [shipCommodityData quantityForGood:[goods oo_stringAtIndex:i]];
8351 containersInHold[i] = 0;
8353 for (i = 0; i < [cargo count]; i++)
8355 ShipEntity *container = [cargo objectAtIndex:i];
8357 quantityInHold[j] += [container commodityAmount];
8358 ++containersInHold[j];
8361 for (i = 0; i < commodityCount; i++)
8363 if (quantityInHold[i] > 0)
8365 NSMutableDictionary *commodity = [NSMutableDictionary dictionaryWithCapacity:4];
8366 NSString *symName = [goods oo_stringAtIndex:i];
8368 [commodity setObject:symName forKey:@"commodity"];
8369 [commodity setObject:[NSNumber numberWithUnsignedInt:quantityInHold[i]] forKey:@"quantity"];
8370 [commodity setObject:[NSNumber numberWithUnsignedInt:containersInHold[i]] forKey:@"containers"];
8371 [commodity setObject:[shipCommodityData nameForGood:symName] forKey:@"displayName"];
8372 [commodity setObject:DisplayStringForMassUnitForCommodity(symName) forKey:@"unit"];
8373 [list addObject:commodity];
8377 return [[list copy] autorelease];
8382- (unsigned) legalStatusOfCargoList
8384 NSString *good =
nil;
8386 unsigned penalty = 0;
8388 foreach (good, [shipCommodityData goods])
8390 amount = [shipCommodityData quantityForGood:good];
8391 penalty += [shipCommodityData exportLegalityForGood:good] * amount;
8397- (NSArray*) contractsListForScriptingFromArray:(NSArray *) contracts_array forCargo:(BOOL)forCargo
8399 NSMutableArray *result = [NSMutableArray array];
8402 for (i = 0; i < [contracts_array count]; i++)
8404 NSMutableDictionary *contract = [NSMutableDictionary dictionaryWithCapacity:10];
8405 NSDictionary *dict = [contracts_array oo_dictionaryAtIndex:i];
8409 [contract setObject:[dict oo_stringForKey:CARGO_KEY_TYPE] forKey:@"commodity"];
8410 [contract setObject:[NSNumber numberWithUnsignedInt:[dict oo_intForKey:CARGO_KEY_AMOUNT]] forKey:@"quantity"];
8411 [contract setObject:[dict oo_stringForKey:CARGO_KEY_DESCRIPTION] forKey:@"description"];
8415 [contract setObject:[dict oo_stringForKey:PASSENGER_KEY_NAME] forKey:PASSENGER_KEY_NAME];
8416 [contract setObject:[NSNumber numberWithUnsignedInt:[dict oo_unsignedIntForKey:CONTRACT_KEY_RISK]] forKey:CONTRACT_KEY_RISK];
8419 OOSystemID planet = [dict oo_intForKey:CONTRACT_KEY_DESTINATION];
8420 NSString *planetName = [UNIVERSE getSystemName:planet];
8421 [contract setObject:[NSNumber numberWithUnsignedInt:planet] forKey:CONTRACT_KEY_DESTINATION];
8422 [contract setObject:planetName forKey:@"destinationName"];
8423 planet = [dict oo_intForKey:CONTRACT_KEY_START];
8424 planetName = [UNIVERSE getSystemName: planet];
8425 [contract setObject:[NSNumber numberWithUnsignedInt:planet] forKey:CONTRACT_KEY_START];
8426 [contract setObject:planetName forKey:@"startName"];
8428 int dest_eta = [dict oo_doubleForKey:CONTRACT_KEY_ARRIVAL_TIME] - ship_clock;
8429 [contract setObject:[NSNumber numberWithInt:dest_eta] forKey:@"eta"];
8430 [contract setObject:[UNIVERSE shortTimeDescription:dest_eta] forKey:@"etaDescription"];
8431 [contract setObject:[NSNumber numberWithInt:[dict oo_intForKey:CONTRACT_KEY_PREMIUM]] forKey:CONTRACT_KEY_PREMIUM];
8432 [contract setObject:[NSNumber numberWithInt:[dict oo_intForKey:CONTRACT_KEY_FEE]] forKey:CONTRACT_KEY_FEE];
8433 [result addObject:contract];
8436 return [[result copy] autorelease];
8440- (NSArray *) passengerListForScripting
8442 return [
self contractsListForScriptingFromArray:passengers forCargo:NO];
8446- (NSArray *) parcelListForScripting
8448 return [
self contractsListForScriptingFromArray:parcels forCargo:NO];
8452- (NSArray *) contractListForScripting
8454 return [
self contractsListForScriptingFromArray:contracts forCargo:YES];
8457- (void) setGuiToSystemDataScreen
8459 [
self setGuiToSystemDataScreenRefreshBackground: NO];
8462- (void) setGuiToSystemDataScreenRefreshBackground: (BOOL) refreshBackground
8464 NSDictionary *infoSystemData;
8465 NSString *infoSystemName;
8467 infoSystemData = [[UNIVERSE generateSystemData:info_system_id] retain];
8468 NSInteger concealment = [infoSystemData oo_intForKey:@"concealment" defaultValue:OO_SYSTEMCONCEALMENT_NONE];
8469 infoSystemName = [infoSystemData oo_stringForKey:KEY_NAME];
8471 BOOL sunGoneNova = ([infoSystemData oo_boolForKey:@"sun_gone_nova"]);
8475 gui_screen = GUI_SCREEN_SYSTEM_DATA;
8476 BOOL guiChanged = (oldScreen != gui_screen);
8478 Random_Seed infoSystemRandomSeed = [[UNIVERSE systemManager] getRandomSeedForSystem:info_system_id
8479 inGalaxy:[
self galaxyNumber]];
8481 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:NO];
8492 NSUInteger techLevel = [infoSystemData oo_intForKey:KEY_TECHLEVEL] + 1;
8493 int population = [infoSystemData oo_intForKey:KEY_POPULATION];
8494 int productivity = [infoSystemData oo_intForKey:KEY_PRODUCTIVITY];
8495 int radius = [infoSystemData oo_intForKey:KEY_RADIUS];
8497 NSString *government_desc = [infoSystemData oo_stringForKey:KEY_GOVERNMENT_DESC
8498 defaultValue:OODisplayStringFromGovernmentID([infoSystemData oo_intForKey:KEY_GOVERNMENT])];
8499 NSString *economy_desc = [infoSystemData oo_stringForKey:KEY_ECONOMY_DESC
8500 defaultValue:OODisplayStringFromEconomyID([infoSystemData oo_intForKey:KEY_ECONOMY])];
8501 NSString *inhabitants = [infoSystemData oo_stringForKey:KEY_INHABITANTS];
8502 NSString *system_desc = [infoSystemData oo_stringForKey:KEY_DESCRIPTION];
8504 NSString *populationDesc = [infoSystemData oo_stringForKey:KEY_POPULATION_DESC
8505 defaultValue:OOExpandKeyWithSeed(kNilRandomSeed, @"sysdata-pop-value", population)];
8518 NSString *system = infoSystemName;
8519 system_desc =
OOExpandKeyWithSeed(infoSystemRandomSeed,
@"nova-system-description", system);
8521 populationDesc =
OOExpandKeyWithSeed(infoSystemRandomSeed,
@"sysdata-pop-value", population);
8526 [UNIVERSE removeDemoShips];
8530 NSString *system = infoSystemName;
8531 [gui
setTitle:OOExpandKeyWithSeed(infoSystemRandomSeed, @"sysdata-data-on-system", system)];
8535 [gui
setTitle:OOExpandKey(@"sysdata-data-on-system-no-name")];
8542 for (i-- ; i > 14 ; --i)
8549 NSPoint infoSystemCoordinates = [[UNIVERSE systemManager] getCoordinatesForSystem: info_system_id inGalaxy: galaxy_number];
8551 if(distance == 0.0 && info_system_id != system_id)
8555 NSString *distanceInfo = [NSString stringWithFormat: @"%.1f ly", distance];
8558 NSDictionary *routeInfo =
nil;
8559 routeInfo = [UNIVERSE routeFromSystem: system_id toSystem: info_system_id optimizedBy: ANA_mode];
8560 if (routeInfo !=
nil)
8562 double routeDistance = [[routeInfo objectForKey: @"distance"] doubleValue];
8563 double routeTime = [[routeInfo objectForKey: @"time"] doubleValue];
8564 int routeJumps = [[routeInfo objectForKey: @"jumps"] intValue];
8565 if(routeDistance == 0.0 && info_system_id != system_id) {
8566 routeDistance = 0.1;
8570 distanceInfo = [NSString stringWithFormat: @"%.1f ly / %.1f %@ / %d %@",
8574 routeTime > 1.05 || routeTime < 0.95 ? DESC(@"sysdata-route-hours%1") : DESC(@"sysdata-route-hours%0"),
8576 DESC_PLURAL(@"sysdata-route-jumps", routeJumps)];
8582 for (i = 1; i <= 16; i++) {
8583 NSString *ln = [NSString stringWithFormat:@"sysdata-line-%ld", (long)i];
8584 NSString *line =
OOExpandKeyWithSeed(infoSystemRandomSeed, ln, economy_desc, government_desc, techLevel, populationDesc, inhabitants, productivity, radius, distanceInfo);
8585 if (![line isEqualToString:
@""])
8587 NSArray *lines = [line componentsSeparatedByString:@"\t"];
8588 if ([lines
count] == 1)
8590 [gui
setArray:[NSArray arrayWithObjects:[lines objectAtIndex:0],
8594 if ([lines
count] == 2)
8596 [gui
setArray:[NSArray arrayWithObjects:[lines objectAtIndex:0],
8597 [lines objectAtIndex:1],
8601 if ([lines
count] == 3)
8603 if ([[lines objectAtIndex:2] isEqualToString:
@""])
8605 [gui
setArray:[NSArray arrayWithObjects:[lines objectAtIndex:0],
8606 [lines objectAtIndex:1],
8612 [gui
setArray:[NSArray arrayWithObjects:[lines objectAtIndex:0],
8613 [lines objectAtIndex:1],
8614 [lines objectAtIndex:2],
8622 [gui
setArray:[NSArray arrayWithObjects:@"",
8631 for (i-- ; i > 16 ; --i)
8635 for (i = 1 ; i <= 14 ; ++i)
8646 [lastTextKey release];
8649 [[UNIVERSE gameView] clearMouse];
8651 [infoSystemData release];
8653 [
self setShowDemoShips:NO];
8654 [UNIVERSE enterGUIViewModeWithMouseInteraction:NO];
8664 if (info_system_id == system_id)
8666 [
self setBackgroundFromDescriptionsKey:@"gui-scene-show-local-planet"];
8670 [
self setBackgroundFromDescriptionsKey:@"gui-scene-show-planet"];
8677 if (refreshBackground || guiChanged)
8682 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen refresh: refreshBackground];
8688- (void) prepareMarkedDestination:(NSMutableDictionary *)markers :(NSDictionary *)marker
8690 NSNumber *key = [NSNumber numberWithInt:[marker oo_intForKey:@"system"]];
8691 NSMutableArray *list = [markers objectForKey:key];
8694 list = [NSMutableArray arrayWithObject:marker];
8698 [list addObject:marker];
8700 [markers setObject:list forKey:key];
8704- (NSDictionary *) markedDestinations
8707 NSMutableDictionary *destinations = [NSMutableDictionary dictionaryWithCapacity:256];
8710 NSDictionary *marker;
8712 for (i = 0; i < [passengers count]; i++)
8714 sysid = [[passengers oo_dictionaryAtIndex:i] oo_unsignedCharForKey:CONTRACT_KEY_DESTINATION];
8715 marker = [
self passengerContractMarker:sysid];
8716 [
self prepareMarkedDestination:destinations:marker];
8718 for (i = 0; i < [parcels count]; i++)
8720 sysid = [[parcels oo_dictionaryAtIndex:i] oo_unsignedCharForKey:CONTRACT_KEY_DESTINATION];
8721 marker = [
self parcelContractMarker:sysid];
8722 [
self prepareMarkedDestination:destinations:marker];
8724 for (i = 0; i < [contracts count]; i++)
8726 sysid = [[contracts oo_dictionaryAtIndex:i] oo_unsignedCharForKey:CONTRACT_KEY_DESTINATION];
8727 marker = [
self cargoContractMarker:sysid];
8728 [
self prepareMarkedDestination:destinations:marker];
8731 NSEnumerator *keyEnum =
nil;
8732 NSString *key =
nil;
8734 for (keyEnum = [missionDestinations keyEnumerator]; (key = [keyEnum nextObject]); )
8736 marker = [missionDestinations objectForKey:key];
8737 [
self prepareMarkedDestination:destinations:marker];
8740 return destinations;
8743- (void) setGuiToLongRangeChartScreen
8749 [
self setMissionBackgroundSpecial: nil];
8750 gui_screen = GUI_SCREEN_LONG_RANGE_CHART;
8752 [
self setGuiToChartScreenFrom: oldScreen];
8755- (void) setGuiToShortRangeChartScreen
8761 [
self setMissionBackgroundSpecial: nil];
8762 gui_screen = GUI_SCREEN_SHORT_RANGE_CHART;
8763 [
self setGuiToChartScreenFrom: oldScreen];
8770 BOOL guiChanged = (oldScreen != gui_screen);
8772 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
8774 target_system_id = [UNIVERSE findSystemNumberAtCoords:cursor_coordinates withGalaxy:galaxy_number includingHidden:NO];
8776 [UNIVERSE preloadPlanetTexturesForSystem:target_system_id];
8794 if (gui_screen == GUI_SCREEN_LONG_RANGE_CHART)
8796 NSString *displaySearchString = planetSearchString ? [planetSearchString capitalizedString] : (NSString *)
@"";
8797 [gui
setText:[NSString stringWithFormat:DESC(@"long-range-chart-find-planet-@"), displaySearchString]
forRow:GUI_ROW_PLANET_FINDER];
8809 [
self setShowDemoShips:NO];
8810 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
8817 if (found_system_id >= 0)
8819 [UNIVERSE findSystemCoordinatesWithPrefix:[[UNIVERSE getSystemName:found_system_id] lowercaseString] exactMatch:YES];
8821 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen];
8826static NSString *SliderString(NSInteger amountIn20ths)
8828 NSString *filledSlider = [@"|||||||||||||||||||||||||" substringToIndex:amountIn20ths];
8829 NSString *emptySlider = [@"........................." substringToIndex:20 - amountIn20ths];
8830 return [NSString stringWithFormat:@"%@%@", filledSlider, emptySlider];
8834- (void) setGuiToGameOptionsScreen
8838 [[UNIVERSE gameView] clearMouse];
8839 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
8843 #define OO_SETACCESSCONDITIONFORROW(condition, row) \
8847 [gui setKey:GUI_KEY_OK forRow:(row)]; \
8851 [gui setColor:[OOColor grayColor] forRow:(row)]; \
8854 BOOL startingGame = [
self status] == STATUS_START_GAME;
8861 [gui
setTitle:[NSString stringWithFormat:DESC(@"status-commander-@"), [
self commanderName]]];
8863#if OO_RESOLUTION_OPTION
8867 if (displayModeIndex == NSNotFound)
8869 OOLogWARN(
@"display.currentMode.notFound",
@"%@",
@"couldn't find current fullscreen setting, switching to default.");
8870 displayModeIndex = 0;
8875 if ([modeList
count])
8877 mode = [modeList objectAtIndex:displayModeIndex];
8881 unsigned modeWidth = [mode oo_unsignedIntForKey:kOODisplayWidth];
8882 unsigned modeHeight = [mode oo_unsignedIntForKey:kOODisplayHeight];
8883 float modeRefresh = [mode oo_floatForKey:kOODisplayRefreshRate];
8887 if (!runningOnPrimaryDisplayDevice)
8889 MONITORINFOEX mInfo = [gameView currentMonitorInfo];
8890 modeWidth = mInfo.rcMonitor.right - mInfo.rcMonitor.left;
8891 modeHeight = mInfo.rcMonitor.bottom - mInfo.rcMonitor.top;
8895 NSString *displayModeString = [
self screenModeStringForWidth:modeWidth height:modeHeight refreshRate:modeRefresh];
8898 if (runningOnPrimaryDisplayDevice)
8910 if ([gameView hdrOutput])
8912 NSArray *brightnesses = [[UNIVERSE descriptions] oo_arrayForKey: @"hdr_maxBrightness_array"];
8913 int brightnessIdx = [brightnesses indexOfObject:[NSString stringWithFormat:@"%d", (int)[gameView hdrMaxBrightness]]];
8915 if (brightnessIdx == NSNotFound)
8917 OOLogWARN(
@"hdr.maxBrightness.notFound",
@"%@",
@"couldn't find current max brightness setting, switching to 400 nits.");
8921 int brightnessValue = [brightnesses oo_intAtIndex:brightnessIdx];
8922 NSString *maxBrightnessString =
OOExpandKey(
@"gameoptions-hdr-maxbrightness", brightnessValue);
8924 [gui
setText:maxBrightnessString
forRow:GUI_ROW(GAME,HDRMAXBRIGHTNESS)
align:GUI_ALIGN_CENTER];
8925 [gui
setKey:GUI_KEY_OK
forRow:GUI_ROW(GAME,HDRMAXBRIGHTNESS)];
8931 [gui
setText:DESC(@"gameoptions-autosave-yes")
forRow:GUI_ROW(GAME,AUTOSAVE)
align:GUI_ALIGN_CENTER];
8933 [gui
setText:DESC(@"gameoptions-autosave-no")
forRow:GUI_ROW(GAME,AUTOSAVE)
align:GUI_ALIGN_CENTER];
8937 if ([
OOSound respondsToSelector:@selector(masterVolume)] && [
OOSound isSoundOK])
8940 int vol = (volume / 5.0 + 0.5);
8941 NSString* soundVolumeWordDesc =
DESC(
@"gameoptions-sound-volume");
8943 [gui
setText:[NSString stringWithFormat:@"%@%@ ", soundVolumeWordDesc, SliderString(vol)]
forRow:GUI_ROW(GAME,VOLUME)
align:GUI_ALIGN_CENTER];
8945 [gui
setText:DESC(@"gameoptions-sound-volume-mute")
forRow:GUI_ROW(GAME,VOLUME)
align:GUI_ALIGN_CENTER];
8950 [gui
setText:DESC(@"gameoptions-volume-external-only")
forRow:GUI_ROW(GAME,VOLUME)
align:GUI_ALIGN_CENTER];
8957 int gamma5 = (gamma * 5);
8958 NSString* gammaWordDesc =
DESC(
@"gameoptions-gamma-value");
8959 [gui
setText:[NSString stringWithFormat:@"%@%@ (%.1f) ", gammaWordDesc, SliderString(gamma5), gamma]
forRow:GUI_ROW(GAME,GAMMA)
align:GUI_ALIGN_CENTER];
8964 float fov = [gameView
fov:NO];
8966 NSString* fovWordDesc =
DESC(
@"gameoptions-fov-value");
8967 [gui
setText:[NSString stringWithFormat:@"%@%@ (%d%c) ", fovWordDesc, SliderString(fovTicks), (int)fov, 176 ]
forRow:GUI_ROW(GAME,FOV)
align:GUI_ALIGN_CENTER];
8971 int colorblindMode = [UNIVERSE colorblindMode];
8972 NSString *colorblindModeDesc = [[[UNIVERSE descriptions] oo_arrayForKey: @"colorblind_mode"] oo_stringAtIndex:[UNIVERSE useShaders] ? colorblindMode : 0];
8973 NSString *colorblindModeMsg =
OOExpandKey(
@"gameoptions-colorblind-mode", colorblindModeDesc);
8974 [gui
setText:colorblindModeMsg
forRow:GUI_ROW(GAME,COLORBLINDMODE)
align:GUI_ALIGN_CENTER];
8977 [gui
setKey:GUI_KEY_OK
forRow:GUI_ROW(GAME,COLORBLINDMODE)];
8984#if OOLITE_SPEECH_SYNTH
8989 [gui
setText:DESC(@"gameoptions-spoken-messages-no")
forRow:GUI_ROW(GAME,SPEECH)
align:GUI_ALIGN_CENTER];
8992 [gui
setText:DESC(@"gameoptions-spoken-messages-comms")
forRow:GUI_ROW(GAME,SPEECH)
align:GUI_ALIGN_CENTER];
8995 [gui
setText:DESC(@"gameoptions-spoken-messages-yes")
forRow:GUI_ROW(GAME,SPEECH)
align:GUI_ALIGN_CENTER];
9002 NSString *voiceName = [UNIVERSE voiceName:voice_no];
9003 NSString *message =
OOExpandKey(
@"gameoptions-voice-name", voiceName);
9007 message = [NSString stringWithFormat:DESC(voice_gender_m ? @"gameoptions-voice-M" : @"gameoptions-voice-F")];
9015 if([gameView inFullScreenMode])
9017 [gui
setText:DESC(@"gameoptions-play-in-window")
forRow:GUI_ROW(GAME,DISPLAYSTYLE)
align:GUI_ALIGN_CENTER];
9021 [gui
setText:DESC(@"gameoptions-play-in-fullscreen")
forRow:GUI_ROW(GAME,DISPLAYSTYLE)
align:GUI_ALIGN_CENTER];
9023 [gui
setKey: GUI_KEY_OK
forRow: GUI_ROW(GAME,DISPLAYSTYLE)];
9026 [gui
setText:DESC(@"gameoptions-joystick-configuration")
forRow: GUI_ROW(GAME,STICKMAPPER)
align: GUI_ALIGN_CENTER];
9029 [gui
setText:DESC(@"gameoptions-keyboard-configuration")
forRow: GUI_ROW(GAME,KEYMAPPER)
align: GUI_ALIGN_CENTER];
9030 [gui
setKey: GUI_KEY_OK
forRow: GUI_ROW(GAME,KEYMAPPER)];
9034 NSString *message =
OOExpandKey(
@"gameoptions-music-mode", musicMode);
9038 if (![gameView hdrOutput])
9041 [gui
setText:DESC(@"gameoptions-wireframe-graphics-yes")
forRow:GUI_ROW(GAME,WIREFRAMEGRAPHICS)
align:GUI_ALIGN_CENTER];
9043 [gui
setText:DESC(@"gameoptions-wireframe-graphics-no")
forRow:GUI_ROW(GAME,WIREFRAMEGRAPHICS)
align:GUI_ALIGN_CENTER];
9044 [gui
setKey:GUI_KEY_OK
forRow:GUI_ROW(GAME,WIREFRAMEGRAPHICS)];
9049 float paperWhite = [gameView hdrPaperWhiteBrightness];
9051 NSString* paperWhiteWordDesc =
DESC(
@"gameoptions-hdr-paperwhite");
9052 [gui
setText:[NSString stringWithFormat:@"%@%@ (%d) ", paperWhiteWordDesc, SliderString(paperWhiteTicks), (int)paperWhite]
forRow:GUI_ROW(GAME,HDRPAPERWHITE)
align:GUI_ALIGN_CENTER];
9053 [gui
setKey:GUI_KEY_OK
forRow:GUI_ROW(GAME,HDRPAPERWHITE)];
9058 if ([
UNIVERSE doProcedurallyTexturedPlanets])
9059 [gui
setText:DESC(@"gameoptions-procedurally-textured-planets-yes")
forRow:GUI_ROW(GAME,PROCEDURALLYTEXTUREDPLANETS)
align:GUI_ALIGN_CENTER];
9061 [gui
setText:DESC(@"gameoptions-procedurally-textured-planets-no")
forRow:GUI_ROW(GAME,PROCEDURALLYTEXTUREDPLANETS)
align:GUI_ALIGN_CENTER];
9062 [gui
setKey:GUI_KEY_OK
forRow:GUI_ROW(GAME,PROCEDURALLYTEXTUREDPLANETS)];
9066 NSString *shaderEffectsOptionsString =
OOExpand(
@"gameoptions-detaillevel-[detailLevel]", detailLevel);
9067 [gui
setText:OOExpandKey(shaderEffectsOptionsString)
forRow:GUI_ROW(GAME,SHADEREFFECTS)
align:GUI_ALIGN_CENTER];
9068 [gui
setKey:GUI_KEY_OK
forRow:GUI_ROW(GAME,SHADEREFFECTS)];
9070 if ([
UNIVERSE dockingClearanceProtocolActive])
9072 [gui
setText:DESC(@"gameoptions-docking-clearance-yes")
forRow:GUI_ROW(GAME,DOCKINGCLEARANCE)
align:GUI_ALIGN_CENTER];
9076 [gui
setText:DESC(@"gameoptions-docking-clearance-no")
forRow:GUI_ROW(GAME,DOCKINGCLEARANCE)
align:GUI_ALIGN_CENTER];
9084 [gui
setSelectableRange:NSMakeRange(first_sel_row, GUI_ROW_GAMEOPTIONS_END_OF_LIST)];
9093 [
self setShowDemoShips:NO];
9094 gui_screen = GUI_SCREEN_GAMEOPTIONS;
9096 [
self setShowDemoShips:NO];
9097 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
9101- (void) setGuiToLoadSaveScreen
9103 BOOL gamePaused = [[UNIVERSE gameController] isGamePaused];
9104 BOOL canLoadOrSave = NO;
9108 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
9110 if ([
self status] == STATUS_DOCKED)
9112 if ([
self dockedStation] ==
nil) [
self setDockedAtMainStation];
9113 canLoadOrSave = (([
self dockedStation] == [UNIVERSE station] || [[
self dockedStation] allowsSaving]) && !([[
UNIVERSE sun] goneNova] || [[
UNIVERSE sun] willGoNova]));
9123 int first_sel_row = (canLoadOrSave)?
GUI_ROW(,SAVE) :
GUI_ROW(,GAMEOPTIONS);
9125 first_sel_row =
GUI_ROW(,QUICKSAVE);
9128 [gui
setTitle:[NSString stringWithFormat:DESC(@"status-commander-@"), [
self commanderName]]];
9130 [gui
setText:DESC(@"options-quick-save")
forRow:GUI_ROW(,QUICKSAVE)
align:GUI_ALIGN_CENTER];
9136 [gui
setText:DESC(@"options-save-commander")
forRow:GUI_ROW(,SAVE)
align:GUI_ALIGN_CENTER];
9137 [gui
setText:DESC(@"options-load-commander")
forRow:GUI_ROW(,LOAD)
align:GUI_ALIGN_CENTER];
9149 [gui
setText:DESC(@"options-return-to-menu")
forRow:GUI_ROW(,BEGIN_NEW)
align:GUI_ALIGN_CENTER];
9152 [gui
setText:DESC(@"options-game-options")
forRow:GUI_ROW(,GAMEOPTIONS)
align:GUI_ALIGN_CENTER];
9160 [gui
setText:DESC(@"options-exit-game")
forRow:GUI_ROW(,QUIT)
align:GUI_ALIGN_CENTER];
9166 if (gamePaused || (!canLoadOrSave && [
self status] == STATUS_DOCKED))
9177 if ([gui setForegroundTextureKey:[
self status] == STATUS_DOCKED ?
@"docked_overlay" :
@"paused_overlay"] && [
UNIVERSE pauseMessageVisible])
9184 [[UNIVERSE gameView] clearMouse];
9186 [
self setShowDemoShips:NO];
9187 gui_screen = GUI_SCREEN_OPTIONS;
9189 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
9193 [[UNIVERSE messageGUI] clear];
9194 NSString *pauseKey = [PLAYER keyBindingDescription2:@"key_pausebutton"];
9195 [UNIVERSE addMessage:OOExpandKey(@"game-paused-docked", pauseKey) forCount:1.0 forceDisplay:YES];
9198 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen];
9205- (void) highlightEquipShipScreenKey:(NSString *)key
9209 NSString *otherKey =
@"";
9211 [last_outfitting_key release];
9233 if ([otherKey isEqualToString:key])
9240 if ([otherKey hasPrefix:
@"More:"])
9242 i = [[otherKey componentsSeparatedByString:@":"] oo_intAtIndex:1];
9257 unsigned available_facings = [shipyardInfo oo_unsignedIntForKey:KEY_WEAPON_FACINGS defaultValue:[
self weaponFacings]];
9263- (void) setGuiToEquipShipScreen:(
int)skipParam selectingFacingFor:(NSString *)eqKeyForSelectFacing
9265 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
9267 missiles = [
self countMissiles];
9269 NSString *showKey =
nil;
9275 searchStatus = STATUS_TEST;
9280 searchStatus = STATUS_ACTIVE;
9287 double priceFactor = 1.0;
9288 OOTechLevelID techlevel = [[UNIVERSE currentSystemData] oo_intForKey:KEY_TECHLEVEL];
9294 if ([dockedStation equivalentTechLevel] != NSNotFound)
9299 NSMutableArray *equipmentAllowed = [NSMutableArray array];
9304 NSMutableSet *options = [NSMutableSet setWithArray:[shipyardInfo oo_arrayForKey:KEY_OPTIONAL_EQUIPMENT]];
9307 [options addObjectsFromArray:[[shipyardInfo oo_dictionaryForKey:KEY_STANDARD_EQUIPMENT] oo_arrayForKey:KEY_EQUIPMENT_EXTRAS]];
9310 NSEnumerator *eqEnum =
nil;
9312 unsigned available_facings = [shipyardInfo oo_unsignedIntForKey:KEY_WEAPON_FACINGS defaultValue:[
self weaponFacings]];
9315 if (eqKeyForSelectFacing !=
nil)
9319 [equipmentAllowed addObject:eqKeyForSelectFacing];
9320 [equipmentAllowed addObject:eqKeyForSelectFacing];
9321 [equipmentAllowed addObject:eqKeyForSelectFacing];
9323 else for (eqEnum = [
OOEquipmentType equipmentEnumeratorOutfitting]; (eqType = [eqEnum nextObject]); i++)
9332 if ([eqType isAvailableToAll]) [options addObject:eqKey];
9335 if (minTechLevel != 0 && [
self hasEquipmentItem:[eqType damagedIdentifier]]) minTechLevel--;
9338 if (techlevel < minTechLevel && techlevel + 3 > minTechLevel)
9340 unsigned day = i * 13 + (unsigned)floor([
UNIVERSE getTime] / 86400.0);
9341 unsigned char dayRnd = (day & 0xff) ^ (
unsigned char)system_id;
9344 while (minTechLevel > 0 && minTechLevel > originalMinTechLevel - 3 && !(dayRnd & 7))
9346 dayRnd = dayRnd >> 2;
9352 if ([options containsObject:eqKey])
9355 [options removeObject:eqKey];
9360 if (techlevel < minTechLevel) isOK = NO;
9361 if (![
self canAddEquipment:eqKey inContext:
@"purchase"]) isOK = NO;
9362 if (available_facings == 0 && [eqType isPrimaryWeapon]) isOK = NO;
9363 if (isOK) [equipmentAllowed addObject:eqKey];
9366 if (searchStatus == STATUS_DEAD && isOK)
9369 searchStatus = STATUS_ACTIVE;
9371 if (searchStatus == STATUS_TEST)
9373 if (isOK) showKey = eqKey;
9375 searchStatus = isOK ? STATUS_ACTIVE : STATUS_DEAD;
9378 if (searchStatus != STATUS_TEST && showKey !=
nil)
9380 [last_outfitting_key release];
9389 unsigned facing_count = 0;
9390 BOOL displayRow = YES;
9391 BOOL weaponMounted = NO;
9392 BOOL guiChanged = (gui_screen != GUI_SCREEN_EQUIP_SHIP);
9395 [gui
setTitle:DESC(@"equip-title")];
9398 [gui
setText:OOExpandKey(@"equip-cash-value", credits)
forRow:GUI_ROW_EQUIPMENT_CASH];
9402 tab_stops[1] = -360;
9403 tab_stops[2] = -480;
9408 NSUInteger
count = [equipmentAllowed count];
9416 if (
count <= n_rows || skip < n_rows)
9420 previous = skip - (n_rows - 2);
9425 if (eqKeyForSelectFacing !=
nil)
9429 [gui
setKey:[NSString stringWithFormat:@"More:%d:%@", previous, eqKeyForSelectFacing]
forRow:row];
9433 [gui
setKey:[NSString stringWithFormat:@"More:%d", previous]
forRow:row];
9436 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-back"), @"", @" <-- ", nil]
forRow:row];
9440 for (i = skip; i <
count && (row - start_row < (
OOGUIRow)n_rows); i++)
9442 NSString *eqKey = [equipmentAllowed oo_stringAtIndex:i];
9445 NSString *desc = [NSString stringWithFormat:@" %@ ", [eqInfo
name]];
9453 if ([eqKey isEqual:
@"EQ_FUEL"])
9457 else if ([eqKey isEqualToString:
@"EQ_RENOVATION"])
9459 price = [
self renovationCosts];
9464 price = pricePerUnit;
9467 price = [
self adjustPriceByScriptForEqKey:eqKey withCurrent:price];
9469 price *= priceFactor;
9472 if (installTime == 0)
9474 installTime = 600 + price;
9477 if ([
self hasEquipmentItem:eq_key_damaged])
9479 desc = [NSString stringWithFormat:DESC(@"equip-repair-@"), desc];
9482 if (installTime == 0)
9484 installTime = 600 + price;
9490 NSString *timeString = [UNIVERSE shortTimeDescription:installTime];
9491 NSString *priceString = [NSString stringWithFormat:@" %@ ", OOCredits(price)];
9493 if ([eqKeyForSelectFacing isEqualToString:eqKey])
9496 while (facing_count < 5)
9498 NSUInteger multiplier = 1;
9499 switch (facing_count)
9508 if (_multiplyWeapons)
9510 multiplier = [forwardWeaponOffset count];
9518 if (_multiplyWeapons)
9520 multiplier = [aftWeaponOffset count];
9528 if (_multiplyWeapons)
9530 multiplier = [portWeaponOffset count];
9538 if (_multiplyWeapons)
9540 multiplier = [starboardWeaponOffset count];
9556 priceString = [NSString stringWithFormat:@" %@ ", OOCredits(price*multiplier)];
9559 [gui
setArray:[NSArray arrayWithObjects:desc, (facing_count > 0 ? priceString : (NSString *)@""), timeString, nil]
forRow:row];
9570 if (![eqInfo hideValues])
9572 [gui
setArray:[NSArray arrayWithObjects:desc, priceString, timeString, nil]
forRow:row];
9587 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-more"), @"", @" --> ", nil]
forRow:row - 1];
9588 [gui
setKey:[NSString stringWithFormat:@"More:%d", i - 1]
forRow:row - 1];
9593 if ([gui selectedRow] != start_row)
9596 if (eqKeyForSelectFacing !=
nil)
9599 [
self showInformationForSelectedUpgradeWithFormatString:DESC(@"@-select-where-to-install")];
9603 [
self showInformationForSelectedUpgrade];
9608 [gui
setText:DESC(@"equip-no-equipment-available-for-purchase")
forRow:GUI_ROW_NO_SHIPS
align:GUI_ALIGN_CENTER];
9613 [
self showInformationForSelectedUpgrade];
9622 NSDictionary *background = [UNIVERSE screenTextureDescriptorForKey:@"equip_ship"];
9623 [
self setEquipScreenBackgroundDescriptor:background];
9626 else if (eqKeyForSelectFacing !=
nil)
9628 NSDictionary *bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"mount_weapon"];
9639 [
self setShowDemoShips:NO];
9640 gui_screen = GUI_SCREEN_EQUIP_SHIP;
9642 [
self setShowDemoShips:NO];
9643 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
9647- (void) setGuiToEquipShipScreen:(
int)skip
9649 [
self setGuiToEquipShipScreen:skip selectingFacingFor:nil];
9653- (void) showInformationForSelectedUpgrade
9655 [
self showInformationForSelectedUpgradeWithFormatString:nil];
9659- (void) showInformationForSelectedUpgradeWithFormatString:(NSString *)formatString
9673 if (![eqKey hasPrefix:
@"More:"])
9676 NSString* eq_key_damaged = [NSString stringWithFormat:@"%@_DAMAGED", eqKey];
9678 if ([
self hasEquipmentItem:eq_key_damaged])
9680 desc = [NSString stringWithFormat:DESC(@"upgradeinfo-@-price-is-for-repairing"), desc];
9684 if([eqKey hasSuffix:
@"ENERGY_UNIT"] && ([
self hasEquipmentItem:
@"EQ_ENERGY_UNIT_DAMAGED"] || [
self hasEquipmentItem:
@"EQ_ENERGY_UNIT"] || [
self hasEquipmentItem:
@"EQ_NAVAL_ENERGY_UNIT_DAMAGED"]))
9685 desc = [NSString stringWithFormat:
DESC(
@"@-will-replace-other-energy"), desc];
9686 if (weight > 0) desc = [NSString stringWithFormat:DESC(@"upgradeinfo-@-weight-d-of-equipment"), desc, weight];
9688 if (formatString) desc = [NSString stringWithFormat:formatString, desc];
9695- (void) setGuiToInterfacesScreen:(
int)skip
9697 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
9698 if (gui_screen != GUI_SCREEN_INTERFACES)
9700 [
self noteGUIWillChangeTo:GUI_SCREEN_INTERFACES];
9704 NSDictionary *interfaces = [[
self dockedStation] localInterfaces];
9705 NSArray *interfaceKeys = [interfaces keysSortedByValueUsingSelector:@selector(interfaceCompare:)];
9713 BOOL guiChanged = (gui_screen != GUI_SCREEN_INTERFACES);
9716 [gui
setTitle:DESC(@"interfaces-title")];
9721 tab_stops[1] = -480;
9726 NSUInteger
count = [interfaceKeys count];
9734 if (
count <= n_rows || skip < (NSInteger)n_rows)
9740 previous = skip - (n_rows - 2);
9747 [gui
setKey:[NSString stringWithFormat:@"More:%d", previous]
forRow:row];
9749 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-back"), @" <-- ", nil]
forRow:row];
9753 for (i = skip; i < (NSInteger)
count && (row - start_row < (
OOGUIRow)n_rows); i++)
9755 NSString *interfaceKey = [interfaceKeys objectAtIndex:i];
9765 if (i < (NSInteger)
count)
9769 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-more"), @" --> ", nil]
forRow:row - 1];
9770 [gui
setKey:[NSString stringWithFormat:@"More:%d", i - 1]
forRow:row - 1];
9775 if ([gui selectedRow] != start_row)
9780 [
self showInformationForSelectedInterface];
9784 [gui
setText:DESC(@"interfaces-no-interfaces-available-for-use")
forRow:GUI_ROW_NO_INTERFACES
align:GUI_ALIGN_LEFT];
9794 NSString *desc = [NSString stringWithFormat:DESC(@"interfaces-for-ship-@-and-station-@"), [
self displayName], [[
self dockedStation] displayName]];
9802 NSDictionary *background = [UNIVERSE screenTextureDescriptorForKey:@"interfaces"];
9809 [
self setShowDemoShips:NO];
9812 gui_screen = GUI_SCREEN_INTERFACES;
9813 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen];
9815 [
self setShowDemoShips:NO];
9816 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
9821- (void) showInformationForSelectedInterface
9834 if (interfaceKey && ![interfaceKey hasPrefix:
@"More:"])
9836 NSDictionary *interfaces = [[
self dockedStation] localInterfaces];
9847- (void) activateSelectedInterface
9852 if ([key hasPrefix:
@"More:"])
9854 int from_item = [[key componentsSeparatedByString:@":"] oo_intAtIndex:1];
9855 [
self setGuiToInterfacesScreen:from_item];
9857 if ([gui selectedRow] < 0)
9860 [gui
setSelectedRow:GUI_ROW_INTERFACES_START + GUI_MAX_ROWS_INTERFACES - 1];
9861 [
self showInformationForSelectedInterface];
9867 NSDictionary *interfaces = [[
self dockedStation] localInterfaces];
9871 [[UNIVERSE gameView] clearKeys];
9876 OOLog(
@"interface.missingCallback",
@"Unable to find callback definition for key %@", key);
9881- (void) setupStartScreenGui
9884 NSString *text =
nil;
9886 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
9892 text =
DESC(
@"game-copyright");
9896 text =
DESC(
@"theme-music-credit");
9900 int initialRow = 22;
9901 int row = initialRow;
9903 text =
DESC(
@"oolite-start-option-1");
9906 [gui
setKey:[NSString stringWithFormat:@"Start:%d", row]
forRow:row];
9910 text =
DESC(
@"oolite-start-option-2");
9913 [gui
setKey:[NSString stringWithFormat:@"Start:%d", row]
forRow:row];
9917 text =
DESC(
@"oolite-start-option-3");
9920 [gui
setKey:[NSString stringWithFormat:@"Start:%d", row]
forRow:row];
9924 text =
DESC(
@"oolite-start-option-4");
9927 [gui
setKey:[NSString stringWithFormat:@"Start:%d", row]
forRow:row];
9931 text =
DESC(
@"oolite-start-option-5");
9934 [gui
setKey:[NSString stringWithFormat:@"Start:%d", row]
forRow:row];
9938 text =
DESC(
@"oolite-start-option-6");
9941 [gui
setKey:[NSString stringWithFormat:@"Start:%d", row]
forRow:row];
9955- (void) setGuiToIntroFirstGo:(BOOL)justCobra
9957 NSString *text =
nil;
9961 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:NO];
9962 [[UNIVERSE gameView] clearMouse];
9963 [[UNIVERSE gameView] clearKeys];
9968 [UNIVERSE removeDemoShips];
9974 [
self setupStartScreenGui];
9983 for (i-- ; i >= ms_start ; i--) [gui setColor:[OOColor redColor] forRow:i];
9989 if ([OXPsWithMessages
count] > 0)
9991 NSString *messageToDisplay =
@"";
9995 if ([OXPsWithMessages
count] < 5)
9997 NSString *messageSourceList = [OXPsWithMessages componentsJoinedByString:@", "];
9998 messageToDisplay =
OOExpandKey(
@"oxp-containing-messages-list", messageSourceList);
10000 messageToDisplay =
OOExpandKey(
@"oxp-containing-messages-found");
10005 for (i--; i >= ms_start; i--)
10013 NSArray* arguments = [[NSProcessInfo processInfo] arguments];
10015 for (i = 0; i < [arguments count]; i++)
10017 if (([[arguments objectAtIndex:i] isEqual:
@"-message"])&&(i < [arguments
count] - 1))
10020 NSString* message = [arguments oo_stringAtIndex:i + 1];
10022 for (i-- ; i >= ms_start; i--)
10027 if ([[arguments objectAtIndex:i] isEqual:
@"-showversion"])
10030 NSString *version = [NSString stringWithFormat:@"Version %@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]];
10032 for (i-- ; i >= ms_start; i--)
10043 text =
DESC(
@"oolite-ship-library-title");
10046 text =
DESC(
@"oolite-ship-library-exit");
10053 [UNIVERSE setupIntroFirstGo: justCobra];
10057 gui_screen = justCobra ? GUI_SCREEN_INTRO1 : GUI_SCREEN_SHIPLIBRARY;
10059 if ([
self status] == STATUS_START_GAME)
10064 [
self setShowDemoShips:YES];
10073 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
10078- (void) setGuiToOXZManager
10081 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:NO];
10082 [[UNIVERSE gameView] clearMouse];
10083 [UNIVERSE removeDemoShips];
10085 gui_screen = GUI_SCREEN_OXZMANAGER;
10087 [[UNIVERSE gui] clearAndKeepBackground:NO];
10092 [[UNIVERSE gui] setBackgroundTextureKey:@"oxz-manager"];
10093 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
10110 [
self noteGUIDidChangeFrom: fromScreen to: toScreen refresh: NO];
10117 if (fromScreen != toScreen || refresh)
10120 switch (fromScreen)
10122 case GUI_SCREEN_SHIPYARD:
10123 case GUI_SCREEN_LOAD:
10124 case GUI_SCREEN_SAVE:
10125 [demoShip release];
10134 if (toScreen == GUI_SCREEN_SYSTEM_DATA)
10137 [[UNIVERSE sun] setSunColor:[
OOColor colorWithDescription:[[UNIVERSE systemManager] getProperty:@"sun_color" forSystem:info_system_id inGalaxy:[
self galaxyNumber]]]];
10142 [[UNIVERSE sun] setSunColor:[
OOColor colorWithDescription:[[UNIVERSE systemManager] getProperty:@"sun_color" forSystem:system_id inGalaxy:[
self galaxyNumber]]]];
10145 if (![[
UNIVERSE gameController] isGamePaused])
10157 [
self noteSwitchToView:toView fromView:fromView];
10161- (void) buySelectedItem
10166 if ([key hasPrefix:
@"More:"])
10168 int from_item = [[key componentsSeparatedByString:@":"] oo_intAtIndex:1];
10169 NSString *weaponKey = [[key componentsSeparatedByString:@":"] oo_stringAtIndex:2];
10171 [
self setGuiToEquipShipScreen:from_item];
10172 if (weaponKey !=
nil)
10174 [
self highlightEquipShipScreenKey:weaponKey];
10178 if ([gui selectedRow] < 0)
10180 if (from_item == 0)
10181 [gui
setSelectedRow:GUI_ROW_EQUIPMENT_START + GUI_MAX_ROWS_EQUIPMENT - 1];
10182 [
self showInformationForSelectedUpgrade];
10203 if ([
self tryBuyingItem:key])
10205 if (credits == old_credits)
10208 [
self playMenuNavigationDown];
10212 [
self playBuyCommodity];
10215 if(credits != old_credits || ![key hasPrefix:
@"EQ_WEAPON_"])
10219 NSUInteger adjust = 0;
10228 double time_adjust = (old_credits > credits) ? (old_credits - credits) : 0.0;
10229 [UNIVERSE forceWitchspaceEntries];
10232 ship_clock_adjust += time_adjust + 600.0;
10236 ship_clock_adjust += (double)adjust;
10239 [
self doScriptEvent:OOJSID("playerBoughtEquipment") withArguments:[NSArray arrayWithObjects:key, [NSNumber numberWithLongLong:(old_credits - credits)], nil]];
10240 if (gui_screen == GUI_SCREEN_EQUIP_SHIP)
10243 [
self setGuiToEquipShipScreen:0];
10245 [
self highlightEquipShipScreenKey:key];
10248 if ([
UNIVERSE autoSave]) [UNIVERSE setAutoSaveNow:YES];
10253 [
self playCantBuyCommodity];
10261 if (condition_script !=
nil)
10263 OOJSScript *condScript = [UNIVERSE getConditionScript:condition_script];
10264 if (condScript !=
nil)
10271 OK = JS_NewNumberValue(JScontext, price, &args[1]);
10275 OK = [condScript
callMethod:OOJSID("updateEquipmentPrice")
10283 OK = JS_ValueToInt32(JScontext, result, &newPrice);
10284 if (OK && newPrice >= 0)
10296- (BOOL) tryBuyingItem:(NSString *)eqKey
10302 double price = pricePerUnit;
10303 double priceFactor = 1.0;
10305 BOOL isRepair = NO;
10308 if ([
self hasEquipmentItem:eqKeyDamaged])
10314 if ([eqKey isEqualToString:
@"EQ_RENOVATION"])
10316 price = [
self renovationCosts];
10319 price = [
self adjustPriceByScriptForEqKey:eqKey withCurrent:price];
10327 price *= priceFactor;
10329 if (price > credits)
10334 if ([eqType isPrimaryWeapon])
10338 [
self setGuiToEquipShipScreen:0 selectingFacingFor:eqKey];
10345 NSUInteger multiplier = 1;
10347 switch (chosen_weapon_facing)
10350 current_weapon = forward_weapon_type;
10351 forward_weapon_type = chosen_weapon;
10352 if (_multiplyWeapons)
10354 multiplier = [forwardWeaponOffset count];
10359 current_weapon = aft_weapon_type;
10360 aft_weapon_type = chosen_weapon;
10361 if (_multiplyWeapons)
10363 multiplier = [aftWeaponOffset count];
10368 current_weapon = port_weapon_type;
10369 port_weapon_type = chosen_weapon;
10370 if (_multiplyWeapons)
10372 multiplier = [portWeaponOffset count];
10377 current_weapon = starboard_weapon_type;
10378 starboard_weapon_type = chosen_weapon;
10379 if (_multiplyWeapons)
10381 multiplier = [starboardWeaponOffset count];
10389 price *= multiplier;
10391 if (price > credits)
10396 switch (chosen_weapon_facing)
10399 forward_weapon_type = current_weapon;
10402 aft_weapon_type = current_weapon;
10405 port_weapon_type = current_weapon;
10408 starboard_weapon_type = current_weapon;
10418 if (current_weapon !=
nil)
10420 tradeIn = [UNIVERSE getEquipmentPriceForKey:OOEquipmentIdentifierFromWeaponType(current_weapon)] * multiplier;
10423 [
self doTradeIn:tradeIn forPriceFactor:priceFactor];
10425 [
self removeEquipmentItem:eqKeyDamaged];
10429 if ([eqType isMissileOrMine] && missiles >= max_missiles)
10431 OOLog(
@"equip.buy.mounted.failed.full",
@"%@",
@"rejecting missile because already full");
10444 if ([eqKey isEqualToString:
@"EQ_FUEL"])
10446#if MASS_DEPENDENT_FUEL_PRICES
10451 if (credits >= creditsForRefuel)
10453 credits -= creditsForRefuel;
10454 fuel = [
self fuelCapacity];
10466 switch ([
self energyUnitType])
10469 [
self removeEquipmentItem:@"EQ_NAVAL_ENERGY_UNIT"];
10470 tradeIn = [UNIVERSE getEquipmentPriceForKey:@"EQ_NAVAL_ENERGY_UNIT"] / 2;
10473 [
self removeEquipmentItem:@"EQ_NAVAL_ENERGY_UNIT_DAMAGED"];
10474 tradeIn = [UNIVERSE getEquipmentPriceForKey:@"EQ_NAVAL_ENERGY_UNIT"] / 4;
10477 [
self removeEquipmentItem:@"EQ_ENERGY_UNIT"];
10478 tradeIn = [UNIVERSE getEquipmentPriceForKey:@"EQ_ENERGY_UNIT"] * 3 / 4;
10481 [
self removeEquipmentItem:@"EQ_ENERGY_UNIT_DAMAGED"];
10482 tradeIn = [UNIVERSE getEquipmentPriceForKey:@"EQ_ENERGY_UNIT"] * 3 / 8;
10488 [
self doTradeIn:tradeIn forPriceFactor:priceFactor];
10492 if ([eqKey isEqualToString:
@"EQ_RENOVATION"])
10496 if (techLevel == NSNotFound) techLevel = [[UNIVERSE currentSystemData] oo_unsignedIntForKey:KEY_TECHLEVEL];
10499 ship_trade_in_factor += 5 + techLevel;
10500 if (ship_trade_in_factor > 100) ship_trade_in_factor = 100;
10502 [
self clearSubEntities];
10503 [
self setUpSubEntities];
10508 if ([eqKey hasSuffix:
@"MISSILE"] || [eqKey hasSuffix:
@"MINE"])
10510 ShipEntity* weapon = [[UNIVERSE newShipWithRole:eqKey] autorelease];
10514 BOOL mounted_okay = [
self mountMissile:weapon];
10518 [
self safeAllMissiles];
10519 [
self tidyMissilePylons];
10520 [
self setActiveMissile:0];
10522 return mounted_okay;
10525 if ([eqKey isEqualToString:
@"EQ_PASSENGER_BERTH"])
10527 [
self changePassengerBerths:+1];
10532 if ([eqKey isEqualToString:
@"EQ_PASSENGER_BERTH_REMOVAL"])
10534 [
self changePassengerBerths:-1];
10539 if ([eqKey isEqualToString:
@"EQ_MISSILE_REMOVAL"])
10542 tradeIn += [
self removeMissiles];
10543 [
self doTradeIn:tradeIn forPriceFactor:priceFactor];
10547 if ([
self canAddEquipment:eqKey inContext:
@"purchase"])
10550 [
self addEquipmentItem:eqKey withValidation:NO inContext:@"purchase"];
10553 [
self doScriptEvent:OOJSID("equipmentRepaired") withArgument:eqKey];
10562- (BOOL) setWeaponMount:(
OOWeaponFacing)facing toWeapon:(NSString *)eqKey
10564 return [
self setWeaponMount:facing toWeapon:eqKey inContext:@"purchase"];
10568- (BOOL) setWeaponMount:(
OOWeaponFacing)facing toWeapon:(NSString *)eqKey inContext:(NSString *) context
10572 unsigned available_facings = [shipyardInfo oo_unsignedIntForKey:KEY_WEAPON_FACINGS defaultValue:[
self weaponFacings]];
10575 if (!(available_facings & facing))
10581 if (![eqKey isEqualToString:
@"EQ_WEAPON_NONE"])
10583 if (![
self canAddEquipment:eqKey inContext:context])
10595 forward_weapon_type = chosen_weapon;
10599 aft_weapon_type = chosen_weapon;
10603 port_weapon_type = chosen_weapon;
10607 starboard_weapon_type = chosen_weapon;
10618- (BOOL) changePassengerBerths:(
int) addRemove
10620 if (addRemove == 0)
return NO;
10621 addRemove = (addRemove > 0) ? 1 : -1;
10625 if ((max_passengers < 1 && addRemove == -1) || ([
self maxAvailableCargoSpace] - current_cargo <
PASSENGER_BERTH_SPACE && addRemove == 1))
return NO;
10626 max_passengers += addRemove;
10634 [
self safeAllMissiles];
10637 for (i = 0; i < missiles; i++)
10639 NSString *weapon_key = [missile_list[i] identifier];
10641 if (weapon_key !=
nil)
10642 tradeIn += (
int)[
UNIVERSE getEquipmentPriceForKey:weapon_key];
10645 for (i = 0; i < max_missiles; i++)
10647 [missile_entity[i] release];
10648 missile_entity[i] =
nil;
10656- (void) doTradeIn:(
OOCreditsQuantity)tradeInValue forPriceFactor:(
double)priceFactor
10658 if (tradeInValue != 0)
10660 if (priceFactor < 1.0) tradeInValue *= priceFactor;
10661 credits += tradeInValue;
10670 if ([
self status] != STATUS_DOCKED)
10676 for (i = [cargo
count] - 1; i >= 0 ; i--)
10678 cargoItem = [cargo objectAtIndex:i];
10680 if ([co_type isEqualToString:type])
10682 amount += [cargoItem commodityAmount];
10693 OOMassUnit unit = [shipCommodityData massUnitForGood:type];
10694 if([
self specialCargo] && unit ==
UNITS_TONS)
return 0;
10698 BOOL inPods = ([
self status] != STATUS_DOCKED);
10701 if (unit ==
UNITS_TONS && (available + oldAmount) < amount)
10703 amount = available + oldAmount;
10711 if (safeAmount < amount) amount = (safeAmount < oldAmount) ? oldAmount : safeAmount;
10713 else if (unit ==
UNITS_GRAMS && amount > oldAmount)
10716 if (safeAmount < amount) amount = (safeAmount < oldAmount) ? oldAmount : safeAmount;
10721 if (amount > oldAmount)
10723 [
self loadCargoPodsForType:type amount:(amount - oldAmount)];
10727 [
self unloadCargoPodsForType:type amount:(oldAmount - amount)];
10732 [shipCommodityData setQuantity:amount forGood:type];
10735 [
self calculateCurrentCargo];
10736 return [shipCommodityData quantityForGood:type];
10740- (void) calculateCurrentCargo
10742 current_cargo = [
self cargoQuantityOnBoard];
10748 if ([
self specialCargo] !=
nil)
10750 return [
self maxAvailableCargoSpace];
10761 NSString *good =
nil;
10763 foreach (good, [shipCommodityData goods])
10767 OOMassUnit commodityUnits = [shipCommodityData massUnitForGood:good];
10779 cargoQtyOnBoard += quantity;
10781 cargoQtyOnBoard += [[
self cargo]
count];
10783 return cargoQtyOnBoard;
10790 if (station ==
nil)
10792 if ([[
self primaryTarget] isStation] && [(
StationEntity *)[
self primaryTarget] marketBroadcast])
10794 station = [
self primaryTarget];
10798 station = [UNIVERSE station];
10800 if (station ==
nil)
10807 if (localMarket ==
nil)
10812 return localMarket;
10816- (NSArray *) applyMarketFilter:(NSArray *)goods onMarket:(
OOCommodityMarket *)market
10822 NSMutableArray *filteredGoods = [NSMutableArray arrayWithCapacity:[goods count]];
10824 foreach (good, goods)
10826 switch (marketFilterMode)
10830 [filteredGoods addObject:good];
10833 if ([market quantityForGood:good] > 0 || [
self cargoQuantityForType:good] > 0)
10835 [filteredGoods addObject:good];
10839 if ([
self cargoQuantityForType:good] > 0)
10841 [filteredGoods addObject:good];
10845 if ([market quantityForGood:good] > 0)
10847 [filteredGoods addObject:good];
10851 if ([market exportLegalityForGood:good] == 0 && [market importLegalityForGood:good] == 0)
10853 [filteredGoods addObject:good];
10857 if ([market exportLegalityForGood:good] > 0 || [market importLegalityForGood:good] > 0)
10859 [filteredGoods addObject:good];
10864 return [[filteredGoods copy] autorelease];
10868- (NSArray *) applyMarketSorter:(NSArray *)goods onMarket:(
OOCommodityMarket *)market
10870 switch (marketSorterMode)
10873 return [goods sortedArrayUsingFunction:marketSorterByName context:market];
10875 return [goods sortedArrayUsingFunction:marketSorterByPrice context:market];
10877 return [goods sortedArrayUsingFunction:marketSorterByQuantity context:market];
10879 return [goods sortedArrayUsingFunction:marketSorterByQuantity context:shipCommodityData];
10881 return [goods sortedArrayUsingFunction:marketSorterByMassUnit context:market];
10895 tab_stops[1] = 137;
10896 tab_stops[2] = 187;
10897 tab_stops[3] = 267;
10898 tab_stops[4] = 321;
10899 tab_stops[5] = 431;
10904 [gui
setArray:[NSArray arrayWithObjects: DESC(@"commodity-column-title"), OOPadStringToEms(DESC(@"price-column-title"),3.5),
10905 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];
10906 [gui
setArray:[NSArray arrayWithObjects: DESC(@"commodity-column-title"), DESC(@"oolite-extras-column-title"), OOPadStringToEms(DESC(@"price-column-title"),3.5),
10907 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];
10915 NSString* desc = [NSString stringWithFormat:@" %@ ", [shipCommodityData nameForGood:good]];
10919 OOMassUnit unit = [shipCommodityData massUnitForGood:good];
10921 NSString *available =
OOPadStringToEms(((available_units > 0) ? (NSString *)[NSString stringWithFormat:
@"%d",available_units] :
DESC(
@"commodity-quantity-none")), 2.5);
10923 NSUInteger priceDecimal = pricePerUnit % 10;
10924 NSString *price = [NSString stringWithFormat:@" %@.%lu ",OOPadStringToEms([NSString stringWithFormat:@"%lu",(unsigned long)(pricePerUnit/10)],2.5),priceDecimal];
10928 NSString *owned =
OOPadStringToEms((units_in_hold > 0) ? (NSString *)[NSString stringWithFormat:
@"%d",units_in_hold] :
DESC(
@"commodity-quantity-none"), 4.5);
10930 NSString *units_available = [NSString stringWithFormat:@" %@ %@ ",available, units];
10931 NSString *units_owned = [NSString stringWithFormat:@" %@ %@ ",owned, units];
10935 NSString *legaldesc =
nil;
10936 if (import_legality == 0)
10938 if (export_legality == 0)
10940 legaldesc =
DESC(
@"oolite-legality-clear");
10944 legaldesc =
DESC(
@"oolite-legality-import");
10949 if (export_legality == 0)
10951 legaldesc =
DESC(
@"oolite-legality-export");
10955 legaldesc =
DESC(
@"oolite-legality-neither");
10958 legaldesc = [NSString stringWithFormat:@" %@ ",legaldesc];
10960 NSString *extradesc = [shipCommodityData shortCommentForGood:good];
10964 [gui
setArray:[NSArray arrayWithObjects: desc, extradesc, price, units_available, units_owned, legaldesc, nil]
forRow:row++];
10969- (NSString *)marketScreenTitle
10974 if (dockedStation ==
nil)
10976 if ([[
self primaryTarget] isStation] && [(
StationEntity *)[
self primaryTarget] marketBroadcast])
10978 dockedStation = [
self primaryTarget];
10982 NSString *system =
nil;
10983 if ([
UNIVERSE sun] !=
nil) system = [UNIVERSE getSystemName:system_id];
10985 if (dockedStation ==
nil || dockedStation == [
UNIVERSE station])
10989 return OOExpandKey(
@"system-commodity-market", system);
11000 return OOExpandKey(
@"station-commodity-market", station);
11005- (void) setGuiToMarketScreen
11011 gui_screen = GUI_SCREEN_MARKET;
11012 BOOL guiChanged = (oldScreen != gui_screen);
11015 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
11018 if (localMarket ==
nil)
11020 localMarket = [[UNIVERSE commodities] generateBlankMarket];
11024 NSArray *goods = [
self applyMarketSorter:[
self applyMarketFilter:[localMarket
goods] onMarket:localMarket] onMarket:localMarket];
11025 NSInteger maxOffset = 0;
11031 NSUInteger commodityCount = [shipCommodityData count];
11034 for (NSUInteger i = 0; i < commodityCount; i++)
11036 quantityInHold[i] = [shipCommodityData quantityForGood:[goods oo_stringAtIndex:i]];
11038 for (NSUInteger i = 0; i < [cargo count]; i++)
11040 ShipEntity *container = [cargo objectAtIndex:i];
11041 NSUInteger goodsIndex = [goods indexOfObject:[container
commodityType]];
11043 if (goodsIndex != NSNotFound)
11045 quantityInHold[goodsIndex] += [container commodityAmount];
11049 if (marketSelectedCommodity !=
nil && ([marketSelectedCommodity isEqualToString:
@"<<<"] || [marketSelectedCommodity isEqualToString:
@">>>"]))
11055 if (marketSelectedCommodity ==
nil || [goods indexOfObject:marketSelectedCommodity] == NSNotFound)
11057 DESTROY(marketSelectedCommodity);
11058 if ([goods
count] > 0)
11060 marketSelectedCommodity = [[goods oo_stringAtIndex:0] retain];
11065 NSInteger goodsIndex = [goods indexOfObject:marketSelectedCommodity];
11067 if (goodsIndex <= marketOffset)
11070 if (goodsIndex == 0) {
11073 marketOffset = goodsIndex-1;
11080 if (marketOffset > maxOffset)
11082 marketOffset = maxOffset;
11098 if (dockedStation ==
nil && [[
self primaryTarget] isStation] && [(
StationEntity *)[
self primaryTarget] marketBroadcast])
11100 dockedStation = [
self primaryTarget];
11103 [gui
setTitle:[
self marketScreenTitle]];
11105 [
self showMarketScreenHeaders];
11107 if (marketOffset > maxOffset)
11111 else if (marketOffset < 0)
11113 marketOffset = maxOffset;
11116 if ([goods
count] > 0)
11120 foreach (good, goods)
11122 if (i < marketOffset)
11127 [
self showMarketScreenDataLine:row forGood:good inMarket:localMarket holdQuantity:quantityInHold[i++]];
11128 if ([good isEqualToString:marketSelectedCommodity])
11140 if (marketOffset < maxOffset)
11142 if ([marketSelectedCommodity isEqualToString:
@">>>"])
11148 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-more"), @"", @"", @"", @" --> ", nil]
forRow:GUI_ROW_MARKET_LAST];
11150 if (marketOffset > 0)
11152 if ([marketSelectedCommodity isEqualToString:
@"<<<"])
11158 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-back"), @"", @"", @"", @" <-- ", nil]
forRow:GUI_ROW_MARKET_START];
11165 [gui
setText:DESC(@"oolite-market-filtered-all")
forRow:GUI_ROW_MARKET_START];
11170 current_cargo = [
self cargoQuantityOnBoard];
11171 if (current_cargo > [
self maxAvailableCargoSpace]) current_cargo = [
self maxAvailableCargoSpace];
11175 NSString *filterMode =
OOExpandKey(
OOExpand(
@"oolite-market-filter-[marketFilterMode]", marketFilterMode));
11176 NSString *filterText =
OOExpandKey(
@"oolite-market-filter-line", filterMode);
11177 NSString *sortMode =
OOExpandKey(
OOExpand(
@"oolite-market-sorter-[marketSorterMode]", marketSorterMode));
11178 NSString *sorterText =
OOExpandKey(
@"oolite-market-sorter-line", sortMode);
11179 [gui
setArray:[NSArray arrayWithObjects:filterText, @"", sorterText, nil]
forRow:GUI_ROW_MARKET_END];
11183 [
self showMarketCashAndLoadLine];
11192 [[UNIVERSE gameView] clearMouse];
11194 [
self setShowDemoShips:NO];
11195 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
11201 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen];
11206- (void) setGuiToMarketInfoScreen
11212 gui_screen = GUI_SCREEN_MARKETINFO;
11213 BOOL guiChanged = (oldScreen != gui_screen);
11216 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
11219 if (localMarket ==
nil)
11221 localMarket = [[UNIVERSE commodities] generateBlankMarket];
11225 NSArray *goods = [
self applyMarketSorter:[
self applyMarketFilter:[localMarket
goods] onMarket:localMarket] onMarket:localMarket];
11227 NSUInteger i, j, commodityCount = [shipCommodityData count];
11230 for (i = 0; i < commodityCount; i++)
11232 quantityInHold[i] = [shipCommodityData quantityForGood:[goods oo_stringAtIndex:i]];
11234 for (i = 0; i < [cargo count]; i++)
11236 ShipEntity *container = [cargo objectAtIndex:i];
11238 quantityInHold[j] += [container commodityAmount];
11250 j = [goods indexOfObject:marketSelectedCommodity];
11252 if (j == NSNotFound)
11254 DESTROY(marketSelectedCommodity);
11255 [
self setGuiToMarketScreen];
11261 [gui
setTitle:[NSString stringWithFormat:DESC(@"oolite-commodity-information-@"), [shipCommodityData nameForGood:marketSelectedCommodity]]];
11263 [
self showMarketScreenHeaders];
11264 [
self showMarketScreenDataLine:GUI_ROW_MARKET_START forGood:marketSelectedCommodity inMarket:localMarket holdQuantity:quantityInHold[j]];
11266 OOCargoQuantity contracted = [
self contractedVolumeForGood:marketSelectedCommodity];
11267 if (contracted > 0)
11269 OOMassUnit unit = [shipCommodityData massUnitForGood:marketSelectedCommodity];
11271 [gui
setText:[NSString stringWithFormat:DESC(@"oolite-commodity-contracted-d-@"), contracted, DisplayStringForMassUnit(unit)]
forRow:GUI_ROW_MARKET_START+1];
11274 NSString *info = [shipCommodityData commentForGood:marketSelectedCommodity];
11276 if (info ==
nil || [info length] == 0)
11289 [
self showMarketCashAndLoadLine];
11293 [[UNIVERSE gameView] clearMouse];
11295 [
self setShowDemoShips:NO];
11296 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
11302 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen];
11311 [gui
setText:OOExpandKey(@"market-cash-and-load", credits, currentCargo, cargoCapacity)
forRow:GUI_ROW_MARKET_CASH];
11323 if ([index isEqualToString:
@"<<<"] || [index isEqualToString:
@">>>"])
11329 if (![
self isDocked])
return NO;
11339 int manifest_quantity = [shipCommodityData quantityForGood:index];
11346 int contracted = [
self contractedVolumeForGood:index];
11347 if (manifest_quantity >= contracted)
11353 purchase = contracted-manifest_quantity;
11356 if (purchase > market_quantity)
11358 purchase = market_quantity;
11360 if (purchase * pricePerUnit > credits)
11362 purchase = floor (credits / pricePerUnit);
11365 if (unit ==
UNITS_TONS && purchase + current_cargo > [
self maxAvailableCargoSpace])
11367 purchase = [
self availableCargoSpace];
11371 if (current_cargo == [
self maxAvailableCargoSpace])
11400 [shipCommodityData addQuantity:purchase forGood:index];
11401 credits -= pricePerUnit * purchase;
11403 [
self calculateCurrentCargo];
11405 if ([
UNIVERSE autoSave]) [UNIVERSE setAutoSaveNow:YES];
11407 [
self doScriptEvent:OOJSID("playerBoughtCargo") withArguments:[NSArray arrayWithObjects:index, [NSNumber numberWithInt:purchase], [NSNumber numberWithUnsignedLongLong:pricePerUnit], nil]];
11408 if ([localMarket exportLegalityForGood:index] > 0)
11410 [roleWeightFlags setObject:[NSNumber numberWithInt:1] forKey:@"bought-illegal"];
11414 [roleWeightFlags setObject:[NSNumber numberWithInt:1] forKey:@"bought-legal"];
11423 if ([index isEqualToString:
@"<<<"] || [index isEqualToString:
@">>>"])
11429 if (![
self isDocked])
return NO;
11432 int available_units = [shipCommodityData quantityForGood:index];
11435 if (available_units == 0)
return NO;
11444 int contracted = [
self contractedVolumeForGood:index];
11445 if (available_units <= contracted)
11451 sell = available_units-contracted;
11455 if (sell > available_units)
11456 sell = available_units;
11457 if (sell + market_quantity > capacity)
11458 sell = capacity - market_quantity;
11463 [shipCommodityData removeQuantity:sell forGood:index];
11464 credits += pricePerUnit * sell;
11466 [
self calculateCurrentCargo];
11468 if ([
UNIVERSE autoSave]) [UNIVERSE setAutoSaveNow:YES];
11470 [
self doScriptEvent:OOJSID("playerSoldCargo") withArguments:[NSArray arrayWithObjects:index, [NSNumber numberWithInt:sell], [NSNumber numberWithUnsignedLongLong: pricePerUnit], nil]];
11478 return using_mining_laser;
11488- (BOOL) canAddEquipment:(NSString *)equipmentKey inContext:(NSString *)context
11490 if ([equipmentKey isEqualToString:
@"EQ_RENOVATION"] && !(ship_trade_in_factor < 85 || [[[
self shipSubEntityEnumerator] allObjects]
count] < [
self maxShipSubEntities])) return NO;
11491 if (![super canAddEquipment:equipmentKey inContext:context]) return NO;
11494 if (conditions !=
nil && ![
self scriptTestConditions:conditions]) return NO;
11500- (BOOL) addEquipmentItem:(NSString *)equipmentKey inContext:(NSString *)context
11502 return [
self addEquipmentItem:equipmentKey withValidation:YES inContext:context];
11506- (BOOL) addEquipmentItem:(NSString *)equipmentKey withValidation:(BOOL)validateAddition inContext:(NSString *)context
11509 if ([equipmentKey isEqualToString:
@"EQ_TRUMBLE"])
11520 [
self addTrumble:trumble[ranrot_rand() % PLAYER_MAX_TRUMBLES]];
11526 BOOL OK = [
super addEquipmentItem:equipmentKey withValidation:validateAddition inContext:context];
11530 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_COMPASS"] && [
self compassMode] == COMPASS_MODE_BASIC)
11532 [
self setCompassMode:COMPASS_MODE_PLANET];
11535 [
self addEqScriptForKey:equipmentKey];
11536 [
self addEquipmentWithScriptToCustomKeyArray:equipmentKey];
11542- (NSMutableArray *) customEquipmentActivation
11544 return customEquipActivation;
11548- (void) addEquipmentWithScriptToCustomKeyArray:(NSString *)equipmentKey
11550 NSDictionary *item;
11554 for (i = 0; i < [eqScripts count]; i++)
11556 if ([[[eqScripts oo_arrayAtIndex:i] oo_stringAtIndex:0] isEqualToString:equipmentKey])
11559 for (j = 0; j < [customEquipActivation count]; j++) {
11560 item = [customEquipActivation objectAtIndex:j];
11566 NSMutableDictionary *customKey = [[NSMutableDictionary alloc] initWithObjectsAndKeys:equipmentKey, CUSTOMEQUIP_EQUIPKEY, [eq
name], CUSTOMEQUIP_EQUIPNAME, nil];
11571 if ((
object !=
nil && [
object count] > 0))
11572 [customKey setObject:object forKey:CUSTOMEQUIP_KEYACTIVATE];
11575 if ((
object !=
nil && [
object count] > 0))
11576 [customKey setObject:object forKey:CUSTOMEQUIP_KEYMODE];
11578 [customEquipActivation addObject:customKey];
11579 [customKey release];
11581 [customActivatePressed addObject:[NSNumber numberWithBool:NO]];
11582 [customModePressed addObject:[NSNumber numberWithBool:NO]];
11584 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
11585 [defaults setObject:customEquipActivation forKey:KEYCONFIG_CUSTOMEQUIP];
11592- (void) validateCustomEquipActivationArray
11596 NSString *equipmentKey;
11597 if ([customEquipActivation
count] == 0)
return;
11598 for (i = [customEquipActivation
count] - 1; i >= 0; i--) {
11599 equipmentKey = [[customEquipActivation objectAtIndex:i] oo_stringForKey:CUSTOMEQUIP_EQUIPKEY];
11602 [customEquipActivation removeObjectAtIndex:i];
11603 [customActivatePressed removeObjectAtIndex:i];
11604 [customModePressed removeObjectAtIndex:i];
11609 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
11610 [defaults setObject:customEquipActivation forKey:KEYCONFIG_CUSTOMEQUIP];
11615- (void) removeEquipmentItem:(NSString *)equipmentKey
11617 if(![
self hasEquipmentItemProviding:
@"EQ_ADVANCED_COMPASS"] && [
self compassMode] != COMPASS_MODE_BASIC)
11619 [
self setCompassMode:COMPASS_MODE_BASIC];
11621 [
super removeEquipmentItem:equipmentKey];
11622 if(![
self hasEquipmentItem:equipmentKey]) {
11624 [
self removeEqScriptForKey:equipmentKey];
11629- (void) addEquipmentFromCollection:(
id)equipment
11631 NSDictionary *dict =
nil;
11632 NSEnumerator *eqEnum =
nil;
11633 NSString *eqDesc =
nil;
11634 NSUInteger i,
count;
11637 if ([equipment isKindOfClass:[NSDictionary class]])
11640 eqEnum = [equipment keyEnumerator];
11642 else if ([equipment isKindOfClass:[NSArray class]] || [equipment isKindOfClass:[NSSet class]])
11644 eqEnum = [equipment objectEnumerator];
11646 else if ([equipment isKindOfClass:[NSString class]])
11648 eqEnum = [[NSArray arrayWithObject:equipment] objectEnumerator];
11655 while ((eqDesc = [eqEnum nextObject]))
11670 if ([eqDesc isEqualToString:
@"EQ_TRUMBLE"]) continue;
11673 if (dict !=
nil && ![dict oo_boolForKey:eqDesc]) continue;
11680 count = [dict oo_unsignedIntegerForKey:eqDesc];
11681 for (i=0;i<
count;i++)
11683 [
self addEquipmentItem:eqDesc withValidation:NO inContext:@"loading"];
11688 if ([equipment isKindOfClass:[NSDictionary class]])
11690 eqEnum = [equipment keyEnumerator];
11692 else if ([equipment isKindOfClass:[NSArray class]] || [equipment isKindOfClass:[NSSet class]])
11694 eqEnum = [equipment objectEnumerator];
11696 else if ([equipment isKindOfClass:[NSString class]])
11698 eqEnum = [[NSArray arrayWithObject:equipment] objectEnumerator];
11701 while ((eqDesc = [eqEnum nextObject]))
11703 if (![
self equipmentValidToAdd:eqDesc whileLoading:YES inContext:
@"loading"])
11705 [
self removeEquipmentItem:eqDesc];
11711- (BOOL) hasOneEquipmentItem:(NSString *)itemKey includeMissiles:(BOOL)includeMissiles
11714 if ([super hasOneEquipmentItem:itemKey includeMissiles:NO whileLoading:NO]) return YES;
11717 if (includeMissiles)
11720 for (i = 0; i < max_missiles; i++)
11722 if ([[
self missileForPylon:i] hasPrimaryRole:itemKey]) return YES;
11726 if ([itemKey isEqualToString:
@"EQ_TRUMBLE"])
11728 return [
self trumbleCount] > 0;
11737 if ([[forward_weapon_type identifier] isEqualToString:[weaponType identifier]] ||
11738 [[aft_weapon_type identifier] isEqualToString:[weaponType identifier]] ||
11739 [[port_weapon_type identifier] isEqualToString:[weaponType identifier]] ||
11740 [[starboard_weapon_type identifier] isEqualToString:[weaponType identifier]])
11745 return [
super hasPrimaryWeapon:weaponType];
11755 for (i = 0; i < max_missiles; i++)
11757 if ([[
self missileForPylon:i] hasPrimaryRole:identifier])
11759 [
self removeFromPylon:i];
11769- (BOOL) removeFromPylon:(NSUInteger)pylon
11771 if (pylon >= max_missiles)
return NO;
11773 if (missile_entity[pylon] !=
nil)
11775 NSString *identifier = [missile_entity[pylon] primaryRole];
11779 [missile_entity[pylon] release];
11780 missile_entity[pylon] =
nil;
11782 [
self tidyMissilePylons];
11785 if (pylon <= activeMissile)
11787 if (activeMissile == missiles && missiles > 0) activeMissile--;
11788 if (activeMissile > 0) activeMissile--;
11789 else activeMissile = max_missiles - 1;
11791 [
self selectNextMissile];
11801- (NSUInteger) parcelCount
11803 return [parcels count];
11807- (NSUInteger) passengerCount
11809 return [passengers count];
11813- (NSUInteger) passengerCapacity
11815 return max_passengers;
11819- (BOOL) hasHostileTarget
11821 ShipEntity *playersTarget = [
self primaryTarget];
11822 return ([playersTarget isShip] && [playersTarget hasHostileTarget] && [playersTarget primaryTarget] ==
self);
11826- (void) receiveCommsMessage:(NSString *) message_text from:(
ShipEntity *) other
11828 if ([
self status] == STATUS_DEAD || [
self status] == STATUS_DOCKED)
11833 [UNIVERSE addCommsMessage:[NSString stringWithFormat:@"%@:\n %@", [other
displayName], message_text] forCount:4.5];
11834 [
super receiveCommsMessage:message_text from:other];
11840 if (legalStatus == 0)
return;
11842 OOGovernmentID local_gov = [[UNIVERSE currentSystemData] oo_intForKey:KEY_GOVERNMENT];
11843 if ([
UNIVERSE inInterstellarSpace]) local_gov = 1;
11845 fine *= legalStatus;
11846 if (fine > credits)
11848 int payback = (
int)(legalStatus * credits / fine);
11849 [
self setBounty:(legalStatus-payback) withReason:kOOLegalStatusReasonPaidFine];
11854 [
self setBounty:0 withReason:kOOLegalStatusReasonPaidFine];
11859 NSString *fined_message = [NSString stringWithFormat:OOExpandKey(@"fined-@-credits"), OOCredits(fine)];
11860 [
self addMessageToReport:fined_message];
11861 [UNIVERSE forceWitchspaceEntries];
11862 ship_clock_adjust += 24 * 3600;
11866- (void) adjustTradeInFactorBy:(
int)value
11868 ship_trade_in_factor += value;
11869 if (ship_trade_in_factor < 75) ship_trade_in_factor = 75;
11870 if (ship_trade_in_factor > 100) ship_trade_in_factor = 100;
11874- (
int) tradeInFactor
11876 return ship_trade_in_factor;
11880- (double) renovationCosts
11883 OOCreditsQuantity shipValue = [UNIVERSE tradeInValueForCommanderDictionary:[
self commanderDataDictionary]];
11885 double costs = 0.005 * (100 - ship_trade_in_factor) * shipValue;
11886 costs += 0.01 * shipValue * [
self missingSubEntitiesAdjustment];
11887 costs *= [
self renovationFactor];
11892- (double) renovationFactor
11896 return [shipyardInfo oo_doubleForKey:KEY_RENOVATION_MULTIPLIER defaultValue:1.0];
11900- (void) setDefaultViewOffsets
11902 float halfLength = 0.5f * (boundingBox.max.z - boundingBox.min.z);
11903 float halfWidth = 0.5f * (boundingBox.max.x - boundingBox.min.
x);
11905 forwardViewOffset = make_vector(0.0f, 0.0f, boundingBox.max.z - halfLength);
11906 aftViewOffset = make_vector(0.0f, 0.0f, boundingBox.min.z + halfLength);
11907 portViewOffset = make_vector(boundingBox.min.x + halfWidth, 0.0f, 0.0f);
11908 starboardViewOffset = make_vector(boundingBox.max.x - halfWidth, 0.0f, 0.0f);
11913- (void) setDefaultCustomViews
11917 [_customViews release];
11918 _customViews =
nil;
11919 _customViewIndex = 0;
11920 if (customViews !=
nil)
11922 _customViews = [customViews retain];
11927- (Vector) weaponViewOffset
11929 switch (currentWeaponFacing)
11932 return forwardViewOffset;
11934 return aftViewOffset;
11936 return portViewOffset;
11938 return starboardViewOffset;
11942 return customViewOffset;
11948- (void) setUpTrumbles
11950 NSMutableString *trumbleDigrams = [NSMutableString stringWithCapacity:256];
11951 unichar xchar = (unichar)0;
11952 unichar digramchars[2];
11956 NSString *commanderName = [
self commanderName];
11957 if ([commanderName length] > 0)
11959 [trumbleDigrams appendFormat:@"%@%@", commanderName, [[
self mesh] modelName]];
11963 [trumbleDigrams appendString:@"Some Random Text!"];
11969 digramchars[0] = ([trumbleDigrams characterAtIndex:i] & 0x007f) | 0x0020;
11970 digramchars[1] = (([trumbleDigrams characterAtIndex:i + 1] ^ xchar) & 0x007f) | 0x0020;
11971 xchar = digramchars[0];
11972 NSString *digramstring = [NSString stringWithCharacters:digramchars length:2];
11973 [trumble[i] release];
11974 trumble[i] = [[
OOTrumble alloc] initForPlayer:self digram:digramstring];
11979 [
self setTrumbleAppetiteAccumulator:0.0f];
11983- (void) addTrumble:(
OOTrumble *)papaTrumble
11989 OOTrumble *trumblePup = trumble[trumbleCount];
11995- (void) removeTrumble:(
OOTrumble *)deadTrumble
11997 if (trumbleCount <= 0)
12001 NSUInteger trumble_index = NSNotFound;
12004 for (i = 0; (trumble_index == NSNotFound)&&(i < trumbleCount); i++)
12006 if (trumble[i] == deadTrumble)
12009 if (trumble_index == NSNotFound)
12011 OOLog(
@"trumble.zombie",
@"DEBUG can't get rid of inactive trumble %@", deadTrumble);
12015 trumble[trumble_index] = trumble[trumbleCount];
12016 trumble[trumbleCount] = deadTrumble;
12026- (NSUInteger) trumbleCount
12028 return trumbleCount;
12034 NSString *namekey = [NSString stringWithFormat:@"%@-humbletrash", [
self commanderName]];
12038 [
self mungChecksumWithNSString:[
self commanderName]];
12043 [[NSUserDefaults standardUserDefaults] setInteger:trumbleHash forKey:namekey];
12046 NSMutableArray *trumbleArray = [NSMutableArray arrayWithCapacity:PLAYER_MAX_TRUMBLES];
12049 [trumbleArray addObject:[trumble[i] dictionary]];
12052 return [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInteger:trumbleCount], [NSNumber numberWithInt:trumbleHash], trumbleArray, nil];
12056- (void) setTrumbleValueFrom:(NSObject*) trumbleValue
12058 BOOL info_failed = NO;
12060 int putativeHash = 0;
12061 int putativeNTrumbles = 0;
12062 NSArray *putativeTrumbleArray =
nil;
12064 NSString *namekey = [NSString stringWithFormat:@"%@-humbletrash", [
self commanderName]];
12066 [
self setUpTrumbles];
12070 BOOL possible_cheat = NO;
12071 if (![trumbleValue isKindOfClass:[NSArray class]])
12075 NSArray* values = (NSArray*) trumbleValue;
12076 if ([values
count] >= 1)
12077 putativeNTrumbles = [values oo_intAtIndex:0];
12078 if ([values
count] >= 2)
12079 putativeHash = [values oo_intAtIndex:1];
12080 if ([values
count] >= 3)
12081 putativeTrumbleArray = [values oo_arrayAtIndex:2];
12085 [
self mungChecksumWithNSString:[
self commanderName]];
12090 if (putativeHash != trumbleHash)
12095 OOLog(
@"cheat.tentative",
@"%@",
@"POSSIBLE CHEAT DETECTED");
12096 possible_cheat = YES;
12103 [
self mungChecksumWithNSString:[
self commanderName]];
12107 if (putativeHash == trumbleHash)
12110 putativeNTrumbles = i;
12114 if (possible_cheat && !info_failed)
12115 OOLog(
@"cheat.verified",
@"%@",
@"CHEAT DEFEATED - that's not the way to get rid of trumbles!");
12121 OOLog(
@"cheat.tentative",
@"%@",
@"POSSIBLE CHEAT DETECTED");
12125 if (info_failed && [[NSUserDefaults standardUserDefaults] objectForKey:namekey])
12128 putativeHash = (
int)[[NSUserDefaults standardUserDefaults] integerForKey:namekey];
12132 [
self mungChecksumWithNSString:[
self commanderName]];
12136 if (putativeHash == trumbleHash)
12139 putativeNTrumbles = i;
12144 OOLog(
@"cheat.verified",
@"%@",
@"CHEAT DEFEATED - that's not the way to get rid of trumbles!");
12147 trumbleCount = putativeNTrumbles;
12152 [trumble[i] setFromDictionary:[putativeTrumbleArray oo_dictionaryAtIndex:i]];
12156 [
self mungChecksumWithNSString:[
self commanderName]];
12161 [[NSUserDefaults standardUserDefaults] setInteger:trumbleHash forKey:namekey];
12165- (float) trumbleAppetiteAccumulator
12167 return _trumbleAppetiteAccumulator;
12171- (void) setTrumbleAppetiteAccumulator:(
float)value
12173 _trumbleAppetiteAccumulator = value;
12177- (void) mungChecksumWithNSString:(NSString *)str
12179 if (str ==
nil)
return;
12181 NSUInteger i, length = [str length];
12182 for (i = 0; i < length; i++)
12189- (NSString *) screenModeStringForWidth:(
unsigned)width height:(
unsigned)height refreshRate:(
float)refreshRate
12191 if (0.0f != refreshRate)
12193 return OOExpandKey(
@"gameoptions-fullscreen-with-refresh-rate", width, height, refreshRate);
12197 return OOExpandKey(
@"gameoptions-fullscreen", width, height);
12202- (void) suppressTargetLost
12204 suppressTargetLost = YES;
12208- (void) setScoopsActive
12210 scoopsActive = YES;
12215- (void) setFoundTarget:(
Entity *) targetEntity
12219 if ([
self status] == STATUS_ESCAPE_SEQUENCE)
12223 [_foundTarget release];
12229- (void) addTarget:(
Entity *) targetEntity
12231 if ([
self status] != STATUS_IN_FLIGHT && [
self status] != STATUS_WITCHSPACE_COUNTDOWN)
return;
12232 if (targetEntity ==
self)
return;
12234 [
super addTarget:targetEntity];
12236 if ([targetEntity isWormhole])
12238 assert ([
self hasEquipmentItemProviding:
@"EQ_WORMHOLE_SCANNER"]);
12239 [
self addScannedWormhole:(WormholeEntity*)targetEntity];
12242 else if ([
self hasEquipmentItemProviding:
@"EQ_TARGET_MEMORY"] && targetEntity !=
nil)
12245 NSUInteger i = [target_memory indexOfObject:targetRef];
12247 if (i != NSNotFound)
12249 target_memory_index = i;
12253 i = [target_memory indexOfObject:[NSNull null]];
12255 if (i != NSNotFound)
12257 [target_memory replaceObjectAtIndex:i withObject:targetRef];
12258 target_memory_index = i;
12264 [target_memory replaceObjectAtIndex:target_memory_index withObject:targetRef];
12271 [
self playIdentLockedOn];
12272 [
self printIdentLockedOnForMissile:NO];
12274 else if ([targetEntity isShip] && [
self weaponsOnline])
12276 if ([missile_entity[activeMissile] isMissile])
12279 [missile_entity[activeMissile] addTarget:targetEntity];
12280 [
self playMissileLockedOn];
12281 [
self printIdentLockedOnForMissile:YES];
12286 [
self playIdentLockedOn];
12287 [
self printIdentLockedOnForMissile:NO];
12293- (void) clearTargetMemory
12295 NSUInteger memoryCount = [target_memory count];
12298 if (i < memoryCount)
12300 [target_memory replaceObjectAtIndex:i withObject:[NSNull null]];
12304 [target_memory addObject:[NSNull null]];
12307 target_memory_index = 0;
12311- (NSMutableArray *) targetMemory
12313 return target_memory;
12316- (BOOL) moveTargetMemoryBy:(NSInteger)delta
12321 NSInteger idx = (NSInteger)target_memory_index + delta;
12324 target_memory_index = idx;
12326 id targ_id = [target_memory objectAtIndex:target_memory_index];
12327 if ([targ_id isProxy])
12331 if ((potential_target)&&(potential_target->
isShip)&&([potential_target isInSpace]))
12335 [
super addTarget:potential_target];
12338 if( [missile_entity[activeMissile] isMissile])
12340 [missile_entity[activeMissile] addTarget:potential_target];
12342 [
self printIdentLockedOnForMissile:YES];
12347 [
self playIdentLockedOn];
12348 [
self printIdentLockedOnForMissile:NO];
12353 ident_engaged = YES;
12354 [
self printIdentLockedOnForMissile:NO];
12356 [
self playTargetSwitched];
12362 [target_memory replaceObjectAtIndex:target_memory_index withObject:[NSNull null]];
12367 [
self playNoTargetInMemory];
12372- (void) printIdentLockedOnForMissile:(BOOL)missile
12374 if ([
self primaryTarget] ==
nil)
return;
12376 NSString *fmt = missile ?
@"missile-locked-onto-target" :
@"ident-locked-onto-target";
12377 NSString *target = [[
self primaryTarget] identFromShip:self];
12378 [UNIVERSE addMessage:OOExpandKey(fmt, target) forCount:4.5];
12382- (Quaternion) customViewQuaternion
12384 return customViewQuaternion;
12388- (void) setCustomViewQuaternion:(Quaternion)q
12390 customViewQuaternion = q;
12391 [
self setCustomViewData];
12395- (OOMatrix) customViewMatrix
12397 return customViewMatrix;
12401- (Vector) customViewOffset
12403 return customViewOffset;
12407- (void) setCustomViewOffset:(Vector) offset
12409 customViewOffset =
offset;
12413- (Vector) customViewRotationCenter
12415 return customViewRotationCenter;
12419- (void) setCustomViewRotationCenter:(Vector) center
12421 customViewRotationCenter = center;
12425- (void) customViewZoomIn:(
OOScalar) rate
12427 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12428 customViewOffset = vector_multiply_scalar(customViewOffset, 1.0/rate);
12429 OOScalar m = magnitude(customViewOffset);
12434 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12438- (void) customViewZoomOut:(
OOScalar) rate
12440 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12441 customViewOffset = vector_multiply_scalar(customViewOffset, rate);
12442 OOScalar m = magnitude(customViewOffset);
12447 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12451- (void) customViewRotateLeft:(
OOScalar) angle
12453 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12454 OOScalar m = magnitude(customViewOffset);
12456 [
self setCustomViewData];
12457 customViewOffset = vector_flip(customViewForwardVector);
12458 scale_vector(&customViewOffset, m / magnitude(customViewOffset));
12459 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12463- (void) customViewRotateRight:(
OOScalar) angle
12465 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12466 OOScalar m = magnitude(customViewOffset);
12468 [
self setCustomViewData];
12469 customViewOffset = vector_flip(customViewForwardVector);
12470 scale_vector(&customViewOffset, m / magnitude(customViewOffset));
12471 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12475- (void) customViewRotateUp:(
OOScalar) angle
12477 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12478 OOScalar m = magnitude(customViewOffset);
12480 [
self setCustomViewData];
12481 customViewOffset = vector_flip(customViewForwardVector);
12482 scale_vector(&customViewOffset, m / magnitude(customViewOffset));
12483 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12487- (void) customViewRotateDown:(
OOScalar) angle
12489 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12490 OOScalar m = magnitude(customViewOffset);
12492 [
self setCustomViewData];
12493 customViewOffset = vector_flip(customViewForwardVector);
12494 scale_vector(&customViewOffset, m / magnitude(customViewOffset));
12495 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12499- (void) customViewRollRight:(
OOScalar) angle
12501 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12502 OOScalar m = magnitude(customViewOffset);
12504 [
self setCustomViewData];
12505 customViewOffset = vector_flip(customViewForwardVector);
12506 scale_vector(&customViewOffset, m / magnitude(customViewOffset));
12507 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12511- (void) customViewRollLeft:(
OOScalar) angle
12513 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12514 OOScalar m = magnitude(customViewOffset);
12516 [
self setCustomViewData];
12517 customViewOffset = vector_flip(customViewForwardVector);
12518 scale_vector(&customViewOffset, m / magnitude(customViewOffset));
12519 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12523- (void) customViewPanUp:(
OOScalar) angle
12526 [
self setCustomViewData];
12527 customViewRotationCenter = vector_subtract(customViewOffset, vector_multiply_scalar(customViewForwardVector, dot_product(customViewOffset, customViewForwardVector)));
12531- (void) customViewPanDown:(
OOScalar) angle
12534 [
self setCustomViewData];
12535 customViewRotationCenter = vector_subtract(customViewOffset, vector_multiply_scalar(customViewForwardVector, dot_product(customViewOffset, customViewForwardVector)));
12539- (void) customViewPanLeft:(
OOScalar) angle
12542 [
self setCustomViewData];
12543 customViewRotationCenter = vector_subtract(customViewOffset, vector_multiply_scalar(customViewForwardVector, dot_product(customViewOffset, customViewForwardVector)));
12547- (void) customViewPanRight:(
OOScalar) angle
12550 [
self setCustomViewData];
12551 customViewRotationCenter = vector_subtract(customViewOffset, vector_multiply_scalar(customViewForwardVector, dot_product(customViewOffset, customViewForwardVector)));
12555- (Vector) customViewForwardVector
12557 return customViewForwardVector;
12561- (Vector) customViewUpVector
12563 return customViewUpVector;
12567- (Vector) customViewRightVector
12569 return customViewRightVector;
12573- (NSString *) customViewDescription
12575 return customViewDescription;
12579- (void) resetCustomView
12581 [
self setCustomViewDataFromDictionary:[_customViews oo_dictionaryAtIndex:_customViewIndex] withScaling:NO];
12585- (void) setCustomViewData
12591 Quaternion q1 = customViewQuaternion;
12596- (void) setCustomViewDataFromDictionary:(NSDictionary *)viewDict withScaling:(BOOL)withScaling
12600 if (viewDict ==
nil)
return;
12602 customViewQuaternion = [viewDict oo_quaternionForKey:@"view_orientation"];
12603 [
self setCustomViewData];
12608 customViewOffset = vector_multiply_scalar([viewDict oo_vectorForKey:
@"view_position"],_scaleFactor);
12613 customViewOffset = [viewDict oo_vectorForKey:@"view_position"];
12615 customViewRotationCenter = vector_subtract(customViewOffset, vector_multiply_scalar(customViewForwardVector, dot_product(customViewOffset, customViewForwardVector)));
12616 customViewDescription = [viewDict oo_stringForKey:@"view_description"];
12618 NSString *facing = [[viewDict oo_stringForKey:@"weapon_facing"] lowercaseString];
12619 if ([facing isEqual:
@"aft"])
12623 else if ([facing isEqual:
@"port"])
12627 else if ([facing isEqual:
@"starboard"])
12631 else if ([facing isEqual:
@"forward"])
12640- (BOOL) showInfoFlag
12642 return show_info_flag;
12646- (NSDictionary *) missionOverlayDescriptor
12648 return _missionOverlayDescriptor;
12652- (NSDictionary *) missionOverlayDescriptorOrDefault
12654 NSDictionary *result = [
self missionOverlayDescriptor];
12657 if ([[
self missionTitle] length] == 0)
12659 result = [UNIVERSE screenTextureDescriptorForKey:@"mission_overlay_no_title"];
12663 result = [UNIVERSE screenTextureDescriptorForKey:@"mission_overlay_with_title"];
12671- (void) setMissionOverlayDescriptor:(NSDictionary *)descriptor
12673 if (descriptor != _missionOverlayDescriptor)
12675 [_missionOverlayDescriptor autorelease];
12676 _missionOverlayDescriptor = [descriptor copy];
12681- (NSDictionary *) missionBackgroundDescriptor
12683 return _missionBackgroundDescriptor;
12687- (NSDictionary *) missionBackgroundDescriptorOrDefault
12689 NSDictionary *result = [
self missionBackgroundDescriptor];
12692 result = [UNIVERSE screenTextureDescriptorForKey:@"mission"];
12699- (void) setMissionBackgroundDescriptor:(NSDictionary *)descriptor
12701 if (descriptor != _missionBackgroundDescriptor)
12703 [_missionBackgroundDescriptor autorelease];
12704 _missionBackgroundDescriptor = [descriptor copy];
12711 return _missionBackgroundSpecial;
12715- (void) setMissionBackgroundSpecial:(NSString *)special
12717 if (special ==
nil) {
12720 else if ([special isEqualToString:
@"SHORT_RANGE_CHART"])
12724 else if ([special isEqualToString:
@"SHORT_RANGE_CHART_SHORTEST"])
12726 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_NAVIGATIONAL_ARRAY"])
12735 else if ([special isEqualToString:
@"SHORT_RANGE_CHART_QUICKEST"])
12737 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_NAVIGATIONAL_ARRAY"])
12746 else if ([special isEqualToString:
@"CUSTOM_CHART"])
12750 else if ([special isEqualToString:
@"CUSTOM_CHART_SHORTEST"])
12752 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_NAVIGATIONAL_ARRAY"])
12761 else if ([special isEqualToString:
@"CUSTOM_CHART_QUICKEST"])
12763 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_NAVIGATIONAL_ARRAY"])
12772 else if ([special isEqualToString:
@"LONG_RANGE_CHART"])
12776 else if ([special isEqualToString:
@"LONG_RANGE_CHART_SHORTEST"])
12778 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_NAVIGATIONAL_ARRAY"])
12787 else if ([special isEqualToString:
@"LONG_RANGE_CHART_QUICKEST"])
12789 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_NAVIGATIONAL_ARRAY"])
12807 _missionExitScreen = screen;
12813 return _missionExitScreen;
12817- (NSDictionary *) equipScreenBackgroundDescriptor
12819 return _equipScreenBackgroundDescriptor;
12823- (void) setEquipScreenBackgroundDescriptor:(NSDictionary *)descriptor
12825 if (descriptor != _equipScreenBackgroundDescriptor)
12827 [_equipScreenBackgroundDescriptor autorelease];
12828 _equipScreenBackgroundDescriptor = [descriptor copy];
12833- (BOOL) scriptsLoaded
12835 return worldScripts !=
nil && [worldScripts count] > 0;
12839- (NSArray *) worldScriptNames
12841 return [worldScripts allKeys];
12845- (NSDictionary *) worldScriptsByName
12847 return [[worldScripts copy] autorelease];
12851- (
OOScript *) commodityScriptNamed:(NSString *)scriptName
12853 if (scriptName ==
nil)
12858 if ((cscript = [commodityScripts objectForKey:scriptName]))
12863 if (cscript !=
nil)
12866 [commodityScripts setObject:cscript forKey:scriptName];
12870 OOLog(
@"script.commodityScript.load",
@"Could not load script %@",scriptName);
12876- (void) doScriptEvent:(jsid)message inContext:(JSContext *)context withArguments:(jsval *)argv count:(uintN)argc
12878 [
super doScriptEvent:message inContext:context withArguments:argv count:argc];
12879 [
self doWorldScriptEvent:message inContext:context withArguments:argv count:argc timeLimit:0.0];
12883- (BOOL) doWorldEventUntilMissionScreen:(jsid)message
12885 NSEnumerator *scriptEnum = [worldScripts objectEnumerator];
12889 if (gui_screen != GUI_SCREEN_MISSION && [dockingReport length] > 0 && [
self isDocked] && ![[
self dockedStation] suppressArrivalReports])
12891 [
self setGuiToDockingReportScreen];
12892 [[UNIVERSE messageGUI] clear];
12897 while ((theScript = [scriptEnum nextObject]) && gui_screen != GUI_SCREEN_MISSION && [
self isDocked])
12903 if (gui_screen == GUI_SCREEN_MISSION)
12906 [[UNIVERSE messageGUI] clear];
12914- (void) doWorldScriptEvent:(jsid)message inContext:(JSContext *)context withArguments:(jsval *)argv count:(uintN)argc timeLimit:(
OOTimeDelta)limit
12918 NSEnumerator *scriptEnum =
nil;
12921 for (scriptEnum = [worldScripts objectEnumerator]; (theScript = [scriptEnum nextObject]); )
12934 galacticHyperspaceBehaviour = inBehaviour;
12941 return galacticHyperspaceBehaviour;
12945- (void) setGalacticHyperspaceFixedCoords:(NSPoint)point
12947 return [
self setGalacticHyperspaceFixedCoordsX:OOClamp_0_max_f(round(point.x), 255.0f) y:OOClamp_0_max_f(round(point.y), 255.0f)];
12951- (void) setGalacticHyperspaceFixedCoordsX:(
unsigned char)x y:(
unsigned char)y
12953 galacticHyperspaceFixedCoords.x =
x;
12954 galacticHyperspaceFixedCoords.y =
y;
12958- (NSPoint) galacticHyperspaceFixedCoords
12960 return galacticHyperspaceFixedCoords;
12964- (void) setWitchspaceCountdown:(
int)spin_time
12966 witchspaceCountdown = spin_time;
12971 return longRangeChartMode;
12977 longRangeChartMode =
mode;
12981- (BOOL) scoopOverride
12983 return scoopOverride;
12987- (void) setScoopOverride:(BOOL)newValue
12989 scoopOverride = !!newValue;
12990 if (scoopOverride) [
self setScoopsActive];
12994#if MASS_DEPENDENT_FUEL_PRICES
12995- (GLfloat) fuelChargeRate
12997 GLfloat rate = 1.0;
12999 rate = [
super fuelChargeRate];
13002 if (
EXPECT(ship_trade_in_factor <= 90 && ship_trade_in_factor >= 75))
13004 rate *= 2.0 - (ship_trade_in_factor / 100);
13015if ([entity isStation]) _dockTarget = [entity
universalID];
13021- (NSString *) jumpCause
13027- (void) setJumpCause:(NSString *)value
13029 NSParameterAssert(value !=
nil);
13030 [_jumpCause autorelease];
13031 _jumpCause = [value copy];
13035- (NSString *) commanderName
13037 return _commanderName;
13041- (NSString *) lastsaveName
13043 return _lastsaveName;
13047- (void) setCommanderName:(NSString *)value
13049 NSParameterAssert(value !=
nil);
13050 [_commanderName autorelease];
13051 _commanderName = [value copy];
13055- (void) setLastsaveName:(NSString *)value
13057 NSParameterAssert(value !=
nil);
13058 [_lastsaveName autorelease];
13059 _lastsaveName = [value copy];
13065 BOOL isDockedStatus = NO;
13067 switch ([
self status])
13069 case STATUS_DOCKED:
13070 case STATUS_DOCKING:
13071 case STATUS_START_GAME:
13072 isDockedStatus = YES;
13075 case STATUS_RESTART_GAME:
13077 case STATUS_EFFECT:
13078 case STATUS_ACTIVE:
13079 case STATUS_COCKPIT_DISPLAY:
13081 case STATUS_INACTIVE:
13083 case STATUS_IN_FLIGHT:
13084 case STATUS_AUTOPILOT_ENGAGED:
13085 case STATUS_LAUNCHING:
13086 case STATUS_WITCHSPACE_COUNTDOWN:
13087 case STATUS_ENTERING_WITCHSPACE:
13088 case STATUS_EXITING_WITCHSPACE:
13089 case STATUS_ESCAPE_SEQUENCE:
13090 case STATUS_IN_HOLD:
13091 case STATUS_BEING_SCOOPED:
13092 case STATUS_HANDLING_ERROR:
13099 if (isDockedStatus)
13101 if ([
self dockedStation] ==
nil)
13105 [
self setStatus:STATUS_IN_FLIGHT];
13106 isDockedStatus = NO;
13111 if ([
self dockedStation] !=
nil && [
self status] != STATUS_LAUNCHING)
13114 [
self setStatus:STATUS_DOCKED];
13115 isDockedStatus = YES;
13120 return isDockedStatus;
13124- (BOOL)clearedToDock
13132 dockingClearanceStatus = newValue;
13135 targetDockStation =
nil;
13139 if ([[
self primaryTarget] isStation])
13141 targetDockStation = [
self primaryTarget];
13145 OOLog(
@"player.badDockingTarget",
@"Attempt to dock at %@.", [
self primaryTarget]);
13146 targetDockStation =
nil;
13154 return dockingClearanceStatus;
13158- (void)penaltyForUnauthorizedDocking
13164 if ([
self clearedToDock])
13167 amountToPay =
MIN(maximumFine, calculatedFine);
13168 credits -= amountToPay;
13169 [
self addMessageToReport:[NSString stringWithFormat:DESC(@"station-docking-clearance-fined-@-cr"), OOCredits(amountToPay)]];
13178 assert(scannedWormholes !=
nil);
13179 assert(whole !=
nil);
13182 NSEnumerator *wormholes = [scannedWormholes objectEnumerator];
13184 while ((wh = [wormholes nextObject]))
13186 if (wh == whole)
return;
13189 [scannedWormholes addObject:whole];
13197 assert(scannedWormholes !=
nil);
13199 if ([scannedWormholes
count] == 0)
13202 double now = [
self clockTimeAdjusted];
13204 NSMutableArray * savedWormholes = [[NSMutableArray alloc] initWithCapacity:[scannedWormholes count]];
13205 NSEnumerator * wormholes = [scannedWormholes objectEnumerator];
13212 if ([wh arrivalTime] > now)
13214 [savedWormholes addObject:wh];
13216 else if (NSEqualPoints(galaxy_coordinates, [wh destinationCoordinates]))
13219 if ([[wh shipsInTransit]
count] > 0)
13221 [savedWormholes addObject:wh];
13227 [scannedWormholes release];
13228 scannedWormholes = savedWormholes;
13232- (NSArray *) scannedWormholes
13234 return [NSArray arrayWithArray:scannedWormholes];
13238- (void) initialiseMissionDestinations:(NSDictionary *)destinations andLegacy:(NSArray *)legacy
13240 NSEnumerator *keyEnum =
nil;
13241 NSString *key =
nil;
13246 [missionDestinations release];
13247 missionDestinations = [[NSMutableDictionary alloc] init];
13249 for (keyEnum = [destinations keyEnumerator]; (key = [keyEnum nextObject]); )
13251 value = [destinations objectForKey:key];
13254 if ([value isKindOfClass:[NSDictionary class]])
13256 value = [value mutableCopy];
13257 [missionDestinations setObject:value forKey:key];
13266 NSNumber *legacyMarker;
13267 for (keyEnum = [legacy objectEnumerator]; (legacyMarker = [keyEnum nextObject]); )
13269 dest = [legacyMarker intValue];
13270 [
self addMissionDestinationMarker:[
self defaultMarker:dest]];
13277- (NSString *)markerKey:(NSDictionary *)marker
13279 return [NSString stringWithFormat:@"%d-%@",[marker oo_intForKey:@"system"], [marker oo_stringForKey:@"name"]];
13283- (void) addMissionDestinationMarker:(NSDictionary *)marker
13285 NSDictionary *validated = [
self validatedMarker:marker];
13286 if (validated ==
nil)
13291 [missionDestinations setObject:validated forKey:[
self markerKey:validated]];
13295- (BOOL) removeMissionDestinationMarker:(NSDictionary *)marker
13297 NSDictionary *validated = [
self validatedMarker:marker];
13298 if (validated ==
nil)
13303 if ([missionDestinations objectForKey:[
self markerKey:validated]] !=
nil) {
13306 [missionDestinations removeObjectForKey:[
self markerKey:validated]];
13311- (NSMutableDictionary*) getMissionDestinations
13313 return missionDestinations;
13317- (NSMutableDictionary*) shipyardRecord
13319 return shipyard_record;
13323- (void) setLastShot:(NSArray *)shot
13325 lastShot = [shot retain];
13329- (void) clearExtraMissionKeys
13331 [extraMissionKeys release];
13332 extraMissionKeys =
nil;
13336- (void) setExtraMissionKeys:(NSDictionary *)keys
13338 NSString *key =
nil;
13339 NSMutableDictionary *
final = [[NSMutableDictionary alloc] init];
13340 foreach (key, [keys allKeys])
13342 [final setObject:[
self processKeyCode:[keys oo_arrayForKey:key]] forKey:key];
13344 extraMissionKeys = [final copy];
13349- (void) clearExtraGuiScreenKeys:(
OOGUIScreenID)gui key:(NSString *)key
13351 NSMutableArray *keydefs = [extraGuiScreenKeys objectForKey:[NSString stringWithFormat:@"%d",gui]];
13352 NSInteger i = [keydefs count];
13353 NSDictionary *def =
nil;
13356 def = [keydefs objectAtIndex:i];
13357 if (def && [[def oo_stringForKey:
@"name"] isEqualToString:key])
13359 [keydefs removeObjectAtIndex:i];
13371 NSMutableArray *newarray =
nil;
13372 NSString *key =
nil;
13373 NSMutableDictionary *
final = [[NSMutableDictionary alloc] init];
13375 NSMutableArray *checklist = [[NSMutableArray alloc] init];
13377 foreach (key, [keys allKeys])
13379 NSArray *item = [
self processKeyCode:[keys oo_arrayForKey:key]];
13380 [checklist addObject:item];
13381 [final setObject:item forKey:key];
13387 if (!extraGuiScreenKeys)
13389 extraGuiScreenKeys = [[NSMutableDictionary alloc] init];
13392 if (![extraGuiScreenKeys objectForKey:[NSString stringWithFormat:
@"%d",gui]])
13395 newarray = [[NSMutableArray alloc] init];
13399 newarray = [[extraGuiScreenKeys objectForKey:[NSString stringWithFormat:@"%d",gui]] mutableCopy];
13400 NSInteger i = [newarray count];
13405 def_existing = [newarray objectAtIndex:i];
13407 if (def_existing && [[def_existing name] isEqualToString:[definition name]])
13409 [newarray removeObjectAtIndex:i];
13415 j = [checklist count];
13416 foreach (key, [keydefs allKeys])
13420 if ([[NSString stringWithFormat:
@"%@",[keydefs objectForKey:key]] isEqualToString:[NSString stringWithFormat:
@"%@",[checklist objectAtIndex:j]]])
13423 OOLog(
kOOLogException,
@"***** Exception in setExtraGuiScreenKeys: %@ : %@ (%@)",
@"invalid key settings",
@"key already in use", key);
13430 [newarray addObject:definition];
13432 if (result) [extraGuiScreenKeys setObject:[newarray mutableCopy] forKey:[NSString stringWithFormat:@"%d",gui]];
13433 [newarray release];
13439- (void)dumpSelfState
13441 NSMutableArray *flags =
nil;
13442 NSString *flagsString =
nil;
13444 [
super dumpSelfState];
13446 OOLog(
@"dumpState.playerEntity",
@"Script time: %g", script_time);
13447 OOLog(
@"dumpState.playerEntity",
@"Script time check: %g", script_time_check);
13448 OOLog(
@"dumpState.playerEntity",
@"Script time interval: %g", script_time_interval);
13449 OOLog(
@"dumpState.playerEntity",
@"Roll/pitch/yaw delta: %g, %g, %g", roll_delta, pitch_delta, yaw_delta);
13450 OOLog(
@"dumpState.playerEntity",
@"Shield: %g fore, %g aft", forward_shield, aft_shield);
13451 OOLog(
@"dumpState.playerEntity",
@"Alert level: %u, flags: %#x", alertFlags, alertCondition);
13452 OOLog(
@"dumpState.playerEntity",
@"Missile status: %i", missile_status);
13454 OOLog(
@"dumpState.playerEntity",
@"Fuel leak rate: %g", fuel_leak_rate);
13455 OOLog(
@"dumpState.playerEntity",
@"Trumble count: %lu", trumbleCount);
13457 flags = [NSMutableArray array];
13458 #define ADD_FLAG_IF_SET(x) if (x) { [flags addObject:@#x]; }
13487 flagsString = [flags count] ? [flags componentsJoinedByString:@", "] : (NSString *)
@"none";
13488 OOLog(
@"dumpState.playerEntity",
@"Flags: %@", flagsString);
13499- (BOOL) suppressClangStuff
13501 return missionChoice &&
13502 commanderNameString &&
13506 n_key_roll_right &&
13507 n_key_pitch_forward &&
13508 n_key_pitch_back &&
13511 n_key_view_forward &&
13514 n_key_view_starboard &&
13515 n_key_launch_ship &&
13516 n_key_gui_screen_options &&
13517 n_key_gui_screen_equipship &&
13518 n_key_gui_screen_interfaces &&
13519 n_key_gui_screen_status &&
13520 n_key_gui_chart_screens &&
13521 n_key_gui_system_data &&
13522 n_key_gui_market &&
13523 n_key_gui_arrow_left &&
13524 n_key_gui_arrow_right &&
13525 n_key_gui_arrow_up &&
13526 n_key_gui_arrow_down &&
13527 n_key_gui_page_up &&
13528 n_key_gui_page_down &&
13529 n_key_gui_select &&
13530 n_key_increase_speed &&
13531 n_key_decrease_speed &&
13532 n_key_inject_fuel &&
13533 n_key_fire_lasers &&
13534 n_key_launch_missile &&
13535 n_key_next_missile &&
13537 n_key_prime_next_equipment &&
13538 n_key_prime_previous_equipment &&
13539 n_key_activate_equipment &&
13540 n_key_mode_equipment &&
13541 n_key_fastactivate_equipment_a &&
13542 n_key_fastactivate_equipment_b &&
13543 n_key_target_missile &&
13544 n_key_untarget_missile &&
13545 n_key_target_incoming_missile &&
13546 n_key_ident_system &&
13547 n_key_scanner_zoom &&
13548 n_key_scanner_unzoom &&
13549 n_key_launch_escapepod &&
13550 n_key_galactic_hyperspace &&
13551 n_key_hyperspace &&
13553 n_key_dump_cargo &&
13554 n_key_rotate_cargo &&
13558 n_key_docking_music &&
13559 n_key_advanced_nav_array_next &&
13560 n_key_advanced_nav_array_previous &&
13561 n_key_info_next_system &&
13562 n_key_info_previous_system &&
13565 n_key_map_next_system &&
13566 n_key_map_previous_system &&
13568 n_key_map_zoom_in &&
13569 n_key_map_zoom_out &&
13570 n_key_system_home &&
13571 n_key_system_end &&
13572 n_key_system_next_system &&
13573 n_key_system_previous_system &&
13574 n_key_pausebutton &&
13576 n_key_bloom_toggle &&
13577 n_key_mouse_control_roll &&
13578 n_key_mouse_control_yaw &&
13579 n_key_hud_toggle &&
13581 n_key_prev_compass_mode &&
13582 n_key_next_compass_mode &&
13583 n_key_chart_highlight &&
13584 n_key_market_filter_cycle &&
13585 n_key_market_sorter_cycle &&
13586 n_key_market_buy_one &&
13587 n_key_market_sell_one &&
13588 n_key_market_buy_max &&
13589 n_key_market_sell_max &&
13590 n_key_next_target &&
13591 n_key_previous_target &&
13592 n_key_custom_view &&
13593 n_key_custom_view_zoom_out &&
13594 n_key_custom_view_zoom_in &&
13595 n_key_custom_view_roll_left &&
13596 n_key_custom_view_pan_left &&
13597 n_key_custom_view_roll_right &&
13598 n_key_custom_view_pan_right &&
13599 n_key_custom_view_rotate_up &&
13600 n_key_custom_view_pan_up &&
13601 n_key_custom_view_rotate_down &&
13602 n_key_custom_view_pan_down &&
13603 n_key_custom_view_rotate_left &&
13604 n_key_custom_view_rotate_right &&
13605 n_key_docking_clearance_request &&
13606 n_key_weapons_online_toggle &&
13607 n_key_cycle_next_mfd &&
13608 n_key_cycle_previous_mfd &&
13609 n_key_switch_next_mfd &&
13610 n_key_switch_previous_mfd &&
13611 n_key_oxzmanager_setfilter &&
13612 n_key_oxzmanager_showinfo &&
13613 n_key_oxzmanager_extract &&
13614#if OO_FOV_INFLIGHT_CONTROL_ENABLED
13615 n_key_inc_field_of_view &&
13616 n_key_dec_field_of_view &&
13618 n_key_dump_target_state &&
13619 n_key_dump_entity_list &&
13620 n_key_debug_full &&
13621 n_key_debug_collision &&
13622 n_key_debug_console_connect &&
13623 n_key_debug_bounding_boxes &&
13624 n_key_debug_shaders &&
13630 customEquipActivation &&
13631 customActivatePressed &&
13632 customModePressed &&
13634 showingLongRangeChart &&
13635 _missionAllowInterrupt &&
13636 _missionScreenID &&
13658 return NSOrderedAscending;
13660 else if (result > 0)
13662 return NSOrderedDescending;
13666 return NSOrderedSame;
13677 return NSOrderedAscending;
13679 else if (result > 0)
13681 return NSOrderedDescending;
13685 return NSOrderedSame;
13696 return NSOrderedAscending;
13698 else if (result > 0)
13700 return NSOrderedDescending;
13704 return NSOrderedSame;
BOOL shadowAtPointOcclusionToValue(HPVector e1pos, GLfloat e1rad, Entity *e2, OOSunEntity *the_sun, float *outValue)
NSString * OOStringFromEntityStatus(OOEntityStatus status) CONST_FUNC
#define SCANNER_MAX_RANGE
#define SCANNER_MAX_RANGE2
#define ADD_FLAG_IF_SET(x)
#define MINIMUM_GAME_TICK
@ GUI_BACKGROUND_SPECIAL_CUSTOM_ANA_QUICKEST
@ GUI_BACKGROUND_SPECIAL_SHORT_ANA_SHORTEST
@ GUI_BACKGROUND_SPECIAL_LONG
@ GUI_BACKGROUND_SPECIAL_LONG_ANA_SHORTEST
@ GUI_BACKGROUND_SPECIAL_SHORT
@ GUI_BACKGROUND_SPECIAL_NONE
@ GUI_BACKGROUND_SPECIAL_SHORT_ANA_QUICKEST
@ GUI_BACKGROUND_SPECIAL_LONG_ANA_QUICKEST
@ GUI_BACKGROUND_SPECIAL_CUSTOM
@ GUI_BACKGROUND_SPECIAL_CUSTOM_ANA_SHORTEST
OOGUITabStop OOGUITabSettings[GUI_MAX_COLUMNS]
OOINLINE jsval OOJSValueFromLegalStatusReason(JSContext *context, OOLegalStatusReason value)
OOINLINE jsval OOJSValueFromCompassMode(JSContext *context, OOCompassMode value)
OOINLINE jsval OOJSValueFromGUIScreenID(JSContext *context, OOGUIScreenID value)
NSString * EnergyUnitTypeToString(OOEnergyUnitType unit) CONST_FUNC
NSString * DisplayStringForMassUnit(OOMassUnit unit)
NSString * OOStringFromLegalStatusReason(OOLegalStatusReason reason)
const HPVector kZeroHPVector
#define OOJSStopTimeLimiter()
#define kOOJSLongTimeLimit
#define OOJSStartTimeLimiterWithTimeLimit(limit)
#define JS_IsInRequest(context)
OOINLINE jsval OOJSValueFromNativeObject(JSContext *context, id object)
OOINLINE JSContext * OOJSAcquireContext(void)
OOINLINE void OOJSRelinquishContext(JSContext *context)
#define OOLogWARN(class, format,...)
#define OOLogERR(class, format,...)
NSString *const kOOLogException
NSString *const kOOLogInconsistentState
#define OOLog(class, format,...)
const OOMatrix kIdentityMatrix
OOMatrix OOMatrixForQuaternionRotation(Quaternion orientation)
Vector vector_up_from_quaternion(Quaternion quat)
void quaternion_rotate_about_x(Quaternion *quat, OOScalar angle)
HPVector HPvector_forward_from_quaternion(Quaternion quat)
Vector vector_right_from_quaternion(Quaternion quat)
Vector vector_forward_from_quaternion(Quaternion quat)
void quaternion_rotate_about_z(Quaternion *quat, OOScalar angle)
void quaternion_set_random(Quaternion *quat)
Vector quaternion_rotate_vector(Quaternion q, Vector v)
const Quaternion kIdentityQuaternion
void quaternion_rotate_about_y(Quaternion *quat, OOScalar angle)
const Quaternion kZeroQuaternion
void quaternion_rotate_about_axis(Quaternion *quat, Vector axis, OOScalar angle)
#define OOExpandKey(key,...)
#define OOExpandKeyWithSeed(seed, key,...)
#define OOExpand(string,...)
NSString * ClockToString(double clock, BOOL adjusting)
OOINLINE NSString * OOCredits(OOCreditsQuantity tenthsOfCredits)
NSPoint PointFromString(NSString *xyString)
NSMutableArray * ScanTokensFromString(NSString *values)
NSString * OOPadStringToEms(NSString *string, float numEms)
#define OO_GALAXIES_AVAILABLE
@ OO_SYSTEMCONCEALMENT_NODATA
@ OO_SYSTEMCONCEALMENT_NONAME
#define OO_SYSTEMS_PER_GALAXY
uint8_t OOWeaponFacingSet
NSString * OOCommodityType
@ AEGIS_CLOSE_TO_MAIN_PLANET
uint64_t OOCreditsQuantity
#define VALID_WEAPON_FACINGS
@ DOCKING_CLEARANCE_STATUS_NOT_REQUIRED
@ DOCKING_CLEARANCE_STATUS_GRANTED
@ DOCKING_CLEARANCE_STATUS_NONE
@ DOCKING_CLEARANCE_STATUS_REQUESTED
@ WEAPON_FACING_STARBOARD
@ ENERGY_UNIT_NAVAL_DAMAGED
@ ENERGY_UNIT_NORMAL_DAMAGED
OOCreditsQuantity OODeciCreditsFromObject(id object)
OOGalacticHyperspaceBehaviour
@ GALACTIC_HYPERSPACE_MAX
#define MAX_KILOGRAMS_IN_SAFE
@ GUI_ROW_EQUIPMENT_DETAIL
@ GUI_ROW_EQUIPMENT_START
@ GUI_ROW_INTERFACES_START
@ GUI_MAX_ROWS_INTERFACES
#define PLAYER_STARTING_MISSILES
@ PLAYER_FLEEING_UNLIKELY
#define ESCAPE_SEQUENCE_TIME
#define CUSTOM_VIEW_MAX_ZOOM_IN
@ OOPRIMEDEQUIP_ACTIVATED
#define CHART_WIDTH_AT_MAX_ZOOM
#define PLAYER_MAX_WEAPON_TEMP
#define PORT_FACING_STRING
#define PLAYER_INTERNAL_DAMAGE_FACTOR
@ MARKET_FILTER_MODE_HOLD
@ MARKET_FILTER_MODE_RESTRICTED
@ MARKET_FILTER_MODE_STOCK
@ MARKET_FILTER_MODE_TRADE
@ MARKET_FILTER_MODE_LEGAL
#define MAX_GRAMS_IN_SAFE
#define HYPERSPEED_FACTOR
#define KILOGRAMS_PER_POD
#define PLAYER_DIAL_MAX_ALTITUDE
#define MAX_HYPERSPEED_FACTOR
#define FORWARD_FACING_STRING
#define AFT_FACING_STRING
#define GUI_ROW_INIT(GUI)
@ SCOOP_STATUS_NOT_INSTALLED
#define CHART_HEIGHT_AT_MAX_ZOOM
#define CUSTOM_VIEW_MAX_ZOOM_OUT
#define MIN_HYPERSPEED_FACTOR
#define GUI_ROW(GROUP, ITEM)
#define STARBOARD_FACING_STRING
#define CUSTOMEQUIP_EQUIPKEY
#define CHART_SCROLL_AT_Y
#define SCANNER_ECM_FUZZINESS
@ ALERT_FLAG_YELLOW_LIMIT
#define CHART_SCROLL_AT_X
#define SCRIPT_TIMER_INTERVAL
#define PLAYER_DOCKING_AI_NAME
@ MISSILE_STATUS_TARGET_LOCKED
@ MARKET_SORTER_MODE_PRICE
@ MARKET_SORTER_MODE_STOCK
@ MARKET_SORTER_MODE_ALPHA
@ MARKET_SORTER_MODE_UNIT
@ MARKET_SORTER_MODE_HOLD
#define ECM_ENERGY_DRAIN_FACTOR
NSString * OODisplayStringFromLegalStatus(int legalStatus)
#define GUI_FIRST_ROW(GROUP)
NSString * KillCountToRatingAndKillString(unsigned kills)
#define PLAYER_SHIP_CLOCK_START
#define PLAYER_TARGET_MEMORY_SIZE
#define PLAYER_STARTING_MAX_MISSILES
#define PLAYER_MAX_TRUMBLES
#define PLAYER_MAX_MISSILES
static NSString *const kOOLogBuyMountedOK
static NSString *const kOOLogBuyMountedFailed
#define VELOCITY_CLEANUP_MIN
#define STAGE_TRACKING_END
NSComparisonResult marketSorterByName(id a, id b, void *market)
NSComparisonResult marketSorterByPrice(id a, id b, void *market)
NSComparisonResult marketSorterByQuantity(id a, id b, void *market)
static NSString * last_outfitting_key
static float const kDeadResetTime
#define VELOCITY_CLEANUP_RATE
#define STAGE_TRACKING_BEGIN
NSComparisonResult marketSorterByMassUnit(id a, id b, void *market)
#define VELOCITY_CLEANUP_FULL
#define OO_SETACCESSCONDITIONFORROW(condition, row)
#define SCENARIO_OXP_DEFINITION_NONE
#define SCENARIO_OXP_DEFINITION_ALL
#define MIN_HDR_PAPERWHITE
#define MAX_HDR_PAPERWHITE
#define INITIAL_SHOT_TIME
BOOL isWeaponNone(OOWeaponType weapon)
#define SHIP_COOLING_FACTOR
#define CLOAKING_DEVICE_MIN_ENERGY
OOWeaponType OOWeaponTypeFromEquipmentIdentifierStrict(NSString *string) PURE_FUNC
#define ShipScriptEventNoCx(ship, event,...)
#define ENTITY_PERSONALITY_INVALID
OOWeaponType OOWeaponTypeFromEquipmentIdentifierLegacy(NSString *string)
#define SHIP_MIN_CABIN_TEMP
#define MILITARY_JAMMER_ENERGY_RATE
#define CLOAKING_DEVICE_ENERGY_RATE
#define WEAPON_COOLING_FACTOR
#define SHIP_MAX_CABIN_TEMP
#define MILITARY_JAMMER_MIN_ENERGY
NSString * OOStringFromShipDamageType(OOShipDamageType type) CONST_FUNC
NSString * OODisplayStringFromAlertCondition(OOAlertCondition alertCondition)
OOWeaponType OOWeaponTypeFromEquipmentIdentifierSloppy(NSString *string) PURE_FUNC
#define BASELINE_SHIELD_LEVEL
#define SHIP_THRUST_FACTOR
#define ShipScriptEvent(context, ship, event,...)
#define WEAPON_COOLING_CUTOUT
#define SHIP_INSULATION_FACTOR
#define SHIP_ENERGY_DAMAGE_TO_HEAT_FACTOR
#define PASSENGER_BERTH_SPACE
@ WH_SCANINFO_ARRIVAL_TIME
@ WH_SCANINFO_DESTINATION
@ WH_SCANINFO_COLLAPSE_TIME
void updateAlertConditionForNearbyEntities()
void showMarketCashAndLoadLine()
void updateMovementFlags()
void setExtraEquipmentFromFlags()
void showMarketScreenHeaders()
OOFuelQuantity fuelRequiredForJump()
void checkScriptsIfAppropriate()
void noteCompassLostTarget()
void updateAlertCondition()
double hyperspaceJumpDistance()
void setNextThinkTime:(OOTimeAbsolute ntt)
void setOwner:(ShipEntity *ship)
void setState:(NSString *stateName)
OOUniversalID universalID
HPVector absolutePositionForSubentity()
void setVelocity:(Vector vel)
void setOrientation:(Quaternion quat)
GLfloat collisionRadius()
void setScanClass:(OOScanClass sClass)
void setPositionX:y:z:(OOHPScalar x,[y] OOHPScalar y,[z] OOHPScalar z)
void setPosition:(HPVector posn)
NSString * playerFileToLoad
GameController * sharedController()
void stopAnimationTimer()
void logProgress:(NSString *message)
void startAnimationTimer()
NSUInteger indexOfCurrentDisplayMode()
BOOL setBackgroundTextureKey:(NSString *key)
OOColor * colorFromSetting:defaultValue:(NSString *setting,[defaultValue] OOColor *def)
BOOL setSelectedRow:(OOGUIRow row)
OOGUIRow addLongText:startingAtRow:align:(NSString *str,[startingAtRow] OOGUIRow row,[align] OOGUIAlignment alignment)
BOOL setForegroundTextureKey:(NSString *key)
void setStatusPage:(NSInteger pageNum)
NSString * selectedRowText()
void setText:forRow:(NSString *str,[forRow] OOGUIRow row)
void setText:forRow:align:(NSString *str,[forRow] OOGUIRow row,[align] OOGUIAlignment alignment)
void clearAndKeepBackground:(BOOL keepBackground)
BOOL setForegroundTextureDescriptor:(NSDictionary *descriptor)
void overrideTabs:from:length:(OOGUITabSettings stops,[from] NSString *setting,[length] NSUInteger len)
NSDictionary * userSettings()
void setSelectableRange:(NSRange range)
void setColor:forRow:(OOColor *color,[forRow] OOGUIRow row)
NSString * selectedRowKey()
void setTitle:(NSString *str)
void setTabStops:(OOGUITabSettings stops)
NSString * keyForRow:(OOGUIRow row)
void setShowTextCursor:(BOOL yesno)
void setCurrentRow:(OOGUIRow value)
BOOL setBackgroundTextureDescriptor:(NSDictionary *descriptor)
void setArray:forRow:(NSArray *arr,[forRow] OOGUIRow row)
void setKey:forRow:(NSString *str,[forRow] OOGUIRow row)
BOOL isRunningOnPrimaryDisplayDevice()
float fov:(BOOL inFraction)
void adjustColorSaturation:(float colorSaturationAdjustment)
void setMouseWheelDelta:(float newWheelDelta)
GameController * gameController
OOCacheManager * sharedCache()
OOColor * colorWithRed:green:blue:alpha:(float red,[green] float green,[blue] float blue,[alpha] float alpha)
OOColor * colorWithDescription:(id description)
OOCommodityType legacyCommodityType:(NSUInteger i)
NSUInteger exportLegalityForGood:(OOCommodityType good)
OOMassUnit massUnitForGood:(OOCommodityType good)
NSUInteger importLegalityForGood:(OOCommodityType good)
BOOL removeQuantity:forGood:(OOCargoQuantity quantity,[forGood] OOCommodityType good)
OOCargoQuantity capacityForGood:(OOCommodityType good)
BOOL setQuantity:forGood:(OOCargoQuantity quantity,[forGood] OOCommodityType good)
OOCargoQuantity quantityForGood:(OOCommodityType good)
BOOL addQuantity:forGood:(OOCargoQuantity quantity,[forGood] OOCommodityType good)
OOCreditsQuantity priceForGood:(OOCommodityType good)
NSString * nameForGood:(OOCommodityType good)
NSString * conditionScript()
NSString * damagedIdentifier()
NSArray * defaultActivateKey()
NSArray * defaultModeKey()
OOTechLevelID effectiveTechLevel()
OOCargoQuantity requiredCargoSpace()
OOEquipmentType * equipmentTypeWithIdentifier:(NSString *identifier)
OOCreditsQuantity price()
NSString * descriptiveText()
void setRegisterKeys:(NSDictionary *registerKeys)
NSDictionary * registerKeys()
void runCallback:(NSString *key)
BOOL callMethod:inContext:withArguments:count:result:(jsid methodID,[inContext] JSContext *context,[withArguments] jsval *argv,[count] intN argc,[result] jsval *outResult)
OOJavaScriptEngine * sharedEngine()
void garbageCollectionOpportunity:(BOOL force)
void update:(OOTimeDelta delta_t)
OOMusicController * sharedController()
OOOXZManager * sharedManager()
id jsScriptFromFileNamed:properties:(NSString *fileName,[properties] NSDictionary *properties)
BOOL callMethod:inContext:withArguments:count:result:(jsid methodID,[inContext] JSContext *context,[withArguments] jsval *argv,[count] intN argc,[result] jsval *outResult)
NSDictionary * shipyardInfoForKey:(NSString *key)
OOShipRegistry * sharedRegistry()
NSDictionary * shipInfoForKey:(NSString *key)
void spawnFrom:(OOTrumble *parentTrumble)
void updateTrumble:(double delta_t)
OOWeakReference * weakSelf
void showInformationForSelectedUpgrade()
void setGuiToEquipShipScreen:(int skip)
void copyValuesFromPlayer:(PlayerEntity *player)
NSDictionary * loadScripts()
NSArray * OXPsWithMessagesFound()
NSDictionary * dictionaryFromFilesNamed:inFolder:andMerge:(NSString *fileName,[inFolder] NSString *folderName,[andMerge] BOOL mergeFiles)
void setDemoStartTime:(OOTimeAbsolute time)
void deserializeShipSubEntitiesFrom:(NSString *string)
void setDesiredSpeed:(double amount)
void setStatus:(OOEntityStatus stat)
void setRoll:(double amount)
void setThrust:(double amount)
void setSpeed:(double amount)
void wasAddedToUniverse()
void setAITo:(NSString *aiString)
void setPendingEscortCount:(uint8_t count)
void setEntityPersonalityInt:(uint16_t value)
OOCargoQuantity commodityAmount()
void update:(OOTimeDelta delta_t)
void setTemperature:(GLfloat value)
void setDemoShip:(OOScalar demoRate)
void setBehaviour:(OOBehaviour cond)
void switchAITo:(NSString *aiString)
Triangle absoluteIJKForSubentity()
void setCommodity:andAmount:(OOCommodityType co_type,[andAmount] OOCargoQuantity co_amount)
OOCommodityType commodityType()
void setOwner:(Entity *who_owns_entity)
BoundingBox findSubentityBoundingBox()
OOCommodityMarket * localMarket
OOCommodityMarket * initialiseLocalMarket()
void autoDockShipsOnApproach()
OOCreditsQuantity legalStatusOfManifest:export:(OOCommodityMarket *manifest,[export] BOOL export)
void launchShip:(ShipEntity *ship)
NSString * acceptDockingClearanceRequestFrom:(ShipEntity *other)
OOTechLevelID equivalentTechLevel
void noteDockedShip:(ShipEntity *ship)
float equipmentPriceFactor
void clearDockingCorridor()
double estimatedArrivalTime()
void setMisjumpWithRange:(GLfloat range)
void setScannedAt:(double time)
void setScanInfo:(WORMHOLE_SCANINFO scanInfo)
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
RANROTSeed RANROTGetFullSeed(void)
void setRandomSeed(RNG_Seed a_seed)
int16_t munge_checksum(long long value_)
RNG_Seed currentRandomSeed(void)
void RANROTSetFullSeed(RANROTSeed seed)
double cunningFee(double value, double precision)
OOINLINE double distanceBetweenPlanetPositions(int x1, int y1, int x2, int y2) INLINE_CONST_FUNC