diff --git a/binaries/data/mods/public/gui/gamesetup/gamesetup.js b/binaries/data/mods/public/gui/gamesetup/gamesetup.js index ea317caf60..3cf663b9d9 100644 --- a/binaries/data/mods/public/gui/gamesetup/gamesetup.js +++ b/binaries/data/mods/public/gui/gamesetup/gamesetup.js @@ -932,7 +932,7 @@ function launchGame() if (!g_GameAttributes.settings.TriggerScripts) g_GameAttributes.settings.TriggerScripts = g_GameAttributes.settings.VictoryScripts; else - g_GameAttributes.settings.TriggerScripts = g_GameAttributes.settings.VictoryScripts.concat(g_GameAttrbutes.settings.TriggerScripts); + g_GameAttributes.settings.TriggerScripts = g_GameAttributes.settings.VictoryScripts.concat(g_GameAttributes.settings.TriggerScripts); g_GameStarted = true; g_GameAttributes.settings.mapType = g_GameAttributes.mapType; var numPlayers = g_GameAttributes.settings.PlayerData.length; diff --git a/binaries/data/mods/public/maps/scripts/Conquest.js b/binaries/data/mods/public/maps/scripts/Conquest.js index 25df2dc421..269cb5456c 100644 --- a/binaries/data/mods/public/maps/scripts/Conquest.js +++ b/binaries/data/mods/public/maps/scripts/Conquest.js @@ -6,7 +6,7 @@ Trigger.prototype.CheckConquestCriticalEntities = function() if (this.checkingConquestCriticalEntities) return; // wait a turn for actually checking the players - this.DoAfterDelay(100, "CheckConquestCriticalEntitiesNow", null); + this.DoAfterDelay(1, "CheckConquestCriticalEntitiesNow", null); this.checkingConquestCriticalEntities = true; }; @@ -65,6 +65,6 @@ var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); var data = {"enabled": true}; cmpTrigger.RegisterTrigger("OnOwnershipChanged", "CheckConquestCriticalEntities", data); // also check at the start of the game -cmpTrigger.DoAfterDelay(100, "CheckConquestCriticalEntities", null); +cmpTrigger.DoAfterDelay(1, "CheckConquestCriticalEntitiesNow", null); cmpTrigger.checkingConquestCriticalEntities = false; diff --git a/binaries/data/mods/public/maps/scripts/TriggerHelper.js b/binaries/data/mods/public/maps/scripts/TriggerHelper.js new file mode 100644 index 0000000000..21b4d8a92d --- /dev/null +++ b/binaries/data/mods/public/maps/scripts/TriggerHelper.js @@ -0,0 +1,132 @@ +// Contains standardized functions suitable for using in trigger scripts. +// Do not use them in any other simulation script. + +var TriggerHelper = {}; + +TriggerHelper.GetPlayerIDFromEntity = function(ent) +{ + var cmpPlayer = Engine.QueryInterface(ent, IID_Player); + if (cmpPlayer) + return cmpPlayer.GetPlayerID(); + return -1; +}; + +TriggerHelper.GetOwner = function(ent) +{ + var cmpOwnership = Engine.QueryInterface(ent, IID_Ownership); + if (cmpOwnership) + return cmpOwnership.GetOwner(); + return -1; +}; + +/** + * Can be used to "force" a building to spawn a group of entities. + * Only works for buildings that can already train units. + * @param source Entity id of the point where they will be spawned from + * @param template Name of the template + * @param count Number of units to spawn + * @param owner Player id of the owner of the new units. By default, the owner + * of the source entity. + */ +TriggerHelper.SpawnUnits = function(source, template, count, owner) +{ + var r = []; // array of entities to return; + var cmpFootprint = Engine.QueryInterface(source, IID_Footprint); + var cmpPosition = Engine.QueryInterface(source, IID_Position); + if (!cmpPosition || !cmpPosition.IsInWorld()) + { + error("tried to create entity from a source without position"); + return r; + } + if (owner == null) + owner = TriggerHelper.GetOwner(source); + + for (var i = 0; i < count; i++) + { + var ent = Engine.AddEntity(template); + var cmpEntPosition = Engine.QueryInterface(ent, IID_Position); + if (!cmpEntPosition) + { + error("tried to create entity without position"); + continue; + } + var cmpEntOwnership = Engine.QueryInterface(ent, IID_Ownership); + if (cmpEntOwnership) + cmpEntOwnership.SetOwner(owner); + r.push(ent); + var pos; + if (cmpFootprint) + pos = cmpFootprint.PickSpawnPoint(ent); + // TODO this can happen if the player build on the place + // where our trigger point is + // We should probably warn the trigger maker in some way, + // but not interrupt the game for the player + if (!pos || pos.y < 0) + pos = cmpPosition.GetPosition(); + cmpEntPosition.JumpTo(pos.x, pos.z); + } + return r; +}; + +/** + * Spawn units from all trigger points with this reference + * If player is defined, only spaw units from the trigger points + * that belong to that player + * @param ref Trigger point reference name to spawn units from + * @param template Template name + * @param count Number of spawned entities per Trigger point + * @param owner Owner of the spawned units. Default: the owner of the origins + * @return A list of new entities per origin like + * {originId1: [entId1, entId2], originId2: [entId3, entId4], ...} + */ +TriggerHelper.SpawnUnitsFromTriggerPoints = function(ref, template, count, owner = null) +{ + var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); + var triggerPoints = cmpTrigger.GetTriggerPoints(ref); + var r = {}; + for (var point of triggerPoints) + r[point] = TriggerHelper.SpawnUnits(point, template, count, owner); + return r; +} + +/** + * Returs a function that can be used to filter an array of entities by player + */ +TriggerHelper.GetPlayerFilter = function(playerID) +{ + return function(entity) { + var cmpOwnership = Engine.QueryInterface(entity, IID_Ownership); + return cmpOwnership && cmpOwnership.GetOwner() == playerID; + } +}; + +/** + * Returns the resource type that can be gathered from an entity + */ +TriggerHelper.GetResourceType = function(entity) +{ + var cmpResourceSupply = Engine.QueryInterface(entity, IID_ResourceSupply); + if (!cmpResourceSupply) + return undefined; + return cmpResourceSupply.GetType(); +}; + +/** + * Wins the game for a player + */ +TriggerHelper.SetPlayerWon = function(playerID) +{ + var cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager); + cmpEndGameManager.MarkPlayerAsWon(playerID); +}; + +/** + * Defeats a player + */ +TriggerHelper.DefeatPlayer = function(playerID) +{ + var playerEnt = GetPlayerEntityByID(playerID); + Engine.PostMessage(playerEnt, MT_PlayerDefeated, { "playerId": playerID } ); +}; + +Engine.RegisterGlobal("TriggerHelper", TriggerHelper); diff --git a/binaries/data/mods/public/maps/scripts/WonderVictory.js b/binaries/data/mods/public/maps/scripts/WonderVictory.js index 72a119c4d1..7ea66058ae 100644 --- a/binaries/data/mods/public/maps/scripts/WonderVictory.js +++ b/binaries/data/mods/public/maps/scripts/WonderVictory.js @@ -1,6 +1,5 @@ Trigger.prototype.CheckWonderVictory = function(data) { - warn(uneval(data)); var ent = data.entity; var cmpWonder = Engine.QueryInterface(ent, IID_Wonder); if (!cmpWonder) diff --git a/binaries/data/mods/public/maps/skirmishes/Gallic Fields (3).js b/binaries/data/mods/public/maps/skirmishes/Gallic Fields (3).js new file mode 100644 index 0000000000..ea9a687199 --- /dev/null +++ b/binaries/data/mods/public/maps/skirmishes/Gallic Fields (3).js @@ -0,0 +1,44 @@ +Trigger.prototype.SpawnAndAttack = function() +{ + var rand = Math.random(); + // randomize spawn points + var spawnPoint = rand > 0.5 ? "B" : "C"; + var intruders = TriggerHelper.SpawnUnitsFromTriggerPoints(spawnPoint, "units/rome_legionnaire_marian", this.attackSize, 0); + + for (var origin in intruders) + { + var playerID = TriggerHelper.GetOwner(+origin); + var cmd = null; + for (var target of this.GetTriggerPoints("A")) + { + if (TriggerHelper.GetOwner(target) != playerID) + continue; + var cmpPosition = Engine.QueryInterface(target, IID_Position); + if (!cmpPosition || !cmpPosition.IsInWorld) + continue; + // store the x and z coordinates in the command + cmd = cmpPosition.GetPosition(); + break; + } + if (!cmd) + continue; + cmd.type = "attack-walk"; + cmd.entities = intruders[origin]; + cmd.queued = true; + ProcessCommand(0, cmd); + } + + // enlarge the attack time and size + // multiply with a number between 1 and 3 + rand = Math.random() * 2 + 1; + this.attackTime *= rand; // + this.attackSize = Math.round(this.attackSize * rand); + this.DoAfterDelay(this.attackTime, "SpawnAndAttack", {}); +}; + +var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); + +cmpTrigger.attackSize = 1; // attack with 1 soldier +cmpTrigger.attackTime = 60*1000; // attack in 1 minute +cmpTrigger.DoAfterDelay(cmpTrigger.attackTime, "SpawnAndAttack", {}); + diff --git a/binaries/data/mods/public/maps/skirmishes/Gallic Fields (3).xml b/binaries/data/mods/public/maps/skirmishes/Gallic Fields (3).xml index 28f3434e48..2a55f85701 100644 --- a/binaries/data/mods/public/maps/skirmishes/Gallic Fields (3).xml +++ b/binaries/data/mods/public/maps/skirmishes/Gallic Fields (3).xml @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d9fe12bf36af39c371a6e024f095ae100b3e47b3c55fd85d76a6a5f72cb6b052 -size 661191 +oid sha256:23e42c4eefe3bc100525d7396fac1e97e587ed3f800a0c68cc6f4af174af123e +size 658371 diff --git a/binaries/data/mods/public/simulation/helpers/Commands.js b/binaries/data/mods/public/simulation/helpers/Commands.js index 2f9f5c97de..636b94a4c5 100644 --- a/binaries/data/mods/public/simulation/helpers/Commands.js +++ b/binaries/data/mods/public/simulation/helpers/Commands.js @@ -33,8 +33,7 @@ function ProcessCommand(player, cmd) if (commands[cmd.type]) { var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); - if (cmpTrigger) - cmpTrigger.CallEvent("PlayerCommand", {"player": player, "cmd": cmd}); + cmpTrigger.CallEvent("PlayerCommand", {"player": player, "cmd": cmd}); commands[cmd.type](player, cmd, data); } else