mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-17 13:53:57 -07:00
Up to now `eslint-plugin-brace-rules` was used to enforce a common brace style for JavaScript code. This plugin was however updated the last time over 9 years ago and will be incompatible with ESLint v10, as that [removes `context.getSourceCode()`][1], the plugin relies on. To keep the eslint config working with ESLint v10, this replaces `eslint-plugin-brace-rules` with the [`@stylistic/brace-style`][2] rule from `@stylistic/eslint-plugin`, a package we already use. While `@stylistic/brace-style` doesn't offer an option to format braces in exactly the same way as before, the "allman" style seems to be the one closest to the existing code. [1]: https://eslint.org/blog/2025/11/eslint-v10.0.0-alpha.0-released/#removed-deprecated-rule-context-members [2]: https://eslint.style/rules/brace-style
206 lines
8 KiB
JavaScript
206 lines
8 KiB
JavaScript
Engine.LoadComponentScript("interfaces/BuildRestrictions.js");
|
|
Engine.LoadComponentScript("interfaces/EntityLimits.js");
|
|
Engine.LoadComponentScript("interfaces/Foundation.js");
|
|
Engine.LoadComponentScript("interfaces/TrainingRestrictions.js");
|
|
Engine.LoadComponentScript("interfaces/Player.js");
|
|
Engine.LoadComponentScript("EntityLimits.js");
|
|
|
|
const template ={
|
|
"Limits": {
|
|
"Tower": 5,
|
|
"Wonder": 1,
|
|
"Hero": 2,
|
|
"Champion": 1
|
|
},
|
|
"LimitChangers": {
|
|
"Tower": { "Monument": 1 }
|
|
},
|
|
"LimitRemovers": {
|
|
"Tower": { "RequiredTechs": { "_string": "TechA" } },
|
|
"Hero": { "RequiredClasses": { "_string": "Aegis" } }
|
|
}
|
|
};
|
|
|
|
AddMock(10, IID_Player, {
|
|
"GetPlayerID": id => 1
|
|
});
|
|
AddMock(SYSTEM_ENTITY, IID_GuiInterface, {
|
|
"PushNotification": () => {}
|
|
});
|
|
|
|
const cmpEntityLimits = ConstructComponent(10, "EntityLimits", template);
|
|
|
|
// Test getters
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetCounts(), { "Tower": 0, "Wonder": 0, "Hero": 0, "Champion": 0 });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetLimits(), { "Tower": 5, "Wonder": 1, "Hero": 2, "Champion": 1 });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetLimitChangers(), { "Tower": { "Monument": 1 } });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetMatchCounts(), {});
|
|
|
|
// Test training restrictions
|
|
TS_ASSERT(cmpEntityLimits.AllowedToTrain("Hero"));
|
|
TS_ASSERT(cmpEntityLimits.AllowedToTrain("Hero", 1));
|
|
TS_ASSERT(cmpEntityLimits.AllowedToTrain("Hero", 2));
|
|
|
|
for (let ent = 60; ent < 63; ++ent)
|
|
{
|
|
AddMock(ent, IID_TrainingRestrictions, {
|
|
"GetCategory": () => "Hero"
|
|
});
|
|
}
|
|
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 60, "from": INVALID_PLAYER, "to": 1 });
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 61, "from": 2, "to": 1 });
|
|
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetCounts(), { "Tower": 0, "Wonder": 0, "Hero": 2, "Champion": 0 });
|
|
TS_ASSERT(cmpEntityLimits.AllowedToTrain("Hero"));
|
|
TS_ASSERT(!cmpEntityLimits.AllowedToTrain("Hero", 1));
|
|
|
|
// Restrictions can be enforced
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 62, "from": INVALID_PLAYER, "to": 1 });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetCounts(), { "Tower": 0, "Wonder": 0, "Hero": 3, "Champion": 0 });
|
|
|
|
for (let ent = 60; ent < 63; ++ent)
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": ent, "from": 1, "to": INVALID_PLAYER });
|
|
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetCounts(), { "Tower": 0, "Wonder": 0, "Hero": 0, "Champion": 0 });
|
|
|
|
// Test building restrictions
|
|
AddMock(70, IID_BuildRestrictions, {
|
|
"GetCategory": () => "Wonder"
|
|
});
|
|
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 70, "from": 3, "to": 1 });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetCounts(), { "Tower": 0, "Wonder": 1, "Hero": 0, "Champion": 0 });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetLimits(), { "Tower": 5, "Wonder": 1, "Hero": 2, "Champion": 1 });
|
|
|
|
// AllowedToBuild is used after foundation placement, which are meant to be replaced
|
|
TS_ASSERT(cmpEntityLimits.AllowedToBuild("Wonder"));
|
|
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 70, "from": 1, "to": INVALID_PLAYER });
|
|
|
|
// Test limit changers
|
|
AddMock(80, IID_Identity, {
|
|
"GetClassesList": () => ["Monument"]
|
|
});
|
|
|
|
AddMock(81, IID_Identity, {
|
|
"GetClassesList": () => ["Monument"]
|
|
});
|
|
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 80, "from": INVALID_PLAYER, "to": 1 });
|
|
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetCounts(), { "Tower": 0, "Wonder": 0, "Hero": 0, "Champion": 0 });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetLimits(), { "Tower": 5 + 1, "Wonder": 1, "Hero": 2, "Champion": 1 });
|
|
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 81, "from": 1, "to": INVALID_PLAYER });
|
|
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetCounts(), { "Tower": 0, "Wonder": 0, "Hero": 0, "Champion": 0 });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetLimits(), { "Tower": 5, "Wonder": 1, "Hero": 2, "Champion": 1 });
|
|
|
|
// Foundations don't change limits
|
|
AddMock(81, IID_Foundation, {});
|
|
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 81, "from": INVALID_PLAYER, "to": 1 });
|
|
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetCounts(), { "Tower": 0, "Wonder": 0, "Hero": 0, "Champion": 0 });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetLimits(), { "Tower": 5, "Wonder": 1, "Hero": 2, "Champion": 1 });
|
|
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 81, "from": 1, "to": INVALID_PLAYER });
|
|
|
|
// Test limit removers by classes
|
|
AddMock(90, IID_Identity, {
|
|
"GetClassesList": () => ["Aegis"]
|
|
});
|
|
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 90, "from": INVALID_PLAYER, "to": 1 });
|
|
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetLimits(), { "Tower": 5, "Wonder": 1, "Hero": undefined, "Champion": 1 });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetCounts(), { "Tower": 0, "Wonder": 0, "Hero": 0, "Champion": 0 });
|
|
|
|
AddMock(91, IID_TrainingRestrictions, {
|
|
"GetCategory": () => "Hero"
|
|
});
|
|
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 91, "from": INVALID_PLAYER, "to": 1 });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetLimits(), { "Tower": 5, "Wonder": 1, "Hero": undefined, "Champion": 1 });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetCounts(), { "Tower": 0, "Wonder": 0, "Hero": 1, "Champion": 0 });
|
|
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 90, "from": 1, "to": INVALID_PLAYER });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetLimits(), { "Tower": 5, "Wonder": 1, "Hero": 2, "Champion": 1 });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetCounts(), { "Tower": 0, "Wonder": 0, "Hero": 1, "Champion": 0 });
|
|
|
|
// Edge case
|
|
AddMock(92, IID_TrainingRestrictions, {
|
|
"GetCategory": () => "Hero"
|
|
});
|
|
AddMock(92, IID_Identity, {
|
|
"GetClassesList": () => ["Aegis"]
|
|
});
|
|
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 92, "from": INVALID_PLAYER, "to": 1 });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetLimits(), { "Tower": 5, "Wonder": 1, "Hero": undefined, "Champion": 1 });
|
|
TS_ASSERT(cmpEntityLimits.AllowedToTrain("Hero", 157));
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetCounts(), { "Tower": 0, "Wonder": 0, "Hero": 2, "Champion": 0 });
|
|
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 91, "from": 1, "to": INVALID_PLAYER });
|
|
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 92, "from": 1, "to": INVALID_PLAYER });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetLimits(), { "Tower": 5, "Wonder": 1, "Hero": 2, "Champion": 1 });
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetCounts(), { "Tower": 0, "Wonder": 0, "Hero": 0, "Champion": 0 });
|
|
|
|
// Test AllowedToReplace
|
|
AddMock(SYSTEM_ENTITY, IID_TemplateManager, {
|
|
"GetTemplate": name =>
|
|
{
|
|
switch (name)
|
|
{
|
|
case "templateA":
|
|
return { "TrainingRestrictions": { "Category": "Champion" } };
|
|
case "templateB":
|
|
return { "TrainingRestrictions": { "Category": "Hero" } };
|
|
case "templateC":
|
|
return { "BuildRestrictions": { "Category": "Wonder" } };
|
|
case "templateD":
|
|
return { "BuildRestrictions": { "Category": "Tower" } };
|
|
default:
|
|
return null;
|
|
}
|
|
},
|
|
"GetCurrentTemplateName": id =>
|
|
{
|
|
switch (id)
|
|
{
|
|
case 100:
|
|
return "templateA";
|
|
case 101:
|
|
return "templateB";
|
|
case 102:
|
|
return "templateC";
|
|
case 103:
|
|
return "templateD";
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
});
|
|
|
|
cmpEntityLimits.ChangeCount("Champion", 1);
|
|
TS_ASSERT(cmpEntityLimits.AllowedToReplace(100, "templateA"));
|
|
TS_ASSERT(!cmpEntityLimits.AllowedToReplace(101, "templateA"));
|
|
cmpEntityLimits.ChangeCount("Champion", -1);
|
|
|
|
cmpEntityLimits.ChangeCount("Tower", 5);
|
|
TS_ASSERT(!cmpEntityLimits.AllowedToReplace(102, "templateD"));
|
|
TS_ASSERT(cmpEntityLimits.AllowedToReplace(103, "templateD"));
|
|
cmpEntityLimits.ChangeCount("Tower", -5);
|
|
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetCounts(), { "Tower": 0, "Wonder": 0, "Hero": 0, "Champion": 0 });
|
|
|
|
// Test limit removers by tech
|
|
cmpEntityLimits.UpdateLimitsFromTech("TechB");
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetLimits(), { "Tower": 5, "Wonder": 1, "Hero": 2, "Champion": 1 });
|
|
|
|
cmpEntityLimits.UpdateLimitsFromTech("TechA");
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetLimits(), { "Tower": undefined, "Wonder": 1, "Hero": 2, "Champion": 1 });
|
|
|
|
cmpEntityLimits.UpdateLimitsFromTech("TechA");
|
|
TS_ASSERT_UNEVAL_EQUALS(cmpEntityLimits.GetLimits(), { "Tower": undefined, "Wonder": 1, "Hero": 2, "Champion": 1 });
|