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", }; 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) @@ -71,6 +68,7 @@ Attacking.HandleAttackEffects(target, data.type, data.attackData, data.attacker, data.attackerOwner)) { cmpProjectileManager.RemoveProjectile(data.projectileId); + this.PlayImpactSound(data.attacker, data.type, data.position); return; } @@ -85,8 +83,26 @@ continue; cmpProjectileManager.RemoveProjectile(data.projectileId); - break; + this.PlayImpactSound(data.attacker, data.type, data.position); + return; } + + this.PlayImpactSound(data.attacker, data.type, data.position, true); }; +DelayedDamage.prototype.PlayImpactSound = function(attacker, type, position, missed = false) +{ + let cmpSound = Engine.QueryInterface(attacker, IID_Sound) + if (!cmpSound) + return; + + let soundGroup = cmpSound.GetSoundGroup("attack_impact_" + type + (missed ? "_missed" : "")); + if (!soundGroup) + return; + + let cmpSoundManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_SoundManager); + if (cmpSoundManager) + cmpSoundManager.PlaySoundGroupAtPosition(soundGroup, position); +} + Engine.RegisterSystemComponentType(IID_DelayedDamage, "DelayedDamage", DelayedDamage); Index: binaries/data/mods/public/simulation/components/Identity.js =================================================================== --- binaries/data/mods/public/simulation/components/Identity.js +++ binaries/data/mods/public/simulation/components/Identity.js @@ -28,6 +28,11 @@ "" + "" + "" + + "" + + "" + + "" + + "" + + "" + "" + "" + "" + @@ -186,6 +191,11 @@ return this.template.GenericName; }; +Identity.prototype.GetMaterial = function() +{ + return this.template.Material; +}; + Identity.prototype.IsUndeletable = function() { return this.template.Undeletable == "true"; Index: binaries/data/mods/public/simulation/components/tests/test_Damage.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_Damage.js +++ binaries/data/mods/public/simulation/components/tests/test_Damage.js @@ -14,6 +14,7 @@ Engine.LoadHelperScript("Attacking.js"); Engine.LoadHelperScript("Player.js"); Engine.LoadHelperScript("Position.js"); +Engine.LoadHelperScript("Sound.js"); Engine.LoadHelperScript("ValueModification.js"); Engine.LoadComponentScript("interfaces/DelayedDamage.js"); Engine.LoadComponentScript("interfaces/Health.js"); Index: binaries/data/mods/public/simulation/components/tests/test_Resistance.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_Resistance.js +++ binaries/data/mods/public/simulation/components/tests/test_Resistance.js @@ -23,6 +23,7 @@ Engine.LoadHelperScript("Attacking.js"); Engine.LoadHelperScript("Player.js"); +Engine.LoadHelperScript("Sound.js"); Engine.LoadHelperScript("ValueModification.js"); Engine.LoadComponentScript("interfaces/Capturable.js"); Engine.LoadComponentScript("interfaces/Foundation.js"); Index: binaries/data/mods/public/simulation/helpers/Attacking.js =================================================================== --- binaries/data/mods/public/simulation/helpers/Attacking.js +++ binaries/data/mods/public/simulation/helpers/Attacking.js @@ -301,7 +301,9 @@ Attacking.prototype.HandleAttackEffects = function(target, attackType, attackData, attacker, attackerOwner, bonusMultiplier = 1) { let cmpResistance = Engine.QueryInterface(target, IID_Resistance); - if (cmpResistance && cmpResistance.IsInvulnerable()) + let blocked = cmpResistance && cmpResistance.IsInvulnerable(); + PlayEntityHitSoundGroup(attackType, target, blocked); + if (blocked) return false; bonusMultiplier *= !attackData.Bonuses ? 1 : this.GetAttackBonus(attacker, target, attackType, attackData.Bonuses); 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,42 @@ 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. + * @return {string} - The impact sound group. + */ +function PlayEntityHitSoundGroup(type, target, blocked) +{ + let cmpSound = Engine.QueryInterface(target, IID_Sound); + if (!cmpSound) + return; + + let attackImpactType = "hit_" + type.toLowerCase(); + if (blocked) + { + cmpSound.PlaySoundGroup(attackImpactType + "_blocked"); + return; + } + + let cmpIdentity = Engine.QueryInterface(target, IID_Identity); + if (!cmpIdentity) + { + cmpSound.PlaySoundGroup(attackImpactType); + return; + } + + let material = cmpIdentity.GetMaterial(); + if (!material) + { + cmpSound.PlaySoundGroup(attackImpactType); + return; + } + + cmpSound.PlaySoundGroup(attackImpactType + "_" + material); +} + +Engine.RegisterGlobal("PlayEntityHitSoundGroup", PlayEntityHitSoundGroup); Engine.RegisterGlobal("PlaySound", PlaySound); Index: binaries/data/mods/public/simulation/helpers/tests/test_Attacking.js =================================================================== --- binaries/data/mods/public/simulation/helpers/tests/test_Attacking.js +++ binaries/data/mods/public/simulation/helpers/tests/test_Attacking.js @@ -22,6 +22,7 @@ }; Engine.LoadHelperScript("Attacking.js"); +Engine.LoadHelperScript("Sound.js"); Engine.LoadComponentScript("interfaces/Capturable.js"); Engine.LoadComponentScript("interfaces/Health.js"); Engine.LoadComponentScript("interfaces/Promotion.js"); Index: binaries/data/mods/public/simulation/templates/template_structure.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_structure.xml +++ binaries/data/mods/public/simulation/templates/template_structure.xml @@ -43,6 +43,7 @@ gaia + stone Structure Structure false @@ -149,6 +150,10 @@ interface/alarm/alarm_attacked_gaia.xml interface/alarm/alarm_attackplayer.xml interface/alarm/alarm_attacked_gaia.xml + attack/impact/arrow_metal.xml + attack/impact/arrow_metal.xml + attack/impact/arrow_impact.xml + attack/impact/arrow_impact.xml 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 @@ -35,6 +35,7 @@ gaia Unit Organic ConquestCritical Unit + flesh special/formations/null special/formations/box Index: binaries/data/mods/public/simulation/templates/template_unit_ship.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_unit_ship.xml +++ binaries/data/mods/public/simulation/templates/template_unit_ship.xml @@ -25,6 +25,7 @@ Ship + wood -Organic Ship @@ -63,6 +64,10 @@ actor/ship/warship_move_01.xml actor/ship/warship_move_01.xml actor/ship/warship_death.xml + attack/impact/shield_wooden.xml + attack/impact/shield_wooden.xml + attack/impact/arrow_metal.xml + attack/impact/arrow_impact.xml