Oolite 1.91.0.7646-241128-10e222e
Loading...
Searching...
No Matches
OOShipRegistry(OODataLoader) Category Reference

Instance Methods

(void) - loadShipData
 
(void) - loadDemoShipConditions
 
(void) - loadDemoShips
 
(void) - loadCachedRoleProbabilitySets
 
(void) - buildRoleProbabilitySets
 
(BOOL) - applyLikeShips:withKey:
 
(BOOL) - loadAndMergeShipyard:
 
(BOOL) - stripPrivateKeys:
 
(BOOL) - makeShipEntriesMutable:
 
(BOOL) - loadAndApplyShipDataOverrides:
 
(BOOL) - canonicalizeAndTagSubentities:
 
(BOOL) - removeUnusableEntries:shipMode:
 
(BOOL) - sanitizeConditions:
 
(NSMutableDictionary *) - mergeShip:withParent:
 
(void) - mergeShipRoles:forShipKey:intoProbabilityMap:
 
(NSDictionary *) - canonicalizeSubentityDeclaration:forShip:shipData:fatalError:
 
(NSDictionary *) - translateOldStyleSubentityDeclaration:forShip:shipData:fatalError:
 
(NSDictionary *) - translateOldStyleFlasherDeclaration:forShip:fatalError:
 
(NSDictionary *) - translateOldStandardBasicSubentityDeclaration:forShip:shipData:fatalError:
 
(NSDictionary *) - validateNewStyleSubentityDeclaration:forShip:fatalError:
 
(NSDictionary *) - validateNewStyleFlasherDeclaration:forShip:fatalError:
 
(NSDictionary *) - validateNewStyleStandardSubentityDeclaration:forShip:fatalError:
 
(BOOL) - shipIsBallTurretForKey:inShipData:
 

Detailed Description

Definition at line 68 of file OOShipRegistry.m.

Method Documentation

◆ applyLikeShips:withKey:

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

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

615 :(NSMutableDictionary *)ioData withKey:(NSString *)likeKey
616{
617 NSMutableSet *remainingLikeShips = nil;
618 NSEnumerator *enumerator = nil;
619 NSString *key = nil;
620 NSString *parentKey = nil;
621 NSDictionary *shipEntry = nil;
622 NSDictionary *parentEntry = nil;
623 NSUInteger count, lastCount;
624 NSMutableArray *reportedBadShips = nil;
625
626 // Build set of ships with like_ship references
627 remainingLikeShips = [NSMutableSet set];
628 for (enumerator = [ioData keyEnumerator]; (key = [enumerator nextObject]); )
629 {
630 shipEntry = [ioData objectForKey:key];
631 if ([shipEntry oo_stringForKey:likeKey] != nil)
632 {
633 [remainingLikeShips addObject:key];
634 }
635 }
636
637 count = lastCount = [remainingLikeShips count];
638 while (count != 0)
639 {
640 for (enumerator = [[[remainingLikeShips copy] autorelease] objectEnumerator]; (key = [enumerator nextObject]); )
641 {
642 // Look up like_ship entry
643 shipEntry = [ioData objectForKey:key];
644 parentKey = [shipEntry objectForKey:likeKey];
645 if (![remainingLikeShips containsObject:parentKey])
646 {
647 // If parent is fully resolved, we can resolve this child.
648 parentEntry = [ioData objectForKey:parentKey];
649 shipEntry = [self mergeShip:shipEntry withParent:parentEntry];
650 if (shipEntry != nil)
651 {
652 [remainingLikeShips removeObject:key];
653 [ioData setObject:shipEntry forKey:key];
654 }
655 }
656 }
657
658 count = [remainingLikeShips count];
659 if (count == lastCount)
660 {
661 /* Fail: we couldn't resolve all like_ship entries.
662 Remove unresolved entries, building a list of the ones that
663 don't have is_external_dependency set.
664 */
665 reportedBadShips = [NSMutableArray array];
666 for (enumerator = [remainingLikeShips objectEnumerator]; (key = [enumerator nextObject]); )
667 {
668 if (![[ioData oo_dictionaryForKey:key] oo_boolForKey:@"is_external_dependency"])
669 {
670 [reportedBadShips addObject:key];
671 }
672 [ioData removeObjectForKey:key];
673 }
674
675 if ([reportedBadShips count] != 0)
676 {
677 [reportedBadShips sortUsingSelector:@selector(caseInsensitiveCompare:)];
678 OOLogERR(@"shipData.merge.failed", @"one or more shipdata.plist entries have %@ references that cannot be resolved: %@", likeKey, [reportedBadShips componentsJoinedByString:@", "]); // FIXME: distinguish shipdata and effectdata
679 OOStandardsError(@"Likely missing a dependency in a manifest.plist");
680 }
681 break;
682 }
683 lastCount = count;
684 }
685
686 return YES;
687}
void OOStandardsError(NSString *message)
#define OOLogERR(class, format,...)
Definition OOLogging.h:112
unsigned count
return nil

