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.");
393- (void) loadDemoShipConditions
395 NSMutableArray *conditionScripts = [[NSMutableArray alloc] init];
396 NSDictionary *key =
nil;
397 NSArray *initialDemoShips =
nil;
404 foreach (key, initialDemoShips)
406 NSString *conditions = [key oo_stringForKey:kOODemoShipConditions defaultValue:nil];
407 if (conditions !=
nil)
409 [conditionScripts addObject:conditions];
414 [conditionScripts release];
424- (void) loadDemoShips
426 NSDictionary *key =
nil;
427 NSArray *initialDemoShips =
nil;
428 NSMutableArray *demoShips =
nil;
436 demoShips = [NSMutableArray arrayWithArray:initialDemoShips];
439 foreach (key, initialDemoShips)
441 NSString *shipKey = [key oo_stringForKey:kOODemoShipKey];
442 if (![key isKindOfClass:[NSDictionary class]] || [
self shipInfoForKey:shipKey] ==
nil)
444 [demoShips removeObject:key];
448 NSString *conditions = [key oo_stringForKey:kOODemoShipConditions defaultValue:nil];
449 if (conditions !=
nil)
451 if ([
PLAYER status] == STATUS_START_GAME)
454 [demoShips removeObject:key];
458 OOJSScript *condScript = [UNIVERSE getConditionScript:conditions];
459 if (condScript !=
nil)
467 OK = [condScript
callMethod:OOJSID("allowShowLibraryShip")
472 if (OK) OK = JS_ValueToBoolean(context, result, &allow_use);
475 if (OK && !allow_use)
480 [demoShips removeObject:key];
488 if ([demoShips
count] == 0)
490 NSString *shipKey =
nil;
497 shipKey = [[_shipData allKeys] objectAtIndex:0];
499 [demoShips addObject:[NSDictionary dictionaryWithObject:shipKey forKey:kOODemoShipKey]];
503 NSMutableDictionary *demoList = [NSMutableDictionary dictionaryWithCapacity:8];
504 NSMutableArray *demoClass =
nil;
505 foreach (key, demoShips)
507 NSString *
class = [key oo_stringForKey:
kOODemoShipClass defaultValue:
@"ship"];
508 if ([OOShipLibraryCategoryPlural(class) length] == 0)
510 OOLog(
@"shipdata.load.warning",
@"Unexpected class '%@' in shiplibrary.plist for '%@'",
class,[key oo_stringForKey:
kOODemoShipKey]);
513 demoClass = [demoList objectForKey:class];
514 if (demoClass ==
nil)
516 [demoList setObject:[NSMutableArray array] forKey:class];
517 demoClass = [demoList objectForKey:class];
519 NSMutableDictionary *demoEntry = [NSMutableDictionary dictionaryWithDictionary:key];
521 [demoEntry setObject:[[
self shipInfoForKey:[demoEntry oo_stringForKey:@"ship"]] oo_stringForKey:kOODemoShipName] forKey:kOODemoShipName];
523 if (![[demoEntry oo_stringForKey:
kOODemoShipClass defaultValue:
nil] isEqualToString:class])
525 [demoEntry setObject:class forKey:kOODemoShipClass];
527 [demoClass addObject:demoEntry];
530 NSString *demoClassName =
nil;
531 foreach (demoClassName, demoList)
533 [[demoList objectForKey:demoClassName] sortUsingFunction:SortDemoShipsByName context:NULL];
537 _demoShips = [[[demoList allValues] sortedArrayUsingFunction:SortDemoCategoriesByName context:NULL] retain];
541- (void) loadCachedRoleProbabilitySets
543 NSDictionary *cachedSets =
nil;
544 NSMutableDictionary *restoredSets =
nil;
545 NSString *role =
nil;
548 if (cachedSets ==
nil)
return;
550 restoredSets = [NSMutableDictionary dictionaryWithCapacity:[cachedSets count]];
556 _probabilitySets = [restoredSets copy];
560- (void) buildRoleProbabilitySets
562 NSMutableDictionary *probabilitySets =
nil;
563 NSString *shipKey =
nil;
564 NSDictionary *shipEntry =
nil;
565 NSString *roles =
nil;
566 NSString *role =
nil;
568 NSMutableDictionary *cacheEntry =
nil;
570 probabilitySets = [NSMutableDictionary dictionary];
575 shipEntry = [_shipData objectForKey:shipKey];
576 roles = [shipEntry oo_stringForKey:@"roles"];
577 [
self mergeShipRoles:roles forShipKey:shipKey intoProbabilityMap:probabilitySets];
582 cacheEntry = [NSMutableDictionary dictionaryWithCapacity:[probabilitySets count]];
583 foreach (role, [probabilitySets allKeys])
585 pset = [probabilitySets objectForKey:role];
586 pset = [[pset copy] autorelease];
587 [probabilitySets setObject:pset forKey:role];
591 _probabilitySets = [probabilitySets copy];
610- (BOOL) applyLikeShips:(NSMutableDictionary *)ioData withKey:(NSString *)likeKey
612 NSMutableSet *remainingLikeShips =
nil;
614 NSString *parentKey =
nil;
615 NSDictionary *shipEntry =
nil;
616 NSDictionary *parentEntry =
nil;
617 NSUInteger
count, lastCount;
618 NSMutableArray *reportedBadShips =
nil;
621 remainingLikeShips = [NSMutableSet set];
624 shipEntry = [ioData objectForKey:key];
625 if ([shipEntry oo_stringForKey:likeKey] !=
nil)
627 [remainingLikeShips addObject:key];
631 count = lastCount = [remainingLikeShips count];
634 foreach (key, [[remainingLikeShips copy] autorelease])
637 shipEntry = [ioData objectForKey:key];
638 parentKey = [shipEntry objectForKey:likeKey];
639 if (![remainingLikeShips containsObject:parentKey])
642 parentEntry = [ioData objectForKey:parentKey];
643 shipEntry = [
self mergeShip:shipEntry withParent:parentEntry];
644 if (shipEntry !=
nil)
646 [remainingLikeShips removeObject:key];
647 [ioData setObject:shipEntry forKey:key];
652 count = [remainingLikeShips count];
653 if (
count == lastCount)
659 reportedBadShips = [NSMutableArray array];
660 foreach (key, remainingLikeShips)
662 if (![[ioData oo_dictionaryForKey:key] oo_boolForKey:
@"is_external_dependency"])
664 [reportedBadShips addObject:key];
666 [ioData removeObjectForKey:key];
669 if ([reportedBadShips
count] != 0)
671 [reportedBadShips sortUsingSelector:@selector(caseInsensitiveCompare:)];
672 OOLogERR(
@"shipData.merge.failed",
@"one or more shipdata.plist entries have %@ references that cannot be resolved: %@", likeKey, [reportedBadShips componentsJoinedByString:
@", "]);
684- (NSMutableDictionary *) mergeShip:(NSDictionary *)child withParent:(NSDictionary *)parent
686 NSMutableDictionary *result = [[parent mutableCopy] autorelease];
687 if (result ==
nil)
return nil;
689 [result addEntriesFromDictionary:child];
690 [result removeObjectForKey:@"like_ship"];
693 if ([child oo_stringForKey:
@"display_name"] ==
nil) [result removeObjectForKey:
@"display_name"];
694 if ([child oo_stringForKey:
@"is_template"] ==
nil) [result removeObjectForKey:
@"is_template"];
701 if ([result oo_stringForKey:
@"scan_class"] !=
nil && [result oo_stringForKey:
@"scanClass"] !=
nil)
703 if ([child oo_stringForKey:
@"scanClass"] !=
nil)
704 [result removeObjectForKey:
@"scan_class"];
706 [result removeObjectForKey:@"scanClass"];
709 if ([result oo_stringForKey:
@"escort_role"] !=
nil && [result oo_stringForKey:
@"escort-role"] !=
nil)
711 if ([child oo_stringForKey:
@"escort-role"] !=
nil)
712 [result removeObjectForKey:
@"escort_role"];
714 [result removeObjectForKey:@"escort-role"];
716 if ([result oo_stringForKey:
@"escort_ship"] !=
nil && [result oo_stringForKey:
@"escort-ship"] !=
nil)
718 if ([child oo_stringForKey:
@"escort-ship"] !=
nil)
719 [result removeObjectForKey:
@"escort_ship"];
721 [result removeObjectForKey:@"escort-ship"];
723 if ([result oo_stringForKey:
@"is_carrier"] !=
nil && [result oo_stringForKey:
@"isCarrier"] !=
nil)
725 if ([child oo_stringForKey:
@"isCarrier"] !=
nil)
726 [result removeObjectForKey:
@"is_carrier"];
728 [result removeObjectForKey:@"isCarrier"];
730 if ([result oo_stringForKey:
@"has_shipyard"] !=
nil && [result oo_stringForKey:
@"hasShipyard"] !=
nil)
732 if ([child oo_stringForKey:
@"hasShipyard"] !=
nil)
733 [result removeObjectForKey:
@"has_shipyard"];
735 [result removeObjectForKey:@"hasShipyard"];
741- (BOOL) makeShipEntriesMutable:(NSMutableDictionary *)ioData
743 NSString *shipKey =
nil;
744 NSDictionary *shipEntry =
nil;
746 foreach (shipKey, [ioData allKeys])
748 shipEntry = [ioData objectForKey:shipKey];
749 if (![shipEntry isKindOfClass:[NSDictionary class]])
751 OOLogERR(
@"shipData.load.badEntry",
@"the shipdata.plist entry \"%@\
" is not a dictionary.", shipKey);
752 [ioData removeObjectForKey:shipKey];
756 shipEntry = [shipEntry mutableCopy];
758 [ioData setObject:shipEntry forKey:shipKey];
767- (BOOL) loadAndApplyShipDataOverrides:(NSMutableDictionary *)ioData
769 NSString *shipKey =
nil;
770 NSMutableDictionary *shipEntry =
nil;
771 NSDictionary *overrides =
nil;
772 NSDictionary *overridesEntry =
nil;
781 shipEntry = [ioData objectForKey:shipKey];
782 if (shipEntry !=
nil)
784 overridesEntry = [overrides objectForKey:shipKey];
785 if (![overridesEntry isKindOfClass:[NSDictionary class]])
787 OOLogERR(
@"shipData.load.error",
@"the shipdata-overrides.plist entry \"%@\
" is not a dictionary.", shipKey);
791 [shipEntry addEntriesFromDictionary:overridesEntry];
800- (BOOL) stripPrivateKeys:(NSMutableDictionary *)ioData
802 NSString *shipKey =
nil;
803 NSMutableDictionary *shipEntry =
nil;
804 NSEnumerator *attrKeyEnum =
nil;
805 NSString *attrKey =
nil;
809 shipEntry = [ioData objectForKey:shipKey];
811 for (attrKeyEnum = [shipEntry keyEnumerator]; (attrKey = [attrKeyEnum nextObject]); )
813 if ([attrKey hasPrefix:
@"_oo_"])
815 [shipEntry removeObjectForKey:attrKey];
831- (BOOL) loadAndMergeShipyard:(NSMutableDictionary *)ioData
833 NSString *shipKey =
nil;
834 NSMutableDictionary *shipEntry =
nil;
835 NSDictionary *shipyard =
nil;
836 NSDictionary *shipyardOverrides =
nil;
837 NSDictionary *shipyardEntry =
nil;
838 NSDictionary *shipyardOverridesEntry =
nil;
839 NSMutableArray *playerShips =
nil;
844 shipEntry = [ioData objectForKey:shipKey];
845 if ([shipEntry objectForKey:
@"_oo_shipyard"] !=
nil)
847 [shipEntry removeObjectForKey:@"_oo_shipyard"];
860 playerShips = [NSMutableArray arrayWithCapacity:[shipyard count]];
865 shipEntry = [ioData objectForKey:shipKey];
866 if (shipEntry !=
nil)
868 shipyardEntry = [shipyard objectForKey:shipKey];
869 shipyardOverridesEntry = [shipyardOverrides objectForKey:shipKey];
870 shipyardEntry = [shipyardEntry dictionaryByAddingEntriesFromDictionary:shipyardOverridesEntry];
872 [shipEntry setObject:shipyardEntry forKey:@"_oo_shipyard"];
874 [playerShips addObject:shipKey];
878 OOLogWARN(
@"shipData.load.shipyard.unknown",
@"the shipyard.plist entry \"%@\
" does not have a corresponding shipdata.plist entry, ignoring.", shipKey);
882 _playerShips = [playerShips copy];
889- (BOOL) canonicalizeAndTagSubentities:(NSMutableDictionary *)ioData
891 NSString *shipKey =
nil;
892 NSMutableDictionary *shipEntry =
nil;
893 NSArray *subentityDeclarations =
nil;
894 id subentityDecl =
nil;
895 NSDictionary *subentityDict =
nil;
896 NSString *subentityKey =
nil;
897 NSMutableDictionary *subentityShipEntry =
nil;
898 NSMutableSet *badSubentities =
nil;
899 NSString *badSubentitiesList =
nil;
900 NSMutableArray *okSubentities =
nil;
907 foreach (shipKey, [ioData allKeys])
909 shipEntry = [ioData objectForKey:shipKey];
911 badSubentities =
nil;
914 subentityDeclarations = [shipEntry oo_arrayForKey:@"subentities"];
915 if (subentityDeclarations !=
nil)
917 okSubentities = [NSMutableArray arrayWithCapacity:[subentityDeclarations count]];
918 foreach (subentityDecl, subentityDeclarations)
920 subentityDict = [
self canonicalizeSubentityDeclaration:subentityDecl forShip:shipKey shipData:ioData fatalError:&fatal];
928 else if (subentityDict !=
nil)
930 [okSubentities addObject:subentityDict];
933 if (![[subentityDict oo_stringForKey:
@"type"] isEqualToString:
@"flasher"])
935 subentityKey = [subentityDict oo_stringForKey:@"subentity_key"];
936 subentityShipEntry = [ioData objectForKey:subentityKey];
937 if (subentityKey ==
nil || subentityShipEntry ==
nil)
940 if (badSubentities ==
nil) badSubentities = [NSMutableSet set];
941 [badSubentities addObject:subentityKey];
946 [subentityShipEntry oo_setBool:YES forKey:@"_oo_is_subentity"];
953 if ([okSubentities
count] != 0)
955 [shipEntry setObject:okSubentities forKey:@"subentities"];
959 [shipEntry removeObjectForKey:@"subentities"];
962 if (badSubentities !=
nil)
964 if (![shipEntry oo_boolForKey:
@"is_external_dependency"])
966 badSubentitiesList = [[[badSubentities allObjects] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] componentsJoinedByString:@", "];
967 OOLogERR(
@"shipData.load.error",
@"the shipdata.plist entry \"%@\
" has unresolved subentit%@ %@.", shipKey, ([badSubentities
count] == 1) ?
@"y" :
@"ies", badSubentitiesList);
976 [shipEntry oo_setBool:YES forKey:@"_oo_deferred_remove"];
985- (BOOL) removeUnusableEntries:(NSMutableDictionary *)ioData shipMode:(BOOL)shipMode
987 NSString *shipKey =
nil;
988 NSMutableDictionary *shipEntry =
nil;
990 NSString *modelName =
nil;
993 foreach (shipKey, [ioData allKeys])
995 shipEntry = [ioData objectForKey:shipKey];
998 if ([shipEntry oo_boolForKey:
@"is_template"] || [shipEntry oo_boolForKey:
@"_oo_deferred_remove"]) remove = YES;
999 else if (shipMode && [[shipEntry oo_stringForKey:
@"roles"] length] == 0 && ![shipEntry oo_boolForKey:
@"_oo_is_subentity"] && ![shipEntry oo_boolForKey:
@"_oo_is_effect"])
1001 OOLogERR(
@"shipData.load.error",
@"the shipdata.plist entry \"%@\
" specifies no %@.", shipKey,
@"roles");
1007 modelName = [shipEntry oo_stringForKey:@"model"];
1008 if (shipMode && [modelName length] == 0)
1010 OOLogERR(
@"shipData.load.error",
@"the shipdata.plist entry \"%@\
" specifies no %@.", shipKey,
@"model");
1014 else if ([modelName length] != 0 && [
ResourceManager pathForFileNamed:modelName inFolder:
@"Models"] ==
nil)
1016 OOLogERR(
@"shipData.load.error",
@"the shipdata.plist entry \"%@\
" specifies non-existent model \"%@\".", shipKey, modelName);
1021 if (
remove) [ioData removeObjectForKey:shipKey];
1032- (BOOL) sanitizeConditions:(NSMutableDictionary *)ioData
1034 NSString *shipKey =
nil;
1035 NSMutableDictionary *shipEntry =
nil;
1036 NSMutableDictionary *mutableShipyard =
nil;
1037 NSArray *conditions =
nil;
1038 NSArray *hasShipyard =
nil;
1039 NSArray *shipyardConditions =
nil;
1040 NSString *condition_script =
nil;
1041 NSString *shipyard_condition_script =
nil;
1043 NSMutableArray *conditionScripts = [[NSMutableArray alloc] init];
1045 foreach (shipKey, [ioData allKeys])
1047 shipEntry = [ioData objectForKey:shipKey];
1048 conditions = [shipEntry objectForKey:@"conditions"];
1049 condition_script = [shipEntry oo_stringForKey:@"condition_script"];
1050 if (condition_script !=
nil)
1052 if (![conditionScripts containsObject:condition_script])
1054 [conditionScripts addObject:condition_script];
1058 hasShipyard = [shipEntry objectForKey:@"has_shipyard"];
1059 if (![hasShipyard isKindOfClass:[NSArray class]]) hasShipyard =
nil;
1060 if (hasShipyard ==
nil)
1062 hasShipyard = [shipEntry objectForKey:@"hasShipyard"];
1063 if (![hasShipyard isKindOfClass:[NSArray class]]) hasShipyard =
nil;
1065 shipyardConditions = [[shipEntry oo_dictionaryForKey:@"_oo_shipyard"] objectForKey:@"conditions"];
1066 shipyard_condition_script = [[shipEntry oo_dictionaryForKey:@"_oo_shipyard"] oo_stringForKey:@"condition_script"];
1067 if (shipyard_condition_script !=
nil)
1069 if (![conditionScripts containsObject:shipyard_condition_script])
1071 [conditionScripts addObject:shipyard_condition_script];
1076 if (conditions ==
nil && hasShipyard && shipyardConditions ==
nil)
continue;
1078 if (conditions !=
nil)
1080 OOStandardsDeprecated([NSString stringWithFormat:
@"The 'conditions' key is deprecated in shipdata entry %@",shipKey]);
1083 if ([conditions isKindOfClass:[NSArray class]])
1089 OOLogWARN(
@"shipdata.load.warning",
@"conditions for shipdata.plist entry \"%@\
" are not an array, ignoring.", shipKey);
1093 if (conditions !=
nil)
1095 [shipEntry setObject:conditions forKey:@"conditions"];
1099 [shipEntry removeObjectForKey:@"conditions"];
1104 if (hasShipyard !=
nil)
1107 OOStandardsDeprecated([NSString stringWithFormat:
@"Use of legacy script conditions in the 'has_shipyard' key is deprecated in shipyard entry %@",shipKey]);
1110 if (hasShipyard !=
nil)
1112 [shipEntry setObject:hasShipyard forKey:@"has_shipyard"];
1116 [shipEntry removeObjectForKey:@"hasShipyard"];
1117 [shipEntry removeObjectForKey:@"has_shipyard"];
1122 if (shipyardConditions !=
nil)
1124 OOStandardsDeprecated([NSString stringWithFormat:
@"The 'conditions' key is deprecated in shipyard entry %@",shipKey]);
1127 mutableShipyard = [[[shipEntry oo_dictionaryForKey:@"_oo_shipyard"] mutableCopy] autorelease];
1129 if ([shipyardConditions isKindOfClass:[NSArray class]])
1135 OOLogWARN(
@"shipdata.load.warning",
@"conditions for shipyard.plist entry \"%@\
" are not an array, ignoring.", shipKey);
1136 shipyardConditions =
nil;
1139 if (shipyardConditions !=
nil)
1141 [mutableShipyard setObject:shipyardConditions forKey:@"conditions"];
1145 [mutableShipyard removeObjectForKey:@"conditions"];
1148 [shipEntry setObject:mutableShipyard forKey:@"_oo_shipyard"];
1154 [conditionScripts release];
1161- (BOOL) preloadShipMeshes:(NSMutableDictionary *)ioData
1163 NSEnumerator *shipKeyEnum =
nil;
1164 NSString *shipKey =
nil;
1165 NSMutableDictionary *shipEntry =
nil;
1167 NSString *modelName =
nil;
1169 NSAutoreleasePool *pool =
nil;
1170 NSUInteger i = 0,
count;
1172 count = [ioData count];
1175 for (shipKeyEnum = [[ioData allKeys] objectEnumerator]; (shipKey = [shipKeyEnum nextObject]); )
1177 pool = [[NSAutoreleasePool alloc] init];
1181 shipEntry = [ioData objectForKey:shipKey];
1184 modelName = [shipEntry oo_stringForKey:@"model"];
1185 mesh = [
OOMesh meshWithName:modelName
1186 materialDictionary:[shipEntry oo_dictionaryForKey:@"materials"]
1187 shadersDictionary:[shipEntry oo_dictionaryForKey:@"shaders"]
1188 smooth:[shipEntry oo_boolForKey:@"smooth"]
1190 shaderBindingTarget:nil];
1197 OOLogERR(
@"shipData.load.error",
@"model \"%@\
" could not be loaded for ship \"%@\", removing.", modelName, shipKey);
1198 [ioData removeObjectForKey:shipKey];
1209- (void) mergeShipRoles:(NSString *)roles
1210 forShipKey:(NSString *)shipKey
1211 intoProbabilityMap:(NSMutableDictionary *)probabilitySets
1213 NSDictionary *rolesAndWeights =
nil;
1214 NSString *role =
nil;
1228 NSMutableDictionary *
mutable = [NSMutableDictionary dictionaryWithDictionary:rolesAndWeights];
1229 [mutable setObject:[NSNumber numberWithFloat:1.0] forKey:[[[NSString alloc] initWithFormat:@"[%@]",shipKey] autorelease]];
1230 rolesAndWeights =
mutable;
1232 id thargonValue = [rolesAndWeights objectForKey:@"thargon"];
1233 if (thargonValue !=
nil && [rolesAndWeights objectForKey:
@"EQ_THARGON"] ==
nil)
1235 NSMutableDictionary *
mutable = [NSMutableDictionary dictionaryWithDictionary:rolesAndWeights];
1236 [mutable setObject:thargonValue forKey:@"EQ_THARGON"];
1237 rolesAndWeights =
mutable;
1242 probSet = [probabilitySets objectForKey:role];
1246 [probabilitySets setObject:probSet forKey:role];
1254- (NSDictionary *) canonicalizeSubentityDeclaration:(
id)declaration
1255 forShip:(NSString *)shipKey
1256 shipData:(NSDictionary *)shipData
1257 fatalError:(BOOL *)outFatalError
1259 NSDictionary *result =
nil;
1261 assert(outFatalError != NULL);
1262 *outFatalError = NO;
1264 if ([declaration isKindOfClass:[NSString class]])
1267 OOStandardsDeprecated([NSString stringWithFormat:
@"Old style sub-entity declarations are deprecated in %@",shipKey]);
1270 result = [
self translateOldStyleSubentityDeclaration:declaration
1273 fatalError:outFatalError];
1278 result = [
self validateNewStyleSubentityDeclaration:result
1280 fatalError:outFatalError];
1283 else if ([declaration isKindOfClass:[NSDictionary class]])
1286 result = [
self validateNewStyleSubentityDeclaration:declaration
1288 fatalError:outFatalError];
1292 OOLogERR(
@"shipData.load.error.badSubentity",
@"subentity declaration for ship %@ should be string or dictionary, found %@.", shipKey, [declaration
class]);
1293 *outFatalError = YES;
1297 if (*outFatalError && [[shipData oo_dictionaryForKey:shipKey] oo_boolForKey:
@"frangible"]) *outFatalError = NO;
1303- (NSDictionary *) translateOldStyleSubentityDeclaration:(NSString *)declaration
1304 forShip:(NSString *)shipKey
1305 shipData:(NSDictionary *)shipData
1306 fatalError:(BOOL *)outFatalError
1308 NSArray *tokens =
nil;
1309 NSString *subentityKey =
nil;
1314 subentityKey = [tokens objectAtIndex:0];
1315 isFlasher = [subentityKey isEqualToString:@"*FLASHER*"];
1318 if ([tokens
count] != 8)
1322 OOLogERR(
@"shipData.load.error.badSubentity",
@"the shipdata.plist entry \"%@\
" has a broken subentity definition \"%@\" (should have 8 tokens, has %llu).", shipKey, subentityKey, [tokens
count]);
1323 *outFatalError = YES;
1327 OOLogWARN(
@"shipData.load.warning.badFlasher",
@"the shipdata.plist entry \"%@\
" has a broken flasher definition (should have 8 tokens, has %llu). This flasher will be ignored.", shipKey, [tokens
count]);
1334 return [
self translateOldStyleFlasherDeclaration:tokens
1336 fatalError:outFatalError];
1340 return [
self translateOldStandardBasicSubentityDeclaration:tokens
1343 fatalError:outFatalError];
1348- (NSDictionary *) translateOldStyleFlasherDeclaration:(NSArray *)tokens
1349 forShip:(NSString *)shipKey
1350 fatalError:(BOOL *)outFatalError
1353 float size, frequency, phase, hue;
1354 NSDictionary *colorDict =
nil;
1355 NSDictionary *result =
nil;
1357 position.x = [tokens oo_floatAtIndex:1];
1358 position.y = [tokens oo_floatAtIndex:2];
1359 position.z = [tokens oo_floatAtIndex:3];
1361 hue = [tokens oo_floatAtIndex:4];
1362 frequency = [tokens oo_floatAtIndex:5];
1363 phase = [tokens oo_floatAtIndex:6];
1364 size = [tokens oo_floatAtIndex:7];
1366 colorDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:hue] forKey:@"hue"];
1368 result = [NSDictionary dictionaryWithObjectsAndKeys:
1369 @"flasher", @"type",
1370 OOPropertyListFromVector(position), @"position",
1371 [NSArray arrayWithObject:colorDict], @"colors",
1372 [NSNumber numberWithFloat:frequency], @"frequency",
1373 [NSNumber numberWithFloat:phase], @"phase",
1374 [NSNumber numberWithFloat:size], @"size",
1377 OOLog(
@"shipData.translateSubentity.flasher",
@"Translated flasher declaration \"%@\
" to %@", [tokens componentsJoinedByString:
@" "], result);
1383- (NSDictionary *) translateOldStandardBasicSubentityDeclaration:(NSArray *)tokens
1384 forShip:(NSString *)shipKey
1385 shipData:(NSDictionary *)shipData
1386 fatalError:(BOOL *)outFatalError
1388 NSString *subentityKey =
nil;
1390 Quaternion orientation;
1391 NSMutableDictionary *result =
nil;
1392 BOOL isTurret, isDock = NO;
1394 subentityKey = [tokens oo_stringAtIndex:0];
1396 isTurret = [
self shipIsBallTurretForKey:subentityKey inShipData:shipData];
1398 position.x = [tokens oo_floatAtIndex:1];
1399 position.y = [tokens oo_floatAtIndex:2];
1400 position.z = [tokens oo_floatAtIndex:3];
1402 orientation.w = [tokens oo_floatAtIndex:4];
1403 orientation.x = [tokens oo_floatAtIndex:5];
1404 orientation.y = [tokens oo_floatAtIndex:6];
1405 orientation.z = [tokens oo_floatAtIndex:7];
1407 if(orientation.w == 0 && orientation.x == 0 && orientation.y == 0 && orientation.z == 0)
1410 OOLogWARN(
@"shipData.load.error",
@"The ship %@ has an undefined orientation for its %@ subentity. Setting it now at (1,0,0,0)", shipKey, subentityKey);
1413 quaternion_normalize(&orientation);
1417 isDock = [subentityKey rangeOfString:@"dock"].location != NSNotFound;
1420 result = [NSMutableDictionary dictionaryWithCapacity:5];
1421 [result setObject:isTurret ? @"ball_turret" : @"standard" forKey:@"type"];
1422 [result setObject:subentityKey forKey:@"subentity_key"];
1423 [result oo_setVector:position forKey:@"position"];
1424 [result oo_setQuaternion:orientation forKey:@"orientation"];
1425 if (isDock) [result oo_setBool:YES forKey:@"is_dock"];
1427 OOLog(
@"shipData.translateSubentity.standard",
@"Translated subentity declaration \"%@\
" to %@", [tokens componentsJoinedByString:
@" "], result);
1429 return [[result copy] autorelease];
1433- (NSDictionary *) validateNewStyleSubentityDeclaration:(NSDictionary *)declaration
1434 forShip:(NSString *)shipKey
1435 fatalError:(BOOL *)outFatalError
1437 NSString *type =
nil;
1439 type = [declaration oo_stringForKey:@"type"];
1440 if (type ==
nil) type =
@"standard";
1442 if ([type isEqualToString:
@"flasher"])
1444 return [
self validateNewStyleFlasherDeclaration:declaration forShip:shipKey fatalError:outFatalError];
1446 else if ([type isEqualToString:
@"standard"] || [type isEqualToString:
@"ball_turret"])
1448 return [
self validateNewStyleStandardSubentityDeclaration:declaration forShip:shipKey fatalError:outFatalError];
1452 OOLogERR(
@"shipData.load.error.badSubentity",
@"subentity declaration for ship %@ does not declare a valid type (must be standard, flasher or ball_turret).", shipKey);
1453 *outFatalError = YES;
1459- (NSDictionary *) validateNewStyleFlasherDeclaration:(NSDictionary *)declaration
1460 forShip:(NSString *)shipKey
1461 fatalError:(BOOL *)outFatalError
1463 NSMutableDictionary *result =
nil;
1465 NSArray *colors =
nil;
1467 float size, frequency, phase, brightfraction;
1470#define kDefaultFlasherColor @"redColor"
1473 colors = [declaration oo_arrayForKey:@"colors"];
1474 if ([colors
count] == 0)
1476 colorDesc = [declaration objectForKey:@"color"];
1478 if ([colorDesc isKindOfClass:[NSArray class]])
1481 OOLogWARN(
@"shipData.load.warning.flasher.badColor",
@"changing flasher for ship %@ from a color to a colors definition.", shipKey);
1486 colors = [NSArray arrayWithObject:colorDesc];
1491 NSMutableArray *validColors = [NSMutableArray arrayWithCapacity:[colors count]];
1492 foreach (colorDesc, colors)
1501 OOLogWARN(
@"shipdata.load.warning.flasher.badColor",
@"skipping invalid colour specifier for flasher for ship %@.", shipKey);
1505 if ([validColors
count] == 0)
1507 [validColors addObject:kDefaultFlasherColor];
1509 colors = validColors;
1511 position = [declaration oo_vectorForKey:@"position"];
1513 size = [declaration oo_floatForKey:@"size" defaultValue:8.0];
1517 OOLogWARN(
@"shipData.load.warning.flasher.badSize",
@"skipping flasher of invalid size %g for ship %@.",
size, shipKey);
1521 brightfraction = [declaration oo_floatForKey:@"bright_fraction" defaultValue:0.5];
1522 if (brightfraction < 0.0 || brightfraction > 1.0)
1524 OOLogWARN(
@"shipData.load.warning.flasher.badFraction",
@"skipping flasher of invalid bright fraction %g for ship %@.", brightfraction, shipKey);
1528 frequency = [declaration oo_floatForKey:@"frequency" defaultValue:2.0];
1529 phase = [declaration oo_floatForKey:@"phase" defaultValue:0.0];
1530 initiallyOn = [declaration oo_boolForKey:@"initially_on" defaultValue:YES];
1532 result = [NSMutableDictionary dictionaryWithCapacity:8];
1533 [result setObject:@"flasher" forKey:@"type"];
1534 [result setObject:colors forKey:@"colors"];
1535 [result oo_setVector:position forKey:@"position"];
1536 [result setObject:[NSNumber numberWithFloat:size] forKey:@"size"];
1537 [result setObject:[NSNumber numberWithFloat:frequency] forKey:@"frequency"];
1538 if (phase != 0) [result setObject:[NSNumber numberWithFloat:phase] forKey:@"phase"];
1539 [result setObject:[NSNumber numberWithFloat:brightfraction] forKey:@"bright_fraction"];
1540 [result setObject:[NSNumber numberWithBool:initiallyOn] forKey:@"initially_on"];
1542 return [[result copy] autorelease];
1546- (NSDictionary *) validateNewStyleStandardSubentityDeclaration:(NSDictionary *)declaration
1547 forShip:(NSString *)shipKey
1548 fatalError:(BOOL *)outFatalError
1550 NSMutableDictionary *result =
nil;
1551 NSString *subentityKey =
nil;
1556 float fireRate = -1.0f;
1557 float weaponRange = -1.0f;
1558 float weaponEnergy = -1.0f;
1559 NSDictionary *scriptInfo =
nil;
1561 subentityKey = [declaration objectForKey:@"subentity_key"];
1562 if (subentityKey ==
nil)
1564 OOLogERR(
@"shipData.load.error.badSubentity",
@"subentity declaration for ship %@ specifies no subentity_key.", shipKey);
1565 *outFatalError = YES;
1569 isTurret = [[declaration oo_stringForKey:@"type"] isEqualToString:@"ball_turret"];
1572 fireRate = [declaration oo_floatForKey:@"fire_rate" defaultValue:-1.0f];
1573 if (fireRate < 0.25f && fireRate >= 0.0f)
1575 OOLogWARN(
@"shipData.load.warning.turret.badFireRate",
@"ball turret fire rate of %g for subentity of ship %@ is invalid, using 0.25.", fireRate, shipKey);
1578 weaponRange = [declaration oo_floatForKey:@"weapon_range" defaultValue:-1.0f];
1585 weaponEnergy = [declaration oo_floatForKey:@"weapon_energy" defaultValue:-1.0f];
1586 if (weaponEnergy > 100.0f)
1589 OOLogWARN(
@"shipData.load.warning.turret.badWeaponEnergy",
@"ball turret weapon energy of %g for subentity of ship %@ is too high, using 100.", weaponEnergy, shipKey);
1590 weaponEnergy = 100.0f;
1595 isDock = [declaration oo_boolForKey:@"is_dock"];
1598 position = [declaration oo_vectorForKey:@"position"];
1599 orientation = [declaration oo_quaternionForKey:@"orientation"];
1600 quaternion_normalize(&orientation);
1602 scriptInfo = [declaration oo_dictionaryForKey:@"script_info"];
1604 result = [NSMutableDictionary dictionaryWithCapacity:10];
1605 [result setObject:isTurret ? @"ball_turret" : @"standard" forKey:@"type"];
1606 [result setObject:subentityKey forKey:@"subentity_key"];
1607 [result oo_setVector:position forKey:@"position"];
1608 [result oo_setQuaternion:orientation forKey:@"orientation"];
1611 [result oo_setBool:YES forKey:@"is_dock"];
1613 NSString* docklabel = [declaration oo_stringForKey:@"dock_label" defaultValue:@"the docking bay"];
1614 [result setObject:docklabel forKey:@"dock_label"];
1616 BOOL dockable = [declaration oo_boolForKey:@"allow_docking" defaultValue:YES];
1617 BOOL playerdockable = [declaration oo_boolForKey:@"disallowed_docking_collides" defaultValue:NO];
1618 BOOL undockable = [declaration oo_boolForKey:@"allow_launching" defaultValue:YES];
1620 [result oo_setBool:dockable forKey:@"allow_docking"];
1621 [result oo_setBool:playerdockable forKey:@"disallowed_docking_collides"];
1622 [result oo_setBool:undockable forKey:@"allow_launching"];
1629 if (fireRate > 0) [result oo_setFloat:fireRate forKey:@"fire_rate"];
1630 if (weaponRange >= 0) [result oo_setFloat:weaponRange forKey:@"weapon_range"];
1631 if (weaponEnergy >= 0) [result oo_setFloat:weaponEnergy forKey:@"weapon_energy"];
1634 if (scriptInfo !=
nil)
1636 [result setObject:scriptInfo forKey:@"script_info"];
1639 return [[result copy] autorelease];
1643- (BOOL) shipIsBallTurretForKey:(NSString *)shipKey inShipData:(NSDictionary *)shipData
1646 NSArray *setupActions =
nil;
1647 NSString *action =
nil;
1649 setupActions = [[shipData oo_dictionaryForKey:shipKey] oo_arrayForKey:@"setup_actions"];
1651 foreach (action, setupActions)
1653 if ([[
ScanTokensFromString(action) objectAtIndex:0] isEqualToString:
@"initialiseTurret"]) return YES;
1656 if ([shipKey isEqualToString:
@"ballturret"])
1669@implementation OOShipRegistry (Singleton)
1678+ (id) allocWithZone:(NSZone *)inZone
1682 OOLog(
@"shipData.load.begin",
@"%@",
@"Loading ship data.");
1690- (id) copyWithZone:(NSZone *)inZone
1722static void GatherStringAddrs(
id object, NSMutableSet *strings, NSString *context);
1728 static FILE *dump = NULL;
1729 if (dump == NULL) dump = fopen(
"strings.txt",
"w");
1730 if (dump == NULL)
return;
1732 NSAutoreleasePool *pool = [NSAutoreleasePool new];
1733 NSMutableSet *strings = [NSMutableSet set];
1736 NSDictionary *entry =
nil;
1737 foreach (entry, strings)
1739 NSString *
string = [entry objectForKey:@"string"];
1740 NSString *context = [entry objectForKey:@"context"];
1741 void *pointer = [[entry objectForKey:@"address"] pointerValue];
1743 string = [NSString stringWithFormat:@"%p\t%@: \"%@\"", pointer, context, string];
1745 fprintf(dump,
"%s\n", [
string UTF8String]);
1748 fprintf(dump,
"\n");
1757 NSString *keyContext = [context stringByAppendingString:@" key"];
1761 GatherStringAddrs([dict objectForKey:key], strings, [context stringByAppendingFormat:@".%@", key]);
1779 if ([
object isKindOfClass:[NSString class]])
1781 NSDictionary *entry = [NSDictionary dictionaryWithObjectsAndKeys:object, @"string", [NSValue valueWithPointer:object], @"address", context, @"context", nil];
1782 [strings addObject:entry];
1784 else if ([
object isKindOfClass:[NSArray class]])
1788 else if ([
object isKindOfClass:[NSDictionary class]])
1797 return [[a oo_stringForKey:@"name"] compare:[b oo_stringForKey:@"name"]];
1803 return [OOShipLibraryCategoryPlural([[a oo_dictionaryAtIndex:0] oo_stringForKey:@"class"]) compare:OOShipLibraryCategoryPlural([[b oo_dictionaryAtIndex:0] oo_stringForKey:@"class"])];
#define foreachkey(VAR, DICT)
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)