Oolite
Loading...
Searching...
No Matches
OOShipRegistry Class Reference

#include <OOShipRegistry.h>

+ Inheritance diagram for OOShipRegistry:
+ Collaboration diagram for OOShipRegistry:

Instance Methods

(NSDictionary *) - shipInfoForKey:
 
(void) - setShipInfoForKey:with:
 
(NSDictionary *) - effectInfoForKey:
 
(NSDictionary *) - shipyardInfoForKey:
 
(OOProbabilitySet *) - probabilitySetForRole:
 
(NSArray *) - demoShipKeys
 
(NSArray *) - playerShipKeys
 
(id) - init [implementation]
 
(void) - dealloc [implementation]
 
(NSArray *) - shipKeys
 
(NSArray *) - shipRoles
 
(NSArray *) - shipKeysWithRole:
 
(NSString *) - randomShipKeyForRole:
 
(void) - loadShipData [implementation]
 
(void) - loadDemoShipConditions [implementation]
 
(void) - loadDemoShips [implementation]
 
(void) - loadCachedRoleProbabilitySets [implementation]
 
(void) - buildRoleProbabilitySets [implementation]
 
(BOOL) - applyLikeShips:withKey: [implementation]
 
(BOOL) - loadAndMergeShipyard: [implementation]
 
(BOOL) - stripPrivateKeys: [implementation]
 
(BOOL) - makeShipEntriesMutable: [implementation]
 
(BOOL) - loadAndApplyShipDataOverrides: [implementation]
 
(BOOL) - canonicalizeAndTagSubentities: [implementation]
 
(BOOL) - removeUnusableEntries:shipMode: [implementation]
 
(BOOL) - sanitizeConditions: [implementation]
 
(NSMutableDictionary *) - mergeShip:withParent: [implementation]
 
(void) - mergeShipRoles:forShipKey:intoProbabilityMap: [implementation]
 
(NSDictionary *) - canonicalizeSubentityDeclaration:forShip:shipData:fatalError: [implementation]
 
(NSDictionary *) - translateOldStyleSubentityDeclaration:forShip:shipData:fatalError: [implementation]
 
(NSDictionary *) - translateOldStyleFlasherDeclaration:forShip:fatalError: [implementation]
 
(NSDictionary *) - translateOldStandardBasicSubentityDeclaration:forShip:shipData:fatalError: [implementation]
 
(NSDictionary *) - validateNewStyleSubentityDeclaration:forShip:fatalError: [implementation]
 
(NSDictionary *) - validateNewStyleFlasherDeclaration:forShip:fatalError: [implementation]
 
(NSDictionary *) - validateNewStyleStandardSubentityDeclaration:forShip:fatalError: [implementation]
 
(BOOL) - shipIsBallTurretForKey:inShipData: [implementation]
 
(id) - copyWithZone: [implementation]
 
(id) - retain [implementation]
 
(NSUInteger) - retainCount [implementation]
 
(void) - release [implementation]
 
(id) - autorelease [implementation]
 

Class Methods

(OOShipRegistry *) + sharedRegistry
 
(void) + reload
 
(id) + allocWithZone: [implementation]
 

Private Attributes

NSDictionary * _shipData
 
NSDictionary * _effectData
 
NSArray * _demoShips
 
NSArray * _playerShips
 
NSDictionary * _probabilitySets
 

Detailed Description

Definition at line 35 of file OOShipRegistry.h.

Method Documentation

◆ allocWithZone:

+ (id) allocWithZone: (NSZone *)  inZone
implementation

Provided by category OOShipRegistry(Singleton).

Definition at line 1801 of file OOShipRegistry.m.

1678 :(NSZone *)inZone
1679{
1680 if (sSingleton == nil)
1681 {
1682 OOLog(@"shipData.load.begin", @"%@", @"Loading ship data.");
1683 sSingleton = [super allocWithZone:inZone];
1684 return sSingleton;
1685 }
1686 return nil;
1687}
static OODebugMonitor * sSingleton
#define OOLog(class, format,...)
Definition OOLogging.h:88
return nil

◆ applyLikeShips:withKey:

- (BOOL) applyLikeShips: (NSMutableDictionary *)  ioData
withKey: (NSString *)  likeKey 
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

610 :(NSMutableDictionary *)ioData withKey:(NSString *)likeKey
611{
612 NSMutableSet *remainingLikeShips = nil;
613 NSString *key = nil;
614 NSString *parentKey = nil;
615 NSDictionary *shipEntry = nil;
616 NSDictionary *parentEntry = nil;
617 NSUInteger count, lastCount;
618 NSMutableArray *reportedBadShips = nil;
619
620 // Build set of ships with like_ship references
621 remainingLikeShips = [NSMutableSet set];
622 foreachkey (key, ioData)
623 {
624 shipEntry = [ioData objectForKey:key];
625 if ([shipEntry oo_stringForKey:likeKey] != nil)
626 {
627 [remainingLikeShips addObject:key];
628 }
629 }
630
631 count = lastCount = [remainingLikeShips count];
632 while (count != 0)
633 {
634 foreach (key, [[remainingLikeShips copy] autorelease])
635 {
636 // Look up like_ship entry
637 shipEntry = [ioData objectForKey:key];
638 parentKey = [shipEntry objectForKey:likeKey];
639 if (![remainingLikeShips containsObject:parentKey])
640 {
641 // If parent is fully resolved, we can resolve this child.
642 parentEntry = [ioData objectForKey:parentKey];
643 shipEntry = [self mergeShip:shipEntry withParent:parentEntry];
644 if (shipEntry != nil)
645 {
646 [remainingLikeShips removeObject:key];
647 [ioData setObject:shipEntry forKey:key];
648 }
649 }
650 }
651
652 count = [remainingLikeShips count];
653 if (count == lastCount)
654 {
655 /* Fail: we couldn't resolve all like_ship entries.
656 Remove unresolved entries, building a list of the ones that
657 don't have is_external_dependency set.
658 */
659 reportedBadShips = [NSMutableArray array];
660 foreach (key, remainingLikeShips)
661 {
662 if (![[ioData oo_dictionaryForKey:key] oo_boolForKey:@"is_external_dependency"])
663 {
664 [reportedBadShips addObject:key];
665 }
666 [ioData removeObjectForKey:key];
667 }
668
669 if ([reportedBadShips count] != 0)
670 {
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:@", "]); // FIXME: distinguish shipdata and effectdata
673 OOStandardsError(@"Likely missing a dependency in a manifest.plist");
674 }
675 break;
676 }
677 lastCount = count;
678 }
679
680 return YES;
681}
#define foreachkey(VAR, DICT)
Definition OOCocoa.h:353
void OOStandardsError(NSString *message)
#define OOLogERR(class, format,...)
Definition OOLogging.h:112
unsigned count

◆ autorelease

- (id) autorelease
implementation

Provided by category OOShipRegistry(Singleton).

Definition at line 1801 of file OOShipRegistry.m.

1713{
1714 return self;
1715}

◆ buildRoleProbabilitySets

- (void) buildRoleProbabilitySets
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

561{
562 NSMutableDictionary *probabilitySets = nil;
563 NSString *shipKey = nil;
564 NSDictionary *shipEntry = nil;
565 NSString *roles = nil;
566 NSString *role = nil;
567 OOProbabilitySet *pset = nil;
568 NSMutableDictionary *cacheEntry = nil;
569
570 probabilitySets = [NSMutableDictionary dictionary];
571
572 // Build role sets
573 foreachkey (shipKey, _shipData)
574 {
575 shipEntry = [_shipData objectForKey:shipKey];
576 roles = [shipEntry oo_stringForKey:@"roles"];
577 [self mergeShipRoles:roles forShipKey:shipKey intoProbabilityMap:probabilitySets];
578 }
579
580 // Convert role sets to immutable form, and build cache entry.
581 // Note: we iterate over a copy of the keys to avoid mutating while iterating.
582 cacheEntry = [NSMutableDictionary dictionaryWithCapacity:[probabilitySets count]];
583 foreach (role, [probabilitySets allKeys])
584 {
585 pset = [probabilitySets objectForKey:role];
586 pset = [[pset copy] autorelease];
587 [probabilitySets setObject:pset forKey:role];
588 [cacheEntry setObject:[pset propertyListRepresentation] forKey:role];
589 }
590
591 _probabilitySets = [probabilitySets copy];
592 [[OOCacheManager sharedCache] setObject:cacheEntry forKey:kRoleWeightsCacheKey inCache:kShipRegistryCacheName];
593}
void setObject:forKey:inCache:(id inElement,[forKey] NSString *inKey,[inCache] NSString *inCacheKey)
OOCacheManager * sharedCache()
NSDictionary * propertyListRepresentation()