◆ buildRoleProbabilitySets

- (void) buildRoleProbabilitySets

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

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

◆ canonicalizeAndTagSubentities:

- (BOOL) canonicalizeAndTagSubentities: (NSMutableDictionary *) ioData

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

899 :(NSMutableDictionary *)ioData
900{
901 NSEnumerator *shipKeyEnum = nil;
902 NSString *shipKey = nil;
903 NSMutableDictionary *shipEntry = nil;
904 NSArray *subentityDeclarations = nil;
905 NSEnumerator *subentityEnum = nil;
906 id subentityDecl = nil;
907 NSDictionary *subentityDict = nil;
908 NSString *subentityKey = nil;
909 NSMutableDictionary *subentityShipEntry = nil;
910 NSMutableSet *badSubentities = nil;
911 NSString *badSubentitiesList = nil;
912 NSMutableArray *okSubentities = nil;
913 BOOL remove, fatal;
914
915 // Convert all subentity declarations to dictionaries and add
916 // _oo_is_subentity=YES to all entries used as subentities.
917
918 // Iterate over all ships. (Iterates over a copy of keys since it mutates the dictionary.)
919 for (shipKeyEnum = [[ioData allKeys] objectEnumerator]; (shipKey = [shipKeyEnum nextObject]); )
920 {
921 shipEntry = [ioData objectForKey:shipKey];
922 remove = NO;
923 badSubentities = nil;
924
925 // Iterate over each subentity declaration of each ship
926 subentityDeclarations = [shipEntry oo_arrayForKey:@"subentities"];
927 if (subentityDeclarations != nil)
928 {
929 okSubentities = [NSMutableArray arrayWithCapacity:[subentityDeclarations count]];
930 for (subentityEnum = [subentityDeclarations objectEnumerator]; (subentityDecl = [subentityEnum nextObject]); )
931 {
932 subentityDict = [self canonicalizeSubentityDeclaration:subentityDecl forShip:shipKey shipData:ioData fatalError:&fatal];
933
934 // If entry is broken, we need to kill this ship.
935 if (fatal)
936 {
937 OOStandardsError(@"Bad subentity definition found");
938 remove = YES;
939 }
940 else if (subentityDict != nil)
941 {
942 [okSubentities addObject:subentityDict];
943
944 // Tag subentities.
945 if (![[subentityDict oo_stringForKey:@"type"] isEqualToString:@"flasher"])
946 {
947 subentityKey = [subentityDict oo_stringForKey:@"subentity_key"];
948 subentityShipEntry = [ioData objectForKey:subentityKey];
949 if (subentityKey == nil || subentityShipEntry == nil)
950 {
951 // Oops, reference to non-existent subent.
952 if (badSubentities == nil) badSubentities = [NSMutableSet set];
953 [badSubentities addObject:subentityKey];
954 }
955 else
956 {
957 // Subent exists, add _oo_is_subentity so roles aren't required.
958 [subentityShipEntry oo_setBool:YES forKey:@"_oo_is_subentity"];
959 }
960 }
961 }
962 }
963
964 // Set updated subentity list.
965 if ([okSubentities count] != 0)
966 {
967 [shipEntry setObject:okSubentities forKey:@"subentities"];
968 }
969 else
970 {
971 [shipEntry removeObjectForKey:@"subentities"];
972 }
973
974 if (badSubentities != nil)
975 {
976 if (![shipEntry oo_boolForKey:@"is_external_dependency"])
977 {
978 badSubentitiesList = [[[badSubentities allObjects] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] componentsJoinedByString:@", "];
979 OOLogERR(@"shipData.load.error", @"the shipdata.plist entry \"%@\" has unresolved subentit%@ %@.", shipKey, ([badSubentities count] == 1) ? @"y" : @"ies", badSubentitiesList);
980 OOStandardsError(@"Bad subentity definition found");
981 }
982 remove = YES;
983 }
984
985 if (remove)
986 {
987 // Removal is deferred to avoid bogus "entry doesn't exist" errors.
988 [shipEntry oo_setBool:YES forKey:@"_oo_deferred_remove"];
989 }
990 }
991 }
992
993 return YES;
994}

