1 //  Copyright (C) 2007 Ole Laursen
2 //  Copyright (C) 2007, 2008, 2011, 2014, 2015, 2020 Ben Asselstine
3 //
4 //  This program is free software; you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation; either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU Library General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program; if not, write to the Free Software
16 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 //  02110-1301, USA.
18 
19 #pragma once
20 #ifndef GAME_PARAMETERS_H
21 #define GAME_PARAMETERS_H
22 
23 #include <iostream>
24 #include <sstream>
25 #include <vector>
26 #include <glibmm.h>
27 #include "defs.h"
28 #include "ucompose.hpp"
29 #include "gui/main.h"
30 
31 //! Scenario information that can be used to instantiate a new GameScenario.
32 class GameParameters
33 {
34 public:
35     struct Player
36     {
37 	enum Type { HUMAN, EASY, HARD, OFF, NETWORKED };
38 
39 	Type type;
40 	Glib::ustring name;
41 	guint32 id;
42     };
43 
44     std::vector<Player> players;
45 
46     struct Map
47     {
48 	int width, height;
49 	int grass, water, swamp, forest, hills, mountains;
50 	int cities, ruins, temples, signposts;
51     };
52 
53     Map map;
54 
55     // path to map file to load, empty if none
56     Glib::ustring map_path;
57     Glib::ustring tile_theme;
58     Glib::ustring army_theme;
59     Glib::ustring shield_theme;
60     Glib::ustring city_theme;
61 
62     bool see_opponents_stacks;
63     bool see_opponents_production;
64     enum QuestPolicy {
65       NO_QUESTING = 0, ONE_QUEST_PER_PLAYER, ONE_QUEST_PER_HERO
66     };
67     QuestPolicy play_with_quests;
68     enum QuickStartPolicy {
69       NO_QUICK_START = 0,
70       EVENLY_DIVIDED = 1,
71       AI_HEAD_START = 2
72     };
73     QuickStartPolicy quick_start;
74 
75     bool hidden_map;
76     bool diplomacy;
77 
78     enum NeutralCities {
79         AVERAGE = 0, STRONG, ACTIVE, DEFENSIVE
80     };
81     NeutralCities neutral_cities;
82     enum RazingCities {
83         NEVER = 0, ON_CAPTURE, ALWAYS
84     };
85     RazingCities razing_cities;
86 
87     enum VectoringMode {
88       VECTORING_ALWAYS_TWO_TURNS = 0,
89       VECTORING_VARIABLE_TURNS = 1,
90     };
91     VectoringMode vectoring_mode;
92 
93     enum BuildProductionMode {
94       BUILD_PRODUCTION_ALWAYS = 0,
95       BUILD_PRODUCTION_USUALLY = 1,
96       BUILD_PRODUCTION_SELDOM = 2,
97       BUILD_PRODUCTION_NEVER = 3,
98     };
99     BuildProductionMode build_production_mode;
100 
101     enum SackingMode {
102       SACKING_ALWAYS = 0,
103       SACKING_ON_CAPTURE = 1,
104       SACKING_ON_QUEST = 2,
105       SACKING_NEVER = 3,
106     };
107     SackingMode sacking_mode;
108 
109     bool cusp_of_war;
110     bool intense_combat;
111     bool military_advisor;
112     bool random_turns;
113     bool cities_can_produce_allies;
114     int difficulty;
115     Glib::ustring name;
player_type_to_player_param(guint32 type)116   static GameParameters::Player::Type player_type_to_player_param(guint32 type)
117     {
118       if (type == 0) //Player::HUMAN
119         return GameParameters::Player::HUMAN;
120       else if (type == 1) //Player::AI_FAST
121         return GameParameters::Player::EASY;
122       else if (type == 2) //Player::AI_DUMMY
123         return GameParameters::Player::HUMAN; //no equiv.
124       else if (type == 4) //Player::AI_SMART
125         return GameParameters::Player::HARD;
126       else if (type == 8)
127         return GameParameters::Player::NETWORKED;
128       return GameParameters::Player::OFF;
129     }
player_param_to_player_type(guint32 param)130   static guint32 player_param_to_player_type(guint32 param)
131     {
132       if (param == GameParameters::Player::HUMAN)
133         return 0;
134       else if (param == GameParameters::Player::EASY)
135         return 1;
136       else if (param == GameParameters::Player::HARD)
137         return 4;
138       else if (param == GameParameters::Player::NETWORKED)
139         return 8;
140       else if (param == GameParameters::Player::OFF)
141         return 0; //no equiv.
142       return 0;
143     }
player_param_string_to_player_param(Glib::ustring s)144   static GameParameters::Player::Type player_param_string_to_player_param(Glib::ustring s)
145     {
146       if (s == HUMAN_PLAYER_TYPE) return GameParameters::Player::HUMAN;
147       else if (s == EASY_PLAYER_TYPE) return GameParameters::Player::EASY;
148       else if (s == HARD_PLAYER_TYPE) return GameParameters::Player::HARD;
149       else if (s == NO_PLAYER_TYPE) return GameParameters::Player::OFF;
150       else if (s == NETWORKED_PLAYER_TYPE) return GameParameters::Player::NETWORKED;
151       else return GameParameters::Player::HUMAN;
152     }
player_param_to_string(guint32 type)153   static Glib::ustring player_param_to_string (guint32 type)
154     {
155       switch (type)
156         {
157         case GameParameters::Player::HUMAN: return HUMAN_PLAYER_TYPE;
158         case GameParameters::Player::EASY: return EASY_PLAYER_TYPE;
159         case GameParameters::Player::HARD: return HARD_PLAYER_TYPE;
160         case GameParameters::Player::OFF: return NO_PLAYER_TYPE;
161         case GameParameters::Player::NETWORKED: return NETWORKED_PLAYER_TYPE;
162         default: return NO_PLAYER_TYPE;
163         }
164     }
dump()165   std::string dump ()
166     {
167       std::stringstream out;
168 
169       out << "This map was made with the following parameters:" << std::endl;
170       out << String::ucompose ("random seed: %1",
171                                Main::instance().random_number_seed) << std::endl;
172       out << String::ucompose ("%1 players", players.size ()) << std::endl;
173       for (guint32 i = 0; i < players.size (); i++)
174         {
175           out << String::ucompose ("  player %1: type='", i);
176 
177           switch (players[i].type)
178             {
179             case GameParameters::Player::HUMAN:
180               out << "HUMAN"; break;
181             case GameParameters::Player::EASY:
182               out << "EASY"; break;
183             case GameParameters::Player::HARD:
184               out << "HARD"; break;
185             case GameParameters::Player::OFF:
186               out << "OFF"; break;
187             case GameParameters::Player::NETWORKED:
188               out << "NETWORKED"; break;
189             }
190           out << String::ucompose ("', name='%1', id=%2",
191                                    players[i].name, players[i].id) << std::endl;
192         }
193       out << String::ucompose ("map size: width=%1, height=%2",
194                                map.width, map.height) << std::endl;
195       out << "map terrain:" << std::endl;
196       out << String::ucompose
197         ("  grass=%1, water=%2, swamp=%3, forest=%4, hills=%5, mountains=%6",
198          map.grass, map.water, map.swamp, map.forest, map.hills,
199          map.mountains) << std::endl;
200       out << String::ucompose
201         ("map features: cities=%1, ruins=%2, temples=%3, signposts=%4",
202          map.cities, map.ruins, map.temples, map.signposts) << std::endl;
203       out << String::ucompose ("map path: '%1'", map_path) << std::endl;
204       out << String::ucompose ("tile theme: '%1'", tile_theme) << std::endl;
205       out << String::ucompose ("army theme: '%1'", army_theme) << std::endl;
206       out <<
207         String::ucompose ("shield theme: '%1'", shield_theme) << std::endl;
208       out << String::ucompose ("city theme: '%1'", city_theme) << std::endl;
209       out <<String::ucompose ("see opponents stacks: %1",
210                               see_opponents_stacks) << std::endl;
211       out << String::ucompose ("see opponents production: %1",
212                                see_opponents_stacks) << std::endl;
213       out << "quest policy: ";
214       switch (play_with_quests)
215         {
216         case GameParameters::QuestPolicy::NO_QUESTING:
217           out << "NO_QUESTING"; break;
218         case GameParameters::QuestPolicy::ONE_QUEST_PER_PLAYER:
219           out << "ONE_QUEST_PER_PLAYER"; break;
220         case GameParameters::QuestPolicy::ONE_QUEST_PER_HERO:
221           out << "ONE_QUEST_PER_HERO"; break;
222         }
223       out << std::endl;
224 
225       out << "quick start: ";
226       switch (quick_start)
227         {
228         case GameParameters::QuickStartPolicy::NO_QUICK_START:
229           out << "NO_QUICK_START"; break;
230         case GameParameters::QuickStartPolicy::EVENLY_DIVIDED:
231           out << "EVENLY_DIVIDED"; break;
232         case GameParameters::QuickStartPolicy::AI_HEAD_START:
233           out << "AI_HEAD_START"; break;
234         }
235       out << std::endl;
236 
237       out << String::ucompose ("hidden map: %1", hidden_map) << std::endl;
238       out << String::ucompose ("diplomacy: %1", diplomacy) << std::endl;
239 
240       out << "neutral cities: ";
241       switch (neutral_cities)
242         {
243         case GameParameters::NeutralCities::AVERAGE:
244           out << "AVERAGE"; break;
245         case GameParameters::NeutralCities::STRONG:
246           out << "STRONG"; break;
247         case GameParameters::NeutralCities::ACTIVE:
248           out << "ACTIVE"; break;
249         case GameParameters::NeutralCities::DEFENSIVE:
250           out << "DEFENSIVE"; break;
251         }
252       out << std::endl;
253 
254       out << "razing cities: ";
255       switch (razing_cities)
256         {
257         case GameParameters::RazingCities::NEVER:
258           out << "NEVER"; break;
259         case GameParameters::RazingCities::ON_CAPTURE:
260           out << "ON_CAPTURE"; break;
261         case GameParameters::RazingCities::ALWAYS:
262           out << "ALWAYS"; break;
263         }
264       out << std::endl;
265 
266       out << "vectoring mode: ";
267       switch (vectoring_mode)
268         {
269         case GameParameters::VectoringMode::VECTORING_ALWAYS_TWO_TURNS:
270           out << "VECTORING_ALWAYS_TWO_TURNS"; break;
271         case GameParameters::VectoringMode::VECTORING_VARIABLE_TURNS:
272           out << "VECTORING_VARIABLE_TURNS"; break;
273         }
274       out << std::endl;
275 
276       out << "build production mode: ";
277       switch (build_production_mode)
278         {
279         case GameParameters::BuildProductionMode::BUILD_PRODUCTION_ALWAYS:
280           out << "BUILD_PRODUCTION_ALWAYS"; break;
281         case GameParameters::BuildProductionMode::BUILD_PRODUCTION_USUALLY:
282           out << "BUILD_PRODUCTION_USUALLY"; break;
283         case GameParameters::BuildProductionMode::BUILD_PRODUCTION_SELDOM:
284           out << "BUILD_PRODUCTION_SELDOM"; break;
285         case GameParameters::BuildProductionMode::BUILD_PRODUCTION_NEVER:
286           out << "BUILD_PRODUCTION_NEVER"; break;
287         }
288       out << std::endl;
289 
290       out << "sacking mode: ";
291       switch (sacking_mode)
292         {
293         case GameParameters::SackingMode::SACKING_ALWAYS:
294           out << "SACKING_ALWAYS"; break;
295         case GameParameters::SackingMode::SACKING_ON_CAPTURE:
296           out << "SACKING_ON_CAPTURE"; break;
297         case GameParameters::SackingMode::SACKING_ON_QUEST:
298           out << "SACKING_ON_QUEST"; break;
299         case GameParameters::SackingMode::SACKING_NEVER:
300           out << "SACKING_NEVER"; break;
301         }
302       out << std::endl;
303 
304       out << String::ucompose ("cusp of war: %1", cusp_of_war) << std::endl;
305       out << String::ucompose ("intense combat: %1", intense_combat) << std::endl;
306       out << String::ucompose ("military advisor: %1",
307                                military_advisor) << std::endl;
308       out << String::ucompose ("random turns: %1", random_turns) << std::endl;
309       out << String::ucompose ("cities can produce allies: %1",
310                                      cities_can_produce_allies) << std::endl;
311       out << String::ucompose ("difficulty : %1", difficulty) << std::endl;
312       out << String::ucompose ("name: '%1'", name) << std::endl;
313       return out.str ();
314     }
315 };
316 
317 #endif
318