Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Technologies_effects.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Technologies_effects.js (revision 23861) +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Technologies_effects.js (nonexistent) @@ -1,30 +0,0 @@ -// TODO: Move this to a folder of tests for GlobalScripts (once one is created) - -// This tests the GetTechModifiedProperty function. -let add = [{ "add": 10, "affects": "Unit" }]; - -let add_add = [{ "add": 10, "affects": "Unit" }, { "add": 5, "affects": "Unit" }]; - -let add_mul_add = [{ "add": 10, "affects": "Unit" }, { "multiply": 2, "affects": "Unit" }, { "add": 5, "affects": "Unit" }]; - -let add_replace = [{ "add": 10, "affects": "Unit" }, { "replace": 10, "affects": "Unit" }]; - -let replace_add = [{ "replace": 10, "affects": "Unit" }, { "add": 10, "affects": "Unit" }]; - -let replace_replace = [{ "replace": 10, "affects": "Unit" }, { "replace": 30, "affects": "Unit" }]; - -let replace_nonnum = [{ "replace": "alpha", "affects": "Unit" }]; - -TS_ASSERT_EQUALS(GetTechModifiedProperty(add, "Unit", 5), 15); -TS_ASSERT_EQUALS(GetTechModifiedProperty(add_add, "Unit", 5), 20); -TS_ASSERT_EQUALS(GetTechModifiedProperty(add_add, "Other", 5), 5); - -// Technologies work by multiplying then adding all. -TS_ASSERT_EQUALS(GetTechModifiedProperty(add_mul_add, "Unit", 5), 25); - -TS_ASSERT_EQUALS(GetTechModifiedProperty(add_replace, "Unit", 5), 10); - -// Only the first replace is taken into account -TS_ASSERT_EQUALS(GetTechModifiedProperty(replace_replace, "Unit", 5), 10); - -TS_ASSERT_EQUALS(GetTechModifiedProperty(replace_nonnum, "Unit", "beta"), "alpha"); Property changes on: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Technologies_effects.js ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Technologies_reqs.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Technologies_reqs.js (revision 23861) +++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Technologies_reqs.js (nonexistent) @@ -1,583 +0,0 @@ -// TODO: Move this to a folder of tests for GlobalScripts (once one is created) - -// No requirements set in template -let template = {}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); - -/** - * First, the basics: - */ - -// Technology Requirement -template.requirements = { "tech": "expected_tech" }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["expected_tech"] }]); - -// Entity Requirement: Count of entities matching given class -template.requirements = { "entity": { "class": "Village", "number": 5 } }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "entities": [{ "class": "Village", "number": 5, "check": "count" }] }]); - -// Entity Requirement: Count of entities matching given class -template.requirements = { "entity": { "class": "Village", "numberOfTypes": 5 } }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "entities": [{ "class": "Village", "number": 5, "check": "variants" }] }]); - -// Single `civ` -template.requirements = { "civ": "athen" }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), false); - -// Single `notciv` -template.requirements = { "notciv": "athen" }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), []); - - -/** - * Basic `all`s: - */ - -// Multiple techs -template.requirements = { "all": [{ "tech": "tech_A" }, { "tech": "tech_B" }, { "tech": "tech_C" }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A", "tech_B", "tech_C"] }]); - -// Multiple entity definitions -template.requirements = { - "all": [ - { "entity": { "class": "class_A", "number": 5 } }, - { "entity": { "class": "class_B", "number": 5 } }, - { "entity": { "class": "class_C", "number": 5 } } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), - [{ "entities": [{ "class": "class_A", "number": 5, "check": "count" }, { "class": "class_B", "number": 5, "check": "count" }, { "class": "class_C", "number": 5, "check": "count" }] }]); - -// A `tech` and an `entity` -template.requirements = { "all": [{ "tech": "tech_A" }, { "entity": { "class": "class_B", "number": 5, "check": "count" } }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A"], "entities": [{ "class": "class_B", "number": 5, "check": "count" }] }]); - -// Multiple `civ`s -template.requirements = { "all": [{ "civ": "civ_A" }, { "civ": "civ_B" }, { "civ": "civ_C" }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), []); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), []); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), []); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), false); - -// Multiple `notciv`s -template.requirements = { "all": [{ "notciv": "civ_A" }, { "notciv": "civ_B" }, { "notciv": "civ_C" }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), []); - -// A `civ` with a tech/entity -template.requirements = { "all": [{ "civ": "athen" }, { "tech": "expected_tech" }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["expected_tech"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), false); - -template.requirements = { "all": [{ "civ": "athen" }, { "entity": { "class": "Village", "number": 5 } }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "entities": [{ "class": "Village", "number": 5, "check": "count" }] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), false); - -template.requirements = { "all": [{ "civ": "athen" }, { "entity": { "class": "Village", "numberOfTypes": 5 } }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "entities": [{ "class": "Village", "number": 5, "check": "variants" }] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), false); - -// A `notciv` with a tech/entity -template.requirements = { "all": [{ "notciv": "athen" }, { "tech": "expected_tech" }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "techs": ["expected_tech"] }]); - -template.requirements = { "all": [{ "notciv": "athen" }, { "entity": { "class": "Village", "number": 5 } }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "entities": [{ "class": "Village", "number": 5, "check": "count" }] }]); - -template.requirements = { "all": [{ "notciv": "athen" }, { "entity": { "class": "Village", "numberOfTypes": 5 } }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "entities": [{ "class": "Village", "number": 5, "check": "variants" }] }]); - - -/** - * Basic `any`s: - */ - -// Multiple techs -template.requirements = { "any": [{ "tech": "tech_A" }, { "tech": "tech_B" }, { "tech": "tech_C" }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A"] }, { "techs": ["tech_B"] }, { "techs": ["tech_C"] }]); - -// Multiple entity definitions -template.requirements = { - "any": [ - { "entity": { "class": "class_A", "number": 5 } }, - { "entity": { "class": "class_B", "number": 5 } }, - { "entity": { "class": "class_C", "number": 5 } } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [ - { "entities": [{ "class": "class_A", "number": 5, "check": "count" }] }, - { "entities": [{ "class": "class_B", "number": 5, "check": "count" }] }, - { "entities": [{ "class": "class_C", "number": 5, "check": "count" }] } -]); - -// A tech or an entity -template.requirements = { "any": [{ "tech": "tech_A" }, { "entity": { "class": "class_B", "number": 5, "check": "count" } }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A"] }, { "entities": [{ "class": "class_B", "number": 5, "check": "count" }] }]); - -// Multiple `civ`s -template.requirements = { "any": [{ "civ": "civ_A" }, { "civ": "civ_B" }, { "civ": "civ_C" }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), []); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), []); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), []); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), false); - -// Multiple `notciv`s -template.requirements = { "any": [{ "notciv": "civ_A" }, { "notciv": "civ_B" }, { "notciv": "civ_C" }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), []); - -// A `civ` or a tech/entity -template.requirements = { "any": [{ "civ": "athen" }, { "tech": "expected_tech" }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "techs": ["expected_tech"] }]); - -template.requirements = { "any": [{ "civ": "athen" }, { "entity": { "class": "Village", "number": 5 } }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "entities": [{ "class": "Village", "number": 5, "check": "count" }] }]); - -template.requirements = { "any": [{ "civ": "athen" }, { "entity": { "class": "Village", "numberOfTypes": 5 } }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "entities": [{ "class": "Village", "number": 5, "check": "variants" }] }]); - -// A `notciv` or a tech -template.requirements = { "any": [{ "notciv": "athen" }, { "tech": "expected_tech" }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "techs": ["expected_tech"] }]); - -template.requirements = { "any": [{ "notciv": "athen" }, { "entity": { "class": "Village", "number": 5 } }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "entities": [{ "class": "Village", "number": 5, "check": "count" }] }]); - -template.requirements = { "any": [{ "notciv": "athen" }, { "entity": { "class": "Village", "numberOfTypes": 5 } }] }; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "entities": [{ "class": "Village", "number": 5, "check": "variants" }] }]); - - -/** - * Complicated `all`s, part 1 - an `all` inside an `all`: - */ - -// Techs -template.requirements = { - "all": [ - { "all": [{ "tech": "tech_A" }, { "tech": "tech_B" }] }, - { "all": [{ "tech": "tech_C" }, { "tech": "tech_D" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A", "tech_B", "tech_C", "tech_D"] }]); - -// Techs and entities -template.requirements = { - "all": [ - { "all": [{ "tech": "tech_A" }, { "entity": { "class": "class_A", "number": 5 } }] }, - { "all": [{ "entity": { "class": "class_B", "numberOfTypes": 5 } }, { "tech": "tech_B" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ - "techs": ["tech_A", "tech_B"], - "entities": [{ "class": "class_A", "number": 5, "check": "count" }, { "class": "class_B", "number": 5, "check": "variants" }] -}]); - -// Two `civ`s, without and with a tech -template.requirements = { - "all": [ - { "all": [{ "civ": "athen" }, { "civ": "spart" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), false); - -template.requirements = { - "all": [ - { "tech": "required_tech" }, - { "all": [{ "civ": "athen" }, { "civ": "spart" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["required_tech"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), false); - -// Two `notciv`s, without and with a tech -template.requirements = { - "all": [ - { "all": [{ "notciv": "athen" }, { "notciv": "spart" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), []); - -template.requirements = { - "all": [ - { "tech": "required_tech" }, - { "all": [{ "notciv": "athen" }, { "notciv": "spart" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["required_tech"] }]); - -// Inner `all` has a tech and a `civ`/`notciv` -template.requirements = { - "all": [ - { "all": [{ "tech": "tech_A" }, { "civ": "maur" }] }, - { "tech": "tech_B" } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_B"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["tech_A", "tech_B"] }]); - -template.requirements = { - "all": [ - { "all": [{ "tech": "tech_A" }, { "notciv": "maur" }] }, - { "tech": "tech_B" } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A", "tech_B"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["tech_B"] }]); - - -/** - * Complicated `all`s, part 2 - an `any` inside an `all`: - */ - -// Techs -template.requirements = { - "all": [ - { "any": [{ "tech": "tech_A" }, { "tech": "tech_B" }] }, - { "any": [{ "tech": "tech_C" }, { "tech": "tech_D" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [ - { "techs": ["tech_A", "tech_C"] }, - { "techs": ["tech_A", "tech_D"] }, - { "techs": ["tech_B", "tech_C"] }, - { "techs": ["tech_B", "tech_D"] } -]); - -// Techs and entities -template.requirements = { - "all": [ - { "any": [{ "tech": "tech_A" }, { "entity": { "class": "class_A", "number": 5 } }] }, - { "any": [{ "entity": { "class": "class_B", "numberOfTypes": 5 } }, { "tech": "tech_B" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [ - { "techs": ["tech_A"], "entities": [{ "class": "class_B", "number": 5, "check": "variants" }] }, - { "techs": ["tech_A", "tech_B"] }, - { "entities": [{ "class": "class_A", "number": 5, "check": "count" }, { "class": "class_B", "number": 5, "check": "variants" }] }, - { "entities": [{ "class": "class_A", "number": 5, "check": "count" }], "techs": ["tech_B"] } -]); - -// Two `civ`s, without and with a tech -template.requirements = { - "all": [ - { "any": [{ "civ": "athen" }, { "civ": "spart" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), false); - -template.requirements = { - "all": [ - { "tech": "required_tech" }, - { "any": [{ "civ": "athen" }, { "civ": "spart" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["required_tech"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), false); - -// Two `notciv`s, without and with a tech -template.requirements = { - "all": [ - { "any": [{ "notciv": "athen" }, { "notciv": "spart" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), []); - -template.requirements = { - "all": [ - { "tech": "required_tech" }, - { "any": [{ "notciv": "athen" }, { "notciv": "spart" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["required_tech"] }]); - - -/** - * Complicated `any`s, part 1 - an `all` inside an `any`: - */ - -// Techs -template.requirements = { - "any": [ - { "all": [{ "tech": "tech_A" }, { "tech": "tech_B" }] }, - { "all": [{ "tech": "tech_C" }, { "tech": "tech_D" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [ - { "techs": ["tech_A", "tech_B"] }, - { "techs": ["tech_C", "tech_D"] } -]); - -// Techs and entities -template.requirements = { - "any": [ - { "all": [{ "tech": "tech_A" }, { "entity": { "class": "class_A", "number": 5 } }] }, - { "all": [{ "entity": { "class": "class_B", "numberOfTypes": 5 } }, { "tech": "tech_B" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [ - { "techs": ["tech_A"], "entities": [{ "class": "class_A", "number": 5, "check": "count" }] }, - { "entities": [{ "class": "class_B", "number": 5, "check": "variants" }], "techs": ["tech_B"] } -]); - -// Two `civ`s, without and with a tech -template.requirements = { - "any": [ - { "all": [{ "civ": "athen" }, { "civ": "spart" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), false); - -template.requirements = { - "any": [ - { "tech": "required_tech" }, - { "all": [{ "civ": "athen" }, { "civ": "spart" }] } - ] -}; -// Note: these requirements don't really make sense, as the `any` makes the `civ`s in the the inner `all` irrelevant. -// We test it anyway as a precursor to later tests. -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["required_tech"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["required_tech"] }]); - -// Two `notciv`s, without and with a tech -template.requirements = { - "any": [ - { "all": [{ "notciv": "athen" }, { "notciv": "spart" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), []); - -template.requirements = { - "any": [ - { "tech": "required_tech" }, - { "all": [{ "notciv": "athen" }, { "notciv": "spart" }] } - ] -}; -// Note: these requirements have a result that might seen unexpected at first glance. -// This is because the `notciv`s are rendered irrelevant by the `any`, and they have nothing else to operate on. -// We test it anyway as a precursor for later tests. -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["required_tech"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["required_tech"] }]); - -// Inner `all` has a tech and a `civ`/`notciv` -template.requirements = { - "any": [ - { "all": [{ "civ": "civA" }, { "tech": "tech1" }] }, - { "tech": "tech2" } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civA"), [{ "techs": ["tech1"] }, { "techs": ["tech2"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civB"), [{ "techs": ["tech2"] }]); - -template.requirements = { - "any": [ - { "all": [{ "notciv": "civA" }, { "tech": "tech1" }] }, - { "tech": "tech2" } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civA"), [{ "techs": ["tech2"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civB"), [{ "techs": ["tech1"] }, { "techs": ["tech2"] }]); - - -/** - * Complicated `any`s, part 2 - an `any` inside an `any`: - */ - -// Techs -template.requirements = { - "any": [ - { "any": [{ "tech": "tech_A" }, { "tech": "tech_B" }] }, - { "any": [{ "tech": "tech_C" }, { "tech": "tech_D" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [ - { "techs": ["tech_A"] }, - { "techs": ["tech_B"] }, - { "techs": ["tech_C"] }, - { "techs": ["tech_D"] } -]); - -// Techs and entities -template.requirements = { - "any": [ - { "any": [{ "tech": "tech_A" }, { "entity": { "class": "class_A", "number": 5 } }] }, - { "any": [{ "entity": { "class": "class_B", "numberOfTypes": 5 } }, { "tech": "tech_B" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [ - { "techs": ["tech_A"] }, - { "entities": [{ "class": "class_A", "number": 5, "check": "count" }] }, - { "entities": [{ "class": "class_B", "number": 5, "check": "variants" }] }, - { "techs": ["tech_B"] } -]); - -// Two `civ`s, without and with a tech -template.requirements = { - "any": [ - { "any": [{ "civ": "athen" }, { "civ": "spart" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), false); - -template.requirements = { - "any": [ - { "tech": "required_tech" }, - { "any": [{ "civ": "athen" }, { "civ": "spart" }] } - ] -}; -// These requirements may not make sense, as the `civ`s are unable to restrict the requirements due to the outer `any` -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["required_tech"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["required_tech"] }]); - -// Two `notciv`s, without and with a tech -template.requirements = { - "any": [ - { "any": [{ "notciv": "athen" }, { "notciv": "spart" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), []); - -template.requirements = { - "any": [ - { "tech": "required_tech" }, - { "any": [{ "notciv": "athen" }, { "notciv": "spart" }] } - ] -}; -// These requirements may not make sense, as the `notciv`s are made irrelevant by the outer `any` -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["required_tech"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["required_tech"] }]); - - -/** - * Further tests - */ - -template.requirements = { - "all": [ - { "tech": "tech1" }, - { "any": [{ "civ": "civA" }, { "civ": "civB" }] }, - { "notciv": "civC" } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civA"), [{ "techs": ["tech1"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civC"), false); - -template.requirements = { - "any": [ - { "all": [{ "civ": "civA" }, { "tech": "tech1" }] }, - { "all": [{ "civ": "civB" }, { "tech": "tech2" }] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civA"), [{ "techs": ["tech1"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civB"), [{ "techs": ["tech2"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civC"), false); - -template.requirements = { - "any": [ - { "all": [{ "civ": "civA" }, { "tech": "tech1" }] }, - { "all": [ - { "any": [{ "civ": "civB" }, { "civ": "civC" }] }, - { "tech": "tech2" } - ] } - ] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civA"), [{ "techs": ["tech1"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civC"), [{ "techs": ["tech2"] }]); -TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civD"), false); - -// Test DeriveModificationsFromTech -template = { - "modifications": [{ - "value": "ResourceGatherer/Rates/food.grain", - "multiply": 15, - "affects": "Spearman Swordsman" - }, - { - "value": "ResourceGatherer/Rates/food.meat", - "multiply": 10 - }], - "affects": ["FemaleCitizen", "CitizenSoldier Melee"] -}; -let techMods = { - "ResourceGatherer/Rates/food.grain": [{ - "affects": [ - ["FemaleCitizen", "Spearman", "Swordsman"], - ["CitizenSoldier", "Melee", "Spearman", "Swordsman"] - ], - "multiply": 15 - }], - "ResourceGatherer/Rates/food.meat": [{ - "affects": [ - ["FemaleCitizen"], - ["CitizenSoldier", "Melee"] - ], - "multiply": 10 - }] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveModificationsFromTech(template), techMods); - -template = { - "modifications": [{ - "value": "ResourceGatherer/Rates/food.grain", - "multiply": 15, - "affects": "Spearman" - }, - { - "value": "ResourceGatherer/Rates/food.grain", - "multiply": 15, - "affects": "Swordsman" - }, - { - "value": "ResourceGatherer/Rates/food.meat", - "multiply": 10 - }], - "affects": ["FemaleCitizen", "CitizenSoldier Melee"] -}; -techMods = { - "ResourceGatherer/Rates/food.grain": [{ - "affects": [ - ["FemaleCitizen", "Spearman"], - ["CitizenSoldier", "Melee", "Spearman"] - ], - "multiply": 15 - }, - { - "affects": [ - ["FemaleCitizen", "Swordsman"], - ["CitizenSoldier", "Melee", "Swordsman"] - ], - "multiply": 15 - }], - "ResourceGatherer/Rates/food.meat": [{ - "affects": [ - ["FemaleCitizen"], - ["CitizenSoldier", "Melee"] - ], - "multiply": 10 - }] -}; -TS_ASSERT_UNEVAL_EQUALS(DeriveModificationsFromTech(template), techMods); Property changes on: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Technologies_reqs.js ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Index: ps/trunk/binaries/data/mods/public/globalscripts/Technologies.js =================================================================== --- ps/trunk/binaries/data/mods/public/globalscripts/Technologies.js (revision 23861) +++ ps/trunk/binaries/data/mods/public/globalscripts/Technologies.js (revision 23862) @@ -1,344 +1,374 @@ /** * This file contains shared logic for applying tech modifications in GUI, AI, * and simulation scripts. As such it must be fully deterministic and not store * any global state, but each context should do its own caching as needed. * Also it cannot directly access the simulation and requires data passed to it. */ /** * Returns modified property value modified by the applicable tech * modifications. * * @param modifications array of modificiations * @param classes Array containing the class list of the template. * @param originalValue Number storing the original value. Can also be * non-numeric, but then only "replace" and "tokens" techs can be supported. */ function GetTechModifiedProperty(modifications, classes, originalValue) { if (!modifications.length) return originalValue; + // From indicative profiling, splitting in two sub-functions or checking directly + // is about as efficient, but splitting makes it easier to report errors. + if (typeof originalValue === "string") + return GetTechModifiedProperty_string(modifications, classes, originalValue); + return GetTechModifiedProperty_numeric(modifications, classes, originalValue); +} + + +function GetTechModifiedProperty_numeric(modifications, classes, originalValue) +{ let multiply = 1; let add = 0; for (let modification of modifications) { if (!DoesModificationApply(modification, classes)) continue; if (modification.replace !== undefined) return modification.replace; - if (modification.tokens !== undefined) - return HandleTokens(originalValue, modification.tokens); if (modification.multiply) multiply *= modification.multiply; else if (modification.add) add += modification.add; else - warn("GetTechModifiedProperty: modification format not recognised : " + uneval(modification)); + warn("GetTechModifiedProperty: numeric modification format not recognised : " + uneval(modification)); } return originalValue * multiply + add; } +function GetTechModifiedProperty_string(modifications, classes, originalValue) +{ + let value = originalValue; + for (let modification of modifications) + { + if (!DoesModificationApply(modification, classes)) + continue; + if (modification.replace !== undefined) + return modification.replace; + // Multiple token replacement works, though ordering is not technically guaranteed. + // In practice, the order will be that of 'research', which ought to be fine, + // and operations like adding tokens are order-independent anyways, + // but modders beware if replacement or deletions are implemented. + if (modification.tokens !== undefined) + value = HandleTokens(value, modification.tokens); + else + warn("GetTechModifiedProperty: string modification format not recognised : " + uneval(modification)); + } + return value; +} + + /** * Returns whether the given modification applies to the entity containing the given class list */ function DoesModificationApply(modification, classes) { return MatchesClassList(classes, modification.affects); } /** * Returns a modified list of tokens. * Supports "A>B" to replace A by B, "-A" to remove A, and the rest will add tokens. */ function HandleTokens(originalValue, modification) { let tokens = originalValue === "" ? [] : originalValue.split(/\s+/); let newTokens = modification === "" ? [] : modification.split(/\s+/); for (let token of newTokens) { if (token.indexOf(">") !== -1) { let [oldToken, newToken] = token.split(">"); let index = tokens.indexOf(oldToken); if (index !== -1) tokens[index] = newToken; } else if (token[0] == "-") { let index = tokens.indexOf(token.substr(1)); if (index !== -1) tokens.splice(index, 1); } else tokens.push(token); } return tokens.join(" "); } /** * Derives the technology requirements from a given technology template. * Takes into account the `supersedes` attribute. * * @param {object} template - The template object. Loading of the template must have already occured. * * @return Derived technology requirements. See `InterpretTechRequirements` for object's syntax. */ function DeriveTechnologyRequirements(template, civ) { let requirements = []; if (template.requirements) { let op = Object.keys(template.requirements)[0]; let val = template.requirements[op]; requirements = InterpretTechRequirements(civ, op, val); } if (template.supersedes && requirements) { if (!requirements.length) requirements.push({}); for (let req of requirements) { if (!req.techs) req.techs = []; req.techs.push(template.supersedes); } } return requirements; } /** * Interprets the prerequisite requirements of a technology. * * Takes the initial { key: value } from the short-form requirements object in entity templates, * and parses it into an object that can be more easily checked by simulation and gui. * * Works recursively if needed. * * The returned object is in the form: * ``` * { "techs": ["tech1", "tech2"] }, * { "techs": ["tech3"] } * ``` * or * ``` * { "entities": [[{ * "class": "human", * "number": 2, * "check": "count" * } * or * ``` * false; * ``` * (Or, to translate: * 1. need either both `tech1` and `tech2`, or `tech3` * 2. need 2 entities with the `human` class * 3. cannot research this tech at all) * * @param {string} civ - The civ code * @param {string} operator - The base operation. Can be "civ", "notciv", "tech", "entity", "all" or "any". * @param {mixed} value - The value associated with the above operation. * * @return Object containing the requirements for the given civ, or false if the civ cannot research the tech. */ function InterpretTechRequirements(civ, operator, value) { let requirements = []; switch (operator) { case "civ": return !civ || civ == value ? [] : false; case "notciv": return civ == value ? false : []; case "entity": { let number = value.number || value.numberOfTypes || 0; if (number > 0) requirements.push({ "entities": [{ "class": value.class, "number": number, "check": value.number ? "count" : "variants" }] }); break; } case "tech": requirements.push({ "techs": [value] }); break; case "all": { let civPermitted = undefined; // tri-state (undefined, false, or true) for (let subvalue of value) { let newOper = Object.keys(subvalue)[0]; let newValue = subvalue[newOper]; let result = InterpretTechRequirements(civ, newOper, newValue); switch (newOper) { case "civ": if (result) civPermitted = true; else if (civPermitted !== true) civPermitted = false; break; case "notciv": if (!result) return false; break; case "any": if (!result) return false; // else, fall through case "all": if (!result) { let nullcivreqs = InterpretTechRequirements(null, newOper, newValue); if (!nullcivreqs || !nullcivreqs.length) civPermitted = false; continue; } // else, fall through case "tech": case "entity": { if (result.length) { if (!requirements.length) requirements.push({}); let newRequirements = []; for (let currReq of requirements) for (let res of result) { let newReq = {}; for (let subtype in currReq) newReq[subtype] = currReq[subtype]; for (let subtype in res) { if (!newReq[subtype]) newReq[subtype] = []; newReq[subtype] = newReq[subtype].concat(res[subtype]); } newRequirements.push(newReq); } requirements = newRequirements; } break; } } } if (civPermitted === false) // if and only if false return false; break; } case "any": { let civPermitted = false; for (let subvalue of value) { let newOper = Object.keys(subvalue)[0]; let newValue = subvalue[newOper]; let result = InterpretTechRequirements(civ, newOper, newValue); switch (newOper) { case "civ": if (result) return []; break; case "notciv": if (!result) return false; civPermitted = true; break; case "any": if (!result) { let nullcivreqs = InterpretTechRequirements(null, newOper, newValue); if (!nullcivreqs || !nullcivreqs.length) continue; return false; } // else, fall through case "all": if (!result) continue; civPermitted = true; // else, fall through case "tech": case "entity": for (let res of result) requirements.push(res); break; } } if (!civPermitted && !requirements.length) return false; break; } default: warn("Unknown requirement operator: "+operator); } return requirements; } /** * Determine order of phases. * * @param {object} phases - The current available store of phases. * @return {array} List of phases */ function UnravelPhases(phases) { let phaseMap = {}; for (let phaseName in phases) { let phaseData = phases[phaseName]; if (!phaseData.reqs.length || !phaseData.reqs[0].techs || !phaseData.replaces) continue; let myPhase = phaseData.replaces[0]; let reqPhase = phaseData.reqs[0].techs[0]; if (phases[reqPhase] && phases[reqPhase].replaces) reqPhase = phases[reqPhase].replaces[0]; phaseMap[myPhase] = reqPhase; if (!phaseMap[reqPhase]) phaseMap[reqPhase] = undefined; } let phaseList = Object.keys(phaseMap); phaseList.sort((a, b) => phaseList.indexOf(a) - phaseList.indexOf(phaseMap[b])); return phaseList; } Index: ps/trunk/binaries/data/mods/public/globalscripts/tests/test_Technologies_effects.js =================================================================== --- ps/trunk/binaries/data/mods/public/globalscripts/tests/test_Technologies_effects.js (nonexistent) +++ ps/trunk/binaries/data/mods/public/globalscripts/tests/test_Technologies_effects.js (revision 23862) @@ -0,0 +1,61 @@ +// This tests the GetTechModifiedProperty function. + +function test_numeric() +{ + let add = [{ "add": 10, "affects": "Unit" }]; + + let add_add = [{ "add": 10, "affects": "Unit" }, { "add": 5, "affects": "Unit" }]; + + let add_mul_add = [{ "add": 10, "affects": "Unit" }, { "multiply": 2, "affects": "Unit" }, { "add": 5, "affects": "Unit" }]; + + let add_replace = [{ "add": 10, "affects": "Unit" }, { "replace": 10, "affects": "Unit" }]; + + let replace_add = [{ "replace": 10, "affects": "Unit" }, { "add": 10, "affects": "Unit" }]; + + let replace_replace = [{ "replace": 10, "affects": "Unit" }, { "replace": 30, "affects": "Unit" }]; + + TS_ASSERT_EQUALS(GetTechModifiedProperty(add, "Unit", 5), 15); + TS_ASSERT_EQUALS(GetTechModifiedProperty(add_add, "Unit", 5), 20); + TS_ASSERT_EQUALS(GetTechModifiedProperty(add_add, "Other", 5), 5); + + // Technologies work by multiplying then adding all. + TS_ASSERT_EQUALS(GetTechModifiedProperty(add_mul_add, "Unit", 5), 25); + + TS_ASSERT_EQUALS(GetTechModifiedProperty(add_replace, "Unit", 5), 10); + + // Only the first replace is taken into account + TS_ASSERT_EQUALS(GetTechModifiedProperty(replace_replace, "Unit", 5), 10); +} +test_numeric(); + +function test_non_numeric() +{ + let replace_nonnum = [{ "replace": "alpha", "affects": "Unit" }]; + + TS_ASSERT_EQUALS(GetTechModifiedProperty(replace_nonnum, "Unit", "beta"), "alpha"); + TS_ASSERT_EQUALS(GetTechModifiedProperty(replace_nonnum, "Structure", "beta"), "beta"); + + let replace_tokens = [{ "tokens": "-beta alpha gamma -delta", "affects": "Unit" }]; + TS_ASSERT_EQUALS(GetTechModifiedProperty(replace_tokens, "Unit", "beta"), "alpha gamma"); + TS_ASSERT_EQUALS(GetTechModifiedProperty(replace_tokens, "Structure", "beta"), "beta"); + + let replace_tokens_2 = [{ "tokens": "beta>gamma -delta", "affects": "Unit" }]; + TS_ASSERT_EQUALS(GetTechModifiedProperty(replace_tokens_2, "Unit", "beta"), "gamma"); + TS_ASSERT_EQUALS(GetTechModifiedProperty(replace_tokens_2, "Structure", "beta"), "beta"); + + let replace_tokens_3 = [ + { "tokens": "beta>alpha gamma", "affects": "Unit" }, + { "tokens": "alpha>zeta -gamma delta", "affects": "Unit" } + ]; + TS_ASSERT_EQUALS(GetTechModifiedProperty(replace_tokens_3, "Unit", "beta"), "zeta delta"); + TS_ASSERT_EQUALS(GetTechModifiedProperty(replace_tokens_3, "Structure", "beta"), "beta"); + + // Ordering matters. + let replace_tokens_4 = [ + { "tokens": "alpha>zeta -gamma delta", "affects": "Unit" }, + { "tokens": "beta>alpha gamma", "affects": "Unit" } + ]; + TS_ASSERT_EQUALS(GetTechModifiedProperty(replace_tokens_4, "Unit", "beta"), "alpha delta gamma"); +} + +test_non_numeric(); Property changes on: ps/trunk/binaries/data/mods/public/globalscripts/tests/test_Technologies_effects.js ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ps/trunk/binaries/data/mods/public/globalscripts/tests/test_Technologies_reqs.js =================================================================== --- ps/trunk/binaries/data/mods/public/globalscripts/tests/test_Technologies_reqs.js (nonexistent) +++ ps/trunk/binaries/data/mods/public/globalscripts/tests/test_Technologies_reqs.js (revision 23862) @@ -0,0 +1,581 @@ +// No requirements set in template +let template = {}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); + +/** + * First, the basics: + */ + +// Technology Requirement +template.requirements = { "tech": "expected_tech" }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["expected_tech"] }]); + +// Entity Requirement: Count of entities matching given class +template.requirements = { "entity": { "class": "Village", "number": 5 } }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "entities": [{ "class": "Village", "number": 5, "check": "count" }] }]); + +// Entity Requirement: Count of entities matching given class +template.requirements = { "entity": { "class": "Village", "numberOfTypes": 5 } }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "entities": [{ "class": "Village", "number": 5, "check": "variants" }] }]); + +// Single `civ` +template.requirements = { "civ": "athen" }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), false); + +// Single `notciv` +template.requirements = { "notciv": "athen" }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), []); + + +/** + * Basic `all`s: + */ + +// Multiple techs +template.requirements = { "all": [{ "tech": "tech_A" }, { "tech": "tech_B" }, { "tech": "tech_C" }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A", "tech_B", "tech_C"] }]); + +// Multiple entity definitions +template.requirements = { + "all": [ + { "entity": { "class": "class_A", "number": 5 } }, + { "entity": { "class": "class_B", "number": 5 } }, + { "entity": { "class": "class_C", "number": 5 } } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), + [{ "entities": [{ "class": "class_A", "number": 5, "check": "count" }, { "class": "class_B", "number": 5, "check": "count" }, { "class": "class_C", "number": 5, "check": "count" }] }]); + +// A `tech` and an `entity` +template.requirements = { "all": [{ "tech": "tech_A" }, { "entity": { "class": "class_B", "number": 5, "check": "count" } }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A"], "entities": [{ "class": "class_B", "number": 5, "check": "count" }] }]); + +// Multiple `civ`s +template.requirements = { "all": [{ "civ": "civ_A" }, { "civ": "civ_B" }, { "civ": "civ_C" }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), []); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), []); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), []); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), false); + +// Multiple `notciv`s +template.requirements = { "all": [{ "notciv": "civ_A" }, { "notciv": "civ_B" }, { "notciv": "civ_C" }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), []); + +// A `civ` with a tech/entity +template.requirements = { "all": [{ "civ": "athen" }, { "tech": "expected_tech" }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["expected_tech"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), false); + +template.requirements = { "all": [{ "civ": "athen" }, { "entity": { "class": "Village", "number": 5 } }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "entities": [{ "class": "Village", "number": 5, "check": "count" }] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), false); + +template.requirements = { "all": [{ "civ": "athen" }, { "entity": { "class": "Village", "numberOfTypes": 5 } }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "entities": [{ "class": "Village", "number": 5, "check": "variants" }] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), false); + +// A `notciv` with a tech/entity +template.requirements = { "all": [{ "notciv": "athen" }, { "tech": "expected_tech" }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "techs": ["expected_tech"] }]); + +template.requirements = { "all": [{ "notciv": "athen" }, { "entity": { "class": "Village", "number": 5 } }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "entities": [{ "class": "Village", "number": 5, "check": "count" }] }]); + +template.requirements = { "all": [{ "notciv": "athen" }, { "entity": { "class": "Village", "numberOfTypes": 5 } }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "entities": [{ "class": "Village", "number": 5, "check": "variants" }] }]); + + +/** + * Basic `any`s: + */ + +// Multiple techs +template.requirements = { "any": [{ "tech": "tech_A" }, { "tech": "tech_B" }, { "tech": "tech_C" }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A"] }, { "techs": ["tech_B"] }, { "techs": ["tech_C"] }]); + +// Multiple entity definitions +template.requirements = { + "any": [ + { "entity": { "class": "class_A", "number": 5 } }, + { "entity": { "class": "class_B", "number": 5 } }, + { "entity": { "class": "class_C", "number": 5 } } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [ + { "entities": [{ "class": "class_A", "number": 5, "check": "count" }] }, + { "entities": [{ "class": "class_B", "number": 5, "check": "count" }] }, + { "entities": [{ "class": "class_C", "number": 5, "check": "count" }] } +]); + +// A tech or an entity +template.requirements = { "any": [{ "tech": "tech_A" }, { "entity": { "class": "class_B", "number": 5, "check": "count" } }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A"] }, { "entities": [{ "class": "class_B", "number": 5, "check": "count" }] }]); + +// Multiple `civ`s +template.requirements = { "any": [{ "civ": "civ_A" }, { "civ": "civ_B" }, { "civ": "civ_C" }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), []); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), []); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), []); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), false); + +// Multiple `notciv`s +template.requirements = { "any": [{ "notciv": "civ_A" }, { "notciv": "civ_B" }, { "notciv": "civ_C" }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_A"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_B"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_C"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civ_D"), []); + +// A `civ` or a tech/entity +template.requirements = { "any": [{ "civ": "athen" }, { "tech": "expected_tech" }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "techs": ["expected_tech"] }]); + +template.requirements = { "any": [{ "civ": "athen" }, { "entity": { "class": "Village", "number": 5 } }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "entities": [{ "class": "Village", "number": 5, "check": "count" }] }]); + +template.requirements = { "any": [{ "civ": "athen" }, { "entity": { "class": "Village", "numberOfTypes": 5 } }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "entities": [{ "class": "Village", "number": 5, "check": "variants" }] }]); + +// A `notciv` or a tech +template.requirements = { "any": [{ "notciv": "athen" }, { "tech": "expected_tech" }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "techs": ["expected_tech"] }]); + +template.requirements = { "any": [{ "notciv": "athen" }, { "entity": { "class": "Village", "number": 5 } }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "entities": [{ "class": "Village", "number": 5, "check": "count" }] }]); + +template.requirements = { "any": [{ "notciv": "athen" }, { "entity": { "class": "Village", "numberOfTypes": 5 } }] }; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "spart"), [{ "entities": [{ "class": "Village", "number": 5, "check": "variants" }] }]); + + +/** + * Complicated `all`s, part 1 - an `all` inside an `all`: + */ + +// Techs +template.requirements = { + "all": [ + { "all": [{ "tech": "tech_A" }, { "tech": "tech_B" }] }, + { "all": [{ "tech": "tech_C" }, { "tech": "tech_D" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A", "tech_B", "tech_C", "tech_D"] }]); + +// Techs and entities +template.requirements = { + "all": [ + { "all": [{ "tech": "tech_A" }, { "entity": { "class": "class_A", "number": 5 } }] }, + { "all": [{ "entity": { "class": "class_B", "numberOfTypes": 5 } }, { "tech": "tech_B" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ + "techs": ["tech_A", "tech_B"], + "entities": [{ "class": "class_A", "number": 5, "check": "count" }, { "class": "class_B", "number": 5, "check": "variants" }] +}]); + +// Two `civ`s, without and with a tech +template.requirements = { + "all": [ + { "all": [{ "civ": "athen" }, { "civ": "spart" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), false); + +template.requirements = { + "all": [ + { "tech": "required_tech" }, + { "all": [{ "civ": "athen" }, { "civ": "spart" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["required_tech"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), false); + +// Two `notciv`s, without and with a tech +template.requirements = { + "all": [ + { "all": [{ "notciv": "athen" }, { "notciv": "spart" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), []); + +template.requirements = { + "all": [ + { "tech": "required_tech" }, + { "all": [{ "notciv": "athen" }, { "notciv": "spart" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["required_tech"] }]); + +// Inner `all` has a tech and a `civ`/`notciv` +template.requirements = { + "all": [ + { "all": [{ "tech": "tech_A" }, { "civ": "maur" }] }, + { "tech": "tech_B" } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_B"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["tech_A", "tech_B"] }]); + +template.requirements = { + "all": [ + { "all": [{ "tech": "tech_A" }, { "notciv": "maur" }] }, + { "tech": "tech_B" } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["tech_A", "tech_B"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["tech_B"] }]); + + +/** + * Complicated `all`s, part 2 - an `any` inside an `all`: + */ + +// Techs +template.requirements = { + "all": [ + { "any": [{ "tech": "tech_A" }, { "tech": "tech_B" }] }, + { "any": [{ "tech": "tech_C" }, { "tech": "tech_D" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [ + { "techs": ["tech_A", "tech_C"] }, + { "techs": ["tech_A", "tech_D"] }, + { "techs": ["tech_B", "tech_C"] }, + { "techs": ["tech_B", "tech_D"] } +]); + +// Techs and entities +template.requirements = { + "all": [ + { "any": [{ "tech": "tech_A" }, { "entity": { "class": "class_A", "number": 5 } }] }, + { "any": [{ "entity": { "class": "class_B", "numberOfTypes": 5 } }, { "tech": "tech_B" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [ + { "techs": ["tech_A"], "entities": [{ "class": "class_B", "number": 5, "check": "variants" }] }, + { "techs": ["tech_A", "tech_B"] }, + { "entities": [{ "class": "class_A", "number": 5, "check": "count" }, { "class": "class_B", "number": 5, "check": "variants" }] }, + { "entities": [{ "class": "class_A", "number": 5, "check": "count" }], "techs": ["tech_B"] } +]); + +// Two `civ`s, without and with a tech +template.requirements = { + "all": [ + { "any": [{ "civ": "athen" }, { "civ": "spart" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), false); + +template.requirements = { + "all": [ + { "tech": "required_tech" }, + { "any": [{ "civ": "athen" }, { "civ": "spart" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["required_tech"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), false); + +// Two `notciv`s, without and with a tech +template.requirements = { + "all": [ + { "any": [{ "notciv": "athen" }, { "notciv": "spart" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), []); + +template.requirements = { + "all": [ + { "tech": "required_tech" }, + { "any": [{ "notciv": "athen" }, { "notciv": "spart" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["required_tech"] }]); + + +/** + * Complicated `any`s, part 1 - an `all` inside an `any`: + */ + +// Techs +template.requirements = { + "any": [ + { "all": [{ "tech": "tech_A" }, { "tech": "tech_B" }] }, + { "all": [{ "tech": "tech_C" }, { "tech": "tech_D" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [ + { "techs": ["tech_A", "tech_B"] }, + { "techs": ["tech_C", "tech_D"] } +]); + +// Techs and entities +template.requirements = { + "any": [ + { "all": [{ "tech": "tech_A" }, { "entity": { "class": "class_A", "number": 5 } }] }, + { "all": [{ "entity": { "class": "class_B", "numberOfTypes": 5 } }, { "tech": "tech_B" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [ + { "techs": ["tech_A"], "entities": [{ "class": "class_A", "number": 5, "check": "count" }] }, + { "entities": [{ "class": "class_B", "number": 5, "check": "variants" }], "techs": ["tech_B"] } +]); + +// Two `civ`s, without and with a tech +template.requirements = { + "any": [ + { "all": [{ "civ": "athen" }, { "civ": "spart" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), false); + +template.requirements = { + "any": [ + { "tech": "required_tech" }, + { "all": [{ "civ": "athen" }, { "civ": "spart" }] } + ] +}; +// Note: these requirements don't really make sense, as the `any` makes the `civ`s in the the inner `all` irrelevant. +// We test it anyway as a precursor to later tests. +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["required_tech"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["required_tech"] }]); + +// Two `notciv`s, without and with a tech +template.requirements = { + "any": [ + { "all": [{ "notciv": "athen" }, { "notciv": "spart" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), []); + +template.requirements = { + "any": [ + { "tech": "required_tech" }, + { "all": [{ "notciv": "athen" }, { "notciv": "spart" }] } + ] +}; +// Note: these requirements have a result that might seen unexpected at first glance. +// This is because the `notciv`s are rendered irrelevant by the `any`, and they have nothing else to operate on. +// We test it anyway as a precursor for later tests. +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["required_tech"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["required_tech"] }]); + +// Inner `all` has a tech and a `civ`/`notciv` +template.requirements = { + "any": [ + { "all": [{ "civ": "civA" }, { "tech": "tech1" }] }, + { "tech": "tech2" } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civA"), [{ "techs": ["tech1"] }, { "techs": ["tech2"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civB"), [{ "techs": ["tech2"] }]); + +template.requirements = { + "any": [ + { "all": [{ "notciv": "civA" }, { "tech": "tech1" }] }, + { "tech": "tech2" } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civA"), [{ "techs": ["tech2"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civB"), [{ "techs": ["tech1"] }, { "techs": ["tech2"] }]); + + +/** + * Complicated `any`s, part 2 - an `any` inside an `any`: + */ + +// Techs +template.requirements = { + "any": [ + { "any": [{ "tech": "tech_A" }, { "tech": "tech_B" }] }, + { "any": [{ "tech": "tech_C" }, { "tech": "tech_D" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [ + { "techs": ["tech_A"] }, + { "techs": ["tech_B"] }, + { "techs": ["tech_C"] }, + { "techs": ["tech_D"] } +]); + +// Techs and entities +template.requirements = { + "any": [ + { "any": [{ "tech": "tech_A" }, { "entity": { "class": "class_A", "number": 5 } }] }, + { "any": [{ "entity": { "class": "class_B", "numberOfTypes": 5 } }, { "tech": "tech_B" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [ + { "techs": ["tech_A"] }, + { "entities": [{ "class": "class_A", "number": 5, "check": "count" }] }, + { "entities": [{ "class": "class_B", "number": 5, "check": "variants" }] }, + { "techs": ["tech_B"] } +]); + +// Two `civ`s, without and with a tech +template.requirements = { + "any": [ + { "any": [{ "civ": "athen" }, { "civ": "spart" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), []); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), false); + +template.requirements = { + "any": [ + { "tech": "required_tech" }, + { "any": [{ "civ": "athen" }, { "civ": "spart" }] } + ] +}; +// These requirements may not make sense, as the `civ`s are unable to restrict the requirements due to the outer `any` +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["required_tech"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["required_tech"] }]); + +// Two `notciv`s, without and with a tech +template.requirements = { + "any": [ + { "any": [{ "notciv": "athen" }, { "notciv": "spart" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), false); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), []); + +template.requirements = { + "any": [ + { "tech": "required_tech" }, + { "any": [{ "notciv": "athen" }, { "notciv": "spart" }] } + ] +}; +// These requirements may not make sense, as the `notciv`s are made irrelevant by the outer `any` +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "athen"), [{ "techs": ["required_tech"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "maur"), [{ "techs": ["required_tech"] }]); + + +/** + * Further tests + */ + +template.requirements = { + "all": [ + { "tech": "tech1" }, + { "any": [{ "civ": "civA" }, { "civ": "civB" }] }, + { "notciv": "civC" } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civA"), [{ "techs": ["tech1"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civC"), false); + +template.requirements = { + "any": [ + { "all": [{ "civ": "civA" }, { "tech": "tech1" }] }, + { "all": [{ "civ": "civB" }, { "tech": "tech2" }] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civA"), [{ "techs": ["tech1"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civB"), [{ "techs": ["tech2"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civC"), false); + +template.requirements = { + "any": [ + { "all": [{ "civ": "civA" }, { "tech": "tech1" }] }, + { "all": [ + { "any": [{ "civ": "civB" }, { "civ": "civC" }] }, + { "tech": "tech2" } + ] } + ] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civA"), [{ "techs": ["tech1"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civC"), [{ "techs": ["tech2"] }]); +TS_ASSERT_UNEVAL_EQUALS(DeriveTechnologyRequirements(template, "civD"), false); + +// Test DeriveModificationsFromTech +template = { + "modifications": [{ + "value": "ResourceGatherer/Rates/food.grain", + "multiply": 15, + "affects": "Spearman Swordsman" + }, + { + "value": "ResourceGatherer/Rates/food.meat", + "multiply": 10 + }], + "affects": ["FemaleCitizen", "CitizenSoldier Melee"] +}; +let techMods = { + "ResourceGatherer/Rates/food.grain": [{ + "affects": [ + ["FemaleCitizen", "Spearman", "Swordsman"], + ["CitizenSoldier", "Melee", "Spearman", "Swordsman"] + ], + "multiply": 15 + }], + "ResourceGatherer/Rates/food.meat": [{ + "affects": [ + ["FemaleCitizen"], + ["CitizenSoldier", "Melee"] + ], + "multiply": 10 + }] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveModificationsFromTech(template), techMods); + +template = { + "modifications": [{ + "value": "ResourceGatherer/Rates/food.grain", + "multiply": 15, + "affects": "Spearman" + }, + { + "value": "ResourceGatherer/Rates/food.grain", + "multiply": 15, + "affects": "Swordsman" + }, + { + "value": "ResourceGatherer/Rates/food.meat", + "multiply": 10 + }], + "affects": ["FemaleCitizen", "CitizenSoldier Melee"] +}; +techMods = { + "ResourceGatherer/Rates/food.grain": [{ + "affects": [ + ["FemaleCitizen", "Spearman"], + ["CitizenSoldier", "Melee", "Spearman"] + ], + "multiply": 15 + }, + { + "affects": [ + ["FemaleCitizen", "Swordsman"], + ["CitizenSoldier", "Melee", "Swordsman"] + ], + "multiply": 15 + }], + "ResourceGatherer/Rates/food.meat": [{ + "affects": [ + ["FemaleCitizen"], + ["CitizenSoldier", "Melee"] + ], + "multiply": 10 + }] +}; +TS_ASSERT_UNEVAL_EQUALS(DeriveModificationsFromTech(template), techMods); Property changes on: ps/trunk/binaries/data/mods/public/globalscripts/tests/test_Technologies_reqs.js ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property