◆ canonicalizeSubentityDeclaration:forShip:shipData:fatalError:

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

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

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

◆ loadAndApplyShipDataOverrides:

- (BOOL) loadAndApplyShipDataOverrides: (NSMutableDictionary *) ioData

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

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

◆ loadAndMergeShipyard:

- (BOOL) loadAndMergeShipyard: (NSMutableDictionary *) ioData

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

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

◆ loadCachedRoleProbabilitySets

- (void) loadCachedRoleProbabilitySets

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

544{
545 NSDictionary *cachedSets = nil;
546 NSMutableDictionary *restoredSets = nil;
547 NSEnumerator *roleEnum = nil;
548 NSString *role = nil;
549
550 cachedSets = [[OOCacheManager sharedCache] objectForKey:kRoleWeightsCacheKey inCache:kShipRegistryCacheName];
551 if (cachedSets == nil) return;
552
553 restoredSets = [NSMutableDictionary dictionaryWithCapacity:[cachedSets count]];
554 for (roleEnum = [cachedSets keyEnumerator]; (role = [roleEnum nextObject]); )
555 {
556 [restoredSets setObject:[OOProbabilitySet probabilitySetWithPropertyListRepresentation:[cachedSets objectForKey:role]] forKey:role];
557 }
558
559 _probabilitySets = [restoredSets copy];
560}
id objectForKey:inCache:(NSString *inKey,[inCache] NSString *inCacheKey)
void setObject:forKey:(id value,[forKey] id key)
Definition OOCache.m:248
id probabilitySetWithPropertyListRepresentation:(NSDictionary *plist)

◆ loadDemoShipConditions

- (void) loadDemoShipConditions

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

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

◆ loadDemoShips

- (void) loadDemoShips

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

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

◆ loadShipData

- (void) loadShipData

Extends class OOShipRegistry.

Definition at line 1820 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

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

747 :(NSMutableDictionary *)ioData
748{
749 NSEnumerator *shipKeyEnum = nil;
750 NSString *shipKey = nil;
751 NSDictionary *shipEntry = nil;
752
753 for (shipKeyEnum = [[ioData allKeys] objectEnumerator]; (shipKey = [shipKeyEnum nextObject]); )
754 {
755 shipEntry = [ioData objectForKey:shipKey];
756 if (![shipEntry isKindOfClass:[NSDictionary class]])
757 {
758 OOLogERR(@"shipData.load.badEntry", @"the shipdata.plist entry \"%@\" is not a dictionary.", shipKey);
759 [ioData removeObjectForKey:shipKey];
760 }
761 else
762 {
763 shipEntry = [shipEntry mutableCopy];
764
765 [ioData setObject:shipEntry forKey:shipKey];
766 [shipEntry release];
767 }
768 }
769
770 return YES;
771}

◆ mergeShip:withParent:

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

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

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

◆ mergeShipRoles:forShipKey:intoProbabilityMap:

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

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

