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]];
1137 foreach (wh, scannedWormholes)
1139 [wormholeDicts addObject:[wh
getDict]];
1141 [result setObject:wormholeDicts forKey:@"wormholes"];
1145 [result setObject:dockedStation != nil ? [dockedStation
primaryRole]:(NSString *)@"" forKey:@"docked_station_role"];
1148 HPVector dpos = [dockedStation
position];
1149 [result setObject:ArrayFromHPVector(dpos) forKey:@"docked_station_position"];
1153 [result setObject:[NSArray array] forKey:@"docked_station_position"];
1155 [result setObject:[UNIVERSE getStationMarkets] forKey:@"station_markets"];
1158 if (scenarioKey !=
nil)
1160 [result setObject:scenarioKey forKey:@"scenario"];
1173 if (mission_variables !=
nil)
1177 if (equipment !=
nil)
1182 int final_checksum =
munge_checksum([[
self shipDataKey] length]);
1185 [result oo_setInteger:final_checksum forKey:@"checksum"];
1191- (BOOL)setCommanderDataFromDictionary:(NSDictionary *) dict
1195 [multiFunctionDisplayText release];
1196 multiFunctionDisplayText = [[NSMutableDictionary alloc] init];
1198 [multiFunctionDisplaySettings release];
1199 multiFunctionDisplaySettings = [[NSMutableArray alloc] init];
1201 [customDialSettings release];
1202 customDialSettings = [[NSMutableDictionary alloc] init];
1204 [[UNIVERSE gameView] resetTypedString];
1207 if ([dict oo_stringForKey:
@"ship_desc"] ==
nil) return NO;
1209 if ([dict oo_stringForKey:
@"galaxy_seed"] ==
nil && [dict oo_stringForKey:
@"galaxy_id"] ==
nil) return NO;
1211 if ([dict oo_stringForKey:
@"galaxy_coordinates"] ==
nil && [dict oo_stringForKey:
@"system_id"] ==
nil) return NO;
1213 NSString *scenarioRestrict = [dict oo_stringForKey:@"scenario_restriction" defaultValue:nil];
1214 if (scenarioRestrict ==
nil)
1217 BOOL strict = [dict oo_boolForKey:@"strict" defaultValue:NO];
1228 if (![
UNIVERSE setUseAddOns:scenarioRestrict fromSaveGame:YES])
1235 [
self setShipDataKey:[dict oo_stringForKey:@"ship_desc"]];
1238 if (shipDict ==
nil)
return NO;
1239 if (![
self setUpShipFromDictionary:shipDict]) return NO;
1240 OOLog(
@"fuelPrices",
@"Got \"%@\
", fuel charge rate: %.2f", [
self shipDataKey],[
self fuelChargeRate]);
1243 ship_trade_in_factor = [dict oo_intForKey:@"ship_trade_in_factor" defaultValue:95];
1246 if ([dict oo_stringForKey:
@"galaxy_id"] !=
nil)
1248 galaxy_number = [dict oo_unsignedIntegerForKey:@"galaxy_id"];
1253 [UNIVERSE setGalaxyTo:galaxy_number andReinit:YES];
1255 system_id = [dict oo_intForKey:@"system_id"];
1261 [UNIVERSE setSystemTo:system_id];
1263 NSArray *coord_vals =
ScanTokensFromString([[
UNIVERSE systemManager] getProperty:
@"coordinates" forSystem:system_id inGalaxy:galaxy_number]);
1264 galaxy_coordinates.x = [coord_vals oo_unsignedCharAtIndex:0];
1265 galaxy_coordinates.y = [coord_vals oo_unsignedCharAtIndex:1];
1266 chart_centre_coordinates = galaxy_coordinates;
1267 target_chart_centre = chart_centre_coordinates;
1268 cursor_coordinates = galaxy_coordinates;
1269 chart_zoom = [dict oo_floatForKey:@"chart_zoom" defaultValue:1.0];
1270 target_chart_zoom = chart_zoom;
1271 saved_chart_zoom = chart_zoom;
1272 ANA_mode = [dict oo_intForKey:@"chart_ana_mode" defaultValue:OPTIMIZED_BY_NONE];
1273 longRangeChartMode = [dict oo_intForKey:@"chart_colour_mode" defaultValue:OOLRC_MODE_SUNCOLOR];
1274 if (longRangeChartMode == OOLRC_MODE_UNKNOWN) longRangeChartMode = OOLRC_MODE_SUNCOLOR;
1276 target_system_id = [dict oo_intForKey:@"target_id" defaultValue:system_id];
1277 previous_system_id = [dict oo_intForKey:@"previous_system_id" defaultValue:system_id];
1278 info_system_id = target_system_id;
1279 coord_vals =
ScanTokensFromString([[
UNIVERSE systemManager] getProperty:
@"coordinates" forSystem:target_system_id inGalaxy:galaxy_number]);
1280 cursor_coordinates.x = [coord_vals oo_unsignedCharAtIndex:0];
1281 cursor_coordinates.y = [coord_vals oo_unsignedCharAtIndex:1];
1283 chart_focus_coordinates = chart_centre_coordinates;
1284 target_chart_focus = chart_focus_coordinates;
1286 found_system_id = [dict oo_intForKey:@"found_system_id" defaultValue:-1];
1291 galaxy_number = [dict oo_unsignedIntegerForKey:@"galaxy_number"];
1293 [UNIVERSE setGalaxyTo: galaxy_number andReinit:YES];
1296 galaxy_coordinates.x = [coord_vals oo_unsignedCharAtIndex:0];
1297 galaxy_coordinates.y = [coord_vals oo_unsignedCharAtIndex:1];
1298 chart_centre_coordinates = galaxy_coordinates;
1299 target_chart_centre = chart_centre_coordinates;
1300 cursor_coordinates = galaxy_coordinates;
1302 target_chart_zoom = 1.0;
1303 saved_chart_zoom = 1.0;
1306 NSString *keyStringValue = [dict oo_stringForKey:@"target_coordinates"];
1308 if (keyStringValue !=
nil)
1311 cursor_coordinates.x = [coord_vals oo_unsignedCharAtIndex:0];
1312 cursor_coordinates.y = [coord_vals oo_unsignedCharAtIndex:1];
1314 chart_focus_coordinates = chart_centre_coordinates;
1315 target_chart_focus = chart_focus_coordinates;
1318 if ([dict objectForKey:
@"current_system_name"])
1320 system_id = [UNIVERSE findSystemFromName:[dict oo_stringForKey:@"current_system_name"]];
1321 if (system_id == -1) system_id = [UNIVERSE findSystemNumberAtCoords:galaxy_coordinates withGalaxy:galaxy_number includingHidden:YES];
1327 system_id = [UNIVERSE findSystemNumberAtCoords:galaxy_coordinates withGalaxy:galaxy_number includingHidden:YES];
1331 if ([dict objectForKey:
@"target_system_name"])
1333 target_system_id = [UNIVERSE findSystemFromName:[dict oo_stringForKey:@"target_system_name"]];
1334 if (target_system_id == -1) target_system_id = [UNIVERSE findSystemNumberAtCoords:cursor_coordinates withGalaxy:galaxy_number includingHidden:YES];
1338 target_system_id = [UNIVERSE findSystemNumberAtCoords:cursor_coordinates withGalaxy:galaxy_number includingHidden:YES];
1340 info_system_id = target_system_id;
1341 found_system_id = -1;
1344 NSString *cname = [dict oo_stringForKey:@"player_name" defaultValue:PLAYER_DEFAULT_NAME];
1345 [
self setCommanderName:cname];
1346 [
self setLastsaveName:[dict oo_stringForKey:@"player_save_name" defaultValue:cname]];
1348 [
self setShipUniqueName:[dict oo_stringForKey:@"ship_unique_name" defaultValue:@""]];
1349 [
self setShipClassName:[dict oo_stringForKey:@"ship_class_name" defaultValue:[shipDict oo_stringForKey:@"name"]]];
1351 [shipCommodityData loadPlayerAmounts:[dict oo_arrayForKey:@"shipCommodityData"]];
1354 [
self removeAllEquipment];
1355 NSMutableDictionary *equipment = [NSMutableDictionary dictionaryWithDictionary:[dict oo_dictionaryForKey:@"extra_equipment"]];
1358 if ([dict oo_boolForKey:
@"has_docking_computer"]) [equipment oo_setInteger:1 forKey:
@"EQ_DOCK_COMP"];
1359 if ([dict oo_boolForKey:
@"has_galactic_hyperdrive"]) [equipment oo_setInteger:1 forKey:
@"EQ_GAL_DRIVE"];
1360 if ([dict oo_boolForKey:
@"has_escape_pod"]) [equipment oo_setInteger:1 forKey:
@"EQ_ESCAPE_POD"];
1361 if ([dict oo_boolForKey:
@"has_ecm"]) [equipment oo_setInteger:1 forKey:
@"EQ_ECM"];
1362 if ([dict oo_boolForKey:
@"has_scoop"]) [equipment oo_setInteger:1 forKey:
@"EQ_FUEL_SCOOPS"];
1363 if ([dict oo_boolForKey:
@"has_energy_bomb"]) [equipment oo_setInteger:1 forKey:
@"EQ_ENERGY_BOMB"];
1364 if ([dict oo_boolForKey:
@"has_fuel_injection"]) [equipment oo_setInteger:1 forKey:
@"EQ_FUEL_INJECTION"];
1368 if ([dict oo_boolForKey:
@"has_energy_unit"] && [
self installedEnergyUnitType] ==
ENERGY_UNIT_NONE)
1370 OOEnergyUnitType eType = [dict oo_intForKey:@"energy_unit" defaultValue:ENERGY_UNIT_NORMAL];
1375 [equipment oo_setInteger:1 forKey:@"EQ_NAVAL_ENERGY_UNIT"];
1379 [equipment oo_setInteger:1 forKey:@"EQ_ENERGY_UNIT"];
1387 custom_chart_zoom = 1.0;
1388 custom_chart_centre_coordinates = NSMakePoint(galaxy_coordinates.y, galaxy_coordinates.y);
1394 BOOL energyBombCompensation = NO;
1395 if ([equipment oo_boolForKey:
@"EQ_ENERGY_BOMB"] && [
OOEquipmentType equipmentTypeWithIdentifier:
@"EQ_ENERGY_BOMB"] ==
nil)
1397 energyBombCompensation = YES;
1398 [equipment removeObjectForKey:@"EQ_ENERGY_BOMB"];
1401 eqScripts = [[NSMutableArray alloc] init];
1402 [
self addEquipmentFromCollection:equipment];
1403 primedEquipment = [
self eqScriptIndexForKey:[dict oo_stringForKey:@"primed_equipment"]];
1405 [
self setFastEquipmentA:[dict oo_stringForKey:@"primed_equipment_a" defaultValue:@"EQ_CLOAKING_DEVICE"]];
1406 [
self setFastEquipmentB:[dict oo_stringForKey:@"primed_equipment_b" defaultValue:@"EQ_ENERGY_BOMB"]];
1408 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_COMPASS"]) compassMode = COMPASS_MODE_PLANET;
1409 else compassMode = COMPASS_MODE_BASIC;
1413 isSpeechOn = [dict oo_intForKey:@"speech_on"];
1415 voice_gender_m = [dict oo_boolForKey:@"speech_gender" defaultValue:YES];
1416 voice_no = [UNIVERSE setVoice:[UNIVERSE voiceNumber:[dict oo_stringForKey:@"speech_voice" defaultValue:nil]] withGenderM:voice_gender_m];
1420 [reputation release];
1421 reputation = [[dict oo_dictionaryForKey:@"reputation"] mutableCopy];
1422 if (reputation ==
nil) reputation = [[NSMutableDictionary alloc] init];
1423 [
self normaliseReputation];
1427 [parcel_record release];
1428 [passengers release];
1429 [passenger_record release];
1430 [contracts release];
1431 [contract_record release];
1433 max_passengers = [dict oo_intForKey:@"max_passengers" defaultValue:0];
1434 passengers = [[dict oo_arrayForKey:@"passengers"] mutableCopy];
1435 passenger_record = [[dict oo_dictionaryForKey:@"passenger_record"] mutableCopy];
1438 contracts = [[dict oo_arrayForKey:@"contracts"] mutableCopy];
1439 NSMutableDictionary *contractInfo =
nil;
1442 for (NSInteger i = (NSInteger)[contracts
count] - 1; i >= 0; i--)
1444 contractInfo = [[[contracts oo_dictionaryAtIndex:i] mutableCopy] autorelease];
1446 if ([[contractInfo objectForKey:
CARGO_KEY_TYPE] isKindOfClass:[NSNumber class]])
1449 NSUInteger legacy_type = [contractInfo oo_unsignedIntegerForKey:CARGO_KEY_TYPE];
1451 [contracts replaceObjectAtIndex:i withObject:[[contractInfo copy] autorelease]];
1455 OOCommodityType new_type = [contractInfo oo_stringForKey:CARGO_KEY_TYPE];
1457 if (![[
UNIVERSE commodities] goodDefined:new_type])
1459 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);
1460 [contracts removeObjectAtIndex:i];
1465 contract_record = [[dict oo_dictionaryForKey:@"contract_record"] mutableCopy];
1466 parcels = [[dict oo_arrayForKey:@"parcels"] mutableCopy];
1467 parcel_record = [[dict oo_dictionaryForKey:@"parcel_record"] mutableCopy];
1471 if (passengers ==
nil) passengers = [[NSMutableArray alloc] init];
1472 if (passenger_record ==
nil) passenger_record = [[NSMutableDictionary alloc] init];
1473 if (contracts ==
nil) contracts = [[NSMutableArray alloc] init];
1474 if (contract_record ==
nil) contract_record = [[NSMutableDictionary alloc] init];
1475 if (parcels ==
nil) parcels = [[NSMutableArray alloc] init];
1476 if (parcel_record ==
nil) parcel_record = [[NSMutableDictionary alloc] init];
1479 [specialCargo release];
1480 specialCargo = [[dict oo_stringForKey:@"special_cargo"] copy];
1483 NSArray *legacyDestinations = [dict oo_arrayForKey:@"missionDestinations"];
1485 NSDictionary *newDestinations = [dict oo_dictionaryForKey:@"mission_destinations"];
1486 [
self initialiseMissionDestinations:newDestinations andLegacy:legacyDestinations];
1490 shipyard_record = [[dict oo_dictionaryForKey:@"shipyard_record"] mutableCopy];
1491 if (shipyard_record ==
nil) shipyard_record = [[NSMutableDictionary alloc] init];
1494 unsigned original_hold_size = [UNIVERSE maxCargoForShip:[
self shipDataKey]];
1499 max_cargo = [dict oo_unsignedIntForKey:@"max_cargo" defaultValue:max_cargo];
1500 if (max_cargo > original_hold_size) [
self addEquipmentItem:@"EQ_CARGO_BAY" inContext:@"loading"];
1501 max_cargo = original_hold_size + ([
self hasExpandedCargoBay] ? extra_cargo : 0);
1505 unsigned originalMaxPassengers = max_passengers;
1507 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);
1512 if (passengers && ([passengers
count] > max_passengers))
1514 OOLogWARN(
@"setCommanderDataFromDictionary.inconsistency.passengers",
@"player ship %@ had more passengers (%llu) than passenger berths (%u). Removing extra passengers.", [
self name], [passengers
count], max_passengers);
1515 for (NSInteger i = (NSInteger)[passengers
count] - 1; i >= max_passengers; i--)
1517 [passenger_record removeObjectForKey:[[passengers oo_dictionaryAtIndex:i] oo_stringForKey:PASSENGER_KEY_NAME]];
1518 [passengers removeObjectAtIndex:i];
1523 NSInteger excessCargo = (NSInteger)[
self cargoQuantityOnBoard] - (NSInteger)[
self maxAvailableCargoSpace];
1524 if (excessCargo > 0)
1526 OOLogWARN(
@"setCommanderDataFromDictionary.inconsistency.cargo",
@"player ship %@ had more cargo (%i) than it can hold (%u). Removing extra cargo.", [
self name], [
self cargoQuantityOnBoard], [
self maxAvailableCargoSpace]);
1535 foreach (type, [shipCommodityData goods])
1537 units = [shipCommodityData massUnitForGood:type];
1539 oldAmount = [shipCommodityData quantityForGood:type];
1541 if (roundedTon || (units ==
UNITS_TONS && oldAmount > 0))
1546 while (remainingExcess > 0 && partAmount > 0)
1552 partAmount = oldAmount - toRemove;
1555 else if (!roundedTon)
1566 [shipCommodityData removeQuantity:toRemove forGood:type];
1573 fuel = [dict oo_unsignedIntForKey:@"fuel" defaultValue:fuel];
1574 galaxy_number = [dict oo_intForKey:@"galaxy_number"];
1577 OOWeaponFacingSet available_facings = [shipyard_info oo_unsignedIntForKey:KEY_WEAPON_FACINGS defaultValue:[
self weaponFacings]];
1599 [
self setWeaponDataFromType:forward_weapon_type];
1601 if (hud !=
nil && [hud nonlinearScanner])
1603 [hud setScannerZoom: [dict oo_floatForKey:@"ship_scanner_zoom" defaultValue: 1.0]];
1606 weapons_online = [dict oo_boolForKey:@"weapons_online" defaultValue:YES];
1608 legalStatus = [dict oo_intForKey:@"legal_status"];
1609 market_rnd = [dict oo_intForKey:@"market_rnd"];
1610 ship_kills = [dict oo_intForKey:@"ship_kills"];
1612 ship_clock = [dict oo_doubleForKey:@"ship_clock" defaultValue:PLAYER_SHIP_CLOCK_START];
1613 fps_check_time = ship_clock;
1615 escape_pod_rescue_time = [dict oo_doubleForKey:@"escape_pod_rescue_time" defaultValue:0.0];
1618 [roleWeights release];
1619 roleWeights = [[dict oo_arrayForKey:@"role_weights"] mutableCopy];
1620 NSUInteger rc = [
self maxPlayerRoles];
1621 if (roleWeights ==
nil)
1623 roleWeights = [[NSMutableArray alloc] initWithCapacity:rc];
1626 [roleWeights addObject:@"player-unknown"];
1631 if ([roleWeights
count] > rc)
1633 [roleWeights removeObjectsInRange:(NSRange) {rc,[roleWeights count]-rc}];
1637 roleWeightFlags = [[dict oo_dictionaryForKey:@"role_weight_flags"] mutableCopy];
1638 if (roleWeightFlags ==
nil)
1640 roleWeightFlags = [[NSMutableDictionary alloc] init];
1643 roleSystemList = [[dict oo_arrayForKey:@"role_system_memory"] mutableCopy];
1644 if (roleSystemList ==
nil)
1646 roleSystemList = [[NSMutableArray alloc] initWithCapacity:32];
1651 [mission_variables release];
1652 mission_variables = [[dict oo_dictionaryForKey:@"mission_variables"] mutableCopy];
1653 if (mission_variables ==
nil) mission_variables = [[NSMutableDictionary alloc] init];
1656 NSDictionary *planetInfoOverrides = [dict oo_dictionaryForKey:@"scripted_planetinfo_overrides"];
1657 if (planetInfoOverrides !=
nil)
1659 [[UNIVERSE systemManager] importScriptedChanges:planetInfoOverrides];
1664 planetInfoOverrides = [dict oo_dictionaryForKey:@"local_planetinfo_overrides"];
1665 if (planetInfoOverrides !=
nil)
1667 [[UNIVERSE systemManager] importLegacyScriptedChanges:planetInfoOverrides];
1673 commLog = [[NSMutableArray alloc] initWithCapacity:kCommLogTrimThreshold];
1675 NSArray *savedCommLog = [dict oo_arrayForKey:@"comm_log"];
1676 NSUInteger commCount = [savedCommLog count];
1677 for (NSUInteger i = 0; i < commCount; i++)
1679 [UNIVERSE addCommsMessage:[savedCommLog objectAtIndex:i] forCount:0 andShowComms:NO logOnly:YES];
1687 entity_personality = [dict oo_unsignedShortForKey:@"entity_personality" defaultValue:entity_personality];
1690 [
self setActiveMissile:0];
1693 [missile_entity[i] release];
1694 missile_entity[i] =
nil;
1696 NSArray *missileRoles = [dict oo_arrayForKey:@"missile_roles"];
1697 if (missileRoles !=
nil)
1699 unsigned missileCount = 0;
1700 for (NSUInteger roleIndex = 0; roleIndex < [missileRoles count] && missileCount < max_missiles; roleIndex++)
1702 NSString *missile_desc = [missileRoles oo_stringAtIndex:roleIndex];
1703 if (missile_desc !=
nil && ![missile_desc isEqualToString:
@"NONE"])
1705 ShipEntity *amiss = [UNIVERSE newShipWithRole:missile_desc];
1709 missile_entity[missileCount] = amiss;
1714 OOLogWARN(
@"load.failed.missileNotFound",
@"couldn't find missile with role '%@' in [PlayerEntity setCommanderDataFromDictionary:], missile entry discarded.", missile_desc);
1717 missiles = missileCount;
1722 for (NSUInteger i = 0; i < missiles; i++)
1725 missile_entity[i] = [UNIVERSE newShipWithRole:@"EQ_MISSILE"];
1730 if (energyBombCompensation)
1737 if ([
self mountMissileWithRole:
@"EQ_QC_MINE"])
1739 OOLog(
@"load.upgrade.replacedEnergyBomb",
@"%@",
@"Replaced legacy energy bomb with Quirium cascade mine.");
1744 OOLog(
@"load.upgrade.replacedEnergyBomb",
@"%@",
@"Compensated legacy energy bomb with 900 credits.");
1748 [
self setActiveMissile:0];
1750 [
self setHeatInsulation:1.0];
1755 forward_shield_recharge_rate = 2.0;
1756 aft_shield_recharge_rate = 2.0;
1758 forward_shield = [
self maxForwardShieldLevel];
1759 aft_shield = [
self maxAftShieldLevel];
1765 [
self deserializeShipSubEntitiesFrom:[dict oo_stringForKey:@"subentities_status"]];
1769 whArray = [dict objectForKey:@"wormholes"];
1770 NSDictionary * whCurrDict;
1771 [scannedWormholes release];
1772 scannedWormholes = [[NSMutableArray alloc] initWithCapacity:[whArray count]];
1773 foreach (whCurrDict, whArray)
1776 [scannedWormholes addObject:wh];
1788 if (_customViews !=
nil)
1789 _customViewIndex = [dict oo_unsignedIntForKey:@"custom_view_index"] % [_customViews count];
1793 [UNIVERSE setDockingClearanceProtocolActive:[dict oo_boolForKey:@"docking_clearance_protocol" defaultValue:NO]];
1796 [
self setUpTrumbles];
1797 [
self setTrumbleValueFrom:[dict objectForKey:@"trumbles"]];
1821 NSAssert(
gOOPlayer ==
nil,
@"Expected only one PlayerEntity to exist at a time.");
1822 return [
super initBypassForPlayer];
1826- (void) deferredInit
1828 NSAssert(
gOOPlayer ==
self,
@"Expected only one PlayerEntity to exist at a time.");
1829 NSAssert([super initWithKey:
PLAYER_SHIP_DESC definition:[NSDictionary dictionary]] ==
self,
@"PlayerEntity requires -[ShipEntity initWithKey:definition:] to return unmodified self.");
1832#if OO_FOV_INFLIGHT_CONTROL_ENABLED
1836 compassMode = COMPASS_MODE_BASIC;
1838 afterburnerSoundLooping = NO;
1842 [
self setStatus:STATUS_START_GAME];
1847 missile_entity[i] =
nil;
1849 [
self setUpAndConfirmOK:NO];
1855 target_memory_index = 0;
1858 dockingReport = [[NSMutableString alloc] init];
1859 [hud resetGuis:[NSDictionary dictionaryWithObjectsAndKeys:[NSDictionary dictionary], @"message_gui",
1860 [NSDictionary dictionary], @"comm_log_gui", nil]];
1862 [
self initControls];
1866- (BOOL) setUpAndConfirmOK:(BOOL)stopOnError
1868 return [
self setUpAndConfirmOK:stopOnError saveGame:NO];
1872- (BOOL) setUpAndConfirmOK:(BOOL)stopOnError saveGame:(BOOL)saveGame
1874 fieldOfView = [[UNIVERSE gameView] fov:YES];
1878 show_info_flag = NO;
1879 DESTROY(marketSelectedCommodity);
1910 [
self setDockedStation:nil];
1911 [
self setStatus:STATUS_DEAD];
1912 OOLog(
@"script.javascript.init.error",
@"%@",
@"Scheduling new JavaScript reset.");
1928 [UNIVERSE setBlockJSPlayerShipProps:NO];
1930 DESTROY(worldScriptsRequiringTickle);
1936 [UNIVERSE preloadSounds];
1939 [UNIVERSE loadConditionScripts];
1940 commodityScripts = [[NSMutableDictionary alloc] init];
1945 [UNIVERSE preloadSounds];
1950 [UNIVERSE loadConditionScripts];
1951 commodityScripts = [[NSMutableDictionary alloc] init];
1961 if ([
self cargoList] !=
nil)
1963 [
self removeAllCargo:YES];
1966 [
self setShipDataKey:PLAYER_SHIP_DESC];
1967 ship_trade_in_factor = 95;
1970 [UNIVERSE setAutoCommLog:YES];
1971 [UNIVERSE setPermanentCommLog:NO];
1973 [multiFunctionDisplayText release];
1974 multiFunctionDisplayText = [[NSMutableDictionary alloc] init];
1976 [multiFunctionDisplaySettings release];
1977 multiFunctionDisplaySettings = [[NSMutableArray alloc] init];
1979 [customDialSettings release];
1980 customDialSettings = [[NSMutableDictionary alloc] init];
1982 [
self switchHudTo:@"hud.plist"];
1983 scanner_zoom_rate = 0.0f;
1984 longRangeChartMode = OOLRC_MODE_SUNCOLOR;
1986 [mission_variables release];
1987 mission_variables = [[NSMutableDictionary alloc] init];
1989 [localVariables release];
1990 localVariables = [[NSMutableDictionary alloc] init];
1992 [
self setScriptTarget:nil];
1993 [
self resetMissionChoice];
1994 [[UNIVERSE gameView] resetTypedString];
1995 found_system_id = -1;
1997 [reputation release];
1998 reputation = [[NSMutableDictionary alloc] initWithCapacity:6];
1999 [reputation oo_setInteger:0 forKey:CONTRACTS_GOOD_KEY];
2000 [reputation oo_setInteger:0 forKey:CONTRACTS_BAD_KEY];
2001 [reputation oo_setInteger:MAX_CONTRACT_REP forKey:CONTRACTS_UNKNOWN_KEY];
2002 [reputation oo_setInteger:0 forKey:PASSAGE_GOOD_KEY];
2003 [reputation oo_setInteger:0 forKey:PASSAGE_BAD_KEY];
2004 [reputation oo_setInteger:MAX_CONTRACT_REP forKey:PASSAGE_UNKNOWN_KEY];
2005 [reputation oo_setInteger:0 forKey:PARCEL_GOOD_KEY];
2006 [reputation oo_setInteger:0 forKey:PARCEL_BAD_KEY];
2007 [reputation oo_setInteger:MAX_CONTRACT_REP forKey:PARCEL_UNKNOWN_KEY];
2010 roleWeights = [[NSMutableArray alloc] initWithCapacity:8];
2011 for (i = 0 ; i < 8 ; i++)
2013 [roleWeights addObject:@"player-unknown"];
2016 roleWeightFlags = [[NSMutableDictionary alloc] init];
2019 roleSystemList = [[NSMutableArray alloc] initWithCapacity:32];
2023 forward_weapon_temp = 0.0f;
2024 aft_weapon_temp = 0.0f;
2025 port_weapon_temp = 0.0f;
2026 starboard_weapon_temp = 0.0f;
2032 ship_temperature = 60.0f;
2034 hyperspeed_engaged = NO;
2035 autopilot_engaged = NO;
2043 [passengers release];
2044 passengers = [[NSMutableArray alloc] init];
2045 [passenger_record release];
2046 passenger_record = [[NSMutableDictionary alloc] init];
2048 [contracts release];
2049 contracts = [[NSMutableArray alloc] init];
2050 [contract_record release];
2051 contract_record = [[NSMutableDictionary alloc] init];
2054 parcels = [[NSMutableArray alloc] init];
2055 [parcel_record release];
2056 parcel_record = [[NSMutableDictionary alloc] init];
2058 [missionDestinations release];
2059 missionDestinations = [[NSMutableDictionary alloc] init];
2061 [shipyard_record release];
2062 shipyard_record = [[NSMutableDictionary alloc] init];
2064 [target_memory release];
2065 target_memory = [[NSMutableArray alloc] initWithCapacity:PLAYER_TARGET_MEMORY_SIZE];
2066 [
self clearTargetMemory];
2068 [
self setMissionOverlayDescriptor:nil];
2069 [
self setMissionBackgroundDescriptor:nil];
2070 [
self setMissionBackgroundSpecial:nil];
2071 [
self setEquipScreenBackgroundDescriptor:nil];
2073 DESTROY(marketSelectedCommodity);
2079 NSCalendarDate *nowDate = [NSCalendarDate calendarDate];
2081 ship_clock += [nowDate hourOfDay] * 3600.0;
2082 ship_clock += [nowDate minuteOfHour] * 60.0;
2083 ship_clock += [nowDate secondOfMinute];
2084 fps_check_time = ship_clock;
2085 ship_clock_adjust = 0.0;
2086 escape_pod_rescue_time = 0.0;
2090 voice_gender_m = YES;
2091 voice_no = [UNIVERSE setVoice:-1 withGenderM:voice_gender_m];
2094 [_customViews release];
2096 _customViewIndex = 0;
2098 mouse_control_on = NO;
2103 [
self setCommanderName:PLAYER_DEFAULT_NAME];
2104 [
self setLastsaveName:PLAYER_DEFAULT_NAME];
2106 galaxy_coordinates = NSMakePoint(0x14,0xAD);
2110 fuel_accumulator = 0.0f;
2111 fuel_leak_rate = 0.0f;
2115 forward_weapon_type =
nil;
2116 aft_weapon_type =
nil;
2117 port_weapon_type =
nil;
2118 starboard_weapon_type =
nil;
2121 weapons_online = YES;
2123 ecm_in_operation = NO;
2124 last_ecm_time = [UNIVERSE getTime];
2125 compassMode = COMPASS_MODE_BASIC;
2132 shipCommodityData = [[[UNIVERSE commodities] generateManifestForPlayer] retain];
2138 [eqScripts release];
2139 eqScripts = [[NSMutableArray alloc] init];
2140 primedEquipment = 0;
2141 [
self setFastEquipmentA:@"EQ_CLOAKING_DEVICE"];
2142 [
self setFastEquipmentB:@"EQ_ENERGY_BOMB"];
2144 [
self setActiveMissile:0];
2145 for (i = 0; i < missiles; i++)
2147 [missile_entity[i] release];
2148 missile_entity[i] =
nil;
2150 [
self safeAllMissiles];
2152 [
self clearSubEntities];
2158 chart_centre_coordinates = galaxy_coordinates;
2159 target_chart_centre = chart_centre_coordinates;
2160 cursor_coordinates = galaxy_coordinates;
2161 chart_focus_coordinates = cursor_coordinates;
2162 target_chart_focus = chart_focus_coordinates;
2164 target_chart_zoom = 1.0;
2165 saved_chart_zoom = 1.0;
2169 scripted_misjump = NO;
2170 _scriptedMisjumpRange = 0.5;
2176 forward_shield_recharge_rate = 2.0;
2177 aft_shield_recharge_rate = 2.0;
2179 forward_shield = [
self maxForwardShieldLevel];
2180 aft_shield = [
self maxAftShieldLevel];
2182 scanClass = CLASS_PLAYER;
2184 [UNIVERSE clearGUIs];
2187 targetDockStation =
nil;
2189 [
self setDockedStation:[UNIVERSE station]];
2194 [specialCargo release];
2205 [
self currentWeaponStats];
2207 [save_path autorelease];
2210 [scannedWormholes release];
2211 scannedWormholes = [[NSMutableArray alloc] init];
2213 [
self setUpTrumbles];
2215 suppressTargetLost = NO;
2219 [dockingReport release];
2220 dockingReport = [[NSMutableString alloc] init];
2223 shipAI = [[
AI alloc] initWithStateMachine:PLAYER_DOCKING_AI_NAME andState:@"GLOBAL"];
2224 [
self resetAutopilotAI];
2226 lastScriptAlertCondition = [
self alertCondition];
2230 [
self setSystemID:[UNIVERSE findSystemNumberAtCoords:[
self galaxy_coordinates] withGalaxy:galaxy_number includingHidden:YES]];
2231 [UNIVERSE setGalaxyTo:galaxy_number];
2232 [UNIVERSE setSystemTo:system_id];
2234 [
self setUpWeaponSounds];
2236 [
self setGalacticHyperspaceBehaviourTo:[[UNIVERSE globalSettings] oo_stringForKey:@"galactic_hyperspace_behaviour" defaultValue:@"BEHAVIOUR_STANDARD"]];
2237 [
self setGalacticHyperspaceFixedCoordsTo:[[UNIVERSE globalSettings] oo_stringForKey:@"galactic_hyperspace_fixed_coords" defaultValue:@"96 96"]];
2239 cloaking_device_active = NO;
2244 [stickProfileScreen release];
2250- (void) completeSetUp
2252 [
self completeSetUpAndSetTarget:YES];
2256- (void) completeSetUpAndSetTarget:(BOOL)setTarget
2260 [
self setDockedStation:[UNIVERSE station]];
2261 [
self setLastAegisLock:[UNIVERSE planet]];
2265 [
self validateCustomEquipActivationArray];
2269 [
self doWorldScriptEvent:OOJSID("startUp") inContext:context withArguments:NULL count:0 timeLimit:MAX(0.0, [[NSUserDefaults standardUserDefaults] oo_floatForKey:@"start-script-limit-value" defaultValue:kOOJSLongTimeLimit])];
2274- (void) startUpComplete
2277 [
self doWorldScriptEvent:OOJSID("startUpComplete") inContext:context withArguments:NULL count:0 timeLimit:kOOJSLongTimeLimit];
2282- (BOOL) setUpShipFromDictionary:(NSDictionary *)shipDict
2285 [UNIVERSE setBlockJSPlayerShipProps:NO];
2287 if (![super setUpFromDictionary:shipDict]) return NO;
2290 cargo = [[NSMutableArray alloc] initWithCapacity:max_cargo];
2295 roll_delta = 2.0f * max_flight_roll;
2296 pitch_delta = 2.0f * max_flight_pitch;
2297 yaw_delta = 2.0f * max_flight_yaw;
2305 [
self setPrimaryRole:@"player"];
2307 [
self removeAllEquipment];
2308 [
self addEquipmentFromCollection:[shipDict objectForKey:@"extra_equipment"]];
2316 if (missiles > max_missiles) missiles = max_missiles;
2322 [missile_entity[i] release];
2323 missile_entity[i] =
nil;
2325 for (i = 0; i < missiles; i++)
2328 missile_entity[i] = [UNIVERSE newShipWithRole:@"EQ_MISSILE"];
2332 [
self safeAllMissiles];
2333 [
self setActiveMissile:0];
2336 [
self setDefaultViewOffsets];
2338 if (
EXPECT(_scaleFactor == 1.0f))
2340 forwardViewOffset = [shipDict oo_vectorForKey:@"view_position_forward" defaultValue:forwardViewOffset];
2341 aftViewOffset = [shipDict oo_vectorForKey:@"view_position_aft" defaultValue:aftViewOffset];
2342 portViewOffset = [shipDict oo_vectorForKey:@"view_position_port" defaultValue:portViewOffset];
2343 starboardViewOffset = [shipDict oo_vectorForKey:@"view_position_starboard" defaultValue:starboardViewOffset];
2347 forwardViewOffset = vector_multiply_scalar([shipDict oo_vectorForKey:
@"view_position_forward" defaultValue:forwardViewOffset],_scaleFactor);
2348 aftViewOffset = vector_multiply_scalar([shipDict oo_vectorForKey:
@"view_position_aft" defaultValue:aftViewOffset],_scaleFactor);
2349 portViewOffset = vector_multiply_scalar([shipDict oo_vectorForKey:
@"view_position_port" defaultValue:portViewOffset],_scaleFactor);
2350 starboardViewOffset = vector_multiply_scalar([shipDict oo_vectorForKey:
@"view_position_starboard" defaultValue:starboardViewOffset],_scaleFactor);
2353 [
self setDefaultCustomViews];
2355 NSArray *customViews = [shipDict oo_arrayForKey:@"custom_views"];
2356 if (customViews !=
nil)
2358 [_customViews release];
2359 _customViews = [customViews retain];
2360 _customViewIndex = 0;
2363 massLockable = [shipDict oo_boolForKey:@"mass_lockable" defaultValue:YES];
2366 [script autorelease];
2367 NSDictionary *scriptProperties = [NSDictionary dictionaryWithObject:self forKey:@"ship"];
2385 DESTROY(multiFunctionDisplayText);
2386 DESTROY(multiFunctionDisplaySettings);
2398 DESTROY(worldScriptsRequiringTickle);
2406 DESTROY(marketSelectedCommodity);
2420 DESTROY(_missionOverlayDescriptor);
2421 DESTROY(_missionBackgroundDescriptor);
2422 DESTROY(_equipScreenBackgroundDescriptor);
2440 [
self destroySound];
2456 DESTROY(customEquipActivation);
2457 DESTROY(customActivatePressed);
2466- (NSUInteger) sessionID
2469 return [UNIVERSE sessionID];
2473- (void) warnAboutHostiles
2475 [
self playHostileWarning];
2481 switch ([
self status])
2483 case STATUS_START_GAME:
2484 case STATUS_DOCKING:
2487 case STATUS_ESCAPE_SEQUENCE:
2496- (NSComparisonResult) compareZeroDistance:(
Entity *)otherEntity
2498 return NSOrderedDescending;
2502- (BOOL) validForAddToUniverse
2508- (GLfloat) lookingAtSunWithThresholdAngleCos:(GLfloat) thresholdAngleCos
2511 GLfloat measuredCos = 999.0f, measuredCosAbs;
2512 GLfloat sunBrightness = 0.0f;
2513 Vector relativePosition, unitRelativePosition;
2518 OOViewID vdir = [UNIVERSE viewDirection];
2520 unsigned ent_count =
UNIVERSE->n_entities;
2522 for (i = 0; i < ent_count; i++)
2524 if (uni_entities[i]->isSunlit)
2526 if ([uni_entities[i] isPlanet] ||
2527 ([uni_entities[i] isShip] &&
2528 [uni_entities[i] isVisible]))
2531 if (
EXPECT(vdir > VIEW_STARBOARD || ![uni_entities[i] isPlayer]))
2533 float shadow = 1.5f;
2545 relativePosition = HPVectorToVector(HPvector_subtract([
self viewpointPosition], [sun position]));
2546 unitRelativePosition = vector_normal_or_zbasis(relativePosition);
2550 measuredCos = -dot_product(unitRelativePosition, v_forward);
2553 measuredCos = +dot_product(unitRelativePosition, v_forward);
2556 measuredCos = +dot_product(unitRelativePosition, v_right);
2558 case VIEW_STARBOARD:
2559 measuredCos = -dot_product(unitRelativePosition, v_right);
2563 Vector relativeView = [
self customViewForwardVector];
2565 measuredCos = -dot_product(unitRelativePosition, absoluteView);
2572 measuredCosAbs = fabs(measuredCos);
2579 if (thresholdAngleCos <= measuredCosAbs && measuredCosAbs <= 1.1f)
2581 sunBrightness = (measuredCos - thresholdAngleCos) / (1.0f - thresholdAngleCos);
2583 if (sunBrightness < 0.0f) sunBrightness = 0.0f;
2584 else if (sunBrightness > 1.0f) sunBrightness = 1.0f;
2587 return sunBrightness * sunBrightness * sunBrightness;
2591- (GLfloat) insideAtmosphereFraction
2593 GLfloat insideAtmoFrac = 0.0f;
2595 if ([
UNIVERSE airResistanceFactor] > 0.01)
2600 return insideAtmoFrac;
2605#define STAGE_TRACKING_BEGIN { \
2606 NSString * volatile updateStage = @"initialisation"; \
2608#define STAGE_TRACKING_END } \
2609 @catch (NSException *exception) \
2611 OOLog(kOOLogException, @"***** Exception during [%@] in %s : %@ : %@ *****", updateStage, __PRETTY_FUNCTION__, [exception name], [exception reason]); \
2615#define UPDATE_STAGE(x) do { updateStage = (x); } while (0)
2617#define STAGE_TRACKING_BEGIN {
2618#define STAGE_TRACKING_END }
2619#define UPDATE_STAGE(x) do { (void) (x); } while (0);
2628 [
self updateMovementFlags];
2630 [
self updateAlertCondition];
2632 [
self updateFuelScoops:delta_t];
2635 [
self updateClocks:delta_t];
2641 [
self checkScriptsIfAppropriate];
2645 [
self manageCollisions];
2648 [
self pollControls:delta_t];
2651 [
self updateTrumbles:delta_t];
2656 if (
EXPECT_NOT(status == STATUS_START_GAME &&
2657 gui_screen != GUI_SCREEN_INTRO1 &&
2658 gui_screen != GUI_SCREEN_SHIPLIBRARY &&
2659 gui_screen != GUI_SCREEN_GAMEOPTIONS &&
2660 gui_screen != GUI_SCREEN_STICKMAPPER &&
2661 gui_screen != GUI_SCREEN_STICKPROFILE &&
2662 gui_screen != GUI_SCREEN_NEWGAME &&
2663 gui_screen != GUI_SCREEN_OXZMANAGER &&
2664 gui_screen != GUI_SCREEN_LOAD &&
2665 gui_screen != GUI_SCREEN_KEYBOARD &&
2666 gui_screen != GUI_SCREEN_KEYBOARD_CONFIRMCLEAR &&
2667 gui_screen != GUI_SCREEN_KEYBOARD_CONFIG &&
2668 gui_screen != GUI_SCREEN_KEYBOARD_ENTRY &&
2669 gui_screen != GUI_SCREEN_KEYBOARD_LAYOUT))
2673 [
self setGuiToIntroFirstGo:YES];
2676 if (status == STATUS_AUTOPILOT_ENGAGED || status == STATUS_ESCAPE_SEQUENCE)
2679 [
self performAutopilotUpdates:delta_t];
2681 else if (![
self isDocked])
2684 [
self performInFlightUpdates:delta_t];
2690 if (status == STATUS_IN_FLIGHT)
2693 [
self doBookkeeping:delta_t];
2695 if (status == STATUS_WITCHSPACE_COUNTDOWN)
2698 [
self performWitchspaceCountdownUpdates:delta_t];
2700 if (status == STATUS_EXITING_WITCHSPACE)
2703 [
self performWitchspaceExitUpdates:delta_t];
2705 if (status == STATUS_LAUNCHING)
2708 [
self performLaunchingUpdates:delta_t];
2710 if (status == STATUS_DOCKING)
2713 [
self performDockingUpdates:delta_t];
2715 if (status == STATUS_DEAD)
2718 [
self performDeadUpdates:delta_t];
2722 [
self updateWormholes];
2728- (void) doBookkeeping:(
double) delta_t
2734 static BOOL gettingInterference = NO;
2737 double external_temp = 0;
2738 GLfloat air_friction = 0.0f;
2739 air_friction = 0.5f * [UNIVERSE airResistanceFactor];
2740 if (air_friction < 0.005f)
2746 UPDATE_STAGE(
@"updating weapon temperatures and shot times");
2749 forward_weapon_temp = fdim(forward_weapon_temp, coolAmount);
2750 aft_weapon_temp = fdim(aft_weapon_temp, coolAmount);
2751 port_weapon_temp = fdim(port_weapon_temp, coolAmount);
2752 starboard_weapon_temp = fdim(starboard_weapon_temp, coolAmount);
2755 forward_shot_time += delta_t;
2756 aft_shot_time += delta_t;
2757 port_shot_time += delta_t;
2758 starboard_shot_time += delta_t;
2761 switch (currentWeaponFacing)
2764 weapon_temp = forward_weapon_temp;
2765 shot_time = forward_shot_time;
2768 weapon_temp = aft_weapon_temp;
2769 shot_time = aft_shot_time;
2772 weapon_temp = port_weapon_temp;
2773 shot_time = port_shot_time;
2776 weapon_temp = starboard_weapon_temp;
2777 shot_time = starboard_shot_time;
2785 if ([
self hasCloakingDevice] && cloaking_device_active)
2791 [
self deactivateCloakingDevice];
2795 if ([
self hasMilitaryJammer])
2799 if (military_jammer_active)
2803 military_jammer_active = NO;
2808 military_jammer_active = YES;
2813 if (ecm_in_operation)
2821 ecm_in_operation = NO;
2822 [UNIVERSE addMessage:DESC(@"ecm-out-of-juice") forCount:3.0];
2826 ecm_in_operation = NO;
2835 if ([
self scannerFuzziness] > 0.0)
2837 if (!gettingInterference)
2839 [UNIVERSE setCurrentPostFX:OO_POSTFX_CRTBADSIGNAL];
2840 gettingInterference = YES;
2845 if (gettingInterference)
2847 [UNIVERSE terminatePostFX:OO_POSTFX_CRTBADSIGNAL];
2848 gettingInterference = NO;
2863 energy += [
self energyRechargeRate] * delta_t;
2866 float fwdMax = [
self maxForwardShieldLevel];
2867 float aftMax = [
self maxAftShieldLevel];
2868 float shieldRechargeFwd = [
self forwardShieldRechargeRate] * delta_t;
2869 float shieldRechargeAft = [
self aftShieldRechargeRate] * delta_t;
2878 float rechargeFwd =
MIN(shieldRechargeFwd, fwdMax - forward_shield);
2879 float rechargeAft =
MIN(shieldRechargeAft, aftMax - aft_shield);
2885 float energyForShields = energy;
2886 if( (forward_shield > fwdMax * 0.25) && (aft_shield > aftMax * 0.25) )
2889 float minEnergyBankLevel = [[UNIVERSE globalSettings] oo_floatForKey:@"shield_charge_energybank_threshold" defaultValue:0.25];
2890 energyForShields =
MAX(0.0, energy -0.1 - (maxEnergy * minEnergyBankLevel));
2893 if( forward_shield < aft_shield )
2895 rechargeFwd =
MIN(rechargeFwd, energyForShields);
2896 rechargeAft =
MIN(rechargeAft, energyForShields - rechargeFwd);
2900 rechargeAft =
MIN(rechargeAft, energyForShields);
2901 rechargeFwd =
MIN(rechargeFwd, energyForShields - rechargeAft);
2905 forward_shield += rechargeFwd;
2906 aft_shield += rechargeAft;
2907 energy -= rechargeFwd + rechargeAft;
2909 forward_shield = OOClamp_0_max_f(forward_shield, fwdMax);
2910 aft_shield = OOClamp_0_max_f(aft_shield, aftMax);
2911 energy = OOClamp_0_max_f(energy, maxEnergy);
2920 double alt1 = sun_cr * sun_cr / sun_zd;
2924 external_temp *= 100;
2926 if ([sun willGoNova])
2930 if ([
self hasFuelScoop] && alt1 > 0.75 && [
self fuel] < [
self fuelCapacity])
2932 fuel_accumulator += (float)(delta_t * flightSpeed * 0.010 / [
self fuelChargeRate]);
2934 scoopsActive = YES && flightSpeed > 0.1f;
2935 while (fuel_accumulator > 1.0f)
2937 [
self setFuel:[
self fuel] + 1];
2938 fuel_accumulator -= 1.0f;
2939 [
self doScriptEvent:OOJSID("shipScoopedFuel")];
2941 [UNIVERSE displayCountdownMessage:DESC(@"fuel-scoop-active") forCount:1.0];
2947 if ((status != STATUS_ESCAPE_SEQUENCE) && (status != STATUS_ENTERING_WITCHSPACE))
2952 float heatInsulation = [
self heatInsulation];
2953 float deltaInsulation = delta_t/heatInsulation;
2954 float heatThreshold = heatInsulation * 100.0f;
2955 ship_temperature += (float)( flightSpeed * air_friction * deltaInsulation);
2957 if (external_temp > heatThreshold && external_temp > ship_temperature)
2958 ship_temperature += (float)((external_temp - ship_temperature) *
SHIP_INSULATION_FACTOR * deltaInsulation);
2962 ship_temperature += (float)((external_temp - heatThreshold - ship_temperature) *
SHIP_COOLING_FACTOR * deltaInsulation);
2966 [
self takeHeatDamage: delta_t * ship_temperature];
2974 [
self setBounty:0 withReason:kOOLegalStatusReasonEscapePod];
2976 thrust = max_thrust;
2979 [
self doScriptEvent:OOJSID("escapePodSequenceOver")];
2984 if (
EXPECT_NOT(target_system_id != system_id))
2986 system_id = target_system_id;
2987 info_system_id = target_system_id;
2988 [UNIVERSE setSystemTo:system_id];
2989 galaxy_coordinates =
PointFromString([[
UNIVERSE systemManager] getProperty:
@"coordinates" forSystem:system_id inGalaxy:galaxy_number]);
2991 [UNIVERSE setUpSpace];
2993 [UNIVERSE populateNormalSpace];
2995 [
self setDockTarget:[UNIVERSE station]];
2998 [UNIVERSE setWitchspaceBreakPattern:YES];
2999 [
self doScriptEvent:OOJSID("shipWillExitWitchspace")];
3000 [
self doScriptEvent:OOJSID("shipExitedWitchspace")];
3002 [[UNIVERSE planet] update: 2.34375 * market_rnd];
3003 [[UNIVERSE station] update: 2.34375 * market_rnd];
3006 Entity *dockTargetEntity = [UNIVERSE entityForUniversalID:_dockTarget];
3007 if ([dockTargetEntity isStation])
3011 ShipEntity *player_ship = [UNIVERSE newShipWithName:[
self shipDataKey]];
3015 [
self setMesh:[player_ship
mesh]];
3016 [player_ship release];
3018 [UNIVERSE setViewDirection:VIEW_FORWARD];
3019 [UNIVERSE setBlockJSPlayerShipProps:NO];
3020 [
self enterDock:(StationEntity *)dockTargetEntity];
3024 [
self setStatus:STATUS_DEAD];
3027 [UNIVERSE displayMessage:DESC(@"gameoverscreen-escape-pod") forCount:kDeadResetTime];
3028 [UNIVERSE displayMessage:@"" forCount:kDeadResetTime];
3029 [
self showGameOver];
3035 travelling_at_hyperspeed = (flightSpeed > maxFlightSpeed);
3036 if (hyperspeed_engaged)
3047 hyperspeed_locked = [
self massLocked];
3051 if (hyperspeed_locked)
3053 [
self playJumpMassLocked];
3054 [UNIVERSE addMessage:DESC(@"jump-mass-locked") forCount:4.5];
3055 hyperspeed_engaged = NO;
3060 if (afterburner_engaged)
3064 float abFactor = [
self afterburnerFactor];
3065 float maxInjectionSpeed = maxFlightSpeed * abFactor;
3066 if (flightSpeed > maxInjectionSpeed)
3069 flightSpeed -= (float)(speed_delta * delta_t * abFactor);
3073 if (flightSpeed < maxInjectionSpeed)
3074 flightSpeed += (float)(speed_delta * delta_t * abFactor);
3075 if (flightSpeed > maxInjectionSpeed)
3076 flightSpeed = maxInjectionSpeed;
3078 fuel_accumulator -= (float)(delta_t * afterburner_rate);
3079 while ((fuel_accumulator < 0)&&(fuel > 0))
3081 fuel_accumulator += 1.0f;
3083 afterburner_engaged = NO;
3091 if (travelling_at_hyperspeed)
3102 flightSpeed -= deceleration;
3103 if (flightSpeed < maxFlightSpeed)
3104 flightSpeed = maxFlightSpeed;
3112 if ((fuel_leak_rate > 0.0)&&(fuel > 0))
3116 fuel_accumulator -= (float)(fuel_leak_rate * delta_t);
3117 while ((fuel_accumulator < 0)&&(fuel > 0))
3119 fuel_accumulator += 1.0f;
3128 if (scanner_zoom_rate)
3130 double z = [hud scannerZoom];
3131 double z1 = z + scanner_zoom_rate * delta_t;
3132 if (scanner_zoom_rate > 0.0)
3134 if (floor(z1) > floor(z))
3137 scanner_zoom_rate = 0.0f;
3145 scanner_zoom_rate = 0.0f;
3148 [hud setScannerZoom:z1];
3151 [[UNIVERSE gameView] setFov:fieldOfView fromFraction:YES];
3154 ShipEntity *primeTarget = [
self primaryTarget];
3155 if (primeTarget && HPdistance2([primeTarget position], [
self position]) >
SCANNER_MAX_RANGE2 && !autopilot_engaged)
3157 [UNIVERSE addMessage:DESC(@"target-lost") forCount:3.0];
3158 [
self removeTarget:primeTarget];
3161 [
self validateCompassTarget];
3165 totalBoundingBox = boundingBox;
3167 foreach (se, [
self subEntities])
3173 bounding_box_add_vector(&totalBoundingBox, sebb.max);
3174 bounding_box_add_vector(&totalBoundingBox, sebb.min);
3179 if (lastShot !=
nil)
3182 foreach (lse, lastShot)
3193 if (mouseWheelDelta > 0.0f)
3198 else if (mouseWheelDelta < 0.0f)
3208- (void) updateMovementFlags
3210 hasMoved = !HPvector_equal(position, lastPosition);
3211 hasRotated = !quaternion_equal(orientation, lastOrientation);
3212 lastPosition = position;
3213 lastOrientation = orientation;
3217- (void) updateAlertConditionForNearbyEntities
3219 if (![
self isInSpace] || [
self status] == STATUS_DOCKING)
3221 [
self clearAlertFlags];
3226 int i, ent_count =
UNIVERSE->n_entities;
3228 Entity *my_entities[ent_count];
3230 for (i = 0; i < ent_count; i++)
3232 my_entities[i] = [uni_entities[i] retain];
3234 BOOL massLocked = NO;
3235 BOOL foundHostiles = NO;
3236#if OO_VARIABLE_TORUS_SPEED
3237 BOOL needHyperspeedNearest = YES;
3238 double hsnDistance = 0;
3240 for (i = 0; i < ent_count; i++)
3242 scannedEntity = my_entities[i];
3244#if OO_VARIABLE_TORUS_SPEED
3248 if (scannedEntity !=
self && [scannedEntity canCollide] && (![scannedEntity isShip] || ![
self collisionExceptedFor:(
ShipEntity *) scannedEntity]))
3250 hsnDistance = sqrt(scannedEntity->
zero_distance)-[scannedEntity collisionRadius];
3251 needHyperspeedNearest = NO;
3254 else if ([scannedEntity isStellarObject])
3259 double thisHSN = sqrt(scannedEntity->
zero_distance)-[scannedEntity collisionRadius];
3260 if (thisHSN < hsnDistance)
3262 hsnDistance = thisHSN;
3269 int theirClass = [scannedEntity
scanClass];
3273 if ([
self massLockable] )
3275 massLocked |= [
self checkEntityForMassLock:scannedEntity withScanClass:theirClass];
3277 if (theirClass != CLASS_NO_DRAW)
3279 if (theirClass == CLASS_THARGOID || [scannedEntity isCascadeWeapon])
3281 foundHostiles = YES;
3283 else if ([scannedEntity isShip])
3286 foundHostiles |= (([ship
hasHostileTarget])&&([ship primaryTarget] ==
self));
3291#if OO_VARIABLE_TORUS_SPEED
3320 [
self setAlertFlag:ALERT_FLAG_MASS_LOCK to:massLocked];
3322 [
self setAlertFlag:ALERT_FLAG_HOSTILES to:foundHostiles];
3324 for (i = 0; i < ent_count; i++)
3326 [my_entities[i] release];
3329 BOOL energyCritical = NO;
3330 if (energy < 64 && energy < maxEnergy * 0.8)
3332 energyCritical = YES;
3334 [
self setAlertFlag:ALERT_FLAG_ENERGY to:energyCritical];
3336 [
self setAlertFlag:ALERT_FLAG_TEMP to:([
self hullHeatLevel] > .90)];
3338 [
self setAlertFlag:ALERT_FLAG_ALT to:([
self dialAltitude] < .10)];
3343- (void) setMaxFlightPitch:(GLfloat)new
3345 max_flight_pitch =
new;
3346 pitch_delta = 2.0 *
new;
3350- (void) setMaxFlightRoll:(GLfloat)new
3352 max_flight_roll =
new;
3353 roll_delta = 2.0 *
new;
3357- (void) setMaxFlightYaw:(GLfloat)new
3359 max_flight_yaw =
new;
3360 yaw_delta = 2.0 *
new;
3364- (BOOL) checkEntityForMassLock:(
Entity *)ent withScanClass:(
int)theirClass
3366 BOOL massLocked = NO;
3376 double factor = ([stellar
isSun]) ? 2.0 : 4.0;
3379 if (dist < rad*rad*factor || dist < rad*rad + 50000*rad + 625000000 )
3385 else if (theirClass != CLASS_NO_DRAW)
3389 theirClass = CLASS_NO_DRAW;
3399 if (entIsCloakedShip && ![ent isPlayer])
3409 case CLASS_VISUAL_EFFECT:
3412 case CLASS_THARGOID:
3416 case CLASS_MILITARY:
3417 case CLASS_WORMHOLE:
3428- (void) updateAlertCondition
3430 [
self updateAlertConditionForNearbyEntities];
3437 if (cond != lastScriptAlertCondition)
3439 ShipScriptEventNoCx(
self,
"alertConditionChanged", INT_TO_JSVAL(cond), INT_TO_JSVAL(lastScriptAlertCondition));
3440 lastScriptAlertCondition = cond;
3467 else if ((fleeing_status ==
PLAYER_FLEEING_MAYBE || fleeing_status ==
PLAYER_FLEEING_CARGO) && cond ==
ALERT_CONDITION_RED && last_shot_time + 10 < t && flightSpeed > 0.75*maxFlightSpeed && energy < maxEnergy * 0.5 && (forward_shield < [
self maxForwardShieldLevel]*0.25 || aft_shield < [
self maxAftShieldLevel]*0.25))
3478 [
self updateFuelScoopSoundWithInterval:delta_t];
3479 if (![
self scoopOverride])
3482 [
self updateFuelScoopSoundWithInterval:delta_t];
3491 shot_time += delta_t;
3492 script_time += delta_t;
3493 unsigned prev_day = floor(ship_clock / 86400);
3494 ship_clock += delta_t;
3495 if (ship_clock_adjust > 0.0)
3497 double fine_adjust = delta_t * 7200.0;
3498 if (ship_clock_adjust > 86400)
3499 fine_adjust = delta_t * 115200.0;
3500 if (ship_clock_adjust > 0)
3502 if (fine_adjust > ship_clock_adjust)
3503 fine_adjust = ship_clock_adjust;
3504 ship_clock += fine_adjust;
3505 ship_clock_adjust -= fine_adjust;
3509 if (fine_adjust < ship_clock_adjust)
3510 fine_adjust = ship_clock_adjust;
3511 ship_clock -= fine_adjust;
3512 ship_clock_adjust += fine_adjust;
3516 ship_clock_adjust = 0.0;
3518 unsigned now_day = floor(ship_clock / 86400.0);
3519 while (prev_day < now_day)
3522 [
self doScriptEvent:OOJSID("dayChanged") withArgument:[NSNumber numberWithUnsignedInt:prev_day]];
3528 if (ship_clock > fps_check_time)
3530 if (![
self clockAdjusting])
3532 fps_counter = (
int)([
UNIVERSE timeAccelerationFactor] * floor([
UNIVERSE framesDoneThisUpdate] / (fps_check_time - last_fps_check_time)));
3533 last_fps_check_time = fps_check_time;
3540 fps_counter = (
int)([
UNIVERSE timeAccelerationFactor] * floor(1.0 / delta_t));
3543 [UNIVERSE resetFramesDoneThisUpdate];
3548- (void) checkScriptsIfAppropriate
3550 if (script_time <= script_time_check)
return;
3552 if ([
self status] != STATUS_IN_FLIGHT)
3557 case GUI_SCREEN_MAIN:
3558 case GUI_SCREEN_INTRO1:
3559 case GUI_SCREEN_SHIPLIBRARY:
3560 case GUI_SCREEN_KEYBOARD:
3561 case GUI_SCREEN_NEWGAME:
3562 case GUI_SCREEN_OXZMANAGER:
3563 case GUI_SCREEN_MARKET:
3564 case GUI_SCREEN_MARKETINFO:
3565 case GUI_SCREEN_OPTIONS:
3566 case GUI_SCREEN_GAMEOPTIONS:
3567 case GUI_SCREEN_LOAD:
3568 case GUI_SCREEN_SAVE:
3569 case GUI_SCREEN_SAVE_OVERWRITE:
3570 case GUI_SCREEN_STICKMAPPER:
3571 case GUI_SCREEN_STICKPROFILE:
3572 case GUI_SCREEN_MISSION:
3573 case GUI_SCREEN_REPORT:
3574 case GUI_SCREEN_KEYBOARD_CONFIRMCLEAR:
3575 case GUI_SCREEN_KEYBOARD_CONFIG:
3576 case GUI_SCREEN_KEYBOARD_ENTRY:
3577 case GUI_SCREEN_KEYBOARD_LAYOUT:
3582 case GUI_SCREEN_EQUIP_SHIP:
3583 case GUI_SCREEN_INTERFACES:
3584 case GUI_SCREEN_MANIFEST:
3585 case GUI_SCREEN_SHIPYARD:
3586 case GUI_SCREEN_LONG_RANGE_CHART:
3587 case GUI_SCREEN_SHORT_RANGE_CHART:
3588 case GUI_SCREEN_STATUS:
3589 case GUI_SCREEN_SYSTEM_DATA:
3597 script_time_check += script_time_interval;
3603 OOTrumble **trumbles = [
self trumbleArray];
3606 for (i = [
self trumbleCount] ; i > 0; i--)
3614- (void) performAutopilotUpdates:(
OOTimeDelta)delta_t
3616 [
self processBehaviour:delta_t];
3617 [
self applyVelocity:delta_t];
3618 [
self doBookkeeping:delta_t];
3621- (void) performDockingRequest:(
StationEntity *)stationForDocking
3623 if (stationForDocking ==
nil)
return;
3624 if (![stationForDocking isStation] || ![stationForDocking isKindOfClass:[
StationEntity class]]) return;
3625 if ([
self isDocked])
return;
3626 if (autopilot_engaged && [
self targetStation] == stationForDocking)
return;
3627 if (autopilot_engaged && [
self targetStation] != stationForDocking)
3629 [
self disengageAutopilot];
3632 if (stationDockingClearanceStatus !=
nil)
3634 [
self doScriptEvent:OOJSID("playerRequestedDockingClearance") withArgument:stationDockingClearanceStatus];
3635 if ([stationDockingClearanceStatus isEqualToString:
@"DOCKING_CLEARANCE_GRANTED"])
3637 [
self doScriptEvent:OOJSID("playerDockingClearanceGranted")];
3642- (void) requestDockingClearance:(
StationEntity *)stationForDocking
3646 [
self performDockingRequest:stationForDocking];
3650- (void) cancelDockingRequest:(
StationEntity *)stationForDocking
3652 if (stationForDocking ==
nil)
return;
3653 if (![stationForDocking isStation] || ![stationForDocking isKindOfClass:[
StationEntity class]]) return;
3654 if ([
self isDocked])
return;
3655 if (autopilot_engaged && [
self targetStation] == stationForDocking)
return;
3656 if (autopilot_engaged && [
self targetStation] != stationForDocking)
3658 [
self disengageAutopilot];
3663 if (stationDockingClearanceStatus !=
nil && [stationDockingClearanceStatus isEqualToString:
@"DOCKING_CLEARANCE_CANCELLED"])
3665 [
self doScriptEvent:OOJSID("playerDockingClearanceCancelled")];
3670- (BOOL) engageAutopilotToStation:(
StationEntity *)stationForDocking
3672 if (stationForDocking ==
nil)
return NO;
3673 if ([
self isDocked])
return NO;
3675 if (autopilot_engaged && [
self targetStation] == stationForDocking)
3680 [
self setTargetStation:stationForDocking];
3682 autopilot_engaged = YES;
3684 [
self safeAllMissiles];
3686 if ([
self status] == STATUS_WITCHSPACE_COUNTDOWN) [
self cancelWitchspaceCountdown];
3687 [
self setStatus:STATUS_AUTOPILOT_ENGAGED];
3688 [
self resetAutopilotAI];
3689 [shipAI setState:@"BEGIN_DOCKING"];
3690 [
self playAutopilotOn];
3692 [
self doScriptEvent:OOJSID("playerStartedAutoPilot") withArgument:stationForDocking];
3693 [
self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_GRANTED];
3695 if (afterburner_engaged)
3697 afterburner_engaged = NO;
3698 if (afterburnerSoundLooping) [
self stopAfterburnerSound];
3705- (void) disengageAutopilot
3707 if (autopilot_engaged)
3709 [
self abortDocking];
3710 behaviour = BEHAVIOUR_IDLE;
3712 autopilot_engaged = NO;
3714 [
self setTargetStation:nil];
3715 [
self setStatus:STATUS_IN_FLIGHT];
3716 [
self playAutopilotOff];
3717 [
self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
3719 [
self doScriptEvent:OOJSID("playerCancelledAutoPilot")];
3721 [
self resetAutopilotAI];
3726- (void) resetAutopilotAI
3728 AI *myAI = [
self getAI];
3732 [
self setAITo:PLAYER_DOCKING_AI_NAME ];
3741#define VELOCITY_CLEANUP_MIN 2000.0f
3742#define VELOCITY_CLEANUP_FULL 5000.0f
3743#define VELOCITY_CLEANUP_RATE 0.001f
3746#if OO_VARIABLE_TORUS_SPEED
3747- (GLfloat) hyperspeedFactor
3749 return hyperspeedFactor;
3754- (BOOL) injectorsEngaged
3756 return afterburner_engaged;
3760- (BOOL) hyperspeedEngaged
3762 return hyperspeed_engaged;
3766- (void) performInFlightUpdates:(
OOTimeDelta)delta_t
3775 [
self applyVelocity:delta_t];
3777 GLfloat thrust_factor = 1.0;
3778 if (flightSpeed > maxFlightSpeed)
3780 if (afterburner_engaged)
3782 thrust_factor = [
self afterburnerFactor];
3791 GLfloat velmag = magnitude(velocity);
3792 GLfloat velmag2 = velmag - (float)delta_t * thrust * thrust_factor;
3803 velmag2 -= velmag * rate;
3806 else velocity = vector_multiply_scalar(velocity, velmag2 / velmag);
3811 [
self applyRoll:(float)delta_t*flightRoll andClimb:(float)delta_t*flightPitch];
3812 if (flightYaw != 0.0)
3814 [
self applyYaw:(float)delta_t*flightYaw];
3818 [
self moveForward:delta_t*flightSpeed];
3821 [
self updateTargeting];
3827- (void) performWitchspaceCountdownUpdates:(
OOTimeDelta)delta_t
3832 [
self doBookkeeping:delta_t];
3835 witchspaceCountdown = fdim(witchspaceCountdown, delta_t);
3841 if (
EXPECT_NOT(galactic_witchjump && ![
self hasEquipmentItem:
@"EQ_GAL_DRIVE"]))
3843 galactic_witchjump = NO;
3844 [
self setStatus:STATUS_IN_FLIGHT];
3845 [
self playHyperspaceAborted];
3850 int seconds = round(witchspaceCountdown);
3851 if (galactic_witchjump)
3853 [UNIVERSE displayCountdownMessage:OOExpandKey(@"witch-galactic-in-x-seconds", seconds) forCount:1.0];
3857 NSString *destination = [UNIVERSE getSystemName:[
self nextHopTargetSystemID]];
3858 [UNIVERSE displayCountdownMessage:OOExpandKey(@"witch-to-x-in-y-seconds", seconds, destination) forCount:1.0];
3861 if (witchspaceCountdown == 0.0)
3864 if (!galactic_witchjump)
3874 [UNIVERSE preloadPlanetTexturesForSystem:target_system_id];
3882 if (galactic_witchjump) [
self enterGalacticWitchspace];
3883 else [
self enterWitchspace];
3884 galactic_witchjump = NO;
3891- (void) performWitchspaceExitUpdates:(
OOTimeDelta)delta_t
3895 [
self resetExhaustPlumes];
3899 [
self resetScriptTimer];
3904 [UNIVERSE addMessage:[NSString stringWithFormat:@" %@. ",[UNIVERSE getSystemName:system_id]] forCount:3.0];
3906 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_COMPASS"])
3907 compassMode = COMPASS_MODE_PLANET;
3909 compassMode = COMPASS_MODE_BASIC;
3913 if ([
UNIVERSE inInterstellarSpace]) [UNIVERSE addMessage:DESC(@"witch-engine-malfunction") forCount:3.0];
3916 [
self setStatus:STATUS_IN_FLIGHT];
3921 if ([
self scriptedMisjump]) [
self setScriptedMisjump:NO];
3923 [
self setScriptedMisjumpRange:0.5];
3925 [
self doScriptEvent:OOJSID("shipExitedWitchspace") withArgument:[
self jumpCause]];
3927 [
self doBookkeeping:delta_t];
3929 suppressAegisMessages=NO;
3934- (void) performLaunchingUpdates:(
OOTimeDelta)delta_t
3938 flightRoll = launchRoll;
3939 [
self doBookkeeping:delta_t];
3948 [
self setStatus:STATUS_IN_FLIGHT];
3950 [
self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
3951 StationEntity *stationLaunchedFrom = [UNIVERSE nearestEntityMatchingPredicate:IsStationPredicate parameter:NULL relativeToEntity:self];
3952 [
self doScriptEvent:OOJSID("shipLaunchedFromStation") withArgument:stationLaunchedFrom];
3957- (void) performDockingUpdates:(
OOTimeDelta)delta_t
3965 [UNIVERSE terminatePostFX:OO_POSTFX_CLOAK];
3966 if ([
UNIVERSE ECMVisualFXEnabled]) [UNIVERSE terminatePostFX:OO_POSTFX_CRTBADSIGNAL];
3972 [UNIVERSE terminatePostFX:OO_POSTFX_CLOAK];
3973 if ([
UNIVERSE ECMVisualFXEnabled]) [UNIVERSE terminatePostFX:OO_POSTFX_CRTBADSIGNAL];
3975 [
self gameOverFadeToBW];
3979 BOOL was_mouse_control_on = mouse_control_on;
3980 [UNIVERSE handleGameOver];
3981 mouse_control_on = was_mouse_control_on;
3986- (void) gameOverFadeToBW
3988 float secondsToBWFadeOut = [[NSUserDefaults standardUserDefaults] oo_floatForKey:@"gameover-seconds-to-bw-fadeout" defaultValue:5.0f];
3992 static float originalColorSaturation = -1.0f;
3993 if (originalColorSaturation == -1.0f) originalColorSaturation = [gameView
colorSaturation];
3994 if ([
self shotTime] < secondsToBWFadeOut)
3998 if (fps_counter != 0)
4000 [gameView
adjustColorSaturation:-(originalColorSaturation * (1.0f / secondsToBWFadeOut) * [UNIVERSE timeAccelerationFactor] / fps_counter)];
4010 originalColorSaturation = -1.0f;
4019- (BOOL)isValidTarget:(
Entity*)target
4030 if ([target isShip])
4033 if ([targetShip isCloaked] ||
4034 ([targetShip isJammingScanning] && ![
self hasMilitaryScannerFilter]))
4039 if (tstatus == STATUS_ENTERING_WITCHSPACE || tstatus == STATUS_IN_HOLD || tstatus == STATUS_DOCKED)
4047 if ([target isWormhole] && [target scanClass] != CLASS_NO_DRAW &&
4048 [
self hasEquipmentItemProviding:
@"EQ_WORMHOLE_SCANNER"] && ident_engaged)
4058- (void) showGameOver
4060 [hud resetGuis:[NSDictionary dictionaryWithObject:[NSDictionary dictionary] forKey:@"message_gui"]];
4061 NSString *scoreMS = [NSString stringWithFormat:OOExpandKey(@"gameoverscreen-score-@"),
4062 KillCountToRatingAndKillString(ship_kills)];
4064 [UNIVERSE displayMessage:OOExpandKey(@"gameoverscreen-game-over") forCount:kDeadResetTime];
4065 [UNIVERSE displayMessage:@"" forCount:kDeadResetTime];
4066 [UNIVERSE displayMessage:scoreMS forCount:kDeadResetTime];
4067 [UNIVERSE displayMessage:@"" forCount:kDeadResetTime];
4068 [UNIVERSE displayMessage:OOExpandKey(@"gameoverscreen-press-space") forCount:kDeadResetTime];
4069 [UNIVERSE displayMessage:@" " forCount:kDeadResetTime];
4070 [UNIVERSE displayMessage:@"" forCount:kDeadResetTime];
4071 [
self resetShotTime];
4075- (void) showShipModelWithKey:(NSString *)shipKey shipData:(NSDictionary *)shipData personality:(uint16_t)personality factorX:(GLfloat)factorX factorY:(GLfloat)factorY factorZ:(GLfloat)factorZ inContext:(NSString *)context
4077 if (shipKey ==
nil)
return;
4079 if (shipData ==
nil)
return;
4081 Quaternion q2 = { (GLfloat)
M_SQRT1_2, (GLfloat)
M_SQRT1_2, (GLfloat)0.0f, (GLfloat)0.0f };
4083 if( demoShip !=
nil )
4085 q2 = [demoShip orientation];
4094 if (context)
OOLog(
@"script.debug.note.showShipModel",
@"::::: showShipModel:'%@' in context: %@.", [ship name], context);
4103 [ship
setAITo: @"nullAI.plist"];
4104 id subEntStatus = [shipData objectForKey:@"subentities_status"];
4107 [UNIVERSE addEntity: ship];
4109 demoShip = [ship retain];
4111 [ship
setStatus: STATUS_COCKPIT_DISPLAY];
4120- (void) doGuiScreenResizeUpdates
4122 switch ([
self guiScreen])
4124 case GUI_SCREEN_GAMEOPTIONS:
4126 [
self setGuiToGameOptionsScreen];
4128 case GUI_SCREEN_STATUS:
4131 [
self setGuiToStatusScreen];
4138 [hud resetGuiPositions];
4148- (void) updateTargeting
4154 if (ident_engaged && [
self primaryTarget] !=
nil)
4156 if (![
self isValidTarget:[
self primaryTarget]])
4158 if (!suppressTargetLost)
4160 [UNIVERSE addMessage:DESC(@"target-lost") forCount:3.0];
4161 [
self playTargetLost];
4162 [
self noteLostTarget];
4166 suppressTargetLost = NO;
4178 for (i = 0; i < max_missiles; i++)
4180 if ([missile_entity[i] primaryTarget] !=
nil &&
4181 ![
self isValidTarget:[missile_entity[i] primaryTarget]])
4183 [UNIVERSE addMessage:DESC(@"target-lost") forCount:3.0];
4184 [
self playTargetLost];
4185 [missile_entity[i] removeTarget:nil];
4186 if (i == activeMissile)
4188 [
self noteLostTarget];
4192 }
else if (i == activeMissile && [missile_entity[i] primaryTarget] ==
nil) {
4201 if ([
self primaryTarget] ==
nil &&
4203 ([
self status] == STATUS_IN_FLIGHT || [
self status] == STATUS_WITCHSPACE_COUNTDOWN))
4205 Entity *target = [UNIVERSE firstEntityTargetedByPlayer];
4206 if ([
self isValidTarget:target])
4208 [
self addTarget:target];
4214 UPDATE_STAGE(
@"checking for additional wormhole information");
4215 if ([[
self primaryTarget] isWormhole])
4218 switch ([wh scanInfo])
4232 if ([
self clockTimeAdjusted] > [wh scanTime] + 2)
4240 if([
self clockTimeAdjusted] > [wh scanTime] + 4)
4243 [UNIVERSE addCommsMessage:[NSString stringWithFormat:DESC(@"wormhole-arrival-time-computed-@"),
4248 if ([
self clockTimeAdjusted] > [wh scanTime] + 7)
4251 [UNIVERSE addCommsMessage:[NSString stringWithFormat:DESC(@"wormhole-destination-computed-@"),
4252 [UNIVERSE getSystemName:[wh
destination]]] forCount:5.0];
4256 if ([
self clockTimeAdjusted] > [wh scanTime] + 10)
4271- (void) orientationChanged
4273 quaternion_normalize(&orientation);
4275 OOMatrixGetBasisVectors(rotMatrix, &v_right, &v_up, &v_forward);
4277 orientation.w = -orientation.w;
4279 orientation.w = -orientation.w;
4283- (void) applyAttitudeChanges:(
double) delta_t
4285 [
self applyRoll:flightRoll*delta_t andClimb:flightPitch*delta_t];
4286 [
self applyYaw:flightYaw*delta_t];
4290- (void) applyRoll:(GLfloat) roll1 andClimb:(GLfloat) climb1
4292 if (roll1 == 0.0 && climb1 == 0.0 && hasRotated == NO)
4307 orientation = lastOrientation;
4315 [
self orientationChanged];
4323- (void) applyYaw:(GLfloat) yaw
4327 [
self orientationChanged];
4331- (OOMatrix) drawRotationMatrix
4333 return playerRotMatrix;
4337- (OOMatrix) drawTransformationMatrix
4339 OOMatrix result = playerRotMatrix;
4341 return OOMatrixTranslate(result, HPVectorToVector(position));
4345- (Quaternion) normalOrientation
4347 return make_quaternion(-orientation.w, orientation.x, orientation.y, orientation.z);
4351- (void) setNormalOrientation:(Quaternion) quat
4353 [
self setOrientation:make_quaternion(-quat.w, quat.x, quat.y, quat.z)];
4357- (void) moveForward:(
double) amount
4359 distanceTravelled += (float)amount;
4360 [
self setPosition:HPvector_add(position, vectorToHPVector(vector_multiply_scalar(v_forward, (float)amount)))];
4364- (HPVector) breakPatternPosition
4366 return HPvector_add(position,vectorToHPVector(
quaternion_rotate_vector(quaternion_conjugate(orientation),forwardViewOffset)));
4370- (Vector) viewpointOffset
4379 return forwardViewOffset;
4381 return aftViewOffset;
4383 return portViewOffset;
4384 case VIEW_STARBOARD:
4385 return starboardViewOffset;
4388 return customViewOffset;
4399- (Vector) viewpointOffsetAft
4401 return aftViewOffset;
4404- (Vector) viewpointOffsetForward
4406 return forwardViewOffset;
4409- (Vector) viewpointOffsetPort
4411 return portViewOffset;
4414- (Vector) viewpointOffsetStarboard
4416 return starboardViewOffset;
4422- (HPVector) viewpointPosition
4424 HPVector viewpoint = position;
4429 Vector
offset = [
self viewpointOffset];
4432 OOMatrix r = rotMatrix;
4434 viewpoint.x +=
offset.
x * r.m[0][0]; viewpoint.y +=
offset.
x * r.m[1][0]; viewpoint.z +=
offset.
x * r.m[2][0];
4435 viewpoint.x +=
offset.
y * r.m[0][1]; viewpoint.y +=
offset.
y * r.m[1][1]; viewpoint.z +=
offset.
y * r.m[2][1];
4436 viewpoint.x +=
offset.z * r.m[0][2]; viewpoint.y +=
offset.z * r.m[1][2]; viewpoint.z +=
offset.z * r.m[2][2];
4442- (void) drawImmediate:(
bool)immediate translucent:(
bool)translucent
4444 switch ([
self status])
4447 case STATUS_COCKPIT_DISPLAY:
4449 case STATUS_START_GAME:
4453 if ([
UNIVERSE breakPatternHide])
return;
4456 [
super drawImmediate:immediate translucent:translucent];
4460- (void) setMassLockable:(BOOL)newValue
4462 massLockable = !!newValue;
4463 [
self updateAlertCondition];
4467- (BOOL) massLockable
4469 return massLockable;
4479- (BOOL) atHyperspeed
4481 return travelling_at_hyperspeed;
4485- (float) occlusionLevel
4487 return occlusion_dial;
4491- (void) setOcclusionLevel:(
float)level
4493 occlusion_dial = level;
4497- (void) setDockedAtMainStation
4499 [
self setDockedStation:[UNIVERSE station]];
4500 if (_dockedStation !=
nil) [
self setStatus:STATUS_DOCKED];
4506 return [_dockedStation weakRefUnderlyingObject];
4512 [_dockedStation release];
4519 targetDockStation = value;
4525 return targetDockStation;
4539 NSString *hud_desc = [shipDict oo_stringForKey:@"hud" defaultValue:@"hud.plist"];
4540 if (![
self switchHudTo:hud_desc]) [
self switchHudTo:
@"hud.plist"];
4544- (BOOL) switchHudTo:(NSString *)hudFileName
4546 NSDictionary *hudDict =
nil;
4547 BOOL wasHidden = NO;
4548 BOOL wasCompassActive = YES;
4549 double scannerZoom = 1.0;
4550 NSUInteger lastMFD = 0;
4553 if (!hudFileName)
return NO;
4556 if (hud !=
nil && [hud isUpdating])
4558 [hud setDeferredHudName:hudFileName];
4566 OOLog(
@"PlayerEntity.switchHudTo.failed",
@"HUD dictionary file %@ to switch to not found or invalid.", hudFileName);
4573 wasHidden = [hud isHidden];
4574 wasCompassActive = [hud isCompassActive];
4575 scannerZoom = [hud scannerZoom];
4576 lastMFD = activeMFD;
4582 [hud setHidden:YES];
4584 hud = [[
HeadUpDisplay alloc] initWithDictionary:hudDict inFile:hudFileName];
4585 [hud resetGuis:hudDict];
4587 [hud setScannerZoom:scannerZoom];
4588 [hud setCompassActive:wasCompassActive];
4589 [hud setHidden:wasHidden];
4591 NSArray *savedMFDs = [NSArray arrayWithArray:multiFunctionDisplaySettings];
4592 [multiFunctionDisplaySettings removeAllObjects];
4593 for (i = 0; i < [hud mfdCount] ; i++)
4595 if ([savedMFDs
count] > i)
4597 [multiFunctionDisplaySettings addObject:[savedMFDs objectAtIndex:i]];
4601 [multiFunctionDisplaySettings addObject:[NSNull null]];
4604 if (lastMFD < [hud mfdCount]) activeMFD = lastMFD;
4611- (float) dialCustomFloat:(NSString *)dialKey
4613 return [customDialSettings oo_floatForKey:dialKey defaultValue:0.0];
4617- (NSString *) dialCustomString:(NSString *)dialKey
4619 return [customDialSettings oo_stringForKey:dialKey defaultValue:@""];
4623- (
OOColor *) dialCustomColor:(NSString *)dialKey
4629- (void) setDialCustom:(
id)value forKey:(NSString *)dialKey
4631 [customDialSettings setObject:value forKey:dialKey];
4635- (void) setShowDemoShips:(BOOL)value
4637 showDemoShips = value;
4641- (BOOL) showDemoShips
4643 return showDemoShips;
4647- (float) maxForwardShieldLevel
4649 return max_forward_shield;
4653- (float) maxAftShieldLevel
4655 return max_aft_shield;
4659- (float) forwardShieldRechargeRate
4661 return forward_shield_recharge_rate;
4665- (float) aftShieldRechargeRate
4667 return aft_shield_recharge_rate;
4671- (void) setMaxForwardShieldLevel:(
float)new
4673 max_forward_shield =
new;
4677- (void) setMaxAftShieldLevel:(
float)new
4679 max_aft_shield =
new;
4683- (void) setForwardShieldRechargeRate:(
float)new
4685 forward_shield_recharge_rate =
new;
4689- (void) setAftShieldRechargeRate:(
float)new
4691 aft_shield_recharge_rate =
new;
4695- (GLfloat) forwardShieldLevel
4697 return forward_shield;
4701- (GLfloat) aftShieldLevel
4707- (void) setForwardShieldLevel:(GLfloat)level
4709 forward_shield = OOClamp_0_max_f(level, [
self maxForwardShieldLevel]);
4713- (void) setAftShieldLevel:(GLfloat)level
4715 aft_shield = OOClamp_0_max_f(level, [
self maxAftShieldLevel]);
4719- (NSDictionary *) keyConfig
4722 return keyconfig2_settings;
4726- (BOOL) isMouseControlOn
4728 return mouse_control_on;
4734 GLfloat result = flightRoll / max_flight_roll;
4735 if ((result < 1.0f)&&(result > -1.0f))
4743- (GLfloat) dialPitch
4745 GLfloat result = flightPitch / max_flight_pitch;
4746 if ((result < 1.0f)&&(result > -1.0f))
4756 GLfloat result = -flightYaw / max_flight_yaw;
4757 if ((result < 1.0f)&&(result > -1.0f))
4765- (GLfloat) dialSpeed
4767 GLfloat result = flightSpeed / maxFlightSpeed;
4768 return OOClamp_0_1_f(result);
4772- (GLfloat) dialHyperSpeed
4774 return flightSpeed / maxFlightSpeed;
4778- (GLfloat) dialForwardShield
4780 if (
EXPECT_NOT([
self maxForwardShieldLevel] <= 0))
4784 GLfloat result = forward_shield / [
self maxForwardShieldLevel];
4785 return OOClamp_0_1_f(result);
4789- (GLfloat) dialAftShield
4791 if (
EXPECT_NOT([
self maxAftShieldLevel] <= 0))
4795 GLfloat result = aft_shield / [
self maxAftShieldLevel];
4796 return OOClamp_0_1_f(result);
4800- (GLfloat) dialEnergy
4802 GLfloat result = energy / maxEnergy;
4803 return OOClamp_0_1_f(result);
4807- (GLfloat) dialMaxEnergy
4817 if (fuel > [
self fuelCapacity])
4819 return (GLfloat)fuel / (GLfloat)[
self fuelCapacity];
4823- (GLfloat) dialHyperRange
4825 if (target_system_id == system_id && ![
UNIVERSE inInterstellarSpace])
return 0.0f;
4830- (GLfloat) laserHeatLevel
4833 return OOClamp_0_1_f(result);
4837- (GLfloat)laserHeatLevelAft
4840 return OOClamp_0_1_f(result);
4844- (GLfloat)laserHeatLevelForward
4848 return OOClamp_0_1_f(result);
4852- (GLfloat)laserHeatLevelPort
4855 return OOClamp_0_1_f(result);
4859- (GLfloat)laserHeatLevelStarboard
4862 return OOClamp_0_1_f(result);
4868- (GLfloat) dialAltitude
4870 if ([
self isDocked])
return 0.0f;
4875 Entity *nearestPlanet = [
self findNearestStellarBody];
4876 if (nearestPlanet ==
nil)
return 1.0f;
4880 GLfloat alt = sqrt(zd) - cr;
4892- (double) clockTimeAdjusted
4894 return ship_clock + ship_clock_adjust;
4898- (BOOL) clockAdjusting
4900 return ship_clock_adjust > 0;
4904- (void) addToAdjustTime:(
double)seconds
4906 ship_clock_adjust += seconds;
4910- (double) escapePodRescueTime
4912 return escape_pod_rescue_time;
4916- (void) setEscapePodRescueTime:(
double)seconds
4918 escape_pod_rescue_time = seconds;
4921- (NSString *) dial_clock
4927- (NSString *) dial_clock_adjusted
4933- (NSString *) dial_fpsinfo
4935 unsigned fpsVal = fps_counter;
4936 return [NSString stringWithFormat:@"FPS: %3d", fpsVal];
4940- (NSString *) dial_objinfo
4942 NSString *result = [NSString stringWithFormat:@"Entities: %3llu", [UNIVERSE entityCount]];
4944 result = [NSString stringWithFormat:@"%@ (%d, %zu KiB, avg %zu bytes)", result, gLiveEntityCount, gTotalEntityMemory >> 10, gTotalEntityMemory / gLiveEntityCount];
4951- (unsigned) countMissiles
4953 unsigned n_missiles = 0;
4955 for (i = 0; i < max_missiles; i++)
4957 if (missile_entity[i])
4966 if ([
self weaponsOnline])
4968 return missile_status;
4975 OOLogERR(
@"player.missilesUnsafe",
@"%@",
@"Missile state is not SAFE when weapons are offline. This is a bug, please report it.");
4976 [
self safeAllMissiles];
4985 if (specialCargo)
return NO;
4986 return [
super canScoop:other];
4994 if ([
self hasScoop])
4998 if (cargoOnBoard >= [
self maxAvailableCargoSpace] || specialCargo)
5009- (float) fuelLeakRate
5011 return fuel_leak_rate;
5015- (void) setFuelLeakRate:(
float)value
5017 fuel_leak_rate = fmax(value, 0.0f);
5021- (NSMutableArray *) commLog
5027 NSUInteger
count = [commLog count];
5030 [commLog removeObjectsInRange:NSMakeRange(0, count - kCommLogTrimSize)];
5035 commLog = [[NSMutableArray alloc] init];
5042- (NSMutableArray *) roleWeights
5048- (void) addRoleForAggression:(
ShipEntity *)victim
5050 if ([victim isExplicitlyUnpiloted] || [victim isHulk] || [victim hasHostileTarget] || [[victim primaryAggressor] isPlayer])
5054 NSString *role =
nil;
5055 if ([[victim primaryRole] isEqualToString:
@"escape-capsule"])
5057 role =
@"assassin-player";
5059 else if ([victim bounty] > 0)
5063 else if ([victim isPirateVictim])
5067 else if ([
UNIVERSE role:[
self primaryRole] isInCategory:
@"oolite-hunter"] || [victim scanClass] == CLASS_POLICE)
5069 role =
@"pirate-interceptor";
5075 NSUInteger times = [roleWeightFlags oo_intForKey:role defaultValue:0];
5077 [roleWeightFlags setObject:[NSNumber numberWithUnsignedInteger:times] forKey:role];
5078 if ((times & (times-1)) == 0)
5080 [
self addRoleToPlayer:role];
5085- (void) addRoleForMining
5087 NSString *role =
@"miner";
5088 NSUInteger times = [roleWeightFlags oo_intForKey:role defaultValue:0];
5090 [roleWeightFlags setObject:[NSNumber numberWithUnsignedInteger:times] forKey:role];
5091 if ((times & (times-1)) == 0)
5093 [
self addRoleToPlayer:role];
5098- (void) addRoleToPlayer:(NSString *)role
5100 NSUInteger slot =
Ranrot() & ([
self maxPlayerRoles]-1);
5101 [
self addRoleToPlayer:role inSlot:slot];
5105- (void) addRoleToPlayer:(NSString *)role inSlot:(NSUInteger)slot
5107 if (slot >= [
self maxPlayerRoles])
5109 slot = [
self maxPlayerRoles]-1;
5111 if (slot >= [roleWeights
count])
5113 [roleWeights addObject:role];
5117 [roleWeights replaceObjectAtIndex:slot withObject:role];
5122- (void) clearRoleFromPlayer:(BOOL)includingLongRange
5124 NSUInteger slot =
Ranrot() % [roleWeights count];
5125 if (!includingLongRange)
5127 NSString *role = [roleWeights objectAtIndex:slot];
5129 if ([role hasSuffix:
@"+"] &&
randf() > 0.5)
5134 [roleWeights replaceObjectAtIndex:slot withObject:@"player-unknown"];
5138- (void) clearRolesFromPlayer:(
float)chance
5140 NSUInteger i,
count=[roleWeights count];
5141 for (i = 0; i <
count; i++)
5143 if (
randf() < chance)
5145 [roleWeights replaceObjectAtIndex:i withObject:@"player-unknown"];
5151- (NSUInteger) maxPlayerRoles
5153 if (ship_kills >= 6400)
5157 else if (ship_kills >= 128)
5168- (void) updateSystemMemory
5175 NSUInteger memory = 4;
5176 if (ship_kills >= 6400)
5180 else if (ship_kills >= 256)
5184 else if (ship_kills >= 64)
5188 if ([roleSystemList
count] >= memory)
5190 [roleSystemList removeObjectAtIndex:0];
5192 [roleSystemList addObject:[NSNumber numberWithInt:sys]];
5196- (
Entity *) compassTarget
5198 Entity *result = [compassTarget weakRefUnderlyingObject];
5208- (void) setCompassTarget:(
Entity *)value
5210 [compassTarget release];
5215- (void) validateCompassTarget
5220 Entity *the_target = [
self primaryTarget];
5221 Entity <OOBeaconEntity> *beacon = [
self nextBeacon];
5222 if ([
self isInSpace] && the_sun && the_planet
5223 && ![the_sun goneNova])
5228 switch ([
self compassMode])
5230 case COMPASS_MODE_INACTIVE:
5233 case COMPASS_MODE_BASIC:
5236 new_target = the_station;
5240 new_target = the_planet;
5244 case COMPASS_MODE_PLANET:
5245 new_target = the_planet;
5248 case COMPASS_MODE_STATION:
5249 new_target = the_station;
5252 case COMPASS_MODE_SUN:
5253 new_target = the_sun;
5256 case COMPASS_MODE_TARGET:
5257 new_target = the_target;
5260 case COMPASS_MODE_BEACONS:
5261 new_target = beacon;
5265 if (new_target ==
nil || [new_target status] < STATUS_ACTIVE || [new_target status] == STATUS_IN_HOLD)
5267 [
self setCompassMode:COMPASS_MODE_PLANET];
5268 new_target = the_planet;
5271 if (
EXPECT_NOT(new_target != [
self compassTarget]))
5273 [
self setCompassTarget:new_target];
5274 [
self doScriptEvent:OOJSID("compassTargetChanged") withArguments:[NSArray arrayWithObjects:new_target, OOStringFromCompassMode([
self compassMode]), nil]];
5280- (NSString *) compassTargetLabel
5282 switch (compassMode)
5284 case COMPASS_MODE_INACTIVE:
5286 case COMPASS_MODE_BASIC:
5288 case COMPASS_MODE_BEACONS:
5290 Entity *target = [
self compassTarget];
5297 case COMPASS_MODE_PLANET:
5298 return [[UNIVERSE planet] name];
5299 case COMPASS_MODE_SUN:
5300 return [[UNIVERSE sun] name];
5301 case COMPASS_MODE_STATION:
5302 return [[UNIVERSE station] displayName];
5303 case COMPASS_MODE_TARGET:
5304 return DESC(
@"oolite-beacon-label-target");
5318 compassMode = value;
5322- (void) setPrevCompassMode
5325 Entity <OOBeaconEntity> *beacon =
nil;
5327 switch (compassMode)
5329 case COMPASS_MODE_INACTIVE:
5330 case COMPASS_MODE_BASIC:
5331 case COMPASS_MODE_PLANET:
5332 beacon = [UNIVERSE lastBeacon];
5333 while (beacon !=
nil && [beacon isJammingScanning])
5335 beacon = [beacon prevBeacon];
5337 [
self setNextBeacon:beacon];
5341 [
self setCompassMode:COMPASS_MODE_BEACONS];
5346 case COMPASS_MODE_BEACONS:
5347 beacon = [
self nextBeacon];
5350 beacon = [beacon prevBeacon];
5351 }
while (beacon !=
nil && [beacon isJammingScanning]);
5352 [
self setNextBeacon:beacon];
5356 if ([
self primaryTarget])
5358 [
self setCompassMode:COMPASS_MODE_TARGET];
5362 [
self setCompassMode:COMPASS_MODE_SUN];
5368 case COMPASS_MODE_TARGET:
5369 [
self setCompassMode:COMPASS_MODE_SUN];
5372 case COMPASS_MODE_SUN:
5373 aegis = [
self checkForAegis];
5376 [
self setCompassMode:COMPASS_MODE_STATION];
5380 [
self setCompassMode:COMPASS_MODE_PLANET];
5384 case COMPASS_MODE_STATION:
5385 [
self setCompassMode:COMPASS_MODE_PLANET];
5391- (void) setNextCompassMode
5394 Entity <OOBeaconEntity> *beacon =
nil;
5396 switch (compassMode)
5398 case COMPASS_MODE_INACTIVE:
5399 case COMPASS_MODE_BASIC:
5400 case COMPASS_MODE_PLANET:
5401 aegis = [
self checkForAegis];
5404 [
self setCompassMode:COMPASS_MODE_STATION];
5408 [
self setCompassMode:COMPASS_MODE_SUN];
5412 case COMPASS_MODE_STATION:
5413 [
self setCompassMode:COMPASS_MODE_SUN];
5416 case COMPASS_MODE_SUN:
5417 if ([
self primaryTarget])
5419 [
self setCompassMode:COMPASS_MODE_TARGET];
5424 case COMPASS_MODE_TARGET:
5425 beacon = [UNIVERSE firstBeacon];
5426 while (beacon !=
nil && [beacon isJammingScanning])
5428 beacon = [beacon nextBeacon];
5430 [
self setNextBeacon:beacon];
5432 if (beacon !=
nil) [
self setCompassMode:COMPASS_MODE_BEACONS];
5433 else [
self setCompassMode:COMPASS_MODE_PLANET];
5436 case COMPASS_MODE_BEACONS:
5437 beacon = [
self nextBeacon];
5440 beacon = [beacon nextBeacon];
5441 }
while (beacon !=
nil && [beacon isJammingScanning]);
5442 [
self setNextBeacon:beacon];
5446 [
self setCompassMode:COMPASS_MODE_PLANET];
5453- (NSUInteger) activeMissile
5455 return activeMissile;
5459- (void) setActiveMissile:(NSUInteger)value
5461 activeMissile = value;
5465- (NSUInteger) dialMaxMissiles
5467 return max_missiles;
5471- (BOOL) dialIdentEngaged
5473 return ident_engaged;
5477- (void) setDialIdentEngaged:(BOOL)newValue
5479 ident_engaged = !!newValue;
5483- (NSString *) specialCargo
5485 return specialCargo;
5489- (NSString *) dialTargetName
5491 Entity *target_entity = [
self primaryTarget];
5492 NSString *result =
nil;
5494 if (target_entity ==
nil)
5496 result =
DESC(
@"no-target-string");
5499 if ([target_entity respondsToSelector:@selector(identFromShip:)])
5504 if (result ==
nil) result =
DESC(
@"unknown-target");
5510- (NSArray *) multiFunctionDisplayList
5512 return multiFunctionDisplaySettings;
5516- (NSString *) multiFunctionText:(NSUInteger)i
5518 NSString *key = [multiFunctionDisplaySettings oo_stringAtIndex:i defaultValue:nil];
5523 NSString *text = [multiFunctionDisplayText oo_stringForKey:key defaultValue:nil];
5528- (void) setMultiFunctionText:(NSString *)text forKey:(NSString *)key
5532 [multiFunctionDisplayText setObject:text forKey:key];
5534 else if (key !=
nil)
5536 [multiFunctionDisplayText removeObjectForKey:key];
5539 while ((index = [multiFunctionDisplaySettings indexOfObject:key]) != NSNotFound)
5541 [multiFunctionDisplaySettings replaceObjectAtIndex:index withObject:[NSNull null]];
5547- (BOOL) setMultiFunctionDisplay:(NSUInteger)index toKey:(NSString *)key
5549 if (index >= [hud mfdCount])
5552 index = [multiFunctionDisplaySettings indexOfObject:[NSNull null]];
5553 if (index == NSNotFound)
5559 if (index < [hud mfdCount])
5563 [multiFunctionDisplaySettings replaceObjectAtIndex:index withObject:[NSNull null]];
5567 [multiFunctionDisplaySettings replaceObjectAtIndex:index withObject:key];
5578- (void) cycleNextMultiFunctionDisplay:(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:0];
5592 [
self setMultiFunctionDisplay:index toKey:key];
5596 NSUInteger cIndex = [keys indexOfObject:current];
5597 if (cIndex == NSNotFound || cIndex + 1 >= [keys
count])
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) cyclePreviousMultiFunctionDisplay:(NSUInteger) index
5617 if ([[
self hud] mfdCount] == 0)
return;
5618 NSArray *keys = [multiFunctionDisplayText allKeys];
5619 NSString *key =
nil;
5620 if ([keys
count] == 0)
5622 [
self setMultiFunctionDisplay:index toKey:nil];
5625 id current = [multiFunctionDisplaySettings objectAtIndex:index];
5626 if (current == [NSNull
null])
5628 key = [keys objectAtIndex:([keys count]-1)];
5629 [
self setMultiFunctionDisplay:index toKey:key];
5633 NSUInteger cIndex = [keys indexOfObject:current];
5634 if (cIndex == NSNotFound || cIndex == 0)
5637 [
self setMultiFunctionDisplay:index toKey:nil];
5641 key = [keys objectAtIndex:(cIndex-1)];
5642 [
self setMultiFunctionDisplay:index toKey:key];
5647 ShipScriptEvent(context,
self,
"mfdKeyChanged", INT_TO_JSVAL(activeMFD), keyVal);
5652- (void) selectNextMultiFunctionDisplay
5654 if ([[
self hud] mfdCount] == 0)
return;
5655 activeMFD = (activeMFD + 1) % [[
self hud] mfdCount];
5656 NSUInteger mfdID = activeMFD + 1;
5657 [UNIVERSE addMessage:OOExpandKey(@"mfd-N-selected", mfdID) forCount:3.0 ];
5659 ShipScriptEvent(context,
self,
"selectedMFDChanged", INT_TO_JSVAL(activeMFD));
5664- (void) selectPreviousMultiFunctionDisplay
5666 if ([[
self hud] mfdCount] == 0)
return;
5669 activeMFD = ([[
self hud] mfdCount] - 1);
5673 activeMFD = (activeMFD - 1);
5675 NSUInteger mfdID = activeMFD + 1;
5676 [UNIVERSE addMessage:OOExpandKey(@"mfd-N-selected", mfdID) forCount:3.0 ];
5678 ShipScriptEvent(context,
self,
"selectedMFDChanged", INT_TO_JSVAL(activeMFD));
5683- (NSUInteger) activeMFD
5689- (
ShipEntity *) missileForPylon:(NSUInteger)value
5691 if (value < max_missiles)
return missile_entity[value];
5697- (void) safeAllMissiles
5702 for (i = 0; i < max_missiles; i++)
5704 if (missile_entity[i] && [missile_entity[i] primaryTarget] !=
nil)
5705 [missile_entity[i] removeTarget:
nil];
5711- (void) tidyMissilePylons
5718 OOLog(
@"missile.tidying.debug",
@"%d %@ %@",i,missile_entity[i],missile_list[i]);
5719 if(missile_entity[i] !=
nil)
5721 missile_entity[pylon] = missile_entity[i];
5730 missile_entity[i] =
nil;
5732 missile_list[i] =
nil;
5737- (void) selectNextMissile
5739 if (![
self weaponsOnline])
return;
5742 for (i = 1; i < max_missiles; i++)
5744 int next_missile = (activeMissile + i) % max_missiles;
5745 if (missile_entity[next_missile])
5748 if( ![
self hasEquipmentItemProviding:
@"EQ_MULTI_TARGET"] && [missile_entity[activeMissile] isMissile] )
5750 [missile_entity[activeMissile] removeTarget:nil];
5754 [
self setActiveMissile:next_missile];
5761 if( [missile_entity[activeMissile] isMissile] )
5763 if( [
self hasEquipmentItemProviding:
@"EQ_MULTI_TARGET"] &&
5764 ([missile_entity[next_missile] primaryTarget] !=
nil))
5767 [
self addTarget:[missile_entity[next_missile] primaryTarget]];
5770 else if ([
self primaryTarget] !=
nil)
5776 if([
self hasEquipmentItemProviding:
@"EQ_MULTI_TARGET"] && !launchingMissile)
5778 [
self noteLostTarget];
5783 [missile_entity[activeMissile] addTarget:[
self primaryTarget]];
5795- (void) clearAlertFlags
5807- (void) setAlertFlag:(
int)flag to:(BOOL)value
5824 return [
self alertCondition];
5833 [
self setAlertFlag:ALERT_FLAG_DOCKED to:[
self status] == STATUS_DOCKED];
5841 if (alertFlags != 0)
5852 [
self playAlertConditionRed];
5855 return alertCondition;
5861 return fleeing_status;
5867- (void) interpretAIMessage:(NSString *)ms
5869 if ([ms isEqual:
@"HOLD_FULL"])
5871 [
self playHoldFull];
5872 [UNIVERSE addMessage:DESC(@"hold-full") forCount:4.5];
5875 if ([ms isEqual:
@"INCOMING_MISSILE"])
5877 if ([
self primaryAggressor] !=
nil)
5879 [
self playIncomingMissile:HPVectorToVector([[
self primaryAggressor] position])];
5883 [
self playIncomingMissile:kZeroVector];
5885 [UNIVERSE addMessage:DESC(@"incoming-missile") forCount:4.5];
5888 if ([ms isEqual:
@"ENERGY_LOW"])
5890 [UNIVERSE addMessage:DESC(@"energy-low") forCount:6.0];
5893 if ([ms isEqual:
@"ECM"] && ![
self isDocked]) [
self playHitByECMSound];
5895 if ([ms isEqual:
@"DOCKING_REFUSED"] && [
self status] == STATUS_AUTOPILOT_ENGAGED)
5897 [
self playDockingDenied];
5898 [UNIVERSE addMessage:DESC(@"autopilot-denied") forCount:4.5];
5899 autopilot_engaged = NO;
5900 [
self resetAutopilotAI];
5902 [
self setStatus:STATUS_IN_FLIGHT];
5904 [
self doScriptEvent:OOJSID("playerDockingRefused")];
5908 if (compassMode != COMPASS_MODE_BASIC)
5910 if ([ms isEqual:
@"AEGIS_CLOSE_TO_MAIN_PLANET"]&&(compassMode == COMPASS_MODE_PLANET))
5912 [
self playAegisCloseToPlanet];
5913 [
self setCompassMode:COMPASS_MODE_STATION];
5915 if ([ms isEqual:
@"AEGIS_IN_DOCKING_RANGE"]&&(compassMode == COMPASS_MODE_PLANET))
5917 [
self playAegisCloseToStation];
5918 [
self setCompassMode:COMPASS_MODE_STATION];
5920 if ([ms isEqual:
@"AEGIS_NONE"]&&(compassMode == COMPASS_MODE_STATION))
5922 [
self setCompassMode:COMPASS_MODE_PLANET];
5930 if (missile ==
nil)
return NO;
5933 for (i = 0; i < max_missiles; i++)
5935 if (missile_entity[i] ==
nil)
5937 missile_entity[i] = [missile retain];
5940 if (missiles == 1) [
self setActiveMissile:0];
5949- (BOOL) mountMissileWithRole:(NSString *)role
5951 if ([
self missileCount] >= [
self missileCapacity])
return NO;
5952 return [
self mountMissile:[[UNIVERSE newShipWithRole:role] autorelease]];
5958 ShipEntity *missile = missile_entity[activeMissile];
5962 if (missile ==
nil)
return nil;
5964 if (![
self weaponsOnline])
return nil;
5969 BOOL cloakedPriorToFiring = cloaking_device_active;
5971 launchingMissile = YES;
5972 replacingMissile = NO;
5976 firedMissile = [
self launchMine:missile];
5977 if (!replacingMissile) [
self removeFromPylon:activeMissile];
5978 if (firedMissile !=
nil) [
self playMineLaunched:[
self missileLaunchPosition] weaponIdentifier:identifier];
5984 firedMissile = [
self fireMissileWithIdentifier:identifier andTarget:[missile
primaryTarget]];
5986 if (firedMissile !=
nil)
5988 if (!replacingMissile) [
self removeFromPylon:activeMissile];
5989 [
self playMissileLaunched:[
self missileLaunchPosition] weaponIdentifier:identifier];
5993 if (cloakedPriorToFiring && cloakPassive)
5998 [
self deactivateCloakingDevice];
6001 replacingMissile = NO;
6002 launchingMissile = NO;
6004 return firedMissile;
6013 if (![
self weaponsOnline])
6018 [
self dumpItem: mine];
6021 float mine_speed = 500.0f;
6022 Vector mvel = vector_subtract([mine velocity], vector_multiply_scalar(v_forward, mine_speed));
6024 [
self doScriptEvent:OOJSID("shipReleasedEquipment") withArgument:mine];
6029- (BOOL) assignToActivePylon:(NSString *)equipmentKey
6031 if (!launchingMissile)
return NO;
6035 if ([equipmentKey hasSuffix:
@"_DAMAGED"])
6050 ShipEntity *amiss = [UNIVERSE newShipWithRole:equipmentKey];
6052 if (!amiss)
return NO;
6055 [missile_entity[activeMissile] release];
6056 missile_entity[activeMissile] = amiss;
6057 missile_list[activeMissile] = eqType;
6060 if (activeMissile > 0) activeMissile--;
6061 else activeMissile = max_missiles - 1;
6062 [
self selectNextMissile];
6064 replacingMissile = YES;
6070- (BOOL) activateCloakingDevice
6072 if (![
self hasCloakingDevice])
return NO;
6074 if ([super activateCloakingDevice])
6076 [UNIVERSE setCurrentPostFX:OO_POSTFX_CLOAK];
6077 [UNIVERSE addMessage:DESC(@"cloak-on") forCount:2];
6078 [
self playCloakingDeviceOn];
6083 [UNIVERSE addMessage:DESC(@"cloak-low-juice") forCount:3];
6084 [
self playCloakingDeviceInsufficientEnergy];
6090- (void) deactivateCloakingDevice
6092 if (![
self hasCloakingDevice])
return;
6094 [
super deactivateCloakingDevice];
6095 [UNIVERSE terminatePostFX:OO_POSTFX_CLOAK];
6096 [UNIVERSE addMessage:DESC(@"cloak-off") forCount:2];
6097 [
self playCloakingDeviceOff];
6103- (double) scannerFuzziness
6108 if (last_ecm_time > 0.0)
6110 double since = [UNIVERSE getTime] - last_ecm_time;
6124 last_ecm_time = [UNIVERSE getTime];
6130 if ([super fireECM])
6132 ecm_in_operation = YES;
6133 ecm_start_time = [UNIVERSE getTime];
6161- (void) currentWeaponStats
6167 [
self setWeaponDataFromType:currentWeapon];
6171- (BOOL) weaponsOnline
6173 return weapons_online;
6177- (void) setWeaponsOnline:(BOOL)newValue
6179 weapons_online = !!newValue;
6180 if (!weapons_online) [
self safeAllMissiles];
6184- (NSArray *) currentLaserOffset
6186 return [
self laserPortOffset:currentWeaponFacing];
6190- (BOOL) fireMainWeapon
6192 OOWeaponType weapon_to_be_fired = [
self currentWeapon];
6194 if (![
self weaponsOnline])
6201 [
self playWeaponOverheated:[[
self currentLaserOffset] oo_vectorAtIndex:0]];
6202 [UNIVERSE addMessage:DESC(@"weapon-overheat") forCount:3.0];
6211 [
self currentWeaponStats];
6213 NSUInteger multiplier = 1;
6214 if (_multiplyWeapons)
6217 multiplier = [[
self laserPortOffset:currentWeaponFacing] count];
6220 if (energy <= weapon_energy_use * multiplier)
6222 [UNIVERSE addMessage:DESC(@"weapon-out-of-juice") forCount:3.0];
6228 energy -= weapon_energy_use * multiplier;
6230 switch (currentWeaponFacing)
6233 forward_weapon_temp += weapon_shot_temperature * multiplier;
6234 forward_shot_time = 0.0;
6238 aft_weapon_temp += weapon_shot_temperature * multiplier;
6239 aft_shot_time = 0.0;
6243 port_weapon_temp += weapon_shot_temperature * multiplier;
6244 port_shot_time = 0.0;
6248 starboard_weapon_temp += weapon_shot_temperature * multiplier;
6249 starboard_shot_time = 0.0;
6256 BOOL weaponFired = NO;
6259 if (![weapon_to_be_fired isTurretLaser])
6261 [
self fireLaserShotInDirection:currentWeaponFacing weaponIdentifier:[[
self currentWeapon] identifier]];
6270 if (weaponFired && cloaking_device_active && cloakPassive)
6272 [
self deactivateCloakingDevice];
6284 return forward_weapon_type;
6287 return aft_weapon_type;
6290 return port_weapon_type;
6293 return starboard_weapon_type;
6304 return [
self weaponForFacing:currentWeaponFacing];
6311- (GLfloat) doesHitLine:(HPVector)v0 :(HPVector)v1 :(
ShipEntity **)hitEntity
6315 Vector u0 = HPVectorToVector(HPvector_between(position, v0));
6316 Vector u1 = HPVectorToVector(HPvector_between(position, v1));
6317 Vector w0 = make_vector(dot_product(u0, v_right), dot_product(u0, v_up), dot_product(u0, v_forward));
6318 Vector w1 = make_vector(dot_product(u1, v_right), dot_product(u1, v_up), dot_product(u1, v_forward));
6319 GLfloat hit_distance = [octree isHitByLine:w0 :w1];
6323 hitEntity[0] =
self;
6326 bool shields =
false;
6327 if ((w0.z >= 0 && forward_shield > 1) || (w0.z <= 0 && aft_shield > 1))
6332 NSEnumerator *subEnum =
nil;
6334 for (subEnum = [
self shipSubEntityEnumerator]; (se = [subEnum nextObject]); )
6338 u0 = HPVectorToVector(HPvector_between(p0, v0));
6339 u1 = HPVectorToVector(HPvector_between(p0, v1));
6340 w0 = resolveVectorInIJK(u0, ijk);
6341 w1 = resolveVectorInIJK(u1, ijk);
6343 GLfloat hitSub = [se->octree isHitByLine:w0 :w1];
6344 if (hitSub && (hit_distance == 0 || hit_distance > hitSub))
6346 hit_distance = hitSub;
6347 if (hitEntity && !shields)
6354 return hit_distance;
6359- (void) takeEnergyDamage:(
double)amount from:(
Entity *)ent becauseOf:(
Entity *)other weaponIdentifier:(NSString *)weaponIdentifier
6363 BOOL internal_damage = NO;
6365 OOLog(
@"player.ship.damage",
@"Player took damage from %@ becauseOf %@", ent, other);
6367 if ([
self status] == STATUS_DEAD)
return;
6368 if ([
self status] == STATUS_ESCAPE_SEQUENCE)
return;
6369 if (amount == 0.0)
return;
6372 BOOL cascading = NO;
6375 cascading = [
self cascadeIfAppropriateWithDamageAmount:amount cascadeOwner:[ent
owner]];
6379 if (ent && [ent isSubEntity]) ent = [ent
owner];
6381 [[ent retain] autorelease];
6382 [[other retain] autorelease];
6385 rel_pos = HPvector_subtract(rel_pos, position);
6387 [
self doScriptEvent:OOJSID("shipBeingAttacked") withArgument:ent];
6388 if ([ent isShip]) [(
ShipEntity *)
ent doScriptEvent:OOJSID("shipAttackedOther") withArgument:self];
6390 d_forward = dot_product(HPVectorToVector(rel_pos), v_forward);
6391 d_right = dot_product(HPVectorToVector(rel_pos), v_right);
6392 d_up = dot_product(HPVectorToVector(rel_pos), v_up);
6393 Vector relative = make_vector(d_right,d_up,d_forward);
6395 [
self playShieldHit:relative weaponIdentifier:weaponIdentifier];
6400 [
self broadcastHitByLaserFrom:(ShipEntity*) other];
6405 forward_shield -= amount;
6406 if (forward_shield < 0.0)
6408 amount = -forward_shield;
6409 forward_shield = 0.0f;
6418 aft_shield -= amount;
6419 if (aft_shield < 0.0)
6421 amount = -aft_shield;
6430 OOShipDamageType damageType = cascadeWeapon ? kOODamageTypeCascadeWeapon : kOODamageTypeEnergy;
6435 [
self playDirectHit:relative weaponIdentifier:weaponIdentifier];
6448 [
self noteTakingDamage:amount from:other type:damageType];
6449 if (cascading) energy = 0.0;
6458 [
self getDestroyedBy:other damageType:damageType];
6462 while (amount > 0.0)
6465 if (internal_damage)
6467 [
self takeInternalDamage];
6475- (void) takeScrapeDamage:(
double) amount from:(
Entity *) ent
6479 BOOL internal_damage = NO;
6481 if ([
self status] == STATUS_DEAD)
return;
6485 OOLog(
@"player.ship.damage",
@"Player took negative scrape damage %.3f so we made it positive", amount);
6488 OOLog(
@"player.ship.damage",
@"Player took %.3f scrape damage from %@", amount, ent);
6490 [[ent retain] autorelease];
6492 rel_pos = HPvector_subtract(rel_pos, position);
6494 d_forward = dot_product(HPVectorToVector(rel_pos), v_forward);
6495 d_right = dot_product(HPVectorToVector(rel_pos), v_right);
6496 d_up = dot_product(HPVectorToVector(rel_pos), v_up);
6497 Vector relative = make_vector(d_right,d_up,d_forward);
6499 [
self playScrapeDamage:relative];
6502 forward_shield -= amount;
6503 if (forward_shield < 0.0)
6505 amount = -forward_shield;
6506 forward_shield = 0.0f;
6515 aft_shield -= amount;
6516 if (aft_shield < 0.0)
6518 amount = -aft_shield;
6527 [
super takeScrapeDamage:amount from:ent];
6529 while (amount > 0.0)
6532 if (internal_damage)
6534 [
self takeInternalDamage];
6541- (void) takeHeatDamage:(
double) amount
6543 if ([
self status] == STATUS_DEAD || amount < 0)
return;
6546 float fwd_amount = (float)(0.5 * amount);
6547 float aft_amount = (float)(0.5 * amount);
6549 forward_shield -= fwd_amount;
6550 if (forward_shield < 0.0)
6552 fwd_amount = -forward_shield;
6553 forward_shield = 0.0f;
6560 aft_shield -= aft_amount;
6561 if (aft_shield < 0.0)
6563 aft_amount = -aft_shield;
6571 double residual_amount = fwd_amount + aft_amount;
6573 [
super takeHeatDamage:residual_amount];
6587 [result
setSpeed:[
self flightSpeed]];
6605 if ([
UNIVERSE displayGUI]) [
self switchToMainView];
6606 [UNIVERSE setViewDirection:VIEW_FORWARD];
6608 if ([
self status] == STATUS_DEAD)
return nil;
6615 [UNIVERSE setBlockJSPlayerShipProps:YES];
6617 if (escape_pod_rescue_time > 0)
6619 ship_clock_adjust += escape_pod_rescue_time;
6620 escape_pod_rescue_time = 0;
6625 ship_clock_adjust += 43200 + 5400 * (
ranrot_rand() & 127);
6628 flightSpeed = fmin(flightSpeed, maxFlightSpeed);
6630 doppelganger = [
self createDoppelganger];
6633 [doppelganger
setVelocity:vector_multiply_scalar(v_forward, flightSpeed)];
6636 [doppelganger
setRoll:0.2 * (randf() - 0.5)];
6639 [UNIVERSE addEntity:doppelganger];
6642 [
self setFoundTarget:doppelganger];
6643 [
self setStatus:STATUS_ESCAPE_SEQUENCE];
6647 float sheight = (float)(boundingBox.max.y - boundingBox.min.y);
6648 position = HPvector_subtract(position, vectorToHPVector(vector_multiply_scalar(v_up, sheight)));
6649 float sdepth = (float)(boundingBox.max.z - boundingBox.min.z);
6650 position = HPvector_subtract(position, vectorToHPVector(vector_multiply_scalar(v_forward, sdepth/2.0)));
6653 escapePod = [UNIVERSE newShipWithName:@"escape-capsule"];
6654 if (escapePod !=
nil)
6657 [
self setMesh:[escapePod
mesh]];
6676 Vector launchVector = vector_add([doppelganger velocity],
6677 vector_add(vector_multiply_scalar(v_up, 15.0f),
6678 vector_multiply_scalar(v_forward, -90.0f)));
6679 [
self setVelocity:launchVector];
6684 [
self removeEquipmentItem:[
self equipmentItemProviding:@"EQ_ESCAPE_POD"]];
6688 target_system_id = system_id;
6689 info_system_id = system_id;
6690 [
self setDockTarget:[UNIVERSE station]];
6692 [
self doScriptEvent:OOJSID("shipLaunchedEscapePod") withArgument:escapePod];
6695 [
self setBounty:0 withReason:kOOLegalStatusReasonEscapePod];
6699 if (ship_kills >= 6400)
6701 [
self clearRolesFromPlayer:0.1];
6703 else if (ship_kills >= 2560)
6705 [
self clearRolesFromPlayer:0.25];
6709 [
self clearRolesFromPlayer:0.5];
6713 if (trumbleCount != 0) trumbleCount = 1;
6716 [cargo removeAllObjects];
6719 [UNIVERSE addMessage:DESC(@"escape-sequence") forCount:4.5];
6720 [
self resetShotTime];
6724 forward_shot_time = 0.0;
6725 aft_shot_time = 0.0;
6726 port_shot_time = 0.0;
6727 starboard_shot_time = 0.0;
6729 [escapePod release];
6731 return doppelganger;
6737 if (flightSpeed > 4.0 * maxFlightSpeed)
6739 [UNIVERSE addMessage:OOExpandKey(@"hold-locked") forCount:3.0];
6746 NSString *commodity = [UNIVERSE displayNameForCommodity:result];
6747 [UNIVERSE addMessage:OOExpandKey(@"commodity-ejected", commodity) forCount:3.0 forceDisplay:YES];
6748 [
self playCargoJettisioned];
6756 NSInteger i, n_cargo = [cargo count];
6757 if (n_cargo == 0)
return;
6762 NSInteger rotates = 0;
6766 [cargo removeObjectAtIndex:0];
6767 [cargo addObject:pod];
6769 pod = (
ShipEntity*)[[cargo objectAtIndex:0] retain];
6772 }
while ([contents isEqualToString:current_contents]&&(rotates < n_cargo));
6775 NSString *commodity = [UNIVERSE displayNameForCommodity:contents];
6776 [UNIVERSE addMessage:OOExpandKey(@"ready-to-eject-commodity", commodity) forCount:3.0];
6780 for (i = 1; i < (n_cargo - rotates); i++)
6782 pod = [cargo objectAtIndex:i];
6783 if ([[pod commodityType] isEqualToString:current_contents])
6786 [cargo removeObjectAtIndex:i--];
6787 [cargo addObject:pod];
6797 [
self setBounty:amount withReason:kOOLegalStatusReasonUnknown];
6804 [
self setBounty:amount withReasonAsString:nReason];
6808- (void) setBounty:(
OOCreditsQuantity)amount withReasonAsString:(NSString *)reason
6812 jsval amountVal = JSVAL_VOID;
6813 int amountVal2 = (
int)amount-(
int)legalStatus;
6814 JS_NewNumberValue(context, amountVal2, &amountVal);
6816 legalStatus = (
int)amount;
6820 ShipScriptEvent(context,
self,
"shipBountyChanged", amountVal, reasonVal);
6838- (void) markAsOffender:(
int)offence_value
6840 [
self markAsOffender:offence_value withReason:kOOLegalStatusReasonUnknown];
6846 if (![
self isCloaked])
6850 jsval amountVal = JSVAL_VOID;
6851 int amountVal2 = (legalStatus | offence_value) - legalStatus;
6852 JS_NewNumberValue(context, amountVal2, &amountVal);
6854 legalStatus |= offence_value;
6858 ShipScriptEvent(context,
self,
"shipBountyChanged", amountVal, reasonVal);
6868 if ([
self status] == STATUS_DEAD)
return;
6870 if (other ==
nil || [other isSubEntity])
return;
6880 if ([
self isCloaked])
6890 if ([other isPolice])
6892 [
self markAsOffender:64 withReason:kOOLegalStatusReasonAttackedPolice];
6895 BOOL killIsCargo = ((killClass == CLASS_CARGO) && ([other commodityAmount] > 0) && ![other
isHulk]);
6896 if ((killIsCargo) || (killClass == CLASS_BUOY) || (killClass == CLASS_ROCK))
6899 if (![other hasRole:
@"tharglet"])
6910 NSString *bonusMessage =
OOExpandKey(
@"bounty-awarded", score, credits);
6911 [UNIVERSE addDelayedMessage:bonusMessage forCount:6 afterDelay:0.15];
6917 if ((ship_kills % 256) == 0)
6920 [UNIVERSE addDelayedMessage:DESC(@"right-on-commander") forCount:4 afterDelay:0.2];
6926- (BOOL) takeInternalDamage
6928 unsigned n_cargo = [
self maxAvailableCargoSpace];
6929 unsigned n_mass = [
self mass] / 10000;
6930 unsigned n_considered = (n_cargo + n_mass) * ship_trade_in_factor / 100;
6931 unsigned damage_to = n_considered ? (
ranrot_rand() % n_considered) : 0;
6934 if (damage_to < [cargo
count])
6937 NSString* cargo_desc = [UNIVERSE displayNameForCommodity:[pod
commodityType]];
6940 [UNIVERSE clearPreviousMessage];
6941 [UNIVERSE addMessage:[NSString stringWithFormat:DESC(@"@-destroyed"), cargo_desc] forCount:4.5];
6942 [cargo removeObject:pod];
6947 damage_to = n_considered - (damage_to + 1);
6950 NSEnumerator *eqEnum = [
self equipmentEnumerator];
6952 NSString *system_key;
6953 unsigned damageableCounter = 0;
6954 GLfloat damageableOdds = 0.0;
6955 while ((system_key = [eqEnum nextObject]) !=
nil)
6958 if ([eqType canBeDamaged])
6960 damageableCounter++;
6961 damageableOdds += [eqType damageProbability];
6965 if (damage_to < damageableCounter)
6967 GLfloat target =
randf() * damageableOdds;
6968 GLfloat accumulator = 0.0;
6969 eqEnum = [
self equipmentEnumerator];
6970 while ((system_key = [eqEnum nextObject]) !=
nil)
6973 accumulator += [eqType damageProbability];
6974 if (accumulator > target)
6976 [system_key retain];
6980 if (system_key ==
nil)
6982 [system_key release];
6986 NSString *system_name = [eqType
name];
6987 if (![eqType canBeDamaged] || system_name ==
nil)
6989 [system_key release];
6994 [
self setScriptTarget:self];
6995 [UNIVERSE clearPreviousMessage];
6996 [
self removeEquipmentItem:system_key];
6998 NSString *damagedKey = [NSString stringWithFormat:@"%@_DAMAGED", system_key];
6999 [
self addEquipmentItem:damagedKey withValidation: NO inContext:@"damage"];
7000 [
self doScriptEvent:OOJSID("equipmentDamaged") withArgument:system_key];
7002 if (![
self hasEquipmentItem:system_name] && [
self hasEquipmentItem:damagedKey])
7010 [UNIVERSE addMessage:[NSString stringWithFormat:DESC(@"@-damaged"), system_name] forCount:4.5];
7016 [system_key release];
7020 if (((damage_to & 7) == 7)&&(ship_trade_in_factor > 75))
7022 ship_trade_in_factor--;
7031 if ([
self isDocked])
return;
7035 if (![[
UNIVERSE gameController] playerFileToLoad])
7037 [[UNIVERSE gameController] setPlayerFileToLoad: save_path];
7041 afterburner_engaged = NO;
7042 [
self disengageAutopilot];
7044 [UNIVERSE setDisplayText:NO];
7045 [UNIVERSE setViewDirection:VIEW_AFT];
7048 [
self noteKilledBy:whom damageType:type];
7050 [
self becomeLargeExplosion:4.0];
7051 [
self moveForward:100.0];
7053 flightSpeed = 160.0f;
7058 [[UNIVERSE messageGUI] clear];
7059 [
self suppressTargetLost];
7060 [
self playGameOver];
7061 [UNIVERSE setBlockJSPlayerShipProps:YES];
7062 [
self removeAllEquipment];
7063 [
self loseTargetStatus];
7064 [
self showGameOver];
7068- (void) loseTargetStatus
7072 int ent_count =
UNIVERSE->n_entities;
7074 Entity* my_entities[ent_count];
7076 for (i = 0; i < ent_count; i++)
7077 my_entities[i] = [uni_entities[i] retain];
7078 for (i = 0; i < ent_count ; i++)
7080 Entity* thing = my_entities[i];
7083 ShipEntity* ship = (ShipEntity *)thing;
7084 if (self == [ship primaryTarget])
7086 [ship noteLostTarget];
7090 for (i = 0; i < ent_count; i++)
7092 [my_entities[i] release];
7097- (BOOL) endScenario:(NSString *)key
7099 if (scenarioKey !=
nil && [key isEqualToString:scenarioKey])
7101 [
self setStatus:STATUS_RESTART_GAME];
7110 NSParameterAssert(station !=
nil);
7111 if ([
self status] == STATUS_DEAD)
return;
7113 [
self setStatus:STATUS_DOCKING];
7114 [
self setDockedStation:station];
7115 [
self doScriptEvent:OOJSID("shipWillDockWithStation") withArgument:station];
7117 if (![hud nonlinearScanner])
7119 [hud setScannerZoom: 1.0];
7122 afterburner_engaged = NO;
7123 autopilot_engaged = NO;
7124 [
self resetAutopilotAI];
7126 cloaking_device_active = NO;
7127 hyperspeed_engaged = NO;
7128 hyperspeed_locked = NO;
7129 [
self safeAllMissiles];
7131 [
self clearTargetMemory];
7133 scanner_zoom_rate = 0.0f;
7134 [UNIVERSE setDisplayText:NO];
7135 [[UNIVERSE gameController] setMouseInteractionModeForFlight];
7136 if ([
self status] == STATUS_LAUNCHING)
return;
7138 [
self setOrientation: kIdentityQuaternion];
7139 [UNIVERSE setUpBreakPattern:[
self breakPatternPosition] orientation:orientation forDocking:YES];
7140 [
self playDockWithStation];
7143 [[UNIVERSE gameView] clearKeys];
7150 if (dockedStation ==
nil)
7152 [
self setStatus:STATUS_IN_FLIGHT];
7156 [
self setStatus:STATUS_DOCKED];
7157 [UNIVERSE enterGUIViewModeWithMouseInteraction:NO];
7159 [
self loseTargetStatus];
7161 [
self setPosition:[dockedStation
position]];
7162 [
self setOrientation:kIdentityQuaternion];
7169 hyperspeed_engaged = NO;
7170 hyperspeed_locked = NO;
7172 forward_shield = [
self maxForwardShieldLevel];
7173 aft_shield = [
self maxAftShieldLevel];
7176 ship_temperature = 60.0f;
7178 [
self setAlertFlag:ALERT_FLAG_DOCKED to:YES];
7180 if ([dockedStation localMarket] ==
nil)
7185 NSString *escapepodReport = [
self processEscapePods];
7186 [
self addMessageToReport:escapepodReport];
7188 [
self unloadCargoPods];
7192 if ([dockedStation marketMonitored])
7195 [
self markAsOffender:[dockedStation
legalStatusOfManifest:shipCommodityData
export:NO] withReason:kOOLegalStatusReasonIllegalImports];
7196 if ([
self bounty] > oldbounty)
7198 [
self addRoleToPlayer:@"trader-smuggler"];
7203 NSString *passengerAndCargoReport = [
self checkPassengerContracts];
7204 [
self addMessageToReport:passengerAndCargoReport];
7206 [UNIVERSE setDisplayText:YES];
7213 if ([dockedStation requiresDockingClearance] &&
7214 ![
self clearedToDock] && ![[
UNIVERSE sun] willGoNova])
7216 [
self penaltyForUnauthorizedDocking];
7220 if (dockedStation == [
UNIVERSE station])
7224 if (being_fined && ![[
UNIVERSE sun] willGoNova] && ![dockedStation suppressArrivalReports]) [
self getFined];
7228 if (gui_screen != GUI_SCREEN_MISSION) [
self checkScript];
7231 [
self doScriptEvent:OOJSID("shipDockedWithStation") withArgument:dockedStation];
7233 if ([
self status] == STATUS_LAUNCHING)
return;
7236 if (gui_screen != GUI_SCREEN_MISSION)
7238 [
self setGuiToStatusScreen];
7244 [
self doWorldEventUntilMissionScreen:OOJSID("missionScreenOpportunity")];
7250 if (station ==
nil)
return;
7251 NSParameterAssert(station == [
self dockedStation]);
7254 [[UNIVERSE gameView] allowStringInput: NO];
7256 if (gui_screen == GUI_SCREEN_MISSION)
7258 [[UNIVERSE gui] clearBackground];
7259 if (_missionWithCallback)
7261 [
self doMissionCallback];
7264 [
self doWorldEventUntilMissionScreen:OOJSID("missionScreenEnded")];
7267 if ([station marketMonitored])
7272 if ([
self bounty] > oldbounty)
7274 [
self addRoleToPlayer:@"trader-smuggler"];
7278 gui_screen = GUI_SCREEN_MAIN;
7279 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen];
7281 if (![hud nonlinearScanner])
7283 [hud setScannerZoom: 1.0];
7285 [
self loadCargoPods];
7295 [
self clearAlertFlags];
7296 [
self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
7298 scanner_zoom_rate = 0.0f;
7300 [
self currentWeaponStats];
7302 forward_weapon_temp = 0.0f;
7303 aft_weapon_temp = 0.0f;
7304 port_weapon_temp = 0.0f;
7305 starboard_weapon_temp = 0.0f;
7307 forward_shield = [
self maxForwardShieldLevel];
7308 aft_shield = [
self maxAftShieldLevel];
7310 [
self clearTargetMemory];
7311 [
self setShowDemoShips:NO];
7312 [UNIVERSE setDisplayText:NO];
7313 [[UNIVERSE gameController] setMouseInteractionModeForFlight];
7315 [[UNIVERSE gameView] clearKeys];
7317 if ([
self isMouseControlOn])
7319 [[UNIVERSE gameView] resetMouse];
7324 [UNIVERSE forceWitchspaceEntries];
7325 ship_clock_adjust += 600.0;
7330 launchRoll = -flightRoll;
7332 [UNIVERSE setUpBreakPattern:[
self breakPatternPosition] orientation:orientation forDocking:YES];
7334 [
self setDockedStation:nil];
7336 suppressAegisMessages = YES;
7337 [
self checkForAegis];
7338 suppressAegisMessages = NO;
7341 [UNIVERSE removeDemoShips];
7346 [
self playLaunchFromStation];
7354 if (autopilot_engaged) [
self disengageAutopilot];
7356 if (![hud nonlinearScanner])
7358 [hud setScannerZoom: 1.0];
7360 [
self safeAllMissiles];
7362 OOViewID previousViewDirection = [UNIVERSE viewDirection];
7363 [UNIVERSE setViewDirection:VIEW_FORWARD];
7364 [
self noteSwitchToView:VIEW_FORWARD fromView:previousViewDirection];
7367 [
self currentWeaponStats];
7369 [
self transitionToAegisNone];
7370 suppressAegisMessages=YES;
7371 hyperspeed_engaged = NO;
7373 if ([
self primaryTarget] !=
nil)
7375 [
self noteLostTarget];
7379 scanner_zoom_rate = 0.0f;
7380 [UNIVERSE setDisplayText:NO];
7382 if ( ![
self wormhole] && !galactic_witchjump)
7386 [UNIVERSE allShipsDoScriptEvent:OOJSID("playerWillEnterWitchspace") andReactToAIMessage:@"PLAYER WITCHSPACE"];
7397 [UNIVERSE setSystemTo:system_id];
7398 galaxy_coordinates = [[UNIVERSE systemManager] getCoordinatesForSystem:system_id inGalaxy:galaxy_number];
7400 [UNIVERSE setUpUniverseFromWitchspace];
7401 [[UNIVERSE planet] update: 2.34375 * market_rnd];
7402 [[UNIVERSE station] update: 2.34375 * market_rnd];
7404 chart_centre_coordinates = galaxy_coordinates;
7405 target_chart_centre = chart_centre_coordinates;
7409- (BOOL) witchJumpChecklist:(BOOL)isGalacticJump
7412 if ([
self status] == STATUS_WITCHSPACE_COUNTDOWN)
7416 ShipEntity* blocker = [UNIVERSE entityForUniversalID:[
self checkShipsInVicinityForWitchJumpExit]];
7419 [UNIVERSE clearPreviousMessage];
7420 NSString *blockerName = [blocker
name];
7421 [UNIVERSE addMessage:OOExpandKey(@"witch-blocked", blockerName) forCount:4.5];
7422 [
self playWitchjumpBlocked];
7423 [
self setStatus:STATUS_IN_FLIGHT];
7436 if (![
UNIVERSE inInterstellarSpace] && system_id == target_system_id)
7440 [UNIVERSE clearPreviousMessage];
7441 [UNIVERSE addMessage:OOExpandKey(@"witch-no-target") forCount: 4.5];
7442 if ([
self status] == STATUS_WITCHSPACE_COUNTDOWN)
7444 [
self playWitchjumpInsufficientFuel];
7445 [
self setStatus:STATUS_IN_FLIGHT];
7448 else [
self playHyperspaceNoTarget];
7454 if ([
self hyperspaceJumpDistance] > [
self maxHyperspaceDistance])
7456 [UNIVERSE clearPreviousMessage];
7457 [UNIVERSE addMessage:DESC(@"witch-too-far") forCount: 4.5];
7458 if ([
self status] == STATUS_WITCHSPACE_COUNTDOWN)
7460 [
self playWitchjumpDistanceTooGreat];
7461 [
self setStatus:STATUS_IN_FLIGHT];
7464 else [
self playHyperspaceDistanceTooGreat];
7470 if (![
self hasSufficientFuelForJump])
7472 [UNIVERSE clearPreviousMessage];
7473 [UNIVERSE addMessage:DESC(@"witch-no-fuel") forCount: 4.5];
7474 if ([
self status] == STATUS_WITCHSPACE_COUNTDOWN)
7476 [
self playWitchjumpInsufficientFuel];
7477 [
self setStatus:STATUS_IN_FLIGHT];
7480 else [
self playHyperspaceNoFuel];
7489- (void) setJumpType:(BOOL)isGalacticJump
7493 galactic_witchjump = YES;
7497 galactic_witchjump = NO;
7505 NSPoint targetCoordinates =
PointFromString([[
UNIVERSE systemManager] getProperty:
@"coordinates" forSystem:[
self nextHopTargetSystemID] inGalaxy:galaxy_number]);
7512 return 10.0 *
MAX(0.1, [
self hyperspaceJumpDistance]);
7516- (BOOL) hasSufficientFuelForJump
7518 return fuel >= [
self fuelRequiredForJump];
7524 if ([[
self hud] isCompassActive])
7529 ShipScriptEvent(context,
self,
"compassTargetChanged", JSVAL_VOID, jsmode);
7532 [[
self hud] setCompassActive:NO];
7537- (void) enterGalacticWitchspace
7539 if (![
self witchJumpChecklist:true])
7550 [
self setStatus:STATUS_ENTERING_WITCHSPACE];
7552 [
self setJumpCause:@"galactic jump"];
7553 [
self setPreviousSystemID:[
self currentSystemID]];
7554 ShipScriptEvent(context,
self,
"shipWillEnterWitchspace", STRING_TO_JSVAL(JS_InternString(context, [[
self jumpCause] UTF8String])), INT_TO_JSVAL(destGalaxy));
7557 [
self noteCompassLostTarget];
7561 [UNIVERSE removeAllEntitiesExceptPlayer];
7565 [contracts removeAllObjects];
7568 [parcels removeAllObjects];
7571 if (missionDestinations)
7572 [missionDestinations removeAllObjects];
7578 for (i = 0; i < [passengers count]; i++)
7581 NSMutableDictionary* passenger_info = [NSMutableDictionary dictionaryWithDictionary:[passengers oo_dictionaryAtIndex:i]];
7582 [passenger_info setObject:[NSNumber numberWithDouble:ship_clock] forKey:CONTRACT_KEY_ARRIVAL_TIME];
7583 [passengers replaceObjectAtIndex:i withObject:passenger_info];
7588 if (ship_kills >= 6400)
7590 [
self clearRolesFromPlayer:0.25];
7592 else if (ship_kills >= 2560)
7594 [
self clearRolesFromPlayer:0.5];
7598 [
self clearRolesFromPlayer:0.9];
7600 [roleWeightFlags removeAllObjects];
7601 [roleSystemList removeAllObjects];
7604 [
self removeEquipmentItem:[
self equipmentItemProviding:@"EQ_GAL_DRIVE"]];
7606 galaxy_number = destGalaxy;
7608 [UNIVERSE setGalaxyTo:galaxy_number];
7615 switch (galacticHyperspaceBehaviour)
7617 case GALACTIC_HYPERSPACE_BEHAVIOUR_FIXED_COORDINATES:
7618 system_id = [UNIVERSE findSystemNumberAtCoords:galacticHyperspaceFixedCoords withGalaxy:galaxy_number includingHidden:YES];
7620 case GALACTIC_HYPERSPACE_BEHAVIOUR_ALL_SYSTEMS_REACHABLE:
7621 system_id = [UNIVERSE findSystemNumberAtCoords:galaxy_coordinates withGalaxy:galaxy_number includingHidden:YES];
7623 case GALACTIC_HYPERSPACE_BEHAVIOUR_STANDARD:
7626 system_id = [UNIVERSE findConnectedSystemAtCoords:galaxy_coordinates withGalaxy:galaxy_number];
7629 target_system_id = system_id;
7630 info_system_id = system_id;
7632 [
self setBounty:0 withReason:kOOLegalStatusReasonNewGalaxy];
7633 cursor_coordinates =
PointFromString([[
UNIVERSE systemManager] getProperty:
@"coordinates" forSystem:system_id inGalaxy:galaxy_number]);
7643 if ([
self status] == STATUS_ENTERING_WITCHSPACE
7644 || [
self status] == STATUS_EXITING_WITCHSPACE)
7648 BOOL misjump = [
self scriptedMisjump] || [w_hole
withMisjump] || flightPitch == max_flight_pitch ||
randf() > 0.995;
7649 wormhole = [w_hole retain];
7650 [
self addScannedWormhole:wormhole];
7651 [
self setStatus:STATUS_ENTERING_WITCHSPACE];
7653 [
self setJumpCause:@"wormhole"];
7654 [
self setPreviousSystemID:[
self currentSystemID]];
7655 ShipScriptEvent(context,
self,
"shipWillEnterWitchspace", STRING_TO_JSVAL(JS_InternString(context, [[
self jumpCause] UTF8String])), INT_TO_JSVAL([w_hole destination]));
7657 if ([
self scriptedMisjump])
7661#ifdef OO_DUMP_PLANETINFO
7664 if (misjump && [
self scriptedMisjumpRange] != 0.5)
7668 [
self witchJumpTo:[w_hole
destination] misjump:misjump];
7672- (void) enterWitchspace
7674 if (![
self witchJumpChecklist:false]) return;
7676 OOSystemID jumpTarget = [
self nextHopTargetSystemID];
7679 unsigned malfunc_chance = 253;
7680 if (ship_trade_in_factor < 80)
7682 malfunc_chance -= (1 +
ranrot_rand() % (81-ship_trade_in_factor)) / 2;
7684 else if (ship_trade_in_factor >= 100)
7686 malfunc_chance = 256;
7689#ifdef OO_DUMP_PLANETINFO
7692 BOOL malfunc = ((
ranrot_rand() & 0xff) > malfunc_chance);
7694 BOOL misjump = [
self scriptedMisjump] || (flightPitch == max_flight_pitch) || (malfunc && (
randf() > 0.75));
7696 if (malfunc && !misjump)
7699 if ([
self takeInternalDamage])
7701 [
self playWitchjumpFailure];
7702 [
self setStatus:STATUS_IN_FLIGHT];
7708 [
self setFuelLeak:[NSString stringWithFormat:@"%f", (randf() + randf()) * 5.0]];
7716 fuel -= [
self fuelRequiredForJump];
7719 wormhole = [[
WormholeEntity alloc] initWormholeTo:jumpTarget fromShip:self];
7720 [UNIVERSE addEntity:wormhole];
7721 [
self addScannedWormhole:wormhole];
7723 [
self setStatus:STATUS_ENTERING_WITCHSPACE];
7725 [
self setJumpCause:@"standard jump"];
7726 [
self setPreviousSystemID:[
self currentSystemID]];
7727 ShipScriptEvent(context,
self,
"shipWillEnterWitchspace", STRING_TO_JSVAL(JS_InternString(context, [[
self jumpCause] UTF8String])), INT_TO_JSVAL(jumpTarget));
7730 [
self updateSystemMemory];
7731 NSUInteger legality = [
self legalStatusOfCargoList];
7734 if ([roleWeightFlags objectForKey:
@"bought-legal"])
7736 if (maxSpace != availSpace)
7738 [
self addRoleToPlayer:@"trader"];
7739 if (maxSpace - availSpace > 20 || availSpace == 0)
7743 [
self addRoleToPlayer:@"trader"];
7748 if ([roleWeightFlags objectForKey:
@"bought-illegal"])
7750 if (maxSpace != availSpace && legality > 0)
7752 [
self addRoleToPlayer:@"trader-smuggler"];
7753 if (maxSpace - availSpace > 20 || availSpace == 0)
7755 if (legality >= 20 || legality >= maxSpace)
7757 [
self addRoleToPlayer:@"trader-smuggler"];
7762 [roleWeightFlags removeAllObjects];
7764 [
self noteCompassLostTarget];
7765 if ([
self scriptedMisjump])
7771 [wormhole setMisjumpWithRange:[
self scriptedMisjumpRange]];
7773 [
self witchJumpTo:jumpTarget misjump:misjump];
7777- (void) witchJumpTo:(
OOSystemID)sTo misjump:(BOOL)misjump
7780 if (info_system_id == system_id)
7782 [
self setInfoSystemID: sTo moveChart: YES];
7785 if (2 * market_rnd < ship_trade_in_factor)
7788 [
self adjustTradeInFactorBy:-(1 + (market_rnd & 3))];
7792 NSPoint destCoords =
PointFromString([[
UNIVERSE systemManager] getProperty:
@"coordinates" forSystem:sTo inGalaxy:galaxy_number]);
7797 if (theSun && [theSun goneNova])
7802 [UNIVERSE removeAllEntitiesExceptPlayer];
7805 ship_clock_adjust += distance * distance * 3600.0;
7806 [
self setSystemID:sTo];
7807 [
self setBounty:(legalStatus/2) withReason:kOOLegalStatusReasonNewSystem];
7809 if (market_rnd < 8) [
self erodeReputation];
7815 if (
randf() < 0.1) [
self erodeReputation];
7817 [wormhole setMisjump];
7822 NSPoint dest = [wormhole destinationCoordinates];
7823 galaxy_coordinates.x = dest.x;
7824 galaxy_coordinates.y = dest.y;
7826 ship_clock_adjust += [wormhole travelTime];
7828 [
self playWitchjumpMisjump];
7829 [UNIVERSE setUpUniverseFromMisjump];
7834- (void) leaveWitchspace
7837 HPVector pos = [UNIVERSE getWitchspaceExitPosition];
7839 HPVector whpos, exitpos;
7841 double min_d1 = [UNIVERSE safeWitchspaceExitDistance];
7843 if (abs((
int)d1) < min_d1)
7845 d1 += ((d1 > 0.0)? min_d1: -min_d1);
7848 exitpos = HPvector_add(pos, HPvector_multiply_scalar(v1, d1));
7850 [
self setOrientation:[UNIVERSE getWitchspaceExitRotation]];
7858 if ([[wormhole shipsInTransit]
count] > 0)
7861 double wh_arrival_time = ([PLAYER clockTimeAdjusted] - [wormhole arrivalTime]);
7862 if (wh_arrival_time > 0)
7865 whpos = HPvector_add(exitpos, vectorToHPVector(vector_multiply_scalar([
self forwardVector], 1000.0f)));
7866 [wormhole setContainsPlayer:YES];
7871 whpos = HPvector_add(exitpos, vectorToHPVector(vector_multiply_scalar([
self forwardVector], -500.0f)));
7873 [wormhole setExitSpeed:maxFlightSpeed*WORMHOLE_LEADER_SPEED_FACTOR];
7876 HPVector distance = HPvector_subtract(whpos, pos);
7877 if (HPmagnitude2(distance) < min_d1*min_d1 )
7881 distance = HPvector_multiply_scalar(HPvector_normal(distance), min_d1);
7882 whpos = HPvector_add(whpos, distance);
7883 position = HPvector_add(position, distance);
7885 [wormhole setExitPosition: whpos];
7890 [wormhole setExitSpeed:maxFlightSpeed*WORMHOLE_LEADER_SPEED_FACTOR];
7897 flightSpeed = wormhole ? [wormhole exitSpeed] : fmin(maxFlightSpeed,50.0f);
7906 [
self setStatus:STATUS_EXITING_WITCHSPACE];
7907 gui_screen = GUI_SCREEN_MAIN;
7909 [
self clearTargetMemory];
7910 [
self setShowDemoShips:NO];
7911 [[UNIVERSE gameController] setMouseInteractionModeForFlight];
7912 [UNIVERSE setDisplayText:NO];
7913 [UNIVERSE setWitchspaceBreakPattern:YES];
7914 [
self playExitWitchspace];
7915 if ([
self currentSystemID] >= 0)
7917 if (![roleSystemList containsObject:[NSNumber numberWithInt:[
self currentSystemID]]])
7920 [
self clearRoleFromPlayer:NO];
7924 if (galactic_witchjump)
7926 [
self doScriptEvent:OOJSID("playerEnteredNewGalaxy") withArgument:[NSNumber numberWithUnsignedInt:galaxy_number]];
7929 [
self doScriptEvent:OOJSID("shipWillExitWitchspace") withArgument:[
self jumpCause]];
7930 [UNIVERSE setUpBreakPattern:[
self breakPatternPosition] orientation:orientation forDocking:NO];
7936- (void) setGuiToStatusScreen
7938 NSString *systemName =
nil;
7939 NSString *targetSystemName =
nil;
7940 NSString *text =
nil;
7944 if (oldScreen != GUI_SCREEN_STATUS)
7946 [
self noteGUIWillChangeTo:GUI_SCREEN_STATUS];
7949 gui_screen = GUI_SCREEN_STATUS;
7950 BOOL guiChanged = (oldScreen != gui_screen);
7952 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:NO];
7956 systemName = [UNIVERSE inInterstellarSpace] ?
DESC(
@"interstellar-space") : [
UNIVERSE getSystemName:system_id];
7957 if ([
self isDocked] && [
self dockedStation] != [
UNIVERSE station])
7959 systemName = [NSString stringWithFormat:@"%@ : %@", systemName, [[
self dockedStation] displayName]];
7962 targetSystemName = [UNIVERSE getSystemName:target_system_id];
7963 NSDictionary *systemInfo = [[UNIVERSE systemManager] getPropertiesForSystem:target_system_id inGalaxy:galaxy_number];
7964 NSInteger concealment = [systemInfo oo_intForKey:@"concealment" defaultValue:OO_SYSTEMCONCEALMENT_NONE];
7967 OOSystemID nextHop = [
self nextHopTargetSystemID];
7968 if (nextHop != target_system_id) {
7969 NSString *nextHopSystemName = [UNIVERSE getSystemName:nextHop];
7970 systemInfo = [[UNIVERSE systemManager] getPropertiesForSystem:nextHop inGalaxy:galaxy_number];
7971 concealment = [systemInfo oo_intForKey:@"concealment" defaultValue:OO_SYSTEMCONCEALMENT_NONE];
7973 targetSystemName =
OOExpandKey(
@"status-hyperspace-system-multi", targetSystemName, nextHopSystemName);
7978 NSString *shipName = [
self displayName];
7979 NSString *legal_desc =
nil, *rating_desc =
nil,
7980 *alert_desc =
nil, *fuel_desc =
nil,
7981 *credits_desc =
nil;
7991 NSString *lightYearsDesc =
DESC(
@"status-light-years-desc");
7996 fuel_desc = [NSString stringWithFormat:@"%.1f %@", fuel/10.0, lightYearsDesc];
8000 text =
DESC(
@"status-commander-@");
8001 [gui
setTitle:[NSString stringWithFormat:text, [
self commanderName]]];
8005 [gui
setArray:[NSArray arrayWithObjects:DESC(@"status-present-system"), systemName, nil]
forRow:1];
8006 if ([
self hasHyperspaceMotor]) [gui
setArray:[NSArray arrayWithObjects:DESC(@"status-hyperspace-system"), targetSystemName, nil]
forRow:2];
8007 [gui
setArray:[NSArray arrayWithObjects:DESC(@"status-condition"), alert_desc, nil]
forRow:3];
8008 [gui
setArray:[NSArray arrayWithObjects:DESC(@"status-fuel"), fuel_desc, nil]
forRow:4];
8009 [gui
setArray:[NSArray arrayWithObjects:DESC(@"status-cash"), credits_desc, nil]
forRow:5];
8010 [gui
setArray:[NSArray arrayWithObjects:DESC(@"status-legal-status"), legal_desc, nil]
forRow:6];
8011 [gui
setArray:[NSArray arrayWithObjects:DESC(@"status-rating"), rating_desc, nil]
forRow:7];
8015 for (i = 1 ; i <= 7 ; ++i)
8031 [lastTextKey release];
8035 [[UNIVERSE gameView] clearMouse];
8038 if (
EXPECT_NOT([[NSUserDefaults standardUserDefaults] boolForKey:
@"show-ship-model-in-status-screen"]))
8040 [UNIVERSE removeDemoShips];
8041 [
self showShipModelWithKey:[
self shipDataKey] shipData:nil personality:[
self entityPersonalityInt]
8042 factorX:2.5 factorY:1.7 factorZ:8.0 inContext:@"GUI_SCREEN_STATUS"];
8043 [
self setShowDemoShips:YES];
8047 [
self setShowDemoShips:NO];
8050 [UNIVERSE enterGUIViewModeWithMouseInteraction:NO];
8054 NSDictionary *fgDescriptor =
nil, *bgDescriptor =
nil;
8055 if ([
self status] == STATUS_DOCKED)
8057 fgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"docked_overlay"];
8058 bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"status_docked"];
8062 fgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"overlay"];
8063 if (alertCondition ==
ALERT_CONDITION_RED) bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"status_red_alert"];
8064 else bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"status_in_flight"];
8069 if (bgDescriptor ==
nil) bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"status"];
8073 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen];
8078- (NSArray *) equipmentList
8081 NSMutableArray *quip1 = [NSMutableArray array];
8082 NSMutableArray *quip2 = [NSMutableArray array];
8083 NSEnumerator *eqTypeEnum =
nil;
8085 NSString *desc =
nil;
8086 NSString *alldesc =
nil;
8088 BOOL prioritiseDamaged = [[gui
userSettings] oo_boolForKey:kGuiStatusPrioritiseDamaged defaultValue:YES];
8090 for (eqTypeEnum = [
OOEquipmentType reverseEquipmentEnumerator]; (eqType = [eqTypeEnum nextObject]); )
8092 if ([eqType isVisible])
8094 if ([eqType canCarryMultiple] && ![eqType isMissileOrMine])
8096 NSString *damagedIdentifier = [[eqType
identifier] stringByAppendingString:@"_DAMAGED"];
8097 NSUInteger
count = 0, okcount = 0;
8098 okcount = [
self countEquipmentItem:[eqType
identifier]];
8099 count = okcount + [
self countEquipmentItem:damagedIdentifier];
8105 else if (
count == okcount)
8110 [quip2 addObject:[NSArray arrayWithObjects:[eqType
name], [NSNumber numberWithBool:YES], [eqType
displayColor], nil]];
8115 NSString *equipmentName = [eqType
name];
8117 [quip2 addObject:[NSArray arrayWithObjects:alldesc, [NSNumber numberWithBool:YES], [eqType
displayColor], nil]];
8121 else if (
count == 1 && okcount == 0)
8123 desc = [NSString stringWithFormat:DESC(@"equipment-@-not-available"), [eqType
name]];
8124 if (prioritiseDamaged)
8126 [quip1 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:NO], [eqType
displayColor], nil]];
8130 [quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:NO], [eqType
displayColor], nil]];
8136 NSString *equipmentName = [eqType
name];
8137 alldesc =
OOExpandKey(
@"equipment-plural-some-na", okcount,
count, equipmentName);
8138 if (prioritiseDamaged)
8140 [quip1 addObject:[NSArray arrayWithObjects:alldesc, [NSNumber numberWithBool:NO], [eqType
displayColor], nil]];
8144 [quip2 addObject:[NSArray arrayWithObjects:alldesc, [NSNumber numberWithBool:NO], [eqType
displayColor], nil]];
8148 else if ([
self hasEquipmentItem:[eqType identifier]])
8150 [quip2 addObject:[NSArray arrayWithObjects:[eqType
name], [NSNumber numberWithBool:YES], [eqType
displayColor], nil]];
8155 if ([
self hasEquipmentItem:[[eqType identifier] stringByAppendingString:
@"_DAMAGED"]])
8157 desc = [NSString stringWithFormat:DESC(@"equipment-@-not-available"), [eqType
name]];
8159 if (prioritiseDamaged)
8161 [quip1 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:NO], [eqType
displayColor], nil]];
8166 [quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:NO], [eqType
displayColor], nil]];
8173 if (max_passengers > 0)
8175 desc = [NSString stringWithFormat:DESC_PLURAL(@"equipment-pass-berth-@", max_passengers), max_passengers];
8181 desc = [NSString stringWithFormat:DESC(@"equipment-fwd-weapon-@"),[forward_weapon_type name]];
8182 [quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:YES], [forward_weapon_type displayColor], nil]];
8186 desc = [NSString stringWithFormat:DESC(@"equipment-aft-weapon-@"),[aft_weapon_type name]];
8187 [quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:YES], [aft_weapon_type displayColor], nil]];
8191 desc = [NSString stringWithFormat:DESC(@"equipment-port-weapon-@"),[port_weapon_type name]];
8192 [quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:YES], [port_weapon_type displayColor], nil]];
8196 desc = [NSString stringWithFormat:DESC(@"equipment-stb-weapon-@"),[starboard_weapon_type name]];
8197 [quip2 addObject:[NSArray arrayWithObjects:desc, [NSNumber numberWithBool:YES], [starboard_weapon_type displayColor], nil]];
8201 [quip1 addObjectsFromArray:quip2];
8206- (NSUInteger) primedEquipmentCount
8208 return [eqScripts count];
8212- (NSString *) primedEquipmentName:(NSInteger)offset
8214 NSUInteger c = [
self primedEquipmentCount];
8215 NSUInteger idx = (primedEquipment+(c+1)+
offset)%(c+1);
8218 return DESC(
@"equipment-primed-none-hud-label");
8227- (NSString *) currentPrimedEquipment
8229 NSString *result =
@"";
8230 NSUInteger c = [eqScripts count];
8231 if (primedEquipment != c)
8233 result = [[eqScripts oo_arrayAtIndex:primedEquipment] oo_stringAtIndex:0];
8239- (BOOL) setPrimedEquipment:(NSString *)eqKey showMessage:(BOOL)showMsg
8241 NSUInteger c = [eqScripts count];
8242 NSUInteger current = primedEquipment;
8243 primedEquipment = [
self eqScriptIndexForKey:eqKey];
8244 BOOL unprimeEq = [eqKey isEqualToString:@""];
8247 if (primedEquipment == c && !unprimeEq)
8249 primedEquipment = current;
8254 if (primedEquipment != current && showMsg == YES)
8257 [UNIVERSE addMessage:unprimeEq ? OOExpandKey(@"equipment-primed-none") : OOExpandKey(@"equipment-primed", equipmentName) forCount:2.0];
8267 if(index < [eqScripts
count])
8269 OOJSScript *eqScript = [[eqScripts oo_arrayAtIndex:index] objectAtIndex:1];
8288- (NSString *) fastEquipmentA
8290 return _fastEquipmentA;
8294- (NSString *) fastEquipmentB
8296 return _fastEquipmentB;
8300- (void) setFastEquipmentA:(NSString *)eqKey
8302 [_fastEquipmentA release];
8303 _fastEquipmentA = [eqKey copy];
8307- (void) setFastEquipmentB:(NSString *)eqKey
8309 [_fastEquipmentB release];
8310 _fastEquipmentB = [eqKey copy];
8321 weaponType = forward_weapon_type;
8325 weaponType = aft_weapon_type;
8329 weaponType = port_weapon_type;
8333 weaponType = starboard_weapon_type;
8344- (NSArray *) missilesList
8346 [
self tidyMissilePylons];
8347 return [
super missilesList];
8351- (NSArray *) cargoList
8353 NSMutableArray *manifest = [NSMutableArray array];
8354 NSArray *list = [
self cargoListForScripting];
8355 NSDictionary *commodity;
8357 if (specialCargo) [manifest addObject:specialCargo];
8359 foreach (commodity, list)
8361 NSInteger quantity = [commodity oo_integerForKey:@"quantity"];
8362 NSString *units = [commodity oo_stringForKey:@"unit"];
8363 NSString *commodityName = [commodity oo_stringForKey:@"displayName"];
8364 NSInteger containers = [commodity oo_intForKey:@"containers"];
8365 BOOL extended = ![units isEqualToString:DESC(@"cargo-tons-symbol")] && containers > 0;
8368 [manifest addObject:OOExpandKey(@"manifest-cargo-quantity-extended", quantity, units, commodityName, containers)];
8370 [manifest addObject:OOExpandKey(@"manifest-cargo-quantity", quantity, units, commodityName)];
8378- (NSArray *) cargoListForScripting
8380 NSMutableArray *list = [NSMutableArray array];
8382 NSUInteger i, j, commodityCount = [shipCommodityData count];
8385 NSArray *goods = [shipCommodityData goods];
8388 for (i = 0; i < commodityCount; i++)
8390 quantityInHold[i] = [shipCommodityData quantityForGood:[goods oo_stringAtIndex:i]];
8391 containersInHold[i] = 0;
8393 for (i = 0; i < [cargo count]; i++)
8395 ShipEntity *container = [cargo objectAtIndex:i];
8397 quantityInHold[j] += [container commodityAmount];
8398 ++containersInHold[j];
8401 for (i = 0; i < commodityCount; i++)
8403 if (quantityInHold[i] > 0)
8405 NSMutableDictionary *commodity = [NSMutableDictionary dictionaryWithCapacity:4];
8406 NSString *symName = [goods oo_stringAtIndex:i];
8408 [commodity setObject:symName forKey:@"commodity"];
8409 [commodity setObject:[NSNumber numberWithUnsignedInt:quantityInHold[i]] forKey:@"quantity"];
8410 [commodity setObject:[NSNumber numberWithUnsignedInt:containersInHold[i]] forKey:@"containers"];
8411 [commodity setObject:[shipCommodityData nameForGood:symName] forKey:@"displayName"];
8412 [commodity setObject:DisplayStringForMassUnitForCommodity(symName) forKey:@"unit"];
8413 [list addObject:commodity];
8417 return [[list copy] autorelease];
8422- (unsigned) legalStatusOfCargoList
8424 NSString *good =
nil;
8426 unsigned penalty = 0;
8428 foreach (good, [shipCommodityData goods])
8430 amount = [shipCommodityData quantityForGood:good];
8431 penalty += [shipCommodityData exportLegalityForGood:good] * amount;
8437- (NSArray*) contractsListForScriptingFromArray:(NSArray *) contracts_array forCargo:(BOOL)forCargo
8439 NSMutableArray *result = [NSMutableArray array];
8442 for (i = 0; i < [contracts_array count]; i++)
8444 NSMutableDictionary *contract = [NSMutableDictionary dictionaryWithCapacity:10];
8445 NSDictionary *dict = [contracts_array oo_dictionaryAtIndex:i];
8449 [contract setObject:[dict oo_stringForKey:CARGO_KEY_TYPE] forKey:@"commodity"];
8450 [contract setObject:[NSNumber numberWithUnsignedInt:[dict oo_intForKey:CARGO_KEY_AMOUNT]] forKey:@"quantity"];
8451 [contract setObject:[dict oo_stringForKey:CARGO_KEY_DESCRIPTION] forKey:@"description"];
8455 [contract setObject:[dict oo_stringForKey:PASSENGER_KEY_NAME] forKey:PASSENGER_KEY_NAME];
8456 [contract setObject:[NSNumber numberWithUnsignedInt:[dict oo_unsignedIntForKey:CONTRACT_KEY_RISK]] forKey:CONTRACT_KEY_RISK];
8459 OOSystemID planet = [dict oo_intForKey:CONTRACT_KEY_DESTINATION];
8460 NSString *planetName = [UNIVERSE getSystemName:planet];
8461 [contract setObject:[NSNumber numberWithUnsignedInt:planet] forKey:CONTRACT_KEY_DESTINATION];
8462 [contract setObject:planetName forKey:@"destinationName"];
8463 planet = [dict oo_intForKey:CONTRACT_KEY_START];
8464 planetName = [UNIVERSE getSystemName: planet];
8465 [contract setObject:[NSNumber numberWithUnsignedInt:planet] forKey:CONTRACT_KEY_START];
8466 [contract setObject:planetName forKey:@"startName"];
8468 int dest_eta = [dict oo_doubleForKey:CONTRACT_KEY_ARRIVAL_TIME] - ship_clock;
8469 [contract setObject:[NSNumber numberWithInt:dest_eta] forKey:@"eta"];
8470 [contract setObject:[UNIVERSE shortTimeDescription:dest_eta] forKey:@"etaDescription"];
8471 [contract setObject:[NSNumber numberWithInt:[dict oo_intForKey:CONTRACT_KEY_PREMIUM]] forKey:CONTRACT_KEY_PREMIUM];
8472 [contract setObject:[NSNumber numberWithInt:[dict oo_intForKey:CONTRACT_KEY_FEE]] forKey:CONTRACT_KEY_FEE];
8473 [result addObject:contract];
8476 return [[result copy] autorelease];
8480- (NSArray *) passengerListForScripting
8482 return [
self contractsListForScriptingFromArray:passengers forCargo:NO];
8486- (NSArray *) parcelListForScripting
8488 return [
self contractsListForScriptingFromArray:parcels forCargo:NO];
8492- (NSArray *) contractListForScripting
8494 return [
self contractsListForScriptingFromArray:contracts forCargo:YES];
8497- (void) setGuiToSystemDataScreen
8499 [
self setGuiToSystemDataScreenRefreshBackground: NO];
8502- (void) setGuiToSystemDataScreenRefreshBackground: (BOOL) refreshBackground
8504 NSDictionary *infoSystemData;
8505 NSString *infoSystemName;
8507 infoSystemData = [[UNIVERSE generateSystemData:info_system_id] retain];
8508 NSInteger concealment = [infoSystemData oo_intForKey:@"concealment" defaultValue:OO_SYSTEMCONCEALMENT_NONE];
8509 infoSystemName = [infoSystemData oo_stringForKey:KEY_NAME];
8511 BOOL sunGoneNova = ([infoSystemData oo_boolForKey:@"sun_gone_nova"]);
8515 gui_screen = GUI_SCREEN_SYSTEM_DATA;
8516 BOOL guiChanged = (oldScreen != gui_screen);
8518 Random_Seed infoSystemRandomSeed = [[UNIVERSE systemManager] getRandomSeedForSystem:info_system_id
8519 inGalaxy:[
self galaxyNumber]];
8521 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:NO];
8532 NSUInteger techLevel = [infoSystemData oo_intForKey:KEY_TECHLEVEL] + 1;
8533 int population = [infoSystemData oo_intForKey:KEY_POPULATION];
8534 int productivity = [infoSystemData oo_intForKey:KEY_PRODUCTIVITY];
8535 int radius = [infoSystemData oo_intForKey:KEY_RADIUS];
8537 NSString *government_desc = [infoSystemData oo_stringForKey:KEY_GOVERNMENT_DESC
8538 defaultValue:OODisplayStringFromGovernmentID([infoSystemData oo_intForKey:KEY_GOVERNMENT])];
8539 NSString *economy_desc = [infoSystemData oo_stringForKey:KEY_ECONOMY_DESC
8540 defaultValue:OODisplayStringFromEconomyID([infoSystemData oo_intForKey:KEY_ECONOMY])];
8541 NSString *inhabitants = [infoSystemData oo_stringForKey:KEY_INHABITANTS];
8542 NSString *system_desc = [infoSystemData oo_stringForKey:KEY_DESCRIPTION];
8544 NSString *populationDesc = [infoSystemData oo_stringForKey:KEY_POPULATION_DESC
8545 defaultValue:OOExpandKeyWithSeed(kNilRandomSeed, @"sysdata-pop-value", population)];
8558 NSString *system = infoSystemName;
8559 system_desc =
OOExpandKeyWithSeed(infoSystemRandomSeed,
@"nova-system-description", system);
8561 populationDesc =
OOExpandKeyWithSeed(infoSystemRandomSeed,
@"sysdata-pop-value", population);
8566 [UNIVERSE removeDemoShips];
8570 NSString *system = infoSystemName;
8571 [gui
setTitle:OOExpandKeyWithSeed(infoSystemRandomSeed, @"sysdata-data-on-system", system)];
8575 [gui
setTitle:OOExpandKey(@"sysdata-data-on-system-no-name")];
8582 for (i-- ; i > 14 ; --i)
8589 NSPoint infoSystemCoordinates = [[UNIVERSE systemManager] getCoordinatesForSystem: info_system_id inGalaxy: galaxy_number];
8591 if(distance == 0.0 && info_system_id != system_id)
8595 NSString *distanceInfo = [NSString stringWithFormat: @"%.1f ly", distance];
8598 NSDictionary *routeInfo =
nil;
8599 routeInfo = [UNIVERSE routeFromSystem: system_id toSystem: info_system_id optimizedBy: ANA_mode];
8600 if (routeInfo !=
nil)
8602 double routeDistance = [[routeInfo objectForKey: @"distance"] doubleValue];
8603 double routeTime = [[routeInfo objectForKey: @"time"] doubleValue];
8604 int routeJumps = [[routeInfo objectForKey: @"jumps"] intValue];
8605 if(routeDistance == 0.0 && info_system_id != system_id) {
8606 routeDistance = 0.1;
8610 distanceInfo = [NSString stringWithFormat: @"%.1f ly / %.1f %@ / %d %@",
8614 routeTime > 1.05 || routeTime < 0.95 ? DESC(@"sysdata-route-hours%1") : DESC(@"sysdata-route-hours%0"),
8616 DESC_PLURAL(@"sysdata-route-jumps", routeJumps)];
8622 for (i = 1; i <= 16; i++) {
8623 NSString *ln = [NSString stringWithFormat:@"sysdata-line-%ld", (long)i];
8624 NSString *line =
OOExpandKeyWithSeed(infoSystemRandomSeed, ln, economy_desc, government_desc, techLevel, populationDesc, inhabitants, productivity, radius, distanceInfo);
8625 if (![line isEqualToString:
@""])
8627 NSArray *lines = [line componentsSeparatedByString:@"\t"];
8628 if ([lines
count] == 1)
8630 [gui
setArray:[NSArray arrayWithObjects:[lines objectAtIndex:0],
8634 if ([lines
count] == 2)
8636 [gui
setArray:[NSArray arrayWithObjects:[lines objectAtIndex:0],
8637 [lines objectAtIndex:1],
8641 if ([lines
count] == 3)
8643 if ([[lines objectAtIndex:2] isEqualToString:
@""])
8645 [gui
setArray:[NSArray arrayWithObjects:[lines objectAtIndex:0],
8646 [lines objectAtIndex:1],
8652 [gui
setArray:[NSArray arrayWithObjects:[lines objectAtIndex:0],
8653 [lines objectAtIndex:1],
8654 [lines objectAtIndex:2],
8662 [gui
setArray:[NSArray arrayWithObjects:@"",
8671 for (i-- ; i > 16 ; --i)
8675 for (i = 1 ; i <= 14 ; ++i)
8686 [lastTextKey release];
8689 [[UNIVERSE gameView] clearMouse];
8691 [infoSystemData release];
8693 [
self setShowDemoShips:NO];
8694 [UNIVERSE enterGUIViewModeWithMouseInteraction:NO];
8704 if (info_system_id == system_id)
8706 [
self setBackgroundFromDescriptionsKey:@"gui-scene-show-local-planet"];
8710 [
self setBackgroundFromDescriptionsKey:@"gui-scene-show-planet"];
8717 if (refreshBackground || guiChanged)
8722 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen refresh: refreshBackground];
8728- (void) prepareMarkedDestination:(NSMutableDictionary *)markers :(NSDictionary *)marker
8730 NSNumber *key = [NSNumber numberWithInt:[marker oo_intForKey:@"system"]];
8731 NSMutableArray *list = [markers objectForKey:key];
8734 list = [NSMutableArray arrayWithObject:marker];
8738 [list addObject:marker];
8740 [markers setObject:list forKey:key];
8744- (NSDictionary *) markedDestinations
8747 NSMutableDictionary *destinations = [NSMutableDictionary dictionaryWithCapacity:256];
8750 NSDictionary *marker;
8752 for (i = 0; i < [passengers count]; i++)
8754 sysid = [[passengers oo_dictionaryAtIndex:i] oo_unsignedCharForKey:CONTRACT_KEY_DESTINATION];
8755 marker = [
self passengerContractMarker:sysid];
8756 [
self prepareMarkedDestination:destinations:marker];
8758 for (i = 0; i < [parcels count]; i++)
8760 sysid = [[parcels oo_dictionaryAtIndex:i] oo_unsignedCharForKey:CONTRACT_KEY_DESTINATION];
8761 marker = [
self parcelContractMarker:sysid];
8762 [
self prepareMarkedDestination:destinations:marker];
8764 for (i = 0; i < [contracts count]; i++)
8766 sysid = [[contracts oo_dictionaryAtIndex:i] oo_unsignedCharForKey:CONTRACT_KEY_DESTINATION];
8767 marker = [
self cargoContractMarker:sysid];
8768 [
self prepareMarkedDestination:destinations:marker];
8771 NSString *key =
nil;
8775 marker = [missionDestinations objectForKey:key];
8776 [
self prepareMarkedDestination:destinations:marker];
8779 return destinations;
8782- (void) setGuiToLongRangeChartScreen
8788 [
self setMissionBackgroundSpecial: nil];
8789 gui_screen = GUI_SCREEN_LONG_RANGE_CHART;
8791 [
self setGuiToChartScreenFrom: oldScreen];
8794- (void) setGuiToShortRangeChartScreen
8800 [
self setMissionBackgroundSpecial: nil];
8801 gui_screen = GUI_SCREEN_SHORT_RANGE_CHART;
8802 [
self setGuiToChartScreenFrom: oldScreen];
8809 BOOL guiChanged = (oldScreen != gui_screen);
8811 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
8813 target_system_id = [UNIVERSE findSystemNumberAtCoords:cursor_coordinates withGalaxy:galaxy_number includingHidden:NO];
8815 [UNIVERSE preloadPlanetTexturesForSystem:target_system_id];
8833 if (gui_screen == GUI_SCREEN_LONG_RANGE_CHART)
8835 NSString *displaySearchString = planetSearchString ? [planetSearchString capitalizedString] : (NSString *)
@"";
8836 [gui
setText:[NSString stringWithFormat:DESC(@"long-range-chart-find-planet-@"), displaySearchString]
forRow:GUI_ROW_PLANET_FINDER];
8848 [
self setShowDemoShips:NO];
8849 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
8856 if (found_system_id >= 0)
8858 [UNIVERSE findSystemCoordinatesWithPrefix:[[UNIVERSE getSystemName:found_system_id] lowercaseString] exactMatch:YES];
8860 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen];
8865static NSString *SliderString(NSInteger amountIn20ths)
8867 NSString *filledSlider = [@"|||||||||||||||||||||||||" substringToIndex:amountIn20ths];
8868 NSString *emptySlider = [@"........................." substringToIndex:20 - amountIn20ths];
8869 return [NSString stringWithFormat:@"%@%@", filledSlider, emptySlider];
8873- (void) setGuiToGameOptionsScreen
8877 [[UNIVERSE gameView] clearMouse];
8878 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
8880 gui_screen = GUI_SCREEN_GAMEOPTIONS;
8884 #define OO_SETACCESSCONDITIONFORROW(condition, row) \
8888 [gui setKey:GUI_KEY_OK forRow:(row)]; \
8892 [gui setColor:[OOColor grayColor] forRow:(row)]; \
8895 BOOL startingGame = [
self status] == STATUS_START_GAME;
8902 [gui
setTitle:[NSString stringWithFormat:DESC(@"status-commander-@"), [
self commanderName]]];
8904#if OO_RESOLUTION_OPTION
8908 if (displayModeIndex == NSNotFound)
8910 OOLogWARN(
@"display.currentMode.notFound",
@"%@",
@"couldn't find current fullscreen setting, switching to default.");
8911 displayModeIndex = 0;
8916 if ([modeList
count])
8918 mode = [modeList objectAtIndex:displayModeIndex];
8922 unsigned modeWidth = [mode oo_unsignedIntForKey:kOODisplayWidth];
8923 unsigned modeHeight = [mode oo_unsignedIntForKey:kOODisplayHeight];
8924 float modeRefresh = [mode oo_floatForKey:kOODisplayRefreshRate];
8928 if (!runningOnPrimaryDisplayDevice)
8930 MONITORINFOEX mInfo = [gameView currentMonitorInfo];
8931 modeWidth = mInfo.rcMonitor.right - mInfo.rcMonitor.left;
8932 modeHeight = mInfo.rcMonitor.bottom - mInfo.rcMonitor.top;
8936 NSString *displayModeString = [
self screenModeStringForWidth:modeWidth height:modeHeight refreshRate:modeRefresh];
8939 if (runningOnPrimaryDisplayDevice)
8951 if ([gameView hdrOutput])
8953 NSArray *brightnesses = [[UNIVERSE descriptions] oo_arrayForKey: @"hdr_maxBrightness_array"];
8954 int brightnessIdx = [brightnesses indexOfObject:[NSString stringWithFormat:@"%d", (int)[gameView hdrMaxBrightness]]];
8956 if (brightnessIdx == NSNotFound)
8958 OOLogWARN(
@"hdr.maxBrightness.notFound",
@"%@",
@"couldn't find current max brightness setting, switching to 400 nits.");
8962 int brightnessValue = [brightnesses oo_intAtIndex:brightnessIdx];
8963 NSString *maxBrightnessString =
OOExpandKey(
@"gameoptions-hdr-maxbrightness", brightnessValue);
8965 [gui
setText:maxBrightnessString
forRow:GUI_ROW(GAME,HDRMAXBRIGHTNESS)
align:GUI_ALIGN_CENTER];
8966 [gui
setKey:GUI_KEY_OK
forRow:GUI_ROW(GAME,HDRMAXBRIGHTNESS)];
8972 [gui
setText:DESC(@"gameoptions-autosave-yes")
forRow:GUI_ROW(GAME,AUTOSAVE)
align:GUI_ALIGN_CENTER];
8974 [gui
setText:DESC(@"gameoptions-autosave-no")
forRow:GUI_ROW(GAME,AUTOSAVE)
align:GUI_ALIGN_CENTER];
8978 if ([
OOSound respondsToSelector:@selector(masterVolume)] && [
OOSound isSoundOK])
8981 int vol = (volume / 5.0 + 0.5);
8982 NSString* soundVolumeWordDesc =
DESC(
@"gameoptions-sound-volume");
8984 [gui
setText:[NSString stringWithFormat:@"%@%@ ", soundVolumeWordDesc, SliderString(vol)]
forRow:GUI_ROW(GAME,VOLUME)
align:GUI_ALIGN_CENTER];
8986 [gui
setText:DESC(@"gameoptions-sound-volume-mute")
forRow:GUI_ROW(GAME,VOLUME)
align:GUI_ALIGN_CENTER];
8991 [gui
setText:DESC(@"gameoptions-volume-external-only")
forRow:GUI_ROW(GAME,VOLUME)
align:GUI_ALIGN_CENTER];
8997 float fov = [gameView
fov:NO];
8999 NSString* fovWordDesc =
DESC(
@"gameoptions-fov-value");
9000 [gui
setText:[NSString stringWithFormat:@"%@%@ (%d%c) ", fovWordDesc, SliderString(fovTicks), (int)fov, 176 ]
forRow:GUI_ROW(GAME,FOV)
align:GUI_ALIGN_CENTER];
9004 int colorblindMode = [UNIVERSE colorblindMode];
9005 NSString *colorblindModeDesc = [[[UNIVERSE descriptions] oo_arrayForKey: @"colorblind_mode"] oo_stringAtIndex:[UNIVERSE useShaders] ? colorblindMode : 0];
9006 NSString *colorblindModeMsg =
OOExpandKey(
@"gameoptions-colorblind-mode", colorblindModeDesc);
9007 [gui
setText:colorblindModeMsg
forRow:GUI_ROW(GAME,COLORBLINDMODE)
align:GUI_ALIGN_CENTER];
9010 [gui
setKey:GUI_KEY_OK
forRow:GUI_ROW(GAME,COLORBLINDMODE)];
9017#if OOLITE_SPEECH_SYNTH
9022 [gui
setText:DESC(@"gameoptions-spoken-messages-no")
forRow:GUI_ROW(GAME,SPEECH)
align:GUI_ALIGN_CENTER];
9025 [gui
setText:DESC(@"gameoptions-spoken-messages-comms")
forRow:GUI_ROW(GAME,SPEECH)
align:GUI_ALIGN_CENTER];
9028 [gui
setText:DESC(@"gameoptions-spoken-messages-yes")
forRow:GUI_ROW(GAME,SPEECH)
align:GUI_ALIGN_CENTER];
9035 NSString *voiceName = [UNIVERSE voiceName:voice_no];
9036 NSString *message =
OOExpandKey(
@"gameoptions-voice-name", voiceName);
9040 message = [NSString stringWithFormat:@"%@", DESC(voice_gender_m ? @"gameoptions-voice-M" : @"gameoptions-voice-F")];
9048 if([gameView inFullScreenMode])
9050 [gui
setText:DESC(@"gameoptions-play-in-window")
forRow:GUI_ROW(GAME,DISPLAYSTYLE)
align:GUI_ALIGN_CENTER];
9054 [gui
setText:DESC(@"gameoptions-play-in-fullscreen")
forRow:GUI_ROW(GAME,DISPLAYSTYLE)
align:GUI_ALIGN_CENTER];
9056 [gui
setKey: GUI_KEY_OK
forRow: GUI_ROW(GAME,DISPLAYSTYLE)];
9059 [gui
setText:DESC(@"gameoptions-joystick-configuration")
forRow: GUI_ROW(GAME,STICKMAPPER)
align: GUI_ALIGN_CENTER];
9062 [gui
setText:DESC(@"gameoptions-keyboard-configuration")
forRow: GUI_ROW(GAME,KEYMAPPER)
align: GUI_ALIGN_CENTER];
9063 [gui
setKey: GUI_KEY_OK
forRow: GUI_ROW(GAME,KEYMAPPER)];
9067 NSString *message =
OOExpandKey(
@"gameoptions-music-mode", musicMode);
9071 if (![gameView hdrOutput])
9074 [gui
setText:DESC(@"gameoptions-wireframe-graphics-yes")
forRow:GUI_ROW(GAME,WIREFRAMEGRAPHICS)
align:GUI_ALIGN_CENTER];
9076 [gui
setText:DESC(@"gameoptions-wireframe-graphics-no")
forRow:GUI_ROW(GAME,WIREFRAMEGRAPHICS)
align:GUI_ALIGN_CENTER];
9077 [gui
setKey:GUI_KEY_OK
forRow:GUI_ROW(GAME,WIREFRAMEGRAPHICS)];
9082 float paperWhite = [gameView hdrPaperWhiteBrightness];
9084 NSString* paperWhiteWordDesc =
DESC(
@"gameoptions-hdr-paperwhite");
9085 [gui
setText:[NSString stringWithFormat:@"%@%@ (%d) ", paperWhiteWordDesc, SliderString(paperWhiteTicks), (int)paperWhite]
forRow:GUI_ROW(GAME,HDRPAPERWHITE)
align:GUI_ALIGN_CENTER];
9086 [gui
setKey:GUI_KEY_OK
forRow:GUI_ROW(GAME,HDRPAPERWHITE)];
9091 if ([
UNIVERSE doProcedurallyTexturedPlanets])
9092 [gui
setText:DESC(@"gameoptions-procedurally-textured-planets-yes")
forRow:GUI_ROW(GAME,PROCEDURALLYTEXTUREDPLANETS)
align:GUI_ALIGN_CENTER];
9094 [gui
setText:DESC(@"gameoptions-procedurally-textured-planets-no")
forRow:GUI_ROW(GAME,PROCEDURALLYTEXTUREDPLANETS)
align:GUI_ALIGN_CENTER];
9095 [gui
setKey:GUI_KEY_OK
forRow:GUI_ROW(GAME,PROCEDURALLYTEXTUREDPLANETS)];
9099 NSString *shaderEffectsOptionsString =
OOExpand(
@"gameoptions-detaillevel-[detailLevel]", detailLevel);
9100 [gui
setText:OOExpandKey(shaderEffectsOptionsString)
forRow:GUI_ROW(GAME,SHADEREFFECTS)
align:GUI_ALIGN_CENTER];
9103 [gui
setKey:GUI_KEY_OK
forRow:GUI_ROW(GAME,SHADEREFFECTS)];
9112 if ([
UNIVERSE dockingClearanceProtocolActive])
9114 [gui
setText:DESC(@"gameoptions-docking-clearance-yes")
forRow:GUI_ROW(GAME,DOCKINGCLEARANCE)
align:GUI_ALIGN_CENTER];
9118 [gui
setText:DESC(@"gameoptions-docking-clearance-no")
forRow:GUI_ROW(GAME,DOCKINGCLEARANCE)
align:GUI_ALIGN_CENTER];
9126 [gui
setSelectableRange:NSMakeRange(first_sel_row, GUI_ROW_GAMEOPTIONS_END_OF_LIST)];
9135 [
self setShowDemoShips:NO];
9136 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
9140- (void) setGuiToLoadSaveScreen
9142 BOOL gamePaused = [[UNIVERSE gameController] isGamePaused];
9143 BOOL canLoadOrSave = NO;
9147 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
9149 gui_screen = GUI_SCREEN_OPTIONS;
9151 if ([
self status] == STATUS_DOCKED)
9153 if ([
self dockedStation] ==
nil) [
self setDockedAtMainStation];
9154 canLoadOrSave = (([
self dockedStation] == [UNIVERSE station] || [[
self dockedStation] allowsSaving]) && !([[
UNIVERSE sun] goneNova] || [[
UNIVERSE sun] willGoNova]));
9164 int first_sel_row = (canLoadOrSave)?
GUI_ROW(,SAVE) :
GUI_ROW(,GAMEOPTIONS);
9166 first_sel_row =
GUI_ROW(,QUICKSAVE);
9169 [gui
setTitle:[NSString stringWithFormat:DESC(@"status-commander-@"), [
self commanderName]]];
9171 [gui
setText:DESC(@"options-quick-save")
forRow:GUI_ROW(,QUICKSAVE)
align:GUI_ALIGN_CENTER];
9177 [gui
setText:DESC(@"options-save-commander")
forRow:GUI_ROW(,SAVE)
align:GUI_ALIGN_CENTER];
9178 [gui
setText:DESC(@"options-load-commander")
forRow:GUI_ROW(,LOAD)
align:GUI_ALIGN_CENTER];
9190 [gui
setText:DESC(@"options-return-to-menu")
forRow:GUI_ROW(,BEGIN_NEW)
align:GUI_ALIGN_CENTER];
9193 [gui
setText:DESC(@"options-game-options")
forRow:GUI_ROW(,GAMEOPTIONS)
align:GUI_ALIGN_CENTER];
9201 [gui
setText:DESC(@"options-exit-game")
forRow:GUI_ROW(,QUIT)
align:GUI_ALIGN_CENTER];
9207 if (gamePaused || (!canLoadOrSave && [
self status] == STATUS_DOCKED))
9218 if ([gui setForegroundTextureKey:[
self status] == STATUS_DOCKED ?
@"docked_overlay" :
@"paused_overlay"] && [
UNIVERSE pauseMessageVisible])
9225 [[UNIVERSE gameView] clearMouse];
9227 [
self setShowDemoShips:NO];
9229 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
9233 [[UNIVERSE messageGUI] clear];
9234 NSString *pauseKey = [PLAYER keyBindingDescription2:@"key_pausebutton"];
9235 [UNIVERSE addMessage:OOExpandKey(@"game-paused-docked", pauseKey) forCount:1.0 forceDisplay:YES];
9238 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen];
9245- (void) highlightEquipShipScreenKey:(NSString *)key
9249 NSString *otherKey =
@"";
9251 [last_outfitting_key release];
9273 if ([otherKey isEqualToString:key])
9280 if ([otherKey hasPrefix:
@"More:"])
9282 i = [[otherKey componentsSeparatedByString:@":"] oo_intAtIndex:1];
9297 unsigned available_facings = [shipyardInfo oo_unsignedIntForKey:KEY_WEAPON_FACINGS defaultValue:[
self weaponFacings]];
9303- (void) setGuiToEquipShipScreen:(
int)skipParam selectingFacingFor:(NSString *)eqKeyForSelectFacing
9305 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
9307 missiles = [
self countMissiles];
9309 NSString *showKey =
nil;
9315 searchStatus = STATUS_TEST;
9320 searchStatus = STATUS_ACTIVE;
9327 double priceFactor = 1.0;
9328 OOTechLevelID techlevel = [[UNIVERSE currentSystemData] oo_intForKey:KEY_TECHLEVEL];
9334 if ([dockedStation equivalentTechLevel] != NSNotFound)
9339 NSMutableArray *equipmentAllowed = [NSMutableArray array];
9344 NSMutableSet *options = [NSMutableSet setWithArray:[shipyardInfo oo_arrayForKey:KEY_OPTIONAL_EQUIPMENT]];
9347 [options addObjectsFromArray:[[shipyardInfo oo_dictionaryForKey:KEY_STANDARD_EQUIPMENT] oo_arrayForKey:KEY_EQUIPMENT_EXTRAS]];
9350 NSEnumerator *eqEnum =
nil;
9352 unsigned available_facings = [shipyardInfo oo_unsignedIntForKey:KEY_WEAPON_FACINGS defaultValue:[
self weaponFacings]];
9355 if (eqKeyForSelectFacing !=
nil)
9359 [equipmentAllowed addObject:eqKeyForSelectFacing];
9360 [equipmentAllowed addObject:eqKeyForSelectFacing];
9361 [equipmentAllowed addObject:eqKeyForSelectFacing];
9363 else for (eqEnum = [
OOEquipmentType equipmentEnumeratorOutfitting]; (eqType = [eqEnum nextObject]); i++)
9372 if ([eqType isAvailableToAll]) [options addObject:eqKey];
9375 if (minTechLevel != 0 && [
self hasEquipmentItem:[eqType damagedIdentifier]]) minTechLevel--;
9378 if (techlevel < minTechLevel && techlevel + 3 > minTechLevel)
9380 unsigned day = i * 13 + (unsigned)floor([
UNIVERSE getTime] / 86400.0);
9381 unsigned char dayRnd = (day & 0xff) ^ (
unsigned char)system_id;
9384 while (minTechLevel > 0 && minTechLevel > originalMinTechLevel - 3 && !(dayRnd & 7))
9386 dayRnd = dayRnd >> 2;
9392 if ([options containsObject:eqKey])
9395 [options removeObject:eqKey];
9400 if (techlevel < minTechLevel) isOK = NO;
9401 if (![
self canAddEquipment:eqKey inContext:
@"purchase"]) isOK = NO;
9402 if (available_facings == 0 && [eqType isPrimaryWeapon]) isOK = NO;
9403 if (isOK) [equipmentAllowed addObject:eqKey];
9406 if (searchStatus == STATUS_DEAD && isOK)
9409 searchStatus = STATUS_ACTIVE;
9411 if (searchStatus == STATUS_TEST)
9413 if (isOK) showKey = eqKey;
9415 searchStatus = isOK ? STATUS_ACTIVE : STATUS_DEAD;
9418 if (searchStatus != STATUS_TEST && showKey !=
nil)
9420 [last_outfitting_key release];
9429 unsigned facing_count = 0;
9430 BOOL displayRow = YES;
9431 BOOL weaponMounted = NO;
9432 BOOL guiChanged = (gui_screen != GUI_SCREEN_EQUIP_SHIP);
9434 gui_screen = GUI_SCREEN_EQUIP_SHIP;
9437 [gui
setTitle:DESC(@"equip-title")];
9440 [gui
setText:OOExpandKey(@"equip-cash-value", credits)
forRow:GUI_ROW_EQUIPMENT_CASH];
9444 tab_stops[1] = -360;
9445 tab_stops[2] = -480;
9450 NSUInteger
count = [equipmentAllowed count];
9458 if (
count <= n_rows || skip < n_rows)
9462 previous = skip - (n_rows - 2);
9467 if (eqKeyForSelectFacing !=
nil)
9471 [gui
setKey:[NSString stringWithFormat:@"More:%d:%@", previous, eqKeyForSelectFacing]
forRow:row];
9475 [gui
setKey:[NSString stringWithFormat:@"More:%d", previous]
forRow:row];
9478 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-back"), @"", @" <-- ", nil]
forRow:row];
9482 for (i = skip; i <
count && (row - start_row < (
OOGUIRow)n_rows); i++)
9484 NSString *eqKey = [equipmentAllowed oo_stringAtIndex:i];
9487 NSString *desc = [NSString stringWithFormat:@" %@ ", [eqInfo
name]];
9495 if ([eqKey isEqual:
@"EQ_FUEL"])
9499 else if ([eqKey isEqualToString:
@"EQ_RENOVATION"])
9501 price = [
self renovationCosts];
9506 price = pricePerUnit;
9509 price = [
self adjustPriceByScriptForEqKey:eqKey withCurrent:price];
9511 price *= priceFactor;
9514 if (installTime == 0)
9516 installTime = 600 + price;
9519 if ([
self hasEquipmentItem:eq_key_damaged])
9521 desc = [NSString stringWithFormat:DESC(@"equip-repair-@"), desc];
9524 if (installTime == 0)
9526 installTime = 600 + price;
9532 NSString *timeString = [UNIVERSE shortTimeDescription:installTime];
9533 NSString *priceString = [NSString stringWithFormat:@" %@ ", OOCredits(price)];
9535 if ([eqKeyForSelectFacing isEqualToString:eqKey])
9538 while (facing_count < 5)
9540 NSUInteger multiplier = 1;
9541 switch (facing_count)
9550 if (_multiplyWeapons)
9552 multiplier = [forwardWeaponOffset count];
9560 if (_multiplyWeapons)
9562 multiplier = [aftWeaponOffset count];
9570 if (_multiplyWeapons)
9572 multiplier = [portWeaponOffset count];
9580 if (_multiplyWeapons)
9582 multiplier = [starboardWeaponOffset count];
9598 priceString = [NSString stringWithFormat:@" %@ ", OOCredits(price*multiplier)];
9601 [gui
setArray:[NSArray arrayWithObjects:desc, (facing_count > 0 ? priceString : (NSString *)@""), timeString, nil]
forRow:row];
9612 if (![eqInfo hideValues])
9614 [gui
setArray:[NSArray arrayWithObjects:desc, priceString, timeString, nil]
forRow:row];
9629 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-more"), @"", @" --> ", nil]
forRow:row - 1];
9630 [gui
setKey:[NSString stringWithFormat:@"More:%d", i - 1]
forRow:row - 1];
9635 if ([gui selectedRow] != start_row)
9638 if (eqKeyForSelectFacing !=
nil)
9641 [
self showInformationForSelectedUpgradeWithFormatString:DESC(@"@-select-where-to-install")];
9645 [
self showInformationForSelectedUpgrade];
9650 [gui
setText:DESC(@"equip-no-equipment-available-for-purchase")
forRow:GUI_ROW_NO_SHIPS
align:GUI_ALIGN_CENTER];
9655 [
self showInformationForSelectedUpgrade];
9664 NSDictionary *background = [UNIVERSE screenTextureDescriptorForKey:@"equip_ship"];
9665 [
self setEquipScreenBackgroundDescriptor:background];
9668 else if (eqKeyForSelectFacing !=
nil)
9670 NSDictionary *bgDescriptor = [UNIVERSE screenTextureDescriptorForKey:@"mount_weapon"];
9682 [
self setShowDemoShips:NO];
9683 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
9687- (void) setGuiToEquipShipScreen:(
int)skip
9689 [
self setGuiToEquipShipScreen:skip selectingFacingFor:nil];
9693- (void) showInformationForSelectedUpgrade
9695 [
self showInformationForSelectedUpgradeWithFormatString:nil];
9699- (void) showInformationForSelectedUpgradeWithFormatString:(NSString *)formatString
9713 if (![eqKey hasPrefix:
@"More:"])
9716 NSString* eq_key_damaged = [NSString stringWithFormat:@"%@_DAMAGED", eqKey];
9718 if ([
self hasEquipmentItem:eq_key_damaged])
9720 desc = [NSString stringWithFormat:DESC(@"upgradeinfo-@-price-is-for-repairing"), desc];
9724 if([eqKey hasSuffix:
@"ENERGY_UNIT"] && ([
self hasEquipmentItem:
@"EQ_ENERGY_UNIT_DAMAGED"] || [
self hasEquipmentItem:
@"EQ_ENERGY_UNIT"] || [
self hasEquipmentItem:
@"EQ_NAVAL_ENERGY_UNIT_DAMAGED"]))
9725 desc = [NSString stringWithFormat:
DESC(
@"@-will-replace-other-energy"), desc];
9726 if (weight > 0) desc = [NSString stringWithFormat:DESC(@"upgradeinfo-@-weight-d-of-equipment"), desc, weight];
9728 if (formatString) desc = [NSString stringWithFormat:formatString, desc];
9735- (void) setGuiToInterfacesScreen:(
int)skip
9737 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
9738 if (gui_screen != GUI_SCREEN_INTERFACES)
9740 [
self noteGUIWillChangeTo:GUI_SCREEN_INTERFACES];
9744 NSDictionary *interfaces = [[
self dockedStation] localInterfaces];
9745 NSArray *interfaceKeys = [interfaces keysSortedByValueUsingSelector:@selector(interfaceCompare:)];
9755 BOOL guiChanged = (gui_screen != GUI_SCREEN_INTERFACES);
9758 [gui
setTitle:DESC(@"interfaces-title")];
9760 gui_screen = GUI_SCREEN_INTERFACES;
9764 tab_stops[1] = -480;
9769 NSUInteger
count = [interfaceKeys count];
9777 if (
count <= n_rows || skip < (NSInteger)n_rows)
9783 previous = skip - (n_rows - 2);
9790 [gui
setKey:[NSString stringWithFormat:@"More:%d", previous]
forRow:row];
9792 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-back"), @" <-- ", nil]
forRow:row];
9796 for (i = skip; i < (NSInteger)
count && (row - start_row < (
OOGUIRow)n_rows); i++)
9798 NSString *interfaceKey = [interfaceKeys objectAtIndex:i];
9808 if (i < (NSInteger)
count)
9812 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-more"), @" --> ", nil]
forRow:row - 1];
9813 [gui
setKey:[NSString stringWithFormat:@"More:%d", i - 1]
forRow:row - 1];
9818 if ([gui selectedRow] != start_row)
9823 [
self showInformationForSelectedInterface];
9827 [gui
setText:DESC(@"interfaces-no-interfaces-available-for-use")
forRow:GUI_ROW_NO_INTERFACES
align:GUI_ALIGN_LEFT];
9837 NSString *desc = [NSString stringWithFormat:DESC(@"interfaces-for-ship-@-and-station-@"), [
self displayName], [[
self dockedStation] displayName]];
9845 NSDictionary *background = [UNIVERSE screenTextureDescriptorForKey:@"interfaces"];
9851 [
self setShowDemoShips:NO];
9853 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen];
9855 [
self setShowDemoShips:NO];
9856 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
9861- (void) showInformationForSelectedInterface
9874 if (interfaceKey && ![interfaceKey hasPrefix:
@"More:"])
9876 NSDictionary *interfaces = [[
self dockedStation] localInterfaces];
9887- (void) activateSelectedInterface
9892 if ([key hasPrefix:
@"More:"])
9894 int from_item = [[key componentsSeparatedByString:@":"] oo_intAtIndex:1];
9895 [
self setGuiToInterfacesScreen:from_item];
9897 if ([gui selectedRow] < 0)
9900 [gui
setSelectedRow:GUI_ROW_INTERFACES_START + GUI_MAX_ROWS_INTERFACES - 1];
9901 [
self showInformationForSelectedInterface];
9907 NSDictionary *interfaces = [[
self dockedStation] localInterfaces];
9911 [[UNIVERSE gameView] clearKeys];
9916 OOLog(
@"interface.missingCallback",
@"Unable to find callback definition for key %@", key);
9921- (void) setupStartScreenGui
9924 NSString *text =
nil;
9926 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
9932 text =
DESC(
@"game-copyright");
9936 text =
DESC(
@"theme-music-credit");
9940 int initialRow = 22;
9941 int row = initialRow;
9943 text =
DESC(
@"oolite-start-option-1");
9946 [gui
setKey:[NSString stringWithFormat:@"Start:%d", row]
forRow:row];
9950 text =
DESC(
@"oolite-start-option-2");
9953 [gui
setKey:[NSString stringWithFormat:@"Start:%d", row]
forRow:row];
9957 text =
DESC(
@"oolite-start-option-3");
9960 [gui
setKey:[NSString stringWithFormat:@"Start:%d", row]
forRow:row];
9964 text =
DESC(
@"oolite-start-option-4");
9967 [gui
setKey:[NSString stringWithFormat:@"Start:%d", row]
forRow:row];
9971 text =
DESC(
@"oolite-start-option-5");
9974 [gui
setKey:[NSString stringWithFormat:@"Start:%d", row]
forRow:row];
9978 text =
DESC(
@"oolite-start-option-6");
9981 [gui
setKey:[NSString stringWithFormat:@"Start:%d", row]
forRow:row];
9995- (void) setGuiToIntroFirstGo:(BOOL)justCobra
9997 NSString *text =
nil;
10001 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:NO];
10002 [[UNIVERSE gameView] clearMouse];
10003 [[UNIVERSE gameView] clearKeys];
10008 [UNIVERSE removeDemoShips];
10014 [
self setupStartScreenGui];
10023 for (i-- ; i >= ms_start ; i--) [gui setColor:[OOColor redColor] forRow:i];
10029 if ([OXPsWithMessages
count] > 0)
10031 NSString *messageToDisplay =
@"";
10035 if ([OXPsWithMessages
count] < 5)
10037 NSString *messageSourceList = [OXPsWithMessages componentsJoinedByString:@", "];
10038 messageToDisplay =
OOExpandKey(
@"oxp-containing-messages-list", messageSourceList);
10040 messageToDisplay =
OOExpandKey(
@"oxp-containing-messages-found");
10045 for (i--; i >= ms_start; i--)
10053 NSArray* arguments = [[NSProcessInfo processInfo] arguments];
10055 for (i = 0; i < [arguments count]; i++)
10057 if (([[arguments objectAtIndex:i] isEqual:
@"-message"])&&(i < [arguments
count] - 1))
10060 NSString* message = [arguments oo_stringAtIndex:i + 1];
10062 for (i-- ; i >= ms_start; i--)
10067 if ([[arguments objectAtIndex:i] isEqual:
@"-showversion"])
10072 for (i-- ; i >= ms_start; i--)
10083 text =
DESC(
@"oolite-ship-library-title");
10086 text =
DESC(
@"oolite-ship-library-exit");
10093 [UNIVERSE setupIntroFirstGo: justCobra];
10097 gui_screen = justCobra ? GUI_SCREEN_INTRO1 : GUI_SCREEN_SHIPLIBRARY;
10099 if ([
self status] == STATUS_START_GAME)
10104 [
self setShowDemoShips:YES];
10113 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
10118- (void) setGuiToOXZManager
10121 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:NO];
10122 [[UNIVERSE gameView] clearMouse];
10123 [UNIVERSE removeDemoShips];
10125 gui_screen = GUI_SCREEN_OXZMANAGER;
10127 [[UNIVERSE gui] clearAndKeepBackground:NO];
10132 [[UNIVERSE gui] setBackgroundTextureKey:@"oxz-manager"];
10133 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
10150 [
self noteGUIDidChangeFrom: fromScreen to: toScreen refresh: NO];
10157 if (fromScreen != toScreen || refresh)
10160 switch (fromScreen)
10162 case GUI_SCREEN_SHIPYARD:
10163 case GUI_SCREEN_LOAD:
10164 case GUI_SCREEN_SAVE:
10165 [demoShip release];
10174 if (toScreen == GUI_SCREEN_SYSTEM_DATA)
10177 [[UNIVERSE sun] setSunColor:[
OOColor colorWithDescription:[[UNIVERSE systemManager] getProperty:@"sun_color" forSystem:info_system_id inGalaxy:[
self galaxyNumber]]]];
10182 [[UNIVERSE sun] setSunColor:[
OOColor colorWithDescription:[[UNIVERSE systemManager] getProperty:@"sun_color" forSystem:system_id inGalaxy:[
self galaxyNumber]]]];
10185 if (![[
UNIVERSE gameController] isGamePaused])
10197 [
self noteSwitchToView:toView fromView:fromView];
10201- (void) buySelectedItem
10206 if ([key hasPrefix:
@"More:"])
10208 int from_item = [[key componentsSeparatedByString:@":"] oo_intAtIndex:1];
10209 NSString *weaponKey = [[key componentsSeparatedByString:@":"] oo_stringAtIndex:2];
10211 [
self setGuiToEquipShipScreen:from_item];
10212 if (weaponKey !=
nil)
10214 [
self highlightEquipShipScreenKey:weaponKey];
10218 if ([gui selectedRow] < 0)
10220 if (from_item == 0)
10221 [gui
setSelectedRow:GUI_ROW_EQUIPMENT_START + GUI_MAX_ROWS_EQUIPMENT - 1];
10222 [
self showInformationForSelectedUpgrade];
10243 if ([
self tryBuyingItem:key])
10245 if (credits == old_credits)
10248 [
self playMenuNavigationDown];
10252 [
self playBuyCommodity];
10255 if(credits != old_credits || ![key hasPrefix:
@"EQ_WEAPON_"])
10259 NSUInteger adjust = 0;
10268 double time_adjust = (old_credits > credits) ? (old_credits - credits) : 0.0;
10269 [UNIVERSE forceWitchspaceEntries];
10272 ship_clock_adjust += time_adjust + 600.0;
10276 ship_clock_adjust += (double)adjust;
10279 [
self doScriptEvent:OOJSID("playerBoughtEquipment") withArguments:[NSArray arrayWithObjects:key, [NSNumber numberWithLongLong:(old_credits - credits)], nil]];
10280 if (gui_screen == GUI_SCREEN_EQUIP_SHIP)
10283 [
self setGuiToEquipShipScreen:0];
10285 [
self highlightEquipShipScreenKey:key];
10288 if ([
UNIVERSE autoSave]) [UNIVERSE setAutoSaveNow:YES];
10293 [
self playCantBuyCommodity];
10301 if (condition_script !=
nil)
10303 OOJSScript *condScript = [UNIVERSE getConditionScript:condition_script];
10304 if (condScript !=
nil)
10311 OK = JS_NewNumberValue(JScontext, price, &args[1]);
10315 OK = [condScript
callMethod:OOJSID("updateEquipmentPrice")
10323 OK = JS_ValueToInt32(JScontext, result, &newPrice);
10324 if (OK && newPrice >= 0)
10336- (BOOL) tryBuyingItem:(NSString *)eqKey
10342 double price = pricePerUnit;
10343 double priceFactor = 1.0;
10345 BOOL isRepair = NO;
10348 if ([
self hasEquipmentItem:eqKeyDamaged])
10354 if ([eqKey isEqualToString:
@"EQ_RENOVATION"])
10356 price = [
self renovationCosts];
10359 price = [
self adjustPriceByScriptForEqKey:eqKey withCurrent:price];
10367 price *= priceFactor;
10369 if (price > credits)
10374 if ([eqType isPrimaryWeapon])
10378 [
self setGuiToEquipShipScreen:0 selectingFacingFor:eqKey];
10385 NSUInteger multiplier = 1;
10387 switch (chosen_weapon_facing)
10390 current_weapon = forward_weapon_type;
10391 forward_weapon_type = chosen_weapon;
10392 if (_multiplyWeapons)
10394 multiplier = [forwardWeaponOffset count];
10399 current_weapon = aft_weapon_type;
10400 aft_weapon_type = chosen_weapon;
10401 if (_multiplyWeapons)
10403 multiplier = [aftWeaponOffset count];
10408 current_weapon = port_weapon_type;
10409 port_weapon_type = chosen_weapon;
10410 if (_multiplyWeapons)
10412 multiplier = [portWeaponOffset count];
10417 current_weapon = starboard_weapon_type;
10418 starboard_weapon_type = chosen_weapon;
10419 if (_multiplyWeapons)
10421 multiplier = [starboardWeaponOffset count];
10429 price *= multiplier;
10431 if (price > credits)
10436 switch (chosen_weapon_facing)
10439 forward_weapon_type = current_weapon;
10442 aft_weapon_type = current_weapon;
10445 port_weapon_type = current_weapon;
10448 starboard_weapon_type = current_weapon;
10458 if (current_weapon !=
nil)
10460 tradeIn = [UNIVERSE getEquipmentPriceForKey:OOEquipmentIdentifierFromWeaponType(current_weapon)] * multiplier;
10463 [
self doTradeIn:tradeIn forPriceFactor:priceFactor];
10465 [
self removeEquipmentItem:eqKeyDamaged];
10469 if ([eqType isMissileOrMine] && missiles >= max_missiles)
10471 OOLog(
@"equip.buy.mounted.failed.full",
@"%@",
@"rejecting missile because already full");
10484 if ([eqKey isEqualToString:
@"EQ_FUEL"])
10486#if MASS_DEPENDENT_FUEL_PRICES
10491 if (credits >= creditsForRefuel)
10493 credits -= creditsForRefuel;
10494 fuel = [
self fuelCapacity];
10506 switch ([
self energyUnitType])
10509 [
self removeEquipmentItem:@"EQ_NAVAL_ENERGY_UNIT"];
10510 tradeIn = [UNIVERSE getEquipmentPriceForKey:@"EQ_NAVAL_ENERGY_UNIT"] / 2;
10513 [
self removeEquipmentItem:@"EQ_NAVAL_ENERGY_UNIT_DAMAGED"];
10514 tradeIn = [UNIVERSE getEquipmentPriceForKey:@"EQ_NAVAL_ENERGY_UNIT"] / 4;
10517 [
self removeEquipmentItem:@"EQ_ENERGY_UNIT"];
10518 tradeIn = [UNIVERSE getEquipmentPriceForKey:@"EQ_ENERGY_UNIT"] * 3 / 4;
10521 [
self removeEquipmentItem:@"EQ_ENERGY_UNIT_DAMAGED"];
10522 tradeIn = [UNIVERSE getEquipmentPriceForKey:@"EQ_ENERGY_UNIT"] * 3 / 8;
10528 [
self doTradeIn:tradeIn forPriceFactor:priceFactor];
10532 if ([eqKey isEqualToString:
@"EQ_RENOVATION"])
10536 if (techLevel == NSNotFound) techLevel = [[UNIVERSE currentSystemData] oo_unsignedIntForKey:KEY_TECHLEVEL];
10539 ship_trade_in_factor += 5 + techLevel;
10540 if (ship_trade_in_factor > 100) ship_trade_in_factor = 100;
10542 [
self clearSubEntities];
10543 [
self setUpSubEntities];
10548 if ([eqKey hasSuffix:
@"MISSILE"] || [eqKey hasSuffix:
@"MINE"])
10550 ShipEntity* weapon = [[UNIVERSE newShipWithRole:eqKey] autorelease];
10554 BOOL mounted_okay = [
self mountMissile:weapon];
10558 [
self safeAllMissiles];
10559 [
self tidyMissilePylons];
10560 [
self setActiveMissile:0];
10562 return mounted_okay;
10565 if ([eqKey isEqualToString:
@"EQ_PASSENGER_BERTH"])
10567 [
self changePassengerBerths:+1];
10572 if ([eqKey isEqualToString:
@"EQ_PASSENGER_BERTH_REMOVAL"])
10574 [
self changePassengerBerths:-1];
10579 if ([eqKey isEqualToString:
@"EQ_MISSILE_REMOVAL"])
10582 tradeIn += [
self removeMissiles];
10583 [
self doTradeIn:tradeIn forPriceFactor:priceFactor];
10587 if ([
self canAddEquipment:eqKey inContext:
@"purchase"])
10590 [
self addEquipmentItem:eqKey withValidation:NO inContext:@"purchase"];
10593 [
self doScriptEvent:OOJSID("equipmentRepaired") withArgument:eqKey];
10602- (BOOL) setWeaponMount:(
OOWeaponFacing)facing toWeapon:(NSString *)eqKey
10604 return [
self setWeaponMount:facing toWeapon:eqKey inContext:@"purchase"];
10608- (BOOL) setWeaponMount:(
OOWeaponFacing)facing toWeapon:(NSString *)eqKey inContext:(NSString *) context
10612 unsigned available_facings = [shipyardInfo oo_unsignedIntForKey:KEY_WEAPON_FACINGS defaultValue:[
self weaponFacings]];
10615 if (!(available_facings & facing))
10621 if (![eqKey isEqualToString:
@"EQ_WEAPON_NONE"])
10623 if (![
self canAddEquipment:eqKey inContext:context])
10635 forward_weapon_type = chosen_weapon;
10639 aft_weapon_type = chosen_weapon;
10643 port_weapon_type = chosen_weapon;
10647 starboard_weapon_type = chosen_weapon;
10658- (BOOL) changePassengerBerths:(
int) addRemove
10660 if (addRemove == 0)
return NO;
10661 addRemove = (addRemove > 0) ? 1 : -1;
10665 if ((max_passengers < 1 && addRemove == -1) || ([
self maxAvailableCargoSpace] - current_cargo <
PASSENGER_BERTH_SPACE && addRemove == 1))
return NO;
10666 max_passengers += addRemove;
10674 [
self safeAllMissiles];
10677 for (i = 0; i < missiles; i++)
10679 NSString *weapon_key = [missile_list[i] identifier];
10681 if (weapon_key !=
nil)
10682 tradeIn += (
int)[
UNIVERSE getEquipmentPriceForKey:weapon_key];
10685 for (i = 0; i < max_missiles; i++)
10687 [missile_entity[i] release];
10688 missile_entity[i] =
nil;
10696- (void) doTradeIn:(
OOCreditsQuantity)tradeInValue forPriceFactor:(
double)priceFactor
10698 if (tradeInValue != 0)
10700 if (priceFactor < 1.0) tradeInValue *= priceFactor;
10701 credits += tradeInValue;
10710 if ([
self status] != STATUS_DOCKED)
10716 for (i = [cargo
count] - 1; i >= 0 ; i--)
10718 cargoItem = [cargo objectAtIndex:i];
10720 if ([co_type isEqualToString:type])
10722 amount += [cargoItem commodityAmount];
10733 OOMassUnit unit = [shipCommodityData massUnitForGood:type];
10734 if([
self specialCargo] && unit ==
UNITS_TONS)
return 0;
10738 BOOL inPods = ([
self status] != STATUS_DOCKED);
10741 if (unit ==
UNITS_TONS && (available + oldAmount) < amount)
10743 amount = available + oldAmount;
10751 if (safeAmount < amount) amount = (safeAmount < oldAmount) ? oldAmount : safeAmount;
10753 else if (unit ==
UNITS_GRAMS && amount > oldAmount)
10756 if (safeAmount < amount) amount = (safeAmount < oldAmount) ? oldAmount : safeAmount;
10761 if (amount > oldAmount)
10763 [
self loadCargoPodsForType:type amount:(amount - oldAmount)];
10767 [
self unloadCargoPodsForType:type amount:(oldAmount - amount)];
10772 [shipCommodityData setQuantity:amount forGood:type];
10775 [
self calculateCurrentCargo];
10776 return [shipCommodityData quantityForGood:type];
10780- (void) calculateCurrentCargo
10782 current_cargo = [
self cargoQuantityOnBoard];
10788 if ([
self specialCargo] !=
nil)
10790 return [
self maxAvailableCargoSpace];
10801 NSString *good =
nil;
10803 foreach (good, [shipCommodityData goods])
10807 OOMassUnit commodityUnits = [shipCommodityData massUnitForGood:good];
10819 cargoQtyOnBoard += quantity;
10821 cargoQtyOnBoard += [[
self cargo]
count];
10823 return cargoQtyOnBoard;
10830 if (station ==
nil)
10832 if ([[
self primaryTarget] isStation] && [(
StationEntity *)[
self primaryTarget] marketBroadcast])
10834 station = [
self primaryTarget];
10838 station = [UNIVERSE station];
10840 if (station ==
nil)
10847 if (localMarket ==
nil)
10852 return localMarket;
10856- (NSArray *) applyMarketFilter:(NSArray *)goods onMarket:(
OOCommodityMarket *)market
10862 NSMutableArray *filteredGoods = [NSMutableArray arrayWithCapacity:[goods count]];
10864 foreach (good, goods)
10866 switch (marketFilterMode)
10870 [filteredGoods addObject:good];
10873 if ([market quantityForGood:good] > 0 || [
self cargoQuantityForType:good] > 0)
10875 [filteredGoods addObject:good];
10879 if ([
self cargoQuantityForType:good] > 0)
10881 [filteredGoods addObject:good];
10885 if ([market quantityForGood:good] > 0)
10887 [filteredGoods addObject:good];
10891 if ([market exportLegalityForGood:good] == 0 && [market importLegalityForGood:good] == 0)
10893 [filteredGoods addObject:good];
10897 if ([market exportLegalityForGood:good] > 0 || [market importLegalityForGood:good] > 0)
10899 [filteredGoods addObject:good];
10904 return [[filteredGoods copy] autorelease];
10908- (NSArray *) applyMarketSorter:(NSArray *)goods onMarket:(
OOCommodityMarket *)market
10910 switch (marketSorterMode)
10913 return [goods sortedArrayUsingFunction:marketSorterByName context:market];
10915 return [goods sortedArrayUsingFunction:marketSorterByPrice context:market];
10917 return [goods sortedArrayUsingFunction:marketSorterByQuantity context:market];
10919 return [goods sortedArrayUsingFunction:marketSorterByQuantity context:shipCommodityData];
10921 return [goods sortedArrayUsingFunction:marketSorterByMassUnit context:market];
10935 tab_stops[1] = 137;
10936 tab_stops[2] = 187;
10937 tab_stops[3] = 267;
10938 tab_stops[4] = 321;
10939 tab_stops[5] = 431;
10944 [gui
setArray:[NSArray arrayWithObjects: DESC(@"commodity-column-title"), OOPadStringToEms(DESC(@"price-column-title"),3.5),
10945 OOPadStringToEms(DESC(@"for-sale-column-title"),3.75), OOPadStringToEms(DESC(@"in-hold-column-title"),5.75), DESC(@"oolite-legality-column-title"), DESC(@"oolite-extras-column-title"), nil]
forRow:GUI_ROW_MARKET_KEY];
10946 [gui
setArray:[NSArray arrayWithObjects: DESC(@"commodity-column-title"), DESC(@"oolite-extras-column-title"), OOPadStringToEms(DESC(@"price-column-title"),3.5),
10947 OOPadStringToEms(DESC(@"for-sale-column-title"),3.75), OOPadStringToEms(DESC(@"in-hold-column-title"),5.75), DESC(@"oolite-legality-column-title"), nil]
forRow:GUI_ROW_MARKET_KEY];
10955 NSString* desc = [NSString stringWithFormat:@" %@ ", [shipCommodityData nameForGood:good]];
10959 OOMassUnit unit = [shipCommodityData massUnitForGood:good];
10961 NSString *available =
OOPadStringToEms(((available_units > 0) ? (NSString *)[NSString stringWithFormat:
@"%d",available_units] :
DESC(
@"commodity-quantity-none")), 2.5);
10963 NSUInteger priceDecimal = pricePerUnit % 10;
10964 NSString *price = [NSString stringWithFormat:@" %@.%llu ",OOPadStringToEms([NSString stringWithFormat:@"%lu",(unsigned long)(pricePerUnit/10)],2.5),priceDecimal];
10968 NSString *owned =
OOPadStringToEms((units_in_hold > 0) ? (NSString *)[NSString stringWithFormat:
@"%d",units_in_hold] :
DESC(
@"commodity-quantity-none"), 4.5);
10970 NSString *units_available = [NSString stringWithFormat:@" %@ %@ ",available, units];
10971 NSString *units_owned = [NSString stringWithFormat:@" %@ %@ ",owned, units];
10975 NSString *legaldesc =
nil;
10976 if (import_legality == 0)
10978 if (export_legality == 0)
10980 legaldesc =
DESC(
@"oolite-legality-clear");
10984 legaldesc =
DESC(
@"oolite-legality-import");
10989 if (export_legality == 0)
10991 legaldesc =
DESC(
@"oolite-legality-export");
10995 legaldesc =
DESC(
@"oolite-legality-neither");
10998 legaldesc = [NSString stringWithFormat:@" %@ ",legaldesc];
11000 NSString *extradesc = [shipCommodityData shortCommentForGood:good];
11004 [gui
setArray:[NSArray arrayWithObjects: desc, extradesc, price, units_available, units_owned, legaldesc, nil]
forRow:row++];
11009- (NSString *)marketScreenTitle
11014 if (dockedStation ==
nil)
11016 if ([[
self primaryTarget] isStation] && [(
StationEntity *)[
self primaryTarget] marketBroadcast])
11018 dockedStation = [
self primaryTarget];
11022 NSString *system =
nil;
11023 if ([
UNIVERSE sun] !=
nil) system = [UNIVERSE getSystemName:system_id];
11025 if (dockedStation ==
nil || dockedStation == [
UNIVERSE station])
11029 return OOExpandKey(
@"system-commodity-market", system);
11040 return OOExpandKey(
@"station-commodity-market", station);
11045- (void) setGuiToMarketScreen
11051 gui_screen = GUI_SCREEN_MARKET;
11052 BOOL guiChanged = (oldScreen != gui_screen);
11055 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
11058 if (localMarket ==
nil)
11060 localMarket = [[UNIVERSE commodities] generateBlankMarket];
11064 NSArray *goods = [
self applyMarketSorter:[
self applyMarketFilter:[localMarket
goods] onMarket:localMarket] onMarket:localMarket];
11065 NSInteger maxOffset = 0;
11071 NSUInteger commodityCount = [shipCommodityData count];
11074 for (NSUInteger i = 0; i < commodityCount; i++)
11076 quantityInHold[i] = [shipCommodityData quantityForGood:[goods oo_stringAtIndex:i]];
11078 for (NSUInteger i = 0; i < [cargo count]; i++)
11080 ShipEntity *container = [cargo objectAtIndex:i];
11081 NSUInteger goodsIndex = [goods indexOfObject:[container
commodityType]];
11083 if (goodsIndex != NSNotFound)
11085 quantityInHold[goodsIndex] += [container commodityAmount];
11089 if (marketSelectedCommodity !=
nil && ([marketSelectedCommodity isEqualToString:
@"<<<"] || [marketSelectedCommodity isEqualToString:
@">>>"]))
11095 if (marketSelectedCommodity ==
nil || [goods indexOfObject:marketSelectedCommodity] == NSNotFound)
11097 DESTROY(marketSelectedCommodity);
11098 if ([goods
count] > 0)
11100 marketSelectedCommodity = [[goods oo_stringAtIndex:0] retain];
11105 NSInteger goodsIndex = [goods indexOfObject:marketSelectedCommodity];
11107 if (goodsIndex <= marketOffset)
11110 if (goodsIndex == 0) {
11113 marketOffset = goodsIndex-1;
11120 if (marketOffset > maxOffset)
11122 marketOffset = maxOffset;
11138 if (dockedStation ==
nil && [[
self primaryTarget] isStation] && [(
StationEntity *)[
self primaryTarget] marketBroadcast])
11140 dockedStation = [
self primaryTarget];
11143 [gui
setTitle:[
self marketScreenTitle]];
11145 [
self showMarketScreenHeaders];
11147 if (marketOffset > maxOffset)
11151 else if (marketOffset < 0)
11153 marketOffset = maxOffset;
11156 if ([goods
count] > 0)
11160 foreach (good, goods)
11162 if (i < marketOffset)
11167 [
self showMarketScreenDataLine:row forGood:good inMarket:localMarket holdQuantity:quantityInHold[i++]];
11168 if ([good isEqualToString:marketSelectedCommodity])
11180 if (marketOffset < maxOffset)
11182 if ([marketSelectedCommodity isEqualToString:
@">>>"])
11188 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-more"), @"", @"", @"", @" --> ", nil]
forRow:GUI_ROW_MARKET_LAST];
11190 if (marketOffset > 0)
11192 if ([marketSelectedCommodity isEqualToString:
@"<<<"])
11198 [gui
setArray:[NSArray arrayWithObjects:DESC(@"gui-back"), @"", @"", @"", @" <-- ", nil]
forRow:GUI_ROW_MARKET_START];
11205 [gui
setText:DESC(@"oolite-market-filtered-all")
forRow:GUI_ROW_MARKET_START];
11210 current_cargo = [
self cargoQuantityOnBoard];
11211 if (current_cargo > [
self maxAvailableCargoSpace]) current_cargo = [
self maxAvailableCargoSpace];
11215 NSString *filterMode =
OOExpandKey(
OOExpand(
@"oolite-market-filter-[marketFilterMode]", marketFilterMode));
11216 NSString *filterText =
OOExpandKey(
@"oolite-market-filter-line", filterMode);
11217 NSString *sortMode =
OOExpandKey(
OOExpand(
@"oolite-market-sorter-[marketSorterMode]", marketSorterMode));
11218 NSString *sorterText =
OOExpandKey(
@"oolite-market-sorter-line", sortMode);
11219 [gui
setArray:[NSArray arrayWithObjects:filterText, @"", sorterText, nil]
forRow:GUI_ROW_MARKET_END];
11223 [
self showMarketCashAndLoadLine];
11232 [[UNIVERSE gameView] clearMouse];
11234 [
self setShowDemoShips:NO];
11235 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
11241 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen];
11246- (void) setGuiToMarketInfoScreen
11252 gui_screen = GUI_SCREEN_MARKETINFO;
11253 BOOL guiChanged = (oldScreen != gui_screen);
11256 [[UNIVERSE gameController] setMouseInteractionModeForUIWithMouseInteraction:YES];
11259 if (localMarket ==
nil)
11261 localMarket = [[UNIVERSE commodities] generateBlankMarket];
11265 NSArray *goods = [
self applyMarketSorter:[
self applyMarketFilter:[localMarket
goods] onMarket:localMarket] onMarket:localMarket];
11267 NSUInteger i, j, commodityCount = [shipCommodityData count];
11270 for (i = 0; i < commodityCount; i++)
11272 quantityInHold[i] = [shipCommodityData quantityForGood:[goods oo_stringAtIndex:i]];
11274 for (i = 0; i < [cargo count]; i++)
11276 ShipEntity *container = [cargo objectAtIndex:i];
11278 quantityInHold[j] += [container commodityAmount];
11290 j = [goods indexOfObject:marketSelectedCommodity];
11292 if (j == NSNotFound)
11294 DESTROY(marketSelectedCommodity);
11295 [
self setGuiToMarketScreen];
11301 [gui
setTitle:[NSString stringWithFormat:DESC(@"oolite-commodity-information-@"), [shipCommodityData nameForGood:marketSelectedCommodity]]];
11303 [
self showMarketScreenHeaders];
11304 [
self showMarketScreenDataLine:GUI_ROW_MARKET_START forGood:marketSelectedCommodity inMarket:localMarket holdQuantity:quantityInHold[j]];
11306 OOCargoQuantity contracted = [
self contractedVolumeForGood:marketSelectedCommodity];
11307 if (contracted > 0)
11309 OOMassUnit unit = [shipCommodityData massUnitForGood:marketSelectedCommodity];
11311 [gui
setText:[NSString stringWithFormat:DESC(@"oolite-commodity-contracted-d-@"), contracted, DisplayStringForMassUnit(unit)]
forRow:GUI_ROW_MARKET_START+1];
11314 NSString *info = [shipCommodityData commentForGood:marketSelectedCommodity];
11316 if (info ==
nil || [info length] == 0)
11329 [
self showMarketCashAndLoadLine];
11333 [[UNIVERSE gameView] clearMouse];
11335 [
self setShowDemoShips:NO];
11336 [UNIVERSE enterGUIViewModeWithMouseInteraction:YES];
11342 [
self noteGUIDidChangeFrom:oldScreen to:gui_screen];
11351 [gui
setText:OOExpandKey(@"market-cash-and-load", credits, currentCargo, cargoCapacity)
forRow:GUI_ROW_MARKET_CASH];
11363 if ([index isEqualToString:
@"<<<"] || [index isEqualToString:
@">>>"])
11369 if (![
self isDocked])
return NO;
11379 int manifest_quantity = [shipCommodityData quantityForGood:index];
11386 int contracted = [
self contractedVolumeForGood:index];
11387 if (manifest_quantity >= contracted)
11393 purchase = contracted-manifest_quantity;
11396 if (purchase > market_quantity)
11398 purchase = market_quantity;
11400 if (purchase * pricePerUnit > credits)
11402 purchase = floor (credits / pricePerUnit);
11405 if (unit ==
UNITS_TONS && purchase + current_cargo > [
self maxAvailableCargoSpace])
11407 purchase = [
self availableCargoSpace];
11411 if (current_cargo == [
self maxAvailableCargoSpace])
11440 [shipCommodityData addQuantity:purchase forGood:index];
11441 credits -= pricePerUnit * purchase;
11443 [
self calculateCurrentCargo];
11445 if ([
UNIVERSE autoSave]) [UNIVERSE setAutoSaveNow:YES];
11447 [
self doScriptEvent:OOJSID("playerBoughtCargo") withArguments:[NSArray arrayWithObjects:index, [NSNumber numberWithInt:purchase], [NSNumber numberWithUnsignedLongLong:pricePerUnit], nil]];
11448 if ([localMarket exportLegalityForGood:index] > 0)
11450 [roleWeightFlags setObject:[NSNumber numberWithInt:1] forKey:@"bought-illegal"];
11454 [roleWeightFlags setObject:[NSNumber numberWithInt:1] forKey:@"bought-legal"];
11463 if ([index isEqualToString:
@"<<<"] || [index isEqualToString:
@">>>"])
11469 if (![
self isDocked])
return NO;
11472 int available_units = [shipCommodityData quantityForGood:index];
11475 if (available_units == 0)
return NO;
11484 int contracted = [
self contractedVolumeForGood:index];
11485 if (available_units <= contracted)
11491 sell = available_units-contracted;
11495 if (sell > available_units)
11496 sell = available_units;
11497 if (sell + market_quantity > capacity)
11498 sell = capacity - market_quantity;
11503 [shipCommodityData removeQuantity:sell forGood:index];
11504 credits += pricePerUnit * sell;
11506 [
self calculateCurrentCargo];
11508 if ([
UNIVERSE autoSave]) [UNIVERSE setAutoSaveNow:YES];
11510 [
self doScriptEvent:OOJSID("playerSoldCargo") withArguments:[NSArray arrayWithObjects:index, [NSNumber numberWithInt:sell], [NSNumber numberWithUnsignedLongLong: pricePerUnit], nil]];
11518 return using_mining_laser;
11528- (BOOL) canAddEquipment:(NSString *)equipmentKey inContext:(NSString *)context
11530 if ([equipmentKey isEqualToString:
@"EQ_RENOVATION"] && !(ship_trade_in_factor < 85 || [[[
self shipSubEntityEnumerator] allObjects]
count] < [
self maxShipSubEntities])) return NO;
11531 if (![super canAddEquipment:equipmentKey inContext:context]) return NO;
11534 if (conditions !=
nil && ![
self scriptTestConditions:conditions]) return NO;
11540- (BOOL) addEquipmentItem:(NSString *)equipmentKey inContext:(NSString *)context
11542 return [
self addEquipmentItem:equipmentKey withValidation:YES inContext:context];
11546- (BOOL) addEquipmentItem:(NSString *)equipmentKey withValidation:(BOOL)validateAddition inContext:(NSString *)context
11549 if ([equipmentKey isEqualToString:
@"EQ_TRUMBLE"])
11560 [
self addTrumble:trumble[ranrot_rand() % PLAYER_MAX_TRUMBLES]];
11566 BOOL OK = [
super addEquipmentItem:equipmentKey withValidation:validateAddition inContext:context];
11570 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_COMPASS"] && [
self compassMode] == COMPASS_MODE_BASIC)
11572 [
self setCompassMode:COMPASS_MODE_PLANET];
11575 [
self addEqScriptForKey:equipmentKey];
11576 [
self addEquipmentWithScriptToCustomKeyArray:equipmentKey];
11582- (NSMutableArray *) customEquipmentActivation
11584 return customEquipActivation;
11588- (void) addEquipmentWithScriptToCustomKeyArray:(NSString *)equipmentKey
11590 NSDictionary *item;
11594 for (i = 0; i < [eqScripts count]; i++)
11596 if ([[[eqScripts oo_arrayAtIndex:i] oo_stringAtIndex:0] isEqualToString:equipmentKey])
11599 for (j = 0; j < [customEquipActivation count]; j++) {
11600 item = [customEquipActivation objectAtIndex:j];
11606 NSMutableDictionary *customKey = [[NSMutableDictionary alloc] initWithObjectsAndKeys:equipmentKey, CUSTOMEQUIP_EQUIPKEY, [eq
name], CUSTOMEQUIP_EQUIPNAME, nil];
11611 if ((
object !=
nil && [
object count] > 0))
11612 [customKey setObject:object forKey:CUSTOMEQUIP_KEYACTIVATE];
11615 if ((
object !=
nil && [
object count] > 0))
11616 [customKey setObject:object forKey:CUSTOMEQUIP_KEYMODE];
11618 [customEquipActivation addObject:customKey];
11619 [customKey release];
11621 [customActivatePressed addObject:[NSNumber numberWithBool:NO]];
11622 [customModePressed addObject:[NSNumber numberWithBool:NO]];
11624 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
11625 [defaults setObject:customEquipActivation forKey:KEYCONFIG_CUSTOMEQUIP];
11632- (void) validateCustomEquipActivationArray
11636 NSString *equipmentKey;
11637 if ([customEquipActivation
count] == 0)
return;
11638 for (i = [customEquipActivation
count] - 1; i >= 0; i--) {
11639 equipmentKey = [[customEquipActivation objectAtIndex:i] oo_stringForKey:CUSTOMEQUIP_EQUIPKEY];
11642 [customEquipActivation removeObjectAtIndex:i];
11643 [customActivatePressed removeObjectAtIndex:i];
11644 [customModePressed removeObjectAtIndex:i];
11649 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
11650 [defaults setObject:customEquipActivation forKey:KEYCONFIG_CUSTOMEQUIP];
11655- (void) removeEquipmentItem:(NSString *)equipmentKey
11657 if(![
self hasEquipmentItemProviding:
@"EQ_ADVANCED_COMPASS"] && [
self compassMode] != COMPASS_MODE_BASIC)
11659 [
self setCompassMode:COMPASS_MODE_BASIC];
11661 [
super removeEquipmentItem:equipmentKey];
11662 if(![
self hasEquipmentItem:equipmentKey]) {
11664 [
self removeEqScriptForKey:equipmentKey];
11669- (void) addEquipmentFromCollection:(
id)equipment
11671 NSDictionary *dict =
nil;
11672 NSEnumerator *eqEnum =
nil;
11673 NSString *eqDesc =
nil;
11674 NSUInteger i,
count;
11677 if ([equipment isKindOfClass:[NSDictionary class]])
11680 eqEnum = [equipment keyEnumerator];
11682 else if ([equipment isKindOfClass:[NSArray class]] || [equipment isKindOfClass:[NSSet class]])
11684 eqEnum = [equipment objectEnumerator];
11686 else if ([equipment isKindOfClass:[NSString class]])
11688 eqEnum = [[NSArray arrayWithObject:equipment] objectEnumerator];
11695 while ((eqDesc = [eqEnum nextObject]))
11710 if ([eqDesc isEqualToString:
@"EQ_TRUMBLE"]) continue;
11713 if (dict !=
nil && ![dict oo_boolForKey:eqDesc]) continue;
11720 count = [dict oo_unsignedIntegerForKey:eqDesc];
11721 for (i=0;i<
count;i++)
11723 [
self addEquipmentItem:eqDesc withValidation:NO inContext:@"loading"];
11728 if ([equipment isKindOfClass:[NSDictionary class]])
11730 eqEnum = [equipment keyEnumerator];
11732 else if ([equipment isKindOfClass:[NSArray class]] || [equipment isKindOfClass:[NSSet class]])
11734 eqEnum = [equipment objectEnumerator];
11736 else if ([equipment isKindOfClass:[NSString class]])
11738 eqEnum = [[NSArray arrayWithObject:equipment] objectEnumerator];
11741 while ((eqDesc = [eqEnum nextObject]))
11743 if (![
self equipmentValidToAdd:eqDesc whileLoading:YES inContext:
@"loading"])
11745 [
self removeEquipmentItem:eqDesc];
11751- (BOOL) hasOneEquipmentItem:(NSString *)itemKey includeMissiles:(BOOL)includeMissiles
11754 if ([super hasOneEquipmentItem:itemKey includeMissiles:NO whileLoading:NO]) return YES;
11757 if (includeMissiles)
11760 for (i = 0; i < max_missiles; i++)
11762 if ([[
self missileForPylon:i] hasPrimaryRole:itemKey]) return YES;
11766 if ([itemKey isEqualToString:
@"EQ_TRUMBLE"])
11768 return [
self trumbleCount] > 0;
11777 if ([[forward_weapon_type identifier] isEqualToString:[weaponType identifier]] ||
11778 [[aft_weapon_type identifier] isEqualToString:[weaponType identifier]] ||
11779 [[port_weapon_type identifier] isEqualToString:[weaponType identifier]] ||
11780 [[starboard_weapon_type identifier] isEqualToString:[weaponType identifier]])
11785 return [
super hasPrimaryWeapon:weaponType];
11795 for (i = 0; i < max_missiles; i++)
11797 if ([[
self missileForPylon:i] hasPrimaryRole:identifier])
11799 [
self removeFromPylon:i];
11809- (BOOL) removeFromPylon:(NSUInteger)pylon
11811 if (pylon >= max_missiles)
return NO;
11813 if (missile_entity[pylon] !=
nil)
11815 NSString *identifier = [missile_entity[pylon] primaryRole];
11819 [missile_entity[pylon] release];
11820 missile_entity[pylon] =
nil;
11822 [
self tidyMissilePylons];
11825 if (pylon <= activeMissile)
11827 if (activeMissile == missiles && missiles > 0) activeMissile--;
11828 if (activeMissile > 0) activeMissile--;
11829 else activeMissile = max_missiles - 1;
11831 [
self selectNextMissile];
11841- (NSUInteger) parcelCount
11843 return [parcels count];
11847- (NSUInteger) passengerCount
11849 return [passengers count];
11853- (NSUInteger) passengerCapacity
11855 return max_passengers;
11859- (BOOL) hasHostileTarget
11861 ShipEntity *playersTarget = [
self primaryTarget];
11862 return ([playersTarget isShip] && [playersTarget hasHostileTarget] && [playersTarget primaryTarget] ==
self);
11866- (void) receiveCommsMessage:(NSString *) message_text from:(
ShipEntity *) other
11868 if ([
self status] == STATUS_DEAD || [
self status] == STATUS_DOCKED)
11873 [UNIVERSE addCommsMessage:[NSString stringWithFormat:@"%@:\n %@", [other
displayName], message_text] forCount:4.5];
11874 [
super receiveCommsMessage:message_text from:other];
11880 if (legalStatus == 0)
return;
11882 OOGovernmentID local_gov = [[UNIVERSE currentSystemData] oo_intForKey:KEY_GOVERNMENT];
11883 if ([
UNIVERSE inInterstellarSpace]) local_gov = 1;
11885 fine *= legalStatus;
11886 if (fine > credits)
11888 int payback = (
int)(legalStatus * credits / fine);
11889 [
self setBounty:(legalStatus-payback) withReason:kOOLegalStatusReasonPaidFine];
11894 [
self setBounty:0 withReason:kOOLegalStatusReasonPaidFine];
11899 NSString *fined_message = [NSString stringWithFormat:OOExpandKey(@"fined-@-credits"), OOCredits(fine)];
11900 [
self addMessageToReport:fined_message];
11901 [UNIVERSE forceWitchspaceEntries];
11902 ship_clock_adjust += 24 * 3600;
11906- (void) adjustTradeInFactorBy:(
int)value
11908 ship_trade_in_factor += value;
11909 if (ship_trade_in_factor < 75) ship_trade_in_factor = 75;
11910 if (ship_trade_in_factor > 100) ship_trade_in_factor = 100;
11914- (
int) tradeInFactor
11916 return ship_trade_in_factor;
11920- (double) renovationCosts
11923 OOCreditsQuantity shipValue = [UNIVERSE tradeInValueForCommanderDictionary:[
self commanderDataDictionary]];
11925 double costs = 0.005 * (100 - ship_trade_in_factor) * shipValue;
11926 costs += 0.01 * shipValue * [
self missingSubEntitiesAdjustment];
11927 costs *= [
self renovationFactor];
11932- (double) renovationFactor
11936 return [shipyardInfo oo_doubleForKey:KEY_RENOVATION_MULTIPLIER defaultValue:1.0];
11940- (void) setDefaultViewOffsets
11942 float halfLength = 0.5f * (boundingBox.max.z - boundingBox.min.z);
11943 float halfWidth = 0.5f * (boundingBox.max.x - boundingBox.min.
x);
11945 forwardViewOffset = make_vector(0.0f, 0.0f, boundingBox.max.z - halfLength);
11946 aftViewOffset = make_vector(0.0f, 0.0f, boundingBox.min.z + halfLength);
11947 portViewOffset = make_vector(boundingBox.min.x + halfWidth, 0.0f, 0.0f);
11948 starboardViewOffset = make_vector(boundingBox.max.x - halfWidth, 0.0f, 0.0f);
11953- (void) setDefaultCustomViews
11957 [_customViews release];
11958 _customViews =
nil;
11959 _customViewIndex = 0;
11960 if (customViews !=
nil)
11962 _customViews = [customViews retain];
11967- (Vector) weaponViewOffset
11969 switch (currentWeaponFacing)
11972 return forwardViewOffset;
11974 return aftViewOffset;
11976 return portViewOffset;
11978 return starboardViewOffset;
11982 return customViewOffset;
11988- (void) setUpTrumbles
11990 NSMutableString *trumbleDigrams = [NSMutableString stringWithCapacity:256];
11991 unichar xchar = (unichar)0;
11992 unichar digramchars[2];
11996 NSString *commanderName = [
self commanderName];
11997 if ([commanderName length] > 0)
11999 [trumbleDigrams appendFormat:@"%@%@", commanderName, [[
self mesh] modelName]];
12003 [trumbleDigrams appendString:@"Some Random Text!"];
12009 digramchars[0] = ([trumbleDigrams characterAtIndex:i] & 0x007f) | 0x0020;
12010 digramchars[1] = (([trumbleDigrams characterAtIndex:i + 1] ^ xchar) & 0x007f) | 0x0020;
12011 xchar = digramchars[0];
12012 NSString *digramstring = [NSString stringWithCharacters:digramchars length:2];
12013 [trumble[i] release];
12014 trumble[i] = [[
OOTrumble alloc] initForPlayer:self digram:digramstring];
12019 [
self setTrumbleAppetiteAccumulator:0.0f];
12023- (void) addTrumble:(
OOTrumble *)papaTrumble
12029 OOTrumble *trumblePup = trumble[trumbleCount];
12035- (void) removeTrumble:(
OOTrumble *)deadTrumble
12037 if (trumbleCount <= 0)
12041 NSUInteger trumble_index = NSNotFound;
12044 for (i = 0; (trumble_index == NSNotFound)&&(i < trumbleCount); i++)
12046 if (trumble[i] == deadTrumble)
12049 if (trumble_index == NSNotFound)
12051 OOLog(
@"trumble.zombie",
@"DEBUG can't get rid of inactive trumble %@", deadTrumble);
12055 trumble[trumble_index] = trumble[trumbleCount];
12056 trumble[trumbleCount] = deadTrumble;
12066- (NSUInteger) trumbleCount
12068 return trumbleCount;
12074 NSString *namekey = [NSString stringWithFormat:@"%@-humbletrash", [
self commanderName]];
12078 [
self mungChecksumWithNSString:[
self commanderName]];
12083 [[NSUserDefaults standardUserDefaults] setInteger:trumbleHash forKey:namekey];
12086 NSMutableArray *trumbleArray = [NSMutableArray arrayWithCapacity:PLAYER_MAX_TRUMBLES];
12089 [trumbleArray addObject:[trumble[i] dictionary]];
12092 return [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInteger:trumbleCount], [NSNumber numberWithInt:trumbleHash], trumbleArray, nil];
12096- (void) setTrumbleValueFrom:(NSObject*) trumbleValue
12098 BOOL info_failed = NO;
12100 int putativeHash = 0;
12101 int putativeNTrumbles = 0;
12102 NSArray *putativeTrumbleArray =
nil;
12104 NSString *namekey = [NSString stringWithFormat:@"%@-humbletrash", [
self commanderName]];
12106 [
self setUpTrumbles];
12110 BOOL possible_cheat = NO;
12111 if (![trumbleValue isKindOfClass:[NSArray class]])
12115 NSArray* values = (NSArray*) trumbleValue;
12116 if ([values
count] >= 1)
12117 putativeNTrumbles = [values oo_intAtIndex:0];
12118 if ([values
count] >= 2)
12119 putativeHash = [values oo_intAtIndex:1];
12120 if ([values
count] >= 3)
12121 putativeTrumbleArray = [values oo_arrayAtIndex:2];
12125 [
self mungChecksumWithNSString:[
self commanderName]];
12130 if (putativeHash != trumbleHash)
12135 OOLog(
@"cheat.tentative",
@"%@",
@"POSSIBLE CHEAT DETECTED");
12136 possible_cheat = YES;
12143 [
self mungChecksumWithNSString:[
self commanderName]];
12147 if (putativeHash == trumbleHash)
12150 putativeNTrumbles = i;
12154 if (possible_cheat && !info_failed)
12155 OOLog(
@"cheat.verified",
@"%@",
@"CHEAT DEFEATED - that's not the way to get rid of trumbles!");
12161 OOLog(
@"cheat.tentative",
@"%@",
@"POSSIBLE CHEAT DETECTED");
12165 if (info_failed && [[NSUserDefaults standardUserDefaults] objectForKey:namekey])
12168 putativeHash = (
int)[[NSUserDefaults standardUserDefaults] integerForKey:namekey];
12172 [
self mungChecksumWithNSString:[
self commanderName]];
12176 if (putativeHash == trumbleHash)
12179 putativeNTrumbles = i;
12184 OOLog(
@"cheat.verified",
@"%@",
@"CHEAT DEFEATED - that's not the way to get rid of trumbles!");
12187 trumbleCount = putativeNTrumbles;
12192 [trumble[i] setFromDictionary:[putativeTrumbleArray oo_dictionaryAtIndex:i]];
12196 [
self mungChecksumWithNSString:[
self commanderName]];
12201 [[NSUserDefaults standardUserDefaults] setInteger:trumbleHash forKey:namekey];
12205- (float) trumbleAppetiteAccumulator
12207 return _trumbleAppetiteAccumulator;
12211- (void) setTrumbleAppetiteAccumulator:(
float)value
12213 _trumbleAppetiteAccumulator = value;
12217- (void) mungChecksumWithNSString:(NSString *)str
12219 if (str ==
nil)
return;
12221 NSUInteger i, length = [str length];
12222 for (i = 0; i < length; i++)
12229- (NSString *) screenModeStringForWidth:(
unsigned)width height:(
unsigned)height refreshRate:(
float)refreshRate
12231 if (0.0f != refreshRate)
12233 return OOExpandKey(
@"gameoptions-fullscreen-with-refresh-rate", width, height, refreshRate);
12237 return OOExpandKey(
@"gameoptions-fullscreen", width, height);
12242- (void) suppressTargetLost
12244 suppressTargetLost = YES;
12248- (void) setScoopsActive
12250 scoopsActive = YES;
12255- (void) setFoundTarget:(
Entity *) targetEntity
12259 if ([
self status] == STATUS_ESCAPE_SEQUENCE)
12263 [_foundTarget release];
12269- (void) addTarget:(
Entity *) targetEntity
12271 if ([
self status] != STATUS_IN_FLIGHT && [
self status] != STATUS_WITCHSPACE_COUNTDOWN)
return;
12272 if (targetEntity ==
self)
return;
12274 [
super addTarget:targetEntity];
12276 if ([targetEntity isWormhole])
12278 assert ([
self hasEquipmentItemProviding:
@"EQ_WORMHOLE_SCANNER"]);
12279 [
self addScannedWormhole:(WormholeEntity*)targetEntity];
12282 else if ([
self hasEquipmentItemProviding:
@"EQ_TARGET_MEMORY"] && targetEntity !=
nil)
12285 NSUInteger i = [target_memory indexOfObject:targetRef];
12287 if (i != NSNotFound)
12289 target_memory_index = i;
12293 i = [target_memory indexOfObject:[NSNull null]];
12295 if (i != NSNotFound)
12297 [target_memory replaceObjectAtIndex:i withObject:targetRef];
12298 target_memory_index = i;
12304 [target_memory replaceObjectAtIndex:target_memory_index withObject:targetRef];
12311 [
self playIdentLockedOn];
12312 [
self printIdentLockedOnForMissile:NO];
12314 else if ([targetEntity isShip] && [
self weaponsOnline])
12316 if ([missile_entity[activeMissile] isMissile])
12319 [missile_entity[activeMissile] addTarget:targetEntity];
12320 [
self playMissileLockedOn];
12321 [
self printIdentLockedOnForMissile:YES];
12326 [
self playIdentLockedOn];
12327 [
self printIdentLockedOnForMissile:NO];
12333- (void) clearTargetMemory
12335 NSUInteger memoryCount = [target_memory count];
12338 if (i < memoryCount)
12340 [target_memory replaceObjectAtIndex:i withObject:[NSNull null]];
12344 [target_memory addObject:[NSNull null]];
12347 target_memory_index = 0;
12351- (NSMutableArray *) targetMemory
12353 return target_memory;
12356- (BOOL) moveTargetMemoryBy:(NSInteger)delta
12361 NSInteger idx = (NSInteger)target_memory_index + delta;
12364 target_memory_index = idx;
12366 id targ_id = [target_memory objectAtIndex:target_memory_index];
12367 if ([targ_id isProxy])
12371 if ((potential_target)&&(potential_target->
isShip)&&([potential_target isInSpace]))
12375 [
super addTarget:potential_target];
12378 if( [missile_entity[activeMissile] isMissile])
12380 [missile_entity[activeMissile] addTarget:potential_target];
12382 [
self printIdentLockedOnForMissile:YES];
12387 [
self playIdentLockedOn];
12388 [
self printIdentLockedOnForMissile:NO];
12393 ident_engaged = YES;
12394 [
self printIdentLockedOnForMissile:NO];
12396 [
self playTargetSwitched];
12402 [target_memory replaceObjectAtIndex:target_memory_index withObject:[NSNull null]];
12407 [
self playNoTargetInMemory];
12412- (void) printIdentLockedOnForMissile:(BOOL)missile
12414 if ([
self primaryTarget] ==
nil)
return;
12416 NSString *fmt = missile ?
@"missile-locked-onto-target" :
@"ident-locked-onto-target";
12417 NSString *target = [[
self primaryTarget] identFromShip:self];
12418 [UNIVERSE addMessage:OOExpandKey(fmt, target) forCount:4.5];
12422- (Quaternion) customViewQuaternion
12424 return customViewQuaternion;
12428- (void) setCustomViewQuaternion:(Quaternion)q
12430 customViewQuaternion = q;
12431 [
self setCustomViewData];
12435- (OOMatrix) customViewMatrix
12437 return customViewMatrix;
12441- (Vector) customViewOffset
12443 return customViewOffset;
12447- (void) setCustomViewOffset:(Vector) offset
12449 customViewOffset =
offset;
12453- (Vector) customViewRotationCenter
12455 return customViewRotationCenter;
12459- (void) setCustomViewRotationCenter:(Vector) center
12461 customViewRotationCenter = center;
12465- (void) customViewZoomIn:(
OOScalar) rate
12467 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12468 customViewOffset = vector_multiply_scalar(customViewOffset, 1.0/rate);
12469 OOScalar m = magnitude(customViewOffset);
12474 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12478- (void) customViewZoomOut:(
OOScalar) rate
12480 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12481 customViewOffset = vector_multiply_scalar(customViewOffset, rate);
12482 OOScalar m = magnitude(customViewOffset);
12487 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12491- (void) customViewRotateLeft:(
OOScalar) angle
12493 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12494 OOScalar m = magnitude(customViewOffset);
12496 [
self setCustomViewData];
12497 customViewOffset = vector_flip(customViewForwardVector);
12498 scale_vector(&customViewOffset, m / magnitude(customViewOffset));
12499 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12503- (void) customViewRotateRight:(
OOScalar) angle
12505 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12506 OOScalar m = magnitude(customViewOffset);
12508 [
self setCustomViewData];
12509 customViewOffset = vector_flip(customViewForwardVector);
12510 scale_vector(&customViewOffset, m / magnitude(customViewOffset));
12511 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12515- (void) customViewRotateUp:(
OOScalar) angle
12517 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12518 OOScalar m = magnitude(customViewOffset);
12520 [
self setCustomViewData];
12521 customViewOffset = vector_flip(customViewForwardVector);
12522 scale_vector(&customViewOffset, m / magnitude(customViewOffset));
12523 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12527- (void) customViewRotateDown:(
OOScalar) angle
12529 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12530 OOScalar m = magnitude(customViewOffset);
12532 [
self setCustomViewData];
12533 customViewOffset = vector_flip(customViewForwardVector);
12534 scale_vector(&customViewOffset, m / magnitude(customViewOffset));
12535 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12539- (void) customViewRollRight:(
OOScalar) angle
12541 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12542 OOScalar m = magnitude(customViewOffset);
12544 [
self setCustomViewData];
12545 customViewOffset = vector_flip(customViewForwardVector);
12546 scale_vector(&customViewOffset, m / magnitude(customViewOffset));
12547 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12551- (void) customViewRollLeft:(
OOScalar) angle
12553 customViewOffset = vector_subtract(customViewOffset, customViewRotationCenter);
12554 OOScalar m = magnitude(customViewOffset);
12556 [
self setCustomViewData];
12557 customViewOffset = vector_flip(customViewForwardVector);
12558 scale_vector(&customViewOffset, m / magnitude(customViewOffset));
12559 customViewOffset = vector_add(customViewOffset, customViewRotationCenter);
12563- (void) customViewPanUp:(
OOScalar) angle
12566 [
self setCustomViewData];
12567 customViewRotationCenter = vector_subtract(customViewOffset, vector_multiply_scalar(customViewForwardVector, dot_product(customViewOffset, customViewForwardVector)));
12571- (void) customViewPanDown:(
OOScalar) angle
12574 [
self setCustomViewData];
12575 customViewRotationCenter = vector_subtract(customViewOffset, vector_multiply_scalar(customViewForwardVector, dot_product(customViewOffset, customViewForwardVector)));
12579- (void) customViewPanLeft:(
OOScalar) angle
12582 [
self setCustomViewData];
12583 customViewRotationCenter = vector_subtract(customViewOffset, vector_multiply_scalar(customViewForwardVector, dot_product(customViewOffset, customViewForwardVector)));
12587- (void) customViewPanRight:(
OOScalar) angle
12590 [
self setCustomViewData];
12591 customViewRotationCenter = vector_subtract(customViewOffset, vector_multiply_scalar(customViewForwardVector, dot_product(customViewOffset, customViewForwardVector)));
12595- (Vector) customViewForwardVector
12597 return customViewForwardVector;
12601- (Vector) customViewUpVector
12603 return customViewUpVector;
12607- (Vector) customViewRightVector
12609 return customViewRightVector;
12613- (NSString *) customViewDescription
12615 return customViewDescription;
12619- (void) resetCustomView
12621 [
self setCustomViewDataFromDictionary:[_customViews oo_dictionaryAtIndex:_customViewIndex] withScaling:NO];
12625- (void) setCustomViewData
12631 Quaternion q1 = customViewQuaternion;
12636- (void) setCustomViewDataFromDictionary:(NSDictionary *)viewDict withScaling:(BOOL)withScaling
12640 if (viewDict ==
nil)
return;
12642 customViewQuaternion = [viewDict oo_quaternionForKey:@"view_orientation"];
12643 [
self setCustomViewData];
12648 customViewOffset = vector_multiply_scalar([viewDict oo_vectorForKey:
@"view_position"],_scaleFactor);
12653 customViewOffset = [viewDict oo_vectorForKey:@"view_position"];
12655 customViewRotationCenter = vector_subtract(customViewOffset, vector_multiply_scalar(customViewForwardVector, dot_product(customViewOffset, customViewForwardVector)));
12656 customViewDescription = [viewDict oo_stringForKey:@"view_description"];
12658 NSString *facing = [[viewDict oo_stringForKey:@"weapon_facing"] lowercaseString];
12659 if ([facing isEqual:
@"aft"])
12663 else if ([facing isEqual:
@"port"])
12667 else if ([facing isEqual:
@"starboard"])
12671 else if ([facing isEqual:
@"forward"])
12680- (BOOL) showInfoFlag
12682 return show_info_flag;
12686- (NSDictionary *) missionOverlayDescriptor
12688 return _missionOverlayDescriptor;
12692- (NSDictionary *) missionOverlayDescriptorOrDefault
12694 NSDictionary *result = [
self missionOverlayDescriptor];
12697 if ([[
self missionTitle] length] == 0)
12699 result = [UNIVERSE screenTextureDescriptorForKey:@"mission_overlay_no_title"];
12703 result = [UNIVERSE screenTextureDescriptorForKey:@"mission_overlay_with_title"];
12711- (void) setMissionOverlayDescriptor:(NSDictionary *)descriptor
12713 if (descriptor != _missionOverlayDescriptor)
12715 [_missionOverlayDescriptor autorelease];
12716 _missionOverlayDescriptor = [descriptor copy];
12721- (NSDictionary *) missionBackgroundDescriptor
12723 return _missionBackgroundDescriptor;
12727- (NSDictionary *) missionBackgroundDescriptorOrDefault
12729 NSDictionary *result = [
self missionBackgroundDescriptor];
12732 result = [UNIVERSE screenTextureDescriptorForKey:@"mission"];
12739- (void) setMissionBackgroundDescriptor:(NSDictionary *)descriptor
12741 if (descriptor != _missionBackgroundDescriptor)
12743 [_missionBackgroundDescriptor autorelease];
12744 _missionBackgroundDescriptor = [descriptor copy];
12751 return _missionBackgroundSpecial;
12755- (void) setMissionBackgroundSpecial:(NSString *)special
12757 if (special ==
nil) {
12760 else if ([special isEqualToString:
@"SHORT_RANGE_CHART"])
12764 else if ([special isEqualToString:
@"SHORT_RANGE_CHART_SHORTEST"])
12766 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_NAVIGATIONAL_ARRAY"])
12775 else if ([special isEqualToString:
@"SHORT_RANGE_CHART_QUICKEST"])
12777 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_NAVIGATIONAL_ARRAY"])
12786 else if ([special isEqualToString:
@"CUSTOM_CHART"])
12790 else if ([special isEqualToString:
@"CUSTOM_CHART_SHORTEST"])
12792 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_NAVIGATIONAL_ARRAY"])
12801 else if ([special isEqualToString:
@"CUSTOM_CHART_QUICKEST"])
12803 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_NAVIGATIONAL_ARRAY"])
12812 else if ([special isEqualToString:
@"LONG_RANGE_CHART"])
12816 else if ([special isEqualToString:
@"LONG_RANGE_CHART_SHORTEST"])
12818 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_NAVIGATIONAL_ARRAY"])
12827 else if ([special isEqualToString:
@"LONG_RANGE_CHART_QUICKEST"])
12829 if ([
self hasEquipmentItemProviding:
@"EQ_ADVANCED_NAVIGATIONAL_ARRAY"])
12847 _missionExitScreen = screen;
12853 return _missionExitScreen;
12857- (NSDictionary *) equipScreenBackgroundDescriptor
12859 return _equipScreenBackgroundDescriptor;
12863- (void) setEquipScreenBackgroundDescriptor:(NSDictionary *)descriptor
12865 if (descriptor != _equipScreenBackgroundDescriptor)
12867 [_equipScreenBackgroundDescriptor autorelease];
12868 _equipScreenBackgroundDescriptor = [descriptor copy];
12873- (BOOL) scriptsLoaded
12875 return worldScripts !=
nil && [worldScripts count] > 0;
12879- (NSArray *) worldScriptNames
12881 return [worldScripts allKeys];
12885- (NSDictionary *) worldScriptsByName
12887 return [[worldScripts copy] autorelease];
12891- (
OOScript *) commodityScriptNamed:(NSString *)scriptName
12893 if (scriptName ==
nil)
12898 if ((cscript = [commodityScripts objectForKey:scriptName]))
12903 if (cscript !=
nil)
12906 [commodityScripts setObject:cscript forKey:scriptName];
12910 OOLog(
@"script.commodityScript.load",
@"Could not load script %@",scriptName);
12916- (void) doScriptEvent:(jsid)message inContext:(JSContext *)context withArguments:(jsval *)argv count:(uintN)argc
12918 [
super doScriptEvent:message inContext:context withArguments:argv count:argc];
12919 [
self doWorldScriptEvent:message inContext:context withArguments:argv count:argc timeLimit:0.0];
12923- (BOOL) doWorldEventUntilMissionScreen:(jsid)message
12925 NSEnumerator *scriptEnum = [worldScripts objectEnumerator];
12929 if (gui_screen != GUI_SCREEN_MISSION && [dockingReport length] > 0 && [
self isDocked] && ![[
self dockedStation] suppressArrivalReports])
12931 [
self setGuiToDockingReportScreen];
12932 [[UNIVERSE messageGUI] clear];
12937 while ((theScript = [scriptEnum nextObject]) && gui_screen != GUI_SCREEN_MISSION && [
self isDocked])
12943 if (gui_screen == GUI_SCREEN_MISSION)
12946 [[UNIVERSE messageGUI] clear];
12954- (void) doWorldScriptEvent:(jsid)message inContext:(JSContext *)context withArguments:(jsval *)argv count:(uintN)argc timeLimit:(
OOTimeDelta)limit
12960 foreach (theScript, [worldScripts allValues])
12973 galacticHyperspaceBehaviour = inBehaviour;
12980 return galacticHyperspaceBehaviour;
12984- (void) setGalacticHyperspaceFixedCoords:(NSPoint)point
12986 return [
self setGalacticHyperspaceFixedCoordsX:OOClamp_0_max_f(round(point.x), 255.0f) y:OOClamp_0_max_f(round(point.y), 255.0f)];
12990- (void) setGalacticHyperspaceFixedCoordsX:(
unsigned char)x y:(
unsigned char)y
12992 galacticHyperspaceFixedCoords.x =
x;
12993 galacticHyperspaceFixedCoords.y =
y;
12997- (NSPoint) galacticHyperspaceFixedCoords
12999 return galacticHyperspaceFixedCoords;
13003- (void) setWitchspaceCountdown:(
int)spin_time
13005 witchspaceCountdown = spin_time;
13010 return longRangeChartMode;
13016 longRangeChartMode =
mode;
13020- (BOOL) scoopOverride
13022 return scoopOverride;
13026- (void) setScoopOverride:(BOOL)newValue
13028 scoopOverride = !!newValue;
13029 if (scoopOverride) [
self setScoopsActive];
13033#if MASS_DEPENDENT_FUEL_PRICES
13034- (GLfloat) fuelChargeRate
13036 GLfloat rate = 1.0;
13038 rate = [
super fuelChargeRate];
13041 if (
EXPECT(ship_trade_in_factor <= 90 && ship_trade_in_factor >= 75))
13043 rate *= 2.0 - (ship_trade_in_factor / 100);
13054if ([entity isStation]) _dockTarget = [entity
universalID];
13060- (NSString *) jumpCause
13066- (void) setJumpCause:(NSString *)value
13068 NSParameterAssert(value !=
nil);
13069 [_jumpCause autorelease];
13070 _jumpCause = [value copy];
13074- (NSString *) commanderName
13076 return _commanderName;
13080- (NSString *) lastsaveName
13082 return _lastsaveName;
13086- (void) setCommanderName:(NSString *)value
13088 NSParameterAssert(value !=
nil);
13089 [_commanderName autorelease];
13090 _commanderName = [value copy];
13094- (void) setLastsaveName:(NSString *)value
13096 NSParameterAssert(value !=
nil);
13097 [_lastsaveName autorelease];
13098 _lastsaveName = [value copy];
13104 BOOL isDockedStatus = NO;
13106 switch ([
self status])
13108 case STATUS_DOCKED:
13109 case STATUS_DOCKING:
13110 case STATUS_START_GAME:
13111 isDockedStatus = YES;
13114 case STATUS_RESTART_GAME:
13116 case STATUS_EFFECT:
13117 case STATUS_ACTIVE:
13118 case STATUS_COCKPIT_DISPLAY:
13120 case STATUS_INACTIVE:
13122 case STATUS_IN_FLIGHT:
13123 case STATUS_AUTOPILOT_ENGAGED:
13124 case STATUS_LAUNCHING:
13125 case STATUS_WITCHSPACE_COUNTDOWN:
13126 case STATUS_ENTERING_WITCHSPACE:
13127 case STATUS_EXITING_WITCHSPACE:
13128 case STATUS_ESCAPE_SEQUENCE:
13129 case STATUS_IN_HOLD:
13130 case STATUS_BEING_SCOOPED:
13131 case STATUS_HANDLING_ERROR:
13138 if (isDockedStatus)
13140 if ([
self dockedStation] ==
nil)
13144 [
self setStatus:STATUS_IN_FLIGHT];
13145 isDockedStatus = NO;
13150 if ([
self dockedStation] !=
nil && [
self status] != STATUS_LAUNCHING)
13153 [
self setStatus:STATUS_DOCKED];
13154 isDockedStatus = YES;
13159 return isDockedStatus;
13163- (BOOL)clearedToDock
13171 dockingClearanceStatus = newValue;
13174 targetDockStation =
nil;
13178 if ([[
self primaryTarget] isStation])
13180 targetDockStation = [
self primaryTarget];
13184 OOLog(
@"player.badDockingTarget",
@"Attempt to dock at %@.", [
self primaryTarget]);
13185 targetDockStation =
nil;
13193 return dockingClearanceStatus;
13197- (void)penaltyForUnauthorizedDocking
13203 if ([
self clearedToDock])
13206 amountToPay =
MIN(maximumFine, calculatedFine);
13207 credits -= amountToPay;
13208 [
self addMessageToReport:[NSString stringWithFormat:DESC(@"station-docking-clearance-fined-@-cr"), OOCredits(amountToPay)]];
13217 assert(scannedWormholes !=
nil);
13218 assert(whole !=
nil);
13222 foreach (wh, scannedWormholes)
13224 if (wh == whole)
return;
13227 [scannedWormholes addObject:whole];
13235 assert(scannedWormholes !=
nil);
13237 if ([scannedWormholes
count] == 0)
13240 double now = [
self clockTimeAdjusted];
13242 NSMutableArray * savedWormholes = [[NSMutableArray alloc] initWithCapacity:[scannedWormholes count]];
13245 foreach (wh, scannedWormholes)
13249 if ([wh arrivalTime] > now)
13251 [savedWormholes addObject:wh];
13253 else if (NSEqualPoints(galaxy_coordinates, [wh destinationCoordinates]))
13256 if ([[wh shipsInTransit]
count] > 0)
13258 [savedWormholes addObject:wh];
13264 [scannedWormholes release];
13265 scannedWormholes = savedWormholes;
13269- (NSArray *) scannedWormholes
13271 return [NSArray arrayWithArray:scannedWormholes];
13275- (void) initialiseMissionDestinations:(NSDictionary *)destinations andLegacy:(NSArray *)legacy
13277 NSString *key =
nil;
13282 [missionDestinations release];
13283 missionDestinations = [[NSMutableDictionary alloc] init];
13287 value = [destinations objectForKey:key];
13290 if ([value isKindOfClass:[NSDictionary class]])
13292 value = [value mutableCopy];
13293 [missionDestinations setObject:value forKey:key];
13302 NSNumber *legacyMarker;
13303 foreach (legacyMarker, legacy)
13305 dest = [legacyMarker intValue];
13306 [
self addMissionDestinationMarker:[
self defaultMarker:dest]];
13313- (NSString *)markerKey:(NSDictionary *)marker
13315 return [NSString stringWithFormat:@"%d-%@",[marker oo_intForKey:@"system"], [marker oo_stringForKey:@"name"]];
13319- (void) addMissionDestinationMarker:(NSDictionary *)marker
13321 NSDictionary *validated = [
self validatedMarker:marker];
13322 if (validated ==
nil)
13327 [missionDestinations setObject:validated forKey:[
self markerKey:validated]];
13331- (BOOL) removeMissionDestinationMarker:(NSDictionary *)marker
13333 NSDictionary *validated = [
self validatedMarker:marker];
13334 if (validated ==
nil)
13339 if ([missionDestinations objectForKey:[
self markerKey:validated]] !=
nil) {
13342 [missionDestinations removeObjectForKey:[
self markerKey:validated]];
13347- (NSMutableDictionary*) getMissionDestinations
13349 return missionDestinations;
13353- (NSMutableDictionary*) shipyardRecord
13355 return shipyard_record;
13359- (void) setLastShot:(NSArray *)shot
13361 lastShot = [shot retain];
13365- (void) clearExtraMissionKeys
13367 [extraMissionKeys release];
13368 extraMissionKeys =
nil;
13372- (void) setExtraMissionKeys:(NSDictionary *)keys
13374 NSString *key =
nil;
13375 NSMutableDictionary *
final = [[NSMutableDictionary alloc] init];
13376 foreach (key, [keys allKeys])
13378 [final setObject:[
self processKeyCode:[keys oo_arrayForKey:key]] forKey:key];
13380 extraMissionKeys = [final copy];
13385- (void) clearExtraGuiScreenKeys:(
OOGUIScreenID)gui key:(NSString *)key
13387 NSMutableArray *keydefs = [extraGuiScreenKeys objectForKey:[NSString stringWithFormat:@"%d",gui]];
13388 NSInteger i = [keydefs count];
13389 NSDictionary *def =
nil;
13392 def = [keydefs objectAtIndex:i];
13393 if (def && [[def oo_stringForKey:
@"name"] isEqualToString:key])
13395 [keydefs removeObjectAtIndex:i];
13407 NSMutableArray *newarray =
nil;
13408 NSString *key =
nil;
13409 NSMutableDictionary *
final = [[NSMutableDictionary alloc] init];
13411 NSMutableArray *checklist = [[NSMutableArray alloc] init];
13413 foreach (key, [keys allKeys])
13415 NSArray *item = [
self processKeyCode:[keys oo_arrayForKey:key]];
13416 [checklist addObject:item];
13417 [final setObject:item forKey:key];
13423 if (!extraGuiScreenKeys)
13425 extraGuiScreenKeys = [[NSMutableDictionary alloc] init];
13428 if (![extraGuiScreenKeys objectForKey:[NSString stringWithFormat:
@"%d",gui]])
13431 newarray = [[NSMutableArray alloc] init];
13435 newarray = [[extraGuiScreenKeys objectForKey:[NSString stringWithFormat:@"%d",gui]] mutableCopy];
13436 NSInteger i = [newarray count];
13441 def_existing = [newarray objectAtIndex:i];
13443 if (def_existing && [[def_existing name] isEqualToString:[definition name]])
13445 [newarray removeObjectAtIndex:i];
13452 foreach (key, [keydefs allKeys])
13454 j = [checklist count];
13457 if ([[NSString stringWithFormat:
@"%@",[keydefs objectForKey:key]] isEqualToString:[NSString stringWithFormat:
@"%@",[checklist objectAtIndex:j]]])
13460 OOLog(
kOOLogException,
@"***** Exception in setExtraGuiScreenKeys: %@ : %@ (%@)",
@"invalid key settings",
@"key already in use", key);
13467 [newarray addObject:definition];
13469 if (result) [extraGuiScreenKeys setObject:[newarray mutableCopy] forKey:[NSString stringWithFormat:@"%d",gui]];
13470 [newarray release];
13476- (void)dumpSelfState
13478 NSMutableArray *flags =
nil;
13479 NSString *flagsString =
nil;
13481 [
super dumpSelfState];
13483 OOLog(
@"dumpState.playerEntity",
@"Script time: %g", script_time);
13484 OOLog(
@"dumpState.playerEntity",
@"Script time check: %g", script_time_check);
13485 OOLog(
@"dumpState.playerEntity",
@"Script time interval: %g", script_time_interval);
13486 OOLog(
@"dumpState.playerEntity",
@"Roll/pitch/yaw delta: %g, %g, %g", roll_delta, pitch_delta, yaw_delta);
13487 OOLog(
@"dumpState.playerEntity",
@"Shield: %g fore, %g aft", forward_shield, aft_shield);
13488 OOLog(
@"dumpState.playerEntity",
@"Alert level: %u, flags: %#x", alertFlags, alertCondition);
13489 OOLog(
@"dumpState.playerEntity",
@"Missile status: %i", missile_status);
13491 OOLog(
@"dumpState.playerEntity",
@"Fuel leak rate: %g", fuel_leak_rate);
13492 OOLog(
@"dumpState.playerEntity",
@"Trumble count: %llu", trumbleCount);
13494 flags = [NSMutableArray array];
13495 #define ADD_FLAG_IF_SET(x) if (x) { [flags addObject:@#x]; }
13524 flagsString = [flags count] ? [flags componentsJoinedByString:@", "] : (NSString *)
@"none";
13525 OOLog(
@"dumpState.playerEntity",
@"Flags: %@", flagsString);
13536- (BOOL) suppressClangStuff
13538 return missionChoice &&
13539 commanderNameString &&
13543 n_key_roll_right &&
13544 n_key_pitch_forward &&
13545 n_key_pitch_back &&
13548 n_key_view_forward &&
13551 n_key_view_starboard &&
13552 n_key_launch_ship &&
13553 n_key_gui_screen_options &&
13554 n_key_gui_screen_equipship &&
13555 n_key_gui_screen_interfaces &&
13556 n_key_gui_screen_status &&
13557 n_key_gui_chart_screens &&
13558 n_key_gui_system_data &&
13559 n_key_gui_market &&
13560 n_key_gui_arrow_left &&
13561 n_key_gui_arrow_right &&
13562 n_key_gui_arrow_up &&
13563 n_key_gui_arrow_down &&
13564 n_key_gui_page_up &&
13565 n_key_gui_page_down &&
13566 n_key_gui_select &&
13567 n_key_increase_speed &&
13568 n_key_decrease_speed &&
13569 n_key_inject_fuel &&
13570 n_key_fire_lasers &&
13571 n_key_launch_missile &&
13572 n_key_next_missile &&
13574 n_key_prime_next_equipment &&
13575 n_key_prime_previous_equipment &&
13576 n_key_activate_equipment &&
13577 n_key_mode_equipment &&
13578 n_key_fastactivate_equipment_a &&
13579 n_key_fastactivate_equipment_b &&
13580 n_key_target_missile &&
13581 n_key_untarget_missile &&
13582 n_key_target_incoming_missile &&
13583 n_key_ident_system &&
13584 n_key_scanner_zoom &&
13585 n_key_scanner_unzoom &&
13586 n_key_launch_escapepod &&
13587 n_key_galactic_hyperspace &&
13588 n_key_hyperspace &&
13590 n_key_dump_cargo &&
13591 n_key_rotate_cargo &&
13595 n_key_docking_music &&
13596 n_key_advanced_nav_array_next &&
13597 n_key_advanced_nav_array_previous &&
13598 n_key_info_next_system &&
13599 n_key_info_previous_system &&
13602 n_key_map_next_system &&
13603 n_key_map_previous_system &&
13605 n_key_map_zoom_in &&
13606 n_key_map_zoom_out &&
13607 n_key_system_home &&
13608 n_key_system_end &&
13609 n_key_system_next_system &&
13610 n_key_system_previous_system &&
13611 n_key_pausebutton &&
13613 n_key_bloom_toggle &&
13614 n_key_mouse_control_roll &&
13615 n_key_mouse_control_yaw &&
13616 n_key_hud_toggle &&
13618 n_key_prev_compass_mode &&
13619 n_key_next_compass_mode &&
13620 n_key_chart_highlight &&
13621 n_key_market_filter_cycle &&
13622 n_key_market_sorter_cycle &&
13623 n_key_market_buy_one &&
13624 n_key_market_sell_one &&
13625 n_key_market_buy_max &&
13626 n_key_market_sell_max &&
13627 n_key_next_target &&
13628 n_key_previous_target &&
13629 n_key_custom_view &&
13630 n_key_custom_view_zoom_out &&
13631 n_key_custom_view_zoom_in &&
13632 n_key_custom_view_roll_left &&
13633 n_key_custom_view_pan_left &&
13634 n_key_custom_view_roll_right &&
13635 n_key_custom_view_pan_right &&
13636 n_key_custom_view_rotate_up &&
13637 n_key_custom_view_pan_up &&
13638 n_key_custom_view_rotate_down &&
13639 n_key_custom_view_pan_down &&
13640 n_key_custom_view_rotate_left &&
13641 n_key_custom_view_rotate_right &&
13642 n_key_docking_clearance_request &&
13643 n_key_weapons_online_toggle &&
13644 n_key_cycle_next_mfd &&
13645 n_key_cycle_previous_mfd &&
13646 n_key_switch_next_mfd &&
13647 n_key_switch_previous_mfd &&
13648 n_key_oxzmanager_setfilter &&
13649 n_key_oxzmanager_showinfo &&
13650 n_key_oxzmanager_extract &&
13651#if OO_FOV_INFLIGHT_CONTROL_ENABLED
13652 n_key_inc_field_of_view &&
13653 n_key_dec_field_of_view &&
13655 n_key_dump_target_state &&
13656 n_key_dump_entity_list &&
13657 n_key_debug_full &&
13658 n_key_debug_collision &&
13659 n_key_debug_console_connect &&
13660 n_key_debug_bounding_boxes &&
13661 n_key_debug_shaders &&
13667 customEquipActivation &&
13668 customActivatePressed &&
13669 customModePressed &&
13671 showingLongRangeChart &&
13672 _missionAllowInterrupt &&
13673 _missionScreenID &&
13695 return NSOrderedAscending;
13697 else if (result > 0)
13699 return NSOrderedDescending;
13703 return NSOrderedSame;
13714 return NSOrderedAscending;
13716 else if (result > 0)
13718 return NSOrderedDescending;
13722 return NSOrderedSame;
13733 return NSOrderedAscending;
13735 else if (result > 0)
13737 return NSOrderedDescending;
13741 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]
#define foreachkey(VAR, DICT)
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,...)
NSMutableArray * ScanTokensFromString(NSString *values)
NSString * ClockToString(double clock, BOOL adjusting)
OOINLINE NSString * OOCredits(OOCreditsQuantity tenthsOfCredits)
NSPoint PointFromString(NSString *xyString)
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