◆ canonicalizeAndTagSubentities:

- (BOOL) canonicalizeAndTagSubentities: (NSMutableDictionary *)  ioData
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

889 :(NSMutableDictionary *)ioData
890{
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;
901 BOOL remove, fatal;
902
903 // Convert all subentity declarations to dictionaries and add
904 // _oo_is_subentity=YES to all entries used as subentities.
905
906 // Iterate over all ships. (Iterates over a copy of keys since it mutates the dictionary.)
907 foreach (shipKey, [ioData allKeys])
908 {
909 shipEntry = [ioData objectForKey:shipKey];
910 remove = NO;
911 badSubentities = nil;
912
913 // Iterate over each subentity declaration of each ship
914 subentityDeclarations = [shipEntry oo_arrayForKey:@"subentities"];
915 if (subentityDeclarations != nil)
916 {
917 okSubentities = [NSMutableArray arrayWithCapacity:[subentityDeclarations count]];
918 foreach (subentityDecl, subentityDeclarations)
919 {
920 subentityDict = [self canonicalizeSubentityDeclaration:subentityDecl forShip:shipKey shipData:ioData fatalError:&fatal];
921
922 // If entry is broken, we need to kill this ship.
923 if (fatal)
924 {
925 OOStandardsError(@"Bad subentity definition found");
926 remove = YES;
927 }
928 else if (subentityDict != nil)
929 {
930 [okSubentities addObject:subentityDict];
931
932 // Tag subentities.
933 if (![[subentityDict oo_stringForKey:@"type"] isEqualToString:@"flasher"])
934 {
935 subentityKey = [subentityDict oo_stringForKey:@"subentity_key"];
936 subentityShipEntry = [ioData objectForKey:subentityKey];
937 if (subentityKey == nil || subentityShipEntry == nil)
938 {
939 // Oops, reference to non-existent subent.
940 if (badSubentities == nil) badSubentities = [NSMutableSet set];
941 [badSubentities addObject:subentityKey];
942 }
943 else
944 {
945 // Subent exists, add _oo_is_subentity so roles aren't required.
946 [subentityShipEntry oo_setBool:YES forKey:@"_oo_is_subentity"];
947 }
948 }
949 }
950 }
951
952 // Set updated subentity list.
953 if ([okSubentities count] != 0)
954 {
955 [shipEntry setObject:okSubentities forKey:@"subentities"];
956 }
957 else
958 {
959 [shipEntry removeObjectForKey:@"subentities"];
960 }
961
962 if (badSubentities != nil)
963 {
964 if (![shipEntry oo_boolForKey:@"is_external_dependency"])
965 {
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);
968 OOStandardsError(@"Bad subentity definition found");
969 }
970 remove = YES;
971 }
972
973 if (remove)
974 {
975 // Removal is deferred to avoid bogus "entry doesn't exist" errors.
976 [shipEntry oo_setBool:YES forKey:@"_oo_deferred_remove"];
977 }
978 }
979 }
980
981 return YES;
982}

◆ canonicalizeSubentityDeclaration:forShip:shipData:fatalError:

- (NSDictionary *) canonicalizeSubentityDeclaration: (id)  declaration
forShip: (NSString *)  shipKey
shipData: (NSDictionary *)  shipData
fatalError: (BOOL *)  outFatalError 
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

1254 :(id)declaration
1255 forShip:(NSString *)shipKey
1256 shipData:(NSDictionary *)shipData
1257 fatalError:(BOOL *)outFatalError
1258{
1259 NSDictionary *result = nil;
1260
1261 assert(outFatalError != NULL);
1262 *outFatalError = NO;
1263
1264 if ([declaration isKindOfClass:[NSString class]])
1265 {
1266 // Update old-style string-based declaration.
1267 OOStandardsDeprecated([NSString stringWithFormat:@"Old style sub-entity declarations are deprecated in %@",shipKey]);
1268 if (!OOEnforceStandards())
1269 {
1270 result = [self translateOldStyleSubentityDeclaration:declaration
1271 forShip:shipKey
1272 shipData:shipData
1273 fatalError:outFatalError];
1274 }
1275 if (result != nil)
1276 {
1277 // Ensure internal translation made sense, and clean up a bit.
1278 result = [self validateNewStyleSubentityDeclaration:result
1279 forShip:shipKey
1280 fatalError:outFatalError];
1281 }
1282 }
1283 else if ([declaration isKindOfClass:[NSDictionary class]])
1284 {
1285 // Validate dictionary-based declaration.
1286 result = [self validateNewStyleSubentityDeclaration:declaration
1287 forShip:shipKey
1288 fatalError:outFatalError];
1289 }
1290 else
1291 {
1292 OOLogERR(@"shipData.load.error.badSubentity", @"subentity declaration for ship %@ should be string or dictionary, found %@.", shipKey, [declaration class]);
1293 *outFatalError = YES;
1294 }
1295
1296 // For frangible ships, bad subentities are non-fatal.
1297 if (*outFatalError && [[shipData oo_dictionaryForKey:shipKey] oo_boolForKey:@"frangible"]) *outFatalError = NO;
1298
1299 return result;
1300}
void OOStandardsDeprecated(NSString *message)
BOOL OOEnforceStandards(void)

◆ copyWithZone:

- (id) copyWithZone: (NSZone *)  inZone
implementation

Provided by category OOShipRegistry(Singleton).

Definition at line 1801 of file OOShipRegistry.m.

1690 :(NSZone *)inZone
1691{
1692 return self;
1693}

◆ dealloc

- (void) dealloc
implementation

Definition at line 1801 of file OOShipRegistry.m.

197{
198 [_shipData release];
199 [_demoShips release];
200 [_playerShips release];
201 [_probabilitySets release];
202
203 [super dealloc];
204}

◆ demoShipKeys

- (NSArray *) demoShipKeys

Definition at line 1801 of file OOShipRegistry.m.

242{
243 // with condition scripts in use, can't cache this value
244 [self loadDemoShips];
245
246 return [[_demoShips copy] autorelease];
247}

◆ effectInfoForKey:

- (NSDictionary *) effectInfoForKey: (NSString *)  key

Definition at line 1801 of file OOShipRegistry.m.

222 :(NSString *)key
223{
224 return [_effectData objectForKey:key];
225}

◆ init

- (id) init
implementation

Definition at line 1801 of file OOShipRegistry.m.

151{
152 if ((self = [super init]))
153 {
154 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
156
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) // Don't accept nil or empty
161 {
162 [self loadShipData];
163 if ([_shipData count] == 0)
164 {
165 [NSException raise:@"OOShipRegistryLoadFailure" format:@"Could not load any ship data."];
166 }
167 if ([_playerShips count] == 0)
168 {
169 [NSException raise:@"OOShipRegistryLoadFailure" format:@"Could not load any player ships."];
170 }
171 }
172
173 [self loadDemoShipConditions];
174 [self loadDemoShips]; // testing only
175 if ([_demoShips count] == 0)
176 {
177 [NSException raise:@"OOShipRegistryLoadFailure" format:@"Could not load or synthesize any demo ships."];
178 }
179
180 [self loadCachedRoleProbabilitySets];
181 if (_probabilitySets == nil)
182 {
183 [self buildRoleProbabilitySets];
184 if ([_probabilitySets count] == 0)
185 {
186 [NSException raise:@"OOShipRegistryLoadFailure" format:@"Could not load or synthesize role probability sets."];
187 }
188 }
189
190 [pool release];
191 }
192 return self;
193}
id objectForKey:inCache:(NSString *inKey,[inCache] NSString *inCacheKey)
NSArray * _demoShips
NSDictionary * _probabilitySets
NSArray * _playerShips
NSDictionary * _effectData
NSDictionary * _shipData

