Merge lp:~shevonar/widelands/feature-random-tribe-and-AI into lp:widelands

Proposed by Shevonar
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
Reviewer Review Type Date Requested Status
Nasenbaer Approve
Victor Pelt Approve
Review via email: mp+75897@code.launchpad.net

Description of the change

Adds a random option for tribes and AI-tactics in singleplayer and multiplayer mode.
Fixes bug #853217

To post a comment you must log in.
Revision history for this message
Victor Pelt (victor-pelt) wrote :

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

Revision history for this message
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.

Revision history for this message
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

review: Needs Information
Revision history for this message
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)

Revision history for this message
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...

Revision history for this message
Victor Pelt (victor-pelt) wrote :

do a "make codecheck" in the build directory (you might need to do a make clean first)

Revision history for this message
Shevonar (shevonar) wrote :

I still don't get codecheck warnings but tried to fix those Victor told me.

Revision history for this message
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

review: Approve
Revision history for this message
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

Revision history for this message
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.

review: Approve
Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
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

Revision history for this message
Shevonar (shevonar) wrote :

Thank you for correcting my codecheck errors and merging.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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'
23Binary 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'
25Binary 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 /**

Subscribers

People subscribed via source and target branches

to status/vote changes: