1 #include "stdafx.h"
2 #include "enemy_factory.h"
3 #include "name_generator.h"
4 #include "technology.h"
5 #include "attack_trigger.h"
6 #include "external_enemies.h"
7 #include "immigrant_info.h"
8 #include "settlement_info.h"
9 #include "enemy_info.h"
10 
EnemyFactory(RandomGen & r)11 EnemyFactory::EnemyFactory(RandomGen& r) : random(r) {
12 }
13 
EnemyInfo(SettlementInfo s,CollectiveConfig c,optional<VillageBehaviour> v,optional<LevelConnection> l)14 EnemyInfo::EnemyInfo(SettlementInfo s, CollectiveConfig c, optional<VillageBehaviour> v,
15     optional<LevelConnection> l)
16   : settlement(s), config(c), villain(v), levelConnection(l) {
17 }
18 
setVillainType(VillainType type)19 EnemyInfo& EnemyInfo::setVillainType(VillainType type) {
20   villainType = type;
21   return *this;
22 }
23 
setId(EnemyId i)24 EnemyInfo& EnemyInfo::setId(EnemyId i) {
25   id = i;
26   return *this;
27 }
28 
setNonDiscoverable()29 EnemyInfo& EnemyInfo::setNonDiscoverable() {
30   discoverable = false;
31   return *this;
32 }
33 
getVault(SettlementType type,CreatureId creature,TribeId tribe,int num,optional<ItemFactory> itemFactory=none)34 static EnemyInfo getVault(SettlementType type, CreatureId creature, TribeId tribe, int num,
35     optional<ItemFactory> itemFactory = none) {
36   return EnemyInfo(CONSTRUCT(SettlementInfo,
37       c.type = type;
38       c.inhabitants.fighters = CreatureList(num, creature);
39       c.tribe = tribe;
40       c.buildingId = BuildingId::DUNGEON;
41       c.shopFactory = itemFactory;
42     ), CollectiveConfig::noImmigrants())
43     .setNonDiscoverable();
44 }
45 
46 struct FriendlyVault {
47   CreatureId id;
48   int min;
49   int max;
50 };
51 
52 static vector<FriendlyVault> friendlyVaults {
53  // {CreatureId::SPECIAL_HUMANOID, 1, 2},
54   {CreatureId::ORC, 3, 8},
55   {CreatureId::OGRE, 2, 5},
56   {CreatureId::VAMPIRE, 2, 5},
57 };
58 
getVaults()59 vector<EnemyInfo> EnemyFactory::getVaults() {
60   vector<EnemyInfo> ret {
61  /*   getVault(SettlementType::VAULT, CreatureFactory::insects(TribeId::getMonster()),
62         TribeId::getMonster(), random.get(6, 12)),*/
63     getVault(SettlementType::VAULT, CreatureId::RAT, TribeId::getPest(), random.get(3, 8),
64         ItemFactory::armory()),
65   };
66   for (int i : Range(random.get(1, 3))) {
67     FriendlyVault v = random.choose(friendlyVaults);
68     ret.push_back(getVault(SettlementType::VAULT, v.id, TribeId::getKeeper(), random.get(v.min, v.max)));
69   }
70   return ret;
71 }
72 
getVillageName()73 static string getVillageName() {
74   return NameGenerator::get(NameGeneratorId::TOWN)->getNext();
75 }
76 
get(EnemyId id)77 EnemyInfo EnemyFactory::get(EnemyId id){
78   return getById(id).setId(id);
79 }
80 
getById(EnemyId enemyId)81 EnemyInfo EnemyFactory::getById(EnemyId enemyId) {
82   switch (enemyId) {
83      case EnemyId::UNICORN_HERD:
84       return EnemyInfo(CONSTRUCT(SettlementInfo,
85             c.type = SettlementType::FOREST;
86             c.inhabitants.fighters = CreatureList(random.get(5, 8), CreatureId::UNICORN);
87             c.stockpiles = LIST({StockpileInfo::GOLD, 100});
88             c.tribe = TribeId::getMonster();
89             c.race = "unicorns"_s;
90             c.buildingId = BuildingId::WOOD;),
91           CollectiveConfig::withImmigrants(200, 9, {
92               ImmigrantInfo(CreatureId::UNICORN, {MinionTrait::FIGHTER}).setFrequency(1),
93           }));
94     case EnemyId::ANTS_CLOSED:
95       return EnemyInfo(CONSTRUCT(SettlementInfo,
96             c.type = SettlementType::ANT_NEST;
97             c.inhabitants.leader = CreatureId::ANT_QUEEN;
98             c.inhabitants.civilians = CreatureList(random.get(5, 7), CreatureId::ANT_WORKER);
99             c.inhabitants.fighters = CreatureList(random.get(5, 7), CreatureId::ANT_SOLDIER);
100             c.tribe = TribeId::getAnt();
101             c.race = "ants"_s;
102             c.buildingId = BuildingId::DUNGEON;),
103           CollectiveConfig::withImmigrants(500, 15, {
104             ImmigrantInfo(CreatureId::ANT_WORKER, {}).setFrequency(1),
105             ImmigrantInfo(CreatureId::ANT_SOLDIER, {MinionTrait::FIGHTER}).setFrequency(1)}),
106           CONSTRUCT(VillageBehaviour,
107             c.minPopulation = 1;
108             c.minTeamSize = 4;
109             c.triggers = LIST(AttackTriggerId::ENTRY);
110             c.attackBehaviour = AttackBehaviour(AttackBehaviourId::KILL_LEADER);));
111     case EnemyId::ANTS_OPEN: {
112         auto ants = get(EnemyId::ANTS_CLOSED);
113         ants.settlement.type = SettlementType::MINETOWN;
114         return ants;
115       }
116     case EnemyId::ORC_VILLAGE:
117       return EnemyInfo(CONSTRUCT(SettlementInfo,
118             c.type = SettlementType::VILLAGE;
119             c.tribe = TribeId::getGreenskin();
120             c.inhabitants.fighters = CreatureList(
121                 random.get(12, 16),
122                 makeVec(CreatureId::ORC, CreatureId::OGRE));
123             c.locationName = getVillageName();
124             c.race = "greenskins"_s;
125             c.buildingId = BuildingId::BRICK;
126             c.furniture = FurnitureFactory::roomFurniture(c.tribe);
127             c.outsideFeatures = FurnitureFactory::villageOutside(c.tribe);),
128           CollectiveConfig::withImmigrants(300, 16, {
129               ImmigrantInfo(CreatureId::ORC, {MinionTrait::FIGHTER}).setFrequency(3),
130               ImmigrantInfo(CreatureId::OGRE, {MinionTrait::FIGHTER}).setFrequency(1)
131             }));
132     case EnemyId::DEMON_DEN_ABOVE:
133       return EnemyInfo(CONSTRUCT(SettlementInfo,
134             c.type = SettlementType::VILLAGE;
135             c.tribe = TribeId::getWildlife();
136             c.inhabitants.fighters = CreatureList(random.get(2, 3), CreatureId::GHOST);
137             c.buildingId = BuildingId::DUNGEON_SURFACE;
138             c.locationName = "Darkshrine Town"_s;
139             c.race = "ghosts"_s;
140             c.furniture = FurnitureFactory::dungeonOutside(c.tribe);
141             ),
142             CollectiveConfig::noImmigrants()).setNonDiscoverable();
143     case EnemyId::DEMON_DEN:
144       return EnemyInfo(CONSTRUCT(SettlementInfo,
145             c.tribe = TribeId::getMonster();
146             c.inhabitants.leader = CreatureId::DEMON_LORD;
147             c.inhabitants.fighters = CreatureList(random.get(5, 10), CreatureId::DEMON_DWELLER);
148             c.locationName = "Darkshrine"_s;
149             c.race = "demons"_s;
150             c.furniture = FurnitureFactory::dungeonOutside(c.tribe);
151             c.outsideFeatures = FurnitureFactory::dungeonOutside(c.tribe);),
152           CollectiveConfig::withImmigrants(300, 16, {
153               ImmigrantInfo(CreatureId::DEMON_DWELLER, {MinionTrait::FIGHTER}).setFrequency(1),
154           }),
155           CONSTRUCT(VillageBehaviour,
156               c.minPopulation = 0;
157               c.minTeamSize = 3;
158               c.triggers = LIST(
159                   {AttackTriggerId::ROOM_BUILT, FurnitureType::DEMON_SHRINE});
160               c.attackBehaviour = AttackBehaviour(AttackBehaviourId::KILL_LEADER);
161               c.ransom = make_pair(0.5, random.get(50, 100));),
162           LevelConnection{LevelConnection::CRYPT, get(EnemyId::DEMON_DEN_ABOVE)});
163     case EnemyId::VILLAGE:
164       return EnemyInfo(CONSTRUCT(SettlementInfo,
165             c.type = SettlementType::VILLAGE;
166             c.tribe = TribeId::getHuman();
167             c.inhabitants.leader = CreatureId::KNIGHT;
168             c.inhabitants.fighters = CreatureList(
169                 random.get(4, 8),
170                 makeVec(CreatureId::KNIGHT, CreatureId::ARCHER));
171             c.inhabitants.civilians = CreatureList(
172                 random.get(4, 8),
173                 makeVec(CreatureId::PESEANT, CreatureId::CHILD, CreatureId::DONKEY, CreatureId::HORSE,
174                     CreatureId::COW, CreatureId::PIG, CreatureId::DOG));
175             c.locationName = getVillageName();
176             c.race = "humans"_s;
177             c.buildingId = BuildingId::WOOD;
178             c.shopFactory = ItemFactory::armory();
179             c.furniture = FurnitureFactory::roomFurniture(c.tribe);
180             ), CollectiveConfig::noImmigrants().setGhostSpawns(0.1, 4));
181     case EnemyId::WARRIORS:
182       return EnemyInfo(CONSTRUCT(SettlementInfo,
183             c.type = SettlementType::CASTLE2;
184             c.tribe = TribeId::getHuman();
185             c.inhabitants.leader = CreatureId::SHAMAN;
186             c.inhabitants.fighters = CreatureList(random.get(7, 10), CreatureId::WARRIOR);
187             c.locationName = getVillageName();
188             c.race = "humans"_s;
189             c.buildingId = BuildingId::WOOD_CASTLE;
190             c.stockpiles = LIST({StockpileInfo::GOLD, 160});
191             c.guardId = CreatureId::WARRIOR;
192             c.elderLoot = ItemType(ItemType::TechBook{TechId::BEAST_MUT});
193             c.furniture = FurnitureFactory::roomFurniture(c.tribe);
194             c.outsideFeatures = FurnitureFactory::castleOutside(c.tribe);),
195           CollectiveConfig::withImmigrants(300, 10, {
196               ImmigrantInfo(CreatureId::WARRIOR, {MinionTrait::FIGHTER}).setFrequency(1),
197             }).setGhostSpawns(0.1, 6),
198           CONSTRUCT(VillageBehaviour,
199               c.minPopulation = 3;
200               c.minTeamSize = 5;
201               c.triggers = LIST(
202                   {AttackTriggerId::ROOM_BUILT, FurnitureType::THRONE},
203                   AttackTriggerId::SELF_VICTIMS,
204                   {AttackTriggerId::NUM_CONQUERED, 2},
205                   AttackTriggerId::STOLEN_ITEMS,
206                   {AttackTriggerId::ROOM_BUILT, FurnitureType::IMPALED_HEAD},
207                   AttackTriggerId::FINISH_OFF,
208                   AttackTriggerId::PROXIMITY);
209               c.attackBehaviour = AttackBehaviour(AttackBehaviourId::KILL_LEADER);
210               c.ransom = make_pair(0.8, random.get(100, 140));));
211     case EnemyId::KNIGHTS:
212       return EnemyInfo(CONSTRUCT(SettlementInfo,
213             c.type = SettlementType::CASTLE;
214             c.tribe = TribeId::getHuman();
215             c.inhabitants.leader = CreatureId::AVATAR;
216             c.inhabitants.fighters = CreatureList(
217                 random.get(12, 17),
218                 makeVec(CreatureId::KNIGHT, CreatureId::ARCHER));
219             c.inhabitants.civilians = CreatureList(
220                 random.get(6, 9),
221                 makeVec(CreatureId::PESEANT, CreatureId::CHILD, CreatureId::DONKEY, CreatureId::HORSE,
222                     CreatureId::COW, CreatureId::PIG, CreatureId::DOG));
223             c.locationName = getVillageName();
224             c.race = "humans"_s;
225             c.stockpiles = LIST({StockpileInfo::GOLD, 140});
226             c.buildingId = BuildingId::BRICK;
227             c.guardId = CreatureId::KNIGHT;
228             c.shopFactory = ItemFactory::villageShop();
229             c.furniture = FurnitureFactory::castleFurniture(c.tribe);
230             c.outsideFeatures = FurnitureFactory::castleOutside(c.tribe);),
231           CollectiveConfig::withImmigrants(300, 26, {
232               ImmigrantInfo(CreatureId::ARCHER, {MinionTrait::FIGHTER}).setFrequency(1),
233               ImmigrantInfo(CreatureId::KNIGHT, {MinionTrait::FIGHTER}).setFrequency(1)
234             }).setGhostSpawns(0.1, 6),
235           CONSTRUCT(VillageBehaviour,
236               c.minPopulation = 12;
237               c.minTeamSize = 10;
238               c.triggers = LIST(
239                   {AttackTriggerId::ROOM_BUILT, FurnitureType::THRONE},
240                   AttackTriggerId::SELF_VICTIMS,
241                   {AttackTriggerId::NUM_CONQUERED, 3},
242                   AttackTriggerId::STOLEN_ITEMS,
243                   {AttackTriggerId::ROOM_BUILT, FurnitureType::IMPALED_HEAD},
244                   AttackTriggerId::FINISH_OFF,
245                   AttackTriggerId::PROXIMITY);
246               c.attackBehaviour = AttackBehaviour(AttackBehaviourId::KILL_LEADER);
247               c.ransom = make_pair(0.9, random.get(280, 400));),
248           random.roll(4) ? LevelConnection{LevelConnection::MAZE, get(EnemyId::MINOTAUR)}
249               : optional<LevelConnection>(none));
250     case EnemyId::MINOTAUR:
251       return EnemyInfo(CONSTRUCT(SettlementInfo,
252             c.tribe = TribeId::getMonster();
253             c.inhabitants.leader = CreatureId::MINOTAUR;
254             c.locationName = "maze"_s;
255             c.race = "monsters"_s;
256             c.furniture = FurnitureFactory::roomFurniture(c.tribe);
257             c.buildingId = BuildingId::BRICK;), CollectiveConfig::noImmigrants());
258     case EnemyId::RED_DRAGON:
259       return EnemyInfo(CONSTRUCT(SettlementInfo,
260             c.type = SettlementType::CAVE;
261             c.inhabitants.leader = CreatureId::RED_DRAGON;
262             c.race = "dragon"_s;
263             c.tribe = TribeId::getMonster();
264             c.buildingId = BuildingId::DUNGEON;
265             c.shopFactory = ItemFactory::dragonCave();), CollectiveConfig::noImmigrants().setLeaderAsFighter()
266           .setGhostSpawns(0.03, 1),
267           CONSTRUCT(VillageBehaviour,
268               c.minPopulation = 0;
269               c.minTeamSize = 1;
270               c.triggers = LIST(
271                   {AttackTriggerId::ENEMY_POPULATION, 22},
272                   AttackTriggerId::STOLEN_ITEMS,
273                   {AttackTriggerId::NUM_CONQUERED, 3},
274                   AttackTriggerId::FINISH_OFF,
275                   AttackTriggerId::PROXIMITY);
276               c.attackBehaviour = AttackBehaviour(AttackBehaviourId::KILL_MEMBERS, 12);
277               c.welcomeMessage = VillageBehaviour::DRAGON_WELCOME;));
278     case EnemyId::GREEN_DRAGON:
279       return EnemyInfo(CONSTRUCT(SettlementInfo,
280             c.type = SettlementType::CAVE;
281             c.inhabitants.leader = CreatureId::RED_DRAGON;
282             c.tribe = TribeId::getMonster();
283             c.race = "dragon"_s;
284             c.buildingId = BuildingId::DUNGEON;
285             c.shopFactory = ItemFactory::dragonCave();), CollectiveConfig::noImmigrants().setLeaderAsFighter()
286           .setGhostSpawns(0.03, 1),
287           CONSTRUCT(VillageBehaviour,
288               c.minPopulation = 0;
289               c.minTeamSize = 1;
290               c.triggers = LIST(
291                   {AttackTriggerId::ENEMY_POPULATION, 18},
292                   AttackTriggerId::STOLEN_ITEMS,
293                   {AttackTriggerId::NUM_CONQUERED, 2},
294                   AttackTriggerId::FINISH_OFF,
295                   AttackTriggerId::PROXIMITY);
296               c.attackBehaviour = AttackBehaviour(AttackBehaviourId::KILL_MEMBERS, 7);
297               c.welcomeMessage = VillageBehaviour::DRAGON_WELCOME;));
298     case EnemyId::DWARVES:
299       return EnemyInfo(CONSTRUCT(SettlementInfo,
300             c.type = SettlementType::MINETOWN;
301             c.tribe = TribeId::getDwarf();
302             c.inhabitants.leader = CreatureId::DWARF_BARON;
303             c.inhabitants.fighters = CreatureList(random.get(6, 9), CreatureId::DWARF);
304             c.inhabitants.civilians = CreatureList(
305                 random.get(3, 5),
306                 makeVec(make_pair(2, CreatureId::DWARF_FEMALE), make_pair(1, CreatureId::RAT)));
307             c.locationName = getVillageName();
308             c.race = "dwarves"_s;
309             c.buildingId = BuildingId::DUNGEON;
310             c.stockpiles = LIST({StockpileInfo::GOLD, 200}, {StockpileInfo::MINERALS, 120});
311             c.shopFactory = ItemFactory::dwarfShop();
312             c.outsideFeatures = FurnitureFactory::dungeonOutside(c.tribe);
313             c.furniture = FurnitureFactory::roomFurniture(c.tribe);),
314           CollectiveConfig::withImmigrants(500, 15, {
315               ImmigrantInfo(CreatureId::DWARF, {MinionTrait::FIGHTER}).setFrequency(1),
316             }).setGhostSpawns(0.1, 4),
317           CONSTRUCT(VillageBehaviour,
318             c.minPopulation = 3;
319             c.minTeamSize = 4;
320             c.triggers = LIST(
321                 {AttackTriggerId::ROOM_BUILT, FurnitureType::THRONE},
322                 AttackTriggerId::SELF_VICTIMS,
323                 AttackTriggerId::STOLEN_ITEMS,
324                 {AttackTriggerId::ROOM_BUILT, FurnitureType::IMPALED_HEAD},
325                 {AttackTriggerId::NUM_CONQUERED, 3},
326                 AttackTriggerId::FINISH_OFF,
327                 AttackTriggerId::PROXIMITY);
328             c.attackBehaviour = AttackBehaviour(AttackBehaviourId::KILL_MEMBERS, 3);
329             c.ransom = make_pair(0.8, random.get(240, 320));));
330     case EnemyId::ELVES:
331       return EnemyInfo(CONSTRUCT(SettlementInfo,
332             c.type = SettlementType::FORREST_VILLAGE;
333             c.inhabitants.leader = CreatureId::ELF_LORD;
334             c.inhabitants.fighters = CreatureList(random.get(6, 9), CreatureId::ELF_ARCHER);
335             c.inhabitants.civilians = CreatureList(
336                 random.get(6, 9),
337                 makeVec(CreatureId::ELF, CreatureId::ELF_CHILD, CreatureId::HORSE));
338             c.locationName = getVillageName();
339             c.tribe = TribeId::getElf();
340             c.race = "elves"_s;
341             c.stockpiles = LIST({StockpileInfo::GOLD, 100});
342             c.buildingId = BuildingId::WOOD;
343             c.elderLoot = ItemType(ItemType::TechBook{TechId::SPELLS_MAS});
344             c.furniture = FurnitureFactory::roomFurniture(TribeId::getPest());),
345           CollectiveConfig::withImmigrants(500, 18, {
346               ImmigrantInfo(CreatureId::ELF_ARCHER, {MinionTrait::FIGHTER}).setFrequency(1),
347             }).setGhostSpawns(0.1, 4),
348           CONSTRUCT(VillageBehaviour,
349               c.minPopulation = 4;
350               c.minTeamSize = 4;
351               c.triggers = LIST(AttackTriggerId::STOLEN_ITEMS);
352               c.attackBehaviour = AttackBehaviour(AttackBehaviourId::KILL_LEADER);));
353     case EnemyId::ELEMENTALIST_ENTRY:
354       return EnemyInfo(CONSTRUCT(SettlementInfo,
355             c.type = SettlementType::TOWER;
356             c.tribe = TribeId::getHuman();
357             c.buildingId = BuildingId::BRICK;),
358           CollectiveConfig::noImmigrants())
359           .setNonDiscoverable();
360     case EnemyId::ELEMENTALIST:
361       return EnemyInfo(CONSTRUCT(SettlementInfo,
362             c.type = SettlementType::TOWER;
363             c.inhabitants.leader = CreatureId::ELEMENTALIST;
364             c.tribe = TribeId::getHuman();
365             c.buildingId = BuildingId::BRICK;
366             c.furniture = FurnitureFactory::roomFurniture(TribeId::getPest());),
367           CollectiveConfig::noImmigrants().setLeaderAsFighter(),
368           CONSTRUCT(VillageBehaviour,
369               c.minPopulation = 0;
370               c.minTeamSize = 1;
371               c.triggers = LIST(
372                   {AttackTriggerId::ROOM_BUILT, FurnitureType::THRONE},
373                   AttackTriggerId::PROXIMITY,
374                   {AttackTriggerId::ROOM_BUILT, FurnitureType::IMPALED_HEAD},
375                   AttackTriggerId::FINISH_OFF,
376                   {AttackTriggerId::NUM_CONQUERED, 3});
377               c.attackBehaviour = AttackBehaviour(AttackBehaviourId::CAMP_AND_SPAWN,
378                 CreatureFactory::elementals(TribeId::getHuman()));
379               c.ransom = make_pair(0.5, random.get(40, 80));),
380           LevelConnection{LevelConnection::TOWER, get(EnemyId::ELEMENTALIST_ENTRY)});
381     case EnemyId::NO_AGGRO_BANDITS:
382       return EnemyInfo(CONSTRUCT(SettlementInfo,
383             c.type = SettlementType::CAVE;
384             c.inhabitants.fighters = CreatureList(random.get(4, 9), CreatureId::BANDIT);
385             c.tribe = TribeId::getBandit();
386             c.race = "bandits"_s;
387             c.buildingId = BuildingId::DUNGEON;),
388           CollectiveConfig::withImmigrants(1000, 10, {
389               ImmigrantInfo(CreatureId::BANDIT, {MinionTrait::FIGHTER}).setFrequency(1),
390             }));
391     case EnemyId::BANDITS:
392       return EnemyInfo(CONSTRUCT(SettlementInfo,
393             c.type = SettlementType::CAVE;
394             c.inhabitants.fighters = CreatureList(random.get(4, 9), CreatureId::BANDIT);
395             c.tribe = TribeId::getBandit();
396             c.race = "bandits"_s;
397             c.buildingId = BuildingId::DUNGEON;),
398           CollectiveConfig::withImmigrants(1000, 10, {
399               ImmigrantInfo(CreatureId::BANDIT, {MinionTrait::FIGHTER}).setFrequency(1),
400             }),
401           CONSTRUCT(VillageBehaviour,
402               c.minPopulation = 0;
403               c.minTeamSize = 3;
404               c.triggers = LIST({AttackTriggerId::GOLD, 100});
405               c.attackBehaviour = AttackBehaviour(AttackBehaviourId::STEAL_GOLD);
406               c.ransom = make_pair(0.5, random.get(40, 80));));
407     case EnemyId::LIZARDMEN:
408       return EnemyInfo(CONSTRUCT(SettlementInfo,
409             c.type = SettlementType::VILLAGE;
410             c.tribe = TribeId::getLizard();
411             c.inhabitants.leader = CreatureId::LIZARDLORD;
412             c.inhabitants.fighters = CreatureList(random.get(7, 10), CreatureId::LIZARDMAN);
413             c.locationName = getVillageName();
414             c.race = "lizardmen"_s;
415             c.buildingId = BuildingId::MUD;
416             c.elderLoot = ItemType(ItemType::TechBook{TechId::HUMANOID_MUT});
417             c.shopFactory = ItemFactory::mushrooms();
418             c.furniture = FurnitureFactory::roomFurniture(c.tribe);
419             c.outsideFeatures = FurnitureFactory::villageOutside(c.tribe);),
420           CollectiveConfig::withImmigrants(140, 11, {
421               ImmigrantInfo(CreatureId::LIZARDMAN, {MinionTrait::FIGHTER}).setFrequency(1),
422             }).setGhostSpawns(0.1, 4),
423           CONSTRUCT(VillageBehaviour,
424               c.minPopulation = 4;
425               c.minTeamSize = 4;
426               c.triggers = LIST(
427                   AttackTriggerId::POWER,
428                   AttackTriggerId::SELF_VICTIMS,
429                   AttackTriggerId::STOLEN_ITEMS,
430                   {AttackTriggerId::ROOM_BUILT, FurnitureType::IMPALED_HEAD},
431                   {AttackTriggerId::NUM_CONQUERED, 2},
432                   AttackTriggerId::FINISH_OFF,
433                   AttackTriggerId::PROXIMITY);
434               c.attackBehaviour = AttackBehaviour(AttackBehaviourId::KILL_LEADER);));
435     case EnemyId::DARK_ELVES:
436       return EnemyInfo(CONSTRUCT(SettlementInfo,
437             c.type = SettlementType::MINETOWN;
438             c.tribe = TribeId::getDarkElf();
439             c.inhabitants.leader = CreatureId::DARK_ELF_LORD;
440             c.inhabitants.fighters = CreatureList(random.get(6, 9), CreatureId::DARK_ELF_WARRIOR);
441             c.inhabitants.civilians = CreatureList(
442                 random.get(6, 9),
443                 makeVec(CreatureId::DARK_ELF, CreatureId::DARK_ELF_CHILD, CreatureId::RAT));
444             c.locationName = getVillageName();
445             c.race = "dark elves"_s;
446             c.buildingId = BuildingId::DUNGEON;
447             c.outsideFeatures = FurnitureFactory::dungeonOutside(c.tribe);
448             c.furniture = FurnitureFactory::roomFurniture(c.tribe);),
449           CollectiveConfig::withImmigrants(500, 15, {
450               ImmigrantInfo(CreatureId::DARK_ELF_WARRIOR, {MinionTrait::FIGHTER}).setFrequency(1),
451           }), none,
452           LevelConnection{LevelConnection::GNOMISH_MINES, get(EnemyId::DARK_ELVES_ENTRY)});
453     case EnemyId::DARK_ELVES_ENTRY:
454       return EnemyInfo(CONSTRUCT(SettlementInfo,
455             c.type = SettlementType::SMALL_MINETOWN;
456             c.tribe = TribeId::getDarkElf();
457             c.inhabitants.fighters = CreatureList(random.get(3, 7), CreatureId::DARK_ELF_WARRIOR);
458             c.race = "dark elves"_s;
459             c.buildingId = BuildingId::DUNGEON;
460             c.outsideFeatures = FurnitureFactory::dungeonOutside(c.tribe);
461             c.furniture = FurnitureFactory::roomFurniture(c.tribe);),
462           CollectiveConfig::noImmigrants(), {})
463           .setNonDiscoverable();
464     case EnemyId::GNOMES:
465       return EnemyInfo(CONSTRUCT(SettlementInfo,
466             c.type = SettlementType::MINETOWN;
467             c.tribe = TribeId::getGnome();
468             c.inhabitants.leader = CreatureId::GNOME_CHIEF;
469             c.inhabitants.fighters = CreatureList(random.get(8, 14), CreatureId::GNOME);
470             c.locationName = getVillageName();
471             c.race = "gnomes"_s;
472             c.buildingId = BuildingId::DUNGEON;
473             c.shopFactory = ItemFactory::gnomeShop();
474             c.outsideFeatures = FurnitureFactory::dungeonOutside(c.tribe);
475             c.furniture = FurnitureFactory::roomFurniture(c.tribe);),
476           CollectiveConfig::noImmigrants(), none,
477           LevelConnection{LevelConnection::GNOMISH_MINES, get(EnemyId::GNOMES_ENTRY)});
478     case EnemyId::GNOMES_ENTRY:
479       return EnemyInfo(CONSTRUCT(SettlementInfo,
480             c.type = SettlementType::SMALL_MINETOWN;
481             c.tribe = TribeId::getGnome();
482             c.inhabitants.fighters = CreatureList(random.get(3, 7), CreatureId::GNOME);
483             c.race = "gnomes"_s;
484             c.buildingId = BuildingId::DUNGEON;
485             c.outsideFeatures = FurnitureFactory::dungeonOutside(c.tribe);
486             c.furniture = FurnitureFactory::roomFurniture(c.tribe);),
487           CollectiveConfig::noImmigrants())
488           .setNonDiscoverable();
489     case EnemyId::ENTS:
490       return EnemyInfo(CONSTRUCT(SettlementInfo,
491             c.type = SettlementType::FOREST;
492             c.inhabitants.fighters = CreatureList(random.get(7, 10), CreatureId::ENT);
493             c.tribe = TribeId::getMonster();
494             c.race = "tree spirits"_s;
495             c.buildingId = BuildingId::WOOD;),
496           CollectiveConfig::withImmigrants(300, 10, {
497               ImmigrantInfo(CreatureId::ENT, {MinionTrait::FIGHTER}).setFrequency(1),
498           }));
499     case EnemyId::DRIADS:
500       return EnemyInfo(CONSTRUCT(SettlementInfo,
501             c.type = SettlementType::FOREST;
502             c.inhabitants.fighters = CreatureList(random.get(7, 10), CreatureId::DRIAD);
503             c.tribe = TribeId::getMonster();
504             c.race = "driads"_s;
505             c.buildingId = BuildingId::WOOD;),
506           CollectiveConfig::withImmigrants(300, 10, {
507               ImmigrantInfo(CreatureId::DRIAD, {MinionTrait::FIGHTER}).setFrequency(1),
508           }));
509     case EnemyId::SHELOB:
510       return EnemyInfo(CONSTRUCT(SettlementInfo,
511             c.type = SettlementType::CAVE;
512             c.tribe = TribeId::getShelob();
513             c.inhabitants.leader = CreatureId::SHELOB;
514             c.race = "giant spider"_s;
515             c.buildingId = BuildingId::DUNGEON;
516             ), CollectiveConfig::noImmigrants().setLeaderAsFighter());
517     case EnemyId::CYCLOPS:
518       return EnemyInfo(CONSTRUCT(SettlementInfo,
519             c.type = SettlementType::CAVE;
520             c.inhabitants.leader = CreatureId::CYCLOPS;
521             c.race = "cyclops"_s;
522             c.tribe = TribeId::getHostile();
523             c.buildingId = BuildingId::DUNGEON;
524             c.shopFactory = ItemFactory::mushrooms(true);), CollectiveConfig::noImmigrants().setLeaderAsFighter()
525           .setGhostSpawns(0.03, 1),
526           CONSTRUCT(VillageBehaviour,
527             c.minPopulation = 0;
528             c.minTeamSize = 1;
529             c.triggers = LIST(
530                 {AttackTriggerId::ENEMY_POPULATION, 13},
531                 AttackTriggerId::PROXIMITY);
532             c.attackBehaviour = AttackBehaviour(AttackBehaviourId::KILL_MEMBERS, 4);));
533     case EnemyId::HYDRA:
534       return EnemyInfo(CONSTRUCT(SettlementInfo,
535             c.type = SettlementType::SWAMP;
536             c.inhabitants.leader = CreatureId::HYDRA;
537             c.race = "hydra"_s;
538             c.tribe = TribeId::getHostile();), CollectiveConfig::noImmigrants().setLeaderAsFighter()
539           .setGhostSpawns(0.03, 1));
540     case EnemyId::KRAKEN:
541       return EnemyInfo(CONSTRUCT(SettlementInfo,
542             c.type = SettlementType::MOUNTAIN_LAKE;
543             c.inhabitants.leader = CreatureId::KRAKEN;
544             c.race = "kraken"_s;
545             c.tribe = TribeId::getMonster();), CollectiveConfig::noImmigrants().setLeaderAsFighter())
546           .setNonDiscoverable();
547     case EnemyId::CEMETERY:
548       return EnemyInfo(CONSTRUCT(SettlementInfo,
549             c.type = SettlementType::CEMETERY;
550             c.inhabitants.fighters = CreatureList(random.get(8, 12), CreatureId::ZOMBIE);
551             c.locationName = "cemetery"_s;
552             c.tribe = TribeId::getMonster();
553             c.race = "undead"_s;
554             c.furniture = FurnitureFactory::cryptCoffins(TribeId::getKeeper());
555             c.buildingId = BuildingId::BRICK;), CollectiveConfig::noImmigrants(), {},
556           LevelConnection{LevelConnection::CRYPT, get(EnemyId::CEMETERY_ENTRY)});
557     case EnemyId::CEMETERY_ENTRY:
558       return EnemyInfo(CONSTRUCT(SettlementInfo,
559             c.type = SettlementType::CEMETERY;
560             c.inhabitants.fighters = CreatureList(1, CreatureId::ZOMBIE);
561             c.locationName = "cemetery"_s;
562             c.race = "undead"_s;
563             c.tribe = TribeId::getMonster();
564             c.buildingId = BuildingId::BRICK;), CollectiveConfig::noImmigrants())
565           .setNonDiscoverable();
566     case EnemyId::OGRE_CAVE:
567       return EnemyInfo(CONSTRUCT(SettlementInfo,
568             c.type = SettlementType::CAVE;
569             c.tribe = TribeId::getGreenskin();
570             c.inhabitants.fighters = CreatureList(random.get(4, 8), CreatureId::OGRE);
571             c.buildingId = BuildingId::DUNGEON;
572             c.closeToPlayer = true;
573             c.furniture = FurnitureFactory::roomFurniture(c.tribe);
574             c.outsideFeatures = FurnitureFactory::villageOutside(c.tribe);),
575           CollectiveConfig::withImmigrants(300, 10, {
576               ImmigrantInfo(CreatureId::OGRE, {MinionTrait::FIGHTER}).setFrequency(1),
577           }));
578     case EnemyId::HARPY_CAVE: {
579       return EnemyInfo(CONSTRUCT(SettlementInfo,
580             c.type = SettlementType::CAVE;
581             c.tribe = TribeId::getGreenskin();
582             c.inhabitants.fighters = CreatureList(random.get(4, 8), CreatureId::HARPY);
583             c.buildingId = BuildingId::DUNGEON;
584             c.closeToPlayer = true;
585             c.furniture = FurnitureFactory::roomFurniture(c.tribe);
586             c.outsideFeatures = FurnitureFactory::villageOutside(c.tribe);),
587           CollectiveConfig::withImmigrants(300, 10, {
588               ImmigrantInfo(CreatureId::HARPY, {MinionTrait::FIGHTER}).setFrequency(1),
589           }));
590       }
591     case EnemyId::SOKOBAN_ENTRY:
592       return EnemyInfo(CONSTRUCT(SettlementInfo,
593             c.type = SettlementType::ISLAND_VAULT_DOOR;
594             c.buildingId = BuildingId::DUNGEON;
595             ), CollectiveConfig::noImmigrants());
596     case EnemyId::SOKOBAN:
597       return EnemyInfo(CONSTRUCT(SettlementInfo,
598             c.type = SettlementType::ISLAND_VAULT;
599             c.inhabitants.leader = random.choose(
600                 CreatureId::SPECIAL_HLBN, CreatureId::SPECIAL_HLBW, CreatureId::SPECIAL_HLGN, CreatureId::SPECIAL_HLGW);
601             c.tribe = TribeId::getKeeper();
602             c.buildingId = BuildingId::DUNGEON;
603             ), CollectiveConfig::noImmigrants(), none,
604           LevelConnection{LevelConnection::SOKOBAN, get(EnemyId::SOKOBAN_ENTRY)})
605           .setNonDiscoverable();
606     case EnemyId::WITCH:
607       return EnemyInfo(CONSTRUCT(SettlementInfo,
608             c.type = SettlementType::WITCH_HOUSE;
609             c.tribe = TribeId::getMonster();
610             c.inhabitants.leader = CreatureId::WITCH;
611             c.race = "witch"_s;
612             c.buildingId = BuildingId::WOOD;
613             c.elderLoot = ItemType(ItemType::TechBook{TechId::ALCHEMY_ADV});
614             c.furniture = FurnitureFactory(c.tribe, FurnitureType::LABORATORY);), CollectiveConfig::noImmigrants());
615     case EnemyId::HUMAN_COTTAGE:
616       return EnemyInfo(CONSTRUCT(SettlementInfo,
617             c.type = SettlementType::COTTAGE;
618             c.tribe = TribeId::getHuman();
619             c.inhabitants.leader = random.choose(CreatureId::KNIGHT, CreatureId::ARCHER);
620             c.inhabitants.fighters = CreatureList(random.get(2, 4), CreatureId::PESEANT);
621             c.inhabitants.civilians = CreatureList(
622                 random.get(3, 7),
623                 makeVec(CreatureId::CHILD, CreatureId::HORSE, CreatureId::DONKEY, CreatureId::COW,
624                     CreatureId::PIG, CreatureId::DOG));
625             c.race = "humans"_s;
626             c.buildingId = BuildingId::WOOD;
627             c.furniture = FurnitureFactory::roomFurniture(c.tribe);),
628           CollectiveConfig::noImmigrants().setGuardian({CreatureId::WITCHMAN, 0.001, 1, 2}));
629     case EnemyId::TUTORIAL_VILLAGE:
630       return EnemyInfo(CONSTRUCT(SettlementInfo,
631             c.type = SettlementType::SMALL_VILLAGE;
632             c.tribe = TribeId::getHuman();
633             c.inhabitants.fighters = CreatureList(random.get(2, 4), CreatureId::PESEANT);
634             c.inhabitants.civilians = CreatureList(
635                 random.get(3, 7),
636                 makeVec(CreatureId::CHILD, CreatureId::HORSE, CreatureId::DONKEY, CreatureId::COW,
637                     CreatureId::PIG, CreatureId::DOG));
638             c.race = "humans"_s;
639             c.buildingId = BuildingId::WOOD;
640             c.stockpiles = LIST({StockpileInfo::GOLD, 50});
641             c.furniture = FurnitureFactory::roomFurniture(c.tribe);),
642           CollectiveConfig::noImmigrants());
643     case EnemyId::ELVEN_COTTAGE:
644       return EnemyInfo(CONSTRUCT(SettlementInfo,
645             c.type = SettlementType::FORREST_COTTAGE;
646             c.tribe = TribeId::getElf();
647             c.inhabitants.leader = CreatureId::ELF_ARCHER;
648             c.inhabitants.fighters = CreatureList(random.get(2, 3), CreatureId::ELF);
649             c.inhabitants.civilians = CreatureList(
650                 random.get(2, 5),
651                 makeVec(CreatureId::ELF_CHILD, CreatureId::HORSE, CreatureId::COW, CreatureId::DOG));
652             c.race = "elves"_s;
653             c.buildingId = BuildingId::WOOD;
654             c.furniture = FurnitureFactory::roomFurniture(c.tribe);),
655           CollectiveConfig::noImmigrants());
656     case EnemyId::KOBOLD_CAVE:
657       return EnemyInfo(CONSTRUCT(SettlementInfo,
658             c.type = SettlementType::SMALL_MINETOWN;
659             c.tribe = TribeId::getDwarf();
660             c.inhabitants.fighters = CreatureList(random.get(3, 7), CreatureId::KOBOLD);
661             c.race = "kobolds"_s;
662             c.buildingId = BuildingId::DUNGEON;
663             c.stockpiles = LIST({StockpileInfo::MINERALS, 60});),
664           CollectiveConfig::noImmigrants());
665     case EnemyId::DWARF_CAVE:
666       return EnemyInfo(CONSTRUCT(SettlementInfo,
667             c.type = SettlementType::SMALL_MINETOWN;
668             c.tribe = TribeId::getDwarf();
669             c.inhabitants.fighters = CreatureList(random.get(2, 5), CreatureId::DWARF);
670             c.inhabitants.civilians = CreatureList(random.get(2, 5), CreatureId::DWARF_FEMALE);
671             c.race = "dwarves"_s;
672             c.buildingId = BuildingId::DUNGEON;
673             c.stockpiles = LIST(random.choose(StockpileInfo{StockpileInfo::MINERALS, 60},
674                 StockpileInfo{StockpileInfo::GOLD, 60}));
675             c.outsideFeatures = FurnitureFactory::dungeonOutside(c.tribe);
676             c.furniture = FurnitureFactory::roomFurniture(c.tribe);),
677           CollectiveConfig::noImmigrants(),
678           CONSTRUCT(VillageBehaviour,
679             c.minPopulation = 0;
680             c.minTeamSize = 1;
681             c.triggers = LIST(AttackTriggerId::SELF_VICTIMS, AttackTriggerId::STOLEN_ITEMS);
682             c.attackBehaviour = AttackBehaviour(AttackBehaviourId::KILL_LEADER);
683             c.ransom = make_pair(0.5, random.get(40, 80));));
684   }
685 }
686 
getExternalEnemies()687 vector<ExternalEnemy> EnemyFactory::getExternalEnemies() {
688   return {
689     ExternalEnemy{
690         CreatureList(1, CreatureId::BANDIT),
691         AttackBehaviourId::KILL_LEADER,
692         "a curious bandit",
693         Range(1000, 10000),
694         1
695     },
696     ExternalEnemy{
697         CreatureList(1, CreatureId::LIZARDMAN)
698             .increaseBaseLevel({{ExperienceType::MELEE, 3}}),
699         AttackBehaviourId::KILL_LEADER,
700         "a lizardman scout",
701         Range(1000, 10000),
702         1
703     },
704     ExternalEnemy{
705         CreatureList(random.get(3, 5), CreatureId::ANT_WORKER),
706         AttackBehaviourId::KILL_LEADER,
707         "an ant patrol",
708         Range(1000, 5000),
709         2
710     },
711     ExternalEnemy{
712         CreatureList(random.get(4, 8), CreatureId::LIZARDMAN)
713             .increaseBaseLevel({{ExperienceType::MELEE, 6}}),
714         AttackBehaviourId::KILL_LEADER,
715         "a nest of lizardmen",
716         Range(6000, 15000),
717         5
718     },
719     ExternalEnemy{
720         CreatureList(random.get(3, 5), CreatureId::BANDIT)
721             .increaseBaseLevel({{ExperienceType::MELEE, 11}}),
722         AttackBehaviourId::KILL_LEADER,
723         "a gang of bandits",
724         Range(8000, 20000),
725         10
726     },
727     ExternalEnemy{
728         CreatureList(random.get(3, 5), CreatureId::ANT_SOLDIER),
729         AttackBehaviourId::KILL_LEADER,
730         "an ant soldier patrol",
731         Range(5000, 10000),
732         1
733     },
734     ExternalEnemy{
735         CreatureList(random.get(3, 5), CreatureId::CLAY_GOLEM)
736             .increaseBaseLevel({{ExperienceType::MELEE, 3}}),
737         AttackBehaviourId::KILL_LEADER,
738         "an alchemist's clay golems",
739         Range(3000, 10000),
740         1
741     },
742     ExternalEnemy{
743         CreatureList(random.get(3, 5), CreatureId::STONE_GOLEM)
744             .increaseBaseLevel({{ExperienceType::MELEE, 3}}),
745         AttackBehaviourId::KILL_LEADER,
746         "an alchemist's stone golems",
747         Range(5000, 12000),
748         2
749     },
750     ExternalEnemy{
751         CreatureList(random.get(5, 8), CreatureId::ANT_SOLDIER)
752             .increaseBaseLevel({{ExperienceType::MELEE, 5}}),
753         AttackBehaviourId::KILL_LEADER,
754         "an ant soldier patrol",
755         Range(6000, 12000),
756         2
757     },
758     ExternalEnemy{
759         CreatureList(random.get(10, 15), CreatureId::ANT_SOLDIER).addUnique(CreatureId::ANT_QUEEN)
760             .increaseBaseLevel({{ExperienceType::MELEE, 6}}),
761         AttackBehaviourId::KILL_LEADER,
762         "an army of ants",
763         Range(10000, 15000),
764         3
765     },
766     ExternalEnemy{
767         CreatureList(random.get(4, 8), CreatureId::ENT)
768             .increaseBaseLevel({{ExperienceType::MELEE, 3}}),
769         AttackBehaviourId::KILL_LEADER,
770         "a group of ents",
771         Range(7000, 12000),
772         2
773     },
774     ExternalEnemy{
775         CreatureList(random.get(4, 8), CreatureId::DWARF),
776         AttackBehaviourId::KILL_LEADER,
777         "a band of dwarves",
778         Range(7000, 15000),
779         3
780     },
781     ExternalEnemy{
782         CreatureList(random.get(3, 5), CreatureId::IRON_GOLEM)
783             .increaseBaseLevel({{ExperienceType::MELEE, 2}}),
784         AttackBehaviourId::KILL_LEADER,
785         "an alchemist's iron golems",
786         Range(9000, 15000),
787         3
788     },
789     ExternalEnemy{
790         CreatureList(random.get(10, 13), CreatureId::DWARF).addUnique(CreatureId::DWARF_BARON)
791             .increaseBaseLevel({{ExperienceType::MELEE, 12}})
792             .addInventory({ItemType::Scroll{Effect::DestroyWalls{}}}),
793         AttackBehaviourId::KILL_LEADER,
794         "a dwarf tribe",
795         Range(12000, 25000),
796         10
797     },
798     ExternalEnemy{
799         CreatureList(random.get(4, 8), CreatureId::ARCHER),
800         AttackBehaviourId::KILL_LEADER,
801         "a patrol of archers",
802         Range(4000, 12000),
803         3
804     },
805     ExternalEnemy{
806         CreatureList(1, CreatureId::KNIGHT),
807         AttackBehaviourId::KILL_LEADER,
808         "a lonely knight",
809         Range(10000, 16000),
810         3
811     },
812     ExternalEnemy{
813         CreatureList(random.get(4, 8), CreatureId::WARRIOR)
814             .increaseBaseLevel({{ExperienceType::MELEE, 6}}),
815         AttackBehaviourId::KILL_LEADER,
816         "a group of warriors",
817         Range(6000, 12000),
818         3
819     },
820     ExternalEnemy{
821         CreatureList(random.get(12, 16), CreatureId::WARRIOR).addUnique(CreatureId::SHAMAN)
822             .increaseBaseLevel({{ExperienceType::MELEE, 14}})
823             .addInventory({ItemType::Scroll{Effect::DestroyWalls{}}}),
824         AttackBehaviourId::KILL_LEADER,
825         "an army of warriors",
826         Range(18000, 100000),
827         100
828     },
829     ExternalEnemy{
830         CreatureList(random.get(12, 16), {make_pair(2, CreatureId::KNIGHT), make_pair(1, CreatureId::ARCHER)})
831             .addUnique(CreatureId::AVATAR)
832             //.increaseBaseLevel({{ExperienceType::MELEE, 4}})
833             .addInventory({ItemType::Scroll{Effect::DestroyWalls{}}}),
834         AttackBehaviourId::KILL_LEADER,
835         "an army of knights",
836         Range(20000, 100000),
837         100
838     },
839     ExternalEnemy{
840         CreatureList(1, CreatureId::CYCLOPS),
841         AttackBehaviourId::KILL_LEADER,
842         "a cyclops",
843         Range(6000, 20000),
844         4
845     },
846     ExternalEnemy{
847         CreatureList(1, CreatureId::WITCHMAN)
848             .increaseBaseLevel({{ExperienceType::MELEE, 20}}),
849         AttackBehaviourId::KILL_LEADER,
850         "a witchman",
851         Range(15000, 40000),
852         5
853     },
854     ExternalEnemy{
855         CreatureList(1, CreatureId::MINOTAUR)
856             .increaseBaseLevel({{ExperienceType::MELEE, 20}}),
857         AttackBehaviourId::KILL_LEADER,
858         "a minotaur",
859         Range(15000, 100000),
860         100
861     },
862     ExternalEnemy{
863         CreatureList(1, CreatureId::ELEMENTALIST),
864         {AttackBehaviourId::CAMP_AND_SPAWN, CreatureFactory::elementals(TribeId::getHuman())},
865         "an elementalist",
866         Range(8000, 14000),
867         1
868     },
869     ExternalEnemy{
870         CreatureList(1, CreatureId::GREEN_DRAGON)
871             .increaseBaseLevel({{ExperienceType::MELEE, 10}}),
872         AttackBehaviourId::KILL_LEADER,
873         "a green dragon",
874         Range(15000, 40000),
875         100
876     },
877     ExternalEnemy{
878         CreatureList(1, CreatureId::RED_DRAGON)
879             .increaseBaseLevel({{ExperienceType::MELEE, 18}}),
880         AttackBehaviourId::KILL_LEADER,
881         "a red dragon",
882         Range(19000, 100000),
883         100
884     },
885     ExternalEnemy{
886         CreatureList(random.get(3, 6), {CreatureId::ADVENTURER_F, CreatureId::ADVENTURER})
887             .addInventory({ItemType::Scroll{Effect::DestroyWalls{}}})
888             .increaseBaseLevel({{ExperienceType::MELEE, 20}}),
889         AttackBehaviourId::KILL_LEADER,
890         "a group of adventurers",
891         Range(10000, 25000),
892         100
893     },
894     ExternalEnemy{
895         CreatureList(random.get(3, 6), CreatureId::OGRE)
896             .increaseBaseLevel({{ExperienceType::MELEE, 25}}),
897         AttackBehaviourId::KILL_LEADER,
898         "a pack of ogres",
899         Range(15000, 50000),
900         100
901     },
902   };
903 }
904