1223 :(NSString *)roles
1224 forShipKey:(NSString *)shipKey
1225 intoProbabilityMap:(NSMutableDictionary *)probabilitySets
1226{
1227 NSDictionary *rolesAndWeights = nil;
1228 NSEnumerator *roleEnum = nil;
1229 NSString *role = nil;
1230 OOMutableProbabilitySet *probSet = nil;
1231
1232
1233 /* probabilitySets is a dictionary whose keys are roles and whose values
1234 are mutable probability sets, whose values are ship keys.
1235
1236 When creating new ships Oolite looks up this probability map.
1237 To upgrade all soliton 'thargon' roles to 'EQ_THARGON' we need
1238 to swap these roles here.
1239 */
1240
1241 rolesAndWeights = OOParseRolesFromString(roles);
1242 // add default [shipKey] role
1243 NSMutableDictionary *mutable = [NSMutableDictionary dictionaryWithDictionary:rolesAndWeights];
1244 [mutable setObject:[NSNumber numberWithFloat:1.0] forKey:[[[NSString alloc] initWithFormat:@"[%@]",shipKey] autorelease]];
1245 rolesAndWeights = mutable;
1246
1247 id thargonValue = [rolesAndWeights objectForKey:@"thargon"];
1248 if (thargonValue != nil && [rolesAndWeights objectForKey:@"EQ_THARGON"] == nil)
1249 {
1250 NSMutableDictionary *mutable = [NSMutableDictionary dictionaryWithDictionary:rolesAndWeights];
1251 [mutable setObject:thargonValue forKey:@"EQ_THARGON"];
1252 rolesAndWeights = mutable;
1253 }
1254
1255 for (roleEnum = [rolesAndWeights keyEnumerator]; (role = [roleEnum nextObject]); )
1256 {
1257 probSet = [probabilitySets objectForKey:role];
1258 if (probSet == nil)
1259 {
1261 [probabilitySets setObject:probSet forKey:role];
1262 }
1263
1264 [probSet setWeight:[rolesAndWeights oo_floatForKey:role] forObject:shipKey];
1265 }
1266}
NSDictionary * OOParseRolesFromString(NSString *string)
void setWeight:forObject:(float weight,[forObject] id object)

◆ removeUnusableEntries:shipMode:

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

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

997 :(NSMutableDictionary *)ioData shipMode:(BOOL)shipMode
998{
999 NSEnumerator *shipKeyEnum = nil;
1000 NSString *shipKey = nil;
1001 NSMutableDictionary *shipEntry = nil;
1002 BOOL remove;
1003 NSString *modelName = nil;
1004
1005 // Clean out invalid entries and templates. (Iterates over a copy of keys since it mutates the dictionary.)
1006 for (shipKeyEnum = [[ioData allKeys] objectEnumerator]; (shipKey = [shipKeyEnum nextObject]); )
1007 {
1008 shipEntry = [ioData objectForKey:shipKey];
1009 remove = NO;
1010
1011 if ([shipEntry oo_boolForKey:@"is_template"] || [shipEntry oo_boolForKey:@"_oo_deferred_remove"]) remove = YES;
1012 else if (shipMode && [[shipEntry oo_stringForKey:@"roles"] length] == 0 && ![shipEntry oo_boolForKey:@"_oo_is_subentity"] && ![shipEntry oo_boolForKey:@"_oo_is_effect"])
1013 {
1014 OOLogERR(@"shipData.load.error", @"the shipdata.plist entry \"%@\" specifies no %@.", shipKey, @"roles");
1015 remove = YES;
1016 OOStandardsError(@"Error in shipdata.plist");
1017 }
1018 else
1019 {
1020 modelName = [shipEntry oo_stringForKey:@"model"];
1021 if (shipMode && [modelName length] == 0)
1022 {
1023 OOLogERR(@"shipData.load.error", @"the shipdata.plist entry \"%@\" specifies no %@.", shipKey, @"model");
1024 OOStandardsError(@"Error in shipdata.plist");
1025 remove = YES;
1026 }
1027 else if ([modelName length] != 0 && [ResourceManager pathForFileNamed:modelName inFolder:@"Models"] == nil)
1028 {
1029 OOLogERR(@"shipData.load.error", @"the shipdata.plist entry \"%@\" specifies non-existent model \"%@\".", shipKey, modelName);
1030 OOStandardsError(@"Error in shipdata.plist");
1031 remove = YES;
1032 }
1033 }
1034 if (remove) [ioData removeObjectForKey:shipKey];
1035 }
1036
1037 return YES;
1038}

◆ sanitizeConditions:

- (BOOL) sanitizeConditions: (NSMutableDictionary *) ioData

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

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

◆ shipIsBallTurretForKey:inShipData:

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

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