◆ loadAndApplyShipDataOverrides:

- (BOOL) loadAndApplyShipDataOverrides: (NSMutableDictionary *)  ioData
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

767 :(NSMutableDictionary *)ioData
768{
769 NSString *shipKey = nil;
770 NSMutableDictionary *shipEntry = nil;
771 NSDictionary *overrides = nil;
772 NSDictionary *overridesEntry = nil;
773
774 overrides = [ResourceManager dictionaryFromFilesNamed:@"shipdata-overrides.plist"
775 inFolder:@"Config"
776 mergeMode:MERGE_SMART
777 cache:NO];
778
779 foreachkey (shipKey, overrides)
780 {
781 shipEntry = [ioData objectForKey:shipKey];
782 if (shipEntry != nil)
783 {
784 overridesEntry = [overrides objectForKey:shipKey];
785 if (![overridesEntry isKindOfClass:[NSDictionary class]])
786 {
787 OOLogERR(@"shipData.load.error", @"the shipdata-overrides.plist entry \"%@\" is not a dictionary.", shipKey);
788 }
789 else
790 {
791 [shipEntry addEntriesFromDictionary:overridesEntry];
792 }
793 }
794 }
795
796 return YES;
797}
NSDictionary * dictionaryFromFilesNamed:inFolder:mergeMode:cache:(NSString *fileName,[inFolder] NSString *folderName,[mergeMode] OOResourceMergeMode mergeMode,[cache] BOOL useCache)

◆ loadAndMergeShipyard:

- (BOOL) loadAndMergeShipyard: (NSMutableDictionary *)  ioData
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

831 :(NSMutableDictionary *)ioData
832{
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;
840
841 // Strip out any shipyard stuff in shipdata (there shouldn't be any).
842 foreachkey (shipKey, ioData)
843 {
844 shipEntry = [ioData objectForKey:shipKey];
845 if ([shipEntry objectForKey:@"_oo_shipyard"] != nil)
846 {
847 [shipEntry removeObjectForKey:@"_oo_shipyard"];
848 }
849 }
850
851 shipyard = [ResourceManager dictionaryFromFilesNamed:@"shipyard.plist"
852 inFolder:@"Config"
853 mergeMode:MERGE_BASIC
854 cache:NO];
855 shipyardOverrides = [ResourceManager dictionaryFromFilesNamed:@"shipyard-overrides.plist"
856 inFolder:@"Config"
857 mergeMode:MERGE_SMART
858 cache:NO];
859
860 playerShips = [NSMutableArray arrayWithCapacity:[shipyard count]];
861
862 // Insert merged shipyard and shipyardOverrides entries.
863 foreachkey (shipKey, shipyard)
864 {
865 shipEntry = [ioData objectForKey:shipKey];
866 if (shipEntry != nil)
867 {
868 shipyardEntry = [shipyard objectForKey:shipKey];
869 shipyardOverridesEntry = [shipyardOverrides objectForKey:shipKey];
870 shipyardEntry = [shipyardEntry dictionaryByAddingEntriesFromDictionary:shipyardOverridesEntry];
871
872 [shipEntry setObject:shipyardEntry forKey:@"_oo_shipyard"];
873
874 [playerShips addObject:shipKey];
875 }
876 else
877 {
878 OOLogWARN(@"shipData.load.shipyard.unknown", @"the shipyard.plist entry \"%@\" does not have a corresponding shipdata.plist entry, ignoring.", shipKey);
879 }
880 }
881
882 _playerShips = [playerShips copy];
883 [[OOCacheManager sharedCache] setObject:_playerShips forKey:kPlayerShipsCacheKey inCache:kShipRegistryCacheName];
884
885 return YES;
886}
#define OOLogWARN(class, format,...)
Definition OOLogging.h:113

◆ loadCachedRoleProbabilitySets

- (void) loadCachedRoleProbabilitySets
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

542{
543 NSDictionary *cachedSets = nil;
544 NSMutableDictionary *restoredSets = nil;
545 NSString *role = nil;
546
547 cachedSets = [[OOCacheManager sharedCache] objectForKey:kRoleWeightsCacheKey inCache:kShipRegistryCacheName];
548 if (cachedSets == nil) return;
549
550 restoredSets = [NSMutableDictionary dictionaryWithCapacity:[cachedSets count]];
551 foreachkey (role, cachedSets)
552 {
553 [restoredSets setObject:[OOProbabilitySet probabilitySetWithPropertyListRepresentation:[cachedSets objectForKey:role]] forKey:role];
554 }
555
556 _probabilitySets = [restoredSets copy];
557}
void setObject:forKey:(id value,[forKey] id key)
Definition OOCache.m:275
id probabilitySetWithPropertyListRepresentation:(NSDictionary *plist)

◆ loadDemoShipConditions

- (void) loadDemoShipConditions
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

394{
395 NSMutableArray *conditionScripts = [[NSMutableArray alloc] init];
396 NSDictionary *key = nil;
397 NSArray *initialDemoShips = nil;
398
399 initialDemoShips = [ResourceManager arrayFromFilesNamed:@"shiplibrary.plist"
400 inFolder:@"Config"
401 andMerge:YES
402 cache:NO];
403
404 foreach (key, initialDemoShips)
405 {
406 NSString *conditions = [key oo_stringForKey:kOODemoShipConditions defaultValue:nil];
407 if (conditions != nil)
408 {
409 [conditionScripts addObject:conditions];
410 }
411 }
412
413 [[OOCacheManager sharedCache] setObject:conditionScripts forKey:@"demoship conditions" inCache:@"condition scripts"];
414 [conditionScripts release];
415}
NSArray * arrayFromFilesNamed:inFolder:andMerge:cache:(NSString *fileName,[inFolder] NSString *folderName,[andMerge] BOOL mergeFiles,[cache] BOOL useCache)

◆ loadDemoShips

- (void) loadDemoShips
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

