forked from miki151/keeperrl
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcollective_warning.cpp
More file actions
136 lines (123 loc) · 5.51 KB
/
collective_warning.cpp
File metadata and controls
136 lines (123 loc) · 5.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include "stdafx.h"
#include "collective_warning.h"
#include "inventory.h"
#include "minion_trait.h"
#include "collective.h"
#include "item_factory.h"
#include "item_type.h"
#include "minion_equipment.h"
#include "creature.h"
#include "construction_map.h"
#include "collective_config.h"
#include "territory.h"
#include "item.h"
#include "minion_task.h"
SERIALIZE_DEF(CollectiveWarnings, warnings, warningTimes, lastWarningTime)
void CollectiveWarnings::setWarning(Warning w, bool state) {
warnings.set(w, state);
}
void CollectiveWarnings::disable() {
lastWarningTime = 1000000000;
}
void CollectiveWarnings::considerWarnings(WCollective col) {
setWarning(Warning::MANA, col->numResource(CollectiveResourceId::MANA) < 100);
setWarning(Warning::DIGGING, col->getTerritory().isEmpty());
setWarning(Warning::LIBRARY, !col->getTerritory().isEmpty() &&
col->getConstructions().getTotalCount(FurnitureType::BOOKCASE) == 0);
for (SpawnType spawnType : ENUM_ALL(SpawnType)) {
DormInfo info = col->getConfig().getDormInfo()[spawnType];
if (info.warning)
setWarning(*info.warning, col->getConstructions().getBuiltCount(info.bedType) <
col->getCreatures(spawnType).size());
}
considerMoraleWarning(col);
considerWeaponWarning(col);
considerTorchesWarning(col);
considerTrainingRoomWarning(col);
/* for (auto minionTask : ENUM_ALL(MinionTask)) {
auto& elem = config->getTaskInfo(minionTask);
if (!getAllSquares(elem.squares).empty() && elem.warning)
setWarning(*elem.warning, false);
}*/
}
bool CollectiveWarnings::isWarning(Warning w) const {
return warnings.contains(w);
}
void CollectiveWarnings::considerWeaponWarning(WCollective col) {
int numWeapons = col->getNumItems(ItemIndex::WEAPON);
PItem genWeapon = ItemFactory::fromId(ItemId::SWORD);
int numNeededWeapons = 0;
for (WCreature c : col->getCreatures(MinionTrait::FIGHTER))
if (col->usesEquipment(c) && col->getMinionEquipment().needsItem(c, genWeapon.get(), true))
++numNeededWeapons;
setWarning(Warning::NO_WEAPONS, numNeededWeapons > numWeapons);
}
void CollectiveWarnings::considerMoraleWarning(WCollective col) {
vector<WCreature> minions = col->getCreatures(MinionTrait::FIGHTER);
setWarning(Warning::LOW_MORALE,
minions.filter([] (WConstCreature c) { return c->getMorale() < -0.2; }).size() > minions.size() / 2);
}
void CollectiveWarnings::considerTorchesWarning(WCollective col) {
double numLit = 0;
const double unlitPen = 4;
for (auto type : col->getConfig().getRoomsNeedingLight())
for (auto pos : col->getConstructions().getBuiltPositions(type))
if (pos.getLight() < 0.8)
numLit -= unlitPen;
else
numLit += 1;
setWarning(Warning::MORE_LIGHTS, numLit < 0);
}
void CollectiveWarnings::considerTrainingRoomWarning(WCollective col) {
optional<FurnitureType> firstDummy;
for (auto dummyType : MinionTasks::getAllFurniture(MinionTask::TRAIN))
if (!firstDummy ||
*col->getConfig().getTrainingMaxLevelIncrease(dummyType) <
*col->getConfig().getTrainingMaxLevelIncrease(*firstDummy))
firstDummy = dummyType;
setWarning(Warning::TRAINING, false);
setWarning(Warning::TRAINING_UPGRADE, false);
for (auto creature : col->getCreatures())
if (auto type = col->getMissingTrainingDummy(creature)) {
if (type == firstDummy)
setWarning(Warning::TRAINING, true);
else
setWarning(Warning::TRAINING_UPGRADE, true);
}
}
const char* CollectiveWarnings::getText(Warning w) {
switch (w) {
case Warning::DIGGING: return "Dig into the mountain and start building a dungeon.";
case Warning::RESOURCE_STORAGE: return "Storage room for resources is needed.";
case Warning::EQUIPMENT_STORAGE: return "Storage room for equipment is needed.";
case Warning::LIBRARY: return "Build a library to start research.";
case Warning::BEDS: return "You need to build beds for your minions.";
case Warning::TRAINING: return "Build a training room for your minions.";
case Warning::TRAINING_UPGRADE: return "Training room upgrade needed.";
case Warning::NO_HATCHERY: return "You need to build a pigsty.";
case Warning::WORKSHOP: return "Build a workshop to produce equipment and traps.";
case Warning::NO_WEAPONS: return "You need weapons for your minions.";
case Warning::LOW_MORALE: return "Kill some enemies or summon a succubus to increase morale of your minions.";
case Warning::GRAVES: return "You need a graveyard to collect corpses";
case Warning::CHESTS: return "You need to build a treasure room.";
case Warning::NO_PRISON: return "You need to build a prison.";
case Warning::LARGER_PRISON: return "You need a larger prison.";
case Warning::TORTURE_ROOM: return "You need to build a torture room.";
// case Warning::ALTAR: return "You need to build a shrine to sacrifice.";
case Warning::MORE_CHESTS: return "You need a larger treasure room.";
case Warning::MANA: return "Conquer an enemy tribe or torture some innocent beings for more mana.";
case Warning::MORE_LIGHTS: return "Place some torches to light up your dungeon.";
}
return "";
}
const double anyWarningFrequency = 100;
const double warningFrequency = 500;
optional<const char*> CollectiveWarnings::getNextWarning(double time) {
if (time > lastWarningTime + anyWarningFrequency)
for (Warning w : ENUM_ALL(Warning))
if (isWarning(w) && (!warningTimes[w] || time > *warningTimes[w] + warningFrequency)) {
warningTimes[w] = lastWarningTime = time;
return getText(w);
}
return none;
}