forked from mirrors/0ad
416049e4b4
Remove the unused "recharge" attack timer which was introduced inb21e798243but should have been removed with4e5c5e2d8f. This was SVN commit r18599.
164 lines
4.2 KiB
JavaScript
164 lines
4.2 KiB
JavaScript
Engine.LoadHelperScript("Player.js");
|
|
Engine.LoadHelperScript("ValueModification.js");
|
|
Engine.LoadComponentScript("interfaces/Auras.js");
|
|
Engine.LoadComponentScript("interfaces/AuraManager.js");
|
|
Engine.LoadComponentScript("interfaces/Capturable.js");
|
|
Engine.LoadComponentScript("interfaces/TechnologyManager.js");
|
|
Engine.LoadComponentScript("interfaces/Formation.js");
|
|
Engine.LoadComponentScript("interfaces/Attack.js");
|
|
Engine.LoadComponentScript("Attack.js");
|
|
|
|
let entityID = 903;
|
|
|
|
function attackComponentTest(defenderClass, test_function)
|
|
{
|
|
ResetState();
|
|
|
|
{
|
|
let playerEnt1 = 5;
|
|
|
|
AddMock(SYSTEM_ENTITY, IID_PlayerManager, {
|
|
"GetPlayerByID": () => playerEnt1
|
|
});
|
|
|
|
AddMock(playerEnt1, IID_Player, {
|
|
"GetPlayerID": () => 1
|
|
});
|
|
}
|
|
|
|
let attacker = entityID;
|
|
|
|
AddMock(attacker, IID_Position, {
|
|
"IsInWorld": () => true,
|
|
"GetHeightOffset": () => 5
|
|
});
|
|
|
|
AddMock(attacker, IID_Ownership, {
|
|
"GetOwner": () => 1
|
|
});
|
|
|
|
let cmpAttack = ConstructComponent(attacker, "Attack", {
|
|
"Melee" : {
|
|
"Hack": 11,
|
|
"Pierce": 5,
|
|
"Crush": 0,
|
|
"MinRange": 3,
|
|
"MaxRange": 5,
|
|
"PreferredClasses": {
|
|
"_string": "Female"
|
|
},
|
|
"RestrictedClasses": {
|
|
"_string": "Elephant Archer"
|
|
},
|
|
"Bonuses":
|
|
{
|
|
"BonusCav": {
|
|
"Classes": "Cavalry",
|
|
"Multiplier": 2
|
|
}
|
|
}
|
|
},
|
|
"Ranged" : {
|
|
"Hack": 0,
|
|
"Pierce": 10,
|
|
"Crush": 0,
|
|
"MinRange": 10,
|
|
"MaxRange": 80,
|
|
"PrepareTime": 300,
|
|
"RepeatTime": 500,
|
|
"PreferredClasses": {
|
|
"_string": "Archer"
|
|
},
|
|
"RestrictedClasses": {
|
|
"_string": "Elephant"
|
|
}
|
|
},
|
|
"Capture" : {
|
|
"Value": 8,
|
|
"MaxRange": 10,
|
|
},
|
|
"Slaughter": {}
|
|
});
|
|
|
|
let defender = ++entityID;
|
|
|
|
AddMock(defender, IID_Identity, {
|
|
"GetClassesList": () => [defenderClass],
|
|
"HasClass": className => className == defenderClass
|
|
});
|
|
|
|
AddMock(defender, IID_Position, {
|
|
"IsInWorld": () => true,
|
|
"GetHeightOffset": () => 0
|
|
});
|
|
|
|
test_function(attacker, cmpAttack, defender);
|
|
}
|
|
|
|
// Validate template getter functions
|
|
attackComponentTest(undefined, (attacker, cmpAttack, defender) => {
|
|
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetAttackTypes(), ["Melee", "Ranged", "Capture"]);
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetPreferredClasses("Melee"), ["Female"]);
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetRestrictedClasses("Melee"), ["Elephant", "Archer"]);
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetFullAttackRange(), { "min": 0, "max": 80 });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetAttackStrengths("Capture"), { "value": 8 });
|
|
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetAttackStrengths("Ranged"), {
|
|
"hack": 0,
|
|
"pierce": 10,
|
|
"crush": 0
|
|
});
|
|
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetTimers("Ranged"), {
|
|
"prepare": 300,
|
|
"repeat": 500
|
|
});
|
|
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetTimers("Capture"), {
|
|
"prepare": 0,
|
|
"repeat": 1000
|
|
});
|
|
});
|
|
|
|
for (let className of ["Infantry", "Cavalry"])
|
|
attackComponentTest(className, (attacker, cmpAttack, defender) => {
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetAttackBonus("Melee", defender), className == "Cavalry" ? 2 : 1);
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetAttackBonus("Ranged", defender), 1);
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetAttackBonus("Capture", defender), 1);
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpAttack.GetAttackBonus("Slaughter", defender), 1);
|
|
});
|
|
|
|
// CanAttack rejects elephant attack due to RestrictedClasses
|
|
attackComponentTest("Elephant", (attacker, cmpAttack, defender) => {
|
|
TS_ASSERT_EQUALS(cmpAttack.CanAttack(defender), false);
|
|
});
|
|
|
|
function testGetBestAttackAgainst(defenderClass, bestAttack, isBuilding = false)
|
|
{
|
|
attackComponentTest(defenderClass, (attacker, cmpAttack, defender) => {
|
|
|
|
if (isBuilding)
|
|
AddMock(defender, IID_Capturable, {
|
|
"CanCapture": playerID => {
|
|
TS_ASSERT_EQUALS(playerID, 1);
|
|
return true;
|
|
}
|
|
});
|
|
|
|
TS_ASSERT_EQUALS(cmpAttack.CanAttack(defender), true);
|
|
|
|
let allowCapturing = [true];
|
|
if (!isBuilding)
|
|
allowCapturing.push(false);
|
|
|
|
for (let allowCapturing of allowCapturing)
|
|
TS_ASSERT_EQUALS(cmpAttack.GetBestAttackAgainst(defender, allowCapturing), bestAttack);
|
|
});
|
|
}
|
|
|
|
testGetBestAttackAgainst("Female", "Melee");
|
|
testGetBestAttackAgainst("Archer", "Ranged");
|
|
testGetBestAttackAgainst("Domestic", "Slaughter");
|
|
testGetBestAttackAgainst("Structure", "Capture", true);
|