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 @@ -504,6 +504,14 @@ { let attackerOwner = Engine.QueryInterface(this.entity, IID_Ownership).GetOwner(); + let data = { + "type": type, + "attackData": this.GetAttackEffectsData(type), + "target": target, + "attacker": this.entity, + "attackerOwner": attackerOwner, + }; + // If this is a ranged attack, then launch a projectile if (type == "Ranged") { @@ -613,24 +621,17 @@ if (cmpSound) attackImpactSound = cmpSound.GetSoundGroup("attack_impact_" + type.toLowerCase()); - let data = { - "type": type, - "attackData": this.GetAttackEffectsData(type), - "target": target, - "attacker": this.entity, - "attackerOwner": attackerOwner, - "position": realTargetPosition, - "direction": missileDirection, - "projectileId": id, - "attackImpactSound": attackImpactSound, - "splash": this.GetSplashData(type), - "friendlyFire": this.template[type].Projectile.FriendlyFire == "true", - }; + data.position = realTargetPosition; + data.direction = missileDirection; + data.projectileId = id; + data.attackImpactSound = attackImpactSound; + data.splash = this.GetSplashData(type); + data.friendlyFire = this.template[type].Projectile.FriendlyFire == "true"; 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); + Attacking.HandleAttackEffects(target, data); }; Attack.prototype.OnValueModification = function(msg) Index: ps/trunk/binaries/data/mods/public/simulation/components/DelayedDamage.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/DelayedDamage.js +++ ps/trunk/binaries/data/mods/public/simulation/components/DelayedDamage.js @@ -68,7 +68,7 @@ // 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)) + Attacking.HandleAttackEffects(target, data)) { cmpProjectileManager.RemoveProjectile(data.projectileId); return; @@ -81,7 +81,7 @@ for (let ent of ents) { if (!PositionHelper.TestCollision(ent, data.position, lateness) || - !Attacking.HandleAttackEffects(ent, data.type, data.attackData, data.attacker, data.attackerOwner)) + !Attacking.HandleAttackEffects(ent, data)) continue; cmpProjectileManager.RemoveProjectile(data.projectileId); Index: ps/trunk/binaries/data/mods/public/simulation/components/StatusEffectsReceiver.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/StatusEffectsReceiver.js +++ ps/trunk/binaries/data/mods/public/simulation/components/StatusEffectsReceiver.js @@ -145,7 +145,12 @@ return; if (status.Damage || status.Capture) - Attacking.HandleAttackEffects(this.entity, statusCode, status, status.source.entity, status.source.owner); + Attacking.HandleAttackEffects(this.entity, { + "type": statusCode, + "attackData": status, + "attacker": status.source.entity, + "attackerOwner": status.source.owner + }); if (!status.Duration) return; Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Damage.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Damage.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Damage.js @@ -147,12 +147,12 @@ damageTaken = false; } - Attacking.HandleAttackEffects(target, data.type, data.attackData, data.attacker, data.attackerOwner); + Attacking.HandleAttackEffects(target, data); TestDamage(); data.type = "Ranged"; type = data.type; - Attacking.HandleAttackEffects(target, data.type, data.attackData, data.attacker, data.attackerOwner); + Attacking.HandleAttackEffects(target, data); TestDamage(); // Check for damage still being dealt if the attacker dies @@ -607,7 +607,7 @@ "DistanceToPoint": (ent) => 0 }); - let bonus= { "BonusCav": { "Classes": "Cavalry", "Multiplier": 400 } }; + let bonus = { "BonusCav": { "Classes": "Cavalry", "Multiplier": 400 } }; let splashBonus = { "BonusCav": { "Classes": "Cavalry", "Multiplier": 10000 } }; AddMock(61, IID_Identity, { Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Resistance.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Resistance.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Resistance.js @@ -73,14 +73,20 @@ } }); let spy = new Spy(cmpHealth, "TakeDamage"); + let data = { + "type": attackType, + "attackData": attackData, + "attacker": this.AttackerID, + "attackerOwner": this.EnemyID + }; - Attacking.HandleAttackEffects(this.EntityID, attackType, attackData, this.AttackerID, this.EnemyID); + Attacking.HandleAttackEffects(this.EntityID, data); TS_ASSERT_EQUALS(spy._called, 1); this.cmpResistance.SetInvulnerability(true); TS_ASSERT(this.cmpResistance.IsInvulnerable()); - Attacking.HandleAttackEffects(this.EntityID, attackType, attackData, this.AttackerID, this.EnemyID); + Attacking.HandleAttackEffects(this.EntityID, data); TS_ASSERT_EQUALS(spy._called, 1); } @@ -114,7 +120,12 @@ }); let spy = new Spy(cmpHealth, "TakeDamage"); - Attacking.HandleAttackEffects(this.EntityID, "Test", attackData, this.AttackerID, this.EnemyID); + Attacking.HandleAttackEffects(this.EntityID, { + "type": "Test", + "attackData": attackData, + "attacker": this.AttackerID, + "attackerOwner": this.EnemyID + }); TS_ASSERT_EQUALS(spy._called, 1); } @@ -143,7 +154,12 @@ }); let spy = new Spy(cmpHealth, "TakeDamage"); - Attacking.HandleAttackEffects(this.EntityID, "Test", attackData, this.AttackerID, this.EnemyID); + Attacking.HandleAttackEffects(this.EntityID, { + "type": "Test", + "attackData": attackData, + "attacker": this.AttackerID, + "attackerOwner": this.EnemyID + }); TS_ASSERT_EQUALS(spy._called, 1); } @@ -169,7 +185,12 @@ }); let spy = new Spy(cmpCapturable, "Capture"); - Attacking.HandleAttackEffects(this.EntityID, "Test", attackData, this.AttackerID, this.EnemyID); + Attacking.HandleAttackEffects(this.EntityID, { + "type": "Test", + "attackData": attackData, + "attacker": this.AttackerID, + "attackerOwner": this.EnemyID + }); TS_ASSERT_EQUALS(spy._called, 1); } @@ -205,7 +226,12 @@ }); let spy = new Spy(cmpStatusEffectsReceiver, "ApplyStatus"); - Attacking.HandleAttackEffects(this.EntityID, "Test", attackData, this.AttackerID, this.EnemyID); + Attacking.HandleAttackEffects(this.EntityID, { + "type": "Test", + "attackData": attackData, + "attacker": this.AttackerID, + "attackerOwner": this.EnemyID + }); TS_ASSERT_EQUALS(spy._called, 1); // Test blocking. @@ -227,7 +253,12 @@ }); spy = new Spy(cmpStatusEffectsReceiver, "ApplyStatus"); - Attacking.HandleAttackEffects(this.EntityID, "Test", attackData, this.AttackerID, this.EnemyID); + Attacking.HandleAttackEffects(this.EntityID, { + "type": "Test", + "attackData": attackData, + "attacker": this.AttackerID, + "attackerOwner": this.EnemyID + }); TS_ASSERT_EQUALS(spy._called, 1); // Test multiple resistances. @@ -266,7 +297,12 @@ }); spy = new Spy(cmpStatusEffectsReceiver, "ApplyStatus"); - Attacking.HandleAttackEffects(this.EntityID, "Test", attackData, this.AttackerID, this.EnemyID); + Attacking.HandleAttackEffects(this.EntityID, { + "type": "Test", + "attackData": attackData, + "attacker": this.AttackerID, + "attackerOwner": this.EnemyID + }); TS_ASSERT_EQUALS(spy._called, 1); } @@ -308,7 +344,12 @@ }); let spy = new Spy(cmpHealth, "TakeDamage"); - Attacking.HandleAttackEffects(this.EntityID, "Test", attackData, this.AttackerID, this.EnemyID); + Attacking.HandleAttackEffects(this.EntityID, { + "type": "Test", + "attackData": attackData, + "attacker": this.AttackerID, + "attackerOwner": this.EnemyID + }); TS_ASSERT_EQUALS(spy._called, 1); } @@ -357,7 +398,12 @@ let healthSpy = new Spy(cmpHealth, "TakeDamage"); let captureSpy = new Spy(cmpCapturable, "Capture"); - Attacking.HandleAttackEffects(this.EntityID, "Test", attackData, this.AttackerID, this.EnemyID); + Attacking.HandleAttackEffects(this.EntityID, { + "type": "Test", + "attackData": attackData, + "attacker": this.AttackerID, + "attackerOwner": this.EnemyID + }); TS_ASSERT_EQUALS(healthSpy._called, 1); TS_ASSERT_EQUALS(captureSpy._called, 1); } Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_StatusEffectsReceiver.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_StatusEffectsReceiver.js +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_StatusEffectsReceiver.js @@ -19,9 +19,9 @@ let statusName; let Attacking = { - "HandleAttackEffects": (_, __, attackData) => { - for (let type in attackData.Damage) - dealtDamage += attackData.Damage[type]; + "HandleAttackEffects": (_, data) => { + for (let type in data.attackData.Damage) + dealtDamage += data.attackData.Damage[type]; } }; Engine.RegisterGlobal("Attacking", Attacking); Index: ps/trunk/binaries/data/mods/public/simulation/helpers/Attacking.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/helpers/Attacking.js +++ ps/trunk/binaries/data/mods/public/simulation/helpers/Attacking.js @@ -283,61 +283,63 @@ // so the multiplier can end up below 0. damageMultiplier = Math.max(0, damageMultiplier); - this.HandleAttackEffects(ent, data.type + ".Splash", data.attackData, data.attacker, data.attackerOwner, damageMultiplier); + data.type += ".Splash"; + this.HandleAttackEffects(ent, data, damageMultiplier); } }; /** * Handle an attack peformed on an entity. * * @param {number} target - The targetted entityID. - * @param {string} attackType - The type of attack that was performed (e.g. "Melee" or "Capture"). - * @param {Object} effectData - The effects use. - * @param {number} attacker - The entityID that attacked us. - * @param {number} attackerOwner - The playerID that owned the attacker when the attack was performed. + * @param {Object} data - The data of the attack. + * @param {string} data.type - The type of attack that was performed (e.g. "Melee" or "Capture"). + * @param {Object} data.effectData - The effects use. + * @param {number} data.attacker - The entityID that attacked us. + * @param {number} data.attackerOwner - The playerID that owned the attacker when the attack was performed. * @param {number} bonusMultiplier - The factor to multiply the total effect with, defaults to 1. * * @return {boolean} - Whether we handled the attack. */ -Attacking.prototype.HandleAttackEffects = function(target, attackType, attackData, attacker, attackerOwner, bonusMultiplier = 1) +Attacking.prototype.HandleAttackEffects = function(target, data, bonusMultiplier = 1) { let cmpResistance = Engine.QueryInterface(target, IID_Resistance); if (cmpResistance && cmpResistance.IsInvulnerable()) return false; - bonusMultiplier *= !attackData.Bonuses ? 1 : this.GetAttackBonus(attacker, target, attackType, attackData.Bonuses); + bonusMultiplier *= !data.attackData.Bonuses ? 1 : this.GetAttackBonus(data.attacker, target, data.type, data.attackData.Bonuses); let targetState = {}; for (let receiver of g_AttackEffects.Receivers()) { - if (!attackData[receiver.type]) + if (!data.attackData[receiver.type]) continue; let cmpReceiver = Engine.QueryInterface(target, global[receiver.IID]); if (!cmpReceiver) continue; - Object.assign(targetState, cmpReceiver[receiver.method](this.GetTotalAttackEffects(target, attackData, receiver.type, bonusMultiplier, cmpResistance), attacker, attackerOwner)); + Object.assign(targetState, cmpReceiver[receiver.method](this.GetTotalAttackEffects(target, data.attackData, receiver.type, bonusMultiplier, cmpResistance), data.attacker, data.attackerOwner)); } if (!Object.keys(targetState).length) return false; Engine.PostMessage(target, MT_Attacked, { - "type": attackType, + "type": data.type, "target": target, - "attacker": attacker, - "attackerOwner": attackerOwner, + "attacker": data.attacker, + "attackerOwner": data.attackerOwner, "damage": -(targetState.healthChange || 0), "capture": targetState.captureChange || 0, "statusEffects": targetState.inflictedStatuses || [], - "fromStatusEffect": !!attackData.StatusEffect, + "fromStatusEffect": !!data.attackData.StatusEffect, }); // We do not want an entity to get XP from active Status Effects. - if (!!attackData.StatusEffect) + if (!!data.attackData.StatusEffect) return true; - let cmpPromotion = Engine.QueryInterface(attacker, IID_Promotion); + let cmpPromotion = Engine.QueryInterface(data.attacker, IID_Promotion); if (cmpPromotion && targetState.xp) cmpPromotion.IncreaseXp(targetState.xp); Index: ps/trunk/binaries/data/mods/public/simulation/helpers/tests/test_Attacking.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/helpers/tests/test_Attacking.js +++ ps/trunk/binaries/data/mods/public/simulation/helpers/tests/test_Attacking.js @@ -59,7 +59,12 @@ "Capture": x => { this.resultString += x; }, }); - Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, "Test", this.attackData, INVALID_ENTITY, INVALID_PLAYER); + Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, { + "type": "Test", + "attackData": this.attackData, + "attacker": INVALID_ENTITY, + "attackerOwner": INVALID_PLAYER + }); TS_ASSERT(this.resultString.indexOf(this.attackData.Damage) !== -1); TS_ASSERT(this.resultString.indexOf(this.attackData.Capture) !== -1); @@ -73,7 +78,12 @@ "Capture": x => { this.resultString += x; }, }); - Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, "Test", this.attackData, INVALID_ENTITY, INVALID_PLAYER); + Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, { + "type": "Test", + "attackData": this.attackData, + "attacker": INVALID_ENTITY, + "attackerOwner": INVALID_PLAYER + }); TS_ASSERT(this.resultString.indexOf(this.attackData.Damage) === -1); TS_ASSERT(this.resultString.indexOf(this.attackData.Capture) !== -1); @@ -85,7 +95,12 @@ "GetMaxHitpoints": () => 1, }); - Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, "Test", this.attackData, INVALID_ENTITY, INVALID_PLAYER); + Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, { + "type": "Test", + "attackData": this.attackData, + "attacker": INVALID_ENTITY, + "attackerOwner": INVALID_PLAYER + }); TS_ASSERT(this.resultString.indexOf(this.attackData.Damage) !== -1); TS_ASSERT(this.resultString.indexOf(this.attackData.Capture) === -1); } @@ -95,14 +110,24 @@ */ testAttackedMessage() { Engine.PostMessage = () => TS_ASSERT(false); - Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, "Test", this.attackData, INVALID_ENTITY, INVALID_PLAYER); + Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, { + "type": "Test", + "attackData": this.attackData, + "attacker": INVALID_ENTITY, + "attackerOwner": INVALID_PLAYER + }); AddMock(this.TESTED_ENTITY_ID, IID_Capturable, { "Capture": () => ({ "captureChange": 0 }), }); let count = 0; Engine.PostMessage = () => count++; - Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, "Test", this.attackData, INVALID_ENTITY, INVALID_PLAYER); + Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, { + "type": "Test", + "attackData": this.attackData, + "attacker": INVALID_ENTITY, + "attackerOwner": INVALID_PLAYER + }); TS_ASSERT_EQUALS(count, 1); AddMock(this.TESTED_ENTITY_ID, IID_Health, { @@ -112,7 +137,12 @@ }); count = 0; Engine.PostMessage = () => count++; - Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, "Test", this.attackData, INVALID_ENTITY, INVALID_PLAYER); + Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, { + "type": "Test", + "attackData": this.attackData, + "attacker": INVALID_ENTITY, + "attackerOwner": INVALID_PLAYER + }); TS_ASSERT_EQUALS(count, 1); } @@ -127,7 +157,12 @@ }); let spy = new Spy(cmpStatusEffectsReceiver, "ApplyStatus"); - Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, "Test", this.attackData, INVALID_ENTITY, INVALID_PLAYER, 2); + Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, { + "type": "Test", + "attackData": this.attackData, + "attacker": INVALID_ENTITY, + "attackerOwner": INVALID_PLAYER + }, 2); TS_ASSERT_EQUALS(spy._called, 1); } @@ -148,7 +183,12 @@ }, }); - Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, "Test", this.attackData, INVALID_ENTITY, INVALID_PLAYER, 2); + Attacking.HandleAttackEffects(this.TESTED_ENTITY_ID, { + "type": "Test", + "attackData": this.attackData, + "attacker": INVALID_ENTITY, + "attackerOwner": INVALID_PLAYER + }, 2); } }