68@interface OOShipRegistry (OODataLoader)
76- (BOOL) applyLikeShips:(NSMutableDictionary *)ioData withKey:(NSString *)likeKey;
77- (BOOL) loadAndMergeShipyard:(NSMutableDictionary *)ioData;
78- (BOOL) stripPrivateKeys:(NSMutableDictionary *)ioData;
79- (BOOL) makeShipEntriesMutable:(NSMutableDictionary *)ioData;
80- (BOOL) loadAndApplyShipDataOverrides:(NSMutableDictionary *)ioData;
81- (BOOL) canonicalizeAndTagSubentities:(NSMutableDictionary *)ioData;
82- (BOOL) removeUnusableEntries:(NSMutableDictionary *)ioData shipMode:(BOOL)shipMode;
83- (BOOL) sanitizeConditions:(NSMutableDictionary *)ioData;
86- (BOOL) preloadShipMeshes:(NSMutableDictionary *)ioData;
89- (NSMutableDictionary *) mergeShip:(NSDictionary *)child withParent:(NSDictionary *)parent;
90- (void) mergeShipRoles:(NSString *)roles forShipKey:(NSString *)shipKey intoProbabilityMap:(NSMutableDictionary *)probabilitySets;
92- (NSDictionary *) canonicalizeSubentityDeclaration:(
id)declaration
93 forShip:(NSString *)shipKey
94 shipData:(NSDictionary *)shipData
95 fatalError:(BOOL *)outFatalError;
96- (NSDictionary *) translateOldStyleSubentityDeclaration:(NSString *)declaration
97 forShip:(NSString *)shipKey
98 shipData:(NSDictionary *)shipData
99 fatalError:(BOOL *)outFatalError;
100- (NSDictionary *) translateOldStyleFlasherDeclaration:(NSArray *)tokens
101 forShip:(NSString *)shipKey
102 fatalError:(BOOL *)outFatalError;
103- (NSDictionary *) translateOldStandardBasicSubentityDeclaration:(NSArray *)tokens
104 forShip:(NSString *)shipKey
105 shipData:(NSDictionary *)shipData
106 fatalError:(BOOL *)outFatalError;
107- (NSDictionary *) validateNewStyleSubentityDeclaration:(NSDictionary *)declaration
108 forShip:(NSString *)shipKey
109 fatalError:(BOOL *)outFatalError;
110- (NSDictionary *) validateNewStyleFlasherDeclaration:(NSDictionary *)declaration
111 forShip:(NSString *)shipKey
112 fatalError:(BOOL *)outFatalError;
113- (NSDictionary *) validateNewStyleStandardSubentityDeclaration:(NSDictionary *)declaration
114 forShip:(NSString *)shipKey
115 fatalError:(BOOL *)outFatalError;
117- (BOOL) shipIsBallTurretForKey:(NSString *)shipKey inShipData:(NSDictionary *)shipData;
145 (void) [
self sharedRegistry];
152 if ((
self = [super init]))
154 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
157 _shipData = [[cache
objectForKey:kShipDataCacheKey
inCache:kShipRegistryCacheName] retain];
158 _playerShips = [[cache
objectForKey:kPlayerShipsCacheKey
inCache:kShipRegistryCacheName] retain];
159 _effectData = [[cache
objectForKey:kVisualEffectDataCacheKey
inCache:kVisualEffectRegistryCacheName] retain];
160 if ([_shipData
count] == 0)
163 if ([_shipData
count] == 0)
165 [NSException raise:@"OOShipRegistryLoadFailure" format:@"Could not load any ship data."];
167 if ([_playerShips
count] == 0)
169 [NSException raise:@"OOShipRegistryLoadFailure" format:@"Could not load any player ships."];
173 [
self loadDemoShipConditions];
174 [
self loadDemoShips];
175 if ([_demoShips
count] == 0)
177 [NSException raise:@"OOShipRegistryLoadFailure" format:@"Could not load or synthesize any demo ships."];
180 [
self loadCachedRoleProbabilitySets];
181 if (_probabilitySets ==
nil)
183 [
self buildRoleProbabilitySets];
184 if ([_probabilitySets
count] == 0)
186 [NSException raise:@"OOShipRegistryLoadFailure" format:@"Could not load or synthesize role probability sets."];
199 [_demoShips release];
200 [_playerShips release];
201 [_probabilitySets release];
207- (NSDictionary *) shipInfoForKey:(NSString *)key
209 return [_shipData objectForKey:key];
213- (void) setShipInfoForKey:(NSString *)key with:(NSDictionary *)newShipData
215 NSMutableDictionary *mutableDict = [NSMutableDictionary dictionaryWithDictionary:_shipData];
216 [mutableDict setObject:OODeepCopy(newShipData) forKey:key];
218 _shipData = [[NSDictionary dictionaryWithDictionary:mutableDict] retain];
222- (NSDictionary *) effectInfoForKey:(NSString *)key
224 return [_effectData objectForKey:key];
228- (NSDictionary *) shipyardInfoForKey:(NSString *)key
230 return [[
self shipInfoForKey:key] objectForKey:@"_oo_shipyard"];
236 if (role ==
nil)
return nil;
237 return [_probabilitySets objectForKey:role];
241- (NSArray *) demoShipKeys
244 [
self loadDemoShips];
246 return [[_demoShips copy] autorelease];
250- (NSArray *) playerShipKeys
258@implementation OOShipRegistry (OOConveniences)
260- (NSArray *) shipKeys
262 return [_shipData allKeys];
265- (NSArray *) shipRoles
267 return [_probabilitySets allKeys];
270- (NSArray *) shipKeysWithRole:(NSString *)role
272 return [[
self probabilitySetForRole:role] allObjects];
276- (NSString *) randomShipKeyForRole:(NSString *)role
278 return [[
self probabilitySetForRole:role] randomObject];
284@implementation OOShipRegistry (OODataLoader)
298 NSMutableDictionary *result =
nil;
302 [_playerShips release];
309 cache:NO] mutableCopy] autorelease];
310 if (result ==
nil)
return;
315 if (![
self makeShipEntriesMutable:result])
return;
316 OOLog(
@"shipData.load.progress",
@"%@",
@"Finished initial cleanup...");
319 if (![
self loadAndApplyShipDataOverrides:result])
return;
320 OOLog(
@"shipData.load.progress",
@"%@",
@"Finished applying patches...");
323 if (![
self stripPrivateKeys:result])
return;
324 OOLog(
@"shipData.load.progress",
@"%@",
@"Finished stripping private keys...");
327 if (![
self applyLikeShips:result withKey:
@"like_ship"])
return;
328 OOLog(
@"shipData.load.progress",
@"%@",
@"Finished resolving like_ships...");
331 if (![
self canonicalizeAndTagSubentities:result])
return;
332 OOLog(
@"shipData.load.progress",
@"%@",
@"Finished cleaning up subentities...");
335 if (![
self removeUnusableEntries:result shipMode:YES])
return;
336 OOLog(
@"shipData.load.progress",
@"%@",
@"Finished removing invalid entries...");
339 if (![
self loadAndMergeShipyard:result])
return;
340 OOLog(
@"shipData.load.progress",
@"%@",
@"Finished adding shipyard entries...");
343 if (![
self sanitizeConditions:result])
return;
344 OOLog(
@"shipData.load.progress",
@"%@",
@"Finished validating data...");
348 if (![
self preloadShipMeshes:result])
return;
349 OOLog(
@"shipData.load.progress",
@"%@",
@"Finished loading meshes...");
355 OOLog(
@"shipData.load.done",
@"%@",
@"Ship data loaded.");
357 [_effectData release];
363 cache:NO] mutableCopy] autorelease];
364 if (result ==
nil)
return;
367 if (![
self makeShipEntriesMutable:result])
return;
368 OOLog(
@"effectData.load.progress",
@"%@",
@"Finished initial cleanup...");
371 if (![
self stripPrivateKeys:result])
return;
372 OOLog(
@"effectData.load.progress",
@"%@",
@"Finished stripping private keys...");
375 if (![
self applyLikeShips:result withKey:
@"like_effect"])
return;
376 OOLog(
@"effectData.load.progress",
@"%@",
@"Finished resolving like_effects...");
379 if (![
self canonicalizeAndTagSubentities:result])
return;
380 OOLog(
@"effectData.load.progress",
@"%@",
@"Finished cleaning up subentities...");
383 if (![
self removeUnusableEntries:result shipMode:NO])
return;
384 OOLog(
@"effectData.load.progress",
@"%@",
@"Finished removing invalid entries...");
389 OOLog(
@"effectData.load.done",
@"%@",
@"Effect data loaded.");
395 NSMutableArray *conditionScripts = [[NSMutableArray alloc] init];
396 NSEnumerator *enumerator =
nil;
397 NSDictionary *key =
nil;
398 NSArray *initialDemoShips =
nil;
405 for (enumerator = [initialDemoShips objectEnumerator]; (key = [enumerator nextObject]); )
407 NSString *conditions = [key oo_stringForKey:kOODemoShipConditions defaultValue:nil];
408 if (conditions !=
nil)
410 [conditionScripts addObject:conditions];
415 [conditionScripts release];
427 NSEnumerator *enumerator =
nil;
428 NSDictionary *key =
nil;
429 NSArray *initialDemoShips =
nil;
430 NSMutableArray *demoShips =
nil;
438 demoShips = [NSMutableArray arrayWithArray:initialDemoShips];
441 for (enumerator = [initialDemoShips objectEnumerator]; (key = [enumerator nextObject]); )
443 NSString *shipKey = [key oo_stringForKey:kOODemoShipKey];
444 if (![key isKindOfClass:[NSDictionary
class]] || [
self shipInfoForKey:shipKey] ==
nil)
446 [demoShips removeObject:key];
450 NSString *conditions = [key oo_stringForKey:kOODemoShipConditions defaultValue:nil];
451 if (conditions !=
nil)
453 if ([
PLAYER status] == STATUS_START_GAME)
456 [demoShips removeObject:key];
460 OOJSScript *condScript = [UNIVERSE getConditionScript:conditions];
461 if (condScript !=
nil)
469 OK = [condScript
callMethod:OOJSID("allowShowLibraryShip")
474 if (OK) OK = JS_ValueToBoolean(context, result, &allow_use);
477 if (OK && !allow_use)
482 [demoShips removeObject:key];
490 if ([demoShips
count] == 0)
492 NSString *shipKey =
nil;
499 shipKey = [[_shipData allKeys] objectAtIndex:0];
501 [demoShips addObject:[NSDictionary dictionaryWithObject:shipKey forKey:kOODemoShipKey]];
505 NSMutableDictionary *demoList = [NSMutableDictionary dictionaryWithCapacity:8];
506 NSMutableArray *demoClass =
nil;
507 foreach(key, demoShips)
509 NSString *
class = [key oo_stringForKey:
kOODemoShipClass defaultValue:
@"ship"];
510 if ([OOShipLibraryCategoryPlural(class) length] == 0)
512 OOLog(
@"shipdata.load.warning",
@"Unexpected class '%@' in shiplibrary.plist for '%@'",
class,[key oo_stringForKey:
kOODemoShipKey]);
515 demoClass = [demoList objectForKey:class];
516 if (demoClass ==
nil)
518 [demoList setObject:[NSMutableArray array] forKey:class];
519 demoClass = [demoList objectForKey:class];
521 NSMutableDictionary *demoEntry = [NSMutableDictionary dictionaryWithDictionary:key];
523 [demoEntry setObject:[[
self shipInfoForKey:[demoEntry oo_stringForKey:@"ship"]] oo_stringForKey:kOODemoShipName] forKey:kOODemoShipName];
525 if (![[demoEntry oo_stringForKey:
kOODemoShipClass defaultValue:
nil] isEqualToString:
class])
527 [demoEntry setObject:class forKey:kOODemoShipClass];
529 [demoClass addObject:demoEntry];
532 NSString *demoClassName =
nil;
533 foreach(demoClassName, demoList)
535 [[demoList objectForKey:demoClassName] sortUsingFunction:SortDemoShipsByName context:NULL];
539 _demoShips = [[[demoList allValues] sortedArrayUsingFunction:SortDemoCategoriesByName context:NULL] retain];
545 NSDictionary *cachedSets =
nil;
546 NSMutableDictionary *restoredSets =
nil;
547 NSEnumerator *roleEnum =
nil;
548 NSString *role =
nil;
551 if (cachedSets ==
nil)
return;
553 restoredSets = [NSMutableDictionary dictionaryWithCapacity:[cachedSets count]];
554 for (roleEnum = [cachedSets keyEnumerator]; (role = [roleEnum nextObject]); )
559 _probabilitySets = [restoredSets copy];
563- (void) buildRoleProbabilitySets
565 NSMutableDictionary *probabilitySets =
nil;
566 NSEnumerator *shipEnum =
nil;
567 NSString *shipKey =
nil;
568 NSDictionary *shipEntry =
nil;
569 NSString *roles =
nil;
570 NSEnumerator *roleEnum =
nil;
571 NSString *role =
nil;
573 NSMutableDictionary *cacheEntry =
nil;
575 probabilitySets = [NSMutableDictionary dictionary];
578 for (shipEnum = [_shipData keyEnumerator]; (shipKey = [shipEnum nextObject]); )
580 shipEntry = [_shipData objectForKey:shipKey];
581 roles = [shipEntry oo_stringForKey:@"roles"];
582 [
self mergeShipRoles:roles forShipKey:shipKey intoProbabilityMap:probabilitySets];
587 cacheEntry = [NSMutableDictionary dictionaryWithCapacity:[probabilitySets count]];
588 for (roleEnum = [[probabilitySets allKeys] objectEnumerator]; (role = [roleEnum nextObject]); )
590 pset = [probabilitySets objectForKey:role];
591 pset = [[pset copy] autorelease];
592 [probabilitySets setObject:pset forKey:role];
596 _probabilitySets = [probabilitySets copy];
615- (BOOL) applyLikeShips:(NSMutableDictionary *)ioData withKey:(NSString *)likeKey
617 NSMutableSet *remainingLikeShips =
nil;
618 NSEnumerator *enumerator =
nil;
620 NSString *parentKey =
nil;
621 NSDictionary *shipEntry =
nil;
622 NSDictionary *parentEntry =
nil;
623 NSUInteger
count, lastCount;
624 NSMutableArray *reportedBadShips =
nil;
627 remainingLikeShips = [NSMutableSet set];
628 for (enumerator = [ioData keyEnumerator]; (key = [enumerator nextObject]); )
630 shipEntry = [ioData objectForKey:key];
631 if ([shipEntry oo_stringForKey:likeKey] !=
nil)
633 [remainingLikeShips addObject:key];
637 count = lastCount = [remainingLikeShips count];
640 for (enumerator = [[[remainingLikeShips copy] autorelease] objectEnumerator]; (key = [enumerator nextObject]); )
643 shipEntry = [ioData objectForKey:key];
644 parentKey = [shipEntry objectForKey:likeKey];
645 if (![remainingLikeShips containsObject:parentKey])
648 parentEntry = [ioData objectForKey:parentKey];
649 shipEntry = [
self mergeShip:shipEntry withParent:parentEntry];
650 if (shipEntry !=
nil)
652 [remainingLikeShips removeObject:key];
653 [ioData setObject:shipEntry forKey:key];
658 count = [remainingLikeShips count];
659 if (
count == lastCount)
665 reportedBadShips = [NSMutableArray array];
666 for (enumerator = [remainingLikeShips objectEnumerator]; (key = [enumerator nextObject]); )
668 if (![[ioData oo_dictionaryForKey:key] oo_boolForKey:
@"is_external_dependency"])
670 [reportedBadShips addObject:key];
672 [ioData removeObjectForKey:key];
675 if ([reportedBadShips
count] != 0)
677 [reportedBadShips sortUsingSelector:@selector(caseInsensitiveCompare:)];
678 OOLogERR(
@"shipData.merge.failed",
@"one or more shipdata.plist entries have %@ references that cannot be resolved: %@", likeKey, [reportedBadShips componentsJoinedByString:
@", "]);
690- (NSMutableDictionary *) mergeShip:(NSDictionary *)child withParent:(NSDictionary *)parent
692 NSMutableDictionary *result = [[parent mutableCopy] autorelease];
693 if (result ==
nil)
return nil;
695 [result addEntriesFromDictionary:child];
696 [result removeObjectForKey:@"like_ship"];
699 if ([child oo_stringForKey:
@"display_name"] ==
nil) [result removeObjectForKey:@"display_name"];
700 if ([child oo_stringForKey:
@"is_template"] ==
nil) [result removeObjectForKey:@"is_template"];
707 if ([result oo_stringForKey:
@"scan_class"] !=
nil && [result oo_stringForKey:
@"scanClass"] !=
nil)
709 if ([child oo_stringForKey:
@"scanClass"] !=
nil)
710 [result removeObjectForKey:@"scan_class"];
712 [result removeObjectForKey:@"scanClass"];
715 if ([result oo_stringForKey:
@"escort_role"] !=
nil && [result oo_stringForKey:
@"escort-role"] !=
nil)
717 if ([child oo_stringForKey:
@"escort-role"] !=
nil)
718 [result removeObjectForKey:@"escort_role"];
720 [result removeObjectForKey:@"escort-role"];
722 if ([result oo_stringForKey:
@"escort_ship"] !=
nil && [result oo_stringForKey:
@"escort-ship"] !=
nil)
724 if ([child oo_stringForKey:
@"escort-ship"] !=
nil)
725 [result removeObjectForKey:@"escort_ship"];
727 [result removeObjectForKey:@"escort-ship"];
729 if ([result oo_stringForKey:
@"is_carrier"] !=
nil && [result oo_stringForKey:
@"isCarrier"] !=
nil)
731 if ([child oo_stringForKey:
@"isCarrier"] !=
nil)
732 [result removeObjectForKey:@"is_carrier"];
734 [result removeObjectForKey:@"isCarrier"];
736 if ([result oo_stringForKey:
@"has_shipyard"] !=
nil && [result oo_stringForKey:
@"hasShipyard"] !=
nil)
738 if ([child oo_stringForKey:
@"hasShipyard"] !=
nil)
739 [result removeObjectForKey:@"has_shipyard"];
741 [result removeObjectForKey:@"hasShipyard"];
747- (BOOL) makeShipEntriesMutable:(NSMutableDictionary *)ioData
749 NSEnumerator *shipKeyEnum =
nil;
750 NSString *shipKey =
nil;
751 NSDictionary *shipEntry =
nil;
753 for (shipKeyEnum = [[ioData allKeys] objectEnumerator]; (shipKey = [shipKeyEnum nextObject]); )
755 shipEntry = [ioData objectForKey:shipKey];
756 if (![shipEntry isKindOfClass:[NSDictionary
class]])
758 OOLogERR(
@"shipData.load.badEntry",
@"the shipdata.plist entry \"%@\
" is not a dictionary.", shipKey);
759 [ioData removeObjectForKey:shipKey];
763 shipEntry = [shipEntry mutableCopy];
765 [ioData setObject:shipEntry forKey:shipKey];
774- (BOOL) loadAndApplyShipDataOverrides:(NSMutableDictionary *)ioData
776 NSEnumerator *shipKeyEnum =
nil;
777 NSString *shipKey =
nil;
778 NSMutableDictionary *shipEntry =
nil;
779 NSDictionary *overrides =
nil;
780 NSDictionary *overridesEntry =
nil;
787 for (shipKeyEnum = [overrides keyEnumerator]; (shipKey = [shipKeyEnum nextObject]); )
789 shipEntry = [ioData objectForKey:shipKey];
790 if (shipEntry !=
nil)
792 overridesEntry = [overrides objectForKey:shipKey];
793 if (![overridesEntry isKindOfClass:[NSDictionary
class]])
795 OOLogERR(
@"shipData.load.error",
@"the shipdata-overrides.plist entry \"%@\
" is not a dictionary.", shipKey);
799 [shipEntry addEntriesFromDictionary:overridesEntry];
808- (BOOL) stripPrivateKeys:(NSMutableDictionary *)ioData
810 NSEnumerator *shipKeyEnum =
nil;
811 NSString *shipKey =
nil;
812 NSMutableDictionary *shipEntry =
nil;
813 NSEnumerator *attrKeyEnum =
nil;
814 NSString *attrKey =
nil;
816 for (shipKeyEnum = [ioData keyEnumerator]; (shipKey = [shipKeyEnum nextObject]); )
818 shipEntry = [ioData objectForKey:shipKey];
820 for (attrKeyEnum = [shipEntry keyEnumerator]; (attrKey = [attrKeyEnum nextObject]); )
822 if ([attrKey hasPrefix:
@"_oo_"])
824 [shipEntry removeObjectForKey:attrKey];
840- (BOOL) loadAndMergeShipyard:(NSMutableDictionary *)ioData
842 NSEnumerator *shipKeyEnum =
nil;
843 NSString *shipKey =
nil;
844 NSMutableDictionary *shipEntry =
nil;
845 NSDictionary *shipyard =
nil;
846 NSDictionary *shipyardOverrides =
nil;
847 NSDictionary *shipyardEntry =
nil;
848 NSDictionary *shipyardOverridesEntry =
nil;
849 NSMutableArray *playerShips =
nil;
852 for (shipKeyEnum = [ioData keyEnumerator]; (shipKey = [shipKeyEnum nextObject]); )
854 shipEntry = [ioData objectForKey:shipKey];
855 if ([shipEntry objectForKey:
@"_oo_shipyard"] !=
nil)
857 [shipEntry removeObjectForKey:@"_oo_shipyard"];
870 playerShips = [NSMutableArray arrayWithCapacity:[shipyard count]];
873 for (shipKeyEnum = [shipyard keyEnumerator]; (shipKey = [shipKeyEnum nextObject]); )
875 shipEntry = [ioData objectForKey:shipKey];
876 if (shipEntry !=
nil)
878 shipyardEntry = [shipyard objectForKey:shipKey];
879 shipyardOverridesEntry = [shipyardOverrides objectForKey:shipKey];
880 shipyardEntry = [shipyardEntry dictionaryByAddingEntriesFromDictionary:shipyardOverridesEntry];
882 [shipEntry setObject:shipyardEntry forKey:@"_oo_shipyard"];
884 [playerShips addObject:shipKey];
888 OOLogWARN(
@"shipData.load.shipyard.unknown",
@"the shipyard.plist entry \"%@\
" does not have a corresponding shipdata.plist entry, ignoring.", shipKey);
892 _playerShips = [playerShips copy];
899- (BOOL) canonicalizeAndTagSubentities:(NSMutableDictionary *)ioData
901 NSEnumerator *shipKeyEnum =
nil;
902 NSString *shipKey =
nil;
903 NSMutableDictionary *shipEntry =
nil;
904 NSArray *subentityDeclarations =
nil;
905 NSEnumerator *subentityEnum =
nil;
906 id subentityDecl =
nil;
907 NSDictionary *subentityDict =
nil;
908 NSString *subentityKey =
nil;
909 NSMutableDictionary *subentityShipEntry =
nil;
910 NSMutableSet *badSubentities =
nil;
911 NSString *badSubentitiesList =
nil;
912 NSMutableArray *okSubentities =
nil;
919 for (shipKeyEnum = [[ioData allKeys] objectEnumerator]; (shipKey = [shipKeyEnum nextObject]); )
921 shipEntry = [ioData objectForKey:shipKey];
923 badSubentities =
nil;
926 subentityDeclarations = [shipEntry oo_arrayForKey:@"subentities"];
927 if (subentityDeclarations !=
nil)
929 okSubentities = [NSMutableArray arrayWithCapacity:[subentityDeclarations count]];
930 for (subentityEnum = [subentityDeclarations objectEnumerator]; (subentityDecl = [subentityEnum nextObject]); )
932 subentityDict = [
self canonicalizeSubentityDeclaration:subentityDecl forShip:shipKey shipData:ioData fatalError:&fatal];
940 else if (subentityDict !=
nil)
942 [okSubentities addObject:subentityDict];
945 if (![[subentityDict oo_stringForKey:
@"type"] isEqualToString:
@"flasher"])
947 subentityKey = [subentityDict oo_stringForKey:@"subentity_key"];
948 subentityShipEntry = [ioData objectForKey:subentityKey];
949 if (subentityKey ==
nil || subentityShipEntry ==
nil)
952 if (badSubentities ==
nil) badSubentities = [NSMutableSet set];
953 [badSubentities addObject:subentityKey];
958 [subentityShipEntry oo_setBool:YES forKey:@"_oo_is_subentity"];
965 if ([okSubentities
count] != 0)
967 [shipEntry setObject:okSubentities forKey:@"subentities"];
971 [shipEntry removeObjectForKey:@"subentities"];
974 if (badSubentities !=
nil)
976 if (![shipEntry oo_boolForKey:
@"is_external_dependency"])
978 badSubentitiesList = [[[badSubentities allObjects] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] componentsJoinedByString:@", "];
979 OOLogERR(
@"shipData.load.error",
@"the shipdata.plist entry \"%@\
" has unresolved subentit%@ %@.", shipKey, ([badSubentities
count] == 1) ?
@"y" :
@"ies", badSubentitiesList);
988 [shipEntry oo_setBool:YES forKey:@"_oo_deferred_remove"];
997- (BOOL) removeUnusableEntries:(NSMutableDictionary *)ioData shipMode:(BOOL)shipMode
999 NSEnumerator *shipKeyEnum =
nil;
1000 NSString *shipKey =
nil;
1001 NSMutableDictionary *shipEntry =
nil;
1003 NSString *modelName =
nil;
1006 for (shipKeyEnum = [[ioData allKeys] objectEnumerator]; (shipKey = [shipKeyEnum nextObject]); )
1008 shipEntry = [ioData objectForKey:shipKey];
1011 if ([shipEntry oo_boolForKey:
@"is_template"] || [shipEntry oo_boolForKey:
@"_oo_deferred_remove"])
remove = YES;
1012 else if (shipMode && [[shipEntry oo_stringForKey:
@"roles"] length] == 0 && ![shipEntry oo_boolForKey:
@"_oo_is_subentity"] && ![shipEntry oo_boolForKey:
@"_oo_is_effect"])
1014 OOLogERR(
@"shipData.load.error",
@"the shipdata.plist entry \"%@\
" specifies no %@.", shipKey,
@"roles");
1020 modelName = [shipEntry oo_stringForKey:@"model"];
1021 if (shipMode && [modelName length] == 0)
1023 OOLogERR(
@"shipData.load.error",
@"the shipdata.plist entry \"%@\
" specifies no %@.", shipKey,
@"model");
1027 else if ([modelName length] != 0 && [
ResourceManager pathForFileNamed:modelName inFolder:
@"Models"] ==
nil)
1029 OOLogERR(
@"shipData.load.error",
@"the shipdata.plist entry \"%@\
" specifies non-existent model \"%@\".", shipKey, modelName);
1034 if (
remove) [ioData removeObjectForKey:shipKey];
1045- (BOOL) sanitizeConditions:(NSMutableDictionary *)ioData
1047 NSEnumerator *shipKeyEnum =
nil;
1048 NSString *shipKey =
nil;
1049 NSMutableDictionary *shipEntry =
nil;
1050 NSMutableDictionary *mutableShipyard =
nil;
1051 NSArray *conditions =
nil;
1052 NSArray *hasShipyard =
nil;
1053 NSArray *shipyardConditions =
nil;
1054 NSString *condition_script =
nil;
1055 NSString *shipyard_condition_script =
nil;
1057 NSMutableArray *conditionScripts = [[NSMutableArray alloc] init];
1059 for (shipKeyEnum = [[ioData allKeys] objectEnumerator]; (shipKey = [shipKeyEnum nextObject]); )
1061 shipEntry = [ioData objectForKey:shipKey];
1062 conditions = [shipEntry objectForKey:@"conditions"];
1063 condition_script = [shipEntry oo_stringForKey:@"condition_script"];
1064 if (condition_script !=
nil)
1066 if (![conditionScripts containsObject:condition_script])
1068 [conditionScripts addObject:condition_script];
1072 hasShipyard = [shipEntry objectForKey:@"has_shipyard"];
1073 if (![hasShipyard isKindOfClass:[NSArray
class]]) hasShipyard =
nil;
1074 if (hasShipyard ==
nil)
1076 hasShipyard = [shipEntry objectForKey:@"hasShipyard"];
1077 if (![hasShipyard isKindOfClass:[NSArray
class]]) hasShipyard =
nil;
1079 shipyardConditions = [[shipEntry oo_dictionaryForKey:@"_oo_shipyard"] objectForKey:@"conditions"];
1080 shipyard_condition_script = [[shipEntry oo_dictionaryForKey:@"_oo_shipyard"] oo_stringForKey:@"condition_script"];
1081 if (shipyard_condition_script !=
nil)
1083 if (![conditionScripts containsObject:shipyard_condition_script])
1085 [conditionScripts addObject:shipyard_condition_script];
1090 if (conditions ==
nil && hasShipyard && shipyardConditions ==
nil)
continue;
1092 if (conditions !=
nil)
1094 OOStandardsDeprecated([NSString stringWithFormat:
@"The 'conditions' key is deprecated in shipdata entry %@",shipKey]);
1097 if ([conditions isKindOfClass:[NSArray
class]])
1103 OOLogWARN(
@"shipdata.load.warning",
@"conditions for shipdata.plist entry \"%@\
" are not an array, ignoring.", shipKey);
1107 if (conditions !=
nil)
1109 [shipEntry setObject:conditions forKey:@"conditions"];
1113 [shipEntry removeObjectForKey:@"conditions"];
1118 if (hasShipyard !=
nil)
1121 OOStandardsDeprecated([NSString stringWithFormat:
@"Use of legacy script conditions in the 'has_shipyard' key is deprecated in shipyard entry %@",shipKey]);
1124 if (hasShipyard !=
nil)
1126 [shipEntry setObject:hasShipyard forKey:@"has_shipyard"];
1130 [shipEntry removeObjectForKey:@"hasShipyard"];
1131 [shipEntry removeObjectForKey:@"has_shipyard"];
1136 if (shipyardConditions !=
nil)
1138 OOStandardsDeprecated([NSString stringWithFormat:
@"The 'conditions' key is deprecated in shipyard entry %@",shipKey]);
1141 mutableShipyard = [[[shipEntry oo_dictionaryForKey:@"_oo_shipyard"] mutableCopy] autorelease];
1143 if ([shipyardConditions isKindOfClass:[NSArray
class]])
1149 OOLogWARN(
@"shipdata.load.warning",
@"conditions for shipyard.plist entry \"%@\
" are not an array, ignoring.", shipKey);
1150 shipyardConditions =
nil;
1153 if (shipyardConditions !=
nil)
1155 [mutableShipyard setObject:shipyardConditions forKey:@"conditions"];
1159 [mutableShipyard removeObjectForKey:@"conditions"];
1162 [shipEntry setObject:mutableShipyard forKey:@"_oo_shipyard"];
1168 [conditionScripts release];
1175- (BOOL) preloadShipMeshes:(NSMutableDictionary *)ioData
1177 NSEnumerator *shipKeyEnum =
nil;
1178 NSString *shipKey =
nil;
1179 NSMutableDictionary *shipEntry =
nil;
1181 NSString *modelName =
nil;
1183 NSAutoreleasePool *pool =
nil;
1184 NSUInteger i = 0,
count;
1186 count = [ioData count];
1189 for (shipKeyEnum = [[ioData allKeys] objectEnumerator]; (shipKey = [shipKeyEnum nextObject]); )
1191 pool = [[NSAutoreleasePool alloc] init];
1195 shipEntry = [ioData objectForKey:shipKey];
1198 modelName = [shipEntry oo_stringForKey:@"model"];
1199 mesh = [
OOMesh meshWithName:modelName
1200 materialDictionary:[shipEntry oo_dictionaryForKey:@"materials"]
1201 shadersDictionary:[shipEntry oo_dictionaryForKey:@"shaders"]
1202 smooth:[shipEntry oo_boolForKey:@"smooth"]
1204 shaderBindingTarget:nil];
1211 OOLogERR(
@"shipData.load.error",
@"model \"%@\
" could not be loaded for ship \"%@\", removing.", modelName, shipKey);
1212 [ioData removeObjectForKey:shipKey];
1223- (void) mergeShipRoles:(NSString *)roles
1224 forShipKey:(NSString *)shipKey
1225 intoProbabilityMap:(NSMutableDictionary *)probabilitySets
1227 NSDictionary *rolesAndWeights =
nil;
1228 NSEnumerator *roleEnum =
nil;
1229 NSString *role =
nil;
1243 NSMutableDictionary *
mutable = [NSMutableDictionary dictionaryWithDictionary:rolesAndWeights];
1244 [mutable setObject:[NSNumber numberWithFloat:1.0] forKey:[[[NSString alloc] initWithFormat:@"[%@]",shipKey] autorelease]];
1245 rolesAndWeights =
mutable;
1247 id thargonValue = [rolesAndWeights objectForKey:@"thargon"];
1248 if (thargonValue !=
nil && [rolesAndWeights objectForKey:
@"EQ_THARGON"] ==
nil)
1250 NSMutableDictionary *
mutable = [NSMutableDictionary dictionaryWithDictionary:rolesAndWeights];
1251 [mutable setObject:thargonValue forKey:@"EQ_THARGON"];
1252 rolesAndWeights =
mutable;
1255 for (roleEnum = [rolesAndWeights keyEnumerator]; (role = [roleEnum nextObject]); )
1257 probSet = [probabilitySets objectForKey:role];
1261 [probabilitySets setObject:probSet forKey:role];
1269- (NSDictionary *) canonicalizeSubentityDeclaration:(
id)declaration
1270 forShip:(NSString *)shipKey
1271 shipData:(NSDictionary *)shipData
1272 fatalError:(BOOL *)outFatalError
1274 NSDictionary *result =
nil;
1276 assert(outFatalError != NULL);
1277 *outFatalError = NO;
1279 if ([declaration isKindOfClass:[NSString
class]])
1282 OOStandardsDeprecated([NSString stringWithFormat:
@"Old style sub-entity declarations are deprecated in %@",shipKey]);
1285 result = [
self translateOldStyleSubentityDeclaration:declaration
1288 fatalError:outFatalError];
1293 result = [
self validateNewStyleSubentityDeclaration:result
1295 fatalError:outFatalError];
1298 else if ([declaration isKindOfClass:[NSDictionary
class]])
1301 result = [
self validateNewStyleSubentityDeclaration:declaration
1303 fatalError:outFatalError];
1307 OOLogERR(
@"shipData.load.error.badSubentity",
@"subentity declaration for ship %@ should be string or dictionary, found %@.", shipKey, [declaration
class]);
1308 *outFatalError = YES;
1312 if (*outFatalError && [[shipData oo_dictionaryForKey:shipKey] oo_boolForKey:
@"frangible"]) *outFatalError = NO;
1318- (NSDictionary *) translateOldStyleSubentityDeclaration:(NSString *)declaration
1319 forShip:(NSString *)shipKey
1320 shipData:(NSDictionary *)shipData
1321 fatalError:(BOOL *)outFatalError
1323 NSArray *tokens =
nil;
1324 NSString *subentityKey =
nil;
1329 subentityKey = [tokens objectAtIndex:0];
1330 isFlasher = [subentityKey isEqualToString:@"*FLASHER*"];
1333 if ([tokens
count] != 8)
1337 OOLogERR(
@"shipData.load.error.badSubentity",
@"the shipdata.plist entry \"%@\
" has a broken subentity definition \"%@\" (should have 8 tokens, has %lu).", shipKey, subentityKey, [tokens
count]);
1338 *outFatalError = YES;
1342 OOLogWARN(
@"shipData.load.warning.badFlasher",
@"the shipdata.plist entry \"%@\
" has a broken flasher definition (should have 8 tokens, has %lu). This flasher will be ignored.", shipKey, [tokens
count]);
1349 return [
self translateOldStyleFlasherDeclaration:tokens
1351 fatalError:outFatalError];
1355 return [
self translateOldStandardBasicSubentityDeclaration:tokens
1358 fatalError:outFatalError];
1363- (NSDictionary *) translateOldStyleFlasherDeclaration:(NSArray *)tokens
1364 forShip:(NSString *)shipKey
1365 fatalError:(BOOL *)outFatalError
1368 float size, frequency, phase, hue;
1369 NSDictionary *colorDict =
nil;
1370 NSDictionary *result =
nil;
1372 position.x = [tokens oo_floatAtIndex:1];
1373 position.y = [tokens oo_floatAtIndex:2];
1374 position.z = [tokens oo_floatAtIndex:3];
1376 hue = [tokens oo_floatAtIndex:4];
1377 frequency = [tokens oo_floatAtIndex:5];
1378 phase = [tokens oo_floatAtIndex:6];
1379 size = [tokens oo_floatAtIndex:7];
1381 colorDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:hue] forKey:@"hue"];
1383 result = [NSDictionary dictionaryWithObjectsAndKeys:
1384 @"flasher", @"type",
1385 OOPropertyListFromVector(position), @"position",
1386 [NSArray arrayWithObject:colorDict], @"colors",
1387 [NSNumber numberWithFloat:frequency], @"frequency",
1388 [NSNumber numberWithFloat:phase], @"phase",
1389 [NSNumber numberWithFloat:size], @"size",
1392 OOLog(
@"shipData.translateSubentity.flasher",
@"Translated flasher declaration \"%@\
" to %@", [tokens componentsJoinedByString:
@" "], result);
1398- (NSDictionary *) translateOldStandardBasicSubentityDeclaration:(NSArray *)tokens
1399 forShip:(NSString *)shipKey
1400 shipData:(NSDictionary *)shipData
1401 fatalError:(BOOL *)outFatalError
1403 NSString *subentityKey =
nil;
1405 Quaternion orientation;
1406 NSMutableDictionary *result =
nil;
1407 BOOL isTurret, isDock = NO;
1409 subentityKey = [tokens oo_stringAtIndex:0];
1411 isTurret = [
self shipIsBallTurretForKey:subentityKey inShipData:shipData];
1413 position.x = [tokens oo_floatAtIndex:1];
1414 position.y = [tokens oo_floatAtIndex:2];
1415 position.z = [tokens oo_floatAtIndex:3];
1417 orientation.w = [tokens oo_floatAtIndex:4];
1418 orientation.x = [tokens oo_floatAtIndex:5];
1419 orientation.y = [tokens oo_floatAtIndex:6];
1420 orientation.z = [tokens oo_floatAtIndex:7];
1422 if(orientation.w == 0 && orientation.x == 0 && orientation.y == 0 && orientation.z == 0)
1425 OOLogWARN(
@"shipData.load.error",
@"The ship %@ has an undefined orientation for its %@ subentity. Setting it now at (1,0,0,0)", shipKey, subentityKey);
1428 quaternion_normalize(&orientation);
1432 isDock = [subentityKey rangeOfString:@"dock"].location != NSNotFound;
1435 result = [NSMutableDictionary dictionaryWithCapacity:5];
1436 [result setObject:isTurret ? @"ball_turret" : @"standard" forKey:@"type"];
1437 [result setObject:subentityKey forKey:@"subentity_key"];
1438 [result oo_setVector:position forKey:@"position"];
1439 [result oo_setQuaternion:orientation forKey:@"orientation"];
1440 if (isDock) [result oo_setBool:YES forKey:@"is_dock"];
1442 OOLog(
@"shipData.translateSubentity.standard",
@"Translated subentity declaration \"%@\
" to %@", [tokens componentsJoinedByString:
@" "], result);
1444 return [[result copy] autorelease];
1448- (NSDictionary *) validateNewStyleSubentityDeclaration:(NSDictionary *)declaration
1449 forShip:(NSString *)shipKey
1450 fatalError:(BOOL *)outFatalError
1452 NSString *type =
nil;
1454 type = [declaration oo_stringForKey:@"type"];
1455 if (type ==
nil) type =
@"standard";
1457 if ([type isEqualToString:
@"flasher"])
1459 return [
self validateNewStyleFlasherDeclaration:declaration forShip:shipKey fatalError:outFatalError];
1461 else if ([type isEqualToString:
@"standard"] || [type isEqualToString:
@"ball_turret"])
1463 return [
self validateNewStyleStandardSubentityDeclaration:declaration forShip:shipKey fatalError:outFatalError];
1467 OOLogERR(
@"shipData.load.error.badSubentity",
@"subentity declaration for ship %@ does not declare a valid type (must be standard, flasher or ball_turret).", shipKey);
1468 *outFatalError = YES;
1474- (NSDictionary *) validateNewStyleFlasherDeclaration:(NSDictionary *)declaration
1475 forShip:(NSString *)shipKey
1476 fatalError:(BOOL *)outFatalError
1478 NSMutableDictionary *result =
nil;
1480 NSArray *colors =
nil;
1482 float size, frequency, phase, brightfraction;
1485#define kDefaultFlasherColor @"redColor"
1488 colors = [declaration oo_arrayForKey:@"colors"];
1489 if ([colors
count] == 0)
1491 colorDesc = [declaration objectForKey:@"color"];
1493 if ([colorDesc isKindOfClass:[NSArray
class]])
1496 OOLogWARN(
@"shipData.load.warning.flasher.badColor",
@"changing flasher for ship %@ from a color to a colors definition.", shipKey);
1501 colors = [NSArray arrayWithObject:colorDesc];
1506 NSMutableArray *validColors = [NSMutableArray arrayWithCapacity:[colors count]];
1507 foreach (colorDesc, colors)
1516 OOLogWARN(
@"shipdata.load.warning.flasher.badColor",
@"skipping invalid colour specifier for flasher for ship %@.", shipKey);
1520 if ([validColors
count] == 0)
1522 [validColors addObject:kDefaultFlasherColor];
1524 colors = validColors;
1526 position = [declaration oo_vectorForKey:@"position"];
1528 size = [declaration oo_floatForKey:@"size" defaultValue:8.0];
1532 OOLogWARN(
@"shipData.load.warning.flasher.badSize",
@"skipping flasher of invalid size %g for ship %@.",
size, shipKey);
1536 brightfraction = [declaration oo_floatForKey:@"bright_fraction" defaultValue:0.5];
1537 if (brightfraction < 0.0 || brightfraction > 1.0)
1539 OOLogWARN(
@"shipData.load.warning.flasher.badFraction",
@"skipping flasher of invalid bright fraction %g for ship %@.", brightfraction, shipKey);
1543 frequency = [declaration oo_floatForKey:@"frequency" defaultValue:2.0];
1544 phase = [declaration oo_floatForKey:@"phase" defaultValue:0.0];
1545 initiallyOn = [declaration oo_boolForKey:@"initially_on" defaultValue:YES];
1547 result = [NSMutableDictionary dictionaryWithCapacity:8];
1548 [result setObject:@"flasher" forKey:@"type"];
1549 [result setObject:colors forKey:@"colors"];
1550 [result oo_setVector:position forKey:@"position"];
1551 [result setObject:[NSNumber numberWithFloat:size] forKey:@"size"];
1552 [result setObject:[NSNumber numberWithFloat:frequency] forKey:@"frequency"];
1553 if (phase != 0) [result setObject:[NSNumber numberWithFloat:phase] forKey:@"phase"];
1554 [result setObject:[NSNumber numberWithFloat:brightfraction] forKey:@"bright_fraction"];
1555 [result setObject:[NSNumber numberWithBool:initiallyOn] forKey:@"initially_on"];
1557 return [[result copy] autorelease];
1561- (NSDictionary *) validateNewStyleStandardSubentityDeclaration:(NSDictionary *)declaration
1562 forShip:(NSString *)shipKey
1563 fatalError:(BOOL *)outFatalError
1565 NSMutableDictionary *result =
nil;
1566 NSString *subentityKey =
nil;
1571 float fireRate = -1.0f;
1572 float weaponRange = -1.0f;
1573 float weaponEnergy = -1.0f;
1574 NSDictionary *scriptInfo =
nil;
1576 subentityKey = [declaration objectForKey:@"subentity_key"];
1577 if (subentityKey ==
nil)
1579 OOLogERR(
@"shipData.load.error.badSubentity",
@"subentity declaration for ship %@ specifies no subentity_key.", shipKey);
1580 *outFatalError = YES;
1584 isTurret = [[declaration oo_stringForKey:@"type"] isEqualToString:@"ball_turret"];
1587 fireRate = [declaration oo_floatForKey:@"fire_rate" defaultValue:-1.0f];
1588 if (fireRate < 0.25f && fireRate >= 0.0f)
1590 OOLogWARN(
@"shipData.load.warning.turret.badFireRate",
@"ball turret fire rate of %g for subentity of ship %@ is invalid, using 0.25.", fireRate, shipKey);
1593 weaponRange = [declaration oo_floatForKey:@"weapon_range" defaultValue:-1.0f];
1600 weaponEnergy = [declaration oo_floatForKey:@"weapon_energy" defaultValue:-1.0f];
1601 if (weaponEnergy > 100.0f)
1604 OOLogWARN(
@"shipData.load.warning.turret.badWeaponEnergy",
@"ball turret weapon energy of %g for subentity of ship %@ is too high, using 100.", weaponEnergy, shipKey);
1605 weaponEnergy = 100.0f;
1610 isDock = [declaration oo_boolForKey:@"is_dock"];
1613 position = [declaration oo_vectorForKey:@"position"];
1614 orientation = [declaration oo_quaternionForKey:@"orientation"];
1615 quaternion_normalize(&orientation);
1617 scriptInfo = [declaration oo_dictionaryForKey:@"script_info"];
1619 result = [NSMutableDictionary dictionaryWithCapacity:10];
1620 [result setObject:isTurret ? @"ball_turret" : @"standard" forKey:@"type"];
1621 [result setObject:subentityKey forKey:@"subentity_key"];
1622 [result oo_setVector:position forKey:@"position"];
1623 [result oo_setQuaternion:orientation forKey:@"orientation"];
1626 [result oo_setBool:YES forKey:@"is_dock"];
1628 NSString* docklabel = [declaration oo_stringForKey:@"dock_label" defaultValue:@"the docking bay"];
1629 [result setObject:docklabel forKey:@"dock_label"];
1631 BOOL dockable = [declaration oo_boolForKey:@"allow_docking" defaultValue:YES];
1632 BOOL playerdockable = [declaration oo_boolForKey:@"disallowed_docking_collides" defaultValue:NO];
1633 BOOL undockable = [declaration oo_boolForKey:@"allow_launching" defaultValue:YES];
1635 [result oo_setBool:dockable forKey:@"allow_docking"];
1636 [result oo_setBool:playerdockable forKey:@"disallowed_docking_collides"];
1637 [result oo_setBool:undockable forKey:@"allow_launching"];
1644 if (fireRate > 0) [result oo_setFloat:fireRate forKey:@"fire_rate"];
1645 if (weaponRange >= 0) [result oo_setFloat:weaponRange forKey:@"weapon_range"];
1646 if (weaponEnergy >= 0) [result oo_setFloat:weaponEnergy forKey:@"weapon_energy"];
1649 if (scriptInfo !=
nil)
1651 [result setObject:scriptInfo forKey:@"script_info"];
1654 return [[result copy] autorelease];
1658- (BOOL) shipIsBallTurretForKey:(NSString *)shipKey inShipData:(NSDictionary *)shipData
1661 NSArray *setupActions =
nil;
1662 NSEnumerator *actionEnum =
nil;
1663 NSString *action =
nil;
1665 setupActions = [[shipData oo_dictionaryForKey:shipKey] oo_arrayForKey:@"setup_actions"];
1667 for (actionEnum = [setupActions objectEnumerator]; (action = [actionEnum nextObject]); )
1669 if ([[
ScanTokensFromString(action) objectAtIndex:0] isEqualToString:
@"initialiseTurret"])
return YES;
1672 if ([shipKey isEqualToString:
@"ballturret"])
1685@implementation OOShipRegistry (Singleton)
1694+ (id) allocWithZone:(NSZone *)inZone
1698 OOLog(
@"shipData.load.begin",
@"%@",
@"Loading ship data.");
1706- (id) copyWithZone:(NSZone *)inZone
1738static void GatherStringAddrs(
id object, NSMutableSet *strings, NSString *context);
1744 static FILE *dump = NULL;
1745 if (dump == NULL) dump = fopen(
"strings.txt",
"w");
1746 if (dump == NULL)
return;
1748 NSAutoreleasePool *pool = [NSAutoreleasePool new];
1749 NSMutableSet *strings = [NSMutableSet set];
1752 NSEnumerator *entryEnum =
nil;
1753 NSDictionary *entry =
nil;
1754 for (entryEnum = [strings objectEnumerator]; (entry = [entryEnum nextObject]); )
1756 NSString *
string = [entry objectForKey:@"string"];
1757 NSString *context = [entry objectForKey:@"context"];
1758 void *pointer = [[entry objectForKey:@"address"] pointerValue];
1760 string = [NSString stringWithFormat:@"%p\t%@: \"%@\"", pointer, context, string];
1762 fprintf(dump,
"%s\n", [
string UTF8String]);
1765 fprintf(dump,
"\n");
1773 NSEnumerator *keyEnum =
nil;
1775 NSString *keyContext = [context stringByAppendingString:@" key"];
1776 for (keyEnum = [dict keyEnumerator]; (key = [keyEnum nextObject]); )
1779 GatherStringAddrs([dict objectForKey:key], strings, [context stringByAppendingFormat:
@".%@", key]);
1786 NSEnumerator *vEnum =
nil;
1789 for (vEnum = [array objectEnumerator]; (v = [vEnum nextObject]); )
1798 if ([
object isKindOfClass:[NSString
class]])
1800 NSDictionary *entry = [NSDictionary dictionaryWithObjectsAndKeys:object, @"string", [NSValue valueWithPointer:object], @"address", context, @"context", nil];
1801 [strings addObject:entry];
1803 else if ([
object isKindOfClass:[NSArray
class]])
1807 else if ([
object isKindOfClass:[NSDictionary
class]])
1816 return [[a oo_stringForKey:@"name"] compare:[b oo_stringForKey:@"name"]];
1822 return [OOShipLibraryCategoryPlural([[a oo_dictionaryAtIndex:0] oo_stringForKey:@"class"]) compare:OOShipLibraryCategoryPlural([[b oo_dictionaryAtIndex:0] oo_stringForKey:@"class"])];
static OODebugMonitor * sSingleton
void OOStandardsDeprecated(NSString *message)
BOOL OOEnforceStandards(void)
void OOStandardsError(NSString *message)
id OODeepCopy(id object) OO_RETURNS_RETAINED
OOINLINE jsval OOJSValueFromNativeObject(JSContext *context, id object)
OOINLINE JSContext * OOJSAcquireContext(void)
OOINLINE void OOJSRelinquishContext(JSContext *context)
NSArray * OOSanitizeLegacyScriptConditions(NSArray *conditions, NSString *context)
#define OOLogWARN(class, format,...)
#define OOLogERR(class, format,...)
#define OOLog(class, format,...)
const Quaternion kIdentityQuaternion
NSDictionary * OOParseRolesFromString(NSString *string)
static NSString *const kOODemoShipClass
static NSString *const kOODemoShipKey
static OOShipRegistry * sSingleton
#define kDefaultFlasherColor
static NSComparisonResult SortDemoCategoriesByName(id a, id b, void *context)
static NSString *const kDefaultDemoShip
static void GatherStringAddrsArray(NSArray *array, NSMutableSet *strings, NSString *context)
static void GatherStringAddrsDict(NSDictionary *dict, NSMutableSet *strings, NSString *context)
static NSString *const kPlayerShipsCacheKey
static NSString *const kShipDataCacheKey
static NSString *const kVisualEffectDataCacheKey
static NSComparisonResult SortDemoShipsByName(id a, id b, void *context)
static void DumpStringAddrs(NSDictionary *dict, NSString *context)
static NSString *const kShipRegistryCacheName
static void GatherStringAddrs(id object, NSMutableSet *strings, NSString *context)
static NSString *const kRoleWeightsCacheKey
static NSString *const kVisualEffectRegistryCacheName
NSMutableArray * ScanTokensFromString(NSString *values)
#define TURRET_SHOT_RANGE
#define COMBAT_WEAPON_RANGE_FACTOR
void loadDemoShipConditions()
void loadCachedRoleProbabilitySets()
void buildRoleProbabilitySets()
GameController * sharedController()
void setObject:forKey:inCache:(id inElement,[forKey] NSString *inKey,[inCache] NSString *inCacheKey)
id objectForKey:inCache:(NSString *inKey,[inCache] NSString *inCacheKey)
OOCacheManager * sharedCache()
void setObject:forKey:(id value,[forKey] id key)
OOColor * colorWithDescription:(id description)
NSArray * normalizedArray()
BOOL callMethod:inContext:withArguments:count:result:(jsid methodID,[inContext] JSContext *context,[withArguments] jsval *argv,[count] intN argc,[result] jsval *outResult)
void setWeight:forObject:(float weight,[forObject] id object)
NSDictionary * propertyListRepresentation()
id probabilitySetWithPropertyListRepresentation:(NSDictionary *plist)
NSArray * arrayFromFilesNamed:inFolder:andMerge:cache:(NSString *fileName,[inFolder] NSString *folderName,[andMerge] BOOL mergeFiles,[cache] BOOL useCache)
NSDictionary * dictionaryFromFilesNamed:inFolder:mergeMode:cache:(NSString *fileName,[inFolder] NSString *folderName,[mergeMode] OOResourceMergeMode mergeMode,[cache] BOOL useCache)