425{
426 NSDictionary *key = nil;
427 NSArray *initialDemoShips = nil;
428 NSMutableArray *demoShips = nil;
429
430 DESTROY(_demoShips);
431
432 initialDemoShips = [ResourceManager arrayFromFilesNamed:@"shiplibrary.plist"
433 inFolder:@"Config"
434 andMerge:YES
435 cache:NO];
436 demoShips = [NSMutableArray arrayWithArray:initialDemoShips];
437
438 // Note: iterate over initialDemoShips to avoid mutating the collection being enu,erated.
439 foreach (key, initialDemoShips)
440 {
441 NSString *shipKey = [key oo_stringForKey:kOODemoShipKey];
442 if (![key isKindOfClass:[NSDictionary class]] || [self shipInfoForKey:shipKey] == nil)
443 {
444 [demoShips removeObject:key];
445 }
446 else
447 {
448 NSString *conditions = [key oo_stringForKey:kOODemoShipConditions defaultValue:nil];
449 if (conditions != nil)
450 {
451 if ([PLAYER status] == STATUS_START_GAME)
452 {
453 // conditions always false here
454 [demoShips removeObject:key];
455 }
456 else
457 {
458 OOJSScript *condScript = [UNIVERSE getConditionScript:conditions];
459 if (condScript != nil) // should always be non-nil, but just in case
460 {
461 JSContext *context = OOJSAcquireContext();
462 BOOL OK;
463 JSBool allow_use;
464 jsval result;
465 jsval args[] = { OOJSValueFromNativeObject(context, shipKey) };
466
467 OK = [condScript callMethod:OOJSID("allowShowLibraryShip")
468 inContext:context
469 withArguments:args count:sizeof args / sizeof *args
470 result:&result];
471
472 if (OK) OK = JS_ValueToBoolean(context, result, &allow_use);
473
474 OOJSRelinquishContext(context);
475 if (OK && !allow_use)
476 {
477 /* if the script exists, the function exists, the function
478 * returns a bool, and that bool is false, hide the
479 * ship. Otherwise allow it as default */
480 [demoShips removeObject:key];
481 }
482 }
483 }
484 }
485 }
486 }
487
488 if ([demoShips count] == 0)
489 {
490 NSString *shipKey = nil;
491 if ([self shipInfoForKey:kDefaultDemoShip] != nil)
492 {
493 shipKey = kDefaultDemoShip;
494 }
495 else
496 {
497 shipKey = [[_shipData allKeys] objectAtIndex:0];
498 }
499 [demoShips addObject:[NSDictionary dictionaryWithObject:shipKey forKey:kOODemoShipKey]];
500 }
501
502 // now separate out the demoships by class, and add some extra keys
503 NSMutableDictionary *demoList = [NSMutableDictionary dictionaryWithCapacity:8];
504 NSMutableArray *demoClass = nil;
505 foreach (key, demoShips)
506 {
507 NSString *class = [key oo_stringForKey:kOODemoShipClass defaultValue:@"ship"];
508 if ([OOShipLibraryCategoryPlural(class) length] == 0)
509 {
510 OOLog(@"shipdata.load.warning",@"Unexpected class '%@' in shiplibrary.plist for '%@'",class,[key oo_stringForKey:kOODemoShipKey]);
511 class = @"ship";
512 }
513 demoClass = [demoList objectForKey:class];
514 if (demoClass == nil)
515 {
516 [demoList setObject:[NSMutableArray array] forKey:class];
517 demoClass = [demoList objectForKey:class];
518 }
519 NSMutableDictionary *demoEntry = [NSMutableDictionary dictionaryWithDictionary:key];
520 // add "name" object to dictionary from ship definition
521 [demoEntry setObject:[[self shipInfoForKey:[demoEntry oo_stringForKey:@"ship"]] oo_stringForKey:kOODemoShipName] forKey:kOODemoShipName];
522 // set "class" object to standard ship if not otherwise set
523 if (![[demoEntry oo_stringForKey:kOODemoShipClass defaultValue:nil] isEqualToString:class])
524 {
525 [demoEntry setObject:class forKey:kOODemoShipClass];
526 }
527 [demoClass addObject:demoEntry];
528 }
529 // sort each ship list by name
530 NSString *demoClassName = nil;
531 foreach (demoClassName, demoList)
532 {
533 [[demoList objectForKey:demoClassName] sortUsingFunction:SortDemoShipsByName context:NULL];
534 }
535
536 // and then sort the ship list list by class name
537 _demoShips = [[[demoList allValues] sortedArrayUsingFunction:SortDemoCategoriesByName context:NULL] retain];
538}
#define DESTROY(x)
Definition OOCocoa.h:75
OOINLINE jsval OOJSValueFromNativeObject(JSContext *context, id object)
OOINLINE JSContext * OOJSAcquireContext(void)
OOINLINE void OOJSRelinquishContext(JSContext *context)
return self
static NSString *const kOODemoShipClass
static NSString *const kOODemoShipKey
static NSString *const kDefaultDemoShip
#define PLAYER
BOOL callMethod:inContext:withArguments:count:result:(jsid methodID,[inContext] JSContext *context,[withArguments] jsval *argv,[count] intN argc,[result] jsval *outResult)
Definition OOJSScript.m:394

◆ loadShipData

- (void) loadShipData
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

297{
298 NSMutableDictionary *result = nil;
299
300 [_shipData release];
301 _shipData = nil;
302 [_playerShips release];
303 _playerShips = nil;
304
305 // Load shipdata.plist.
306 result = [[[ResourceManager dictionaryFromFilesNamed:@"shipdata.plist"
307 inFolder:@"Config"
308 mergeMode:MERGE_BASIC
309 cache:NO] mutableCopy] autorelease];
310 if (result == nil) return;
311
312 DumpStringAddrs(result, @"shipdata.plist");
313
314 // Make each entry mutable to simplify later stages. Also removes any entries that aren't dictionaries.
315 if (![self makeShipEntriesMutable:result]) return;
316 OOLog(@"shipData.load.progress", @"%@", @"Finished initial cleanup...");
317
318 // Apply patches.
319 if (![self loadAndApplyShipDataOverrides:result]) return;
320 OOLog(@"shipData.load.progress", @"%@", @"Finished applying patches...");
321
322 // Strip private keys (anything starting with _oo_).
323 if (![self stripPrivateKeys:result]) return;
324 OOLog(@"shipData.load.progress", @"%@", @"Finished stripping private keys...");
325
326 // Resolve like_ship entries.
327 if (![self applyLikeShips:result withKey:@"like_ship"]) return;
328 OOLog(@"shipData.load.progress", @"%@", @"Finished resolving like_ships...");
329
330 // Clean up subentity declarations and tag subentities so they won't be pruned.
331 if (![self canonicalizeAndTagSubentities:result]) return;
332 OOLog(@"shipData.load.progress", @"%@", @"Finished cleaning up subentities...");
333
334 // Clean out templates and invalid entries.
335 if (![self removeUnusableEntries:result shipMode:YES]) return;
336 OOLog(@"shipData.load.progress", @"%@", @"Finished removing invalid entries...");
337
338 // Add shipyard entries into shipdata entries.
339 if (![self loadAndMergeShipyard:result]) return;
340 OOLog(@"shipData.load.progress", @"%@", @"Finished adding shipyard entries...");
341
342 // Sanitize conditions.
343 if (![self sanitizeConditions:result]) return;
344 OOLog(@"shipData.load.progress", @"%@", @"Finished validating data...");
345
346#if PRELOAD
347 // Preload and cache meshes.
348 if (![self preloadShipMeshes:result]) return;
349 OOLog(@"shipData.load.progress", @"%@", @"Finished loading meshes...");
350#endif
351
352 _shipData = OODeepCopy(result);
353 [[OOCacheManager sharedCache] setObject:_shipData forKey:kShipDataCacheKey inCache:kShipRegistryCacheName];
354
355 OOLog(@"shipData.load.done", @"%@", @"Ship data loaded.");
356
357 [_effectData release];
358 _effectData = nil;
359
360 result = [[[ResourceManager dictionaryFromFilesNamed:@"effectdata.plist"
361 inFolder:@"Config"
362 mergeMode:MERGE_BASIC
363 cache:NO] mutableCopy] autorelease];
364 if (result == nil) return;
365
366 // Make each entry mutable to simplify later stages. Also removes any entries that aren't dictionaries.
367 if (![self makeShipEntriesMutable:result]) return;
368 OOLog(@"effectData.load.progress", @"%@", @"Finished initial cleanup...");
369
370 // Strip private keys (anything starting with _oo_).
371 if (![self stripPrivateKeys:result]) return;
372 OOLog(@"effectData.load.progress", @"%@", @"Finished stripping private keys...");
373
374 // Resolve like_effect entries.
375 if (![self applyLikeShips:result withKey:@"like_effect"]) return;
376 OOLog(@"effectData.load.progress", @"%@", @"Finished resolving like_effects...");
377
378 // Clean up subentity declarations and tag subentities so they won't be pruned.
379 if (![self canonicalizeAndTagSubentities:result]) return;
380 OOLog(@"effectData.load.progress", @"%@", @"Finished cleaning up subentities...");
381
382 // Clean out templates and invalid entries.
383 if (![self removeUnusableEntries:result shipMode:NO]) return;
384 OOLog(@"effectData.load.progress", @"%@", @"Finished removing invalid entries...");
385
386 _effectData = OODeepCopy(result);
387 [[OOCacheManager sharedCache] setObject:_effectData forKey:kVisualEffectDataCacheKey inCache:kVisualEffectRegistryCacheName];
388
389 OOLog(@"effectData.load.done", @"%@", @"Effect data loaded.");
390}
id OODeepCopy(id object) OO_RETURNS_RETAINED
Definition OODeepCopy.m:31
static void DumpStringAddrs(NSDictionary *dict, NSString *context)

◆ makeShipEntriesMutable:

- (BOOL) makeShipEntriesMutable: (NSMutableDictionary *)  ioData
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

741 :(NSMutableDictionary *)ioData
742{
743 NSString *shipKey = nil;
744 NSDictionary *shipEntry = nil;
745
746 foreach (shipKey, [ioData allKeys])
747 {
748 shipEntry = [ioData objectForKey:shipKey];
749 if (![shipEntry isKindOfClass:[NSDictionary class]])
750 {
751 OOLogERR(@"shipData.load.badEntry", @"the shipdata.plist entry \"%@\" is not a dictionary.", shipKey);
752 [ioData removeObjectForKey:shipKey];
753 }
754 else
755 {
756 shipEntry = [shipEntry mutableCopy];
757
758 [ioData setObject:shipEntry forKey:shipKey];
759 [shipEntry release];
760 }
761 }
762
763 return YES;
764}

