Index: binaries/data/mods/public/maps/scenarios/Roll The Dice Abilities.js
===================================================================
--- /dev/null
+++ binaries/data/mods/public/maps/scenarios/Roll The Dice Abilities.js
@@ -0,0 +1,40 @@
+// Welcome to the wonderful world of Javascript.
+// we are going to add a custom ability for this script.
+// The conditions will be RTD-specific.
+// The effect wil be calling a trigger function.
+
+function TriggerAction()
+{
+ this.name = "TriggerAction";
+
+ this.schema =
+ "" +
+ "" +
+ "";
+}
+
+TriggerAction.prototype.SetupData = function(entity, templateData)
+{
+ return templateData;
+}
+
+TriggerAction.prototype.OnFire = function(entity, templateData, commandData)
+{
+ let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
+ if (!cmpTrigger[templateData.TriggerAction.Trigger])
+ return;
+ cmpTrigger[templateData.TriggerAction.Trigger](TriggerHelper.GetOwner(entity));
+}
+
+TriggerAction.prototype.IsFinished = function(entity, templateData, commandData)
+{
+ return true;
+}
+
+TriggerAction.prototype.Validate = function(entity, templateData, sendMessages)
+{
+ return true;
+}
+
+var TriggerAction = new TriggerAction();
+AbilityEffects.RegisterEffect(TriggerAction);
Index: binaries/data/mods/public/maps/scenarios/Roll The Dice.js
===================================================================
--- /dev/null
+++ binaries/data/mods/public/maps/scenarios/Roll The Dice.js
@@ -0,0 +1,463 @@
+// Roll The Dice trigger script.
+// This is basically a port from Age of Empires'2 Roll The Dice map.
+
+// 0 A.D.'s trigger system is extremely powerful, compared to basically anything else. So this won't even require a mod, despite tight integration.
+
+////////////////////
+//// Generic State
+// some constants about the map
+const MAP_SIZE = 64*4 + 2;
+const INNERLAKE = 7*4;
+
+// multiply resources given by this amount, for rounding convenience.
+const RESS_MULTIPLIER = 10;
+// map RTD resources to actual resources in an agnostic manner.
+// All we need is a sufficient number of resources, but it doesn't really matter which.
+var RESOURCES = {};
+{
+ let ress = ["kills"];
+ [0].forEach(i => RESOURCES[ress[i]] = Resources.GetCodes()[i]);
+}
+// helper function
+var RTD_AddResource = function(player, ress, amount)
+{
+ let cmpPlayer = QueryPlayerIDInterface(player);
+ cmpPlayer.AddResource(RESOURCES[ress], amount);
+}
+
+// helper for messages
+var BroadCastMessage = function(message, players)
+{
+ if (!players)
+ {
+ let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
+ players = cmpPlayerManager.playerEntities.map(x => Engine.QueryInterface(x, IID_Player).GetPlayerID());
+ }
+ let cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
+ cmpGuiInterface.PushNotification({ "type": "text", "players": players, "message": message });
+}
+
+// store a tuple for each entity starting position to avoid recomputing each time.
+var g_EntityStartPositions = [];
+
+// player ID: monument entity ID
+var g_MonumentByPlayer = {};
+var g_MonumentsID = [];
+
+////////////////////
+//// Hack simulation
+// disable capturing because that's annoying.
+Capturable.prototype.CanCapture = function() { return false };
+// disable producing
+ProductionQueue.prototype.GetEntitiesList = function() { return []; }
+ProductionQueue.prototype.GetTechnologiesList = function() { return []; }
+Builder.prototype.GetEntitiesList = function() { return []; }
+// disable auras
+Auras.prototype.CanApply = function() { return false; }
+// disable loot
+Loot.prototype.GetResources = function() { return {}; }
+// can't disable repairing entirely but this'll do.
+Repairable.prototype.GetRepairRate = function() { return 0; }
+// warn player
+Repairable.prototype.Repair = function(builderEnt, rate)
+{
+ BroadCastMessage("Repairing is disabled in Roll The Dice", [TriggerHelper.GetOwner(builderEnt)]);
+}
+
+// Instead of idle units return currently active unit.
+GuiInterface.prototype.FindIdleUnits = function(player)
+{
+ let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
+ let entities = cmpRangeManager.GetEntitiesByPlayer(player);
+ for (let ent of entities)
+ {
+ if (ent == g_MonumentByPlayer[player])
+ continue;
+ return [ent];
+ }
+ return []
+}
+GuiInterface.prototype.HasIdleUnits = function(player)
+{
+ return this.FindIdleUnits(player).length;
+}
+////////////////////
+//// Gameplay state
+// Player ID : damage count.
+var RTD_DamageCount = {};
+// player ID : how much extra damage they bought.
+var RTD_AttackBought = {};
+// player ID : how much extra HP they bought.
+var RTD_HPBought = {};
+
+var RTD_HasPanic = {};
+// RULES OF ROLL THE DICE
+// As adapted from Age of Empire's 2 custom scenario.
+
+// 1. At any time, you have a Monument and one (or potentially more) unit on the map.
+// 2. If your Monument is destroyed, you lose.
+// 3. A side-goal is to kill enemy units, thus accruing kills. Actually count damage dealt as a % of enemy HP, to be fair and avoid "stealing" kills.
+// As you kill units, you will be able to upgrade your Monument or your units to make the game easier.
+
+
+// Mechanics to add:
+// A death streak without kill should give bonuses
+// A kill streak should also give bonuses (but warn players so than can gang up on you).
+// Random "drops" of stuff.
+// Terrain changing
+// I have this idea for water rising and sharks attacking units randomly.
+
+Trigger.prototype.InitRTD = function()
+{
+ // Fetch player information.
+ let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager)
+
+ let players = [];
+
+ for (let x = 1; x < cmpPlayerManager.GetNumPlayers(); ++x)
+ {
+ let id = cmpPlayerManager.GetPlayerByID(x);
+ let cmpPlayer = Engine.QueryInterface(id, IID_Player);
+
+ g_EntityStartPositions.push([MAP_SIZE/2 + 3*INNERLAKE * Math.cos(x/cmpPlayerManager.GetNumPlayers()*6.283), MAP_SIZE/2 + 3*INNERLAKE * Math.sin(x/cmpPlayerManager.GetNumPlayers()*6.283)]);
+
+ // imperfect detection of undefined players.
+ if (cmpPlayer.IsAI())
+ continue;
+
+ players.push(x);
+ }
+
+ // create a monument for each player.
+ let count = players.length;
+ for (let id of players)
+ {
+ let monument = Engine.AddEntity("structures/athen_outpost");
+ g_MonumentByPlayer[id] = monument;
+ g_MonumentsID.push(monument);
+
+
+ let cmpOwner = Engine.QueryInterface(monument, IID_Ownership);
+ cmpOwner.SetOwner(+id);
+
+ let cmpModManager = QueryOwnerInterface(monument, IID_ModifiersManager);
+ cmpModManager.AddGlobalModifiers("triggers_RTD_Struct", 100, {
+ "Capturable/RegenRate": {"affects": ["Structure"], "replace": 100},
+ "GarrisonHolder/Max": {"affects": ["Structure"], "replace": 0},
+ "Vision/Range": {"affects": ["Structure"], "replace": 50},
+ "Health/Max": {"affects": ["Structure"], "replace": 2000},
+ });
+ cmpModManager.AddGlobalModifiers("triggers_RTD_Unit", 100, {
+ "Looter/Resource/food": {"affects": ["Unit"], "replace": 0},
+ "Looter/Resource/wood": {"affects": ["Unit"], "replace": 0},
+ "Looter/Resource/stone": {"affects": ["Unit"], "replace": 0},
+ "Looter/Resource/metal": {"affects": ["Unit"], "replace": 0},
+ "Vision/Range": {"affects": ["Unit"], "replace": 20},
+ "Promotion/RequiredXp": {"affects": ["Unit"], "replace": 9999999}
+ });
+
+ // Share all vision.
+ let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
+ cmpRangeManager.SetSharedLos(+id, players)
+
+ let cmpPosition = Engine.QueryInterface(monument, IID_Position);
+ cmpPosition.JumpTo(MAP_SIZE/2 + INNERLAKE * Math.cos(players.indexOf(id)/count*6.283), MAP_SIZE/2 + INNERLAKE * Math.sin(players.indexOf(id)/count*6.283))
+ cmpPosition.SetYRotation(1.5707 + players.indexOf(id)/count*6.283)
+
+ // Init rules
+ RTD_DamageCount[id] = 0;
+
+ RTD_AttackBought[id] = 0;
+ RTD_HPBought[id] = 0;
+ RTD_HasPanic[id] = true;
+
+ let cmpPlayer = QueryOwnerInterface(monument, IID_Player);
+ let resources = {};
+ // set to 0.01 otherwise we have rounding issues in the GUI.
+ Resources.GetCodes().forEach(ress => resources[ress] = 0.01);
+ cmpPlayer.SetResourceCounts(resources);
+
+ // Create the starting entities for each player.
+ this.CreateNewEntity(id, true);
+ }
+}
+
+Trigger.prototype.PickRandomEntity = function()
+{
+ // list of possible units.
+ // TODO: curate this a bit.
+ let list = [
+ "units/athen_cavalry_swordsman_a",
+ "units/athen_infantry_spearman_a",
+ "units/brit_cavalry_swordsman_a",
+ "units/brit_infantry_spearman_a",
+ "units/cart_cavalry_spearman_ital_a",
+ "units/cart_cavalry_swordsman_gaul_a",
+ "units/cart_cavalry_swordsman_iber_a",
+ "units/cart_champion_elephant",
+ "units/cart_hero_hannibal",
+ "units/cart_infantry_spearman_a",
+ "units/cart_infantry_swordsman_gaul_a",
+ "units/cart_infantry_swordsman_ital_a",
+ "units/gaul_cavalry_swordsman_a",
+ "units/gaul_infantry_spearman_a",
+ "units/iber_cavalry_spearman_a",
+ "units/iber_infantry_spearman_a",
+ "units/iber_infantry_swordsman_a",
+ "units/mace_cavalry_spearman_a",
+ "units/mace_hero_alexander",
+ "units/mace_infantry_pikeman_a",
+ "units/maur_cavalry_swordsman_a",
+ "units/maur_champion_elephant",
+ "units/maur_champion_infantry",
+ "units/maur_hero_maurya",
+ "units/maur_infantry_spearman_a",
+ "units/maur_infantry_swordsman_a",
+ "units/merc_thorakites",
+ "units/pers_cavalry_spearman_a",
+ "units/pers_cavalry_swordsman_a",
+ "units/pers_champion_elephant",
+ "units/pers_infantry_spearman_a",
+ "units/pers_mechanical_siege_ram",
+ "units/ptol_cavalry_spearman_merc_a",
+ "units/ptol_champion_elephant",
+ "units/ptol_hero_ptolemy_I",
+ "units/ptol_infantry_pikeman_a",
+ "units/ptol_infantry_spearman_merc_a",
+ "units/ptol_infantry_swordsman_merc_a",
+ "units/rome_cavalry_spearman_a",
+ "units/rome_centurio_imperial",
+ "units/rome_infantry_spearman_a",
+ "units/rome_infantry_swordsman_a",
+ "units/rome_legionnaire_imperial",
+ "units/rome_mechanical_siege_ram",
+ "units/sele_cavalry_spearman_merc_a",
+ "units/sele_champion_elephant",
+ "units/sele_hero_seleucus_victor",
+ "units/sele_infantry_pikeman_a",
+ "units/sele_infantry_spearman_a",
+ "units/sele_infantry_swordsman_merc_a",
+ "units/spart_cavalry_spearman_a",
+ "units/spart_champion_infantry_sword",
+ "units/spart_infantry_spearman_a",
+ "units/spart_support_female_citizen",
+ "units/athen_cavalry_javelinist_a",
+ "units/athen_champion_ranged",
+ "units/athen_infantry_javelinist_a",
+ "units/athen_infantry_marine_archer_a",
+ "units/athen_infantry_slinger_a",
+ "units/brit_cavalry_javelinist_a",
+ "units/brit_infantry_javelinist_a",
+ "units/brit_infantry_slinger_a",
+ "units/cart_cavalry_javelinist_a",
+ "units/cart_infantry_archer_a",
+ "units/cart_infantry_javelinist_iber_a",
+ "units/cart_infantry_slinger_iber_a",
+ "units/gaul_cavalry_javelinist_a",
+ "units/gaul_infantry_javelinist_a",
+ "units/gaul_infantry_slinger_a",
+ "units/iber_cavalry_javelinist_a",
+ "units/iber_champion_cavalry",
+ "units/iber_hero_indibil",
+ "units/iber_infantry_javelinist_a",
+ "units/iber_infantry_slinger_a",
+ "units/mace_cavalry_javelinist_a",
+ "units/mace_infantry_archer_a",
+ "units/mace_infantry_javelinist_a",
+ "units/mace_infantry_slinger_a",
+ "units/maur_cavalry_javelinist_a",
+ "units/maur_elephant_archer_a",
+ "units/maur_infantry_archer_a",
+ "units/pers_cavalry_archer_a",
+ "units/pers_cavalry_javelinist_a",
+ "units/pers_infantry_archer_a",
+ "units/pers_infantry_javelinist_a",
+ "units/ptol_cavalry_archer_a",
+ "units/ptol_cavalry_javelinist_merc_a",
+ "units/ptol_infantry_archer_a",
+ "units/ptol_infantry_archer_nubian",
+ "units/ptol_infantry_javelinist_a",
+ "units/ptol_infantry_slinger_a",
+ "units/rome_cavalry_javelinist_a",
+ "units/rome_infantry_javelinist_a",
+ "units/rome_mechanical_siege_onager_unpacked",
+ "units/sele_cavalry_archer_a",
+ "units/sele_cavalry_javelinist_a",
+ "units/sele_infantry_archer_merc_a",
+ "units/sele_infantry_javelinist_a",
+ "units/spart_cavalry_javelinist_a",
+ "units/spart_infantry_javelinist_a",
+ "units/theb_mechanical_siege_fireraiser",
+ ];
+
+ let item = pickRandom(list);
+
+ return item;
+}
+
+Trigger.prototype.CreateNewEntity = function(player, startPos)
+{
+ // TODO: validate current entity is killed?
+
+ let entity = Engine.AddEntity(this.PickRandomEntity());
+
+ let cmpOwner = Engine.QueryInterface(entity, IID_Ownership);
+ cmpOwner.SetOwner(+player);
+
+ let cmpPosition = Engine.QueryInterface(entity, IID_Position);
+ let pos = startPos ? g_EntityStartPositions[player-1] : pickRandom(g_EntityStartPositions);
+ cmpPosition.JumpTo(pos[0], pos[1]);
+
+ let cmpHealth = Engine.QueryInterface(entity, IID_Health);
+ cmpHealth.SetUndeletable(true);
+
+ let cmpAbilities = Engine.QueryInterface(entity, IID_Abilities);
+
+ {
+ let ability = {
+ "Name": "Re-roll your unit",
+ "Tooltip": "This allows you to kill your current unit and re-roll it.",
+ "Cost": {},
+ "Icon": "icons/kill.png",
+ "TriggerAction": {"Trigger": "RTD_ReRoll"}
+ };
+ ability.Cost[RESOURCES["kills"]] = 2*RESS_MULTIPLIER;
+ cmpAbilities.AddAbility("Reroll", ability);
+ }
+ // for now just do it like this it'll work OK.
+ if (RTD_HasPanic[player])
+ {
+ let ability = {
+ "Name": "Panic",
+ "Tooltip": "This kills every unit on the map. Can only be used once.",
+ "Icon": "portraits/technologies/skull_swords.png",
+ "TriggerAction": {"Trigger": "RTD_Panic"}
+ };
+ cmpAbilities.AddAbility("Panic", ability);
+ }
+ {
+ let ability = {
+ "Name": "Increase Attack",
+ "Tooltip": "This will permanently increase your unit attacks by +2 Hack and +2 Pierce, stacking.",
+ "Cost": {},
+ "Icon": "portraits/technologies/sword.png",
+ "TriggerAction": {"Trigger": "RTD_PurchaseAttack"}
+ };
+ ability.Cost[RESOURCES["kills"]] = 5*RESS_MULTIPLIER;
+ cmpAbilities.AddAbility("PurchaseAttack", ability);
+ }
+ {
+ let ability = {
+ "Name": "Boost Outpost HP",
+ "Tooltip": "This will give +500 HP to your outpost (including max HP)",
+ "Cost": {},
+ "Icon": "portraits/structures/outpost.png",
+ "TriggerAction": {"Trigger": "RTD_PurchaseHP"}
+ };
+ ability.Cost[RESOURCES["kills"]] = 10*RESS_MULTIPLIER;
+ cmpAbilities.AddAbility("PurchaseHP", ability);
+ }
+}
+
+Trigger.prototype.ChangeKillCount = function(player, amount)
+{
+ RTD_DamageCount[player] += +amount;
+ RTD_AddResource(player, "kills", amount*RESS_MULTIPLIER);
+}
+
+// Abilities triggers
+
+Trigger.prototype.RTD_ReRoll = function(player)
+{
+ let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
+ let entities = cmpRangeManager.GetEntitiesByPlayer(player);
+ for (let ent of entities)
+ {
+ if (ent == g_MonumentByPlayer[player])
+ continue;
+ let cmpHealth = Engine.QueryInterface(ent, IID_Health);
+ cmpHealth.Kill();
+ }
+ // no need to create a new entity since on OwnershipChanged deals with it.
+}
+
+Trigger.prototype.RTD_Panic = function(player)
+{
+ RTD_HasPanic[player] = false;
+
+ BroadCastMessage("Player " + player + " has used the PANIC button!");
+ // TODO: sound
+
+ let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
+ let entities = cmpRangeManager.GetNonGaiaEntities();
+ for (let ent of entities)
+ {
+ let player = TriggerHelper.GetOwner(ent);
+ if (ent == g_MonumentByPlayer[player])
+ continue;
+ let cmpHealth = Engine.QueryInterface(ent, IID_Health);
+ cmpHealth.Kill();
+ }
+}
+
+Trigger.prototype.RTD_PurchaseAttack = function(player)
+{
+ RTD_AttackBought[player] += 2;
+
+ let cmpModManager = QueryPlayerIDInterface(player, IID_ModifiersManager);
+ cmpModManager.RemoveGlobalModifiers("RTD_PurchaseAttack");
+ cmpModManager.AddGlobalModifiers("RTD_PurchaseAttack", 1000, {
+ "Attack/Ranged/Hack": {"affects": ["Unit"], "add": RTD_AttackBought[player]},
+ "Attack/Ranged/Pierce": {"affects": ["Unit"], "add": RTD_AttackBought[player]},
+ "Attack/Melee/Hack": {"affects": ["Unit"], "add": RTD_AttackBought[player]},
+ "Attack/Melee/Hack": {"affects": ["Unit"], "add": RTD_AttackBought[player]}
+ });
+}
+
+Trigger.prototype.RTD_PurchaseHP = function(player)
+{
+ RTD_HPBought[player] += 500;
+ let cmpModManager = QueryPlayerIDInterface(player, IID_ModifiersManager);
+ cmpModManager.RemoveGlobalModifiers("RTD_PurchaseHP");
+ cmpModManager.AddGlobalModifiers("RTD_PurchaseHP", 1000, {
+ "Health/Max": {"affects": ["Structure"], "add": RTD_HPBought[player]},
+ });
+}
+/// EVENTS
+
+Trigger.prototype.OnOwnershipChanged = function(msg)
+{
+ if (msg.to != -1)
+ return;
+ if (msg.from > 0 && g_MonumentByPlayer[msg.from] == msg.entity)
+ {
+ TriggerHelper.DefeatPlayer(msg.from);
+ }
+ else if (msg.from != 0)
+ {
+ let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
+ cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_Trigger, "CreateNewEntity", 1000, msg.from);
+ }
+}
+
+Trigger.prototype.OnAttacked = function(msg)
+{
+ if (g_MonumentsID.some(id => msg.target == id))
+ return;
+
+ let cmpHealth = Engine.QueryInterface(msg.target, IID_Health);
+ // on principle this shouldn't happen
+ if (!cmpHealth)
+ return;
+ let damage = msg.damage / cmpHealth.GetMaxHitpoints();
+ // damage caps at 1.
+ this.ChangeKillCount(msg.attackerOwner, damage);
+}
+
+{
+ let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
+
+ cmpTrigger.RegisterTrigger("OnInitGame", "InitRTD", { "enabled": true });
+ cmpTrigger.RegisterTrigger("OnOwnershipChanged", "OnOwnershipChanged", { "enabled": true });
+ cmpTrigger.RegisterTrigger("OnAttacked", "OnAttacked", { "enabled": true });
+}
\ No newline at end of file
Index: binaries/data/mods/public/maps/scenarios/Roll The Dice.xml
===================================================================
--- /dev/null
+++ binaries/data/mods/public/maps/scenarios/Roll The Dice.xml
@@ -0,0 +1,1384 @@
+
+
+
+
+ sunny 1
+
+
+
+
+
+
+ 0
+ 0.5
+
+
+
+
+ lake
+
+
+ 79
+ 1.23047
+ 0.493164
+ 0
+
+
+
+ 0
+ 1
+ 0.99
+ 0.1999
+ default
+
+
+
+
+
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|flora/trees/palm_cretan_date.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/shrub_fanpalm.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/decal_palms_patch.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/grass_temp_field_dry.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_pond_lush_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_pond_lush_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_pond_lush_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_pond_lush_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_pond_lush_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_pond_lush_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_pond_lush_a.xml
+
+
+
+
+
+ actor|props/flora/reeds_pond_lush_b.xml
+
+
+
+
+
+ actor|props/flora/reeds_pond_lush_b.xml
+
+
+
+
+
+ actor|props/flora/reeds_pond_lush_b.xml
+
+
+
+
+
+ actor|props/flora/reeds_pond_lush_b.xml
+
+
+
+
+
+ actor|props/flora/shrub_tropic_plant_flower.xml
+
+
+
+
+
+ actor|props/flora/shrub_tropic_plant_flower.xml
+
+
+
+
+
+ actor|props/flora/shrub_tropic_plant_flower.xml
+
+
+
+
+
+ actor|props/flora/shrub_tropic_plant_flower.xml
+
+
+
+
+
+ actor|props/flora/shrub_tropic_plant_flower.xml
+
+
+
+
+
+ actor|props/flora/water_lillies.xml
+
+
+
+
+
+ actor|props/flora/water_lillies.xml
+
+
+
+
+
+ actor|props/flora/water_lillies.xml
+
+
+
+
+
+ actor|props/flora/water_lillies.xml
+
+
+
+
+
+ actor|props/flora/flower_bright.xml
+
+
+
+
+
+ actor|props/flora/flower_bright.xml
+
+
+
+
+
+ actor|props/flora/flower_bright.xml
+
+
+
+
+
+ actor|props/flora/flower_bright.xml
+
+
+
+
+
+ actor|props/flora/flower_bright.xml
+
+
+
+
+
+ actor|props/flora/flower_bright.xml
+
+
+
+
+
+ actor|props/flora/flower_bright.xml
+
+
+
+
+
+ actor|props/flora/flower_bright.xml
+
+
+
+
+
+ actor|props/flora/flower_bright.xml
+
+
+
+
+
+ actor|props/flora/ferns.xml
+
+
+
+
+
+ actor|props/flora/ferns.xml
+
+
+
+
+
+ actor|props/flora/ferns.xml
+
+
+
+
+
+ actor|props/flora/ferns.xml
+
+
+
+
+
+ actor|props/flora/ferns.xml
+
+
+
+
+
+ actor|props/flora/water_lillies.xml
+
+
+
+
+
+ actor|props/flora/water_lillies.xml
+
+
+
+
+
+ actor|props/flora/water_lillies.xml
+
+
+
+
+
+ actor|props/flora/water_lillies.xml
+
+
+
+
+
+ actor|props/flora/water_lillies.xml
+
+
+
+
+
+ actor|props/flora/water_lillies.xml
+
+
+
+
+
+ actor|props/flora/water_lillies.xml
+
+
+
+
+
+ actor|geology/shoreline_small.xml
+
+
+
+
+
+ actor|geology/shoreline_small.xml
+
+
+
+
+
+ actor|geology/shoreline_small.xml
+
+
+
+
+
+ actor|geology/shoreline_small.xml
+
+
+
+
+
+ actor|geology/shoreline_small.xml
+
+
+
+
+
+ actor|geology/shoreline_small.xml
+
+
+
+
+
+ actor|geology/shoreline_small.xml
+
+
+
+
+
+ actor|geology/shoreline_large.xml
+
+
+
+
+
+ actor|geology/shoreline_large.xml
+
+
+
+
+
+ actor|geology/shoreline_large.xml
+
+
+
+
+
+ actor|geology/shoreline_large.xml
+
+
+
+
+
+ actor|geology/shoreline_large.xml
+
+
+
+
+
+ actor|geology/shoreline_large.xml
+
+
+
+
+
+ actor|geology/shoreline_large.xml
+
+
+
+
+
+ gaia/fauna_shark
+ 0
+
+
+
+
+
+ gaia/fauna_shark
+ 0
+
+
+
+
+
+ gaia/fauna_shark
+ 0
+
+
+
+
+
+ gaia/fauna_shark
+ 0
+
+
+
+
+
+ gaia/fauna_shark
+ 0
+
+
+
+
+
+
+
\ No newline at end of file
Index: binaries/data/mods/public/simulation/components/Trigger.js
===================================================================
--- binaries/data/mods/public/simulation/components/Trigger.js
+++ binaries/data/mods/public/simulation/components/Trigger.js
@@ -24,7 +24,8 @@
"StructureBuilt",
"TrainingFinished",
"TrainingQueued",
- "TreasureCollected"
+ "TreasureCollected",
+ "Attacked"
];
Trigger.prototype.Init = function()
@@ -277,6 +278,11 @@
this.CallEvent("DiplomacyChanged", msg);
};
+Trigger.prototype.OnGlobalAttacked = function(msg)
+{
+ this.CallEvent("Attacked", msg);
+};
+
/**
* Execute a function after a certain delay.
*
Index: binaries/data/mods/public/simulation/templates/template_unit.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_unit.xml
+++ binaries/data/mods/public/simulation/templates/template_unit.xml
@@ -1,5 +1,6 @@
+
1
1