Differential D767 Diff 3070 ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Damage.js
Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Damage.js
Show All 11 Lines | |||||
Engine.LoadComponentScript("interfaces/Promotion.js"); | Engine.LoadComponentScript("interfaces/Promotion.js"); | ||||
Engine.LoadComponentScript("interfaces/Sound.js"); | Engine.LoadComponentScript("interfaces/Sound.js"); | ||||
Engine.LoadComponentScript("interfaces/TechnologyManager.js"); | Engine.LoadComponentScript("interfaces/TechnologyManager.js"); | ||||
Engine.LoadComponentScript("interfaces/Timer.js"); | Engine.LoadComponentScript("interfaces/Timer.js"); | ||||
Engine.LoadComponentScript("Attack.js"); | Engine.LoadComponentScript("Attack.js"); | ||||
Engine.LoadComponentScript("Damage.js"); | Engine.LoadComponentScript("Damage.js"); | ||||
Engine.LoadComponentScript("Timer.js"); | Engine.LoadComponentScript("Timer.js"); | ||||
let Test_Generic = function() | |||||
{ | |||||
ResetState(); | |||||
let cmpDamage = ConstructComponent(SYSTEM_ENTITY, "Damage"); | let cmpDamage = ConstructComponent(SYSTEM_ENTITY, "Damage"); | ||||
let cmpTimer = ConstructComponent(SYSTEM_ENTITY, "Timer"); | let cmpTimer = ConstructComponent(SYSTEM_ENTITY, "Timer"); | ||||
cmpTimer.OnUpdate({ turnLength: 1 }); | cmpTimer.OnUpdate({ turnLength: 1 }); | ||||
let attacker = 11; | let attacker = 11; | ||||
let atkPlayerEntity = 1; | let atkPlayerEntity = 1; | ||||
let attackerOwner = 6; | let attackerOwner = 6; | ||||
let cmpAttack = ConstructComponent(attacker, "Attack", { "Ranged": { "ProjectileSpeed": 500, "Spread": 0.5, "MaxRange": 50, "MinRange": 0 } } ); | let cmpAttack = ConstructComponent(attacker, "Attack", { "Ranged": { "ProjectileSpeed": 500, "Spread": 0.5, "MaxRange": 50, "MinRange": 0 } } ); | ||||
let damage = 5; | let damage = 5; | ||||
let target = 21; | let target = 21; | ||||
let targetOwner = 7; | let targetOwner = 7; | ||||
let targetPos = new Vector3D(3, 0, 3); | let targetPos = new Vector3D(3, 0, 3); | ||||
let type = "Melee"; | let type = "Melee"; | ||||
let damageTaken = false; | let damageTaken = false; | ||||
cmpAttack.GetAttackStrengths = (type) => ({ "hack": 0, "pierce": 0, "crush": damage }); | cmpAttack.GetAttackStrengths = (type) => ({ "hack": 0, "pierce": 0, "crush": damage }); | ||||
cmpAttack.GetAttackBonus = (type, target) => 1.0; | cmpAttack.GetAttackBonus = (type, target) => 1.0; | ||||
let data = { | let data = { | ||||
"attacker": attacker, | "attacker": attacker, | ||||
"target": target, | "target": target, | ||||
"type": "Melee", | "type": "Melee", | ||||
"strengths": { "hack": 0, "pierce": 0, "crush": damage }, | "strengths": { "hack": 0, "pierce": 0, "crush": damage }, | ||||
"multiplier": 1.0, | "multiplier": 1.0, | ||||
"attackerOwner": attackerOwner, | "attackerOwner": attackerOwner, | ||||
"position": targetPos, | "position": targetPos, | ||||
"isSplash": false, | "isSplash": false, | ||||
"projectileId": 9 | "projectileId": 9, | ||||
"direction": new Vector3D(1,0,0) | |||||
}; | }; | ||||
AddMock(atkPlayerEntity, IID_Player, { | AddMock(atkPlayerEntity, IID_Player, { | ||||
GetEnemies: () => [targetOwner] | GetEnemies: () => [targetOwner] | ||||
}); | }); | ||||
AddMock(SYSTEM_ENTITY, IID_PlayerManager, { | AddMock(SYSTEM_ENTITY, IID_PlayerManager, { | ||||
GetPlayerByID: (id) => atkPlayerEntity, | GetPlayerByID: (id) => atkPlayerEntity, | ||||
GetNumPlayers: () => 5 | GetNumPlayers: () => 5 | ||||
}); | }); | ||||
AddMock(SYSTEM_ENTITY, IID_RangeManager, { | AddMock(SYSTEM_ENTITY, IID_RangeManager, { | ||||
ExecuteQueryAroundPos: () => [target], | ExecuteQueryAroundPos: () => [target], | ||||
GetElevationAdaptedRange: (pos, rot, max, bonus, a) => max, | GetElevationAdaptedRange: (pos, rot, max, bonus, a) => max, | ||||
}); | }); | ||||
AddMock(SYSTEM_ENTITY, IID_ProjectileManager, { | AddMock(SYSTEM_ENTITY, IID_ProjectileManager, { | ||||
RemoveProjectile: () => {}, | RemoveProjectile: () => {}, | ||||
LaunchProjectileAtPoint: (ent, pos, speed, gravity) => {}, | LaunchProjectileAtPoint: (ent, pos, speed, gravity) => {}, | ||||
}); | }); | ||||
AddMock(target, IID_Position, { | AddMock(target, IID_Position, { | ||||
GetPosition: () => targetPos, | GetPosition: () => targetPos, | ||||
GetPreviousPosition: () => targetPos, | GetPreviousPosition: () => targetPos, | ||||
GetPosition2D: () => new Vector2D(3, 3), | GetPosition2D: () => new Vector2D(3, 3), | ||||
IsInWorld: () => true, | IsInWorld: () => true, | ||||
}); | }); | ||||
AddMock(target, IID_Health, {}); | AddMock(target, IID_Health, {}); | ||||
AddMock(target, IID_DamageReceiver, { | AddMock(target, IID_DamageReceiver, { | ||||
TakeDamage: (hack, pierce, crush) => { damageTaken = true; return { "killed": false, "change": -crush }; }, | TakeDamage: (hack, pierce, crush) => { damageTaken = true; return { "killed": false, "change": -crush }; }, | ||||
}); | }); | ||||
Engine.PostMessage = function(ent, iid, message) | Engine.PostMessage = function(ent, iid, message) | ||||
{ | { | ||||
TS_ASSERT_UNEVAL_EQUALS({ "attacker": attacker, "target": target, "type": type, "damage": damage, "attackerOwner": attackerOwner }, message); | TS_ASSERT_UNEVAL_EQUALS({ "attacker": attacker, "target": target, "type": type, "damage": damage, "attackerOwner": attackerOwner }, message); | ||||
}; | }; | ||||
AddMock(target, IID_Footprint, { | AddMock(target, IID_Footprint, { | ||||
GetShape: () => ({ "type": "circle", "radius": 20 }), | GetShape: () => ({ "type": "circle", "radius": 20 }), | ||||
}); | }); | ||||
AddMock(attacker, IID_Ownership, { | AddMock(attacker, IID_Ownership, { | ||||
GetOwner: () => attackerOwner, | GetOwner: () => attackerOwner, | ||||
}); | }); | ||||
AddMock(attacker, IID_Position, { | AddMock(attacker, IID_Position, { | ||||
GetPosition: () => new Vector3D(2, 0, 3), | GetPosition: () => new Vector3D(2, 0, 3), | ||||
GetRotation: () => new Vector3D(1, 2, 3), | GetRotation: () => new Vector3D(1, 2, 3), | ||||
IsInWorld: () => true, | IsInWorld: () => true, | ||||
}); | }); | ||||
function TestDamage() | function TestDamage() | ||||
{ | { | ||||
cmpTimer.OnUpdate({ turnLength: 1 }); | cmpTimer.OnUpdate({ turnLength: 1 }); | ||||
TS_ASSERT(damageTaken); | TS_ASSERT(damageTaken); | ||||
damageTaken = false; | damageTaken = false; | ||||
} | } | ||||
cmpDamage.CauseDamage(data); | cmpDamage.CauseDamage(data); | ||||
TestDamage(); | TestDamage(); | ||||
type = data.type = "Ranged"; | type = data.type = "Ranged"; | ||||
cmpDamage.CauseDamage(data); | cmpDamage.CauseDamage(data); | ||||
TestDamage(); | TestDamage(); | ||||
data.friendlyFire = false; | data.friendlyFire = false; | ||||
data.range = 10; | data.range = 10; | ||||
data.shape = "Circular"; | data.shape = "Circular"; | ||||
data.isSplash = true; | data.isSplash = true; | ||||
cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_Damage, "MissileHit", 1000, data); | cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_Damage, "MissileHit", 1000, data); | ||||
TestDamage(); | TestDamage(); | ||||
// Check for damage still being dealt if the attacker dies | // Check for damage still being dealt if the attacker dies | ||||
cmpAttack.PerformAttack("Ranged", target); | cmpAttack.PerformAttack("Ranged", target); | ||||
Engine.DestroyEntity(attacker); | Engine.DestroyEntity(attacker); | ||||
TestDamage(); | TestDamage(); | ||||
atkPlayerEntity = 1; | atkPlayerEntity = 1; | ||||
AddMock(atkPlayerEntity, IID_Player, { | AddMock(atkPlayerEntity, IID_Player, { | ||||
GetEnemies: () => [2, 3] | GetEnemies: () => [2, 3] | ||||
}); | }); | ||||
TS_ASSERT_UNEVAL_EQUALS(cmpDamage.GetPlayersToDamage(atkPlayerEntity, true), [0, 1, 2, 3, 4]); | TS_ASSERT_UNEVAL_EQUALS(cmpDamage.GetPlayersToDamage(atkPlayerEntity, true), [0, 1, 2, 3, 4]); | ||||
TS_ASSERT_UNEVAL_EQUALS(cmpDamage.GetPlayersToDamage(atkPlayerEntity, false), [2, 3]); | TS_ASSERT_UNEVAL_EQUALS(cmpDamage.GetPlayersToDamage(atkPlayerEntity, false), [2, 3]); | ||||
} | |||||
Test_Generic(); | |||||
let TestLinearSplashDamage = function() | |||||
{ | |||||
ResetState(); | |||||
Engine.PostMessage = (ent, iid, message) => {}; | |||||
const attacker = 50; | |||||
const attackerOwner = 1; | |||||
const origin = new Vector2D(0, 0); | |||||
let data = { | |||||
"attacker": attacker, | |||||
"origin": origin, | |||||
"radius": 10, | |||||
"shape": "Linear", | |||||
"strengths": { "hack" : 100, "pierce" : 0, "crush": 0 }, | |||||
"direction": new Vector3D(1, 747, 0), | |||||
"playersToDamage": [2], | |||||
"type": "Ranged", | |||||
"attackerOwner": attackerOwner | |||||
}; | |||||
let fallOff = function(x,y) | |||||
{ | |||||
return (1 - x * x / (data.radius * data.radius)) * (1 - 25 * y * y / (data.radius * data.radius)); | |||||
} | |||||
let cmpDamage = ConstructComponent(SYSTEM_ENTITY, "Damage"); | |||||
AddMock(SYSTEM_ENTITY, IID_RangeManager, { | |||||
ExecuteQueryAroundPos: () => [60, 61, 62], | |||||
}); | |||||
AddMock(60, IID_Position, { | |||||
GetPosition2D: () => new Vector2D(2.2, -0.4), | |||||
}); | |||||
AddMock(61, IID_Position, { | |||||
GetPosition2D: () => new Vector2D(0, 0), | |||||
}); | |||||
AddMock(62, IID_Position, { | |||||
GetPosition2D: () => new Vector2D(5, 2), | |||||
}); | |||||
AddMock(60, IID_DamageReceiver, { | |||||
TakeDamage: (hack, pierce, crush) => { | |||||
TS_ASSERT_EQUALS(hack + pierce + crush, 100 * fallOff(2.2, -0.4)); | |||||
return { "killed": false, "change": -(hack + pierce + crush) }; | |||||
} | |||||
}); | |||||
AddMock(61, IID_DamageReceiver, { | |||||
TakeDamage: (hack, pierce, crush) => { | |||||
TS_ASSERT_EQUALS(hack + pierce + crush, 100 * fallOff(0, 0)); | |||||
return { "killed": false, "change": -(hack + pierce + crush) }; | |||||
} | |||||
}); | |||||
AddMock(62, IID_DamageReceiver, { | |||||
TakeDamage: (hack, pierce, crush) => { | |||||
TS_ASSERT_EQUALS(hack + pierce + crush, 0); | |||||
return { "killed": false, "change": -(hack + pierce + crush) }; | |||||
} | |||||
}); | |||||
cmpDamage.CauseSplashDamage(data); | |||||
data.direction = new Vector3D(0.6, 747, 0.8); | |||||
AddMock(60, IID_DamageReceiver, { | |||||
TakeDamage: (hack, pierce, crush) => { | |||||
TS_ASSERT_EQUALS(hack + pierce + crush, 100 * fallOff(1, 2)); | |||||
return { "killed": false, "change": -(hack + pierce + crush) }; | |||||
} | |||||
}); | |||||
cmpDamage.CauseSplashDamage(data); | |||||
}; | |||||
TestLinearSplashDamage(); |
Wildfire Games · Phabricator