◆ mergeShip:withParent:

- (NSMutableDictionary *) mergeShip: (NSDictionary *)  child
withParent: (NSDictionary *)  parent 
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

684 :(NSDictionary *)child withParent:(NSDictionary *)parent
685{
686 NSMutableDictionary *result = [[parent mutableCopy] autorelease];
687 if (result == nil) return nil;
688
689 [result addEntriesFromDictionary:child];
690 [result removeObjectForKey:@"like_ship"];
691
692 // Certain properties cannot be inherited.
693 if ([child oo_stringForKey:@"display_name"] == nil) [result removeObjectForKey:@"display_name"];
694 if ([child oo_stringForKey:@"is_template"] == nil) [result removeObjectForKey:@"is_template"];
695
696 // Since both 'scanClass' and 'scan_class' are accepted as valid keys for the scanClass property,
697 // we may end up with conflicting scanClass and scan_class keys from like_ship relationships getting
698 // merged in the result dictionary. We want to always have the child overriding the parent setting
699 // and we do that by determining which of the two keys belongs to the child dictionary and removing
700 // the other one from the result - Nikos 20100512
701 if ([result oo_stringForKey:@"scan_class"] != nil && [result oo_stringForKey:@"scanClass"] != nil)
702 {
703 if ([child oo_stringForKey:@"scanClass"] != nil)
704 [result removeObjectForKey:@"scan_class"];
705 else
706 [result removeObjectForKey:@"scanClass"];
707 }
708 // TODO: all normalised/non-normalised value name pairs need to be catered for. - Kaks 2010-05-13
709 if ([result oo_stringForKey:@"escort_role"] != nil && [result oo_stringForKey:@"escort-role"] != nil)
710 {
711 if ([child oo_stringForKey:@"escort-role"] != nil)
712 [result removeObjectForKey:@"escort_role"];
713 else
714 [result removeObjectForKey:@"escort-role"];
715 }
716 if ([result oo_stringForKey:@"escort_ship"] != nil && [result oo_stringForKey:@"escort-ship"] != nil)
717 {
718 if ([child oo_stringForKey:@"escort-ship"] != nil)
719 [result removeObjectForKey:@"escort_ship"];
720 else
721 [result removeObjectForKey:@"escort-ship"];
722 }
723 if ([result oo_stringForKey:@"is_carrier"] != nil && [result oo_stringForKey:@"isCarrier"] != nil)
724 {
725 if ([child oo_stringForKey:@"isCarrier"] != nil)
726 [result removeObjectForKey:@"is_carrier"];
727 else
728 [result removeObjectForKey:@"isCarrier"];
729 }
730 if ([result oo_stringForKey:@"has_shipyard"] != nil && [result oo_stringForKey:@"hasShipyard"] != nil)
731 {
732 if ([child oo_stringForKey:@"hasShipyard"] != nil)
733 [result removeObjectForKey:@"has_shipyard"];
734 else
735 [result removeObjectForKey:@"hasShipyard"];
736 }
737 return result;
738}

◆ mergeShipRoles:forShipKey:intoProbabilityMap:

- (void) mergeShipRoles: (NSString *)  roles
forShipKey: (NSString *)  shipKey
intoProbabilityMap: (NSMutableDictionary *)  probabilitySets 
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

1209 :(NSString *)roles
1210 forShipKey:(NSString *)shipKey
1211 intoProbabilityMap:(NSMutableDictionary *)probabilitySets
1212{
1213 NSDictionary *rolesAndWeights = nil;
1214 NSString *role = nil;
1215 OOMutableProbabilitySet *probSet = nil;
1216
1217
1218 /* probabilitySets is a dictionary whose keys are roles and whose values
1219 are mutable probability sets, whose values are ship keys.
1220
1221 When creating new ships Oolite looks up this probability map.
1222 To upgrade all soliton 'thargon' roles to 'EQ_THARGON' we need
1223 to swap these roles here.
1224 */
1225
1226 rolesAndWeights = OOParseRolesFromString(roles);
1227 // add default [shipKey] role
1228 NSMutableDictionary *mutable = [NSMutableDictionary dictionaryWithDictionary:rolesAndWeights];
1229 [mutable setObject:[NSNumber numberWithFloat:1.0] forKey:[[[NSString alloc] initWithFormat:@"[%@]",shipKey] autorelease]];
1230 rolesAndWeights = mutable;
1231
1232 id thargonValue = [rolesAndWeights objectForKey:@"thargon"];
1233 if (thargonValue != nil && [rolesAndWeights objectForKey:@"EQ_THARGON"] == nil)
1234 {
1235 NSMutableDictionary *mutable = [NSMutableDictionary dictionaryWithDictionary:rolesAndWeights];
1236 [mutable setObject:thargonValue forKey:@"EQ_THARGON"];
1237 rolesAndWeights = mutable;
1238 }
1239
1240 foreachkey (role, rolesAndWeights)
1241 {
1242 probSet = [probabilitySets objectForKey:role];
1243 if (probSet == nil)
1244 {
1246 [probabilitySets setObject:probSet forKey:role];
1247 }
1248
1249 [probSet setWeight:[rolesAndWeights oo_floatForKey:role] forObject:shipKey];
1250 }
1251}
NSDictionary * OOParseRolesFromString(NSString *string)
Definition OORoleSet.m:312
void setWeight:forObject:(float weight,[forObject] id object)

◆ playerShipKeys

- (NSArray *) playerShipKeys

Definition at line 1801 of file OOShipRegistry.m.

251{
252 return _playerShips;
253}

◆ probabilitySetForRole:

- (OOProbabilitySet *) probabilitySetForRole: (NSString *)  role

Definition at line 1801 of file OOShipRegistry.m.

234 :(NSString *)role
235{
236 if (role == nil) return nil;
237 return [_probabilitySets objectForKey:role];
238}

◆ randomShipKeyForRole:

- (NSString *) randomShipKeyForRole: (NSString *)  role

Provided by category OOShipRegistry(OOConveniences).

Definition at line 1801 of file OOShipRegistry.m.

276 :(NSString *)role
277{
278 return [[self probabilitySetForRole:role] randomObject];
279}

◆ release

- (void) release
implementation

Provided by category OOShipRegistry(Singleton).

Definition at line 1801 of file OOShipRegistry.m.

1709{}

◆ reload

+ (void) reload

Definition at line 1801 of file OOShipRegistry.m.

136{
137 if (sSingleton != nil)
138 {
139 /* CIM: 'release' doesn't work - the class definition
140 * overrides it, so this leaks memory. Needs a proper reset
141 * method for reloading the ship registry data instead */
142 [sSingleton release];
143 sSingleton = nil;
144
145 (void) [self sharedRegistry];
146 }
147}
OOShipRegistry * sharedRegistry()

◆ removeUnusableEntries:shipMode:

- (BOOL) removeUnusableEntries: (NSMutableDictionary *)  ioData
shipMode: (BOOL)  shipMode 
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

985 :(NSMutableDictionary *)ioData shipMode:(BOOL)shipMode
986{
987 NSString *shipKey = nil;
988 NSMutableDictionary *shipEntry = nil;
989 BOOL remove;
990 NSString *modelName = nil;
991
992 // Clean out invalid entries and templates. (Iterates over a copy of keys since it mutates the dictionary.)
993 foreach (shipKey, [ioData allKeys])
994 {
995 shipEntry = [ioData objectForKey:shipKey];
996 remove = NO;
997
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"])
1000 {
1001 OOLogERR(@"shipData.load.error", @"the shipdata.plist entry \"%@\" specifies no %@.", shipKey, @"roles");
1002 remove = YES;
1003 OOStandardsError(@"Error in shipdata.plist");
1004 }
1005 else
1006 {
1007 modelName = [shipEntry oo_stringForKey:@"model"];
1008 if (shipMode && [modelName length] == 0)
1009 {
1010 OOLogERR(@"shipData.load.error", @"the shipdata.plist entry \"%@\" specifies no %@.", shipKey, @"model");
1011 OOStandardsError(@"Error in shipdata.plist");
1012 remove = YES;
1013 }
1014 else if ([modelName length] != 0 && [ResourceManager pathForFileNamed:modelName inFolder:@"Models"] == nil)
1015 {
1016 OOLogERR(@"shipData.load.error", @"the shipdata.plist entry \"%@\" specifies non-existent model \"%@\".", shipKey, modelName);
1017 OOStandardsError(@"Error in shipdata.plist");
1018 remove = YES;
1019 }
1020 }
1021 if (remove) [ioData removeObjectForKey:shipKey];
1022 }
1023
1024 return YES;
1025}

◆ retain

- (id) retain
implementation

Provided by category OOShipRegistry(Singleton).

Definition at line 1801 of file OOShipRegistry.m.

1697{
1698 return self;
1699}

◆ retainCount

- (NSUInteger) retainCount
implementation

Provided by category OOShipRegistry(Singleton).

Definition at line 1801 of file OOShipRegistry.m.

1703{
1704 return UINT_MAX;
1705}

◆ sanitizeConditions:

- (BOOL) sanitizeConditions: (NSMutableDictionary *)  ioData
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

1032 :(NSMutableDictionary *)ioData
1033{
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;
1042
1043 NSMutableArray *conditionScripts = [[NSMutableArray alloc] init];
1044
1045 foreach (shipKey, [ioData allKeys])
1046 {
1047 shipEntry = [ioData objectForKey:shipKey];
1048 conditions = [shipEntry objectForKey:@"conditions"];
1049 condition_script = [shipEntry oo_stringForKey:@"condition_script"];
1050 if (condition_script != nil)
1051 {
1052 if (![conditionScripts containsObject:condition_script])
1053 {
1054 [conditionScripts addObject:condition_script];
1055 }
1056 }
1057
1058 hasShipyard = [shipEntry objectForKey:@"has_shipyard"];
1059 if (![hasShipyard isKindOfClass:[NSArray class]]) hasShipyard = nil; // May also be fuzzy boolean
1060 if (hasShipyard == nil)
1061 {
1062 hasShipyard = [shipEntry objectForKey:@"hasShipyard"];
1063 if (![hasShipyard isKindOfClass:[NSArray class]]) hasShipyard = nil; // May also be fuzzy boolean
1064 }
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)
1068 {
1069 if (![conditionScripts containsObject:shipyard_condition_script])
1070 {
1071 [conditionScripts addObject:shipyard_condition_script];
1072 }
1073 }
1074
1075
1076 if (conditions == nil && hasShipyard && shipyardConditions == nil) continue;
1077
1078 if (conditions != nil)
1079 {
1080 OOStandardsDeprecated([NSString stringWithFormat:@"The 'conditions' key is deprecated in shipdata entry %@",shipKey]);
1081 if (!OOEnforceStandards())
1082 {
1083 if ([conditions isKindOfClass:[NSArray class]])
1084 {
1085 conditions = OOSanitizeLegacyScriptConditions(conditions, [NSString stringWithFormat:@"<shipdata.plist entry \"%@\">", shipKey]);
1086 }
1087 else
1088 {
1089 OOLogWARN(@"shipdata.load.warning", @"conditions for shipdata.plist entry \"%@\" are not an array, ignoring.", shipKey);
1090 conditions = nil;
1091 }
1092
1093 if (conditions != nil)
1094 {
1095 [shipEntry setObject:conditions forKey:@"conditions"];
1096 }
1097 else
1098 {
1099 [shipEntry removeObjectForKey:@"conditions"];
1100 }
1101 }
1102 }
1103
1104 if (hasShipyard != nil)
1105 {
1106 hasShipyard = OOSanitizeLegacyScriptConditions(hasShipyard, [NSString stringWithFormat:@"<shipdata.plist entry \"%@\" hasShipyard conditions>", shipKey]);
1107 OOStandardsDeprecated([NSString stringWithFormat:@"Use of legacy script conditions in the 'has_shipyard' key is deprecated in shipyard entry %@",shipKey]);
1108 if (!OOEnforceStandards())
1109 {
1110 if (hasShipyard != nil)
1111 {
1112 [shipEntry setObject:hasShipyard forKey:@"has_shipyard"];
1113 }
1114 else
1115 {
1116 [shipEntry removeObjectForKey:@"hasShipyard"];
1117 [shipEntry removeObjectForKey:@"has_shipyard"];
1118 }
1119 }
1120 }
1121
1122 if (shipyardConditions != nil)
1123 {
1124 OOStandardsDeprecated([NSString stringWithFormat:@"The 'conditions' key is deprecated in shipyard entry %@",shipKey]);
1125 if (!OOEnforceStandards())
1126 {
1127 mutableShipyard = [[[shipEntry oo_dictionaryForKey:@"_oo_shipyard"] mutableCopy] autorelease];
1128
1129 if ([shipyardConditions isKindOfClass:[NSArray class]])
1130 {
1131 shipyardConditions = OOSanitizeLegacyScriptConditions(shipyardConditions, [NSString stringWithFormat:@"<shipyard.plist entry \"%@\">", shipKey]);
1132 }
1133 else
1134 {
1135 OOLogWARN(@"shipdata.load.warning", @"conditions for shipyard.plist entry \"%@\" are not an array, ignoring.", shipKey);
1136 shipyardConditions = nil;
1137 }
1138
1139 if (shipyardConditions != nil)
1140 {
1141 [mutableShipyard setObject:shipyardConditions forKey:@"conditions"];
1142 }
1143 else
1144 {
1145 [mutableShipyard removeObjectForKey:@"conditions"];
1146 }
1147
1148 [shipEntry setObject:mutableShipyard forKey:@"_oo_shipyard"];
1149 }
1150 }
1151 }
1152
1153 [[OOCacheManager sharedCache] setObject:conditionScripts forKey:@"ship conditions" inCache:@"condition scripts"];
1154 [conditionScripts release];
1155
1156 return YES;
1157}
NSArray * OOSanitizeLegacyScriptConditions(NSArray *conditions, NSString *context)

◆ setShipInfoForKey:with:

- (void) setShipInfoForKey: (NSString *)  key
with: (NSDictionary *)  newShipData 

Definition at line 1801 of file OOShipRegistry.m.

213 :(NSString *)key with:(NSDictionary *)newShipData
214{
215 NSMutableDictionary *mutableDict = [NSMutableDictionary dictionaryWithDictionary:_shipData];
216 [mutableDict setObject:OODeepCopy(newShipData) forKey:key];
218 _shipData = [[NSDictionary dictionaryWithDictionary:mutableDict] retain];
219}

Referenced by ShipStaticSetShipDataForKey().

+ Here is the caller graph for this function:

◆ sharedRegistry

+ (OOShipRegistry *) sharedRegistry

Definition at line 1801 of file OOShipRegistry.m.

125{
126 if (sSingleton == nil)
127 {
128 sSingleton = [[self alloc] init];
129 }
130
131 return sSingleton;
132}

Referenced by ShipStaticKeys(), ShipStaticKeysForRole(), ShipStaticRoles(), ShipStaticSetShipDataForKey(), ShipStaticShipDataForKey(), and StationAddShipToShipyard().

+ Here is the caller graph for this function:

◆ shipInfoForKey:

- (NSDictionary *) shipInfoForKey: (NSString *)  key

Definition at line 1801 of file OOShipRegistry.m.

207 :(NSString *)key
208{
209 return [_shipData objectForKey:key];
210}

Referenced by ShipStaticShipDataForKey(), and StationAddShipToShipyard().

+ Here is the caller graph for this function:

◆ shipIsBallTurretForKey:inShipData:

- (BOOL) shipIsBallTurretForKey: (NSString *)  shipKey
inShipData: (NSDictionary *)  shipData 
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

1643 :(NSString *)shipKey inShipData:(NSDictionary *)shipData
1644{
1645 // Test for presence of setup_actions containing initialiseTurret.
1646 NSArray *setupActions = nil;
1647 NSString *action = nil;
1648
1649 setupActions = [[shipData oo_dictionaryForKey:shipKey] oo_arrayForKey:@"setup_actions"];
1650
1651 foreach (action, setupActions)
1652 {
1653 if ([[ScanTokensFromString(action) objectAtIndex:0] isEqualToString:@"initialiseTurret"]) return YES;
1654 }
1655
1656 if ([shipKey isEqualToString:@"ballturret"])
1657 {
1658 // compatibility for OXPs using old subentity declarations and the
1659 // core turret entity
1660 return YES;
1661 }
1662
1663 return NO;
1664}
NSMutableArray * ScanTokensFromString(NSString *values)

◆ shipKeys

- (NSArray *) shipKeys

Provided by category OOShipRegistry(OOConveniences).

Definition at line 1801 of file OOShipRegistry.m.

261{
262 return [_shipData allKeys];
263}

Referenced by ShipStaticKeys().

+ Here is the caller graph for this function:

◆ shipKeysWithRole:

- (NSArray *) shipKeysWithRole: (NSString *)  role

Provided by category OOShipRegistry(OOConveniences).

Definition at line 1801 of file OOShipRegistry.m.

270 :(NSString *)role
271{
272 return [[self probabilitySetForRole:role] allObjects];
273}

Referenced by ShipStaticKeysForRole().

+ Here is the caller graph for this function:

◆ shipRoles

- (NSArray *) shipRoles

Provided by category OOShipRegistry(OOConveniences).

Definition at line 1801 of file OOShipRegistry.m.

266{
267 return [_probabilitySets allKeys];
268}

Referenced by ShipStaticRoles().

+ Here is the caller graph for this function:

◆ shipyardInfoForKey:

- (NSDictionary *) shipyardInfoForKey: (NSString *)  key

Definition at line 1801 of file OOShipRegistry.m.

228 :(NSString *)key
229{
230 return [[self shipInfoForKey:key] objectForKey:@"_oo_shipyard"];
231}

Referenced by StationAddShipToShipyard().

+ Here is the caller graph for this function:

◆ stripPrivateKeys:

- (BOOL) stripPrivateKeys: (NSMutableDictionary *)  ioData
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

800 :(NSMutableDictionary *)ioData
801{
802 NSString *shipKey = nil;
803 NSMutableDictionary *shipEntry = nil;
804 NSEnumerator *attrKeyEnum = nil;
805 NSString *attrKey = nil;
806
807 foreachkey (shipKey, ioData)
808 {
809 shipEntry = [ioData objectForKey:shipKey];
810
811 for (attrKeyEnum = [shipEntry keyEnumerator]; (attrKey = [attrKeyEnum nextObject]); )
812 {
813 if ([attrKey hasPrefix:@"_oo_"])
814 {
815 [shipEntry removeObjectForKey:attrKey];
816 }
817 }
818 }
819
820 return YES;
821}

◆ translateOldStandardBasicSubentityDeclaration:forShip:shipData:fatalError:

- (NSDictionary *) translateOldStandardBasicSubentityDeclaration: (NSArray *)  tokens
forShip: (NSString *)  shipKey
shipData: (NSDictionary *)  shipData
fatalError: (BOOL *)  outFatalError 
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

1383 :(NSArray *)tokens
1384 forShip:(NSString *)shipKey
1385 shipData:(NSDictionary *)shipData
1386 fatalError:(BOOL *)outFatalError
1387{
1388 NSString *subentityKey = nil;
1389 Vector position;
1390 Quaternion orientation;
1391 NSMutableDictionary *result = nil;
1392 BOOL isTurret, isDock = NO;
1393
1394 subentityKey = [tokens oo_stringAtIndex:0];
1395
1396 isTurret = [self shipIsBallTurretForKey:subentityKey inShipData:shipData];
1397
1398 position.x = [tokens oo_floatAtIndex:1];
1399 position.y = [tokens oo_floatAtIndex:2];
1400 position.z = [tokens oo_floatAtIndex:3];
1401
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];
1406
1407 if(orientation.w == 0 && orientation.x == 0 && orientation.y == 0 && orientation.z == 0)
1408 {
1409 orientation.w = 1; // avoid dividing by zero.
1410 OOLogWARN(@"shipData.load.error", @"The ship %@ has an undefined orientation for its %@ subentity. Setting it now at (1,0,0,0)", shipKey, subentityKey);
1411 }
1412
1413 quaternion_normalize(&orientation);
1414
1415 if (!isTurret)
1416 {
1417 isDock = [subentityKey rangeOfString:@"dock"].location != NSNotFound;
1418 }
1419
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"];
1426
1427 OOLog(@"shipData.translateSubentity.standard", @"Translated subentity declaration \"%@\" to %@", [tokens componentsJoinedByString:@" "], result);
1428
1429 return [[result copy] autorelease];
1430}

◆ translateOldStyleFlasherDeclaration:forShip:fatalError:

- (NSDictionary *) translateOldStyleFlasherDeclaration: (NSArray *)  tokens
forShip: (NSString *)  shipKey
fatalError: (BOOL *)  outFatalError 
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

1348 :(NSArray *)tokens
1349 forShip:(NSString *)shipKey
1350 fatalError:(BOOL *)outFatalError
1351{
1352 Vector position;
1353 float size, frequency, phase, hue;
1354 NSDictionary *colorDict = nil;
1355 NSDictionary *result = nil;
1356
1357 position.x = [tokens oo_floatAtIndex:1];
1358 position.y = [tokens oo_floatAtIndex:2];
1359 position.z = [tokens oo_floatAtIndex:3];
1360
1361 hue = [tokens oo_floatAtIndex:4];
1362 frequency = [tokens oo_floatAtIndex:5];
1363 phase = [tokens oo_floatAtIndex:6];
1364 size = [tokens oo_floatAtIndex:7];
1365
1366 colorDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:hue] forKey:@"hue"];
1367
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",
1375 nil];
1376
1377 OOLog(@"shipData.translateSubentity.flasher", @"Translated flasher declaration \"%@\" to %@", [tokens componentsJoinedByString:@" "], result);
1378
1379 return result;
1380}
voidpf void uLong size
Definition ioapi.h:134

◆ translateOldStyleSubentityDeclaration:forShip:shipData:fatalError:

- (NSDictionary *) translateOldStyleSubentityDeclaration: (NSString *)  declaration
forShip: (NSString *)  shipKey
shipData: (NSDictionary *)  shipData
fatalError: (BOOL *)  outFatalError 
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

1303 :(NSString *)declaration
1304 forShip:(NSString *)shipKey
1305 shipData:(NSDictionary *)shipData
1306 fatalError:(BOOL *)outFatalError
1307{
1308 NSArray *tokens = nil;
1309 NSString *subentityKey = nil;
1310 BOOL isFlasher;
1311
1312 tokens = ScanTokensFromString(declaration);
1313
1314 subentityKey = [tokens objectAtIndex:0];
1315 isFlasher = [subentityKey isEqualToString:@"*FLASHER*"];
1316
1317 // Sanity check: require eight tokens.
1318 if ([tokens count] != 8)
1319 {
1320 if (!isFlasher)
1321 {
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;
1324 }
1325 else
1326 {
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]);
1328 }
1329 return nil;
1330 }
1331
1332 if (isFlasher)
1333 {
1334 return [self translateOldStyleFlasherDeclaration:tokens
1335 forShip:shipKey
1336 fatalError:outFatalError];
1337 }
1338 else
1339 {
1340 return [self translateOldStandardBasicSubentityDeclaration:tokens
1341 forShip:shipKey
1342 shipData:shipData
1343 fatalError:outFatalError];
1344 }
1345}

◆ validateNewStyleFlasherDeclaration:forShip:fatalError:

- (NSDictionary *) validateNewStyleFlasherDeclaration: (NSDictionary *)  declaration
forShip: (NSString *)  shipKey
fatalError: (BOOL *)  outFatalError 
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