1658 :(NSString *)shipKey inShipData:(NSDictionary *)shipData
1659{
1660 // Test for presence of setup_actions containing initialiseTurret.
1661 NSArray *setupActions = nil;
1662 NSEnumerator *actionEnum = nil;
1663 NSString *action = nil;
1664
1665 setupActions = [[shipData oo_dictionaryForKey:shipKey] oo_arrayForKey:@"setup_actions"];
1666
1667 for (actionEnum = [setupActions objectEnumerator]; (action = [actionEnum nextObject]); )
1668 {
1669 if ([[ScanTokensFromString(action) objectAtIndex:0] isEqualToString:@"initialiseTurret"]) return YES;
1670 }
1671
1672 if ([shipKey isEqualToString:@"ballturret"])
1673 {
1674 // compatibility for OXPs using old subentity declarations and the
1675 // core turret entity
1676 return YES;
1677 }
1678
1679 return NO;
1680}
NSMutableArray * ScanTokensFromString(NSString *values)

◆ stripPrivateKeys:

- (BOOL) stripPrivateKeys: (NSMutableDictionary *) ioData

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

808 :(NSMutableDictionary *)ioData
809{
810 NSEnumerator *shipKeyEnum = nil;
811 NSString *shipKey = nil;
812 NSMutableDictionary *shipEntry = nil;
813 NSEnumerator *attrKeyEnum = nil;
814 NSString *attrKey = nil;
815
816 for (shipKeyEnum = [ioData keyEnumerator]; (shipKey = [shipKeyEnum nextObject]); )
817 {
818 shipEntry = [ioData objectForKey:shipKey];
819
820 for (attrKeyEnum = [shipEntry keyEnumerator]; (attrKey = [attrKeyEnum nextObject]); )
821 {
822 if ([attrKey hasPrefix:@"_oo_"])
823 {
824 [shipEntry removeObjectForKey:attrKey];
825 }
826 }
827 }
828
829 return YES;
830}

◆ translateOldStandardBasicSubentityDeclaration:forShip:shipData:fatalError:

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

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

1398 :(NSArray *)tokens
1399 forShip:(NSString *)shipKey
1400 shipData:(NSDictionary *)shipData
1401 fatalError:(BOOL *)outFatalError
1402{
1403 NSString *subentityKey = nil;
1404 Vector position;
1405 Quaternion orientation;
1406 NSMutableDictionary *result = nil;
1407 BOOL isTurret, isDock = NO;
1408
1409 subentityKey = [tokens oo_stringAtIndex:0];
1410
1411 isTurret = [self shipIsBallTurretForKey:subentityKey inShipData:shipData];
1412
1413 position.x = [tokens oo_floatAtIndex:1];
1414 position.y = [tokens oo_floatAtIndex:2];
1415 position.z = [tokens oo_floatAtIndex:3];
1416
1417 orientation.w = [tokens oo_floatAtIndex:4];
1418 orientation.x = [tokens oo_floatAtIndex:5];
1419 orientation.y = [tokens oo_floatAtIndex:6];
1420 orientation.z = [tokens oo_floatAtIndex:7];
1421
1422 if(orientation.w == 0 && orientation.x == 0 && orientation.y == 0 && orientation.z == 0)
1423 {
1424 orientation.w = 1; // avoid dividing by zero.
1425 OOLogWARN(@"shipData.load.error", @"The ship %@ has an undefined orientation for its %@ subentity. Setting it now at (1,0,0,0)", shipKey, subentityKey);
1426 }
1427
1428 quaternion_normalize(&orientation);
1429
1430 if (!isTurret)
1431 {
1432 isDock = [subentityKey rangeOfString:@"dock"].location != NSNotFound;
1433 }
1434
1435 result = [NSMutableDictionary dictionaryWithCapacity:5];
1436 [result setObject:isTurret ? @"ball_turret" : @"standard" forKey:@"type"];
1437 [result setObject:subentityKey forKey:@"subentity_key"];
1438 [result oo_setVector:position forKey:@"position"];
1439 [result oo_setQuaternion:orientation forKey:@"orientation"];
1440 if (isDock) [result oo_setBool:YES forKey:@"is_dock"];
1441
1442 OOLog(@"shipData.translateSubentity.standard", @"Translated subentity declaration \"%@\" to %@", [tokens componentsJoinedByString:@" "], result);
1443
1444 return [[result copy] autorelease];
1445}

◆ translateOldStyleFlasherDeclaration:forShip:fatalError:

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

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

