Index: binaries/data/mods/public/simulation/components/Attack.js =================================================================== --- binaries/data/mods/public/simulation/components/Attack.js +++ binaries/data/mods/public/simulation/components/Attack.js @@ -496,6 +496,11 @@ let cmpProjectileManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ProjectileManager); let id = cmpProjectileManager.LaunchProjectileAtPoint(this.entity, realTargetPosition, horizSpeed, gravity); + let damageSound = ""; + let cmpSound = Engine.QueryInterface(this.entity, IID_Sound); + if (cmpSound) + damageSound = cmpSound.GetSoundGroup('damage'); + let data = { "type": type, "attacker": this.entity, @@ -506,7 +511,8 @@ "projectileId": id, "bonus": this.GetBonusTemplate(type), "isSplash": false, - "attackerOwner": attackerOwner + "attackerOwner": attackerOwner, + "damageSound": damageSound }; if (this.template.Ranged.Splash) { Index: binaries/data/mods/public/simulation/components/Damage.js =================================================================== --- binaries/data/mods/public/simulation/components/Damage.js +++ binaries/data/mods/public/simulation/components/Damage.js @@ -111,6 +111,12 @@ if (!data.position) return; + // TODO: Create cpp function to start the explosion animation defined in the unit's actor file + + let cmpSoundManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_SoundManager); + if (cmpSoundManager && data.damageSound) + cmpSoundManager.PlaySoundGroupAtPosition(data.damageSound, data.position); + // Do this first in case the direct hit kills the target if (data.isSplash) { Index: binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_onager.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_onager.xml +++ binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_onager.xml @@ -12,7 +12,7 @@ 4000 5000 4.0 - 0 + 2000 Circular 10 @@ -63,6 +63,7 @@ attack/siege/ballist_attack.xml + attack/destruction/building_collapse_large.xml Index: source/simulation2/components/CCmpSoundManager.cpp =================================================================== --- source/simulation2/components/CCmpSoundManager.cpp +++ source/simulation2/components/CCmpSoundManager.cpp @@ -85,6 +85,13 @@ } } + virtual void PlaySoundGroupAtPosition(const std::wstring& name, const CFixedVector3D& sourcePos) + { + if (!g_SoundManager) + return; + g_SoundManager->PlayAsGroup(name, CVector3D(sourcePos), INVALID_ENTITY, false); + } + virtual void StopMusic() { if (!g_SoundManager) Index: source/simulation2/components/ICmpSoundManager.h =================================================================== --- source/simulation2/components/ICmpSoundManager.h +++ source/simulation2/components/ICmpSoundManager.h @@ -20,6 +20,8 @@ #include "simulation2/system/Interface.h" +#include "maths/FixedVector3D.h" + /** * Interface to the engine's sound system. */ @@ -33,6 +35,8 @@ */ virtual void PlaySoundGroup(const std::wstring& name, entity_id_t source) = 0; + virtual void PlaySoundGroupAtPosition(const std::wstring& name, const CFixedVector3D& sourcePos) = 0; + virtual void StopMusic() = 0; DECLARE_INTERFACE_TYPE(SoundManager) Index: source/simulation2/components/ICmpSoundManager.cpp =================================================================== --- source/simulation2/components/ICmpSoundManager.cpp +++ source/simulation2/components/ICmpSoundManager.cpp @@ -23,5 +23,6 @@ BEGIN_INTERFACE_WRAPPER(SoundManager) DEFINE_INTERFACE_METHOD_2("PlaySoundGroup", void, ICmpSoundManager, PlaySoundGroup, std::wstring, entity_id_t) +DEFINE_INTERFACE_METHOD_2("PlaySoundGroupAtPosition", void, ICmpSoundManager, PlaySoundGroupAtPosition, std::wstring, CFixedVector3D) DEFINE_INTERFACE_METHOD_0("StopMusic", void, ICmpSoundManager, StopMusic) END_INTERFACE_WRAPPER(SoundManager)