Resources = {
"BuildSchema": () => {
let schema = "";
for (let res of ["food", "metal", "wood"])
{
for (let subtype in ["meat", "grain"])
schema += "" + res + "." + subtype + "";
schema += " treasure." + res + "";
}
return "" + schema + "";
},
"GetResource": (type) => {
return {
"subtypes": {
"meat": "meat",
"grain": "grain",
"tree": "tree"
}
};
}
};
Engine.LoadHelperScript("Player.js");
Engine.LoadComponentScript("interfaces/ResourceDropsite.js");
Engine.LoadComponentScript("interfaces/ResourceGatherer.js");
Engine.LoadComponentScript("interfaces/ResourceSupply.js");
Engine.LoadComponentScript("interfaces/StatisticsTracker.js");
Engine.LoadComponentScript("interfaces/Timer.js");
Engine.LoadComponentScript("interfaces/UnitAI.js");
Engine.LoadComponentScript("ResourceGatherer.js");
Engine.LoadComponentScript("Timer.js");
AddMock(SYSTEM_ENTITY, IID_ObstructionManager, {
"IsInTargetRange": () => true
});
Engine.RegisterGlobal("ApplyValueModificationsToEntity", (prop, oVal, ent) => oVal);
Engine.RegisterGlobal("QueryOwnerInterface", () => {});
let cmpTimer;
const gathererID = 11;
const dropsiteID = 12;
const supplyID = 13;
let template = {
"MaxDistance": "10",
"BaseSpeed": "1",
"Rates": {
"food.grain": "1",
"wood.tree": "2"
},
"Capacities": {
"food": "10",
"wood": "20"
}
};
let cmpResourceGatherer = ConstructComponent(gathererID, "ResourceGatherer", template);
cmpResourceGatherer.RecalculateGatherRates();
cmpResourceGatherer.RecalculateCapacities();
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(), []);
cmpResourceGatherer.GiveResources([{ "type": "food", "amount": 11 }]);
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(), [ {
"type": "food",
"amount": 11,
"max": 10
}]);
cmpResourceGatherer.DropResources();
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(), []);
// Test committing resources.
AddMock(dropsiteID, IID_ResourceDropsite, {
"ReceiveResources": (resources, ent) => {
return {
"food": resources.food
};
}
});
cmpResourceGatherer.GiveResources([{ "type": "food", "amount": 1 }]);
cmpResourceGatherer.CommitResources(dropsiteID);
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(), []);
cmpResourceGatherer.GiveResources([{
"type": "food",
"amount": 11
}, {
"type": "wood",
"amount": 1
}]);
cmpResourceGatherer.CommitResources(dropsiteID);
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(), [ {
"type": "wood",
"amount": 1,
"max": 20
}]);
cmpResourceGatherer.DropResources();
function reset()
{
cmpResourceGatherer = ConstructComponent(gathererID, "ResourceGatherer", template);
cmpResourceGatherer.OnGlobalInitGame(); // Force updating values.
cmpTimer = ConstructComponent(SYSTEM_ENTITY, "Timer", null);
}
// Test normal gathering.
reset();
// Supply is empty.
AddMock(supplyID, IID_ResourceSupply, {
"AddActiveGatherer": () => true,
"GetCurrentAmount": () => 0
});
// Supply is wrong type.
AddMock(supplyID, IID_ResourceSupply, {
"AddActiveGatherer": () => true,
"GetCurrentAmount": () => 1,
"GetType": () => ({ "generic": "bogus" }),
"GetDiminishingReturns": () => 1
});
TS_ASSERT(!cmpResourceGatherer.StartGathering(supplyID));
TS_ASSERT(!cmpResourceGatherer.StartGathering(supplyID));
// Resource supply is full (or something else).
AddMock(supplyID, IID_ResourceSupply, {
"AddActiveGatherer": () => false,
"GetCurrentAmount": () => 1,
"GetType": () => ({ "generic": "food" }),
"GetDiminishingReturns": () => 1
});
TS_ASSERT(!cmpResourceGatherer.StartGathering(supplyID));
// Supply is non-empty and right type.
AddMock(supplyID, IID_ResourceSupply, {
"AddActiveGatherer": () => true,
"GetCurrentAmount": () => 2,
"GetType": () => ({ "generic": "food", "specific": "grain" }),
"GetDiminishingReturns": () => 1,
"TakeResources": (amount) => {
return {
"amount": amount,
"exhausted": false
};
},
"RemoveGatherer": () => {}
});
TS_ASSERT(cmpResourceGatherer.StartGathering(supplyID));
cmpTimer.OnUpdate({ "turnLength": 1 });
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(),
[{ "type": "food", "amount": 1, "max": 10 }]);
TS_ASSERT_EQUALS(cmpResourceGatherer.GetMainCarryingType(), "food");
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetLastCarriedType(), { "generic": "food", "specific": "grain" });
cmpTimer.OnUpdate({ "turnLength": 1 });
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(),
[{ "type": "food", "amount": 2, "max": 10 }]);
cmpResourceGatherer.StopGathering();
cmpTimer.OnUpdate({ "turnLength": 1 });
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(),
[{ "type": "food", "amount": 2, "max": 10 }]);
TS_ASSERT(cmpResourceGatherer.IsCarrying("food"));
TS_ASSERT(cmpResourceGatherer.CanCarryMore("food"));
// Test that when gathering a second type the first gathered type is ditched.
reset();
AddMock(supplyID, IID_ResourceSupply, {
"AddActiveGatherer": () => true,
"GetCurrentAmount": () => 2,
"GetType": () => ({ "generic": "food", "specific": "grain" }),
"GetDiminishingReturns": () => 1,
"TakeResources": (amount) => {
return {
"amount": amount,
"exhausted": false
};
},
"RemoveGatherer": () => {}
});
TS_ASSERT(cmpResourceGatherer.StartGathering(supplyID));
cmpTimer.OnUpdate({ "turnLength": 1 });
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(),
[{ "type": "food", "amount": 1, "max": 10 }]);
cmpResourceGatherer.StopGathering();
AddMock(supplyID, IID_ResourceSupply, {
"AddActiveGatherer": () => true,
"GetCurrentAmount": () => 3,
"GetType": () => ({ "generic": "wood", "specific": "tree" }),
"GetDiminishingReturns": () => 1,
"TakeResources": (amount) => {
return {
"amount": amount,
"exhausted": false
};
},
"RemoveGatherer": () => {}
});
TS_ASSERT(cmpResourceGatherer.StartGathering(supplyID));
cmpTimer.OnUpdate({ "turnLength": 1 });
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(),
[{ "type": "wood", "amount": 2, "max": 20 }]);
TS_ASSERT(!cmpResourceGatherer.IsCarrying("food"));
TS_ASSERT(cmpResourceGatherer.CanCarryMore("food"));
TS_ASSERT(cmpResourceGatherer.IsCarrying("wood"));
TS_ASSERT(cmpResourceGatherer.CanCarryMore("wood"));
// Test that we stop gathering when the target is exhausted.
reset();
AddMock(supplyID, IID_ResourceSupply, {
"AddActiveGatherer": () => true,
"GetCurrentAmount": () => 1,
"GetType": () => ({ "generic": "food", "specific": "grain" }),
"GetDiminishingReturns": () => 1,
"TakeResources": (amount) => {
return {
"amount": amount,
"exhausted": true
};
},
"RemoveGatherer": () => {}
});
TS_ASSERT(cmpResourceGatherer.StartGathering(supplyID));
cmpTimer.OnUpdate({ "turnLength": 1 });
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(),
[{ "type": "food", "amount": 1, "max": 10 }]);
cmpTimer.OnUpdate({ "turnLength": 1 });
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(),
[{ "type": "food", "amount": 1, "max": 10 }]);
// Test that we stop gathering when we are filled.
reset();
AddMock(supplyID, IID_ResourceSupply, {
"AddActiveGatherer": () => true,
"GetCurrentAmount": () => 11,
"GetType": () => ({ "generic": "food", "specific": "grain" }),
"GetDiminishingReturns": () => 1,
"TakeResources": (amount) => {
return {
"amount": amount,
"exhausted": false
};
},
"RemoveGatherer": () => {}
});
TS_ASSERT(cmpResourceGatherer.StartGathering(supplyID));
cmpTimer.OnUpdate({ "turnLength": 10 });
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(),
[{ "type": "food", "amount": 10, "max": 10 }]);
cmpTimer.OnUpdate({ "turnLength": 1 });
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(),
[{ "type": "food", "amount": 10, "max": 10 }]);
// Test that starting to gather twice does not add resources at twice the speed.
reset();
AddMock(supplyID, IID_ResourceSupply, {
"AddActiveGatherer": () => true,
"GetCurrentAmount": () => 3,
"GetType": () => ({ "generic": "food", "specific": "grain" }),
"GetDiminishingReturns": () => 1,
"TakeResources": (amount) => {
return {
"amount": amount,
"exhausted": false
};
},
"RemoveGatherer": () => {}
});
TS_ASSERT(cmpResourceGatherer.StartGathering(supplyID));
cmpTimer.OnUpdate({ "turnLength": 1 });
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(),
[{ "type": "food", "amount": 1, "max": 10 }]);
cmpTimer.OnUpdate({ "turnLength": 1 });
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(),
[{ "type": "food", "amount": 2, "max": 10 }]);
TS_ASSERT(cmpResourceGatherer.StartGathering(supplyID));
cmpTimer.OnUpdate({ "turnLength": 1 });
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(),
[{ "type": "food", "amount": 3, "max": 10 }]);
cmpTimer.OnUpdate({ "turnLength": 1 });
TS_ASSERT_UNEVAL_EQUALS(cmpResourceGatherer.GetCarryingStatus(),
[{ "type": "food", "amount": 4, "max": 10 }]);