30
30
#include < utility>
31
31
#include < vector>
32
32
33
- bool IsSoundPlaying (const char *const name, const C4Object * const obj )
33
+ bool IsSoundPlaying (const char *const name, const C4SoundSystem::TargetVariant target )
34
34
{
35
- return Application.SoundSystem ->FindInst (name, obj ).has_value ();
35
+ return Application.SoundSystem ->FindInst (name, target ).has_value ();
36
36
}
37
37
38
- void SoundLevel (const char *const name, C4Object * const obj , const std::int32_t level)
38
+ void SoundLevel (const char *const name, const C4SoundSystem::TargetVariant target , const std::int32_t level)
39
39
{
40
40
// Sound level zero? Stop
41
- if (level <= 0 ) { StopSoundEffect (name, obj ); return ; }
41
+ if (level <= 0 ) { StopSoundEffect (name, target ); return ; }
42
42
// Set volume of existing instance or create new instance
43
- const auto it = Application.SoundSystem ->FindInst (name, obj );
43
+ const auto it = Application.SoundSystem ->FindInst (name, target );
44
44
if (it)
45
45
{
46
46
(**it).volume = level;
47
47
}
48
48
else
49
49
{
50
- StartSoundEffect (name, true , level, obj );
50
+ StartSoundEffect (name, true , level, target );
51
51
}
52
52
}
53
53
54
54
bool StartSoundEffect (const char *const name, const bool loop, const std::int32_t volume,
55
- C4Object * const obj , const std::int32_t falloffDistance)
55
+ const C4SoundSystem::TargetVariant target , const std::int32_t falloffDistance)
56
56
{
57
- return Application.SoundSystem ->NewInstance (name, loop, volume, 0 , obj , falloffDistance) != nullptr ;
57
+ return Application.SoundSystem ->NewInstance (name, loop, volume, 0 , target , falloffDistance) != nullptr ;
58
58
}
59
59
60
60
void StartSoundEffectAt (const char *const name, C4Section §ion, const std::int32_t x, const std::int32_t y)
61
61
{
62
62
std::int32_t volume, pan;
63
63
Application.SoundSystem ->GetVolumeByPos (section, x, y, volume, pan);
64
- Application.SoundSystem ->NewInstance (name, false , volume, pan, nullptr , 0 );
64
+ Application.SoundSystem ->NewInstance (name, false , volume, pan, C4SoundSystem::Position{§ion, x, y} , 0 );
65
65
}
66
66
67
- void StopSoundEffect (const char *const name, const C4Object * const obj )
67
+ void StopSoundEffect (const char *const name, const C4SoundSystem::TargetVariant target )
68
68
{
69
- if (const auto it = Application.SoundSystem ->FindInst (name, obj ))
69
+ if (const auto it = Application.SoundSystem ->FindInst (name, target ))
70
70
{
71
71
(**it).sample .instances .erase (*it);
72
72
}
@@ -156,7 +156,7 @@ bool C4SoundSystem::Instance::DetachObj()
156
156
if (loop) return false ;
157
157
// Otherwise: set volume by last position
158
158
const auto detachedObj = GetObj ();
159
- obj .emplace <const ObjPos>(* detachedObj);
159
+ target .emplace <Position>( detachedObj-> Section , detachedObj-> x , detachedObj-> y );
160
160
GetVolumeByPos (*detachedObj->Section , detachedObj->x , detachedObj->y , volume, pan);
161
161
162
162
// Do not stop instance
@@ -200,6 +200,10 @@ bool C4SoundSystem::Instance::Execute(const bool justStarted)
200
200
vol *= audibility / 100 .0f ;
201
201
pan += obj->GetAudiblePan () / 100 .0f ;
202
202
}
203
+ else if (C4Section *const *const section{std::get_if<C4Section *>(&target)}; section && !Game.GraphicsSystem .IsSectionAudible (**section))
204
+ {
205
+ vol = 0 .0f ;
206
+ }
203
207
204
208
// Sound off? Release channel to make it available for other instances.
205
209
if (vol <= 0 .0f )
@@ -237,7 +241,7 @@ bool C4SoundSystem::Instance::Execute(const bool justStarted)
237
241
238
242
C4Object *C4SoundSystem::Instance::GetObj () const
239
243
{
240
- const auto ptr = std::get_if<C4Object *>(&obj );
244
+ const auto ptr = std::get_if<C4Object *>(&target );
241
245
return ptr ? *ptr : nullptr ;
242
246
}
243
247
@@ -252,10 +256,10 @@ std::uint32_t C4SoundSystem::Instance::GetPlaybackPosition() const
252
256
bool C4SoundSystem::Instance::IsNear (const C4Object &obj2) const
253
257
{
254
258
// Attached to object?
255
- if (const auto objAsObject = std::get_if<C4Object *>(&obj ); objAsObject && *objAsObject )
259
+ if (const auto targetAsObject = std::get_if<C4Object *>(&target ); targetAsObject && *targetAsObject )
256
260
{
257
- const auto x = (**objAsObject ).x ;
258
- const auto y = (**objAsObject ).y ;
261
+ const auto x = (**targetAsObject ).x ;
262
+ const auto y = (**targetAsObject ).y ;
259
263
return (x - obj2.x ) * (x - obj2.x ) + (y - obj2.y ) * (y - obj2.y ) <=
260
264
NearSoundRadius * NearSoundRadius;
261
265
}
@@ -267,7 +271,7 @@ bool C4SoundSystem::Instance::IsNear(const C4Object &obj2) const
267
271
return false ;
268
272
}
269
273
270
- auto C4SoundSystem::FindInst (const char *wildcard, const C4Object * const obj ) ->
274
+ auto C4SoundSystem::FindInst (const char *wildcard, const TargetVariant target ) ->
271
275
std::optional<decltype(Sample::instances)::iterator>
272
276
{
273
277
const auto wildcardStr = PrepareFilename (wildcard);
@@ -279,7 +283,7 @@ auto C4SoundSystem::FindInst(const char *wildcard, const C4Object *const obj) ->
279
283
if (!WildcardMatch (wildcard, sample.name .c_str ())) continue ;
280
284
// Try to find an instance that is bound to obj
281
285
auto it = std::find_if (sample.instances .begin (), sample.instances .end (),
282
- [&](const auto &inst) { return inst.GetObj () == obj ; });
286
+ [&](const auto &inst) { return inst.target == target ; });
283
287
if (it != sample.instances .end ()) return it;
284
288
}
285
289
@@ -299,7 +303,7 @@ void C4SoundSystem::GetVolumeByPos(C4Section §ion, std::int32_t x, std::int3
299
303
}
300
304
301
305
auto C4SoundSystem::NewInstance (const char *filename, const bool loop,
302
- const std::int32_t volume, const std::int32_t pan, C4Object * const obj ,
306
+ const std::int32_t volume, const std::int32_t pan, const TargetVariant target ,
303
307
const std::int32_t falloffDistance) -> Instance *
304
308
{
305
309
if (!Application.AudioSystem ) return nullptr ;
@@ -340,15 +344,13 @@ auto C4SoundSystem::NewInstance(const char *filename, const bool loop,
340
344
if (!loop && sample->instances .size () >= MaxSoundInstances) return nullptr ;
341
345
342
346
// Already playing near?
343
- const auto nearIt = obj ?
344
- std::find_if (sample->instances .cbegin (), sample->instances .cend (),
345
- [&](const auto &inst) { return inst.IsNear (*obj); }) :
346
- std::find_if (sample->instances .cbegin (), sample->instances .cend (),
347
- [](const auto &inst) { return !inst.GetObj (); });
347
+ const auto nearIt = std::holds_alternative<C4Object *>(target)
348
+ ? std::find_if (sample->instances .cbegin (), sample->instances .cend (), [&](const auto &inst) { return inst.IsNear (*std::get<C4Object *>(target)); })
349
+ : std::find_if (sample->instances .cbegin (), sample->instances .cend (), [&](const auto &inst) { return inst.target == target; });
348
350
if (nearIt != sample->instances .cend ()) return nullptr ;
349
351
350
352
// Create instance
351
- auto &inst = sample->instances .emplace_back (*sample, loop, volume, obj , falloffDistance);
353
+ auto &inst = sample->instances .emplace_back (*sample, loop, volume, target , falloffDistance);
352
354
if (!inst.Execute (true ))
353
355
{
354
356
sample->instances .pop_back ();
0 commit comments