Line data Source code
1 0 : /*
2 :
3 : OOEquipmentType.m
4 :
5 :
6 : Copyright (C) 2008-2013 Jens Ayton and contributors
7 :
8 : Permission is hereby granted, free of charge, to any person obtaining a copy
9 : of this software and associated documentation files (the "Software"), to deal
10 : in the Software without restriction, including without limitation the rights
11 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 : copies of the Software, and to permit persons to whom the Software is
13 : furnished to do so, subject to the following conditions:
14 :
15 : The above copyright notice and this permission notice shall be included in all
16 : copies or substantial portions of the Software.
17 :
18 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 : SOFTWARE.
25 :
26 : */
27 :
28 : #import "OOEquipmentType.h"
29 : #import "Universe.h"
30 : #import "OOCollectionExtractors.h"
31 : #import "OOLegacyScriptWhitelist.h"
32 : #import "OOCacheManager.h"
33 : #import "OODebugStandards.h"
34 : #import "PlayerEntityControls.h"
35 : #import "PlayerEntityKeyMapper.h"
36 :
37 0 : static NSArray *sEquipmentTypes = nil;
38 0 : static NSArray *sEquipmentTypesOutfitting = nil;
39 0 : static NSDictionary *sEquipmentTypesByIdentifier = nil;
40 0 : static NSDictionary *sMissilesRegistry = nil;
41 :
42 :
43 : @interface OOEquipmentType (Private)
44 :
45 0 : - (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];
65 : sEquipmentTypes = nil;
66 : equipmentTypes = [NSMutableArray arrayWithCapacity:[equipmentData count]];
67 : conditionScripts = [NSMutableArray arrayWithCapacity:[equipmentData count]];
68 : DESTROY(sEquipmentTypesByIdentifier);
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];
98 : sEquipmentTypesOutfitting = nil;
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];
128 : sEquipmentTypes = nil;
129 : [sEquipmentTypesOutfitting release];
130 : sEquipmentTypesOutfitting = nil;
131 : DESTROY(sEquipmentTypesByIdentifier);
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];
152 : DESTROY(sMissilesRegistry);
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 0 : - (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 0 : - (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 0 : - (id) copyWithZone:(NSZone *)zone
428 : {
429 : // OOEquipmentTypes are immutable.
430 : return [self retain];
431 : }
432 :
433 :
434 0 : - (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 0 : - (BOOL) suppressClangStuff
817 : {
818 : return !_jsSelf;
819 : }
820 :
821 : @end
822 :
823 :
824 : #import "PlayerEntityLegacyScriptEngine.h"
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
|