Index: ps/trunk/binaries/data/mods/public/simulation/components/Attack.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/Attack.js +++ ps/trunk/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 attackImpactSound = ""; + let cmpSound = Engine.QueryInterface(this.entity, IID_Sound); + if (cmpSound) + attackImpactSound = cmpSound.GetSoundGroup("attack_impact"); + let data = { "type": type, "attacker": this.entity, @@ -506,7 +511,8 @@ "projectileId": id, "bonus": this.GetBonusTemplate(type), "isSplash": false, - "attackerOwner": attackerOwner + "attackerOwner": attackerOwner, + "attackImpactSound": attackImpactSound }; if (this.template.Ranged.Splash) { Index: ps/trunk/binaries/data/mods/public/simulation/components/Damage.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/Damage.js +++ ps/trunk/binaries/data/mods/public/simulation/components/Damage.js @@ -99,6 +99,7 @@ * @param {number} data.projectileId - the id of the projectile. * @param {Vector3D} data.direction - the unit vector defining the direction. * @param {Object} data.bonus - the attack bonus template from the attacker. + * @param {string} data.attackImpactSound - the name of the sound emited on impact. * ***When splash damage*** * @param {boolean} data.friendlyFire - a flag indicating if allied entities are also damaged. * @param {number} data.radius - the radius of the splash damage. @@ -111,6 +112,10 @@ if (!data.position) return; + let cmpSoundManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_SoundManager); + if (cmpSoundManager && data.attackImpactSound) + cmpSoundManager.PlaySoundGroupAtPosition(data.attackImpactSound, data.position); + // Do this first in case the direct hit kills the target if (data.isSplash) { @@ -261,8 +266,6 @@ this.TargetKilled(data.attacker, data.target, data.attackerOwner); Engine.PostMessage(data.target, MT_Attacked, { "attacker": data.attacker, "target": data.target, "type": data.type, "damage": -targetState.change, "attackerOwner": data.attackerOwner }); - - PlaySound("attack_impact", data.attacker); }; /** Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_onager.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_onager.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_onager.xml @@ -63,6 +63,7 @@ attack/siege/ballist_attack.xml + attack/impact/siegeprojectilehit.xml Index: ps/trunk/source/simulation2/components/CCmpSoundManager.cpp =================================================================== --- ps/trunk/source/simulation2/components/CCmpSoundManager.cpp +++ ps/trunk/source/simulation2/components/CCmpSoundManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -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: ps/trunk/source/simulation2/components/ICmpSoundManager.h =================================================================== --- ps/trunk/source/simulation2/components/ICmpSoundManager.h +++ ps/trunk/source/simulation2/components/ICmpSoundManager.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -20,6 +20,8 @@ #include "simulation2/system/Interface.h" +#include "maths/FixedVector3D.h" + /** * Interface to the engine's sound system. */ @@ -33,6 +35,13 @@ */ virtual void PlaySoundGroup(const std::wstring& name, entity_id_t source) = 0; + /** + * Start playing audio defined by a sound group file. + * @param name VFS path of sound group .xml, relative to audio/ + * @param sourcePos 3d position of the sound emitter + */ + virtual void PlaySoundGroupAtPosition(const std::wstring& name, const CFixedVector3D& sourcePos) = 0; + virtual void StopMusic() = 0; DECLARE_INTERFACE_TYPE(SoundManager) Index: ps/trunk/source/simulation2/components/ICmpSoundManager.cpp =================================================================== --- ps/trunk/source/simulation2/components/ICmpSoundManager.cpp +++ ps/trunk/source/simulation2/components/ICmpSoundManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -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)