mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-06-24 03:28:43 +00:00
Allow to limit unit count per match.
This allows to limit the number of times a specific template can be constructed/trained/created during a match. Part of: https://wildfiregames.com/forum/index.php?/topic/27214-borg-expansion-pack-mod-implementation-in-0ad-alpha-24-release/ Refs. https://wildfiregames.com/forum/topic/24682-champions-and-civilisations-balance-mod-for-a23/ Differential revision: D2411 Reviewed by: @wraitii Comments by: @Angen, @Stan This was SVN commit r24468.
This commit is contained in:
@@ -291,9 +291,13 @@ function GetTemplateDataHelper(template, player, auraTemplates, modifiers = {})
|
||||
}
|
||||
|
||||
if (template.TrainingRestrictions)
|
||||
{
|
||||
ret.trainingRestrictions = {
|
||||
"category": template.TrainingRestrictions.Category,
|
||||
"category": template.TrainingRestrictions.Category
|
||||
};
|
||||
if (template.TrainingRestrictions.MatchLimit)
|
||||
ret.trainingRestrictions.matchLimit = +template.TrainingRestrictions.MatchLimit;
|
||||
}
|
||||
|
||||
if (template.Cost)
|
||||
{
|
||||
|
||||
@@ -1270,13 +1270,28 @@ function getEntityLimitAndCount(playerState, entType)
|
||||
"entLimit": undefined,
|
||||
"entCount": undefined,
|
||||
"entLimitChangers": undefined,
|
||||
"canBeAddedCount": undefined
|
||||
"canBeAddedCount": undefined,
|
||||
"matchLimit": undefined,
|
||||
"matchCount": undefined,
|
||||
"type": undefined
|
||||
};
|
||||
if (!playerState.entityLimits)
|
||||
return ret;
|
||||
let template = GetTemplateData(entType);
|
||||
let entCategory = template.trainingRestrictions && template.trainingRestrictions.category ||
|
||||
template.buildRestrictions && template.buildRestrictions.category;
|
||||
let entCategory;
|
||||
let matchLimit;
|
||||
if (template.trainingRestrictions)
|
||||
{
|
||||
entCategory = template.trainingRestrictions.category;
|
||||
matchLimit = template.trainingRestrictions.matchLimit;
|
||||
ret.type = "training";
|
||||
}
|
||||
else if (template.buildRestrictions)
|
||||
{
|
||||
entCategory = template.buildRestrictions.category;
|
||||
matchLimit = template.buildRestrictions.matchLimit;
|
||||
ret.type = "build";
|
||||
}
|
||||
|
||||
if (entCategory && playerState.entityLimits[entCategory] !== undefined)
|
||||
{
|
||||
@@ -1285,6 +1300,13 @@ function getEntityLimitAndCount(playerState, entType)
|
||||
ret.entLimitChangers = playerState.entityLimitChangers[entCategory];
|
||||
ret.canBeAddedCount = Math.max(ret.entLimit - ret.entCount, 0);
|
||||
}
|
||||
|
||||
if (matchLimit)
|
||||
{
|
||||
ret.matchLimit = matchLimit;
|
||||
ret.matchCount = playerState.matchEntityCounts[entType] || 0;
|
||||
ret.canBeAddedCount = Math.min(Math.max(ret.entLimit - ret.entCount, 0), Math.max(ret.matchLimit - ret.matchCount, 0));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -257,6 +257,7 @@ g_SelectionPanels.Construction = {
|
||||
let limits = getEntityLimitAndCount(data.playerState, data.item);
|
||||
tooltips.push(
|
||||
formatLimitString(limits.entLimit, limits.entCount, limits.entLimitChangers),
|
||||
formatMatchLimitString(limits.matchLimit, limits.matchCount, limits.type),
|
||||
getRequiredTechnologyTooltip(technologyEnabled, template.requiredTechnology, GetSimState().players[data.player].civ),
|
||||
getNeededResourcesTooltip(neededResources));
|
||||
|
||||
@@ -998,7 +999,8 @@ g_SelectionPanels.Training = {
|
||||
getEntityCostTooltip(template, data.player, unitIds[0], buildingsCountToTrainFullBatch, fullBatchSize, remainderBatch)
|
||||
];
|
||||
let limits = getEntityLimitAndCount(data.playerState, data.item);
|
||||
tooltips.push(formatLimitString(limits.entLimit, limits.entCount, limits.entLimitChangers));
|
||||
tooltips.push(formatLimitString(limits.entLimit, limits.entCount, limits.entLimitChangers),
|
||||
formatMatchLimitString(limits.matchLimit, limits.matchCount, limits.type));
|
||||
|
||||
if (Engine.ConfigDB_GetValue("user", "showdetailedtooltips") === "true")
|
||||
tooltips = tooltips.concat([
|
||||
@@ -1111,6 +1113,7 @@ g_SelectionPanels.Upgrade = {
|
||||
tooltips.push(
|
||||
getEntityCostTooltip(data.item, undefined, undefined, data.unitEntStates.length),
|
||||
formatLimitString(limits.entLimit, limits.entCount, limits.entLimitChangers),
|
||||
formatMatchLimitString(limits.matchLimit, limits.matchCount, limits.type),
|
||||
getRequiredTechnologyTooltip(technologyEnabled, data.item.requiredTechnology, GetSimState().players[data.player].civ),
|
||||
getNeededResourcesTooltip(neededResources),
|
||||
showTemplateViewerOnRightClickTooltip());
|
||||
|
||||
@@ -115,6 +115,66 @@ function formatLimitString(trainEntLimit, trainEntCount, trainEntLimitChangers)
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format template match count/limit message for the tooltip.
|
||||
*
|
||||
* @param {number} matchEntLimit - The limit of the entity.
|
||||
* @param {number} matchEntCount - The count of the entity.
|
||||
* @param {string} type - The type of the action (i.e. "build" or "training").
|
||||
*
|
||||
* @return {string} - The string to show the user with information regarding the limit of this template.
|
||||
*/
|
||||
function formatMatchLimitString(matchEntLimit, matchEntCount, type)
|
||||
{
|
||||
if (matchEntLimit == undefined)
|
||||
return "";
|
||||
|
||||
let passedLimit = matchEntCount >= matchEntLimit;
|
||||
let count = matchEntLimit - matchEntCount;
|
||||
let text;
|
||||
if (type == "build")
|
||||
{
|
||||
if (passedLimit)
|
||||
text = sprintf(translatePlural("Could be constructed merely once.", "Could be constructed merely %(limit)s times.", matchEntLimit), {
|
||||
"limit": matchEntLimit
|
||||
});
|
||||
else if (matchEntLimit == 1)
|
||||
text = translate("Can be constructed only once.");
|
||||
else
|
||||
text = sprintf(translatePlural("Can be constructed %(count)s more time.", "Can be constructed %(count)s more times.", count), {
|
||||
"count": count
|
||||
});
|
||||
}
|
||||
else if (type == "training")
|
||||
{
|
||||
if (passedLimit)
|
||||
text = sprintf(translatePlural("Could be trained merely once.", "Could be trained merely %(limit)s times.", matchEntLimit), {
|
||||
"limit": matchEntLimit
|
||||
});
|
||||
else if (matchEntLimit == 1)
|
||||
text = translate("Can be trained only once.");
|
||||
else
|
||||
text = sprintf(translatePlural("Can be trained %(count)s more time.", "Can be trained %(count)s more times.", count), {
|
||||
"count": count
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (passedLimit)
|
||||
text = sprintf(translatePlural("Could be created merely once.", "Could be created merely %(limit)s times.", matchEntLimit), {
|
||||
"limit": matchEntLimit
|
||||
});
|
||||
else if (matchEntLimit == 1)
|
||||
text = translate("Can be created only once.");
|
||||
else
|
||||
text = sprintf(translatePlural("Can be created %(count)s more time.", "Can be created %(count)s more times.", count), {
|
||||
"count": count
|
||||
});
|
||||
}
|
||||
|
||||
return passedLimit ? coloredText(text, "red") : text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format batch training string for the tooltip
|
||||
* Examples:
|
||||
|
||||
@@ -35,6 +35,11 @@ BuildRestrictions.prototype.Schema =
|
||||
"<element name='Category' a:help='Specifies the category of this building, for satisfying special constraints. Choices include: Apadana, CivilCentre, Council, Embassy, Fortress, Gladiator, Hall, Hero, Juggernaut, Library, Lighthouse, Monument, Pillar, PyramidLarge, PyramidSmall, Stoa, TempleOfAmun, Theater, Tower, UniqueBuilding, WarDog, Wonder'>" +
|
||||
"<text/>" +
|
||||
"</element>" +
|
||||
"<optional>" +
|
||||
"<element name='MatchLimit' a:help='Specifies how many times this entity can be created during a match.'>" +
|
||||
"<data type='positiveInteger'/>" +
|
||||
"</element>" +
|
||||
"</optional>" +
|
||||
"<optional>" +
|
||||
"<element name='Distance' a:help='Specifies distance restrictions on this building, relative to buildings from the given category.'>" +
|
||||
"<interleave>" +
|
||||
|
||||
@@ -72,6 +72,7 @@ EntityLimits.prototype.Init = function()
|
||||
this.removers = {};
|
||||
this.classCount = {}; // counts entities with the given class, used in the limit removal
|
||||
this.removedLimit = {};
|
||||
this.matchTemplateCount = {};
|
||||
for (var category in this.template.Limits)
|
||||
{
|
||||
this.limit[category] = +this.template.Limits[category];
|
||||
@@ -103,6 +104,14 @@ EntityLimits.prototype.ChangeCount = function(category, value)
|
||||
this.count[category] += value;
|
||||
};
|
||||
|
||||
EntityLimits.prototype.ChangeMatchCount = function(template, value)
|
||||
{
|
||||
if (!this.matchTemplateCount[template])
|
||||
this.matchTemplateCount[template] = 0;
|
||||
|
||||
this.matchTemplateCount[template] += value;
|
||||
};
|
||||
|
||||
EntityLimits.prototype.GetLimits = function()
|
||||
{
|
||||
return this.limit;
|
||||
@@ -113,6 +122,11 @@ EntityLimits.prototype.GetCounts = function()
|
||||
return this.count;
|
||||
};
|
||||
|
||||
EntityLimits.prototype.GetMatchCounts = function()
|
||||
{
|
||||
return this.matchTemplateCount;
|
||||
};
|
||||
|
||||
EntityLimits.prototype.GetLimitChangers = function()
|
||||
{
|
||||
return this.changers;
|
||||
@@ -145,40 +159,48 @@ EntityLimits.prototype.UpdateLimitRemoval = function()
|
||||
}
|
||||
};
|
||||
|
||||
EntityLimits.prototype.AllowedToCreate = function(limitType, category, count)
|
||||
EntityLimits.prototype.AllowedToCreate = function(limitType, category, count, templateName, matchLimit)
|
||||
{
|
||||
// Allow unspecified categories and those with no limit
|
||||
if (this.count[category] === undefined || this.limit[category] === undefined)
|
||||
return true;
|
||||
|
||||
if (this.count[category] + count > this.limit[category])
|
||||
if (this.count[category] !== undefined && this.limit[category] !== undefined &&
|
||||
this.count[category] + count > this.limit[category])
|
||||
{
|
||||
var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);
|
||||
var notification = {
|
||||
"players": [cmpPlayer.GetPlayerID()],
|
||||
"translateMessage": true,
|
||||
"translateParameters": ["category"],
|
||||
"parameters": {"category": category, "limit": this.limit[category]},
|
||||
};
|
||||
|
||||
if (limitType == BUILD)
|
||||
notification.message = markForTranslation("%(category)s build limit of %(limit)s reached");
|
||||
else if (limitType == TRAINING)
|
||||
notification.message = markForTranslation("%(category)s training limit of %(limit)s reached");
|
||||
else
|
||||
{
|
||||
warn("EntityLimits.js: Unknown LimitType " + limitType);
|
||||
notification.message = markForTranslation("%(category)s limit of %(limit)s reached");
|
||||
}
|
||||
var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
|
||||
cmpGUIInterface.PushNotification(notification);
|
||||
this.NotifyLimit(limitType, category, this.limit[category]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.matchTemplateCount[templateName] !== undefined && matchLimit !== undefined &&
|
||||
this.matchTemplateCount[templateName] + count > matchLimit)
|
||||
{
|
||||
this.NotifyLimit(limitType, category, matchLimit);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
EntityLimits.prototype.NotifyLimit = function(limitType, category, limit)
|
||||
{
|
||||
let cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);
|
||||
let notification = {
|
||||
"players": [cmpPlayer.GetPlayerID()],
|
||||
"translateMessage": true,
|
||||
"translateParameters": ["category"],
|
||||
"parameters": { "category": category, "limit": limit },
|
||||
};
|
||||
|
||||
if (limitType == BUILD)
|
||||
notification.message = markForTranslation("%(category)s build limit of %(limit)s reached");
|
||||
else if (limitType == TRAINING)
|
||||
notification.message = markForTranslation("%(category)s training limit of %(limit)s reached");
|
||||
else
|
||||
{
|
||||
warn("EntityLimits.js: Unknown LimitType " + limitType);
|
||||
notification.message = markForTranslation("%(category)s limit of %(limit)s reached");
|
||||
}
|
||||
let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
|
||||
cmpGUIInterface.PushNotification(notification);
|
||||
};
|
||||
|
||||
EntityLimits.prototype.AllowedToBuild = function(category)
|
||||
{
|
||||
// We pass count 0 as the creation of the building has already taken place and
|
||||
@@ -186,9 +208,9 @@ EntityLimits.prototype.AllowedToBuild = function(category)
|
||||
return this.AllowedToCreate(BUILD, category, 0);
|
||||
};
|
||||
|
||||
EntityLimits.prototype.AllowedToTrain = function(category, count)
|
||||
EntityLimits.prototype.AllowedToTrain = function(category, count, templateName, matchLimit)
|
||||
{
|
||||
return this.AllowedToCreate(TRAINING, category, count);
|
||||
return this.AllowedToCreate(TRAINING, category, count, templateName, matchLimit);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -119,6 +119,7 @@ GuiInterface.prototype.GetSimulationState = function()
|
||||
"isEnemy": enemies,
|
||||
"entityLimits": cmpPlayerEntityLimits ? cmpPlayerEntityLimits.GetLimits() : null,
|
||||
"entityCounts": cmpPlayerEntityLimits ? cmpPlayerEntityLimits.GetCounts() : null,
|
||||
"matchEntityCounts": cmpPlayerEntityLimits ? cmpPlayerEntityLimits.GetMatchCounts() : null,
|
||||
"entityLimitChangers": cmpPlayerEntityLimits ? cmpPlayerEntityLimits.GetLimitChangers() : null,
|
||||
"researchQueued": cmpTechnologyManager ? cmpTechnologyManager.GetQueuedResearch() : null,
|
||||
"researchStarted": cmpTechnologyManager ? cmpTechnologyManager.GetStartedTechs() : null,
|
||||
|
||||
@@ -397,6 +397,8 @@ ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat
|
||||
let cmpPlayerEntityLimits = QueryOwnerInterface(this.entity, IID_EntityLimits);
|
||||
if (cmpPlayerEntityLimits)
|
||||
cmpPlayerEntityLimits.ChangeCount(unitCategory, count);
|
||||
if (template.TrainingRestrictions.MatchLimit)
|
||||
cmpPlayerEntityLimits.ChangeMatchCount(templateName, count);
|
||||
}
|
||||
|
||||
let buildTime = ApplyValueModificationsToTemplate(
|
||||
@@ -545,6 +547,8 @@ ProductionQueue.prototype.RemoveBatch = function(id)
|
||||
let cmpPlayerEntityLimits = QueryPlayerIDInterface(item.player, IID_EntityLimits);
|
||||
if (cmpPlayerEntityLimits)
|
||||
cmpPlayerEntityLimits.ChangeCount(template.TrainingRestrictions.Category, -item.count);
|
||||
if (template.TrainingRestrictions.MatchLimit)
|
||||
cmpPlayerEntityLimits.ChangeMatchCount(item.unitTemplate, -item.count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,12 @@ TrainingRestrictions.prototype.Schema =
|
||||
"</a:example>" +
|
||||
"<element name='Category' a:help='Specifies the category of this unit, for satisfying special constraints. Choices include: Hero, Juggernaut, WarDog'>" +
|
||||
"<text/>" +
|
||||
"</element>";
|
||||
"</element>" +
|
||||
"<optional>" +
|
||||
"<element name='MatchLimit' a:help='Specifies how many times this entity can be trained during a match.'>" +
|
||||
"<data type='positiveInteger'/>" +
|
||||
"</element>" +
|
||||
"</optional>";
|
||||
|
||||
TrainingRestrictions.prototype.Init = function()
|
||||
{
|
||||
|
||||
@@ -34,6 +34,7 @@ let cmpEntityLimits = ConstructComponent(10, "EntityLimits", template);
|
||||
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"));
|
||||
@@ -44,7 +45,7 @@ for (let ent = 60; ent < 63; ++ent)
|
||||
{
|
||||
AddMock(ent, IID_TrainingRestrictions, {
|
||||
"GetCategory": () => "Hero"
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
cmpEntityLimits.OnGlobalOwnershipChanged({ "entity": 60, "from": INVALID_PLAYER, "to": 1 });
|
||||
|
||||
@@ -124,7 +124,8 @@ AddMock(100, IID_Player, {
|
||||
AddMock(100, IID_EntityLimits, {
|
||||
"GetLimits": function() { return { "Foo": 10 }; },
|
||||
"GetCounts": function() { return { "Foo": 5 }; },
|
||||
"GetLimitChangers": function() {return { "Foo": {} }; }
|
||||
"GetLimitChangers": function() { return { "Foo": {} }; },
|
||||
"GetMatchCounts": function() { return { "Bar": 0 }; }
|
||||
});
|
||||
|
||||
AddMock(100, IID_TechnologyManager, {
|
||||
@@ -211,7 +212,8 @@ AddMock(101, IID_Player, {
|
||||
AddMock(101, IID_EntityLimits, {
|
||||
"GetLimits": function() { return { "Bar": 20 }; },
|
||||
"GetCounts": function() { return { "Bar": 0 }; },
|
||||
"GetLimitChangers": function() {return { "Bar": {} }; }
|
||||
"GetLimitChangers": function() { return { "Bar": {} }; },
|
||||
"GetMatchCounts": function() { return { "Foo": 0 }; }
|
||||
});
|
||||
|
||||
AddMock(101, IID_TechnologyManager, {
|
||||
@@ -299,6 +301,7 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetSimulationState(), {
|
||||
"isEnemy": [true, true],
|
||||
"entityLimits": { "Foo": 10 },
|
||||
"entityCounts": { "Foo": 5 },
|
||||
"matchEntityCounts": { "Bar": 0 },
|
||||
"entityLimitChangers": { "Foo": {} },
|
||||
"researchQueued": new Map(),
|
||||
"researchStarted": new Set(),
|
||||
@@ -349,6 +352,7 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetSimulationState(), {
|
||||
"isEnemy": [false, false],
|
||||
"entityLimits": { "Bar": 20 },
|
||||
"entityCounts": { "Bar": 0 },
|
||||
"matchEntityCounts": { "Foo": 0 },
|
||||
"entityLimitChangers": { "Bar": {} },
|
||||
"researchQueued": new Map(),
|
||||
"researchStarted": new Set(),
|
||||
@@ -409,6 +413,7 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedSimulationState(), {
|
||||
"isEnemy": [true, true],
|
||||
"entityLimits": { "Foo": 10 },
|
||||
"entityCounts": { "Foo": 5 },
|
||||
"matchEntityCounts": { "Bar": 0 },
|
||||
"entityLimitChangers": { "Foo": {} },
|
||||
"researchQueued": new Map(),
|
||||
"researchStarted": new Set(),
|
||||
@@ -482,6 +487,7 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedSimulationState(), {
|
||||
"isEnemy": [false, false],
|
||||
"entityLimits": { "Bar": 20 },
|
||||
"entityCounts": { "Bar": 0 },
|
||||
"matchEntityCounts": { "Foo": 0 },
|
||||
"entityLimitChangers": { "Bar": {} },
|
||||
"researchQueued": new Map(),
|
||||
"researchStarted": new Set(),
|
||||
|
||||
@@ -227,7 +227,8 @@ function regression_test_d1879()
|
||||
"Resources": {}
|
||||
},
|
||||
"TrainingRestrictions": {
|
||||
"Category": "some_limit"
|
||||
"Category": "some_limit",
|
||||
"MatchLimit": "7"
|
||||
}
|
||||
})
|
||||
});
|
||||
@@ -244,6 +245,7 @@ function regression_test_d1879()
|
||||
"UnBlockTraining": () => {},
|
||||
"UnReservePopulationSlots": () => {},
|
||||
"TrySubtractResources": () => true,
|
||||
"AddResources": () => true,
|
||||
"TryReservePopulationSlots": () => false // Always have pop space.
|
||||
});
|
||||
|
||||
@@ -259,6 +261,8 @@ function regression_test_d1879()
|
||||
let cmpEntLimits = QueryOwnerInterface(testEntity, IID_EntityLimits);
|
||||
TS_ASSERT(cmpEntLimits.AllowedToTrain("some_limit", 8));
|
||||
TS_ASSERT(!cmpEntLimits.AllowedToTrain("some_limit", 9));
|
||||
TS_ASSERT(cmpEntLimits.AllowedToTrain("some_limit", 5, "some_template", 8));
|
||||
TS_ASSERT(!cmpEntLimits.AllowedToTrain("some_limit", 10, "some_template", 8));
|
||||
|
||||
// Check that the entity limits do get updated if the spawn succeeds.
|
||||
AddMock(testEntity, IID_Footprint, {
|
||||
@@ -268,10 +272,12 @@ function regression_test_d1879()
|
||||
cmpProdQueue.AddBatch("some_template", "unit", 3);
|
||||
|
||||
TS_ASSERT_EQUALS(cmpEntLimits.GetCounts().some_limit, 3);
|
||||
TS_ASSERT_EQUALS(cmpEntLimits.GetMatchCounts().some_template, 3);
|
||||
|
||||
Engine.QueryInterface(testEntity, IID_ProductionQueue).ProgressTimeout();
|
||||
cmpProdQueue.ProgressTimeout();
|
||||
|
||||
TS_ASSERT_EQUALS(cmpEntLimits.GetCounts().some_limit, 3);
|
||||
TS_ASSERT_EQUALS(cmpEntLimits.GetMatchCounts().some_template, 3);
|
||||
|
||||
// Now check that it doesn't get updated when the spawn doesn't succeed.
|
||||
AddMock(testEntity, IID_Footprint, {
|
||||
@@ -283,10 +289,16 @@ function regression_test_d1879()
|
||||
});
|
||||
|
||||
cmpProdQueue.AddBatch("some_template", "unit", 3);
|
||||
Engine.QueryInterface(testEntity, IID_ProductionQueue).ProgressTimeout();
|
||||
cmpProdQueue.ProgressTimeout();
|
||||
|
||||
TS_ASSERT_EQUALS(cmpProdQueue.GetQueue().length, 1);
|
||||
TS_ASSERT_EQUALS(cmpEntLimits.GetCounts().some_limit, 6);
|
||||
TS_ASSERT_EQUALS(cmpEntLimits.GetMatchCounts().some_template, 6);
|
||||
|
||||
// Check that when the batch is removed the counts are subtracted again.
|
||||
cmpProdQueue.RemoveBatch(cmpProdQueue.GetQueue()[0].id);
|
||||
TS_ASSERT_EQUALS(cmpEntLimits.GetCounts().some_limit, 3);
|
||||
TS_ASSERT_EQUALS(cmpEntLimits.GetMatchCounts().some_template, 3);
|
||||
}
|
||||
|
||||
function test_batch_adding()
|
||||
|
||||
@@ -296,7 +296,7 @@ var g_Commands = {
|
||||
if (unitCategory)
|
||||
{
|
||||
var cmpPlayerEntityLimits = QueryOwnerInterface(ent, IID_EntityLimits);
|
||||
if (cmpPlayerEntityLimits && !cmpPlayerEntityLimits.AllowedToTrain(unitCategory, cmd.count))
|
||||
if (cmpPlayerEntityLimits && !cmpPlayerEntityLimits.AllowedToTrain(unitCategory, cmd.count, cmd.template, template.TrainingRestrictions.MatchLimit))
|
||||
{
|
||||
if (g_DebugCommands)
|
||||
warn(unitCategory + " train limit is reached: " + uneval(cmd));
|
||||
|
||||
Reference in New Issue
Block a user