Oolite 1.91.0.7604-240417-a536cbe
Loading...
Searching...
No Matches
OOEquipmentType.m
Go to the documentation of this file.
1/*
2
3OOEquipmentType.m
4
5
6Copyright (C) 2008-2013 Jens Ayton and contributors
7
8Permission is hereby granted, free of charge, to any person obtaining a copy
9of this software and associated documentation files (the "Software"), to deal
10in the Software without restriction, including without limitation the rights
11to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12copies of the Software, and to permit persons to whom the Software is
13furnished to do so, subject to the following conditions:
14
15The above copyright notice and this permission notice shall be included in all
16copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24SOFTWARE.
25
26*/
27
28#import "OOEquipmentType.h"
29#import "Universe.h"
32#import "OOCacheManager.h"
33#import "OODebugStandards.h"
36
37static NSArray *sEquipmentTypes = nil;
39static NSDictionary *sEquipmentTypesByIdentifier = nil;
40static NSDictionary *sMissilesRegistry = nil;
41
42
43@interface OOEquipmentType (Private)
44
45- (id) initWithInfo:(NSArray *)info;
46
47@end
48
49
50@implementation OOEquipmentType
51
52+ (void) loadEquipment
53{
54 NSArray *equipmentData = nil;
55 NSMutableArray *equipmentTypes = nil;
56 NSMutableDictionary *equipmentTypesByIdentifier = nil;
57 NSArray *itemInfo = nil;
58 OOEquipmentType *item = nil;
59 NSEnumerator *itemEnum = nil;
60 NSMutableArray *conditionScripts = nil;
61
62 equipmentData = [UNIVERSE equipmentData];
63
64 [sEquipmentTypes release];
66 equipmentTypes = [NSMutableArray arrayWithCapacity:[equipmentData count]];
67 conditionScripts = [NSMutableArray arrayWithCapacity:[equipmentData count]];
69 equipmentTypesByIdentifier = [NSMutableDictionary dictionaryWithCapacity:[equipmentData count]];
70
71 for (itemEnum = [equipmentData objectEnumerator]; (itemInfo = [itemEnum nextObject]); )
72 {
73 item = [[[OOEquipmentType alloc] initWithInfo:itemInfo] autorelease];
74 if (item != nil)
75 {
76 [equipmentTypes addObject:item];
77 [equipmentTypesByIdentifier setObject:item forKey:[item identifier]];
78 }
79 NSString* condition_script = [item conditionScript];
80 if (condition_script != nil)
81 {
82 if (![conditionScripts containsObject:condition_script])
83 {
84 [conditionScripts addObject:condition_script];
85 }
86 }
87 }
88
89 [[OOCacheManager sharedCache] setObject:conditionScripts forKey:@"equipment conditions" inCache:@"condition scripts"];
90
91 sEquipmentTypes = [equipmentTypes copy];
92 sEquipmentTypesByIdentifier = [[NSDictionary alloc] initWithDictionary:equipmentTypesByIdentifier];
93
94 // same for the outfitting dataset
95 equipmentData = [UNIVERSE equipmentDataOutfitting];
96
97 [sEquipmentTypesOutfitting release];
99
100 equipmentTypes = [NSMutableArray arrayWithCapacity:[equipmentData count]];
101 for (itemEnum = [equipmentData objectEnumerator]; (itemInfo = [itemEnum nextObject]); )
102 {
103 item = [[[OOEquipmentType alloc] initWithInfo:itemInfo] autorelease];
104 if (item != nil)
105 {
106 [equipmentTypes addObject:item];
107 [equipmentTypesByIdentifier setObject:item forKey:[item identifier]];
108 }
109 }
110 sEquipmentTypesOutfitting = [equipmentTypes copy];
111
112}
113
114
115+ (void) addEquipmentWithInfo:(NSArray *)itemInfo
116{
117 NSMutableArray *equipmentTypes = [NSMutableArray arrayWithArray:sEquipmentTypes];
118 NSMutableArray *equipmentTypesOutfitting = [NSMutableArray arrayWithArray:sEquipmentTypesOutfitting];
119 NSMutableDictionary *equipmentTypesByIdentifier = [[NSMutableDictionary alloc] initWithDictionary:sEquipmentTypesByIdentifier];
120 OOEquipmentType *item = [[[OOEquipmentType alloc] initWithInfo:itemInfo] autorelease];
121 if (item != nil)
122 {
123 [equipmentTypes addObject:item];
124 [equipmentTypesOutfitting addObject:item];
125 [equipmentTypesByIdentifier setObject:item forKey:[item identifier]];
126
127 [sEquipmentTypes release];
129 [sEquipmentTypesOutfitting release];
132 sEquipmentTypes = [equipmentTypes copy];
133 sEquipmentTypesOutfitting = [equipmentTypesOutfitting copy];
134 sEquipmentTypesByIdentifier = [[NSDictionary alloc] initWithDictionary:equipmentTypesByIdentifier];
135 }
136 DESTROY(equipmentTypesByIdentifier);
137}
138
139
140+ (NSString *) getMissileRegistryRoleForShip:(NSString *)shipKey
141{
142 return [sMissilesRegistry oo_stringForKey:shipKey];
143}
144
145
146+ (void) setMissileRegistryRole:(NSString *)role forShip:(NSString *)shipKey
147{
148 NSMutableDictionary *missilesRegistry = [[NSMutableDictionary alloc] initWithDictionary:sMissilesRegistry];
149 if (role != nil && shipKey != nil && ![shipKey isEqualToString:@""])
150 {
151 [missilesRegistry setValue:role forKey:shipKey];
153 sMissilesRegistry = [[NSDictionary alloc] initWithDictionary:missilesRegistry];
154 }
155 DESTROY(missilesRegistry);
156}
157
158
159+ (NSArray *) allEquipmentTypes
160{
161 return sEquipmentTypes;
162}
163
164
165+ (NSEnumerator *) equipmentEnumerator
166{
167 return [sEquipmentTypes objectEnumerator];
168}
169
170
171+ (NSEnumerator *) reverseEquipmentEnumerator
172{
173 return [sEquipmentTypes reverseObjectEnumerator];
174}
175
176
177+ (NSEnumerator *) equipmentEnumeratorOutfitting
178{
179 return [sEquipmentTypesOutfitting objectEnumerator];
180}
181
182
183+ (OOEquipmentType *) equipmentTypeWithIdentifier:(NSString *)identifier
184{
185 return [sEquipmentTypesByIdentifier objectForKey:identifier];
186}
187
188
189- (id) initWithInfo:(NSArray *)info
190{
191 BOOL OK = YES;
192 NSDictionary *extra = nil;
193 NSArray *conditions = nil;
194 NSString *condition_script = nil;
195 NSArray *keydef = nil;
196
197 self = [super init];
198 if (self == nil) OK = NO;
199
200 if (OK && [info count] <= EQUIPMENT_LONG_DESC_INDEX) OK = NO;
201
202 if (OK)
203 {
204 // Read required attributes
205 _techLevel = [info oo_unsignedIntAtIndex:EQUIPMENT_TECH_LEVEL_INDEX];
206 _price = [info oo_unsignedIntAtIndex:EQUIPMENT_PRICE_INDEX];
207 _name = [[info oo_stringAtIndex:EQUIPMENT_SHORT_DESC_INDEX] retain];
208 _identifier = [[info oo_stringAtIndex:EQUIPMENT_KEY_INDEX] retain];
209 _description = [[info oo_stringAtIndex:EQUIPMENT_LONG_DESC_INDEX] retain];
210
211 if (_name == nil || _identifier == nil || _description == nil)
212 {
213 OOLog(@"equipment.load", @"***** ERROR: Invalid equipment.plist entry - missing name, identifier or description (\"%@\", %@, \"%@\")", _name, _identifier, _description);
214 OK = NO;
215 }
216 }
217
218 if (OK)
219 {
220 // Implied attributes for backwards-compatibility
221 if ([_identifier hasSuffix:@"_MISSILE"] || [_identifier hasSuffix:@"_MINE"])
222 {
223 _isMissileOrMine = YES;
224 _requiresEmptyPylon = YES;
225 }
226 else if ([_identifier isEqualToString:@"EQ_PASSENGER_BERTH_REMOVAL"])
227 {
228 _requiresFreePassengerBerth = YES;
229 }
230 else if ([_identifier isEqualToString:@"EQ_FUEL"])
231 {
232 _requiresNonFullFuel = YES;
233 }
234 _isVisible = YES;
235 _isAvailableToPlayer = YES;
236 _isAvailableToNPCs = YES;
237 _damageProbability = 1.0;
238 _hideValues = NO;
239 }
240
241 if (OK && [info count] > EQUIPMENT_EXTRA_INFO_INDEX)
242 {
243 // Read extra info dictionary
244 extra = [info oo_dictionaryAtIndex:EQUIPMENT_EXTRA_INFO_INDEX];
245 if (extra != nil)
246 {
247
248 _isAvailableToAll = [extra oo_boolForKey:@"available_to_all" defaultValue:_isAvailableToAll];
249 _isAvailableToPlayer = [extra oo_boolForKey:@"available_to_player" defaultValue:_isAvailableToPlayer];
250 _isAvailableToNPCs = [extra oo_boolForKey:@"available_to_NPCs" defaultValue:_isAvailableToNPCs];
251
252 _isMissileOrMine = [extra oo_boolForKey:@"is_external_store" defaultValue:_isMissileOrMine];
253 _requiresEmptyPylon = [extra oo_boolForKey:@"requires_empty_pylon" defaultValue:_requiresEmptyPylon];
254 _requiresMountedPylon = [extra oo_boolForKey:@"requires_mounted_pylon" defaultValue:_requiresMountedPylon];
255 _requiresClean = [extra oo_boolForKey:@"requires_clean" defaultValue:_requiresClean];
256 _requiresNotClean = [extra oo_boolForKey:@"requires_not_clean" defaultValue:_requiresNotClean];
257 _portableBetweenShips = [extra oo_boolForKey:@"portable_between_ships" defaultValue:_portableBetweenShips];
258 _requiresFreePassengerBerth = [extra oo_boolForKey:@"requires_free_passenger_berth" defaultValue:_requiresFreePassengerBerth];
259 _requiresFullFuel = [extra oo_boolForKey:@"requires_full_fuel" defaultValue:_requiresFullFuel];
260 _requiresNonFullFuel = [extra oo_boolForKey:@"requires_non_full_fuel" defaultValue:_requiresNonFullFuel];
261 _isVisible = [extra oo_boolForKey:@"visible" defaultValue:_isVisible];
262 _canCarryMultiple = [extra oo_boolForKey:@"can_carry_multiple" defaultValue:NO];
263 _hideValues = [extra oo_boolForKey:@"hide_values" defaultValue:NO];
264
265 _requiredCargoSpace = [extra oo_unsignedIntForKey:@"requires_cargo_space" defaultValue:_requiredCargoSpace];
266
267 _installTime = [extra oo_unsignedIntForKey:@"installation_time" defaultValue:0];
268 _repairTime = [extra oo_unsignedIntForKey:@"repair_time" defaultValue:0];
269 _provides = [[extra oo_arrayForKey:@"provides" defaultValue:[NSArray array]] retain];
270
271 id dispColor = [extra oo_objectForKey:@"display_color" defaultValue:nil];
272 _displayColor = [[OOColor colorWithDescription:dispColor] retain];
273
274 _weaponInfo = [[extra oo_dictionaryForKey:@"weapon_info" defaultValue:[NSDictionary dictionary]] retain];
275
276 _damageProbability = [extra oo_floatForKey:@"damage_probability" defaultValue:(_isMissileOrMine?0.0:1.0)];
277
278 id object = [extra objectForKey:@"requires_equipment"];
279 if ([object isKindOfClass:[NSString class]]) _requiresEquipment = [[NSSet setWithObject:object] retain];
280 else if ([object isKindOfClass:[NSArray class]]) _requiresEquipment = [[NSSet setWithArray:object] retain];
281 else if (object != nil)
282 {
283 OOLog(@"equipment.load", @"***** ERROR: %@ for equipment item %@ is not a string or an array.", @"requires_equipment", _identifier);
284 }
285
286 object = [extra objectForKey:@"requires_any_equipment"];
287 if ([object isKindOfClass:[NSString class]]) _requiresAnyEquipment = [[NSSet setWithObject:object] retain];
288 else if ([object isKindOfClass:[NSArray class]]) _requiresAnyEquipment = [[NSSet setWithArray:object] retain];
289 else if (object != nil)
290 {
291 OOLog(@"equipment.load", @"***** ERROR: %@ for equipment item %@ is not a string or an array.", @"requires_any_equipment", _identifier);
292 }
293
294 object = [extra objectForKey:@"incompatible_with_equipment"];
295 if ([object isKindOfClass:[NSString class]]) _incompatibleEquipment = [[NSSet setWithObject:object] retain];
296 else if ([object isKindOfClass:[NSArray class]]) _incompatibleEquipment = [[NSSet setWithArray:object] retain];
297 else if (object != nil)
298 {
299 OOLog(@"equipment.load", @"***** ERROR: %@ for equipment item %@ is not a string or an array.", @"incompatible_with_equipment", _identifier);
300 }
301
302 object = [extra objectForKey:@"conditions"];
303 if ([object isKindOfClass:[NSString class]]) conditions = [NSArray arrayWithObject:object];
304 else if ([object isKindOfClass:[NSArray class]]) conditions = object;
305 else if (object != nil)
306 {
307 OOLog(@"equipment.load", @"***** ERROR: %@ for equipment item %@ is not a string or an array.", @"conditions", _identifier);
308 }
309 if (conditions != nil)
310 {
311 OOStandardsDeprecated([NSString stringWithFormat:@"The conditions key is deprecated for equipment %@",_name]);
312 if (!OOEnforceStandards())
313 {
314 _conditions = OOSanitizeLegacyScriptConditions(conditions, [NSString stringWithFormat:@"<equipment type \"%@\">", _name]);
315 [_conditions retain];
316 }
317 }
318
319 object = [extra objectForKey:@"condition_script"];
320 if ([object isKindOfClass:[NSString class]])
321 {
322 condition_script = object;
323 }
324 else if (object != nil)
325 {
326 OOLog(@"equipment.load", @"***** ERROR: %@ for equipment item %@ is not a string.", @"condition_script", _identifier);
327 }
328 if (condition_script != nil)
329 {
330 _condition_script = [condition_script retain];
331 }
332 /* Condition scripts are shared: all equipment/ships using the
333 * same condition script use one shared instance. Equipment
334 * scripts and ship scripts are not shared and get one instance
335 * per item. */
336
337 _scriptInfo = [extra oo_dictionaryForKey:@"script_info"];
338 [_scriptInfo retain];
339
340 _script = [extra oo_stringForKey:@"script"];
341 if (_script != nil && ![OOScript jsScriptFromFileNamed:_script properties:nil]) _script = nil;
342 [_script retain];
343 if (_script != nil)
344 {
345 _fastAffinityA = !![extra oo_boolForKey:@"fast_affinity_defensive"];
346 _fastAffinityB = !![extra oo_boolForKey:@"fast_affinity_offensive"];
347
348 // look for default activate and mode key settings
349 // note: the customEquipmentActivation array is only populated when starting a game
350 // so the application of any default key settings on equipment will only happen then
351 NSString *checking;
352
353 object = [extra objectForKey:@"default_activate_key"];
354 if ([object isKindOfClass:[NSArray class]]) keydef = object;
355 else if (object != nil)
356 {
357 OOLog(@"equipment.load", @"***** ERROR: %@ for equipment item %@ is not an array.", @"default_activate_key", _identifier);
358 object = nil;
359 }
360
361 if (object != nil)
362 {
363 // do processing for key
364 _defaultActivateKey = [PLAYER processKeyCode:keydef];
365 checking = [PLAYER validateKey:[NSString stringWithFormat:@"activate_%@", _identifier] checkKeys:_defaultActivateKey];
366
367 if (checking != nil) {
368 OOLog(@"equipment.load", @"***** Error: %@ for equipment item %@ is already in use for %@. Default not applied", @"default_activate_key", _identifier, checking);
369 _defaultActivateKey = nil;
370 }
371 }
372
373 object = [extra objectForKey:@"default_mode_key"];
374 if ([object isKindOfClass:[NSArray class]]) keydef = object;
375 else if (object != nil)
376 {
377 OOLog(@"equipment.load", @"***** ERROR: %@ for equipment item %@ is not an array.", @"default_mode_key", _identifier);
378 object = nil;
379 }
380
381 if (object != nil)
382 {
383 // do processing for key
384 _defaultModeKey = [PLAYER processKeyCode:keydef];
385 checking = [PLAYER validateKey:[NSString stringWithFormat:@"mode_%@", _identifier] checkKeys:_defaultModeKey];
386
387 if (checking != nil) {
388 OOLog(@"equipment.load", @"***** Error: %@ for equipment item %@ is already in use for %@. Default not applied.", @"default_mode_key", _identifier, checking);
389 _defaultModeKey = nil;
390 }
391 }
392 }
393 }
394 }
395
396 if (!OK)
397 {
398 [self release];
399 self = nil;
400 }
401 return self;
402}
403
404
405- (void) dealloc
406{
407 DESTROY(_name);
408 DESTROY(_identifier);
409 DESTROY(_description);
410 DESTROY(_displayColor);
411 DESTROY(_requiresEquipment);
412 DESTROY(_requiresAnyEquipment);
413 DESTROY(_incompatibleEquipment);
414 DESTROY(_conditions);
415 DESTROY(_condition_script);
416 DESTROY(_provides);
417 DESTROY(_weaponInfo);
418 DESTROY(_scriptInfo);
419 DESTROY(_script);
420 DESTROY(_defaultActivateKey);
421 DESTROY(_defaultModeKey);
422
423 [super dealloc];
424}
425
426
427- (id) copyWithZone:(NSZone *)zone
428{
429 // OOEquipmentTypes are immutable.
430 return [self retain];
431}
432
433
434- (NSString *) descriptionComponents
435{
436 return [NSString stringWithFormat:@"%@ \"%@\"", _identifier, _name];
437}
438
439
440- (NSString *) identifier
441{
442 return _identifier;
443}
444
445
446- (NSString *) damagedIdentifier
447{
448 return [_identifier stringByAppendingString:@"_DAMAGED"];
449}
450
451
452- (NSString *) name
453{
454 return _name;
455}
456
457
458- (NSString *) descriptiveText
459{
460 return _description;
461}
462
463
464- (OOTechLevelID) techLevel
465{
466 return _techLevel;
467}
468
469
470- (OOCreditsQuantity) price
471{
472 return _price;
473}
474
475
476- (BOOL) isAvailableToAll
477{
478 return _isAvailableToAll;
479}
480
481
482- (BOOL) requiresEmptyPylon
483{
484 return _requiresEmptyPylon;
485}
486
487
488- (BOOL) requiresMountedPylon
489{
490 return _requiresMountedPylon;
491}
492
493
494- (BOOL) requiresCleanLegalRecord
495{
496 return _requiresClean;
497}
498
499
500- (BOOL) requiresNonCleanLegalRecord
501{
502 return _requiresNotClean;
503}
504
505
506- (BOOL) requiresFreePassengerBerth
507{
508 return _requiresFreePassengerBerth;
509}
510
511
512- (BOOL) requiresFullFuel
513{
514 return _requiresFullFuel;
515}
516
517
518- (BOOL) requiresNonFullFuel
519{
520 return _requiresNonFullFuel;
521}
522
523
524- (BOOL) isPrimaryWeapon
525{
526 return [[self identifier] hasPrefix:@"EQ_WEAPON"];
527}
528
529
530- (BOOL) isMissileOrMine
531{
532 return _isMissileOrMine;
533}
534
535
536- (BOOL) isPortableBetweenShips
537{
538 return _portableBetweenShips;
539}
540
541
542- (BOOL) canCarryMultiple
543{
544 if ([self isMissileOrMine]) return YES;
545 // technically multiple can be fitted, but not to the same mount.
546 if ([self isPrimaryWeapon]) return NO;
547
548 // hard-coded as special items
549 if ([_identifier isEqualToString:@"EQ_PASSENGER_BERTH"] ||
550 [_identifier isEqualToString:@"EQ_TRUMBLE"])
551 {
552 return YES;
553 }
554
555 return _canCarryMultiple;
556}
557
558
559- (GLfloat) damageProbability
560{
561 if ([self isMissileOrMine]) return 0.0;
562
563 return _damageProbability;
564}
565
566
567- (BOOL) canBeDamaged
568{
569 if ([self isMissileOrMine]) return NO;
570
571 if ([self damageProbability] > 0.0)
572 {
573 return YES;
574 }
575
576 return NO;
577}
578
579
580- (BOOL) isVisible
581{
582 return _isVisible;
583}
584
585
586- (BOOL) hideValues
587{
588 return _hideValues;
589}
590
591
592- (BOOL) isAvailableToPlayer
593{
594 return _isAvailableToPlayer;
595}
596
597
598- (BOOL) isAvailableToNPCs
599{
600 return _isAvailableToNPCs;
601}
602
603
604- (OOCargoQuantity) requiredCargoSpace
605{
606 return _requiredCargoSpace;
607}
608
609
610- (NSSet *) requiresEquipment
611{
612 return _requiresEquipment;
613}
614
615
616- (NSSet *) requiresAnyEquipment
617{
618 return _requiresAnyEquipment;
619}
620
621
622- (NSSet *) incompatibleEquipment
623{
624 return _incompatibleEquipment;
625}
626
627
628- (OOColor *) displayColor
629{
630 return _displayColor;
631}
632
633
634- (void) setDisplayColor:(OOColor *)color
635{
636 [_displayColor release];
637 _displayColor = [color retain];
638}
639
640
641- (NSArray *) conditions
642{
643 return _conditions;
644}
645
646
647- (NSString *) conditionScript
648{
649 return _condition_script;
650}
651
652
653- (NSDictionary *) scriptInfo
654{
655 return _scriptInfo;
656}
657
658
659- (NSString *) scriptName
660{
661 return _script;
662}
663
664
665- (BOOL) fastAffinityDefensive
666{
667 return _fastAffinityA;
668}
669
670
671- (BOOL) fastAffinityOffensive
672{
673 return _fastAffinityB;
674}
675
676
677- (NSArray *) defaultActivateKey
678{
679 return _defaultActivateKey;
680}
681
682
683- (NSArray *) defaultModeKey
684{
685 return _defaultModeKey;
686}
687
688
689- (NSUInteger) installTime
690{
691 return _installTime;
692}
693
694
695- (NSUInteger) repairTime
696{
697 if (_repairTime > 0)
698 {
699 return _repairTime;
700 }
701 else
702 {
703 return _installTime / 2;
704 }
705}
706
707
708- (NSArray *) providesForScripting
709{
710 return [[_provides copy] autorelease];
711}
712
713
714- (BOOL) provides:(NSString *)key
715{
716 return [_provides containsObject:key];
717}
718
719
720// weapon properties follow
721- (BOOL) isTurretLaser
722{
723 return [_weaponInfo oo_boolForKey:@"is_turret_laser" defaultValue:NO];
724}
725
726
727- (BOOL) isMiningLaser
728{
729 return [_weaponInfo oo_boolForKey:@"is_mining_laser" defaultValue:NO];
730}
731
732
733- (NSDictionary *) weaponInfo
734{
735 return _weaponInfo;
736}
737
738
739- (GLfloat) weaponRange
740{
741 return [_weaponInfo oo_floatForKey:@"range" defaultValue:12500.0];
742}
743
744
745- (GLfloat) weaponEnergyUse
746{
747 return [_weaponInfo oo_floatForKey:@"energy" defaultValue:0.8];
748}
749
750
751- (GLfloat) weaponDamage
752{
753 return [_weaponInfo oo_floatForKey:@"damage" defaultValue:15.0];
754}
755
756
757- (GLfloat) weaponRechargeRate
758{
759 return [_weaponInfo oo_floatForKey:@"recharge_rate" defaultValue:0.5];
760}
761
762
763- (GLfloat) weaponShotTemperature
764{
765 return [_weaponInfo oo_floatForKey:@"shot_temperature" defaultValue:7.0];
766}
767
768
769- (GLfloat) weaponThreatAssessment
770{
771 return [_weaponInfo oo_floatForKey:@"threat_assessment" defaultValue:1.0];
772}
773
774
775- (OOColor *) weaponColor
776{
777 return [OOColor brightColorWithDescription:[_weaponInfo objectForKey:@"color"]];
778}
779
780
781- (NSString *) fxShotMissName
782{
783 return [_weaponInfo oo_stringForKey:@"fx_shot_miss_name" defaultValue:@"[player-laser-miss]"];
784}
785
786
787- (NSString *) fxShotHitName
788{
789 return [_weaponInfo oo_stringForKey:@"fx_shot_hit_name" defaultValue:@"[player-laser-hit]"];
790}
791
792
793- (NSString *) fxShieldHitName
794{
795 return [_weaponInfo oo_stringForKey:@"fx_hitplayer_shielded_name" defaultValue:@"[player-hit-by-weapon]"];
796}
797
798
799- (NSString *) fxUnshieldedHitName
800{
801 return [_weaponInfo oo_stringForKey:@"fx_hitplayer_unshielded_name" defaultValue:@"[player-direct-hit]"];
802}
803
804
805- (NSString *) fxWeaponLaunchedName
806{
807 return [_weaponInfo oo_stringForKey:@"fx_weapon_launch_name" defaultValue:([[self identifier] hasSuffix:@"_MINE"] ? @"[mine-launched]" : @"[missile-launched]")];
808}
809
810
811/* This method exists purely to suppress Clang static analyzer warnings that
812 this ivar is unused (but may be used by categories, which it is).
813 FIXME: there must be a feature macro we can use to avoid actually building
814 this into the app, but I can't find it in docs.
815*/
816- (BOOL) suppressClangStuff
817{
818 return !_jsSelf;
819}
820
821@end
822
823
825
826@implementation OOEquipmentType (Conveniences)
827
828- (OOTechLevelID) effectiveTechLevel
829{
830 OOTechLevelID tl;
831 id missionVar = nil;
832
833 tl = [self techLevel];
834 if (tl == kOOVariableTechLevel)
835 {
836 OOStandardsDeprecated([NSString stringWithFormat:@"TL99 is deprecated for %@",[self identifier]]);
837 if (!OOEnforceStandards())
838 {
839 missionVar = [PLAYER missionVariableForKey:[@"mission_TL_FOR_" stringByAppendingString:[self identifier]]];
840 tl = OOUIntegerFromObject(missionVar, tl);
841 }
842 }
843
844 return tl;
845}
846
847@end
#define DESTROY(x)
Definition OOCocoa.h:77
OOINLINE NSInteger OOUIntegerFromObject(id object, NSUInteger defaultValue)
void OOStandardsDeprecated(NSString *message)
BOOL OOEnforceStandards(void)
static NSDictionary * sEquipmentTypesByIdentifier
static NSArray * sEquipmentTypes
static NSArray * sEquipmentTypesOutfitting
static NSDictionary * sMissilesRegistry
NSArray * OOSanitizeLegacyScriptConditions(NSArray *conditions, NSString *context)
#define OOLog(class, format,...)
Definition OOLogging.h:88
return self
unsigned count
return nil
uint64_t OOCreditsQuantity
Definition OOTypes.h:182
@ kOOVariableTechLevel
Definition OOTypes.h:202
NSUInteger OOTechLevelID
Definition OOTypes.h:204
uint32_t OOCargoQuantity
Definition OOTypes.h:176
@ EQUIPMENT_LONG_DESC_INDEX
Definition Universe.h:83
@ EQUIPMENT_EXTRA_INFO_INDEX
Definition Universe.h:84
void setObject:forKey:inCache:(id inElement,[forKey] NSString *inKey,[inCache] NSString *inCacheKey)
OOCacheManager * sharedCache()
OOColor * brightColorWithDescription:(id description)
Definition OOColor.m:205
OOColor * colorWithDescription:(id description)
Definition OOColor.m:127
NSString * conditionScript()
NSString * identifier()