Merge lp:~shevonar/widelands/feature-random-tribe-and-AI into lp:widelands
- feature-random-tribe-and-AI
- Merge into trunk
Status: | Merged | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Nasenbaer | ||||||||||||
Approved revision: | no longer in the source branch. | ||||||||||||
Merged at revision: | 5984 | ||||||||||||
Proposed branch: | lp:~shevonar/widelands/feature-random-tribe-and-AI | ||||||||||||
Merge into: | lp:widelands | ||||||||||||
Diff against target: |
571 lines (+165/-59) 11 files modified
ChangeLog (+3/-0) src/gamesettings.h (+4/-2) src/network/netclient.cc (+5/-2) src/network/netclient.h (+2/-2) src/network/nethost.cc (+39/-11) src/network/nethost.h (+2/-2) src/network/network_player_settings_backend.cc (+20/-7) src/network/network_protocol.h (+2/-1) src/wlapplication.cc (+29/-7) src/wui/multiplayersetupgroup.cc (+30/-15) src/wui/playerdescrgroup.cc (+29/-10) |
||||||||||||
To merge this branch: | bzr merge lp:~shevonar/widelands/feature-random-tribe-and-AI | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Nasenbaer | Approve | ||
Victor Pelt | Approve | ||
Review via email: mp+75897@code.launchpad.net |
Commit message
Description of the change
Adds a random option for tribes and AI-tactics in singleplayer and multiplayer mode.
Fixes bug #853217
Victor Pelt (victor-pelt) wrote : | # |
Shevonar (shevonar) wrote : | # |
Your second comment should have answered your first one ;)
If I had created a tribe called random the program would lookup its conf-file which of course does not exist and several other problems would follow. The other reason is that I always store a real existing tribe in the tribe-string for a minimal change of code (during initialization etc.) and network synchronization. To show that a random tribe/ai is chosen the bool is necessary.
Victor Pelt (victor-pelt) wrote : | # |
that's why i expected you to use the random function from random.h. i believe it's designed to solve this problem.
my first instinct would be even in your current approach it might be worth using that function. just for the simple reason that it's easy to check that nobody ever uses std::rand so it's easier to check things don't get broken.
maybe i'm just over critical here
Victor Pelt (victor-pelt) wrote : | # |
2 additional comments
1) i downloaded your patch and i got some codecheck violations please fix these before merging
2) (ok this is very minor) since all tribe names start with a capital i think it would be nice of a random tribe would start with a capital R (so Random instead of random, same goes for AI)
Shevonar (shevonar) wrote : | # |
random function: I think there shouldn't be a problem with the std::rand() because the random tribe is rolled by the host only and then broadcastet to all clients. But I will change it if you think it should be done :)
1) I don't get any codecheck violations :S So I don't know what to fix. However the problem might be that I don't get any checkcode warnings at all :(
2) I had it changed it to a lowercase letter by intention for a better distinction to the tribes. At last its not a tribe called Random but a random tribe...
Victor Pelt (victor-pelt) wrote : | # |
do a "make codecheck" in the build directory (you might need to do a make clean first)
Shevonar (shevonar) wrote : | # |
I still don't get codecheck warnings but tried to fix those Victor told me.
Victor Pelt (victor-pelt) wrote : | # |
if the codecheck issues are fixed it could be merged.
if people (like shevonar) are having problems with getting the right codecheck results maybe that needs to be looked at too, but that's a separate issue
Shevonar (shevonar) wrote : | # |
I would open a bug report for that issue but i'm still not sure if im just to stupid to get a correct setup :S
Nasenbaer (nasenbaer) wrote : | # |
Cool! The changes look complete and generally good to me. Just checked every case I could think about and worked as it should.
There are still some codecheck issues inside and "random" should be translateable, but I'll take care of it.
Thinking about all the patches you lately provided, it would be a good idea, to give you write access to lp:widelands - just the codecheck thing is a bit ugly ;)
what kind of operating system do you use?
and how do you compile? I suggest using cmake and compiling in debug mode.
Shevonar (shevonar) wrote : | # |
I usually use Windows 7 64bit with MinGW/MSYS and cmake. I also have ubuntu installed and tried to compile widelands yesterday (the same checkout as on win7 so it was a ntfs file system and that made some trubble) but the codecheck didn't tell me anything again. I have no idea what the problem is :(
I cannot use the compile.sh script on win7 because it tries to compile with Visual Studio 10 which is installed but I never compiled Widelands successfully with this program. And yes I am compiling in Debug mode.
I think i won't push to trunk till the codecheck problem is solved.
Shevonar (shevonar) wrote : | # |
Just checked it again: I think, all "random"s that are shown in the UI are translatable. The two that are not translatable are never displayed and actualy have no meaning. Could be an empty string as well.
Nasenbaer (nasenbaer) wrote : | # |
jepp sorry for the confusion, there wasn't a missing translate call - everything's fine and pushed to trunk in rev. 5984
Shevonar (shevonar) wrote : | # |
Thank you for correcting my codecheck errors and merging.
Preview Diff
1 | === modified file 'ChangeLog' |
2 | --- ChangeLog 2011-09-04 19:44:46 +0000 |
3 | +++ ChangeLog 2011-09-19 14:59:38 +0000 |
4 | @@ -9,6 +9,8 @@ |
5 | - Added a new win condition "endless game (no fog)" with completely |
6 | visible map from the beginning on. |
7 | - Added a multiplayer scenario |
8 | +- Added feature to play as a random tribe or against a random tribe or |
9 | + random AI. |
10 | - Improved dedicated server functionality: |
11 | * added functionality to save the game on the server via chat command. |
12 | * added functionality to set up a password for the server. |
13 | @@ -24,6 +26,7 @@ |
14 | - Fixed bug #795457: focus in chat window |
15 | - Fixed bug #808008: Delete outdated data when updating Widelands on Windows |
16 | - Fixed bug #805089: Check client in chat commands, when first mentioned. |
17 | +- Fixed bug #853217: start multiplayer game with all slots closed |
18 | |
19 | ### Build 16 |
20 | - Many new graphics, new sounds. |
21 | |
22 | === added file 'pics/ai_Random.png' |
23 | Binary files pics/ai_Random.png 1970-01-01 00:00:00 +0000 and pics/ai_Random.png 2011-09-19 14:59:38 +0000 differ |
24 | === added file 'pics/random.png' |
25 | Binary files pics/random.png 1970-01-01 00:00:00 +0000 and pics/random.png 2011-09-19 14:59:38 +0000 differ |
26 | === modified file 'src/gamesettings.h' |
27 | --- src/gamesettings.h 2011-08-26 08:59:21 +0000 |
28 | +++ src/gamesettings.h 2011-09-19 14:59:38 +0000 |
29 | @@ -40,7 +40,9 @@ |
30 | uint8_t initialization_index; |
31 | std::string name; |
32 | std::string tribe; |
33 | + bool random_tribe; |
34 | std::string ai; /**< Preferred AI provider for this player */ |
35 | + bool random_ai; |
36 | Widelands::TeamNumber team; |
37 | bool closeable; // only used in multiplayer scenario maps |
38 | uint8_t shared_in; // the number of the player that uses this player's starting position |
39 | @@ -136,9 +138,9 @@ |
40 | bool savegame = false) |
41 | = 0; |
42 | virtual void setPlayerState (uint8_t number, PlayerSettings::State) = 0; |
43 | - virtual void setPlayerAI (uint8_t number, std::string const &) = 0; |
44 | + virtual void setPlayerAI (uint8_t number, std::string const &, bool const random_ai = false) = 0; |
45 | virtual void nextPlayerState (uint8_t number) = 0; |
46 | - virtual void setPlayerTribe (uint8_t number, std::string const &) = 0; |
47 | + virtual void setPlayerTribe (uint8_t number, std::string const &, bool const random_tribe = false) = 0; |
48 | virtual void setPlayerInit (uint8_t number, uint8_t index) = 0; |
49 | virtual void setPlayerName (uint8_t number, std::string const &) = 0; |
50 | virtual void setPlayer (uint8_t number, PlayerSettings) = 0; |
51 | |
52 | === modified file 'src/network/netclient.cc' |
53 | --- src/network/netclient.cc 2011-08-26 08:59:21 +0000 |
54 | +++ src/network/netclient.cc 2011-09-19 14:59:38 +0000 |
55 | @@ -396,7 +396,7 @@ |
56 | // client is not allowed to do this |
57 | } |
58 | |
59 | -void NetClient::setPlayerAI(uint8_t, std::string const &) |
60 | +void NetClient::setPlayerAI(uint8_t, std::string const &, bool const random_ai) |
61 | { |
62 | // client is not allowed to do this |
63 | } |
64 | @@ -412,7 +412,7 @@ |
65 | s.send(d->sock); |
66 | } |
67 | |
68 | -void NetClient::setPlayerTribe(uint8_t number, const std::string & tribe) |
69 | +void NetClient::setPlayerTribe(uint8_t number, const std::string & tribe, bool const random_tribe) |
70 | { |
71 | if ((number != d->settings.playernum) && !m_dedicated_access) |
72 | return; |
73 | @@ -421,6 +421,7 @@ |
74 | s.Unsigned8(NETCMD_SETTING_CHANGETRIBE); |
75 | s.Unsigned8(number); |
76 | s.String(tribe); |
77 | + s.Unsigned8(random_tribe ? 1 : 0); |
78 | s.send(d->sock); |
79 | } |
80 | |
81 | @@ -562,8 +563,10 @@ |
82 | player.state = static_cast<PlayerSettings::State>(packet.Unsigned8()); |
83 | player.name = packet.String(); |
84 | player.tribe = packet.String(); |
85 | + player.random_tribe = packet.Unsigned8() == 1; |
86 | player.initialization_index = packet.Unsigned8(); |
87 | player.ai = packet.String(); |
88 | + player.random_ai = packet.Unsigned8() == 1; |
89 | player.team = packet.Unsigned8(); |
90 | player.shared_in = packet.Unsigned8(); |
91 | } |
92 | |
93 | === modified file 'src/network/netclient.h' |
94 | --- src/network/netclient.h 2011-08-26 08:59:21 +0000 |
95 | +++ src/network/netclient.h 2011-09-19 14:59:38 +0000 |
96 | @@ -76,9 +76,9 @@ |
97 | uint32_t maxplayers, |
98 | bool savegame = false); |
99 | virtual void setPlayerState (uint8_t number, PlayerSettings::State state); |
100 | - virtual void setPlayerAI (uint8_t number, std::string const & ai); |
101 | + virtual void setPlayerAI (uint8_t number, std::string const & ai, bool const random_ai = false); |
102 | virtual void nextPlayerState (uint8_t number); |
103 | - virtual void setPlayerTribe (uint8_t number, std::string const & tribe); |
104 | + virtual void setPlayerTribe (uint8_t number, std::string const & tribe, bool const random_tribe = false); |
105 | virtual void setPlayerInit (uint8_t number, uint8_t index); |
106 | virtual void setPlayerName (uint8_t number, std::string const & name); |
107 | virtual void setPlayer (uint8_t number, PlayerSettings ps); |
108 | |
109 | === modified file 'src/network/nethost.cc' |
110 | --- src/network/nethost.cc 2011-08-28 16:49:49 +0000 |
111 | +++ src/network/nethost.cc 2011-09-19 14:59:38 +0000 |
112 | @@ -152,7 +152,7 @@ |
113 | if ((*(it - 1))->name == h->settings().players.at(number).ai) |
114 | break; |
115 | } while (it != impls.end()); |
116 | - if (it == impls.end()) { |
117 | + if (settings().players.at(number).random_ai) { |
118 | setPlayerAI(number, std::string()); |
119 | setPlayerName(number, std::string()); |
120 | // Do not share a player in savegames or scenarios |
121 | @@ -173,6 +173,12 @@ |
122 | } else |
123 | newstate = PlayerSettings::stateClosed; |
124 | } |
125 | + } else if (it == impls.end()) { |
126 | + uint8_t random = (std::rand() % impls.size()); // Choose a random AI |
127 | + it = impls.begin() + random; |
128 | + setPlayerAI(number, (*it)->name, true); |
129 | + newstate = PlayerSettings::stateComputer; |
130 | + break; |
131 | } else { |
132 | setPlayerAI(number, (*it)->name); |
133 | newstate = PlayerSettings::stateComputer; |
134 | @@ -193,7 +199,7 @@ |
135 | h->setPlayerState(number, newstate, true); |
136 | } |
137 | |
138 | - virtual void setPlayerTribe(uint8_t const number, std::string const & tribe) |
139 | + virtual void setPlayerTribe(uint8_t const number, std::string const & tribe, bool const random_tribe) |
140 | { |
141 | if (number >= h->settings().players.size()) |
142 | return; |
143 | @@ -207,8 +213,9 @@ |
144 | || |
145 | settings().players.at(number).state == PlayerSettings::stateOpen // For savegame loading |
146 | ) |
147 | - h->setPlayerTribe(number, tribe); |
148 | + h->setPlayerTribe(number, tribe, random_tribe); |
149 | } |
150 | + |
151 | virtual void setPlayerTeam(uint8_t number, Widelands::TeamNumber team) |
152 | { |
153 | if (number >= h->settings().players.size()) |
154 | @@ -239,8 +246,9 @@ |
155 | h->setPlayerInit(number, index); |
156 | } |
157 | |
158 | - virtual void setPlayerAI(uint8_t number, std::string const & name) { |
159 | - h->setPlayerAI(number, name); |
160 | + virtual void setPlayerAI(uint8_t number, std::string const & name, |
161 | + bool const random_ai = false) { |
162 | + h->setPlayerAI(number, name, random_ai); |
163 | } |
164 | |
165 | virtual void setPlayerName(uint8_t const number, std::string const & name) { |
166 | @@ -1301,11 +1309,15 @@ |
167 | if (d->game) |
168 | return false; |
169 | // all players must be connected to a controller (human/ai) or be closed. |
170 | + // but not all should be closed! |
171 | + bool one_not_closed = false; |
172 | for (size_t i = 0; i < d->settings.players.size(); ++i) { |
173 | + if (d->settings.players.at(i).state != PlayerSettings::stateClosed) |
174 | + one_not_closed = true; |
175 | if (d->settings.players.at(i).state == PlayerSettings::stateOpen) |
176 | return false; |
177 | } |
178 | - return true; |
179 | + return one_not_closed; |
180 | } |
181 | |
182 | void NetHost::setMap |
183 | @@ -1356,9 +1368,11 @@ |
184 | player.state = PlayerSettings::stateOpen; |
185 | player.name = ""; |
186 | player.tribe = d->settings.tribes.at(0).name; |
187 | + player.random_tribe = false; |
188 | player.initialization_index = 0; |
189 | player.team = 0; |
190 | player.ai = ""; |
191 | + player.random_ai = false; |
192 | player.closeable = false; |
193 | player.shared_in = 0; |
194 | |
195 | @@ -1469,19 +1483,28 @@ |
196 | } |
197 | |
198 | |
199 | -void NetHost::setPlayerTribe(uint8_t const number, std::string const & tribe) |
200 | +void NetHost::setPlayerTribe(uint8_t const number, std::string const & tribe, bool const random_tribe) |
201 | { |
202 | if (number >= d->settings.players.size()) |
203 | return; |
204 | |
205 | PlayerSettings & player = d->settings.players.at(number); |
206 | |
207 | - if (player.tribe == tribe) |
208 | + if (player.tribe == tribe && player.random_tribe == random_tribe) |
209 | return; |
210 | |
211 | + std::string actual_tribe = tribe; |
212 | + player.random_tribe = random_tribe; |
213 | + |
214 | + if (random_tribe) { |
215 | + uint8_t num_tribes = d->settings.tribes.size(); |
216 | + uint8_t random = (std::rand() % num_tribes); |
217 | + actual_tribe = d->settings.tribes.at(random).name; |
218 | + } |
219 | + |
220 | container_iterate_const(std::vector<TribeBasicInfo>, d->settings.tribes, i) |
221 | if (i.current->name == player.tribe) { |
222 | - player.tribe = tribe; |
223 | + player.tribe = actual_tribe; |
224 | if (i.current->initializations.size() <= player.initialization_index) |
225 | player.initialization_index = 0; |
226 | |
227 | @@ -1530,13 +1553,14 @@ |
228 | } |
229 | |
230 | |
231 | -void NetHost::setPlayerAI(uint8_t number, std::string const & name) |
232 | +void NetHost::setPlayerAI(uint8_t number, std::string const & name, bool const random_ai) |
233 | { |
234 | if (number >= d->settings.players.size()) |
235 | return; |
236 | |
237 | PlayerSettings & player = d->settings.players.at(number); |
238 | player.ai = name; |
239 | + player.random_ai = random_ai; |
240 | |
241 | // Broadcast changes |
242 | SendPacket s; |
243 | @@ -1769,8 +1793,10 @@ |
244 | packet.Unsigned8(static_cast<uint8_t>(player.state)); |
245 | packet.String(player.name); |
246 | packet.String(player.tribe); |
247 | + packet.Unsigned8(player.random_tribe ? 1 : 0); |
248 | packet.Unsigned8(player.initialization_index); |
249 | packet.String(player.ai); |
250 | + packet.Unsigned8(player.random_ai ? 1 : 0); |
251 | packet.Unsigned8(player.team); |
252 | packet.Unsigned8(player.shared_in); |
253 | } |
254 | @@ -2430,7 +2456,9 @@ |
255 | // Only valid if the server is dedicated and the client was granted access |
256 | if (!client.dedicated_access) |
257 | throw DisconnectException(_("Client has no access to other player's settings.")); |
258 | - setPlayerTribe(num, r.String()); |
259 | + std::string tribe = r.String(); |
260 | + bool random_tribe = r.Unsigned8() == 1; |
261 | + setPlayerTribe(num, tribe, random_tribe); |
262 | } |
263 | break; |
264 | |
265 | |
266 | === modified file 'src/network/nethost.h' |
267 | --- src/network/nethost.h 2011-08-28 16:49:49 +0000 |
268 | +++ src/network/nethost.h 2011-09-19 14:59:38 +0000 |
269 | @@ -67,9 +67,9 @@ |
270 | uint32_t maxplayers, |
271 | bool savegame = false); |
272 | void setPlayerState (uint8_t number, PlayerSettings::State state, bool host = false); |
273 | - void setPlayerTribe (uint8_t number, std::string const & tribe); |
274 | + void setPlayerTribe (uint8_t number, std::string const & tribe, bool const random_tribe = false); |
275 | void setPlayerInit (uint8_t number, uint8_t index); |
276 | - void setPlayerAI (uint8_t number, std::string const & name); |
277 | + void setPlayerAI (uint8_t number, std::string const & name, bool const random_ai = false); |
278 | void setPlayerName (uint8_t number, std::string const & name); |
279 | void setPlayer (uint8_t number, PlayerSettings); |
280 | void setPlayerNumber (uint8_t number); |
281 | |
282 | === modified file 'src/network/network_player_settings_backend.cc' |
283 | --- src/network/network_player_settings_backend.cc 2011-08-25 11:27:28 +0000 |
284 | +++ src/network/network_player_settings_backend.cc 2011-09-19 14:59:38 +0000 |
285 | @@ -43,15 +43,27 @@ |
286 | return; |
287 | |
288 | if (settings.players.at(id).state != PlayerSettings::stateShared) { |
289 | - std::string const & currenttribe = settings.players.at(id).tribe; |
290 | + PlayerSettings const & player = settings.players.at(id); |
291 | + std::string const & currenttribe = player.tribe; |
292 | std::string nexttribe = settings.tribes.at(0).name; |
293 | + uint32_t num_tribes = settings.tribes.size(); |
294 | + bool random_tribe = false; |
295 | |
296 | - for (uint32_t i = 0; i < settings.tribes.size() - 1; ++i) |
297 | - if (settings.tribes[i].name == currenttribe) { |
298 | - nexttribe = settings.tribes.at(i + 1).name; |
299 | - break; |
300 | + if (player.random_tribe) { |
301 | + nexttribe = settings.tribes.at(0).name; |
302 | + } else if (player.tribe == settings.tribes.at(num_tribes - 1).name) { |
303 | + nexttribe = "Random"; |
304 | + random_tribe = true; |
305 | + } else { |
306 | + for (uint32_t i = 0; i < num_tribes - 1; ++i) { |
307 | + if (settings.tribes[i].name == currenttribe) { |
308 | + nexttribe = settings.tribes.at(i + 1).name; |
309 | + break; |
310 | + } |
311 | } |
312 | - s->setPlayerTribe(id, nexttribe); |
313 | + } |
314 | + |
315 | + s->setPlayerTribe(id, nexttribe, random_tribe); |
316 | } else { |
317 | // This button is temporarily used to select the player that uses this starting position |
318 | uint8_t sharedplr = settings.players.at(id).shared_in; |
319 | @@ -144,7 +156,8 @@ |
320 | toggle_tribe(id); |
321 | |
322 | if (shared_in_tribe[id] != settings.players.at(player.shared_in - 1).tribe) { |
323 | - s->setPlayerTribe(id, settings.players.at(player.shared_in - 1).tribe); |
324 | + s->setPlayerTribe(id, settings.players.at(player.shared_in - 1).tribe, |
325 | + settings.players.at(player.shared_in - 1).random_tribe); |
326 | shared_in_tribe[id] = settings.players.at(id).tribe; |
327 | } |
328 | } |
329 | |
330 | === modified file 'src/network/network_protocol.h' |
331 | --- src/network/network_protocol.h 2011-08-26 08:59:21 +0000 |
332 | +++ src/network/network_protocol.h 2011-09-19 14:59:38 +0000 |
333 | @@ -28,7 +28,7 @@ |
334 | * The current version of the in-game network protocol. Client and host |
335 | * protocol versions must match. |
336 | */ |
337 | - NETWORK_PROTOCOL_VERSION = 19, |
338 | + NETWORK_PROTOCOL_VERSION = 20, |
339 | |
340 | /** |
341 | * The default interval (in milliseconds) in which the host issues |
342 | @@ -271,6 +271,7 @@ |
343 | * to a different tribe. Payload is |
344 | * \li Unsigned8: player number |
345 | * \li String: name of tribe |
346 | + * \li bool: random_tribe |
347 | * |
348 | * The client must not assume that the host will accept this request. |
349 | * The host may or may not send a \ref NETCMD_SETTING_ALLPLAYERS or |
350 | |
351 | === modified file 'src/wlapplication.cc' |
352 | --- src/wlapplication.cc 2011-07-07 16:47:45 +0000 |
353 | +++ src/wlapplication.cc 2011-09-19 14:59:38 +0000 |
354 | @@ -1845,6 +1845,7 @@ |
355 | player.state = (oldplayers == 0) ? PlayerSettings::stateHuman : |
356 | PlayerSettings::stateComputer; |
357 | player.tribe = s.tribes.at(0).name; |
358 | + player.random_tribe = false; |
359 | player.initialization_index = 0; |
360 | char buf[200]; |
361 | snprintf(buf, sizeof(buf), "%s %u", _("Player"), oldplayers + 1); |
362 | @@ -1854,8 +1855,10 @@ |
363 | if (player.state == PlayerSettings::stateComputer) { |
364 | Computer_Player::ImplementationVector const & impls = |
365 | Computer_Player::getImplementations(); |
366 | - if (impls.size() > 1) |
367 | + if (impls.size() > 1) { |
368 | player.ai = impls.at(0)->name; |
369 | + player.random_ai = false; |
370 | + } |
371 | } |
372 | ++oldplayers; |
373 | } |
374 | @@ -1873,10 +1876,13 @@ |
375 | s.players[number].state = state; |
376 | } |
377 | |
378 | - virtual void setPlayerAI(uint8_t const number, std::string const & ai) { |
379 | - if (number < s.players.size()) |
380 | + virtual void setPlayerAI(uint8_t const number, std::string const & ai, bool const random_ai) { |
381 | + if (number < s.players.size()) { |
382 | s.players[number].ai = ai; |
383 | + s.players[number].random_ai = random_ai; |
384 | + } |
385 | } |
386 | + |
387 | virtual void nextPlayerState(uint8_t const number) { |
388 | if (number == s.playernum || number >= s.players.size()) |
389 | return; |
390 | @@ -1891,23 +1897,38 @@ |
391 | if ((*(it - 1))->name == s.players[number].ai) |
392 | break; |
393 | } while (it != impls.end()); |
394 | - if (it == impls.end()) |
395 | + if (s.players[number].random_ai) { |
396 | + s.players[number].random_ai = false; |
397 | it = impls.begin(); |
398 | + } else if (it == impls.end()) { |
399 | + s.players[number].random_ai = true; |
400 | + uint8_t random = (std::rand() % impls.size()); // Choose a random AI |
401 | + it = impls.begin() + random; |
402 | + } |
403 | s.players[number].ai = (*it)->name; |
404 | } |
405 | |
406 | s.players[number].state = PlayerSettings::stateComputer; |
407 | } |
408 | |
409 | - virtual void setPlayerTribe(uint8_t const number, std::string const & tribe) |
410 | + virtual void setPlayerTribe(uint8_t const number, std::string const & tribe, bool const random_tribe) |
411 | { |
412 | if (number >= s.players.size()) |
413 | return; |
414 | - |
415 | + |
416 | + std::string actual_tribe = tribe; |
417 | PlayerSettings & player = s.players[number]; |
418 | + player.random_tribe = random_tribe; |
419 | + |
420 | + if (random_tribe) { |
421 | + uint8_t num_tribes = s.tribes.size(); |
422 | + uint8_t random = (std::rand() % num_tribes); |
423 | + actual_tribe = s.tribes.at(random).name; |
424 | + } |
425 | + |
426 | container_iterate_const(std::vector<TribeBasicInfo>, s.tribes, i) |
427 | if (i.current->name == player.tribe) { |
428 | - s.players[number].tribe = tribe; |
429 | + s.players[number].tribe = actual_tribe; |
430 | if |
431 | (i.current->initializations.size() |
432 | <= |
433 | @@ -1915,6 +1936,7 @@ |
434 | player.initialization_index = 0; |
435 | } |
436 | } |
437 | + |
438 | virtual void setPlayerInit(uint8_t const number, uint8_t const index) { |
439 | if (number >= s.players.size()) |
440 | return; |
441 | |
442 | === modified file 'src/wui/multiplayersetupgroup.cc' |
443 | --- src/wui/multiplayersetupgroup.cc 2011-08-25 11:48:39 +0000 |
444 | +++ src/wui/multiplayersetupgroup.cc 2011-09-19 14:59:38 +0000 |
445 | @@ -293,8 +293,13 @@ |
446 | pic += "novalue.png"; |
447 | } else { |
448 | title = _("AI: "); |
449 | - title += _(player.ai); |
450 | - pic += "ai_" + player.ai + ".png"; |
451 | + if (player.random_ai) { |
452 | + title += _("random"); |
453 | + pic += "ai_Random.png"; |
454 | + } else { |
455 | + title += _(player.ai); |
456 | + pic += "ai_" + player.ai + ".png"; |
457 | + } |
458 | } |
459 | } else { // PlayerSettings::stateHuman |
460 | title = _("Human"); |
461 | @@ -302,20 +307,30 @@ |
462 | } |
463 | type->set_tooltip(title.c_str()); |
464 | type->set_pic(g_gr->get_picture(PicMod_UI, pic)); |
465 | - std::string tribepath("tribes/" + player.tribe); |
466 | - if (!m_tribenames[player.tribe].size()) { |
467 | - // get tribes name and picture |
468 | - Profile prof |
469 | - ((tribepath + "/conf").c_str(), 0, "tribe_" + player.tribe); |
470 | - Section & global = prof.get_safe_section("tribe"); |
471 | - m_tribenames[player.tribe] = global.get_safe_string("name"); |
472 | - m_tribepics[player.tribe] = |
473 | - g_gr->get_picture |
474 | - (PicMod_UI, |
475 | - (tribepath + "/") + global.get_safe_string("icon")); |
476 | + if (player.random_tribe) { |
477 | + std::string random = _("random"); |
478 | + if (!m_tribenames["random"].size()) { |
479 | + m_tribepics[random] = |
480 | + g_gr->get_picture(PicMod_UI, "pics/random.png"); |
481 | + } |
482 | + tribe->set_tooltip(random.c_str()); |
483 | + tribe->set_pic(m_tribepics[random]); |
484 | + } else { |
485 | + std::string tribepath("tribes/" + player.tribe); |
486 | + if (!m_tribenames[player.tribe].size()) { |
487 | + // get tribes name and picture |
488 | + Profile prof |
489 | + ((tribepath + "/conf").c_str(), 0, "tribe_" + player.tribe); |
490 | + Section & global = prof.get_safe_section("tribe"); |
491 | + m_tribenames[player.tribe] = global.get_safe_string("name"); |
492 | + m_tribepics[player.tribe] = |
493 | + g_gr->get_picture |
494 | + (PicMod_UI, |
495 | + (tribepath + "/") + global.get_safe_string("icon")); |
496 | + } |
497 | + tribe->set_tooltip(m_tribenames[player.tribe].c_str()); |
498 | + tribe->set_pic(m_tribepics[player.tribe]); |
499 | } |
500 | - tribe->set_tooltip(m_tribenames[player.tribe].c_str()); |
501 | - tribe->set_pic(m_tribepics[player.tribe]); |
502 | tribe->set_flat(false); |
503 | |
504 | if (player.team) { |
505 | |
506 | === modified file 'src/wui/playerdescrgroup.cc' |
507 | --- src/wui/playerdescrgroup.cc 2010-12-04 23:11:18 +0000 |
508 | +++ src/wui/playerdescrgroup.cc 2011-09-19 14:59:38 +0000 |
509 | @@ -170,7 +170,11 @@ |
510 | title = _("Computer"); |
511 | else { |
512 | title = _("AI: "); |
513 | - title += _(player.ai); |
514 | + if (player.random_ai) { |
515 | + title += _("random"); |
516 | + } else { |
517 | + title += _(player.ai); |
518 | + } |
519 | } |
520 | } else { // PlayerSettings::stateHuman |
521 | title = _("Human"); |
522 | @@ -184,7 +188,12 @@ |
523 | Section & global = prof.get_safe_section("tribe"); |
524 | m_tribenames[player.tribe] = global.get_safe_string("name"); |
525 | } |
526 | - d->btnPlayerTribe->set_title(m_tribenames[player.tribe]); |
527 | + if (player.random_tribe) { |
528 | + d->btnPlayerTribe->set_title(_("random")); |
529 | + } else { |
530 | + d->btnPlayerTribe->set_title(m_tribenames[player.tribe]); |
531 | + } |
532 | + |
533 | { |
534 | i18n::Textdomain td(tribepath); // for translated initialisation |
535 | container_iterate_const |
536 | @@ -256,17 +265,27 @@ |
537 | if (d->plnum >= settings.players.size()) |
538 | return; |
539 | |
540 | - std::vector<PlayerSettings> pl = settings.players; |
541 | - std::string const & currenttribe = pl.at(d->plnum).tribe; |
542 | + PlayerSettings const & player = settings.players.at(d->plnum); |
543 | + std::string const & currenttribe = player.tribe; |
544 | std::string nexttribe = settings.tribes.at(0).name; |
545 | + bool random_tribe = false; |
546 | + uint32_t num_tribes = settings.tribes.size(); |
547 | |
548 | - for (uint32_t i = 0; i < settings.tribes.size() - 1; ++i) |
549 | - if (settings.tribes[i].name == currenttribe) { |
550 | - nexttribe = settings.tribes.at(i + 1).name; |
551 | - break; |
552 | + if (player.random_tribe) { |
553 | + nexttribe = settings.tribes.at(0).name; |
554 | + } else if (player.tribe == settings.tribes.at(num_tribes - 1).name) { |
555 | + nexttribe = "Random"; |
556 | + random_tribe = true; |
557 | + } else { |
558 | + for (uint32_t i = 0; i < num_tribes - 1; ++i) { |
559 | + if (settings.tribes[i].name == currenttribe) { |
560 | + nexttribe = settings.tribes.at(i + 1).name; |
561 | + break; |
562 | + } |
563 | } |
564 | - |
565 | - d->settings->setPlayerTribe(d->plnum, nexttribe); |
566 | + } |
567 | + |
568 | + d->settings->setPlayerTribe(d->plnum, nexttribe, random_tribe); |
569 | } |
570 | |
571 | /** |
a few comments.
1) why did you pick an extra bool for the random tribe/ai. why not pick a tribe name called random that later gets changed to the 'real' tribe that is choosen
2) did you take in account that during a network game random will give different results for differnent people? i havn't tried your code but i know randomness can cause problems