1459 :(NSDictionary *)declaration
1460 forShip:(NSString *)shipKey
1461 fatalError:(BOOL *)outFatalError
1462{
1463 NSMutableDictionary *result = nil;
1464 Vector position = kZeroVector;
1465 NSArray *colors = nil;
1466 id colorDesc = nil;
1467 float size, frequency, phase, brightfraction;
1468 BOOL initiallyOn;
1469
1470#define kDefaultFlasherColor @"redColor"
1471
1472 // "Validate" is really "clean up", since all values have defaults.
1473 colors = [declaration oo_arrayForKey:@"colors"];
1474 if ([colors count] == 0)
1475 {
1476 colorDesc = [declaration objectForKey:@"color"];
1477 if (colorDesc == nil) colorDesc = kDefaultFlasherColor;
1478 if ([colorDesc isKindOfClass:[NSArray class]])
1479 {
1480 // an easy made error is adding an array to "color" instead of "colors"
1481 OOLogWARN(@"shipData.load.warning.flasher.badColor", @"changing flasher for ship %@ from a color to a colors definition.", shipKey);
1482 colors = colorDesc;
1483 }
1484 else
1485 {
1486 colors = [NSArray arrayWithObject:colorDesc];
1487 }
1488 }
1489
1490 // Validate colours.
1491 NSMutableArray *validColors = [NSMutableArray arrayWithCapacity:[colors count]];
1492 foreach (colorDesc, colors)
1493 {
1494 OOColor *color = [OOColor colorWithDescription:colorDesc];
1495 if (color != nil)
1496 {
1497 [validColors addObject:[color normalizedArray]];
1498 }
1499 else
1500 {
1501 OOLogWARN(@"shipdata.load.warning.flasher.badColor", @"skipping invalid colour specifier for flasher for ship %@.", shipKey);
1502 }
1503 }
1504 // Ensure there's at least one.
1505 if ([validColors count] == 0)
1506 {
1507 [validColors addObject:kDefaultFlasherColor];
1508 }
1509 colors = validColors;
1510
1511 position = [declaration oo_vectorForKey:@"position"];
1512
1513 size = [declaration oo_floatForKey:@"size" defaultValue:8.0];
1514
1515 if (size <= 0)
1516 {
1517 OOLogWARN(@"shipData.load.warning.flasher.badSize", @"skipping flasher of invalid size %g for ship %@.", size, shipKey);
1518 return nil;
1519 }
1520
1521 brightfraction = [declaration oo_floatForKey:@"bright_fraction" defaultValue:0.5];
1522 if (brightfraction < 0.0 || brightfraction > 1.0)
1523 {
1524 OOLogWARN(@"shipData.load.warning.flasher.badFraction", @"skipping flasher of invalid bright fraction %g for ship %@.", brightfraction, shipKey);
1525 return nil;
1526 }
1527
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];
1531
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"];
1541
1542 return [[result copy] autorelease];
1543}
#define kDefaultFlasherColor
const Vector kZeroVector
Definition OOVector.m:28
OOColor * colorWithDescription:(id description)
Definition OOColor.m:127
NSArray * normalizedArray()
Definition OOColor.m:511

◆ validateNewStyleStandardSubentityDeclaration:forShip:fatalError:

- (NSDictionary *) validateNewStyleStandardSubentityDeclaration: (NSDictionary *)  declaration
forShip: (NSString *)  shipKey
fatalError: (BOOL *)  outFatalError 
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

1546 :(NSDictionary *)declaration
1547 forShip:(NSString *)shipKey
1548 fatalError:(BOOL *)outFatalError
1549{
1550 NSMutableDictionary *result = nil;
1551 NSString *subentityKey = nil;
1552 Vector position = kZeroVector;
1553 Quaternion orientation = kIdentityQuaternion;
1554 BOOL isTurret;
1555 BOOL isDock = NO;
1556 float fireRate = -1.0f; // out of range constants
1557 float weaponRange = -1.0f;
1558 float weaponEnergy = -1.0f;
1559 NSDictionary *scriptInfo = nil;
1560
1561 subentityKey = [declaration objectForKey:@"subentity_key"];
1562 if (subentityKey == nil)
1563 {
1564 OOLogERR(@"shipData.load.error.badSubentity", @"subentity declaration for ship %@ specifies no subentity_key.", shipKey);
1565 *outFatalError = YES;
1566 return nil;
1567 }
1568
1569 isTurret = [[declaration oo_stringForKey:@"type"] isEqualToString:@"ball_turret"];
1570 if (isTurret)
1571 {
1572 fireRate = [declaration oo_floatForKey:@"fire_rate" defaultValue:-1.0f];
1573 if (fireRate < 0.25f && fireRate >= 0.0f)
1574 {
1575 OOLogWARN(@"shipData.load.warning.turret.badFireRate", @"ball turret fire rate of %g for subentity of ship %@ is invalid, using 0.25.", fireRate, shipKey);
1576 fireRate = 0.25f;
1577 }
1578 weaponRange = [declaration oo_floatForKey:@"weapon_range" defaultValue:-1.0f];
1580 {
1581 OOLogWARN(@"shipData.load.warning.turret.badWeaponRange", @"ball turret weapon range of %g for subentity of ship %@ is too high, using %.1f.", weaponRange, shipKey, TURRET_SHOT_RANGE * COMBAT_WEAPON_RANGE_FACTOR);
1582 weaponRange = TURRET_SHOT_RANGE * COMBAT_WEAPON_RANGE_FACTOR; // approx. range of primary plasma canon.
1583 }
1584
1585 weaponEnergy = [declaration oo_floatForKey:@"weapon_energy" defaultValue:-1.0f];
1586 if (weaponEnergy > 100.0f)
1587
1588 {
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;
1591 }
1592 }
1593 else
1594 {
1595 isDock = [declaration oo_boolForKey:@"is_dock"];
1596 }
1597
1598 position = [declaration oo_vectorForKey:@"position"];
1599 orientation = [declaration oo_quaternionForKey:@"orientation"];
1600 quaternion_normalize(&orientation);
1601
1602 scriptInfo = [declaration oo_dictionaryForKey:@"script_info"];
1603
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"];
1609 if (isDock)
1610 {
1611 [result oo_setBool:YES forKey:@"is_dock"];
1612
1613 NSString* docklabel = [declaration oo_stringForKey:@"dock_label" defaultValue:@"the docking bay"];
1614 [result setObject:docklabel forKey:@"dock_label"];
1615
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];
1619
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"];
1623
1624 }
1625
1626 if (isTurret)
1627 {
1628 // default constants are defined and set in shipEntity
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"];
1632 }
1633
1634 if (scriptInfo != nil)
1635 {
1636 [result setObject:scriptInfo forKey:@"script_info"];
1637 }
1638
1639 return [[result copy] autorelease];
1640}
const Quaternion kIdentityQuaternion
#define TURRET_SHOT_RANGE
Definition ShipEntity.h:82
#define COMBAT_WEAPON_RANGE_FACTOR
Definition ShipEntity.h:58

◆ validateNewStyleSubentityDeclaration:forShip:fatalError:

- (NSDictionary *) validateNewStyleSubentityDeclaration: (NSDictionary *)  declaration
forShip: (NSString *)  shipKey
fatalError: (BOOL *)  outFatalError 
implementation

Provided by category OOShipRegistry(OODataLoader).

Definition at line 1801 of file OOShipRegistry.m.

1433 :(NSDictionary *)declaration
1434 forShip:(NSString *)shipKey
1435 fatalError:(BOOL *)outFatalError
1436{
1437 NSString *type = nil;
1438
1439 type = [declaration oo_stringForKey:@"type"];
1440 if (type == nil) type = @"standard";
1441
1442 if ([type isEqualToString:@"flasher"])
1443 {
1444 return [self validateNewStyleFlasherDeclaration:declaration forShip:shipKey fatalError:outFatalError];
1445 }
1446 else if ([type isEqualToString:@"standard"] || [type isEqualToString:@"ball_turret"])
1447 {
1448 return [self validateNewStyleStandardSubentityDeclaration:declaration forShip:shipKey fatalError:outFatalError];
1449 }
1450 else
1451 {
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;
1454 return nil;
1455 }
1456}

Member Data Documentation

◆ _demoShips

- (NSArray*) _demoShips
private

Definition at line 40 of file OOShipRegistry.h.

◆ _effectData

- (NSDictionary*) _effectData
private

Definition at line 39 of file OOShipRegistry.h.

◆ _playerShips

- (NSArray*) _playerShips
private

Definition at line 41 of file OOShipRegistry.h.

◆ _probabilitySets

- (NSDictionary*) _probabilitySets
private

Definition at line 42 of file OOShipRegistry.h.

◆ _shipData

- (NSDictionary*) _shipData
private

Definition at line 38 of file OOShipRegistry.h.


The documentation for this class was generated from the following files: