Move Danubius triggerscript function to compose random templates and garrison all entities of a given identity class to TriggerHelper.

Delete the copy thereof in Elephantine, refs #4805, #5040.
Use absolute paths for template names.

This was SVN commit r21416.
This commit is contained in:
elexis 2018-03-02 16:32:10 +00:00
parent 0ff518148e
commit ce65af8dcb
3 changed files with 106 additions and 140 deletions

View file

@ -12,63 +12,63 @@
const showDebugLog = false;
var shipTemplate = "gaul_ship_trireme";
var siegeTemplate = "gaul_mechanical_siege_ram";
var shipTemplate = "units/gaul_ship_trireme";
var siegeTemplate = "units/gaul_mechanical_siege_ram";
var heroTemplates = [
"gaul_hero_viridomarus",
"gaul_hero_vercingetorix",
"gaul_hero_brennus"
"units/gaul_hero_viridomarus",
"units/gaul_hero_vercingetorix",
"units/gaul_hero_brennus"
];
var femaleTemplate = "gaul_support_female_citizen";
var healerTemplate = "gaul_support_healer_b";
var femaleTemplate = "units/gaul_support_female_citizen";
var healerTemplate = "units/gaul_support_healer_b";
var citizenInfantryTemplates = [
"gaul_infantry_javelinist_b",
"gaul_infantry_spearman_b",
"gaul_infantry_slinger_b"
"units/gaul_infantry_javelinist_b",
"units/gaul_infantry_spearman_b",
"units/gaul_infantry_slinger_b"
];
var citizenCavalryTemplates = [
"gaul_cavalry_javelinist_b",
"gaul_cavalry_swordsman_b"
"units/gaul_cavalry_javelinist_b",
"units/gaul_cavalry_swordsman_b"
];
var citizenTemplates = [...citizenInfantryTemplates, ...citizenCavalryTemplates];
var championInfantryTemplates = [
"gaul_champion_fanatic",
"gaul_champion_infantry"
"units/gaul_champion_fanatic",
"units/gaul_champion_infantry"
];
var championCavalryTemplates = [
"gaul_champion_cavalry"
"units/gaul_champion_cavalry"
];
var championTemplates = [...championInfantryTemplates, ...championCavalryTemplates];
var ccDefenders = [
{ "count": 8, "template": "units/" + pickRandom(citizenInfantryTemplates) },
{ "count": 8, "template": "units/" + pickRandom(championInfantryTemplates) },
{ "count": 4, "template": "units/" + pickRandom(championCavalryTemplates) },
{ "count": 4, "template": "units/" + healerTemplate },
{ "count": 5, "template": "units/" + femaleTemplate },
{ "count": 8, "template": pickRandom(citizenInfantryTemplates) },
{ "count": 8, "template": pickRandom(championInfantryTemplates) },
{ "count": 4, "template": pickRandom(championCavalryTemplates) },
{ "count": 4, "template": healerTemplate },
{ "count": 5, "template": femaleTemplate },
{ "count": 10, "template": "gaia/fauna_sheep" }
];
var gallicBuildingGarrison = [
{
"buildings": ["House"],
"units": [femaleTemplate, healerTemplate]
"buildingClasses": ["House"],
"unitTemplates": [femaleTemplate, healerTemplate]
},
{
"buildings": ["CivCentre", "Temple"],
"units": championTemplates
"buildingClasses": ["CivCentre", "Temple"],
"unitTemplates": championTemplates
},
{
"buildings": ["DefenseTower", "Outpost"],
"units": championInfantryTemplates
"buildingClasses": ["DefenseTower", "Outpost"],
"unitTemplates": championInfantryTemplates
}
];
@ -216,64 +216,16 @@ Trigger.prototype.debugLog = function(txt)
Math.round(Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).GetTime() / 60 / 1000) + "] " + txt + "\n");
};
/**
* Return a random amount of these templates whose sum is count.
*/
Trigger.prototype.RandomAttackerTemplates = function(templates, count)
{
let ratios = new Array(templates.length).fill(1).map(i => randFloat(0, 1));
let ratioSum = ratios.reduce((current, sum) => current + sum, 0);
let remainder = count;
let templateCounts = {};
for (let i in templates)
{
let currentCount = +i == templates.length - 1 ? remainder : Math.round(ratios[i] / ratioSum * count);
if (!currentCount)
continue;
templateCounts[templates[i]] = currentCount;
remainder -= currentCount;
}
if (remainder != 0)
warn("Not as many templates as expected: " + count + " vs " + uneval(templateCounts));
return templateCounts;
};
Trigger.prototype.GarrisonAllGallicBuildings = function(gaiaEnts)
{
this.debugLog("Garrisoning all gallic buildings");
for (let buildingGarrison of gallicBuildingGarrison)
for (let building of buildingGarrison.buildings)
this.SpawnAndGarrisonBuilding(gaiaEnts, building, buildingGarrison.units);
};
/**
* Garrisons all targetEnts that match the targetClass with newly spawned entities of the given template.
*/
Trigger.prototype.SpawnAndGarrisonBuilding = function(gaiaEnts, targetClass, templates)
{
for (let gaiaEnt of gaiaEnts)
{
let cmpIdentity = Engine.QueryInterface(gaiaEnt, IID_Identity);
if (!cmpIdentity || !cmpIdentity.HasClass(targetClass))
continue;
let cmpGarrisonHolder = Engine.QueryInterface(gaiaEnt, IID_GarrisonHolder);
if (!cmpGarrisonHolder)
continue;
let unitCounts = this.RandomAttackerTemplates(templates, cmpGarrisonHolder.GetCapacity());
this.debugLog("Garrisoning " + uneval(unitCounts) + " at " + targetClass);
for (let template in unitCounts)
for (let newEnt of TriggerHelper.SpawnUnits(gaiaEnt, "units/" + template, unitCounts[template], gaulPlayer))
Engine.QueryInterface(gaiaEnt, IID_GarrisonHolder).Garrison(newEnt);
}
for (let buildingClass of buildingGarrison.buildingClasses)
{
let unitCounts = this.SpawnAndGarrison(gaulPlayer, buildingClass, buildingGarrison.unitTemplates, 1);
this.debugLog("Garrisoning at " + buildingClass + ": " + uneval(unitCounts));
}
};
/**
@ -316,7 +268,7 @@ Trigger.prototype.SpawnCCAttackers = function()
for (let spawn of toSpawn)
{
let ents = TriggerHelper.SpawnUnits(gaiaCC, "units/" + spawn.template, spawn.count, gaulPlayer);
let ents = TriggerHelper.SpawnUnits(gaiaCC, spawn.template, spawn.count, gaulPlayer);
if (spawn.hero && ents[0])
this.heroes.push({ "template": spawn.template, "ent": ents[0] });
@ -399,7 +351,7 @@ Trigger.prototype.SpawnShips = function()
this.debugLog("Spawning " + shipSpawnCount + " ships");
while (this.ships.length < shipSpawnCount)
this.ships.push(TriggerHelper.SpawnUnits(pickRandom(this.GetTriggerPoints(triggerPointShipSpawn)), "units/" + shipTemplate, 1, gaulPlayer)[0]);
this.ships.push(TriggerHelper.SpawnUnits(pickRandom(this.GetTriggerPoints(triggerPointShipSpawn)), shipTemplate, 1, gaulPlayer)[0]);
for (let ship of this.ships)
this.AttackAndPatrol([ship], shipTargetClass, triggerPointShipPatrol, "Ships");
@ -436,7 +388,7 @@ Trigger.prototype.GetAttackerComposition = function(attackerCount, addSiege)
remainder -= healerCount;
let championCount = Math.round(championRatio(time) * remainder);
let championTemplateCounts = this.RandomAttackerTemplates(championTemplates, championCount);
let championTemplateCounts = this.RandomTemplateComposition(championTemplates, championCount);
for (let template in championTemplateCounts)
{
let count = championTemplateCounts[template];
@ -445,7 +397,7 @@ Trigger.prototype.GetAttackerComposition = function(attackerCount, addSiege)
remainder -= count;
}
let citizenTemplateCounts = this.RandomAttackerTemplates(citizenTemplates, remainder);
let citizenTemplateCounts = this.RandomTemplateComposition(citizenTemplates, remainder);
for (let template in citizenTemplateCounts)
{
let count = citizenTemplateCounts[template];
@ -478,7 +430,7 @@ Trigger.prototype.FillShips = function()
for (let i = 0; i < spawn.count; ++i)
{
let ent = Engine.AddEntity("units/" + spawn.template);
let ent = Engine.AddEntity(spawn.template);
Engine.QueryInterface(ent, IID_Ownership).SetOwner(gaulPlayer);
if (spawn.hero)

View file

@ -1,70 +1,26 @@
Trigger.prototype.InitElephantine = function()
{
let gaiaEnts = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager).GetEntitiesByPlayer(0);
for (let ent of gaiaEnts)
for (let ent of Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager).GetEntitiesByPlayer(0))
{
let cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
if (cmpIdentity && cmpIdentity.HasClass("Soldier"))
Engine.QueryInterface(ent, IID_UnitAI).SwitchToStance("defensive");
}
let kushSupportUnits = ["kush_support_healer_e", "kush_support_female_citizen"];
let kushInfantryUnits = ["kush_infantry_archer_e", "kush_infantry_spearman_e"];
let kushSupportUnits = [
"units/kush_support_healer_e",
"units/kush_support_female_citizen"
];
this.SpawnAndGarrisonBuilding(gaiaEnts, "Tower", kushInfantryUnits);
let kushInfantryUnits = [
"units/kush_infantry_archer_e",
"units/kush_infantry_spearman_e"
];
this.SpawnAndGarrison(0, "Tower", kushInfantryUnits, 1);
for (let identityClass of ["Wonder", "Temple", "Pyramid"])
this.SpawnAndGarrisonBuilding(gaiaEnts, identityClass, kushInfantryUnits.concat(kushSupportUnits));
};
// Shameless copy of Danubius
Trigger.prototype.SpawnAndGarrisonBuilding = function(gaiaEnts, targetClass, templates)
{
for (let gaiaEnt of gaiaEnts)
{
let cmpIdentity = Engine.QueryInterface(gaiaEnt, IID_Identity);
if (!cmpIdentity || !cmpIdentity.HasClass(targetClass))
continue;
let cmpGarrisonHolder = Engine.QueryInterface(gaiaEnt, IID_GarrisonHolder);
if (!cmpGarrisonHolder)
continue;
let unitCounts = this.RandomAttackerTemplates(templates, cmpGarrisonHolder.GetCapacity());
for (let template in unitCounts)
for (let newEnt of TriggerHelper.SpawnUnits(gaiaEnt, "units/" + template, unitCounts[template], 0))
Engine.QueryInterface(gaiaEnt, IID_GarrisonHolder).Garrison(newEnt);
}
};
/**
* Return a random amount of these templates whose sum is count.
*/
Trigger.prototype.RandomAttackerTemplates = function(templates, count)
{
let ratios = new Array(templates.length).fill(1).map(i => randFloat(0, 1));
let ratioSum = ratios.reduce((current, sum) => current + sum, 0);
let remainder = count;
let templateCounts = {};
for (let i in templates)
{
let currentCount = +i == templates.length - 1 ? remainder : Math.round(ratios[i] / ratioSum * count);
if (!currentCount)
continue;
templateCounts[templates[i]] = currentCount;
remainder -= currentCount;
}
if (remainder != 0)
warn("Not as many templates as expected: " + count + " vs " + uneval(templateCounts));
return templateCounts;
this.SpawnAndGarrison(0, identityClass, kushInfantryUnits.concat(kushSupportUnits), 1);
};
{

View file

@ -261,4 +261,62 @@ TriggerHelper.HasDealtWithTech = function(playerID, techName)
cmpTechnologyManager.IsTechnologyResearched(techName));
};
/**
* Composes a random set of the given templates of the given total size.
* Returns an object where the keys are template names and values are amounts.
*/
Trigger.prototype.RandomTemplateComposition = function(templates, count)
{
let ratios = new Array(templates.length).fill(1).map(i => randFloat(0, 1));
let ratioSum = ratios.reduce((current, sum) => current + sum, 0);
let remainder = count;
let templateCounts = {};
for (let i = 0; i < templates.length; ++i)
{
let currentCount = i == templates.length - 1 ? remainder : Math.round(ratios[i] / ratioSum * count);
if (!currentCount)
continue;
templateCounts[templates[i]] = currentCount;
remainder -= currentCount;
}
if (remainder != 0)
error("Could not chose as many templates as intended: " + count + " vs " + uneval(templateCounts));
return templateCounts;
};
/**
* This will spawn random compositions of entities of the given templates at all garrisonholders of the given targetClass of the given player.
* The garrisonholder will be filled to capacityPercent.
* Returns an object where keys are entityIDs of the affected garrisonholders and the properties are template compositions, see RandomTemplateComposition.
*/
Trigger.prototype.SpawnAndGarrison = function(playerID, targetClass, templates, capacityPercent)
{
let results = {};
for (let entGarrisonHolder of Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager).GetEntitiesByPlayer(playerID))
{
let cmpIdentity = Engine.QueryInterface(entGarrisonHolder, IID_Identity);
if (!cmpIdentity || !cmpIdentity.HasClass(targetClass))
continue;
let cmpGarrisonHolder = Engine.QueryInterface(entGarrisonHolder, IID_GarrisonHolder);
if (!cmpGarrisonHolder)
continue;
// TODO: account for already garrisoned entities
results[entGarrisonHolder] = this.RandomTemplateComposition(templates, Math.floor(cmpGarrisonHolder.GetCapacity() * capacityPercent));
for (let template in results[entGarrisonHolder])
for (let entSpawned of TriggerHelper.SpawnUnits(entGarrisonHolder, template, results[entGarrisonHolder][template], playerID))
Engine.QueryInterface(entGarrisonHolder, IID_GarrisonHolder).Garrison(entSpawned);
}
return results;
};
Engine.RegisterGlobal("TriggerHelper", TriggerHelper);