1 /* Copyright (C) 2013-2014 Michal Brzozowski (rusolis@poczta.fm) 2 3 This file is part of KeeperRL. 4 5 KeeperRL is free software; you can redistribute it and/or modify it under the terms of the 6 GNU General Public License as published by the Free Software Foundation; either version 2 7 of the License, or (at your option) any later version. 8 9 KeeperRL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 10 even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along with this program. 14 If not, see http://www.gnu.org/licenses/ . */ 15 #pragma once 16 17 #include "move_info.h" 18 #include "task_callback.h" 19 #include "resource_id.h" 20 #include "event_listener.h" 21 #include "entity_map.h" 22 #include "minion_trait.h" 23 #include "spawn_type.h" 24 25 class CollectiveAttack; 26 class Creature; 27 class CollectiveControl; 28 class Tribe; 29 class TribeId; 30 class Level; 31 class Trigger; 32 struct AttractionInfo; 33 class MinionEquipment; 34 class TaskMap; 35 class KnownTiles; 36 class CollectiveTeams; 37 class ConstructionMap; 38 class Technology; 39 class CollectiveConfig; 40 class CostInfo; 41 struct TriggerInfo; 42 class Territory; 43 struct CollectiveName; 44 class Workshops; 45 class TileEfficiency; 46 class Zones; 47 struct ItemFetchInfo; 48 class CollectiveWarnings; 49 class Immigration; 50 51 class Collective : public TaskCallback, public UniqueEntity<Collective>, public EventListener<Collective> { 52 public: 53 static PCollective create(WLevel, TribeId, const optional<CollectiveName>&, bool discoverable); 54 void init(CollectiveConfig&&, Immigration&&); 55 void acquireInitialTech(); 56 void addCreature(WCreature, EnumSet<MinionTrait>); 57 void addCreature(PCreature, Position, EnumSet<MinionTrait>); 58 MoveInfo getMove(WCreature); 59 void setControl(PCollectiveControl); 60 void tick(); 61 void update(bool currentlyActive); 62 TribeId getTribeId() const; 63 Tribe* getTribe() const; 64 WLevel getLevel() const; 65 WModel getModel() const; 66 WGame getGame() const; 67 void addNewCreatureMessage(const vector<WCreature>&); 68 void setTask(WCreature, PTask); 69 bool hasTask(WConstCreature) const; 70 void cancelTask(WConstCreature); 71 void banishCreature(WCreature); 72 bool wasBanished(WConstCreature) const; 73 void setVillainType(VillainType); 74 bool isDiscoverable() const; 75 void setEnemyId(EnemyId); 76 VillainType getVillainType() const; 77 optional<EnemyId> getEnemyId() const; 78 WCollectiveControl getControl() const; 79 double getLocalTime() const; 80 double getGlobalTime() const; 81 82 typedef CollectiveResourceId ResourceId; 83 84 SERIALIZATION_DECL(Collective) 85 86 const vector<WCreature>& getCreatures() const; 87 bool isConquered() const; 88 89 const vector<WCreature>& getCreatures(SpawnType) const; 90 const vector<WCreature>& getCreatures(MinionTrait) const; 91 vector<WCreature> getCreaturesAnyOf(EnumSet<MinionTrait>) const; 92 bool hasTrait(WConstCreature, MinionTrait) const; 93 bool hasAnyTrait(WConstCreature, EnumSet<MinionTrait>) const; 94 void setTrait(WCreature c, MinionTrait); 95 void removeTrait(WCreature c, MinionTrait); 96 97 bool canPillage() const; 98 bool hasTradeItems() const; 99 vector<WItem> getTradeItems() const; 100 PItem buyItem(WItem); 101 vector<TriggerInfo> getTriggers(WConstCollective against) const; 102 103 double getEfficiency(WConstCreature) const; 104 WConstCreature getLeader() const; 105 WCreature getLeader(); 106 bool hasLeader() const; 107 void clearLeader(); 108 109 const Territory& getTerritory() const; 110 Territory& getTerritory(); 111 bool canClaimSquare(Position pos) const; 112 void claimSquare(Position); 113 const KnownTiles& getKnownTiles() const; 114 const TileEfficiency& getTileEfficiency() const; 115 void retire(); 116 CollectiveWarnings& getWarnings(); 117 const CollectiveConfig& getConfig() const; 118 119 bool usesEquipment(WConstCreature) const; 120 121 virtual ~Collective(); 122 123 int numResource(ResourceId) const; 124 int numResourcePlusDebt(ResourceId) const; 125 bool hasResource(const CostInfo&) const; 126 void takeResource(const CostInfo&); 127 void returnResource(const CostInfo&); 128 129 const ConstructionMap& getConstructions() const; 130 131 void setMinionTask(WConstCreature c, MinionTask task); 132 optional<MinionTask> getMinionTask(WConstCreature) const; 133 bool isMinionTaskPossible(WCreature c, MinionTask task); 134 135 vector<WItem> getAllItems(bool includeMinions = true) const; 136 vector<WItem> getAllItems(ItemPredicate predicate, bool includeMinions = true) const; 137 vector<WItem> getAllItems(ItemIndex, bool includeMinions = true) const; 138 139 vector<pair<WItem, Position>> getTrapItems(TrapType, const vector<Position>&) const; 140 141 void addTrap(Position, TrapType); 142 void removeTrap(Position); 143 bool canAddFurniture(Position, FurnitureType) const; 144 void addFurniture(Position, FurnitureType, const CostInfo&, bool noCredit); 145 void removeFurniture(Position, FurnitureLayer); 146 void destroySquare(Position, FurnitureLayer); 147 bool isPlannedTorch(Position) const; 148 bool canPlaceTorch(Position) const; 149 void removeTorch(Position); 150 void addTorch(Position); 151 Zones& getZones(); 152 const Zones& getZones() const; 153 void cancelMarkedTask(Position); 154 void orderDestruction(Position pos, const DestroyAction&); 155 double getDangerLevel() const; 156 bool isMarked(Position) const; 157 HighlightType getMarkHighlight(Position) const; 158 void setPriorityTasks(Position); 159 bool hasPriorityTasks(Position) const; 160 161 bool hasTech(TechId id) const; 162 void acquireTech(Technology*); 163 vector<Technology*> getTechnologies() const; 164 bool addKnownTile(Position); 165 166 const EntitySet<Creature>& getKills() const; 167 int getPoints() const; 168 169 MinionEquipment& getMinionEquipment(); 170 const MinionEquipment& getMinionEquipment() const; 171 optional<FurnitureType> getMissingTrainingFurniture(WConstCreature, ExperienceType) const; 172 173 Workshops& getWorkshops(); 174 const Workshops& getWorkshops() const; 175 176 Immigration& getImmigration(); 177 const Immigration& getImmigration() const; 178 179 int getPopulationSize() const; 180 int getMaxPopulation() const; 181 182 void orderConsumption(WCreature consumer, WCreature who); 183 vector<WCreature> getConsumptionTargets(WCreature consumer) const; 184 void addAttack(const CollectiveAttack&); 185 void onRansomPaid(); 186 void onExternalEnemyKilled(const string& name); 187 188 CollectiveTeams& getTeams(); 189 const CollectiveTeams& getTeams() const; 190 void freeTeamMembers(TeamId); 191 192 const optional<CollectiveName>& getName() const; 193 const TaskMap& getTaskMap() const; 194 TaskMap& getTaskMap(); 195 void updateResourceProduction(); 196 bool isItemMarked(WConstItem) const; 197 int getNumItems(ItemIndex, bool includeMinions = true) const; 198 optional<set<Position>> getStorageFor(WConstItem) const; 199 200 void addKnownVillain(WConstCollective); 201 bool isKnownVillain(WConstCollective) const; 202 void addKnownVillainLocation(WConstCollective); 203 bool isKnownVillainLocation(WConstCollective) const; 204 205 void onEvent(const GameEvent&); 206 void onPositionDiscovered(Position); 207 208 private: 209 struct Private {}; 210 211 public: 212 Collective(Private, WLevel, TribeId, const optional<CollectiveName>&); 213 214 protected: 215 // From Task::Callback 216 virtual void onAppliedItem(Position, WItem item) override; 217 virtual void onAppliedItemCancel(Position) override; 218 virtual void onConstructed(Position, FurnitureType) override; 219 virtual void onDestructed(Position, FurnitureType, const DestroyAction&) override; 220 virtual void onAppliedSquare(WCreature, Position) override; 221 virtual void onKillCancelled(WCreature) override; 222 virtual void onCopulated(WCreature who, WCreature with) override; 223 virtual bool isConstructionReachable(Position) override; 224 225 private: 226 void addCreatureInTerritory(PCreature, EnumSet<MinionTrait>); 227 void removeCreature(WCreature); 228 void onMinionKilled(WCreature victim, WCreature killer); 229 void onKilledSomeone(WCreature victim, WCreature killer); 230 231 void fetchItems(Position, const ItemFetchInfo&); 232 233 void addMoraleForKill(WConstCreature killer, WConstCreature victim); 234 void decreaseMoraleForKill(WConstCreature killer, WConstCreature victim); 235 void decreaseMoraleForBanishing(WConstCreature); 236 237 bool isItemNeeded(WConstItem) const; 238 void addProducesMessage(WConstCreature, const vector<PItem>&); 239 int getDebt(ResourceId id) const; 240 241 HeapAllocated<MinionEquipment> SERIAL(minionEquipment); 242 EnumMap<ResourceId, int> SERIAL(credit); 243 HeapAllocated<TaskMap> SERIAL(taskMap); 244 vector<TechId> SERIAL(technologies); 245 void markItem(WConstItem, WConstTask); 246 void unmarkItem(UniqueEntity<Item>::Id); 247 248 HeapAllocated<KnownTiles> SERIAL(knownTiles); 249 250 struct CurrentTaskInfo { 251 MinionTask SERIAL(task); 252 // If none then it's a one-time task. Upon allocating the task, the variable is set to a negative value, 253 // so the job immediately times out after finishing the task. 254 optional<double> SERIAL(finishTime); 255 256 SERIALIZE_ALL(task, finishTime) 257 }; 258 259 EntityMap<Creature, CurrentTaskInfo> SERIAL(currentTasks); 260 optional<Position> getTileToExplore(WConstCreature, MinionTask) const; 261 WTask getStandardTask(WCreature c); 262 PTask getEquipmentTask(WCreature c); 263 void considerHealingTask(WCreature c); 264 bool isTaskGood(WConstCreature, MinionTask, bool ignoreTaskLock = false) const; 265 void setRandomTask(WConstCreature); 266 267 void handleSurprise(Position); 268 int getTaskDuration(WConstCreature, MinionTask) const; 269 void decayMorale(); 270 vector<WCreature> SERIAL(creatures); 271 WCreature SERIAL(leader) = nullptr; 272 EnumMap<MinionTrait, vector<WCreature>> SERIAL(byTrait); 273 EnumMap<SpawnType, vector<WCreature>> SERIAL(bySpawnType); 274 PCollectiveControl SERIAL(control); 275 HeapAllocated<TribeId> SERIAL(tribe); 276 WLevel SERIAL(level) = nullptr; 277 HeapAllocated<Territory> SERIAL(territory); 278 struct AlarmInfo { 279 double SERIAL(finishTime); 280 Position SERIAL(position); 281 SERIALIZE_ALL(finishTime, position) 282 }; 283 optional<AlarmInfo> SERIAL(alarmInfo); 284 HeapAllocated<ConstructionMap> SERIAL(constructions); 285 EntityMap<Item, WConstTask> SERIAL(markedItems); 286 EntitySet<Creature> SERIAL(surrendering); 287 void updateConstructions(); 288 void handleTrapPlacementAndProduction(); 289 void scheduleAutoProduction(function<bool (WConstItem)> itemPredicate, int count); 290 void delayDangerousTasks(const vector<Position>& enemyPos, double delayTime); 291 bool isDelayed(Position); 292 unordered_map<Position, double, CustomHash<Position>> SERIAL(delayedPos); 293 vector<Position> getEnemyPositions() const; 294 double manaRemainder = 0; 295 double getKillManaScore(WConstCreature) const; 296 void addMana(double); 297 EntitySet<Creature> SERIAL(kills); 298 int SERIAL(points) = 0; 299 HeapAllocated<CollectiveTeams> SERIAL(teams); 300 HeapAllocated<optional<CollectiveName>> SERIAL(name); 301 HeapAllocated<CollectiveConfig> SERIAL(config); 302 EntitySet<Creature> SERIAL(banished); 303 VillainType SERIAL(villainType); 304 optional<EnemyId> SERIAL(enemyId); 305 unique_ptr<Workshops> SERIAL(workshops); 306 HeapAllocated<Zones> SERIAL(zones); 307 HeapAllocated<TileEfficiency> SERIAL(tileEfficiency); 308 HeapAllocated<CollectiveWarnings> SERIAL(warnings); 309 PImmigration SERIAL(immigration); 310 mutable optional<double> dangerLevelCache; 311 EntitySet<Collective> SERIAL(knownVillains); 312 EntitySet<Collective> SERIAL(knownVillainLocations); 313 set<EnemyId> SERIAL(conqueredVillains); 314 void setDiscoverable(); 315 bool SERIAL(discoverable) = false; 316 }; 317