1363 :(NSArray *)tokens
1364 forShip:(NSString *)shipKey
1365 fatalError:(BOOL *)outFatalError
1366{
1367 Vector position;
1368 float size, frequency, phase, hue;
1369 NSDictionary *colorDict = nil;
1370 NSDictionary *result = nil;
1371
1372 position.x = [tokens oo_floatAtIndex:1];
1373 position.y = [tokens oo_floatAtIndex:2];
1374 position.z = [tokens oo_floatAtIndex:3];
1375
1376 hue = [tokens oo_floatAtIndex:4];
1377 frequency = [tokens oo_floatAtIndex:5];
1378 phase = [tokens oo_floatAtIndex:6];
1379 size = [tokens oo_floatAtIndex:7];
1380
1381 colorDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:hue] forKey:@"hue"];
1382
1383 result = [NSDictionary dictionaryWithObjectsAndKeys:
1384 @"flasher", @"type",
1385 OOPropertyListFromVector(position), @"position",
1386 [NSArray arrayWithObject:colorDict], @"colors",
1387 [NSNumber numberWithFloat:frequency], @"frequency",
1388 [NSNumber numberWithFloat:phase], @"phase",
1389 [NSNumber numberWithFloat:size], @"size",
1390 nil];
1391
1392 OOLog(@"shipData.translateSubentity.flasher", @"Translated flasher declaration \"%@\" to %@", [tokens componentsJoinedByString:@" "], result);
1393
1394 return result;
1395}
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 

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

1318 :(NSString *)declaration
1319 forShip:(NSString *)shipKey
1320 shipData:(NSDictionary *)shipData
1321 fatalError:(BOOL *)outFatalError
1322{
1323 NSArray *tokens = nil;
1324 NSString *subentityKey = nil;
1325 BOOL isFlasher;
1326
1327 tokens = ScanTokensFromString(declaration);
1328
1329 subentityKey = [tokens objectAtIndex:0];
1330 isFlasher = [subentityKey isEqualToString:@"*FLASHER*"];
1331
1332 // Sanity check: require eight tokens.
1333 if ([tokens count] != 8)
1334 {
1335 if (!isFlasher)
1336 {
1337 OOLogERR(@"shipData.load.error.badSubentity", @"the shipdata.plist entry \"%@\" has a broken subentity definition \"%@\" (should have 8 tokens, has %lu).", shipKey, subentityKey, [tokens count]);
1338 *outFatalError = YES;
1339 }
1340 else
1341 {
1342 OOLogWARN(@"shipData.load.warning.badFlasher", @"the shipdata.plist entry \"%@\" has a broken flasher definition (should have 8 tokens, has %lu). This flasher will be ignored.", shipKey, [tokens count]);
1343 }
1344 return nil;
1345 }
1346
1347 if (isFlasher)
1348 {
1349 return [self translateOldStyleFlasherDeclaration:tokens
1350 forShip:shipKey
1351 fatalError:outFatalError];
1352 }
1353 else
1354 {
1355 return [self translateOldStandardBasicSubentityDeclaration:tokens
1356 forShip:shipKey
1357 shipData:shipData
1358 fatalError:outFatalError];
1359 }
1360}

◆ validateNewStyleFlasherDeclaration:forShip:fatalError:

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

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

