Line data Source code
1 0 : /*
2 :
3 : PlayerEntitySound.m
4 :
5 : Oolite
6 : Copyright (C) 2004-2013 Giles C Williams and contributors
7 :
8 : This program is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License
10 : as published by the Free Software Foundation; either version 2
11 : of the License, or (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 : MA 02110-1301, USA.
22 :
23 : */
24 :
25 : #import "PlayerEntitySound.h"
26 : #import "OOSound.h"
27 : #import "ResourceManager.h"
28 : #import "Universe.h"
29 : #import "OOSoundSourcePool.h"
30 : #import "OOMaths.h"
31 : #import "OOEquipmentType.h"
32 :
33 :
34 : // Sizes of sound source pools
35 0 : enum
36 : {
37 : kBuySellSourcePoolSize = 4,
38 : kWarningPoolSize = 6,
39 : kWeaponPoolSize = 3,
40 : kDamagePoolSize = 4,
41 : kMiscPoolSize = 2
42 : };
43 :
44 :
45 0 : static OOSoundSourcePool *sWarningSoundPool;
46 0 : static OOSoundSourcePool *sWeaponSoundPool;
47 0 : static OOSoundSourcePool *sDamageSoundPool;
48 0 : static OOSoundSourcePool *sMiscSoundPool;
49 0 : static OOSoundSource *sHyperspaceSoundSource;
50 0 : static OOSoundSource *sInterfaceBeepSource;
51 0 : static OOSoundSource *sEcmSource;
52 0 : static OOSoundSource *sBreakPatternSource;
53 0 : static OOSoundSourcePool *sBuySellSourcePool;
54 0 : static OOSoundSource *sAfterburnerSources[2];
55 :
56 0 : static NSDictionary *weaponShotMiss;
57 0 : static NSDictionary *weaponShotHit;
58 0 : static NSDictionary *weaponShieldHit;
59 0 : static NSDictionary *weaponUnshieldedHit;
60 0 : static NSDictionary *weaponLaunched;
61 :
62 0 : static const Vector kInterfaceBeepPosition = { 0.0f, -0.2f, 0.5f };
63 0 : static const Vector kInterfaceWarningPosition = { 0.0f, -0.2f, 0.4f };
64 0 : static const Vector kBreakPatternPosition = { 0.0f, 0.0f, 1.0f };
65 0 : static const Vector kEcmPosition = { 0.2f, 0.6f, -0.1f };
66 0 : static const Vector kWitchspacePosition = { 0.0f, -0.3f, -0.3f };
67 : // maybe these should actually track engine positions
68 0 : static const Vector kAfterburner1Position = { -0.1f, 0.0f, -1.0f };
69 0 : static const Vector kAfterburner2Position = { 0.1f, 0.0f, -1.0f };
70 :
71 : @implementation PlayerEntity (Sound)
72 :
73 : - (void) setUpSound
74 : {
75 : [self destroySound];
76 :
77 : sInterfaceBeepSource = [[OOSoundSource alloc] init];
78 : [sInterfaceBeepSource setPosition:kInterfaceBeepPosition];
79 :
80 : sBreakPatternSource = [[OOSoundSource alloc] init];
81 : [sBreakPatternSource setPosition:kBreakPatternPosition];
82 :
83 : sEcmSource = [[OOSoundSource alloc] init];
84 : [sEcmSource setPosition:kEcmPosition];
85 :
86 : sHyperspaceSoundSource = [[OOSoundSource alloc] init];
87 : [sHyperspaceSoundSource setPosition:kWitchspacePosition];
88 :
89 : sBuySellSourcePool = [[OOSoundSourcePool alloc] initWithCount:kBuySellSourcePoolSize minRepeatTime:0.0];
90 : sWarningSoundPool = [[OOSoundSourcePool alloc] initWithCount:kWarningPoolSize minRepeatTime:0.0];
91 : sWeaponSoundPool = [[OOSoundSourcePool alloc] initWithCount:kWeaponPoolSize minRepeatTime:0.0];
92 : sDamageSoundPool = [[OOSoundSourcePool alloc] initWithCount:kDamagePoolSize minRepeatTime:0.1]; // Repeat time limit is to avoid playing a scrape sound every frame on glancing scrapes. This does limit the number of laser hits that can be played in a furrball, though; maybe lasers and scrapes should use different pools.
93 : sMiscSoundPool = [[OOSoundSourcePool alloc] initWithCount:kMiscPoolSize minRepeatTime:0.0];
94 :
95 : // Two sources with the same sound are used to simulate looping.
96 : OOSound *afterburnerSound = [ResourceManager ooSoundNamed:@"afterburner1.ogg" inFolder:@"Sounds"];
97 : sAfterburnerSources[0] = [[OOSoundSource alloc] initWithSound:afterburnerSound];
98 : [sAfterburnerSources[0] setPosition:kAfterburner1Position];
99 : sAfterburnerSources[1] = [[OOSoundSource alloc] initWithSound:afterburnerSound];
100 : [sAfterburnerSources[1] setPosition:kAfterburner2Position];
101 : }
102 :
103 :
104 : // sets up the sound key dictionaries for all the available weapons/missiles/mines defined.
105 : - (void) setUpWeaponSounds
106 : {
107 : NSArray *eqTypes = [OOEquipmentType allEquipmentTypes];
108 : NSMutableDictionary *shotMissSounds = [NSMutableDictionary dictionary];
109 : NSMutableDictionary *shotHitSounds = [NSMutableDictionary dictionary];
110 : NSMutableDictionary *shieldHitSounds = [NSMutableDictionary dictionary];
111 : NSMutableDictionary *unshieldedHitSounds = [NSMutableDictionary dictionary];
112 : NSMutableDictionary *weaponLaunchedSounds = [NSMutableDictionary dictionary];
113 : NSEnumerator *eqTypeEnum = nil;
114 : OOEquipmentType *eqType = nil;
115 :
116 : // special case: turrets aren't defined with a "EQ_WEAPON" prefix, and plasma shots don't have a matching equipment item,
117 : // so add a unique entry here. this could be overridden if an OXP creates an equipment item with this key.
118 : // plasma shots don't make a sound when fired, so we only need to provide for the hit player sound keys.
119 : [shieldHitSounds setObject:@"[player-hit-by-weapon]" forKey:@"EQ_WEAPON_PLASMA_SHOT"];
120 : [unshieldedHitSounds setObject:@"[player-direct-hit]" forKey:@"EQ_WEAPON_PLASMA_SHOT"];
121 : // grab a local copy of the sound identifiers for weapons to make the process of looking up a sound ref as fast as possible
122 : // but we must ensure that no nil values are used for setObject
123 0 : #define OO_ASSIGN_SOUNDSTR_TO_SOUNDS(soundStr, sounds) do { \
124 : fxString = [eqType soundStr]; \
125 : if (!fxString) fxString = @""; \
126 : [sounds setObject:fxString forKey:[eqType identifier]]; \
127 : } while(0)
128 :
129 : for (eqTypeEnum = [eqTypes objectEnumerator]; (eqType = [eqTypeEnum nextObject]); )
130 : {
131 : NSString *fxString = nil;
132 : if ([[eqType identifier] hasPrefix:@"EQ_WEAPON"])
133 : {
134 : OO_ASSIGN_SOUNDSTR_TO_SOUNDS(fxShotMissName, shotMissSounds);
135 : OO_ASSIGN_SOUNDSTR_TO_SOUNDS(fxShotHitName, shotHitSounds);
136 : OO_ASSIGN_SOUNDSTR_TO_SOUNDS(fxShieldHitName, shieldHitSounds);
137 : OO_ASSIGN_SOUNDSTR_TO_SOUNDS(fxUnshieldedHitName, unshieldedHitSounds);
138 : }
139 : if ([eqType isMissileOrMine])
140 : {
141 : OO_ASSIGN_SOUNDSTR_TO_SOUNDS(fxWeaponLaunchedName, weaponLaunchedSounds);
142 : OO_ASSIGN_SOUNDSTR_TO_SOUNDS(fxShieldHitName, shieldHitSounds);
143 : OO_ASSIGN_SOUNDSTR_TO_SOUNDS(fxUnshieldedHitName, unshieldedHitSounds);
144 : }
145 : }
146 :
147 : DESTROY(weaponShotMiss);
148 : DESTROY(weaponShotHit);
149 : DESTROY(weaponShieldHit);
150 : DESTROY(weaponUnshieldedHit);
151 : DESTROY(weaponLaunched);
152 :
153 : weaponShotMiss = [[NSDictionary alloc] initWithDictionary:shotMissSounds];
154 : weaponShotHit = [[NSDictionary alloc] initWithDictionary:shotHitSounds];
155 : weaponShieldHit = [[NSDictionary alloc] initWithDictionary:shieldHitSounds];
156 : weaponUnshieldedHit = [[NSDictionary alloc] initWithDictionary:unshieldedHitSounds];
157 : weaponLaunched = [[NSDictionary alloc] initWithDictionary:weaponLaunchedSounds];
158 : }
159 :
160 : - (void) destroySound
161 : {
162 : DESTROY(sInterfaceBeepSource);
163 : DESTROY(sBreakPatternSource);
164 : DESTROY(sEcmSource);
165 : DESTROY(sHyperspaceSoundSource);
166 :
167 : DESTROY(sAfterburnerSources[0]);
168 : DESTROY(sAfterburnerSources[1]);
169 :
170 : DESTROY(sBuySellSourcePool);
171 : DESTROY(sWarningSoundPool);
172 : DESTROY(sWeaponSoundPool);
173 : DESTROY(sDamageSoundPool);
174 : DESTROY(sMiscSoundPool);
175 :
176 : DESTROY(weaponShotMiss);
177 : DESTROY(weaponShotHit);
178 : DESTROY(weaponShieldHit);
179 : DESTROY(weaponUnshieldedHit);
180 : DESTROY(weaponLaunched);
181 : }
182 :
183 :
184 0 : - (void) playInterfaceBeep:(NSString *)beepKey
185 : {
186 : #if OOLITE_WINDOWS
187 : if ([self status] == STATUS_START_GAME) { return; }
188 : #endif
189 : [sInterfaceBeepSource playSound:[OOSound soundWithCustomSoundKey:beepKey]];
190 : }
191 :
192 :
193 : - (BOOL) isBeeping
194 : {
195 : return [sInterfaceBeepSource isPlaying];
196 : }
197 :
198 :
199 0 : - (void) boop
200 : {
201 : [self playInterfaceBeep:@"[general-boop]"];
202 : }
203 :
204 :
205 : - (void) playIdentOn
206 : {
207 : [self playInterfaceBeep:@"[ident-on]"];
208 : }
209 :
210 :
211 : - (void) playIdentOff
212 : {
213 : [self playInterfaceBeep:@"[ident-off]"];
214 : }
215 :
216 :
217 : - (void) playIdentLockedOn
218 : {
219 : [self playInterfaceBeep:@"[ident-locked-on]"];
220 : }
221 :
222 :
223 : - (void) playMissileArmed
224 : {
225 : [self playInterfaceBeep:@"[missile-armed]"];
226 : }
227 :
228 :
229 : - (void) playMineArmed
230 : {
231 : [self playInterfaceBeep:@"[mine-armed]"];
232 : }
233 :
234 :
235 : - (void) playMissileSafe
236 : {
237 : [self playInterfaceBeep:@"[missile-safe]"];
238 : }
239 :
240 :
241 : - (void) playMissileLockedOn
242 : {
243 : [self playInterfaceBeep:@"[missile-locked-on]"];
244 : }
245 :
246 :
247 : - (void) playNextEquipmentSelected
248 : {
249 : [self playInterfaceBeep:@"[next-equipment-selected]"];
250 : }
251 :
252 :
253 : - (void) playNextMissileSelected
254 : {
255 : [self playInterfaceBeep:@"[next-missile-selected]"];
256 : }
257 :
258 :
259 : - (void) playWeaponsOnline
260 : {
261 : [self playInterfaceBeep:@"[weapons-online]"];
262 : }
263 :
264 :
265 : - (void) playWeaponsOffline
266 : {
267 : [self playInterfaceBeep:@"[weapons-offline]"];
268 : }
269 :
270 :
271 : - (void) playCargoJettisioned
272 : {
273 : [self playInterfaceBeep:@"[cargo-jettisoned]"];
274 : }
275 :
276 :
277 : - (void) playAutopilotOn
278 : {
279 : [self playInterfaceBeep:@"[autopilot-on]"];
280 : }
281 :
282 :
283 : - (void) playAutopilotOff
284 : {
285 : // only if still alive
286 : if (energy > 0.0)
287 : {
288 : [self playInterfaceBeep:@"[autopilot-off]"];
289 : }
290 : }
291 :
292 :
293 : - (void) playAutopilotOutOfRange
294 : {
295 : [self playInterfaceBeep:@"[autopilot-out-of-range]"];
296 : }
297 :
298 :
299 : - (void) playAutopilotCannotDockWithTarget
300 : {
301 : [self playInterfaceBeep:@"[autopilot-cannot-dock-with-target]"];
302 : }
303 :
304 :
305 : - (void) playSaveOverwriteYes
306 : {
307 : [self playInterfaceBeep:@"[save-overwrite-yes]"];
308 : }
309 :
310 :
311 : - (void) playSaveOverwriteNo
312 : {
313 : [self playInterfaceBeep:@"[save-overwrite-no]"];
314 : }
315 :
316 :
317 : - (void) playHoldFull
318 : {
319 : [self playInterfaceBeep:@"[hold-full]"];
320 : }
321 :
322 :
323 : - (void) playJumpMassLocked
324 : {
325 : [self playInterfaceBeep:@"[jump-mass-locked]"];
326 : }
327 :
328 :
329 : - (void) playTargetLost
330 : {
331 : [self playInterfaceBeep:@"[target-lost]"];
332 : }
333 :
334 :
335 : - (void) playNoTargetInMemory
336 : {
337 : [self playInterfaceBeep:@"[no-target-in-memory]"];
338 : }
339 :
340 :
341 : - (void) playTargetSwitched
342 : {
343 : [self playInterfaceBeep:@"[target-switched]"];
344 : }
345 :
346 :
347 : - (void) playHyperspaceNoTarget
348 : {
349 : [self playInterfaceBeep:@"[witch-no-target]"];
350 : }
351 :
352 :
353 : - (void) playHyperspaceNoFuel
354 : {
355 : [self playInterfaceBeep:@"[witch-no-fuel]"];
356 : }
357 :
358 :
359 : - (void) playHyperspaceBlocked
360 : {
361 : [self playInterfaceBeep:@"[hyperspace-blocked]"];
362 : }
363 :
364 : - (void) playHyperspaceDistanceTooGreat
365 : {
366 : [self playInterfaceBeep:@"[witch-too-far]"];
367 : }
368 :
369 : - (void) playCloakingDeviceOn
370 : {
371 : [self playInterfaceBeep:@"[cloaking-device-on]"];
372 : }
373 :
374 :
375 : - (void) playCloakingDeviceOff
376 : {
377 : [self playInterfaceBeep:@"[cloaking-device-off]"];
378 : }
379 :
380 :
381 : - (void) playMenuNavigationUp
382 : {
383 : [self playInterfaceBeep:@"[menu-navigation-up]"];
384 : }
385 :
386 :
387 : - (void) playMenuNavigationDown
388 : {
389 : [self playInterfaceBeep:@"[menu-navigation-down]"];
390 : }
391 :
392 :
393 : - (void) playMenuNavigationNot
394 : {
395 : [self playInterfaceBeep:@"[menu-navigation-not]"];
396 : }
397 :
398 :
399 : - (void) playMenuPagePrevious
400 : {
401 : [self playInterfaceBeep:@"[menu-next-page]"];
402 : }
403 :
404 :
405 : - (void) playMenuPageNext
406 : {
407 : [self playInterfaceBeep:@"[menu-previous-page]"];
408 : }
409 :
410 :
411 : - (void) playDismissedReportScreen
412 : {
413 : [self playInterfaceBeep:@"[dismissed-report-screen]"];
414 : }
415 :
416 :
417 : - (void) playDismissedMissionScreen
418 : {
419 : [self playInterfaceBeep:@"[dismissed-mission-screen]"];
420 : }
421 :
422 :
423 : - (void) playChangedOption
424 : {
425 : [self playInterfaceBeep:@"[changed-option]"];
426 : }
427 :
428 :
429 : - (void) updateFuelScoopSoundWithInterval:(OOTimeDelta)delta_t
430 : {
431 : static double scoopSoundPlayTime = 0.0;
432 : scoopSoundPlayTime -= delta_t;
433 : if (scoopSoundPlayTime < 0.0)
434 : {
435 : if(![sInterfaceBeepSource isPlaying])
436 : {
437 : /* TODO: this should use the scoop position, not the standard
438 : * interface beep position */
439 : [self playInterfaceBeep:@"[scoop]"];
440 : scoopSoundPlayTime = 0.5;
441 : }
442 : else scoopSoundPlayTime = 0.0;
443 : }
444 : if (![self scoopOverride])
445 : {
446 : scoopSoundPlayTime = 0.0;
447 : }
448 : }
449 :
450 :
451 : // time delay method for playing afterburner sounds
452 : // this overlaps two sounds each 2 seconds long, but with a 0.75s
453 : // crossfade
454 0 : - (void) updateAfterburnerSound
455 : {
456 : static uint8_t which = 0;
457 :
458 : if (!afterburner_engaged) // end the loop cycle
459 : {
460 : afterburnerSoundLooping = NO;
461 : }
462 :
463 : if (afterburnerSoundLooping)
464 : {
465 : [sAfterburnerSources[which] play];
466 : which = !which;
467 :
468 : [self performSelector:@selector(updateAfterburnerSound)
469 : withObject:NULL
470 : afterDelay:1.25]; // and swap sounds in 1.25s time
471 : }
472 : }
473 :
474 :
475 : - (void) startAfterburnerSound
476 : {
477 : if (!afterburnerSoundLooping)
478 : {
479 : afterburnerSoundLooping = YES;
480 : [self updateAfterburnerSound];
481 : }
482 : }
483 :
484 :
485 : - (void) stopAfterburnerSound
486 : {
487 : // Do nothing, stop is detected in updateAfterburnerSound
488 : }
489 :
490 :
491 : - (void) playCloakingDeviceInsufficientEnergy
492 : {
493 : [self playInterfaceBeep:@"[cloaking-device-insufficent-energy]"];
494 : }
495 :
496 :
497 : - (void) playBuyCommodity
498 : {
499 : [sBuySellSourcePool playSoundWithKey:@"[buy-commodity]"];
500 : }
501 :
502 :
503 : - (void) playBuyShip
504 : {
505 : [sBuySellSourcePool playSoundWithKey:@"[buy-ship]"];
506 : }
507 :
508 :
509 : - (void) playSellCommodity
510 : {
511 : [sBuySellSourcePool playSoundWithKey:@"[sell-commodity]"];
512 : }
513 :
514 :
515 : - (void) playCantBuyCommodity
516 : {
517 : [sBuySellSourcePool playSoundWithKey:@"[could-not-buy-commodity]"];
518 : }
519 :
520 :
521 : - (void) playCantSellCommodity
522 : {
523 : [sBuySellSourcePool playSoundWithKey:@"[could-not-sell-commodity]"];
524 : }
525 :
526 :
527 : - (void) playCantBuyShip
528 : {
529 : [sBuySellSourcePool playSoundWithKey:@"[could-not-buy-ship]"];
530 : }
531 :
532 :
533 : - (void) playStandardHyperspace
534 : {
535 : [sHyperspaceSoundSource playCustomSoundWithKey:@"[hyperspace-countdown-begun]"];
536 : }
537 :
538 :
539 : - (void) playGalacticHyperspace
540 : {
541 : [sHyperspaceSoundSource playCustomSoundWithKey:@"[galactic-hyperspace-countdown-begun]"];
542 : }
543 :
544 :
545 : - (void) playHyperspaceAborted
546 : {
547 : [sHyperspaceSoundSource playCustomSoundWithKey:@"[hyperspace-countdown-aborted]"];
548 : }
549 :
550 :
551 : - (void) playHitByECMSound
552 : {
553 : if (![sEcmSource isPlaying]) [sEcmSource playCustomSoundWithKey:@"[player-hit-by-ecm]"];
554 : }
555 :
556 :
557 : - (void) playFiredECMSound
558 : {
559 : if (![sEcmSource isPlaying]) [sEcmSource playCustomSoundWithKey:@"[player-fired-ecm]"];
560 : }
561 :
562 :
563 : - (void) playLaunchFromStation
564 : {
565 : [sBreakPatternSource playCustomSoundWithKey:@"[player-launch-from-station]"];
566 : }
567 :
568 :
569 : - (void) playDockWithStation
570 : {
571 : [sBreakPatternSource playCustomSoundWithKey:@"[player-dock-with-station]"];
572 : }
573 :
574 :
575 : - (void) playExitWitchspace
576 : {
577 : [sBreakPatternSource playCustomSoundWithKey:@"[player-exit-witchspace]"];
578 : }
579 :
580 :
581 : - (void) playHostileWarning
582 : {
583 : [sWarningSoundPool playSoundWithKey:@"[hostile-warning]" priority:1 position:kInterfaceWarningPosition];
584 : }
585 :
586 :
587 : - (void) playAlertConditionRed
588 : {
589 : [sWarningSoundPool playSoundWithKey:@"[alert-condition-red]" priority:2 position:kInterfaceWarningPosition];
590 : }
591 :
592 :
593 : - (void) playIncomingMissile:(Vector)missileVector
594 : {
595 : [sWarningSoundPool playSoundWithKey:@"[incoming-missile]" priority:3 position:missileVector];
596 : }
597 :
598 :
599 : - (void) playEnergyLow
600 : {
601 : [sWarningSoundPool playSoundWithKey:@"[energy-low]" priority:0.5 position:kInterfaceWarningPosition];
602 : }
603 :
604 :
605 : - (void) playDockingDenied
606 : {
607 : [sWarningSoundPool playSoundWithKey:@"[autopilot-denied]" priority:1 position:kInterfaceWarningPosition];
608 : }
609 :
610 :
611 : - (void) playWitchjumpFailure
612 : {
613 : [sWarningSoundPool playSoundWithKey:@"[witchdrive-failure]" priority:1.5 position:kWitchspacePosition];
614 : }
615 :
616 :
617 : - (void) playWitchjumpMisjump
618 : {
619 : [sWarningSoundPool playSoundWithKey:@"[witchdrive-malfunction]" priority:1.5 position:kWitchspacePosition];
620 : }
621 :
622 :
623 : - (void) playWitchjumpBlocked
624 : {
625 : [sWarningSoundPool playSoundWithKey:@"[witch-blocked-by-@]" priority:1.3 position:kWitchspacePosition];
626 : }
627 :
628 :
629 : - (void) playWitchjumpDistanceTooGreat
630 : {
631 : [sWarningSoundPool playSoundWithKey:@"[witch-too-far]" priority:1.3 position:kWitchspacePosition];
632 : }
633 :
634 :
635 : - (void) playWitchjumpInsufficientFuel
636 : {
637 : [sWarningSoundPool playSoundWithKey:@"[witch-no-fuel]" priority:1.3 position:kWitchspacePosition];
638 : }
639 :
640 :
641 : - (void) playFuelLeak
642 : {
643 : [sWarningSoundPool playSoundWithKey:@"[fuel-leak]" priority:0.5 position:kWitchspacePosition];
644 : }
645 :
646 :
647 : - (void) playShieldHit:(Vector)attackVector weaponIdentifier:(NSString *)weaponIdentifier
648 : {
649 : NSString *identifier = [weaponShieldHit objectForKey:weaponIdentifier];
650 : if (!identifier) identifier = @"[player-hit-by-weapon]";
651 : [sDamageSoundPool playSoundWithKey:identifier position:attackVector];
652 : }
653 :
654 :
655 : - (void) playDirectHit:(Vector)attackVector weaponIdentifier:(NSString *) weaponIdentifier
656 : {
657 : NSString *identifier = [weaponUnshieldedHit objectForKey:weaponIdentifier];
658 : if (!identifier) identifier = @"[player-direct-hit]";
659 : [sDamageSoundPool playSoundWithKey:identifier position:attackVector];
660 : }
661 :
662 :
663 : - (void) playScrapeDamage:(Vector)attackVector
664 : {
665 : [sDamageSoundPool playSoundWithKey:@"[player-scrape-damage]" position:attackVector];
666 : }
667 :
668 :
669 : - (void) playLaserHit:(BOOL)hit offset:(Vector)weaponOffset weaponIdentifier:(NSString *)weaponIdentifier
670 : {
671 : NSString *identifier = nil;
672 : if (hit)
673 : {
674 : identifier = [weaponShotHit objectForKey:weaponIdentifier];
675 : if (!identifier) identifier = @"[player-laser-hit]";
676 : [sWeaponSoundPool playSoundWithKey:identifier priority:1.0 expiryTime:0.05 overlap:YES position:weaponOffset];
677 : }
678 : else
679 : {
680 : identifier = [weaponShotMiss objectForKey:weaponIdentifier];
681 : if (!identifier) identifier = @"[player-laser-miss]";
682 : [sWeaponSoundPool playSoundWithKey:identifier priority:1.0 expiryTime:0.05 overlap:YES position:weaponOffset];
683 :
684 : }
685 : }
686 :
687 :
688 : - (void) playWeaponOverheated:(Vector)weaponOffset
689 : {
690 : [sWeaponSoundPool playSoundWithKey:@"[weapon-overheat]" overlap:NO position:weaponOffset];
691 : }
692 :
693 :
694 : - (void) playMissileLaunched:(Vector)weaponOffset weaponIdentifier:(NSString *)weaponIdentifier
695 : {
696 : NSString *identifier = [weaponLaunched objectForKey:weaponIdentifier];
697 : if (!identifier) identifier = @"[missile_launched]";
698 : [sWeaponSoundPool playSoundWithKey:identifier position:weaponOffset];
699 : }
700 :
701 :
702 : - (void) playMineLaunched:(Vector)weaponOffset weaponIdentifier:(NSString *)weaponIdentifier
703 : {
704 : NSString *identifier = [weaponLaunched objectForKey:weaponIdentifier];
705 : if (!identifier) identifier = @"[mine_launched]";
706 : [sWeaponSoundPool playSoundWithKey:identifier position:weaponOffset];
707 : }
708 :
709 :
710 : - (void) playEscapePodScooped
711 : {
712 : [sMiscSoundPool playSoundWithKey:@"[escape-pod-scooped]" position:kInterfaceBeepPosition];
713 : }
714 :
715 :
716 : - (void) playAegisCloseToPlanet
717 : {
718 : [sMiscSoundPool playSoundWithKey:@"[aegis-planet]" position:kInterfaceBeepPosition];
719 : }
720 :
721 :
722 : - (void) playAegisCloseToStation
723 : {
724 : [sMiscSoundPool playSoundWithKey:@"[aegis-station]" position:kInterfaceBeepPosition];
725 : }
726 :
727 :
728 : - (void) playGameOver
729 : {
730 : [sMiscSoundPool playSoundWithKey:@"[game-over]"];
731 : }
732 :
733 :
734 : - (void) playLegacyScriptSound:(NSString *)key
735 : {
736 : [sMiscSoundPool playSoundWithKey:key priority:1.1];
737 : }
738 :
739 : @end
|