1 #include "stdafx.h"
2 #include "campaign.h"
3 #include "view_id.h"
4 #include "model.h"
5 #include "progress_meter.h"
6 #include "campaign_type.h"
7 #include "player_role.h"
8 #include "villain_type.h"
9
10 SERIALIZATION_CONSTRUCTOR_IMPL(Campaign);
11
SERIALIZE_DEF(Campaign,sites,playerPos,worldName,defeated,influencePos,influenceSize,playerRole,type) const12 SERIALIZE_DEF(Campaign, sites, playerPos, worldName, defeated, influencePos, influenceSize, playerRole, type)
13
14 const Table<Campaign::SiteInfo>& Campaign::getSites() const {
15 return sites;
16 }
17
canEmbark(Vec2 pos) const18 bool Campaign::canEmbark(Vec2 pos) const {
19 if (type == CampaignType::CAMPAIGN)
20 return false;
21 switch (playerRole) {
22 case PlayerRole::ADVENTURER: return !!sites[pos].dweller;
23 case PlayerRole::KEEPER: return !sites[pos].dweller && !sites[pos].blocked;
24 }
25 }
26
getType() const27 CampaignType Campaign::getType() const {
28 return type;
29 }
30
canTravelTo(Vec2 pos) const31 bool Campaign::canTravelTo(Vec2 pos) const {
32 return (isInInfluence(pos) || playerPos == pos) && !sites[pos].isEmpty();
33 }
34
getPlayerPos() const35 optional<Vec2> Campaign::getPlayerPos() const {
36 return playerPos;
37 }
38
Campaign(Table<SiteInfo> s,CampaignType t,PlayerRole r,const string & w)39 Campaign::Campaign(Table<SiteInfo> s, CampaignType t, PlayerRole r, const string& w)
40 : sites(s), worldName(w), defeated(sites.getBounds(), false), playerRole(r), type(t) {
41 }
42
getWorldName() const43 const string& Campaign::getWorldName() const {
44 return worldName;
45 }
46
clearSite(Vec2 v)47 void Campaign::clearSite(Vec2 v) {
48 sites[v] = SiteInfo{};
49 sites[v].viewId = {ViewId::GRASS};
50 }
51
isDefeated(Vec2 pos) const52 bool Campaign::isDefeated(Vec2 pos) const {
53 return defeated[pos];
54 }
55
setDefeated(Vec2 pos)56 void Campaign::setDefeated(Vec2 pos) {
57 defeated[pos] = true;
58 refreshInfluencePos();
59 }
60
isEnemy() const61 bool Campaign::VillainInfo::isEnemy() const {
62 return type != VillainType::ALLY;
63 }
64
getDescription() const65 string Campaign::VillainInfo::getDescription() const {
66 switch (type) {
67 case VillainType::ALLY: return "ally";
68 case VillainType::MAIN: return "main villain";
69 case VillainType::LESSER: return "lesser villain";
70 case VillainType::PLAYER: return "player";
71 case VillainType::NONE:
72 FATAL << "Tried to present villain of type NONE in campaign";
73 return "player";
74 }
75 }
76
getVillain() const77 optional<Campaign::VillainInfo> Campaign::SiteInfo::getVillain() const {
78 if (dweller)
79 return dweller->getValueMaybe<VillainInfo>();
80 return none;
81 }
82
getKeeper() const83 optional<Campaign::KeeperInfo> Campaign::SiteInfo::getKeeper() const {
84 if (dweller)
85 return dweller->getValueMaybe<KeeperInfo>();
86 return none;
87 }
88
getRetired() const89 optional<Campaign::RetiredInfo> Campaign::SiteInfo::getRetired() const {
90 if (dweller)
91 return dweller->getValueMaybe<RetiredInfo>();
92 return none;
93 }
94
isEmpty() const95 bool Campaign::SiteInfo::isEmpty() const {
96 return !dweller;
97 }
98
getDwellerDescription() const99 optional<string> Campaign::SiteInfo::getDwellerDescription() const {
100 if (dweller)
101 return dweller->match(
102 [](const VillainInfo& info) { return info.name + " (" + info.getDescription() + ")"; },
103 [](const RetiredInfo& info) { return info.gameInfo.getName() + " (main villain)" ;},
104 [](const KeeperInfo&)->string { return "This is your home site"; });
105 else
106 return none;
107 }
108
getVillainType() const109 optional<VillainType> Campaign::SiteInfo::getVillainType() const {
110 if (dweller)
111 return dweller->match(
112 [](const VillainInfo& info) { return info.type; },
113 [](const RetiredInfo&) { return VillainType::MAIN; },
114 [](const KeeperInfo&) { return VillainType::PLAYER; });
115 else
116 return none;
117 }
118
getDwellerViewId() const119 optional<ViewId> Campaign::SiteInfo::getDwellerViewId() const {
120 if (dweller)
121 return dweller->match(
122 [](const VillainInfo& info) { return info.viewId; },
123 [](const RetiredInfo& info) { return info.gameInfo.getViewId(); },
124 [](const KeeperInfo& info) { return info.viewId; });
125 else
126 return none;
127 }
128
isEnemy() const129 bool Campaign::SiteInfo::isEnemy() const {
130 return getRetired() || (getVillain() && getVillain()->isEnemy());
131 }
132
setBlocked()133 void Campaign::SiteInfo::setBlocked() {
134 blocked = true;
135 viewId.push_back(Random.choose(ViewId::MAP_MOUNTAIN1, ViewId::MAP_MOUNTAIN2, ViewId::MAP_MOUNTAIN3,
136 ViewId::CANIF_TREE, ViewId::DECID_TREE));
137 }
138
isInInfluence(Vec2 pos) const139 bool Campaign::isInInfluence(Vec2 pos) const {
140 return influencePos.count(pos);
141 }
142
refreshInfluencePos()143 void Campaign::refreshInfluencePos() {
144 influencePos.clear();
145 if (!playerPos)
146 return;
147 for (double r = 1; r <= max(sites.getWidth(), sites.getHeight()); r += 0.1) {
148 for (Vec2 v : sites.getBounds())
149 if ((sites[v].getVillain() || sites[v].getRetired()) && v.distD(*playerPos) <= r)
150 influencePos.insert(v);
151 int numEnemies = 0;
152 for (Vec2 v : influencePos)
153 if (sites[v].isEnemy() && !defeated[v])
154 ++numEnemies;
155 if (numEnemies >= influenceSize)
156 break;
157 }
158 }
159
getNumNonEmpty() const160 int Campaign::getNumNonEmpty() const {
161 int ret = 0;
162 for (Vec2 v : sites.getBounds())
163 if (!sites[v].isEmpty())
164 ++ret;
165 return ret;
166 }
167
getParameters() const168 map<string, string> Campaign::getParameters() const {
169 int numMain = 0;
170 int numLesser = 0;
171 int numAlly = 0;
172 int numRetired = 0;
173 for (Vec2 v : sites.getBounds())
174 if (sites[v].getRetired())
175 ++numRetired;
176 else if (auto villain = sites[v].getVillain())
177 switch (villain->type) {
178 case VillainType::ALLY: ++numAlly; break;
179 case VillainType::MAIN: ++numMain; break;
180 case VillainType::LESSER: ++numLesser; break;
181 default: break;
182 }
183 return {
184 {"main", toString(numMain)},
185 {"lesser", toString(numLesser)},
186 {"allies", toString(numAlly)},
187 {"retired", toString(numRetired)},
188 {"player_role", EnumInfo<PlayerRole>::getString(playerRole)},
189 {"game_type", EnumInfo<CampaignType>::getString(type)},
190 };
191 }
192
getPlayerRole() const193 PlayerRole Campaign::getPlayerRole() const {
194 return playerRole;
195 }
196