1474 :(NSDictionary *)declaration
1475 forShip:(NSString *)shipKey
1476 fatalError:(BOOL *)outFatalError
1477{
1478 NSMutableDictionary *result = nil;
1479 Vector position = kZeroVector;
1480 NSArray *colors = nil;
1481 id colorDesc = nil;
1482 float size, frequency, phase, brightfraction;
1483 BOOL initiallyOn;
1484
1485#define kDefaultFlasherColor @"redColor"
1486
1487 // "Validate" is really "clean up", since all values have defaults.
1488 colors = [declaration oo_arrayForKey:@"colors"];
1489 if ([colors count] == 0)
1490 {
1491 colorDesc = [declaration objectForKey:@"color"];
1492 if (colorDesc == nil) colorDesc = kDefaultFlasherColor;
1493 if ([colorDesc isKindOfClass:[NSArray class]])
1494 {
1495 // an easy made error is adding an array to "color" instead of "colors"
1496 OOLogWARN(@"shipData.load.warning.flasher.badColor", @"changing flasher for ship %@ from a color to a colors definition.", shipKey);
1497 colors = colorDesc;
1498 }
1499 else
1500 {
1501 colors = [NSArray arrayWithObject:colorDesc];
1502 }
1503 }
1504
1505 // Validate colours.
1506 NSMutableArray *validColors = [NSMutableArray arrayWithCapacity:[colors count]];
1507 foreach (colorDesc, colors)
1508 {
1509 OOColor *color = [OOColor colorWithDescription:colorDesc];
1510 if (color != nil)
1511 {
1512 [validColors addObject:[color normalizedArray]];
1513 }
1514 else
1515 {
1516 OOLogWARN(@"shipdata.load.warning.flasher.badColor", @"skipping invalid colour specifier for flasher for ship %@.", shipKey);
1517 }
1518 }
1519 // Ensure there's at least one.
1520 if ([validColors count] == 0)
1521 {
1522 [validColors addObject:kDefaultFlasherColor];
1523 }
1524 colors = validColors;
1525
1526 position = [declaration oo_vectorForKey:@"position"];
1527
1528 size = [declaration oo_floatForKey:@"size" defaultValue:8.0];
1529
1530 if (size <= 0)
1531 {
1532 OOLogWARN(@"shipData.load.warning.flasher.badSize", @"skipping flasher of invalid size %g for ship %@.", size, shipKey);
1533 return nil;
1534 }
1535
1536 brightfraction = [declaration oo_floatForKey:@"bright_fraction" defaultValue:0.5];
1537 if (brightfraction < 0.0 || brightfraction > 1.0)
1538 {
1539 OOLogWARN(@"shipData.load.warning.flasher.badFraction", @"skipping flasher of invalid bright fraction %g for ship %@.", brightfraction, shipKey);
1540 return nil;
1541 }
1542
1543 frequency = [declaration oo_floatForKey:@"frequency" defaultValue:2.0];
1544 phase = [declaration oo_floatForKey:@"phase" defaultValue:0.0];
1545 initiallyOn = [declaration oo_boolForKey:@"initially_on" defaultValue:YES];
1546
1547 result = [NSMutableDictionary dictionaryWithCapacity:8];
1548 [result setObject:@"flasher" forKey:@"type"];
1549 [result setObject:colors forKey:@"colors"];
1550 [result oo_setVector:position forKey:@"position"];
1551 [result setObject:[NSNumber numberWithFloat:size] forKey:@"size"];
1552 [result setObject:[NSNumber numberWithFloat:frequency] forKey:@"frequency"];
1553 if (phase != 0) [result setObject:[NSNumber numberWithFloat:phase] forKey:@"phase"];
1554 [result setObject:[NSNumber numberWithFloat:brightfraction] forKey:@"bright_fraction"];
1555 [result setObject:[NSNumber numberWithBool:initiallyOn] forKey:@"initially_on"];
1556
1557 return [[result copy] autorelease];
1558}
#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 

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

