Index: binaries/data/mods/public/globalscripts/AttackEffects.js =================================================================== --- binaries/data/mods/public/globalscripts/AttackEffects.js +++ binaries/data/mods/public/globalscripts/AttackEffects.js @@ -15,3 +15,10 @@ "method": "ApplyStatus" } }; + +const g_ImpactSoundsClasses = { + "flesh": ["Organic"], + "stone": ["Structure"], + "metal": ["Champion"], + "wood": ["Ship"] +} 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 @@ -575,12 +575,6 @@ } let id = cmpProjectileManager.LaunchProjectileAtPoint(launchPoint, realTargetPosition, horizSpeed, gravity, actorName, impactActorName, impactAnimationLifetime); - - let attackImpactSound = ""; - let cmpSound = Engine.QueryInterface(this.entity, IID_Sound); - if (cmpSound) - attackImpactSound = cmpSound.GetSoundGroup("attack_impact_" + type.toLowerCase()); - let data = { "type": type, "attackData": this.GetAttackEffectsData(type), @@ -590,7 +584,6 @@ "position": realTargetPosition, "direction": missileDirection, "projectileId": id, - "attackImpactSound": attackImpactSound, "splash": this.GetSplashData(type), "friendlyFire": this.template[type].Projectile.FriendlyFire == "true", }; @@ -598,7 +591,12 @@ cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_DelayedDamage, "MissileHit", +this.template[type].Delay + timeToTarget * 1000, data); } else + { Attacking.HandleAttackEffects(target, type, this.GetAttackEffectsData(type), this.entity, attackerOwner); + let impactSoundGroup = GetImpactSoundGroup(type, target, this.entity, false); + if (impactSoundGroup) + PlaySound(impactSoundGroup, this.entity); + } }; Attack.prototype.OnValueModification = function(msg) Index: binaries/data/mods/public/simulation/components/DelayedDamage.js =================================================================== --- binaries/data/mods/public/simulation/components/DelayedDamage.js +++ binaries/data/mods/public/simulation/components/DelayedDamage.js @@ -39,9 +39,6 @@ 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.splash) @@ -65,10 +62,15 @@ if (cmpMirage) target = cmpMirage.GetParent(); + var hitTarget = PositionHelper.TestCollision(target, data.position, lateness) && + Attacking.HandleAttackEffects(target, data.type, data.attackData, data.attacker, data.attackerOwner); + + let cmpSoundManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_SoundManager); + if (cmpSoundManager) + cmpSoundManager.PlaySoundGroupAtPosition(GetImpactSoundGroup(data.type, target, data.attacker, !hitTarget), data.position); // Deal direct damage if we hit the main target // and we could handle the attack. - if (PositionHelper.TestCollision(target, data.position, lateness) && - Attacking.HandleAttackEffects(target, data.type, data.attackData, data.attacker, data.attackerOwner)) + if (hitTarget) { cmpProjectileManager.RemoveProjectile(data.projectileId); return; Index: binaries/data/mods/public/simulation/helpers/Sound.js =================================================================== --- binaries/data/mods/public/simulation/helpers/Sound.js +++ binaries/data/mods/public/simulation/helpers/Sound.js @@ -10,4 +10,35 @@ cmpSound.PlaySoundGroup(name); } +/** + * Gets the matching impact sound group depending on the . + * @param {string} type - The type of damage. + * @param {number} target - The entity id of the target. + * @param {number} attacker - The entity id of the attacker. + * @param {boolean} missed - Whether the target was missed. + * @return {string} - The impact sound group. + */ +function GetImpactSoundGroup(type, target, attacker, missed) +{ + let cmpSound = Engine.QueryInterface(attacker, IID_Sound); + if (!cmpSound) + return ""; + + let attackImpactType = "attack_impact_" + type.toLowerCase(); + if (missed) + return cmpSound.GetSoundGroup(attackImpactType + "_missed"); + + let cmpIdentity = Engine.QueryInterface(target, IID_Identity); + if (cmpIdentity) + { + let classes = cmpIdentity.GetClassesList(); + for(let impactClass in g_ImpactSoundsClasses) + if(MatchesClassList(classes, g_ImpactSoundsClasses[impactType])) + return cmpSound.GetSoundGroup(attackImpactType + "_" + impactClass); + } + + return cmpSound.GetSoundGroup(attackImpactType); +} + +Engine.RegisterGlobal("GetImpactSoundGroup", GetImpactSoundGroup); Engine.RegisterGlobal("PlaySound", PlaySound); Index: binaries/data/mods/public/simulation/templates/template_unit.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_unit.xml +++ binaries/data/mods/public/simulation/templates/template_unit.xml @@ -112,6 +112,13 @@ interface/alarm/alarm_attackplayer.xml interface/alarm/alarm_attacked_gaia.xml attack/weapon/sword_attack.xml + attack/impact/shield_wooden.xml + attack/impact/shield_metal.xml + attack/impact/shield_wooden.xml + attack/impact/shield_wooden.xml + attack/impact/arrow_metal.xml + attack/impact/javelin_impact.xml + attack/impact/javelin_impact.xml