3 "gaia/special_treasure_food_barrel",
4 "gaia/special_treasure_food_bin",
5 "gaia/special_treasure_food_crate",
6 "gaia/special_treasure_food_jars",
7 "gaia/special_treasure_metal",
8 "gaia/special_treasure_stone",
9 "gaia/special_treasure_wood",
10 "gaia/special_treasure_wood",
11 "gaia/special_treasure_wood"
13 var attackerEntityTemplates =
16 "units/athen_champion_infantry",
17 "units/athen_champion_marine",
18 "units/athen_champion_ranged",
19 "units/athen_mechanical_siege_lithobolos_packed",
20 "units/athen_mechanical_siege_oxybeles_packed",
23 "units/brit_champion_cavalry",
24 "units/brit_champion_infantry",
25 "units/brit_mechanical_siege_ram",
28 "units/cart_champion_cavalry",
29 "units/cart_champion_elephant",
30 "units/cart_champion_infantry",
31 "units/cart_champion_pikeman",
34 "units/gaul_champion_cavalry",
35 "units/gaul_champion_fanatic",
36 "units/gaul_champion_infantry",
37 "units/gaul_mechanical_siege_ram",
40 "units/iber_champion_cavalry",
41 "units/iber_champion_infantry",
42 "units/iber_mechanical_siege_ram",
45 "units/mace_champion_cavalry",
46 "units/mace_champion_infantry_a",
47 "units/mace_champion_infantry_e",
48 "units/mace_mechanical_siege_lithobolos_packed",
49 "units/mace_mechanical_siege_oxybeles_packed",
52 "units/maur_champion_chariot",
53 "units/maur_champion_elephant",
54 "units/maur_champion_infantry",
55 "units/maur_champion_maiden",
56 "units/maur_champion_maiden_archer",
59 "units/pers_champion_cavalry",
60 "units/pers_champion_infantry",
61 "units/pers_champion_elephant",
64 "units/ptol_champion_cavalry",
65 "units/ptol_champion_elephant",
68 "units/rome_champion_cavalry",
69 "units/rome_champion_infantry",
70 "units/rome_mechanical_siege_ballista_packed",
71 "units/rome_mechanical_siege_scorpio_packed",
74 "units/sele_champion_cavalry",
75 "units/sele_champion_chariot",
76 "units/sele_champion_elephant",
77 "units/sele_champion_infantry_pikeman",
78 "units/sele_champion_infantry_swordsman",
81 "units/spart_champion_infantry_pike",
82 "units/spart_champion_infantry_spear",
83 "units/spart_champion_infantry_sword",
84 "units/spart_mechanical_siege_ram",
88 Trigger.prototype.StartAnEnemyWave = function()
90 let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
91 let attackerTemplates = attackerEntityTemplates[Math.floor(Math.random() * attackerEntityTemplates.length)];
92 // A soldier for each 2-3 minutes of the game. Should be waves of 20 soldiers after an hour
93 let nextTime = Math.round(120000 + Math.random() * 60000);
94 let attackersPerTemplate = Math.round(cmpTimer.GetTime() / nextTime / attackerTemplates.length);
97 for (let point of this.GetTriggerPoints("A"))
99 let cmpPlayer = QueryOwnerInterface(point, IID_Player);
100 if (cmpPlayer.GetPlayerID() == 0 || cmpPlayer.GetState() != "active")
103 let cmpPosition = Engine.QueryInterface(this.playerCivicCenter[cmpPlayer.GetPlayerID()], IID_Position);
104 if (!cmpPosition || !cmpPosition.IsInWorld)
106 let targetPos = cmpPosition.GetPosition();
108 for (let template of attackerTemplates)
110 let entities = TriggerHelper.SpawnUnits(point, template, attackersPerTemplate, 0);
113 "type": "attack-walk",
114 "entities": entities,
118 "targetClasses": undefined
127 let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
128 cmpGUIInterface.PushNotification({
129 "message": markForTranslation("An enemy wave is attacking!"),
130 "translateMessage": true
132 this.DoAfterDelay(nextTime, "StartAnEnemyWave", {}); // The next wave will come in 3 minutes
135 Trigger.prototype.InitGame = function()
137 let numberOfPlayers = TriggerHelper.GetNumberOfPlayers();
138 // Find all of the civic centers, disable some structures
139 for (let i = 1; i < numberOfPlayers; ++i)
141 let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
142 let playerEntities = cmpRangeManager.GetEntitiesByPlayer(i); // Get all of each player's entities
144 for (let entity of playerEntities)
146 if (TriggerHelper.EntityHasClass(entity, "CivilCentre"))
147 this.playerCivicCenter[i] = entity;
148 else if (TriggerHelper.EntityHasClass(entity, "Female"))
150 let cmpDamageReceiver = Engine.QueryInterface(entity, IID_DamageReceiver);
151 cmpDamageReceiver.SetInvulnerability(true);
153 let cmpHealth = Engine.QueryInterface(entity, IID_Health);
154 cmpHealth.SetUndeletable(true);
159 this.PlaceTreasures();
161 // Disable farms, civic centers and walls for all players
162 for (let i = 1; i < numberOfPlayers; ++i)
164 let cmpPlayer = QueryPlayerIDInterface(i);
165 let civ = cmpPlayer.GetCiv();
166 cmpPlayer.SetDisabledTemplates([
167 "structures/" + civ + "_field",
168 "structures/" + civ + "_corral",
169 "structures/" + civ + "_civil_centre",
170 "structures/" + civ + "_military_colony",
171 "structures/" + civ + "_wallset_stone",
172 "other/wallset_palisade"
177 Trigger.prototype.PlaceTreasures = function()
179 let point = ["B", "C", "D"][Math.floor(Math.random() * 3)];
180 let triggerPoints = this.GetTriggerPoints(point);
181 for (let point of triggerPoints)
183 let template = treasures[Math.floor(Math.random() * treasures.length)];
184 TriggerHelper.SpawnUnits(point, template, 1, 0);
186 this.DoAfterDelay(4*60*1000, "PlaceTreasures", {}); // Place more treasures after 4 minutes
189 Trigger.prototype.InitializeEnemyWaves = function()
191 let time = (5 + Math.round(Math.random() * 10)) * 60 * 1000;
192 let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
193 cmpGUIInterface.AddTimeNotification({
194 "message": markForTranslation("The first wave will start in %(time)s!"),
195 "translateMessage": true
197 this.DoAfterDelay(time, "StartAnEnemyWave", {});
200 Trigger.prototype.DefeatPlayerOnceCCIsDestroyed = function(data)
202 if (data.entity == this.playerCivicCenter[data.from])
203 TriggerHelper.DefeatPlayer(data.from);
208 let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
209 cmpTrigger.playerCivicCenter = {};
210 cmpTrigger.DoAfterDelay(0, "InitGame", {});
211 cmpTrigger.DoAfterDelay(1000, "InitializeEnemyWaves", {});
212 cmpTrigger.RegisterTrigger("OnOwnershipChanged", "DefeatPlayerOnceCCIsDestroyed", { "enabled": true });