1561 :(NSDictionary *)declaration
1562 forShip:(NSString *)shipKey
1563 fatalError:(BOOL *)outFatalError
1564{
1565 NSMutableDictionary *result = nil;
1566 NSString *subentityKey = nil;
1567 Vector position = kZeroVector;
1568 Quaternion orientation = kIdentityQuaternion;
1569 BOOL isTurret;
1570 BOOL isDock = NO;
1571 float fireRate = -1.0f; // out of range constants
1572 float weaponRange = -1.0f;
1573 float weaponEnergy = -1.0f;
1574 NSDictionary *scriptInfo = nil;
1575
1576 subentityKey = [declaration objectForKey:@"subentity_key"];
1577 if (subentityKey == nil)
1578 {
1579 OOLogERR(@"shipData.load.error.badSubentity", @"subentity declaration for ship %@ specifies no subentity_key.", shipKey);
1580 *outFatalError = YES;
1581 return nil;
1582 }
1583
1584 isTurret = [[declaration oo_stringForKey:@"type"] isEqualToString:@"ball_turret"];
1585 if (isTurret)
1586 {
1587 fireRate = [declaration oo_floatForKey:@"fire_rate" defaultValue:-1.0f];
1588 if (fireRate < 0.25f && fireRate >= 0.0f)
1589 {
1590 OOLogWARN(@"shipData.load.warning.turret.badFireRate", @"ball turret fire rate of %g for subentity of ship %@ is invalid, using 0.25.", fireRate, shipKey);
1591 fireRate = 0.25f;
1592 }
1593 weaponRange = [declaration oo_floatForKey:@"weapon_range" defaultValue:-1.0f];
1595 {
1596 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);
1597 weaponRange = TURRET_SHOT_RANGE * COMBAT_WEAPON_RANGE_FACTOR; // approx. range of primary plasma canon.
1598 }
1599
1600 weaponEnergy = [declaration oo_floatForKey:@"weapon_energy" defaultValue:-1.0f];
1601 if (weaponEnergy > 100.0f)
1602
1603 {
1604 OOLogWARN(@"shipData.load.warning.turret.badWeaponEnergy", @"ball turret weapon energy of %g for subentity of ship %@ is too high, using 100.", weaponEnergy, shipKey);
1605 weaponEnergy = 100.0f;
1606 }
1607 }
1608 else
1609 {
1610 isDock = [declaration oo_boolForKey:@"is_dock"];
1611 }
1612
1613 position = [declaration oo_vectorForKey:@"position"];
1614 orientation = [declaration oo_quaternionForKey:@"orientation"];
1615 quaternion_normalize(&orientation);
1616
1617 scriptInfo = [declaration oo_dictionaryForKey:@"script_info"];
1618
1619 result = [NSMutableDictionary dictionaryWithCapacity:10];
1620 [result setObject:isTurret ? @"ball_turret" : @"standard" forKey:@"type"];
1621 [result setObject:subentityKey forKey:@"subentity_key"];
1622 [result oo_setVector:position forKey:@"position"];
1623 [result oo_setQuaternion:orientation forKey:@"orientation"];
1624 if (isDock)
1625 {
1626 [result oo_setBool:YES forKey:@"is_dock"];
1627
1628 NSString* docklabel = [declaration oo_stringForKey:@"dock_label" defaultValue:@"the docking bay"];
1629 [result setObject:docklabel forKey:@"dock_label"];
1630
1631 BOOL dockable = [declaration oo_boolForKey:@"allow_docking" defaultValue:YES];
1632 BOOL playerdockable = [declaration oo_boolForKey:@"disallowed_docking_collides" defaultValue:NO];
1633 BOOL undockable = [declaration oo_boolForKey:@"allow_launching" defaultValue:YES];
1634
1635 [result oo_setBool:dockable forKey:@"allow_docking"];
1636 [result oo_setBool:playerdockable forKey:@"disallowed_docking_collides"];
1637 [result oo_setBool:undockable forKey:@"allow_launching"];
1638
1639 }
1640
1641 if (isTurret)
1642 {
1643 // default constants are defined and set in shipEntity
1644 if (fireRate > 0) [result oo_setFloat:fireRate forKey:@"fire_rate"];
1645 if (weaponRange >= 0) [result oo_setFloat:weaponRange forKey:@"weapon_range"];
1646 if (weaponEnergy >= 0) [result oo_setFloat:weaponEnergy forKey:@"weapon_energy"];
1647 }
1648
1649 if (scriptInfo != nil)
1650 {
1651 [result setObject:scriptInfo forKey:@"script_info"];
1652 }
1653
1654 return [[result copy] autorelease];
1655}
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 

Extends class OOShipRegistry.

Definition at line 1820 of file OOShipRegistry.m.

1448 :(NSDictionary *)declaration
1449 forShip:(NSString *)shipKey
1450 fatalError:(BOOL *)outFatalError
1451{
1452 NSString *type = nil;
1453
1454 type = [declaration oo_stringForKey:@"type"];
1455 if (type == nil) type = @"standard";
1456
1457 if ([type isEqualToString:@"flasher"])
1458 {
1459 return [self validateNewStyleFlasherDeclaration:declaration forShip:shipKey fatalError:outFatalError];
1460 }
1461 else if ([type isEqualToString:@"standard"] || [type isEqualToString:@"ball_turret"])
1462 {
1463 return [self validateNewStyleStandardSubentityDeclaration:declaration forShip:shipKey fatalError:outFatalError];
1464 }
1465 else
1466 {
1467 OOLogERR(@"shipData.load.error.badSubentity", @"subentity declaration for ship %@ does not declare a valid type (must be standard, flasher or ball_turret).", shipKey);
1468 *outFatalError = YES;
1469 return nil;
1470 }
1471}

The documentation for this category was generated from the following file: