Merge lp:~widelands-dev/widelands/bug-987510 into lp:widelands
- bug-987510
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 7339 | ||||
Proposed branch: | lp:~widelands-dev/widelands/bug-987510 | ||||
Merge into: | lp:widelands | ||||
Diff against target: |
3767 lines (+1236/-756) 24 files modified
src/logic/building.cc (+2/-2) src/logic/building.h (+2/-1) src/logic/cmd_luacoroutine.cc (+1/-1) src/logic/message.h (+53/-16) src/logic/message_queue.h (+21/-21) src/logic/militarysite.cc (+4/-4) src/logic/player.cc (+7/-7) src/logic/player.h (+1/-1) src/logic/playercommand.cc (+2/-2) src/logic/productionsite.cc (+1/-1) src/logic/ship.cc (+402/-377) src/logic/ship.h (+1/-2) src/logic/soldier.cc (+2/-2) src/logic/warehouse.cc (+388/-233) src/logic/worker.cc (+14/-2) src/map_io/map_players_messages_packet.cc (+14/-14) src/scripting/lua_game.cc (+14/-31) src/scripting/lua_game.h (+0/-1) src/wui/game_message_menu.cc (+283/-28) src/wui/game_message_menu.h (+14/-0) src/wui/interactive_player.cc (+1/-1) test/maps/lua_persistence.wmf/scripting/test_persistence.lua (+1/-2) test/maps/lua_testsuite.wmf/scripting/messages.lua (+0/-5) txts/README.lua (+8/-2) |
||||
To merge this branch: | bzr merge lp:~widelands-dev/widelands/bug-987510 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
GunChleoc | Needs Resubmitting | ||
Review via email: mp+236231@code.launchpad.net |
Commit message
Description of the change
Messages can be filtered by category now. Added new buttons for 5 categories and an icon on the bottom right of each message to show its message type. Added keyboard shortcuts and tooltips.
TiborB (tiborb95) wrote : | # |
TiborB (tiborb95) wrote : | # |
question about shortcuts - numbers before categories (in tooltips) indicate shortcuts? I could not make them work. Is it '$number' or 'ctrl+$number'?
GunChleoc (gunchleoc) wrote : | # |
Hotkeys work just fine with me, the toggle on/off. Is it '$number'.
1. That would make the filter harder to implement - I just went with the easy option.
2. The flag on the bottom is not the currently selected category, but the category of the current message. Maybe the tooltip should be clearer - "Type of this message: " maybe?
Hans Joachim Desserud (hjd) wrote : | # |
Speaking of the hotkeys, how do they work together with the "area bookmarks" we have currently? At the moment I can use Ctrl+number to store a location, then later go back to it by pressing the number. How will we tell whether the user wish to toggle filtering in the news window or go to another place on the map? (Might be a question discussed in the bug report rather than the review)
Please resolve the conflicts mentioned at the top.
TiborB (tiborb95) wrote : | # |
Probably hotkey does not work on my (linux) at all - but no problem now
> The flag on the bottom is not the currently selected category, but the category of the current message.
Oh yes, I did not got it, now it makes sense
Also you can consider "Type of selected message" or "Type of highlighted message"
Or even better, but probably more work for you - remove that flag on the bottom and add new column that would contain a particular flag for the message.
And yet another comment - will users understand that number on the beginning of tip is a shortcut?
GunChleoc (gunchleoc) wrote : | # |
I overlooked that we already have the hotkeys 1-9 in use. I willcome up with different hotkeys.
> Or even better, but probably more work for you - remove that flag on the
> bottom and add new column that would contain a particular flag for the
> message.
This column would need a header and eat up space - we are already tight on width there. The translations need more space than the English strings. The message titles also need a lot of space-
> And yet another comment - will users understand that number on the beginning
> of tip is a shortcut?
I thought this would be nice for the user, but if you think it is confusing, I can remove these easily without messing up translations.
TiborB (tiborb95) wrote : | # |
if the hotkeys will be like Ctrl+1, then it will be obvious that they are hotkeys and no confusion for user
wl-zocker (wl-zocker) wrote : | # |
I have not tested it in the game, but some ideas based on these comments:
- I imagined that when the news window is open, 1-5 would act on it (6-0 should do nothing). When it is not open, they work as location marker. Ctrl+number is also already used. I do not know if Widelands currently supports this. The problem is that many keys are already used (g = geologist/GoTo, s = seafaring/
- Why not simply write "Hotkey: %s"? That should avoid any confusion.
GunChleoc (gunchleoc) wrote : | # |
I found some letters that are included somewhere in the English strings for the hotkeys. Since we don't have localizable hotkeys, we will have to live with other languages not matching. But we have thet problem anyway with all hotkeys that are letters.
> - Why not simply write "Hotkey: %s"? That should avoid any confusion.
Good idea, done.
SirVer (sirver) wrote : | # |
Using the same keys is fine: the mail window will have the focus for the keyboard when it is clicked or just opened, so the keys will do what the user expects.
TiborB (tiborb95) wrote : | # |
Looks good now, and shortcuts works on my PC now :)
GunChleoc (gunchleoc) wrote : | # |
So, what are the preferred hotkeys for you guys: 0-5, or the letters I'm using right now?
TiborB (tiborb95) wrote : | # |
As letters does not match first letter of particular world, perhaps numbers could be better ( 0 for all), but personally I dont care much...
I think users might live happily with both approaches...
SirVer (sirver) wrote : | # |
+1 for numbers.
SirVer (sirver) : | # |
GunChleoc (gunchleoc) wrote : | # |
Will do the numbers then.
The discinct message types are needed elsewhere, see the diff comment for details.
GunChleoc (gunchleoc) wrote : | # |
All done. Hotkeys work as SirVer described.
Preview Diff
1 | === modified file 'pics/message_archive.png' |
2 | Binary files pics/message_archive.png 2010-01-14 18:22:23 +0000 and pics/message_archive.png 2014-12-28 17:03:29 +0000 differ |
3 | === modified file 'pics/message_archived.png' |
4 | Binary files pics/message_archived.png 2010-01-14 18:22:23 +0000 and pics/message_archived.png 2014-12-28 17:03:29 +0000 differ |
5 | === added file 'pics/message_clear_selection.png' |
6 | Binary files pics/message_clear_selection.png 1970-01-01 00:00:00 +0000 and pics/message_clear_selection.png 2014-12-28 17:03:29 +0000 differ |
7 | === modified file 'pics/message_restore.png' |
8 | Binary files pics/message_restore.png 2010-01-14 18:22:23 +0000 and pics/message_restore.png 2014-12-28 17:03:29 +0000 differ |
9 | === added file 'pics/message_selection_invert.png' |
10 | Binary files pics/message_selection_invert.png 1970-01-01 00:00:00 +0000 and pics/message_selection_invert.png 2014-12-28 17:03:29 +0000 differ |
11 | === added file 'pics/messages_warfare.png' |
12 | Binary files pics/messages_warfare.png 1970-01-01 00:00:00 +0000 and pics/messages_warfare.png 2014-12-28 17:03:29 +0000 differ |
13 | === modified file 'src/logic/building.cc' |
14 | --- src/logic/building.cc 2014-12-11 12:38:10 +0000 |
15 | +++ src/logic/building.cc 2014-12-28 17:03:29 +0000 |
16 | @@ -880,7 +880,7 @@ |
17 | */ |
18 | void Building::send_message |
19 | (Game & game, |
20 | - const std::string & msgsender, |
21 | + const Message::Type msgtype, |
22 | const std::string & title, |
23 | const std::string & description, |
24 | bool link_to_building_lifetime, |
25 | @@ -910,7 +910,7 @@ |
26 | % rt_description % description).str(); |
27 | |
28 | Message * msg = new Message |
29 | - (msgsender, game.get_gametime(), title, rt_description, |
30 | + (msgtype, game.get_gametime(), title, rt_description, |
31 | get_position(), (link_to_building_lifetime ? m_serial : 0)); |
32 | |
33 | if (throttle_time) |
34 | |
35 | === modified file 'src/logic/building.h' |
36 | --- src/logic/building.h 2014-09-14 11:31:58 +0000 |
37 | +++ src/logic/building.h 2014-12-28 17:03:29 +0000 |
38 | @@ -31,6 +31,7 @@ |
39 | #include "logic/bill_of_materials.h" |
40 | #include "logic/buildcost.h" |
41 | #include "logic/immovable.h" |
42 | +#include "logic/message.h" |
43 | #include "logic/soldier_counts.h" |
44 | #include "logic/wareworker.h" |
45 | #include "logic/widelands.h" |
46 | @@ -259,7 +260,7 @@ |
47 | |
48 | void send_message |
49 | (Game & game, |
50 | - const std::string & msgsender, |
51 | + const Message::Type msgtype, |
52 | const std::string & title, |
53 | const std::string & description, |
54 | bool link_to_building_lifetime = true, |
55 | |
56 | === modified file 'src/logic/cmd_luacoroutine.cc' |
57 | --- src/logic/cmd_luacoroutine.cc 2014-09-20 09:37:47 +0000 |
58 | +++ src/logic/cmd_luacoroutine.cc 2014-12-28 17:03:29 +0000 |
59 | @@ -50,7 +50,7 @@ |
60 | for (int i = 1; i <= game.map().get_nrplayers(); i++) { |
61 | Widelands::Message & msg = |
62 | *new Widelands::Message |
63 | - ("Game Logic", game.get_gametime(), "Lua Coroutine Failed", e.what()); |
64 | + (Message::Type::kGameLogic, game.get_gametime(), "Lua Coroutine Failed", e.what()); |
65 | game.player(i).add_message(game, msg, true); |
66 | } |
67 | game.game_controller()->set_desired_speed(0); |
68 | |
69 | === modified file 'src/logic/message.h' |
70 | --- src/logic/message.h 2014-09-19 12:54:54 +0000 |
71 | +++ src/logic/message.h 2014-12-28 17:03:29 +0000 |
72 | @@ -29,10 +29,30 @@ |
73 | namespace Widelands { |
74 | |
75 | struct Message { |
76 | - enum Status {New, Read, Archived}; |
77 | + enum class Status: uint8_t {kNew, kRead, kArchived}; |
78 | + enum class Type: uint8_t { |
79 | + kNoMessages, |
80 | + kAllMessages, |
81 | + kGameLogic, |
82 | + kGeologists, |
83 | + kGeologistsCoal, |
84 | + kGeologistsGold, |
85 | + kGeologistsGranite, |
86 | + kGeologistsIron, |
87 | + kGeologistsWater, |
88 | + kScenario, |
89 | + kSeafaring, |
90 | + kEconomy, // economy |
91 | + kEconomySiteOccupied, // economy |
92 | + kWarfare, // everything starting from here is warfare |
93 | + kWarfareSiteDefeated, |
94 | + kWarfareSiteLost, |
95 | + kWarfareUnderAttack |
96 | + }; |
97 | + |
98 | /** |
99 | * A new message to be displayed to the player |
100 | - * \param msgsender The message sender |
101 | + * \param msgtype The type of message (economy, geologists, etc.) |
102 | * \param sent_time The (game) time at which the message is sent |
103 | * \param t The message title |
104 | * \param b The message body |
105 | @@ -43,16 +63,16 @@ |
106 | * \param s The message status. Defaults to Status::New |
107 | */ |
108 | Message |
109 | - (const std::string & msgsender, |
110 | + (Message::Type msgtype, |
111 | uint32_t sent_time, |
112 | const std::string & t, |
113 | const std::string & b, |
114 | Widelands::Coords const c = Coords::null(), |
115 | Widelands::Serial ser = 0, |
116 | - Status s = New) |
117 | + Status s = Status::kNew) |
118 | : |
119 | - m_sender(msgsender), |
120 | - m_title(t), |
121 | + m_type (msgtype), |
122 | + m_title (t), |
123 | m_body (b), |
124 | m_sent (sent_time), |
125 | m_position(c), |
126 | @@ -60,18 +80,35 @@ |
127 | m_status (s) |
128 | {} |
129 | |
130 | - const std::string & sender() const {return m_sender;} |
131 | - uint32_t sent () const {return m_sent;} |
132 | - const std::string & title() const {return m_title;} |
133 | - const std::string & body () const {return m_body;} |
134 | - Widelands::Coords position() const {return m_position;} |
135 | - Widelands::Serial serial() const {return m_serial;} |
136 | - Status status () const {return m_status;} |
137 | - Status set_status(Status const s) {return m_status = s;} |
138 | + Message::Type type () const {return m_type;} |
139 | + uint32_t sent () const {return m_sent;} |
140 | + const std::string & title () const {return m_title;} |
141 | + const std::string & body () const {return m_body;} |
142 | + Widelands::Coords position() const {return m_position;} |
143 | + Widelands::Serial serial () const {return m_serial;} |
144 | + Status status () const {return m_status;} |
145 | + Status set_status(Status const s) {return m_status = s;} |
146 | + |
147 | + /** |
148 | + * Returns the main type for the message's sub type |
149 | + */ |
150 | + Message::Type message_type_category() const { |
151 | + if (m_type >= Widelands::Message::Type::kWarfare) { |
152 | + return Widelands::Message::Type::kWarfare; |
153 | + |
154 | + } else if (m_type >= Widelands::Message::Type::kEconomy && |
155 | + m_type <= Widelands::Message::Type::kEconomySiteOccupied) { |
156 | + return Widelands::Message::Type::kEconomy; |
157 | + } else if (m_type >= Widelands::Message::Type::kGeologists && |
158 | + m_type <= Widelands::Message::Type::kGeologistsWater) { |
159 | + return Widelands::Message::Type::kGeologists; |
160 | + } |
161 | + return m_type; |
162 | + } |
163 | |
164 | private: |
165 | - std::string m_sender; |
166 | - std::string m_title; |
167 | + Message::Type m_type; |
168 | + std::string m_title; |
169 | std::string m_body; |
170 | uint32_t m_sent; |
171 | Widelands::Coords m_position; |
172 | |
173 | === modified file 'src/logic/message_queue.h' |
174 | --- src/logic/message_queue.h 2014-09-19 12:54:54 +0000 |
175 | +++ src/logic/message_queue.h 2014-12-28 17:03:29 +0000 |
176 | @@ -33,9 +33,9 @@ |
177 | friend class MapPlayersMessagesPacket; |
178 | |
179 | MessageQueue() { |
180 | - m_counts[Message::New] = 0; // C++0x: |
181 | - m_counts[Message::Read] = 0; // C++0x: |
182 | - m_counts[Message::Archived] = 0; // C++0x: |
183 | + m_counts[static_cast<int>(Message::Status::kNew)] = 0; // C++0x: |
184 | + m_counts[static_cast<int>(Message::Status::kRead)] = 0; // C++0x: |
185 | + m_counts[static_cast<int>(Message::Status::kArchived)] = 0; // C++0x: |
186 | } // C++0x: |
187 | |
188 | ~MessageQueue() { |
189 | @@ -67,8 +67,8 @@ |
190 | /// \returns the number of messages with the given status. |
191 | uint32_t nr_messages(Message::Status const status) const { |
192 | assert_counts(); |
193 | - assert(status < 3); |
194 | - return m_counts[status]; |
195 | + assert(static_cast<int>(status) < 3); |
196 | + return m_counts[static_cast<int>(status)]; |
197 | } |
198 | |
199 | /// Adds the message. Takes ownership of the message. Assumes that it has |
200 | @@ -81,8 +81,8 @@ |
201 | /// The loading code calls this function to add messages form the map file. |
202 | MessageId add_message(Message & message) { |
203 | assert_counts(); |
204 | - assert(message.status() < 3); |
205 | - ++m_counts[message.status()]; |
206 | + assert(static_cast<int>(message.status()) < 3); |
207 | + ++m_counts[static_cast<int>(message.status())]; |
208 | insert |
209 | (std::map<MessageId, Message *>::end(), |
210 | std::pair<MessageId, Message *>(++m_current_message_id, &message)); |
211 | @@ -93,14 +93,14 @@ |
212 | /// Sets the status of the message with the given id, if it exists. |
213 | void set_message_status(const MessageId& id, Message::Status const status) { |
214 | assert_counts(); |
215 | - assert(status < 3); |
216 | + assert(static_cast<int>(status) < 3); |
217 | MessageQueue::iterator const it = find(id); |
218 | if (it != end()) { |
219 | Message & message = *it->second; |
220 | - assert(it->second->status() < 3); |
221 | - assert(m_counts[message.status()]); |
222 | - --m_counts[message.status ()]; |
223 | - ++m_counts[message.set_status(status)]; |
224 | + assert(static_cast<int>(it->second->status()) < 3); |
225 | + assert(m_counts[static_cast<int>(message.status())]); |
226 | + --m_counts[static_cast<int>(message.status())]; |
227 | + ++m_counts[static_cast<int>(message.set_status(status))]; |
228 | } |
229 | assert_counts(); |
230 | } |
231 | @@ -117,9 +117,9 @@ |
232 | return; |
233 | } |
234 | Message & message = *it->second; |
235 | - assert(message.status() < 3); |
236 | - assert(m_counts[message.status()]); |
237 | - --m_counts[message.status()]; |
238 | + assert(static_cast<int>(message.status()) < 3); |
239 | + assert(m_counts[static_cast<int>(message.status())]); |
240 | + --m_counts[static_cast<int>(message.status())]; |
241 | delete &message; |
242 | erase(it); |
243 | assert_counts(); |
244 | @@ -143,9 +143,9 @@ |
245 | void clear() { |
246 | assert_counts(); |
247 | m_current_message_id = MessageId::null(); |
248 | - m_counts[Message::New] = 0; |
249 | - m_counts[Message::Read] = 0; |
250 | - m_counts[Message::Archived] = 0; |
251 | + m_counts[static_cast<int>(Message::Status::kNew)] = 0; |
252 | + m_counts[static_cast<int>(Message::Status::kRead)] = 0; |
253 | + m_counts[static_cast<int>(Message::Status::kArchived)] = 0; |
254 | std::map<MessageId, Message *>::clear(); |
255 | assert_counts(); |
256 | } |
257 | @@ -161,9 +161,9 @@ |
258 | void assert_counts() const { |
259 | assert |
260 | (size() == |
261 | - m_counts[Message::New] + |
262 | - m_counts[Message::Read] + |
263 | - m_counts[Message::Archived]); |
264 | + m_counts[static_cast<int>(Message::Status::kNew)] + |
265 | + m_counts[static_cast<int>(Message::Status::kRead)] + |
266 | + m_counts[static_cast<int>(Message::Status::kArchived)]); |
267 | } |
268 | |
269 | DISALLOW_COPY_AND_ASSIGN(MessageQueue); |
270 | |
271 | === modified file 'src/logic/militarysite.cc' |
272 | --- src/logic/militarysite.cc 2014-11-30 18:49:38 +0000 |
273 | +++ src/logic/militarysite.cc 2014-12-28 17:03:29 +0000 |
274 | @@ -248,7 +248,7 @@ |
275 | if (upcast(Game, game, &egbase)) { |
276 | send_message |
277 | (*game, |
278 | - "site_occupied", |
279 | + Message::Type::kEconomySiteOccupied, |
280 | descr().descname(), |
281 | descr().m_occupied_str, |
282 | true); |
283 | @@ -845,7 +845,7 @@ |
284 | { |
285 | send_message |
286 | (game, |
287 | - "site_lost", |
288 | + Message::Type::kWarfareSiteLost, |
289 | _("Militarysite lost!"), |
290 | descr().m_defeated_enemy_str, |
291 | false); |
292 | @@ -899,7 +899,7 @@ |
293 | // Of course we should inform the victorious player as well |
294 | newsite->send_message |
295 | (game, |
296 | - "site_defeated", |
297 | + Message::Type::kWarfareSiteDefeated, |
298 | _("Enemy at site defeated!"), |
299 | newsite->descr().m_defeated_you_str, |
300 | true); |
301 | @@ -949,7 +949,7 @@ |
302 | // radius <= 5 near the current location in the last 60 seconds |
303 | send_message |
304 | (game, |
305 | - "under_attack", |
306 | + Message::Type::kWarfareUnderAttack, |
307 | _("You are under attack"), |
308 | discovered ? descr().m_aggressor_str : descr().m_attack_str, |
309 | false, |
310 | |
311 | === modified file 'src/logic/player.cc' |
312 | --- src/logic/player.cc 2014-12-16 21:39:00 +0000 |
313 | +++ src/logic/player.cc 2014-12-28 17:03:29 +0000 |
314 | @@ -292,15 +292,15 @@ |
315 | * Plays the corresponding sound when a message is received and if sound is |
316 | * enabled. |
317 | */ |
318 | -void Player::play_message_sound(const std::string & sender) { |
319 | -#define MAYBE_PLAY(a, b) if (sender == a) { \ |
320 | - g_sound_handler.play_fx(b, 200, PRIO_ALWAYS_PLAY); \ |
321 | +void Player::play_message_sound(const Message::Type & msgtype) { |
322 | +#define MAYBE_PLAY(type, file) if (msgtype == type) { \ |
323 | + g_sound_handler.play_fx(file, 200, PRIO_ALWAYS_PLAY); \ |
324 | return; \ |
325 | } |
326 | |
327 | if (g_options.pull_section("global").get_bool("sound_at_message", true)) { |
328 | - MAYBE_PLAY("site_occupied", "sound/military/site_occupied"); |
329 | - MAYBE_PLAY("under_attack", "sound/military/under_attack"); |
330 | + MAYBE_PLAY(Message::Type::kEconomySiteOccupied, "sound/military/site_occupied"); |
331 | + MAYBE_PLAY(Message::Type::kWarfareUnderAttack, "sound/military/under_attack"); |
332 | |
333 | g_sound_handler.play_fx("sound/message", 200, PRIO_ALWAYS_PLAY); |
334 | } |
335 | @@ -321,7 +321,7 @@ |
336 | // Sound & popup |
337 | if (InteractivePlayer * const iplayer = game.get_ipl()) { |
338 | if (&iplayer->player() == this) { |
339 | - play_message_sound(message.sender()); |
340 | + play_message_sound(message.type()); |
341 | if (popup) |
342 | iplayer->popup_message(id, message); |
343 | } |
344 | @@ -339,7 +339,7 @@ |
345 | Coords const position = m .position (); |
346 | for (std::pair<MessageId, Message *> tmp_message : messages()) { |
347 | if |
348 | - (tmp_message.second->sender() == m.sender() && |
349 | + (tmp_message.second->type() == m.type() && |
350 | gametime < tmp_message.second->sent() + timeout && |
351 | map.calc_distance(tmp_message.second->position(), position) <= radius) |
352 | { |
353 | |
354 | === modified file 'src/logic/player.h' |
355 | --- src/logic/player.h 2014-12-16 21:39:00 +0000 |
356 | +++ src/logic/player.h 2014-12-28 17:03:29 +0000 |
357 | @@ -521,7 +521,7 @@ |
358 | BuildingStatsVector* get_mutable_building_statistics(const BuildingIndex& i); |
359 | void update_building_statistics(Building &, NoteImmovable::Ownership ownership); |
360 | void update_team_players(); |
361 | - void play_message_sound(const std::string & sender); |
362 | + void play_message_sound(const Message::Type & msgtype); |
363 | void _enhance_or_dismantle |
364 | (Building *, BuildingIndex const index_of_new_building); |
365 | |
366 | |
367 | === modified file 'src/logic/playercommand.cc' |
368 | --- src/logic/playercommand.cc 2014-09-20 09:37:47 +0000 |
369 | +++ src/logic/playercommand.cc 2014-12-28 17:03:29 +0000 |
370 | @@ -1784,7 +1784,7 @@ |
371 | void CmdMessageSetStatusRead::execute (Game & game) |
372 | { |
373 | game.player(sender()).messages().set_message_status |
374 | - (message_id(), Message::Read); |
375 | + (message_id(), Message::Status::kRead); |
376 | } |
377 | |
378 | void CmdMessageSetStatusRead::serialize (StreamWrite & ser) |
379 | @@ -1800,7 +1800,7 @@ |
380 | void CmdMessageSetStatusArchived::execute (Game & game) |
381 | { |
382 | game.player(sender()).messages().set_message_status |
383 | - (message_id(), Message::Archived); |
384 | + (message_id(), Message::Status::kArchived); |
385 | } |
386 | |
387 | void CmdMessageSetStatusArchived::serialize (StreamWrite & ser) |
388 | |
389 | === modified file 'src/logic/productionsite.cc' |
390 | --- src/logic/productionsite.cc 2014-12-06 12:22:35 +0000 |
391 | +++ src/logic/productionsite.cc 2014-12-28 17:03:29 +0000 |
392 | @@ -925,7 +925,7 @@ |
393 | assert(!descr().out_of_resource_message().empty()); |
394 | send_message |
395 | (game, |
396 | - "produce", |
397 | + Message::Type::kEconomy, |
398 | descr().out_of_resource_title(), |
399 | descr().out_of_resource_message(), |
400 | true, |
401 | |
402 | === modified file 'src/logic/ship.cc' |
403 | --- src/logic/ship.cc 2014-12-12 22:59:39 +0000 |
404 | +++ src/logic/ship.cc 2014-12-28 17:03:29 +0000 |
405 | @@ -21,8 +21,6 @@ |
406 | |
407 | #include <memory> |
408 | |
409 | -#include <boost/format.hpp> |
410 | - |
411 | #include "base/macros.h" |
412 | #include "economy/economy.h" |
413 | #include "economy/flag.h" |
414 | @@ -51,24 +49,24 @@ |
415 | |
416 | namespace Widelands { |
417 | |
418 | -ShipDescr::ShipDescr(const char* given_name, |
419 | - const char* gdescname, |
420 | - const std::string& directory, |
421 | - Profile& prof, |
422 | - Section& global_s, |
423 | - const TribeDescr& gtribe) |
424 | - : BobDescr(MapObjectType::SHIP, given_name, gdescname, >ribe) { |
425 | - { // global options |
426 | - Section& idle_s = prof.get_safe_section("idle"); |
427 | +ShipDescr::ShipDescr |
428 | + (const char * given_name, const char * gdescname, |
429 | + const std::string & directory, Profile & prof, Section & global_s, |
430 | + const TribeDescr & gtribe) |
431 | + : |
432 | + BobDescr(MapObjectType::SHIP, given_name, gdescname, >ribe) |
433 | +{ |
434 | + { // global options |
435 | + Section & idle_s = prof.get_safe_section("idle"); |
436 | add_animation("idle", g_gr->animations().load(directory, idle_s)); |
437 | } |
438 | m_sail_anims.parse(*this, directory, prof, "sail"); |
439 | |
440 | - Section* sinking_s = prof.get_section("sinking"); |
441 | + Section * sinking_s = prof.get_section("sinking"); |
442 | if (sinking_s) |
443 | add_animation("sinking", g_gr->animations().load(directory, *sinking_s)); |
444 | |
445 | - m_capacity = global_s.get_natural("capacity", 20); |
446 | + m_capacity = global_s.get_natural("capacity", 20); |
447 | m_vision_range = global_s.get_natural("vision_range", 7); |
448 | } |
449 | |
450 | @@ -76,12 +74,18 @@ |
451 | return MOVECAPS_SWIM; |
452 | } |
453 | |
454 | -Bob& ShipDescr::create_object() const { |
455 | +Bob & ShipDescr::create_object() const { |
456 | return *new Ship(*this); |
457 | } |
458 | |
459 | -Ship::Ship(const ShipDescr& gdescr) |
460 | - : Bob(gdescr), m_window(nullptr), m_fleet(nullptr), m_economy(nullptr), m_ship_state(TRANSPORT) { |
461 | + |
462 | +Ship::Ship(const ShipDescr & gdescr) : |
463 | + Bob(gdescr), |
464 | + m_window(nullptr), |
465 | + m_fleet(nullptr), |
466 | + m_economy(nullptr), |
467 | + m_ship_state(TRANSPORT) |
468 | +{ |
469 | } |
470 | |
471 | Ship::~Ship() { |
472 | @@ -100,11 +104,11 @@ |
473 | return m_fleet; |
474 | } |
475 | |
476 | -void Ship::init_auto_task(Game& game) { |
477 | +void Ship::init_auto_task(Game & game) { |
478 | start_task_ship(game); |
479 | } |
480 | |
481 | -void Ship::init(EditorGameBase& egbase) { |
482 | +void Ship::init(EditorGameBase & egbase) { |
483 | Bob::init(egbase); |
484 | init_fleet(egbase); |
485 | } |
486 | @@ -114,15 +118,15 @@ |
487 | * The fleet code will automatically merge us into a larger |
488 | * fleet, if one is reachable. |
489 | */ |
490 | -void Ship::init_fleet(EditorGameBase& egbase) { |
491 | +void Ship::init_fleet(EditorGameBase & egbase) { |
492 | assert(get_owner() != nullptr); |
493 | - Fleet* fleet = new Fleet(*get_owner()); |
494 | + Fleet * fleet = new Fleet(*get_owner()); |
495 | fleet->add_ship(this); |
496 | fleet->init(egbase); |
497 | // fleet calls the set_fleet function appropriately |
498 | } |
499 | |
500 | -void Ship::cleanup(EditorGameBase& egbase) { |
501 | +void Ship::cleanup(EditorGameBase & egbase) { |
502 | if (m_fleet) { |
503 | m_fleet->remove_ship(egbase, this); |
504 | } |
505 | @@ -138,48 +142,52 @@ |
506 | /** |
507 | * This function is to be called only by @ref Fleet. |
508 | */ |
509 | -void Ship::set_fleet(Fleet* fleet) { |
510 | +void Ship::set_fleet(Fleet * fleet) { |
511 | m_fleet = fleet; |
512 | } |
513 | |
514 | -void Ship::wakeup_neighbours(Game& game) { |
515 | +void Ship::wakeup_neighbours(Game & game) { |
516 | FCoords position = get_position(); |
517 | Area<FCoords> area(position, 1); |
518 | - std::vector<Bob*> ships; |
519 | + std::vector<Bob *> ships; |
520 | game.map().find_bobs(area, &ships, FindBobShip()); |
521 | |
522 | - for (std::vector<Bob*>::const_iterator it = ships.begin(); it != ships.end(); ++it) { |
523 | + for |
524 | + (std::vector<Bob *>::const_iterator it = ships.begin(); |
525 | + it != ships.end(); ++it) |
526 | + { |
527 | if (*it == this) |
528 | continue; |
529 | |
530 | - static_cast<Ship*>(*it)->ship_wakeup(game); |
531 | + static_cast<Ship *>(*it)->ship_wakeup(game); |
532 | } |
533 | } |
534 | |
535 | + |
536 | /** |
537 | * Standard behaviour of ships. |
538 | * |
539 | * ivar1 = helper flag for coordination of mutual evasion of ships |
540 | */ |
541 | const Bob::Task Ship::taskShip = { |
542 | - "ship", |
543 | - static_cast<Bob::Ptr>(&Ship::ship_update), |
544 | - nullptr, |
545 | - nullptr, |
546 | - true // unique task |
547 | + "ship", |
548 | + static_cast<Bob::Ptr>(&Ship::ship_update), |
549 | + nullptr, |
550 | + nullptr, |
551 | + true // unique task |
552 | }; |
553 | |
554 | -void Ship::start_task_ship(Game& game) { |
555 | +void Ship::start_task_ship(Game & game) { |
556 | push_task(game, taskShip); |
557 | top_state().ivar1 = 0; |
558 | } |
559 | |
560 | -void Ship::ship_wakeup(Game& game) { |
561 | +void Ship::ship_wakeup(Game & game) { |
562 | if (get_state(taskShip)) |
563 | send_signal(game, "wakeup"); |
564 | } |
565 | |
566 | -void Ship::ship_update(Game& game, Bob::State& state) { |
567 | +void Ship::ship_update(Game & game, Bob::State & state) { |
568 | // Handle signals |
569 | std::string signal = get_signal(); |
570 | if (!signal.empty()) { |
571 | @@ -203,43 +211,44 @@ |
572 | } |
573 | |
574 | switch (m_ship_state) { |
575 | - case TRANSPORT: |
576 | - if (ship_update_transport(game, state)) |
577 | - return; |
578 | - break; |
579 | - case EXP_FOUNDPORTSPACE: |
580 | - case EXP_SCOUTING: |
581 | - case EXP_WAITING: |
582 | - ship_update_expedition(game, state); |
583 | - break; |
584 | - case EXP_COLONIZING: |
585 | - break; |
586 | - case SINK_REQUEST: |
587 | - if (descr().is_animation_known("sinking")) { |
588 | - m_ship_state = SINK_ANIMATION; |
589 | - start_task_idle(game, descr().get_animation("sinking"), 3000); |
590 | - return; |
591 | - } |
592 | - log("Oh no... this ship has no sinking animation :(!\n"); |
593 | - // fall trough |
594 | - case SINK_ANIMATION: |
595 | - // The sink animation has been played, so finally remove the ship from the map |
596 | - pop_task(game); |
597 | - remove(game); |
598 | - return; |
599 | - default: |
600 | - assert(false); // never here |
601 | + case TRANSPORT: |
602 | + if (ship_update_transport(game, state)) |
603 | + return; |
604 | + break; |
605 | + case EXP_FOUNDPORTSPACE: |
606 | + case EXP_SCOUTING: |
607 | + case EXP_WAITING: |
608 | + ship_update_expedition(game, state); |
609 | + break; |
610 | + case EXP_COLONIZING: |
611 | + break; |
612 | + case SINK_REQUEST: |
613 | + if (descr().is_animation_known("sinking")) { |
614 | + m_ship_state = SINK_ANIMATION; |
615 | + start_task_idle(game, descr().get_animation("sinking"), 3000); |
616 | + return; |
617 | + } |
618 | + log("Oh no... this ship has no sinking animation :(!\n"); |
619 | + // fall trough |
620 | + case SINK_ANIMATION: |
621 | + // The sink animation has been played, so finally remove the ship from the map |
622 | + pop_task(game); |
623 | + remove(game); |
624 | + return; |
625 | + default: |
626 | + assert(false); // never here |
627 | } |
628 | |
629 | // if the real update function failed (e.g. nothing to transport), the ship goes idle |
630 | ship_update_idle(game, state); |
631 | } |
632 | |
633 | + |
634 | /// updates a ships tasks in transport mode \returns false if failed to update tasks |
635 | -bool Ship::ship_update_transport(Game& game, Bob::State&) { |
636 | - Map& map = game.map(); |
637 | +bool Ship::ship_update_transport(Game & game, Bob::State &) { |
638 | + Map & map = game.map(); |
639 | |
640 | - PortDock* dst = get_destination(game); |
641 | + PortDock * dst = get_destination(game); |
642 | if (!dst) { |
643 | molog("ship_update: No destination anymore.\n"); |
644 | if (m_items.empty()) |
645 | @@ -268,7 +277,7 @@ |
646 | |
647 | molog("ship_update: Go to dock %u\n", dst->serial()); |
648 | |
649 | - PortDock* lastdock = m_lastdock.get(game); |
650 | + PortDock * lastdock = m_lastdock.get(game); |
651 | if (lastdock && lastdock != dst) { |
652 | molog("ship_update: Have lastdock %u\n", lastdock->serial()); |
653 | |
654 | @@ -323,9 +332,10 @@ |
655 | return true; |
656 | } |
657 | |
658 | + |
659 | /// updates a ships tasks in expedition mode |
660 | -void Ship::ship_update_expedition(Game& game, Bob::State&) { |
661 | - Map& map = game.map(); |
662 | +void Ship::ship_update_expedition(Game & game, Bob::State &) { |
663 | + Map & map = game.map(); |
664 | |
665 | assert(m_expedition); |
666 | |
667 | @@ -333,30 +343,30 @@ |
668 | FCoords position = get_position(); |
669 | for (Direction dir = FIRST_DIRECTION; dir <= LAST_DIRECTION; ++dir) { |
670 | m_expedition->swimable[dir - 1] = |
671 | - map.get_neighbour(position, dir).field->nodecaps() & MOVECAPS_SWIM; |
672 | + map.get_neighbour(position, dir).field->nodecaps() & MOVECAPS_SWIM; |
673 | } |
674 | |
675 | if (m_ship_state == EXP_SCOUTING) { |
676 | // Check surrounding fields for port buildspaces |
677 | - std::unique_ptr<std::list<Coords>> temp_port_buildspaces(new std::list<Coords>()); |
678 | - MapRegion<Area<Coords>> mr(map, Area<Coords>(position, descr().vision_range())); |
679 | + std::unique_ptr<std::list<Coords> > temp_port_buildspaces(new std::list<Coords>()); |
680 | + MapRegion<Area<Coords> > mr(map, Area<Coords>(position, descr().vision_range())); |
681 | bool new_port_space = false; |
682 | do { |
683 | if (map.is_port_space(mr.location())) { |
684 | FCoords fc = map.get_fcoords(mr.location()); |
685 | |
686 | - // Check whether the maximum theoretical possible NodeCap of the field is of the size |
687 | - // big |
688 | + // Check whether the maximum theoretical possible NodeCap of the field is of the size big |
689 | // and whether it can theoretically be a port space |
690 | - if ((map.get_max_nodecaps(game.world(), fc) & BUILDCAPS_SIZEMASK) != BUILDCAPS_BIG || |
691 | - map.find_portdock(fc).empty()) { |
692 | + if |
693 | + ((map.get_max_nodecaps(game.world(), fc) & BUILDCAPS_SIZEMASK) != BUILDCAPS_BIG |
694 | + || |
695 | + map.find_portdock(fc).empty()) |
696 | + { |
697 | continue; |
698 | } |
699 | |
700 | - // NOTE This is the place to handle enemy territory and "clearing a port space from the |
701 | - // enemy". |
702 | - // NOTE There is a simple check for the current land owner to avoid placement of ports |
703 | - // into enemy |
704 | + // NOTE This is the place to handle enemy territory and "clearing a port space from the enemy". |
705 | + // NOTE There is a simple check for the current land owner to avoid placement of ports into enemy |
706 | // NOTE territory, as "clearing" is not yet implemented. |
707 | // NOTE further it checks, whether there is a Player_immovable on one of the fields. |
708 | // TODO(unknown): handle this more gracefully concering opposing players |
709 | @@ -368,7 +378,7 @@ |
710 | invalid = true; |
711 | continue; |
712 | } |
713 | - BaseImmovable* baim = coord.field->get_immovable(); |
714 | + BaseImmovable * baim = coord.field->get_immovable(); |
715 | if (baim) |
716 | if (is_a(PlayerImmovable, baim)) { |
717 | invalid = true; |
718 | @@ -377,60 +387,60 @@ |
719 | |
720 | // Check all neighboured fields that will be used by the port |
721 | switch (step) { |
722 | - case 0: |
723 | - map.get_ln(fc, &coord); |
724 | - break; |
725 | - case 1: |
726 | - map.get_tln(fc, &coord); |
727 | - break; |
728 | - case 2: |
729 | - map.get_trn(fc, &coord); |
730 | - break; |
731 | - case 3: |
732 | - // Flag coordinate |
733 | - map.get_brn(fc, &coord); |
734 | - break; |
735 | - default: |
736 | - break; |
737 | + case 0: |
738 | + map.get_ln(fc, &coord); |
739 | + break; |
740 | + case 1: |
741 | + map.get_tln(fc, &coord); |
742 | + break; |
743 | + case 2: |
744 | + map.get_trn(fc, &coord); |
745 | + break; |
746 | + case 3: |
747 | + // Flag coordinate |
748 | + map.get_brn(fc, &coord); |
749 | + break; |
750 | + default: |
751 | + break; |
752 | } |
753 | } |
754 | // Now check whether there is a flag in the surroundings of the flag position |
755 | FCoords neighb; |
756 | map.get_ln(coord, &neighb); |
757 | for (uint8_t step = 0; !invalid && step < 5; ++step) { |
758 | - BaseImmovable* baim = neighb.field->get_immovable(); |
759 | + BaseImmovable * baim = neighb.field->get_immovable(); |
760 | if (baim) |
761 | if (is_a(Flag, baim)) { |
762 | invalid = true; |
763 | continue; |
764 | } |
765 | - // Check all neighboured fields but not the one already checked for a |
766 | - // PlayerImmovable. |
767 | + // Check all neighboured fields but not the one already checked for a PlayerImmovable. |
768 | switch (step) { |
769 | - case 0: |
770 | - map.get_bln(coord, &neighb); |
771 | - break; |
772 | - case 1: |
773 | - map.get_brn(coord, &neighb); |
774 | - break; |
775 | - case 2: |
776 | - map.get_rn(coord, &neighb); |
777 | - break; |
778 | - case 3: |
779 | - map.get_trn(coord, &neighb); |
780 | - break; |
781 | - default: |
782 | - break; |
783 | + case 0: |
784 | + map.get_bln(coord, &neighb); |
785 | + break; |
786 | + case 1: |
787 | + map.get_brn(coord, &neighb); |
788 | + break; |
789 | + case 2: |
790 | + map.get_rn(coord, &neighb); |
791 | + break; |
792 | + case 3: |
793 | + map.get_trn(coord, &neighb); |
794 | + break; |
795 | + default: |
796 | + break; |
797 | } |
798 | } |
799 | if (invalid) |
800 | continue; |
801 | |
802 | bool pbs_saved = false; |
803 | - for (std::list<Coords>::const_iterator it = |
804 | - m_expedition->seen_port_buildspaces->begin(); |
805 | - it != m_expedition->seen_port_buildspaces->end() && !pbs_saved; |
806 | - ++it) { |
807 | + for |
808 | + (std::list<Coords>::const_iterator it = m_expedition->seen_port_buildspaces->begin(); |
809 | + it != m_expedition->seen_port_buildspaces->end() && !pbs_saved; |
810 | + ++it) |
811 | + { |
812 | // Check if the ship knows this port space already from its last check |
813 | if (*it == mr.location()) { |
814 | temp_port_buildspaces->push_back(mr.location()); |
815 | @@ -449,13 +459,13 @@ |
816 | // Send a message to the player, that a new port space was found |
817 | std::string msg_head = _("Port Space Found"); |
818 | std::string msg_body = _("An expedition ship found a new port build space."); |
819 | - send_message(game, "exp_port_space", msg_head, msg_body, "port.png"); |
820 | + send_message(game, msg_head, msg_body, "port.png"); |
821 | } |
822 | m_expedition->seen_port_buildspaces.swap(temp_port_buildspaces); |
823 | } |
824 | } |
825 | |
826 | -void Ship::ship_update_idle(Game& game, Bob::State& state) { |
827 | +void Ship::ship_update_idle(Game & game, Bob::State & state) { |
828 | if (state.ivar1) { |
829 | // We've just completed one step, so give neighbours |
830 | // a chance to move away first |
831 | @@ -465,221 +475,214 @@ |
832 | return; |
833 | } |
834 | |
835 | - // If we are waiting for the next transport job, check if we should move away from ships and |
836 | - // shores |
837 | + // If we are waiting for the next transport job, check if we should move away from ships and shores |
838 | switch (m_ship_state) { |
839 | - case TRANSPORT: { |
840 | - FCoords position = get_position(); |
841 | - Map& map = game.map(); |
842 | - unsigned int dirs[LAST_DIRECTION + 1]; |
843 | - unsigned int dirmax = 0; |
844 | - |
845 | - for (Direction dir = 0; dir <= LAST_DIRECTION; ++dir) { |
846 | - FCoords node = dir ? map.get_neighbour(position, dir) : position; |
847 | - dirs[dir] = node.field->nodecaps() & MOVECAPS_WALK ? 10 : 0; |
848 | - |
849 | - Area<FCoords> area(node, 0); |
850 | - std::vector<Bob*> ships; |
851 | - map.find_bobs(area, &ships, FindBobShip()); |
852 | - |
853 | - for (std::vector<Bob*>::const_iterator it = ships.begin(); it != ships.end(); ++it) { |
854 | - if (*it == this) |
855 | - continue; |
856 | - |
857 | - dirs[dir] += 3; |
858 | - } |
859 | - |
860 | - dirmax = std::max(dirmax, dirs[dir]); |
861 | - } |
862 | - |
863 | - if (dirmax) { |
864 | - unsigned int prob[LAST_DIRECTION + 1]; |
865 | - unsigned int totalprob = 0; |
866 | - |
867 | - // The probability for moving into a given direction is also |
868 | - // affected by the "close" directions. |
869 | + case TRANSPORT: { |
870 | + FCoords position = get_position(); |
871 | + Map & map = game.map(); |
872 | + unsigned int dirs[LAST_DIRECTION + 1]; |
873 | + unsigned int dirmax = 0; |
874 | + |
875 | for (Direction dir = 0; dir <= LAST_DIRECTION; ++dir) { |
876 | - prob[dir] = 10 * dirmax - 10 * dirs[dir]; |
877 | - |
878 | - if (dir > 0) { |
879 | - unsigned int delta = |
880 | - std::min(prob[dir], dirs[(dir % 6) + 1] + dirs[1 + ((dir - 1) % 6)]); |
881 | - prob[dir] -= delta; |
882 | - } |
883 | - |
884 | - totalprob += prob[dir]; |
885 | - } |
886 | - |
887 | - if (totalprob == 0) { |
888 | - start_task_idle(game, descr().main_animation(), 1500); |
889 | - return; |
890 | - } |
891 | - |
892 | - unsigned int rnd = game.logic_rand() % totalprob; |
893 | - Direction dir = 0; |
894 | - while (rnd >= prob[dir]) { |
895 | - rnd -= prob[dir]; |
896 | - ++dir; |
897 | - } |
898 | - |
899 | - if (dir == 0 || dir > LAST_DIRECTION) { |
900 | - start_task_idle(game, descr().main_animation(), 1500); |
901 | - return; |
902 | - } |
903 | - |
904 | - FCoords neighbour = map.get_neighbour(position, dir); |
905 | - if (!(neighbour.field->nodecaps() & MOVECAPS_SWIM)) { |
906 | - start_task_idle(game, descr().main_animation(), 1500); |
907 | - return; |
908 | - } |
909 | - |
910 | - state.ivar1 = 1; |
911 | - start_task_move(game, dir, descr().get_sail_anims(), false); |
912 | + FCoords node = dir ? map.get_neighbour(position, dir) : position; |
913 | + dirs[dir] = node.field->nodecaps() & MOVECAPS_WALK ? 10 : 0; |
914 | + |
915 | + Area<FCoords> area(node, 0); |
916 | + std::vector<Bob *> ships; |
917 | + map.find_bobs(area, &ships, FindBobShip()); |
918 | + |
919 | + for (std::vector<Bob *>::const_iterator it = ships.begin(); it != ships.end(); ++it) { |
920 | + if (*it == this) |
921 | + continue; |
922 | + |
923 | + dirs[dir] += 3; |
924 | + } |
925 | + |
926 | + dirmax = std::max(dirmax, dirs[dir]); |
927 | + } |
928 | + |
929 | + if (dirmax) { |
930 | + unsigned int prob[LAST_DIRECTION + 1]; |
931 | + unsigned int totalprob = 0; |
932 | + |
933 | + // The probability for moving into a given direction is also |
934 | + // affected by the "close" directions. |
935 | + for (Direction dir = 0; dir <= LAST_DIRECTION; ++dir) { |
936 | + prob[dir] = 10 * dirmax - 10 * dirs[dir]; |
937 | + |
938 | + if (dir > 0) { |
939 | + unsigned int delta = std::min(prob[dir], dirs[(dir % 6) + 1] + dirs[1 + ((dir - 1) % 6)]); |
940 | + prob[dir] -= delta; |
941 | + } |
942 | + |
943 | + totalprob += prob[dir]; |
944 | + } |
945 | + |
946 | + if (totalprob == 0) { |
947 | + start_task_idle(game, descr().main_animation(), 1500); |
948 | + return; |
949 | + } |
950 | + |
951 | + unsigned int rnd = game.logic_rand() % totalprob; |
952 | + Direction dir = 0; |
953 | + while (rnd >= prob[dir]) { |
954 | + rnd -= prob[dir]; |
955 | + ++dir; |
956 | + } |
957 | + |
958 | + if (dir == 0 || dir > LAST_DIRECTION) { |
959 | + start_task_idle(game, descr().main_animation(), 1500); |
960 | + return; |
961 | + } |
962 | + |
963 | + FCoords neighbour = map.get_neighbour(position, dir); |
964 | + if (!(neighbour.field->nodecaps() & MOVECAPS_SWIM)) { |
965 | + start_task_idle(game, descr().main_animation(), 1500); |
966 | + return; |
967 | + } |
968 | + |
969 | + state.ivar1 = 1; |
970 | + start_task_move(game, dir, descr().get_sail_anims(), false); |
971 | + return; |
972 | + } |
973 | + // No desire to move around, so sleep |
974 | + start_task_idle(game, descr().main_animation(), -1); |
975 | return; |
976 | } |
977 | - // No desire to move around, so sleep |
978 | - start_task_idle(game, descr().main_animation(), -1); |
979 | - return; |
980 | - } |
981 | - case EXP_SCOUTING: { |
982 | - if (m_expedition->island_exploration) { // Exploration of the island |
983 | - if (exp_close_to_coast()) { |
984 | - if (m_expedition->direction == 0) { |
985 | - // Make sure we know the location of the coast and use it as initial direction we |
986 | - // come from |
987 | - m_expedition->direction = WALK_SE; |
988 | - for (uint8_t secure = 0; exp_dir_swimable(m_expedition->direction); ++secure) { |
989 | - assert(secure < 6); |
990 | - m_expedition->direction = get_cw_neighbour(m_expedition->direction); |
991 | + case EXP_SCOUTING: { |
992 | + if (m_expedition->island_exploration) { // Exploration of the island |
993 | + if (exp_close_to_coast()) { |
994 | + if (m_expedition->direction == 0) { |
995 | + // Make sure we know the location of the coast and use it as initial direction we come from |
996 | + m_expedition->direction = WALK_SE; |
997 | + for (uint8_t secure = 0; exp_dir_swimable(m_expedition->direction); ++secure) { |
998 | + assert(secure < 6); |
999 | + m_expedition->direction = get_cw_neighbour(m_expedition->direction); |
1000 | + } |
1001 | + m_expedition->direction = get_backward_dir(m_expedition->direction); |
1002 | + // Save the position - this is where we start |
1003 | + m_expedition->exploration_start = get_position(); |
1004 | + } else { |
1005 | + // Check whether the island was completely surrounded |
1006 | + if (get_position() == m_expedition->exploration_start) { |
1007 | + std::string msg_head = _("Island Circumnavigated"); |
1008 | + std::string msg_body = _("An expedition ship sailed around its" |
1009 | + " island without any events."); |
1010 | + send_message(game, msg_head, msg_body, |
1011 | + "ship_explore_island_cw.png"); |
1012 | + m_ship_state = EXP_WAITING; |
1013 | + return start_task_idle(game, descr().main_animation(), 1500); |
1014 | + } |
1015 | } |
1016 | + // The ship is supposed to follow the coast as close as possible, therefore the check for |
1017 | + // a swimable field begins at the neighbour field of the direction we came from. |
1018 | m_expedition->direction = get_backward_dir(m_expedition->direction); |
1019 | - // Save the position - this is where we start |
1020 | - m_expedition->exploration_start = get_position(); |
1021 | - } else { |
1022 | - // Check whether the island was completely surrounded |
1023 | - if (get_position() == m_expedition->exploration_start) { |
1024 | - std::string msg_head = _("Island Circumnavigated"); |
1025 | - std::string msg_body = _("An expedition ship sailed around its" |
1026 | - " island without any events."); |
1027 | - send_message( |
1028 | - game, "exp_island", msg_head, msg_body, "ship_explore_island_cw.png"); |
1029 | - m_ship_state = EXP_WAITING; |
1030 | - return start_task_idle(game, descr().main_animation(), 1500); |
1031 | - } |
1032 | - } |
1033 | - // The ship is supposed to follow the coast as close as possible, therefore the check |
1034 | - // for |
1035 | - // a swimable field begins at the neighbour field of the direction we came from. |
1036 | - m_expedition->direction = get_backward_dir(m_expedition->direction); |
1037 | - if (m_expedition->clockwise) { |
1038 | - do { |
1039 | - m_expedition->direction = get_ccw_neighbour(m_expedition->direction); |
1040 | - } while (!exp_dir_swimable(m_expedition->direction)); |
1041 | - } else { |
1042 | - do { |
1043 | - m_expedition->direction = get_cw_neighbour(m_expedition->direction); |
1044 | - } while (!exp_dir_swimable(m_expedition->direction)); |
1045 | - } |
1046 | - state.ivar1 = 1; |
1047 | - return start_task_move(game, m_expedition->direction, descr().get_sail_anims(), false); |
1048 | - } else { |
1049 | - // The ship got the command to scout around an island, but is not close to any island |
1050 | - // Most likely the command was send as the ship was on an exploration and just leaving |
1051 | - // the island - therefore we try to find the island again. |
1052 | - FCoords position = get_position(); |
1053 | - Map& map = game.map(); |
1054 | - for (uint8_t dir = FIRST_DIRECTION; dir <= LAST_DIRECTION; ++dir) { |
1055 | - FCoords neighbour = map.get_neighbour(position, dir); |
1056 | - for (uint8_t sur = FIRST_DIRECTION; sur <= LAST_DIRECTION; ++sur) |
1057 | - if (!(map.get_neighbour(neighbour, sur).field->nodecaps() & MOVECAPS_SWIM)) { |
1058 | - // Okay we found the next coast, so now the ship should go there. |
1059 | - // However, we do neither save the position as starting position, nor do we |
1060 | - // save |
1061 | - // the direction we currently go. So the ship can start exploring normally |
1062 | - state.ivar1 = 1; |
1063 | - return start_task_move(game, dir, descr().get_sail_anims(), false); |
1064 | - } |
1065 | - } |
1066 | - // if we are here, it seems something really strange happend. |
1067 | - log("WARNING: ship was not able to start exploration. Entering WAIT mode."); |
1068 | + if (m_expedition->clockwise) { |
1069 | + do { |
1070 | + m_expedition->direction = get_ccw_neighbour(m_expedition->direction); |
1071 | + } while (!exp_dir_swimable(m_expedition->direction)); |
1072 | + } else { |
1073 | + do { |
1074 | + m_expedition->direction = get_cw_neighbour(m_expedition->direction); |
1075 | + } while (!exp_dir_swimable(m_expedition->direction)); |
1076 | + } |
1077 | + state.ivar1 = 1; |
1078 | + return start_task_move(game, m_expedition->direction, descr().get_sail_anims(), false); |
1079 | + } else { |
1080 | + // The ship got the command to scout around an island, but is not close to any island |
1081 | + // Most likely the command was send as the ship was on an exploration and just leaving |
1082 | + // the island - therefore we try to find the island again. |
1083 | + FCoords position = get_position(); |
1084 | + Map & map = game.map(); |
1085 | + for (uint8_t dir = FIRST_DIRECTION; dir <= LAST_DIRECTION; ++dir) { |
1086 | + FCoords neighbour = map.get_neighbour(position, dir); |
1087 | + for (uint8_t sur = FIRST_DIRECTION; sur <= LAST_DIRECTION; ++sur) |
1088 | + if (!(map.get_neighbour(neighbour, sur).field->nodecaps() & MOVECAPS_SWIM)) { |
1089 | + // Okay we found the next coast, so now the ship should go there. |
1090 | + // However, we do neither save the position as starting position, nor do we save |
1091 | + // the direction we currently go. So the ship can start exploring normally |
1092 | + state.ivar1 = 1; |
1093 | + return start_task_move(game, dir, descr().get_sail_anims(), false); |
1094 | + } |
1095 | + } |
1096 | + // if we are here, it seems something really strange happend. |
1097 | + log("WARNING: ship was not able to start exploration. Entering WAIT mode."); |
1098 | + m_ship_state = EXP_WAITING; |
1099 | + return start_task_idle(game, descr().main_animation(), 1500); |
1100 | + } |
1101 | + } else { // scouting towards a specific direction |
1102 | + if (exp_dir_swimable(m_expedition->direction)) { |
1103 | + // the scouting direction is still free to move |
1104 | + state.ivar1 = 1; |
1105 | + start_task_move(game, m_expedition->direction, descr().get_sail_anims(), false); |
1106 | + return; |
1107 | + } |
1108 | + // coast reached |
1109 | m_ship_state = EXP_WAITING; |
1110 | - return start_task_idle(game, descr().main_animation(), 1500); |
1111 | - } |
1112 | - } else { // scouting towards a specific direction |
1113 | - if (exp_dir_swimable(m_expedition->direction)) { |
1114 | - // the scouting direction is still free to move |
1115 | - state.ivar1 = 1; |
1116 | - start_task_move(game, m_expedition->direction, descr().get_sail_anims(), false); |
1117 | + start_task_idle(game, descr().main_animation(), 1500); |
1118 | + // Send a message to the player, that a new coast was reached |
1119 | + std::string msg_head = _("Coast Reached"); |
1120 | + std::string msg_body = |
1121 | + _("An expedition ship reached a coast and is waiting for further commands."); |
1122 | + send_message(game, msg_head, msg_body, "ship_explore_island_cw.png"); |
1123 | return; |
1124 | } |
1125 | - // coast reached |
1126 | - m_ship_state = EXP_WAITING; |
1127 | + } |
1128 | + case EXP_COLONIZING: { |
1129 | + assert(m_expedition->seen_port_buildspaces && !m_expedition->seen_port_buildspaces->empty()); |
1130 | + BaseImmovable * baim = game.map()[m_expedition->seen_port_buildspaces->front()].get_immovable(); |
1131 | + assert(baim); |
1132 | + upcast(ConstructionSite, cs, baim); |
1133 | + |
1134 | + for (int i = m_items.size() - 1; i >= 0; --i) { |
1135 | + WareInstance * ware; |
1136 | + Worker * worker; |
1137 | + m_items.at(i).get(game, &ware, &worker); |
1138 | + if (ware) { |
1139 | + // no, we don't transfer the wares, we create new ones out of air and remove the old ones ;) |
1140 | + WaresQueue & wq = cs->waresqueue(ware->descr_index()); |
1141 | + const uint32_t max = wq.get_max_fill(); |
1142 | + const uint32_t cur = wq.get_filled(); |
1143 | + assert(max > cur); |
1144 | + wq.set_filled(cur + 1); |
1145 | + m_items.at(i).remove(game); |
1146 | + m_items.resize(i); |
1147 | + break; |
1148 | + } else { |
1149 | + assert(worker); |
1150 | + worker->set_economy(nullptr); |
1151 | + worker->set_location(cs); |
1152 | + worker->set_position(game, cs->get_position()); |
1153 | + worker->reset_tasks(game); |
1154 | + PartiallyFinishedBuilding::request_builder_callback |
1155 | + (game, *cs->get_builder_request(), worker->descr().worker_index(), worker, *cs); |
1156 | + m_items.resize(i); |
1157 | + } |
1158 | + } |
1159 | + if (m_items.empty()) { |
1160 | + m_ship_state = TRANSPORT; // That's it, expedition finished |
1161 | + |
1162 | + init_fleet(game); |
1163 | + m_expedition.reset(nullptr); |
1164 | + |
1165 | + if (upcast(InteractiveGameBase, igb, game.get_ibase())) |
1166 | + refresh_window(*igb); |
1167 | + } |
1168 | + return start_task_idle(game, descr().main_animation(), 1500); // unload the next item |
1169 | + } |
1170 | + |
1171 | + default: { |
1172 | + // wait for input |
1173 | start_task_idle(game, descr().main_animation(), 1500); |
1174 | - // Send a message to the player, that a new coast was reached |
1175 | - std::string msg_head = _("Coast Reached"); |
1176 | - std::string msg_body = |
1177 | - _("An expedition ship reached a coast and is waiting for further commands."); |
1178 | - send_message(game, "exp_coast", msg_head, msg_body, "ship_explore_island_cw.png"); |
1179 | return; |
1180 | } |
1181 | } |
1182 | - case EXP_COLONIZING: { |
1183 | - assert(m_expedition->seen_port_buildspaces && !m_expedition->seen_port_buildspaces->empty()); |
1184 | - BaseImmovable* baim = |
1185 | - game.map()[m_expedition->seen_port_buildspaces->front()].get_immovable(); |
1186 | - assert(baim); |
1187 | - upcast(ConstructionSite, cs, baim); |
1188 | - |
1189 | - for (int i = m_items.size() - 1; i >= 0; --i) { |
1190 | - WareInstance* ware; |
1191 | - Worker* worker; |
1192 | - m_items.at(i).get(game, &ware, &worker); |
1193 | - if (ware) { |
1194 | - // no, we don't transfer the wares, we create new ones out of air and remove the old |
1195 | - // ones ;) |
1196 | - WaresQueue& wq = cs->waresqueue(ware->descr_index()); |
1197 | - const uint32_t max = wq.get_max_fill(); |
1198 | - const uint32_t cur = wq.get_filled(); |
1199 | - assert(max > cur); |
1200 | - wq.set_filled(cur + 1); |
1201 | - m_items.at(i).remove(game); |
1202 | - m_items.resize(i); |
1203 | - break; |
1204 | - } else { |
1205 | - assert(worker); |
1206 | - worker->set_economy(nullptr); |
1207 | - worker->set_location(cs); |
1208 | - worker->set_position(game, cs->get_position()); |
1209 | - worker->reset_tasks(game); |
1210 | - PartiallyFinishedBuilding::request_builder_callback( |
1211 | - game, *cs->get_builder_request(), worker->descr().worker_index(), worker, *cs); |
1212 | - m_items.resize(i); |
1213 | - } |
1214 | - } |
1215 | - if (m_items.empty()) { |
1216 | - m_ship_state = TRANSPORT; // That's it, expedition finished |
1217 | - |
1218 | - init_fleet(game); |
1219 | - m_expedition.reset(nullptr); |
1220 | - |
1221 | - if (upcast(InteractiveGameBase, igb, game.get_ibase())) |
1222 | - refresh_window(*igb); |
1223 | - } |
1224 | - return start_task_idle(game, descr().main_animation(), 1500); // unload the next item |
1225 | - } |
1226 | - |
1227 | - default: { |
1228 | - // wait for input |
1229 | - start_task_idle(game, descr().main_animation(), 1500); |
1230 | - return; |
1231 | - } |
1232 | - } |
1233 | |
1234 | // never here |
1235 | - assert(false); |
1236 | + assert (false); |
1237 | } |
1238 | |
1239 | -void Ship::set_economy(Game& game, Economy* e) { |
1240 | +void Ship::set_economy(Game & game, Economy * e) { |
1241 | // Do not check here that the economy actually changed, because on loading |
1242 | // we rely that wares really get reassigned our economy. |
1243 | |
1244 | @@ -694,23 +697,23 @@ |
1245 | * |
1246 | * @note This is supposed to be called only from the scheduling code of @ref Fleet. |
1247 | */ |
1248 | -void Ship::set_destination(Game& game, PortDock& pd) { |
1249 | +void Ship::set_destination(Game & game, PortDock & pd) { |
1250 | molog("set_destination to %u (currently %" PRIuS " items)\n", pd.serial(), m_items.size()); |
1251 | m_destination = &pd; |
1252 | send_signal(game, "wakeup"); |
1253 | } |
1254 | |
1255 | -void Ship::add_item(Game& game, const ShippingItem& item) { |
1256 | +void Ship::add_item(Game & game, const ShippingItem & item) { |
1257 | assert(m_items.size() < descr().get_capacity()); |
1258 | |
1259 | m_items.push_back(item); |
1260 | m_items.back().set_location(game, this); |
1261 | } |
1262 | |
1263 | -void Ship::withdraw_items(Game& game, PortDock& pd, std::vector<ShippingItem>& items) { |
1264 | +void Ship::withdraw_items(Game & game, PortDock & pd, std::vector<ShippingItem> & items) { |
1265 | uint32_t dst = 0; |
1266 | for (uint32_t src = 0; src < m_items.size(); ++src) { |
1267 | - PortDock* destination = m_items[src].get_destination(game); |
1268 | + PortDock * destination = m_items[src].get_destination(game); |
1269 | if (!destination || destination == &pd) { |
1270 | items.push_back(m_items[src]); |
1271 | } else { |
1272 | @@ -723,8 +726,8 @@ |
1273 | /** |
1274 | * Find a path to the dock @p pd and follow it without using precomputed paths. |
1275 | */ |
1276 | -void Ship::start_task_movetodock(Game& game, PortDock& pd) { |
1277 | - Map& map = game.map(); |
1278 | +void Ship::start_task_movetodock(Game & game, PortDock & pd) { |
1279 | + Map & map = game.map(); |
1280 | StepEvalAStar se(pd.get_warehouse()->get_position()); |
1281 | se.m_swim = true; |
1282 | se.m_conservative = false; |
1283 | @@ -750,7 +753,7 @@ |
1284 | } |
1285 | |
1286 | /// Prepare everything for the coming exploration |
1287 | -void Ship::start_task_expedition(Game& game) { |
1288 | +void Ship::start_task_expedition(Game & game) { |
1289 | // Now we are waiting |
1290 | m_ship_state = EXP_WAITING; |
1291 | // Initialize a new, yet empty expedition |
1292 | @@ -770,8 +773,8 @@ |
1293 | set_economy(game, m_expedition->economy.get()); |
1294 | |
1295 | for (int i = m_items.size() - 1; i >= 0; --i) { |
1296 | - WareInstance* ware; |
1297 | - Worker* worker; |
1298 | + WareInstance * ware; |
1299 | + Worker * worker; |
1300 | m_items.at(i).get(game, &ware, &worker); |
1301 | if (worker) { |
1302 | worker->reset_tasks(game); |
1303 | @@ -784,12 +787,12 @@ |
1304 | // Send a message to the player, that an expedition is ready to go |
1305 | const std::string msg_head = _("Expedition Ready"); |
1306 | const std::string msg_body = _("An expedition ship is waiting for your commands."); |
1307 | - send_message(game, "exp_ready", msg_head, msg_body, "start_expedition.png"); |
1308 | + send_message(game, msg_head, msg_body, "start_expedition.png"); |
1309 | } |
1310 | |
1311 | /// Initializes / changes the direction of scouting to @arg direction |
1312 | /// @note only called via player command |
1313 | -void Ship::exp_scout_direction(Game&, uint8_t direction) { |
1314 | +void Ship::exp_scout_direction(Game &, uint8_t direction) { |
1315 | assert(m_expedition); |
1316 | m_ship_state = EXP_SCOUTING; |
1317 | m_expedition->direction = direction; |
1318 | @@ -798,7 +801,7 @@ |
1319 | |
1320 | /// Initializes the construction of a port at @arg c |
1321 | /// @note only called via player command |
1322 | -void Ship::exp_construct_port(Game&, const Coords& c) { |
1323 | +void Ship::exp_construct_port (Game &, const Coords& c) { |
1324 | assert(m_expedition); |
1325 | BuildingIndex port_idx = get_owner()->tribe().safe_building_index("port"); |
1326 | get_owner()->force_csite(c, port_idx); |
1327 | @@ -807,7 +810,7 @@ |
1328 | |
1329 | /// Initializes / changes the direction the island exploration in @arg clockwise direction |
1330 | /// @note only called via player command |
1331 | -void Ship::exp_explore_island(Game&, bool clockwise) { |
1332 | +void Ship::exp_explore_island (Game &, bool clockwise) { |
1333 | assert(m_expedition); |
1334 | m_ship_state = EXP_SCOUTING; |
1335 | m_expedition->clockwise = clockwise; |
1336 | @@ -817,7 +820,7 @@ |
1337 | |
1338 | /// Cancels a currently running expedition |
1339 | /// @note only called via player command |
1340 | -void Ship::exp_cancel(Game& game) { |
1341 | +void Ship::exp_cancel (Game & game) { |
1342 | // Running colonization has the highest priority before cancelation |
1343 | // + cancelation only works if an expedition is actually running |
1344 | if ((m_ship_state == EXP_COLONIZING) || !state_is_expedition()) |
1345 | @@ -831,7 +834,7 @@ |
1346 | // Theres nothing to be done for wares - they already changed |
1347 | // economy with us and the warehouse will make sure that they are |
1348 | // getting used. |
1349 | - Worker* worker; |
1350 | + Worker * worker; |
1351 | for (ShippingItem& item : m_items) { |
1352 | item.get(game, nullptr, &worker); |
1353 | if (worker) { |
1354 | @@ -856,7 +859,7 @@ |
1355 | |
1356 | /// Sinks the ship |
1357 | /// @note only called via player command |
1358 | -void Ship::sink_ship(Game& game) { |
1359 | +void Ship::sink_ship (Game & game) { |
1360 | // Running colonization has the highest priority + a sink request is only valid once |
1361 | if (!state_is_sinkable()) |
1362 | return; |
1363 | @@ -866,22 +869,25 @@ |
1364 | close_window(); |
1365 | } |
1366 | |
1367 | -void Ship::log_general_info(const EditorGameBase& egbase) { |
1368 | +void Ship::log_general_info(const EditorGameBase & egbase) |
1369 | +{ |
1370 | Bob::log_general_info(egbase); |
1371 | |
1372 | - molog("Fleet: %u, destination: %u, lastdock: %u, carrying: %" PRIuS "\n", |
1373 | - m_fleet ? m_fleet->serial() : 0, |
1374 | - m_destination.serial(), |
1375 | - m_lastdock.serial(), |
1376 | - m_items.size()); |
1377 | + molog |
1378 | + ("Fleet: %u, destination: %u, lastdock: %u, carrying: %" PRIuS "\n", |
1379 | + m_fleet? m_fleet->serial() : 0, |
1380 | + m_destination.serial(), m_lastdock.serial(), |
1381 | + m_items.size()); |
1382 | |
1383 | for (const ShippingItem& shipping_item : m_items) { |
1384 | - molog(" IT %u, destination %u\n", |
1385 | - shipping_item.m_object.serial(), |
1386 | - shipping_item.m_destination_dock.serial()); |
1387 | + molog |
1388 | + (" IT %u, destination %u\n", |
1389 | + shipping_item.m_object.serial(), |
1390 | + shipping_item.m_destination_dock.serial()); |
1391 | } |
1392 | } |
1393 | |
1394 | + |
1395 | /** |
1396 | * Send a message to the owning player. |
1397 | * |
1398 | @@ -889,31 +895,29 @@ |
1399 | * |
1400 | * \param msgsender a computer-readable description of why the message was sent |
1401 | * \param title user-visible title of the message |
1402 | - * \param description user-visible message body, will be placed in an appropriate rich-text |
1403 | - *paragraph |
1404 | + * \param description user-visible message body, will be placed in an appropriate rich-text paragraph |
1405 | * \param picture picture name relative to the pics directory |
1406 | */ |
1407 | -void Ship::send_message(Game& game, |
1408 | - const std::string& msgsender, |
1409 | - const std::string& title, |
1410 | - const std::string& description, |
1411 | - const std::string& picture) { |
1412 | +void Ship::send_message |
1413 | + (Game & game, const std::string & title, const std::string & description, const std::string & picture) |
1414 | +{ |
1415 | std::string rt_description; |
1416 | if (picture.size() > 3) { |
1417 | - rt_description = (boost::format("<rt image=pics/%s><p font-face=serif font-size=14>") |
1418 | - % picture).str(); |
1419 | - } else { |
1420 | - rt_description = "<rt><p font-face=serif font-size=14>"; |
1421 | - } |
1422 | + rt_description = "<rt image=pics/"; |
1423 | + rt_description += picture; |
1424 | + rt_description += "><p font-size=14 font-face=DejaVuSerif>"; |
1425 | + } else |
1426 | + rt_description = "<rt><p font-size=14 font-face=DejaVuSerif>"; |
1427 | rt_description += description; |
1428 | rt_description += "</p></rt>"; |
1429 | |
1430 | - Message* msg = |
1431 | - new Message(msgsender, game.get_gametime(), title, rt_description, get_position(), m_serial); |
1432 | + Message * msg = new Message |
1433 | + (Message::Type::kSeafaring, game.get_gametime(), title, rt_description, get_position(), m_serial); |
1434 | |
1435 | get_owner()->add_message(game, *msg); |
1436 | } |
1437 | |
1438 | + |
1439 | /* |
1440 | ============================== |
1441 | |
1442 | @@ -924,16 +928,20 @@ |
1443 | |
1444 | #define SHIP_SAVEGAME_VERSION 4 |
1445 | |
1446 | -Ship::Loader::Loader() : m_lastdock(0), m_destination(0) { |
1447 | +Ship::Loader::Loader() : |
1448 | + m_lastdock(0), |
1449 | + m_destination(0) |
1450 | +{ |
1451 | } |
1452 | |
1453 | -const Bob::Task* Ship::Loader::get_task(const std::string& name) { |
1454 | - if (name == "shipidle" || name == "ship") |
1455 | - return &taskShip; |
1456 | +const Bob::Task * Ship::Loader::get_task(const std::string & name) |
1457 | +{ |
1458 | + if (name == "shipidle" || name == "ship") return &taskShip; |
1459 | return Bob::Loader::get_task(name); |
1460 | } |
1461 | |
1462 | -void Ship::Loader::load(FileRead& fr, uint8_t version) { |
1463 | +void Ship::Loader::load(FileRead & fr, uint8_t version) |
1464 | +{ |
1465 | Bob::Loader::load(fr); |
1466 | |
1467 | if (version >= 2) { |
1468 | @@ -942,8 +950,15 @@ |
1469 | m_ship_state = fr.unsigned_8(); |
1470 | |
1471 | // Expedition specific data |
1472 | - if (m_ship_state == EXP_SCOUTING || m_ship_state == EXP_WAITING || |
1473 | - m_ship_state == EXP_FOUNDPORTSPACE || m_ship_state == EXP_COLONIZING) { |
1474 | + if |
1475 | + (m_ship_state == EXP_SCOUTING |
1476 | + || |
1477 | + m_ship_state == EXP_WAITING |
1478 | + || |
1479 | + m_ship_state == EXP_FOUNDPORTSPACE |
1480 | + || |
1481 | + m_ship_state == EXP_COLONIZING) |
1482 | + { |
1483 | m_expedition.reset(new Expedition()); |
1484 | // Currently seen port build spaces |
1485 | m_expedition->seen_port_buildspaces.reset(new std::list<Coords>()); |
1486 | @@ -975,10 +990,11 @@ |
1487 | } |
1488 | } |
1489 | |
1490 | -void Ship::Loader::load_pointers() { |
1491 | +void Ship::Loader::load_pointers() |
1492 | +{ |
1493 | Bob::Loader::load_pointers(); |
1494 | |
1495 | - Ship& ship = get<Ship>(); |
1496 | + Ship & ship = get<Ship>(); |
1497 | |
1498 | if (m_lastdock) |
1499 | ship.m_lastdock = &mol().get<PortDock>(m_lastdock); |
1500 | @@ -991,10 +1007,11 @@ |
1501 | } |
1502 | } |
1503 | |
1504 | -void Ship::Loader::load_finish() { |
1505 | +void Ship::Loader::load_finish() |
1506 | +{ |
1507 | Bob::Loader::load_finish(); |
1508 | |
1509 | - Ship& ship = get<Ship>(); |
1510 | + Ship & ship = get<Ship>(); |
1511 | |
1512 | // restore the state the ship is in |
1513 | ship.m_ship_state = m_ship_state; |
1514 | @@ -1004,8 +1021,7 @@ |
1515 | ship.m_expedition.swap(m_expedition); |
1516 | ship.m_expedition->economy.reset(new Economy(*ship.get_owner())); |
1517 | ship.m_economy = ship.m_expedition->economy.get(); |
1518 | - } else |
1519 | - assert(m_ship_state == TRANSPORT); |
1520 | + } else assert(m_ship_state == TRANSPORT); |
1521 | |
1522 | // Workers load code set their economy to the economy of their location |
1523 | // (which is a PlayerImmovable), that means that workers on ships do not get |
1524 | @@ -1016,7 +1032,10 @@ |
1525 | ship.set_economy(dynamic_cast<Game&>(egbase()), ship.m_economy); |
1526 | } |
1527 | |
1528 | -MapObject::Loader* Ship::load(EditorGameBase& egbase, MapObjectLoader& mol, FileRead& fr) { |
1529 | + |
1530 | +MapObject::Loader * Ship::load |
1531 | + (EditorGameBase & egbase, MapObjectLoader & mol, FileRead & fr) |
1532 | +{ |
1533 | std::unique_ptr<Loader> loader(new Loader); |
1534 | |
1535 | try { |
1536 | @@ -1026,28 +1045,32 @@ |
1537 | if (1 <= version && version <= SHIP_SAVEGAME_VERSION) { |
1538 | std::string owner = fr.c_string(); |
1539 | std::string name = fr.c_string(); |
1540 | - const ShipDescr* descr = nullptr; |
1541 | + const ShipDescr * descr = nullptr; |
1542 | |
1543 | egbase.manually_load_tribe(owner); |
1544 | |
1545 | - if (const TribeDescr* tribe = egbase.get_tribe(owner)) |
1546 | - descr = dynamic_cast<const ShipDescr*>(tribe->get_bob_descr(name)); |
1547 | + if (const TribeDescr * tribe = egbase.get_tribe(owner)) |
1548 | + descr = dynamic_cast<const ShipDescr *> |
1549 | + (tribe->get_bob_descr(name)); |
1550 | |
1551 | if (!descr) |
1552 | - throw GameDataError("undefined ship %s/%s", owner.c_str(), name.c_str()); |
1553 | + throw GameDataError |
1554 | + ("undefined ship %s/%s", owner.c_str(), name.c_str()); |
1555 | |
1556 | loader->init(egbase, mol, descr->create_object()); |
1557 | loader->load(fr, version); |
1558 | } else |
1559 | throw GameDataError("unknown/unhandled version %u", version); |
1560 | - } catch (const std::exception& e) { |
1561 | + } catch (const std::exception & e) { |
1562 | throw wexception("loading ship: %s", e.what()); |
1563 | } |
1564 | |
1565 | return loader.release(); |
1566 | } |
1567 | |
1568 | -void Ship::save(EditorGameBase& egbase, MapObjectSaver& mos, FileWrite& fw) { |
1569 | +void Ship::save |
1570 | + (EditorGameBase & egbase, MapObjectSaver & mos, FileWrite & fw) |
1571 | +{ |
1572 | fw.unsigned_8(HeaderShip); |
1573 | fw.unsigned_8(SHIP_SAVEGAME_VERSION); |
1574 | |
1575 | @@ -1064,9 +1087,11 @@ |
1576 | // currently seen port buildspaces |
1577 | assert(m_expedition->seen_port_buildspaces); |
1578 | fw.unsigned_8(m_expedition->seen_port_buildspaces->size()); |
1579 | - for (std::list<Coords>::const_iterator it = m_expedition->seen_port_buildspaces->begin(); |
1580 | - it != m_expedition->seen_port_buildspaces->end(); |
1581 | - ++it) { |
1582 | + for |
1583 | + (std::list<Coords>::const_iterator it = m_expedition->seen_port_buildspaces->begin(); |
1584 | + it != m_expedition->seen_port_buildspaces->end(); |
1585 | + ++it) |
1586 | + { |
1587 | write_coords_32(&fw, *it); |
1588 | } |
1589 | // swimability of the directions |
1590 | @@ -1091,4 +1116,4 @@ |
1591 | } |
1592 | } |
1593 | |
1594 | -} // namespace Widelands |
1595 | +} // namespace Widelands |
1596 | |
1597 | === modified file 'src/logic/ship.h' |
1598 | --- src/logic/ship.h 2014-09-10 08:55:04 +0000 |
1599 | +++ src/logic/ship.h 2014-12-28 17:03:29 +0000 |
1600 | @@ -208,8 +208,7 @@ |
1601 | void init_fleet(EditorGameBase &); |
1602 | void set_fleet(Fleet * fleet); |
1603 | |
1604 | - void send_message |
1605 | - (Game &, const std::string &, const std::string &, const std::string &, const std::string &); |
1606 | + void send_message(Game &, const std::string &, const std::string &, const std::string &); |
1607 | |
1608 | UI::Window * m_window; |
1609 | |
1610 | |
1611 | === modified file 'src/logic/soldier.cc' |
1612 | --- src/logic/soldier.cc 2014-11-30 18:49:38 +0000 |
1613 | +++ src/logic/soldier.cc 2014-12-28 17:03:29 +0000 |
1614 | @@ -1571,7 +1571,7 @@ |
1615 | owner().add_message |
1616 | (game, |
1617 | *new Message |
1618 | - ("game engine", |
1619 | + (Message::Type::kGameLogic, |
1620 | game.get_gametime(), |
1621 | _("Logic error"), |
1622 | messagetext, |
1623 | @@ -1580,7 +1580,7 @@ |
1624 | opponent.owner().add_message |
1625 | (game, |
1626 | *new Message |
1627 | - ("game engine", |
1628 | + (Message::Type::kGameLogic, |
1629 | game.get_gametime(), |
1630 | _("Logic error"), |
1631 | messagetext, |
1632 | |
1633 | === modified file 'src/logic/warehouse.cc' |
1634 | --- src/logic/warehouse.cc 2014-12-12 22:59:39 +0000 |
1635 | +++ src/logic/warehouse.cc 2014-12-28 17:03:29 +0000 |
1636 | @@ -50,7 +50,7 @@ |
1637 | |
1638 | namespace Widelands { |
1639 | |
1640 | -namespace { |
1641 | +namespace { |
1642 | |
1643 | static const uint32_t WORKER_WITHOUT_COST_SPAWN_INTERVAL = 2500; |
1644 | |
1645 | @@ -68,17 +68,19 @@ |
1646 | |
1647 | } // namespace |
1648 | |
1649 | -WarehouseSupply::~WarehouseSupply() { |
1650 | +WarehouseSupply::~WarehouseSupply() |
1651 | +{ |
1652 | if (m_economy) { |
1653 | - log("WarehouseSupply::~WarehouseSupply: Warehouse %u still belongs to " |
1654 | - "an economy", |
1655 | - m_warehouse->serial()); |
1656 | + log |
1657 | + ("WarehouseSupply::~WarehouseSupply: Warehouse %u still belongs to " |
1658 | + "an economy", |
1659 | + m_warehouse->serial()); |
1660 | set_economy(nullptr); |
1661 | } |
1662 | |
1663 | // We're removed from the Economy. Therefore, the wares can simply |
1664 | // be cleared out. The global inventory will be okay. |
1665 | - m_wares.clear(); |
1666 | + m_wares .clear(); |
1667 | m_workers.clear(); |
1668 | } |
1669 | |
1670 | @@ -94,8 +96,10 @@ |
1671 | m_workers.set_nrwares(i); |
1672 | } |
1673 | |
1674 | + |
1675 | /// Add and remove our wares and the Supply to the economies as necessary. |
1676 | -void WarehouseSupply::set_economy(Economy* const e) { |
1677 | +void WarehouseSupply::set_economy(Economy * const e) |
1678 | +{ |
1679 | if (e == m_economy) |
1680 | return; |
1681 | |
1682 | @@ -122,74 +126,87 @@ |
1683 | } |
1684 | } |
1685 | |
1686 | + |
1687 | /// Add wares and update the economy. |
1688 | -void WarehouseSupply::add_wares(WareIndex const id, uint32_t const count) { |
1689 | +void WarehouseSupply::add_wares(WareIndex const id, uint32_t const count) |
1690 | +{ |
1691 | if (!count) |
1692 | return; |
1693 | |
1694 | - if (m_economy) // No economies in the editor |
1695 | + if (m_economy) // No economies in the editor |
1696 | m_economy->add_wares(id, count); |
1697 | m_wares.add(id, count); |
1698 | } |
1699 | |
1700 | + |
1701 | /// Remove wares and update the economy. |
1702 | -void WarehouseSupply::remove_wares(WareIndex const id, uint32_t const count) { |
1703 | +void WarehouseSupply::remove_wares(WareIndex const id, uint32_t const count) |
1704 | +{ |
1705 | if (!count) |
1706 | return; |
1707 | |
1708 | m_wares.remove(id, count); |
1709 | - if (m_economy) // No economies in the editor |
1710 | + if (m_economy) // No economies in the editor |
1711 | m_economy->remove_wares(id, count); |
1712 | } |
1713 | |
1714 | + |
1715 | /// Add workers and update the economy. |
1716 | -void WarehouseSupply::add_workers(WareIndex const id, uint32_t const count) { |
1717 | +void WarehouseSupply::add_workers(WareIndex const id, uint32_t const count) |
1718 | +{ |
1719 | if (!count) |
1720 | return; |
1721 | |
1722 | - if (m_economy) // No economies in the editor |
1723 | + if (m_economy) // No economies in the editor |
1724 | m_economy->add_workers(id, count); |
1725 | m_workers.add(id, count); |
1726 | } |
1727 | |
1728 | + |
1729 | /** |
1730 | * Remove workers and update the economy. |
1731 | * Comments see add_workers |
1732 | */ |
1733 | -void WarehouseSupply::remove_workers(WareIndex const id, uint32_t const count) { |
1734 | +void WarehouseSupply::remove_workers(WareIndex const id, uint32_t const count) |
1735 | +{ |
1736 | if (!count) |
1737 | return; |
1738 | |
1739 | m_workers.remove(id, count); |
1740 | - if (m_economy) // No economies in the editor |
1741 | + if (m_economy) // No economies in the editor |
1742 | m_economy->remove_workers(id, count); |
1743 | } |
1744 | |
1745 | /// Return the position of the Supply, i.e. the owning Warehouse. |
1746 | -PlayerImmovable* WarehouseSupply::get_position(Game&) { |
1747 | - return m_warehouse; |
1748 | -} |
1749 | +PlayerImmovable * WarehouseSupply::get_position(Game &) {return m_warehouse;} |
1750 | + |
1751 | |
1752 | /// Warehouse supplies are never active. |
1753 | -bool WarehouseSupply::is_active() const { |
1754 | - return false; |
1755 | -} |
1756 | +bool WarehouseSupply::is_active() const {return false;} |
1757 | |
1758 | -bool WarehouseSupply::has_storage() const { |
1759 | +bool WarehouseSupply::has_storage() const |
1760 | +{ |
1761 | return true; |
1762 | } |
1763 | |
1764 | -void WarehouseSupply::get_ware_type(WareWorker& /* type */, WareIndex& /* ware */) const { |
1765 | - throw wexception("WarehouseSupply::get_ware_type: calling this is nonsensical"); |
1766 | +void WarehouseSupply::get_ware_type(WareWorker & /* type */, WareIndex & /* ware */) const |
1767 | +{ |
1768 | + throw wexception |
1769 | + ("WarehouseSupply::get_ware_type: calling this is nonsensical"); |
1770 | } |
1771 | |
1772 | -void WarehouseSupply::send_to_storage(Game&, Warehouse* /* wh */) { |
1773 | +void WarehouseSupply::send_to_storage(Game &, Warehouse * /* wh */) |
1774 | +{ |
1775 | throw wexception("WarehouseSupply::send_to_storage: should never be called"); |
1776 | } |
1777 | |
1778 | -uint32_t WarehouseSupply::nr_supplies(const Game& game, const Request& req) const { |
1779 | +uint32_t WarehouseSupply::nr_supplies |
1780 | + (const Game & game, const Request & req) const |
1781 | +{ |
1782 | if (req.get_type() == wwWORKER) |
1783 | - return m_warehouse->count_workers(game, req.get_index(), req.get_requirements()); |
1784 | + return |
1785 | + m_warehouse->count_workers |
1786 | + (game, req.get_index(), req.get_requirements()); |
1787 | |
1788 | // Calculate how many wares can be sent out - it might be that we need them |
1789 | // ourselves. E.g. for hiring new soldiers. |
1790 | @@ -199,16 +216,18 @@ |
1791 | // of *this* warehouse + 1 (+1 is important, as else the ware would directly |
1792 | // be taken back to the warehouse as the request of the warehouse would be |
1793 | // highered and would have the same value as the original request) |
1794 | - int32_t const y = x + (req.get_priority(0) / 100) - |
1795 | - (m_warehouse->get_priority(wwWARE, req.get_index()) / 100) - 1; |
1796 | + int32_t const y = |
1797 | + x + (req.get_priority(0) / 100) |
1798 | + - (m_warehouse->get_priority(wwWARE, req.get_index()) / 100) - 1; |
1799 | // But the number should never be higher than the number of wares available |
1800 | if (y > x) |
1801 | return x; |
1802 | return (x > 0) ? x : 0; |
1803 | } |
1804 | |
1805 | + |
1806 | /// Launch a ware. |
1807 | -WareInstance& WarehouseSupply::launch_ware(Game& game, const Request& req) { |
1808 | +WareInstance & WarehouseSupply::launch_ware(Game & game, const Request & req) { |
1809 | if (req.get_type() != wwWARE) |
1810 | throw wexception("WarehouseSupply::launch_ware: called for non-ware request"); |
1811 | if (!m_wares.stock(req.get_index())) |
1812 | @@ -218,26 +237,29 @@ |
1813 | } |
1814 | |
1815 | /// Launch a ware as worker. |
1816 | -Worker& WarehouseSupply::launch_worker(Game& game, const Request& req) { |
1817 | - return m_warehouse->launch_worker(game, req.get_index(), req.get_requirements()); |
1818 | +Worker & WarehouseSupply::launch_worker(Game & game, const Request & req) |
1819 | +{ |
1820 | + return |
1821 | + m_warehouse->launch_worker |
1822 | + (game, req.get_index(), req.get_requirements()); |
1823 | } |
1824 | |
1825 | + |
1826 | /* |
1827 | ============================== |
1828 | Warehouse Building |
1829 | ============================== |
1830 | */ |
1831 | |
1832 | + |
1833 | /// Warehouse Descr |
1834 | -WarehouseDescr::WarehouseDescr(char const* const _name, |
1835 | - char const* const _descname, |
1836 | - const std::string& directory, |
1837 | - Profile& prof, |
1838 | - Section& global_s, |
1839 | - const TribeDescr& _tribe) |
1840 | - : BuildingDescr(MapObjectType::WAREHOUSE, _name, _descname, directory, prof, global_s, _tribe), |
1841 | - m_conquers(0), |
1842 | - m_heal_per_second(0) { |
1843 | +WarehouseDescr::WarehouseDescr |
1844 | + (char const* const _name, char const* const _descname, |
1845 | + const std::string& directory, Profile& prof, Section& global_s, const TribeDescr& _tribe) |
1846 | + : BuildingDescr(MapObjectType::WAREHOUSE, _name, _descname, directory, prof, global_s, _tribe), |
1847 | + m_conquers (0), |
1848 | + m_heal_per_second (0) |
1849 | +{ |
1850 | m_heal_per_second = global_s.get_safe_int("heal_per_second"); |
1851 | if ((m_conquers = prof.get_safe_section("global").get_positive("conquers", 0))) |
1852 | m_workarea_info[m_conquers].insert(descname() + " conquer"); |
1853 | @@ -249,21 +271,25 @@ |
1854 | ============================== |
1855 | */ |
1856 | |
1857 | -Warehouse::Warehouse(const WarehouseDescr& warehouse_descr) |
1858 | - : Building(warehouse_descr), |
1859 | - m_supply(new WarehouseSupply(this)), |
1860 | - m_next_military_act(0), |
1861 | - m_portdock(nullptr) { |
1862 | +Warehouse::Warehouse(const WarehouseDescr & warehouse_descr) : |
1863 | + Building(warehouse_descr), |
1864 | + m_supply(new WarehouseSupply(this)), |
1865 | + m_next_military_act(0), |
1866 | + m_portdock(nullptr) |
1867 | +{ |
1868 | uint8_t nr_worker_types_without_cost = |
1869 | - warehouse_descr.tribe().worker_types_without_cost().size(); |
1870 | - m_next_worker_without_cost_spawn = new uint32_t[nr_worker_types_without_cost]; |
1871 | + warehouse_descr.tribe().worker_types_without_cost().size(); |
1872 | + m_next_worker_without_cost_spawn = |
1873 | + new uint32_t[nr_worker_types_without_cost]; |
1874 | for (int i = 0; i < nr_worker_types_without_cost; ++i) { |
1875 | m_next_worker_without_cost_spawn[i] = never(); |
1876 | } |
1877 | m_next_stock_remove_act = 0; |
1878 | } |
1879 | |
1880 | -Warehouse::~Warehouse() { |
1881 | + |
1882 | +Warehouse::~Warehouse() |
1883 | +{ |
1884 | delete m_supply; |
1885 | delete[] m_next_worker_without_cost_spawn; |
1886 | } |
1887 | @@ -272,19 +298,22 @@ |
1888 | * Try to bring the given \ref PlannedWorkers up to date with our game data. |
1889 | * Return \c false if \p pw cannot be salvaged. |
1890 | */ |
1891 | -bool Warehouse::_load_finish_planned_worker(PlannedWorkers& pw) { |
1892 | +bool Warehouse::_load_finish_planned_worker(PlannedWorkers & pw) |
1893 | +{ |
1894 | if (pw.index == INVALID_INDEX || !(pw.index < m_supply->get_workers().get_nrwareids())) |
1895 | return false; |
1896 | |
1897 | - const WorkerDescr* w_desc = descr().tribe().get_worker_descr(pw.index); |
1898 | + const WorkerDescr * w_desc = descr().tribe().get_worker_descr(pw.index); |
1899 | if (!w_desc || !w_desc->is_buildable()) |
1900 | return false; |
1901 | |
1902 | - const WorkerDescr::Buildcost& cost = w_desc->buildcost(); |
1903 | + const WorkerDescr::Buildcost & cost = w_desc->buildcost(); |
1904 | uint32_t idx = 0; |
1905 | |
1906 | - for (WorkerDescr::Buildcost::const_iterator cost_it = cost.begin(); cost_it != cost.end(); |
1907 | - ++cost_it, ++idx) { |
1908 | + for |
1909 | + (WorkerDescr::Buildcost::const_iterator cost_it = cost.begin(); |
1910 | + cost_it != cost.end(); ++cost_it, ++idx) |
1911 | + { |
1912 | WareWorker type; |
1913 | WareIndex ware; |
1914 | ware = descr().tribe().ware_index(cost_it->first); |
1915 | @@ -296,10 +325,13 @@ |
1916 | return false; |
1917 | |
1918 | if (idx < pw.requests.size()) { |
1919 | - if (pw.requests[idx]->get_type() == type && pw.requests[idx]->get_index() == ware) |
1920 | + if |
1921 | + (pw.requests[idx]->get_type() == type && |
1922 | + pw.requests[idx]->get_index() == ware) |
1923 | continue; |
1924 | |
1925 | - std::vector<Request*>::iterator req_it = pw.requests.begin() + idx + 1; |
1926 | + std::vector<Request *>::iterator req_it = |
1927 | + pw.requests.begin() + idx + 1; |
1928 | while (req_it != pw.requests.end()) { |
1929 | if ((*req_it)->get_type() == type && (*req_it)->get_index() == ware) |
1930 | break; |
1931 | @@ -312,16 +344,19 @@ |
1932 | } |
1933 | } |
1934 | |
1935 | - log("_load_finish_planned_worker: old savegame: " |
1936 | - "need to create new request for '%s'\n", |
1937 | - cost_it->first.c_str()); |
1938 | - pw.requests.insert( |
1939 | - pw.requests.begin() + idx, new Request(*this, ware, &Warehouse::request_cb, type)); |
1940 | + log |
1941 | + ("_load_finish_planned_worker: old savegame: " |
1942 | + "need to create new request for '%s'\n", |
1943 | + cost_it->first.c_str()); |
1944 | + pw.requests.insert |
1945 | + (pw.requests.begin() + idx, |
1946 | + new Request(*this, ware, &Warehouse::request_cb, type)); |
1947 | } |
1948 | |
1949 | while (pw.requests.size() > idx) { |
1950 | - log("_load_finish_planned_worker: old savegame: " |
1951 | - "removing outdated request.\n"); |
1952 | + log |
1953 | + ("_load_finish_planned_worker: old savegame: " |
1954 | + "removing outdated request.\n"); |
1955 | delete pw.requests.back(); |
1956 | pw.requests.pop_back(); |
1957 | } |
1958 | @@ -329,31 +364,30 @@ |
1959 | return true; |
1960 | } |
1961 | |
1962 | -void Warehouse::load_finish(EditorGameBase& egbase) { |
1963 | +void Warehouse::load_finish(EditorGameBase & egbase) { |
1964 | Building::load_finish(egbase); |
1965 | |
1966 | uint32_t next_spawn = never(); |
1967 | - const std::vector<WareIndex>& worker_types_without_cost = |
1968 | - descr().tribe().worker_types_without_cost(); |
1969 | + const std::vector<WareIndex> & worker_types_without_cost = |
1970 | + descr().tribe().worker_types_without_cost(); |
1971 | for (uint8_t i = worker_types_without_cost.size(); i;) { |
1972 | WareIndex const worker_index = worker_types_without_cost.at(--i); |
1973 | - if (owner().is_worker_type_allowed(worker_index) && |
1974 | - m_next_worker_without_cost_spawn[i] == static_cast<uint32_t>(never())) { |
1975 | + if |
1976 | + (owner().is_worker_type_allowed(worker_index) && |
1977 | + m_next_worker_without_cost_spawn[i] == static_cast<uint32_t>(never())) |
1978 | + { |
1979 | if (next_spawn == static_cast<uint32_t>(never())) { |
1980 | - next_spawn = |
1981 | - schedule_act(dynamic_cast<Game&>(egbase), WORKER_WITHOUT_COST_SPAWN_INTERVAL); |
1982 | + next_spawn = schedule_act(dynamic_cast<Game&>(egbase), WORKER_WITHOUT_COST_SPAWN_INTERVAL); |
1983 | } |
1984 | m_next_worker_without_cost_spawn[i] = next_spawn; |
1985 | - log("WARNING: player %u is allowed to create worker type %s but his " |
1986 | - "%s %u at (%i, %i) does not have a next_spawn time set for that " |
1987 | - "worker type; setting it to %u\n", |
1988 | - owner().player_number(), |
1989 | - descr().tribe().get_worker_descr(worker_index)->descname().c_str(), |
1990 | - descr().descname().c_str(), |
1991 | - serial(), |
1992 | - get_position().x, |
1993 | - get_position().y, |
1994 | - next_spawn); |
1995 | + log |
1996 | + ("WARNING: player %u is allowed to create worker type %s but his " |
1997 | + "%s %u at (%i, %i) does not have a next_spawn time set for that " |
1998 | + "worker type; setting it to %u\n", |
1999 | + owner().player_number(), |
2000 | + descr().tribe().get_worker_descr(worker_index)->descname().c_str(), |
2001 | + descr().descname().c_str(), serial(), get_position().x, get_position().y, |
2002 | + next_spawn); |
2003 | } |
2004 | } |
2005 | |
2006 | @@ -371,12 +405,13 @@ |
2007 | } |
2008 | } |
2009 | |
2010 | -void Warehouse::init(EditorGameBase& egbase) { |
2011 | +void Warehouse::init(EditorGameBase & egbase) |
2012 | +{ |
2013 | Building::init(egbase); |
2014 | |
2015 | - WareIndex const nr_wares = descr().tribe().get_nrwares(); |
2016 | + WareIndex const nr_wares = descr().tribe().get_nrwares (); |
2017 | WareIndex const nr_workers = descr().tribe().get_nrworkers(); |
2018 | - m_supply->set_nrwares(nr_wares); |
2019 | + m_supply->set_nrwares (nr_wares); |
2020 | m_supply->set_nrworkers(nr_workers); |
2021 | |
2022 | m_ware_policy.resize(nr_wares, SP_Normal); |
2023 | @@ -385,15 +420,17 @@ |
2024 | // Even though technically, a warehouse might be completely empty, |
2025 | // we let warehouse see always for simplicity's sake (since there's |
2026 | // almost always going to be a carrier inside, that shouldn't hurt). |
2027 | - Player& player = owner(); |
2028 | + Player & player = owner(); |
2029 | if (upcast(Game, game, &egbase)) { |
2030 | - player.see_area( |
2031 | - Area<FCoords>(egbase.map().get_fcoords(get_position()), descr().vision_range())); |
2032 | + player.see_area |
2033 | + (Area<FCoords> |
2034 | + (egbase.map().get_fcoords(get_position()), descr().vision_range())); |
2035 | |
2036 | { |
2037 | - uint32_t const act_time = schedule_act(*game, WORKER_WITHOUT_COST_SPAWN_INTERVAL); |
2038 | - const std::vector<WareIndex>& worker_types_without_cost = |
2039 | - descr().tribe().worker_types_without_cost(); |
2040 | + uint32_t const act_time = schedule_act |
2041 | + (*game, WORKER_WITHOUT_COST_SPAWN_INTERVAL); |
2042 | + const std::vector<WareIndex> & worker_types_without_cost = |
2043 | + descr().tribe().worker_types_without_cost(); |
2044 | |
2045 | for (size_t i = 0; i < worker_types_without_cost.size(); ++i) { |
2046 | if (owner().is_worker_type_allowed(worker_types_without_cost.at(i))) { |
2047 | @@ -408,21 +445,38 @@ |
2048 | |
2049 | m_next_stock_remove_act = schedule_act(*game, 4000); |
2050 | |
2051 | - log("Message: adding (wh) (%s) %i \n", |
2052 | - to_string(descr().type()).c_str(), |
2053 | - player.player_number()); |
2054 | - send_message(*game, |
2055 | - "warehouse", |
2056 | - descr().descname(), |
2057 | - (boost::format(_("A new %s was added to your economy.")) % |
2058 | - descr().descname().c_str()).str(), |
2059 | - true); |
2060 | + log("Message: adding (wh) (%s) %i \n", to_string(descr().type()).c_str(), player.player_number()); |
2061 | + |
2062 | + if (descr().name() == "port") { |
2063 | + send_message |
2064 | + (*game, |
2065 | + Message::Type::kSeafaring, |
2066 | + descr().descname(), |
2067 | + _("A new port was added to your economy."), |
2068 | + true); |
2069 | + } else if (descr().name() == "headquarters") { |
2070 | + send_message |
2071 | + (*game, |
2072 | + Message::Type::kEconomy, |
2073 | + descr().descname(), |
2074 | + _("A new headquarters was added to your economy."), |
2075 | + true); |
2076 | + } else { |
2077 | + send_message |
2078 | + (*game, |
2079 | + Message::Type::kEconomy, |
2080 | + descr().descname(), |
2081 | + _("A new warehouse was added to your economy."), |
2082 | + true); |
2083 | + } |
2084 | } |
2085 | |
2086 | if (uint32_t const conquer_radius = descr().get_conquers()) |
2087 | - egbase.conquer_area(PlayerArea<Area<FCoords>>( |
2088 | - player.player_number(), |
2089 | - Area<FCoords>(egbase.map().get_fcoords(get_position()), conquer_radius))); |
2090 | + egbase.conquer_area |
2091 | + (PlayerArea<Area<FCoords> > |
2092 | + (player.player_number(), |
2093 | + Area<FCoords> |
2094 | + (egbase.map().get_fcoords(get_position()), conquer_radius))); |
2095 | |
2096 | if (descr().get_isport()) |
2097 | init_portdock(egbase); |
2098 | @@ -432,10 +486,11 @@ |
2099 | * Find a contiguous set of water fields close to the port for docking |
2100 | * and initialize the @ref PortDock instance. |
2101 | */ |
2102 | -void Warehouse::init_portdock(EditorGameBase& egbase) { |
2103 | +void Warehouse::init_portdock(EditorGameBase & egbase) |
2104 | +{ |
2105 | molog("Setting up port dock fields\n"); |
2106 | |
2107 | - Map& map = egbase.map(); |
2108 | + Map & map = egbase.map(); |
2109 | std::vector<Coords> dock = map.find_portdock(get_position()); |
2110 | if (dock.empty()) { |
2111 | log("Attempting to setup port without neighboring water.\n"); |
2112 | @@ -456,12 +511,14 @@ |
2113 | m_portdock->set_economy(get_economy()); |
2114 | } |
2115 | |
2116 | -void Warehouse::destroy(EditorGameBase& egbase) { |
2117 | +void Warehouse::destroy(EditorGameBase & egbase) |
2118 | +{ |
2119 | Building::destroy(egbase); |
2120 | } |
2121 | |
2122 | /// Destroy the warehouse. |
2123 | -void Warehouse::cleanup(EditorGameBase& egbase) { |
2124 | +void Warehouse::cleanup(EditorGameBase & egbase) |
2125 | +{ |
2126 | if (egbase.objects().object_still_available(m_portdock)) { |
2127 | m_portdock->remove(egbase); |
2128 | m_portdock = nullptr; |
2129 | @@ -488,18 +545,21 @@ |
2130 | |
2131 | Map& map = egbase.map(); |
2132 | if (const uint32_t conquer_radius = descr().get_conquers()) |
2133 | - egbase.unconquer_area( |
2134 | - PlayerArea<Area<FCoords>>(owner().player_number(), |
2135 | - Area<FCoords>(map.get_fcoords(get_position()), conquer_radius)), |
2136 | - m_defeating_player); |
2137 | + egbase.unconquer_area |
2138 | + (PlayerArea<Area<FCoords> > |
2139 | + (owner().player_number(), |
2140 | + Area<FCoords>(map.get_fcoords(get_position()), conquer_radius)), |
2141 | + m_defeating_player); |
2142 | |
2143 | // Unsee the area that we started seeing in init() |
2144 | - Player& player = owner(); |
2145 | - player.unsee_area(Area<FCoords>(map.get_fcoords(get_position()), descr().vision_range())); |
2146 | + Player & player = owner(); |
2147 | + player.unsee_area |
2148 | + (Area<FCoords>(map.get_fcoords(get_position()), descr().vision_range())); |
2149 | |
2150 | Building::cleanup(egbase); |
2151 | } |
2152 | |
2153 | + |
2154 | /// Act regularly to create workers of buildable types without cost. According |
2155 | /// to intelligence, this is some highly advanced technology. Not only do the |
2156 | /// settlers have no problems with birth control, they do not even need anybody |
2157 | @@ -507,11 +567,12 @@ |
2158 | /// what the hell are they doing, killing useless tribesmen! The Borg? Or just |
2159 | /// like Soylent Green? Or maybe I should just stop writing comments that late |
2160 | /// at night ;-) |
2161 | -void Warehouse::act(Game& game, uint32_t const data) { |
2162 | +void Warehouse::act(Game & game, uint32_t const data) |
2163 | +{ |
2164 | uint32_t const gametime = game.get_gametime(); |
2165 | { |
2166 | - const std::vector<WareIndex>& worker_types_without_cost = |
2167 | - owner().tribe().worker_types_without_cost(); |
2168 | + const std::vector<WareIndex> & worker_types_without_cost = |
2169 | + owner().tribe().worker_types_without_cost(); |
2170 | for (size_t i = worker_types_without_cost.size(); i;) |
2171 | if (m_next_worker_without_cost_spawn[--i] <= gametime) { |
2172 | WareIndex const id = worker_types_without_cost.at(i); |
2173 | @@ -529,7 +590,8 @@ |
2174 | remove_workers(id, 1); |
2175 | } |
2176 | |
2177 | - m_next_worker_without_cost_spawn[i] = schedule_act(game, tdelta); |
2178 | + m_next_worker_without_cost_spawn[i] = |
2179 | + schedule_act(game, tdelta); |
2180 | } else |
2181 | m_next_worker_without_cost_spawn[i] = never(); |
2182 | } |
2183 | @@ -540,15 +602,19 @@ |
2184 | WareIndex const ware = descr().tribe().safe_worker_index("soldier"); |
2185 | |
2186 | if (m_incorporated_workers.count(ware)) { |
2187 | - WorkerList& soldiers = m_incorporated_workers[ware]; |
2188 | + WorkerList & soldiers = m_incorporated_workers[ware]; |
2189 | |
2190 | uint32_t total_heal = descr().get_heal_per_second(); |
2191 | // Using an explicit iterator, as we plan to erase some |
2192 | // of those guys |
2193 | - for (WorkerList::iterator it = soldiers.begin(); it != soldiers.end(); ++it) { |
2194 | + for |
2195 | + (WorkerList::iterator it = soldiers.begin(); |
2196 | + it != soldiers.end(); |
2197 | + ++it) |
2198 | + { |
2199 | // This is a safe cast: we know only soldiers can land in this |
2200 | // slot in the incorporated array |
2201 | - Soldier* soldier = static_cast<Soldier*>(*it); |
2202 | + Soldier * soldier = static_cast<Soldier *>(*it); |
2203 | |
2204 | // Soldier dead ... |
2205 | if (!soldier || soldier->get_current_hitpoints() == 0) { |
2206 | @@ -561,6 +627,7 @@ |
2207 | soldier->heal(total_heal); |
2208 | continue; |
2209 | } |
2210 | + |
2211 | } |
2212 | } |
2213 | m_next_military_act = schedule_act(game, 1000); |
2214 | @@ -581,9 +648,11 @@ |
2215 | Building::act(game, data); |
2216 | } |
2217 | |
2218 | + |
2219 | /// Transfer our registration to the new economy. |
2220 | -void Warehouse::set_economy(Economy* const e) { |
2221 | - Economy* const old = get_economy(); |
2222 | +void Warehouse::set_economy(Economy * const e) |
2223 | +{ |
2224 | + Economy * const old = get_economy(); |
2225 | |
2226 | if (old == e) |
2227 | return; |
2228 | @@ -597,7 +666,7 @@ |
2229 | Building::set_economy(e); |
2230 | |
2231 | for (const PlannedWorkers& pw : m_planned_workers) { |
2232 | - for (Request* req : pw.requests) { |
2233 | + for (Request * req : pw.requests) { |
2234 | req->set_economy(e); |
2235 | } |
2236 | } |
2237 | @@ -609,62 +678,82 @@ |
2238 | e->add_warehouse(*this); |
2239 | } |
2240 | |
2241 | -const WareList& Warehouse::get_wares() const { |
2242 | + |
2243 | +const WareList & Warehouse::get_wares() const |
2244 | +{ |
2245 | return m_supply->get_wares(); |
2246 | } |
2247 | |
2248 | -const WareList& Warehouse::get_workers() const { |
2249 | + |
2250 | +const WareList & Warehouse::get_workers() const |
2251 | +{ |
2252 | return m_supply->get_workers(); |
2253 | } |
2254 | |
2255 | -PlayerImmovable::Workers Warehouse::get_incorporated_workers() { |
2256 | +PlayerImmovable::Workers Warehouse::get_incorporated_workers() |
2257 | +{ |
2258 | PlayerImmovable::Workers all_workers; |
2259 | |
2260 | for (const std::pair<WareIndex, WorkerList>& worker_pair : m_incorporated_workers) { |
2261 | - for (Worker* worker : worker_pair.second) { |
2262 | + for (Worker * worker : worker_pair.second) { |
2263 | all_workers.push_back(worker); |
2264 | } |
2265 | } |
2266 | return all_workers; |
2267 | } |
2268 | |
2269 | + |
2270 | /// Magically create wares in this warehouse. Updates the economy accordingly. |
2271 | -void Warehouse::insert_wares(WareIndex const id, uint32_t const count) { |
2272 | +void Warehouse::insert_wares(WareIndex const id, uint32_t const count) |
2273 | +{ |
2274 | m_supply->add_wares(id, count); |
2275 | } |
2276 | |
2277 | + |
2278 | /// Magically destroy wares. |
2279 | -void Warehouse::remove_wares(WareIndex const id, uint32_t const count) { |
2280 | +void Warehouse::remove_wares(WareIndex const id, uint32_t const count) |
2281 | +{ |
2282 | m_supply->remove_wares(id, count); |
2283 | } |
2284 | |
2285 | + |
2286 | /// Magically create workers in this warehouse. Updates the economy accordingly. |
2287 | -void Warehouse::insert_workers(WareIndex const id, uint32_t const count) { |
2288 | +void Warehouse::insert_workers(WareIndex const id, uint32_t const count) |
2289 | +{ |
2290 | m_supply->add_workers(id, count); |
2291 | } |
2292 | |
2293 | + |
2294 | /// Magically destroy workers. |
2295 | -void Warehouse::remove_workers(WareIndex const id, uint32_t const count) { |
2296 | +void Warehouse::remove_workers(WareIndex const id, uint32_t const count) |
2297 | +{ |
2298 | m_supply->remove_workers(id, count); |
2299 | } |
2300 | |
2301 | + |
2302 | + |
2303 | /// Launch a carrier to fetch an ware from our flag. |
2304 | -bool Warehouse::fetch_from_flag(Game& game) { |
2305 | +bool Warehouse::fetch_from_flag(Game & game) |
2306 | +{ |
2307 | WareIndex const carrierid = descr().tribe().safe_worker_index("carrier"); |
2308 | |
2309 | - if (!m_supply->stock_workers(carrierid)) // XXX yep, let's cheat |
2310 | + if (!m_supply->stock_workers(carrierid)) // XXX yep, let's cheat |
2311 | insert_workers(carrierid, 1); |
2312 | |
2313 | - launch_worker(game, carrierid, Requirements()).start_task_fetchfromflag(game); |
2314 | + launch_worker(game, carrierid, Requirements()).start_task_fetchfromflag |
2315 | + (game); |
2316 | |
2317 | return true; |
2318 | } |
2319 | |
2320 | + |
2321 | /** |
2322 | * \return the number of workers that we can launch satisfying the given |
2323 | * requirements. |
2324 | */ |
2325 | -uint32_t Warehouse::count_workers(const Game& /* game */, WareIndex ware, const Requirements& req) { |
2326 | +uint32_t Warehouse::count_workers |
2327 | + (const Game & /* game */, WareIndex ware, const Requirements & req) |
2328 | +{ |
2329 | uint32_t sum = 0; |
2330 | |
2331 | do { |
2332 | @@ -672,7 +761,7 @@ |
2333 | |
2334 | // NOTE: This code lies about the TrainingAttributes of non-instantiated workers. |
2335 | if (m_incorporated_workers.count(ware)) { |
2336 | - for (Worker* worker : m_incorporated_workers[ware]) { |
2337 | + for (Worker * worker : m_incorporated_workers[ware]) { |
2338 | if (!req.check(*worker)) { |
2339 | // This is one of the workers in our sum. |
2340 | // But he is too stupid for this job |
2341 | @@ -689,7 +778,9 @@ |
2342 | |
2343 | /// Start a worker of a given type. The worker will |
2344 | /// be assigned a job by the caller. |
2345 | -Worker& Warehouse::launch_worker(Game& game, WareIndex ware, const Requirements& req) { |
2346 | +Worker & Warehouse::launch_worker |
2347 | + (Game & game, WareIndex ware, const Requirements & req) |
2348 | +{ |
2349 | do { |
2350 | if (m_supply->stock_workers(ware)) { |
2351 | uint32_t unincorporated = m_supply->stock_workers(ware); |
2352 | @@ -702,15 +793,15 @@ |
2353 | remove_no_longer_existing_workers(game, &m_incorporated_workers[ware]); |
2354 | WorkerList& incorporated_workers = m_incorporated_workers[ware]; |
2355 | |
2356 | - for (std::vector<Worker*>::iterator worker_iter = incorporated_workers.begin(); |
2357 | - worker_iter != incorporated_workers.end(); |
2358 | - ++worker_iter) { |
2359 | + for (std::vector<Worker *>::iterator worker_iter = incorporated_workers.begin(); |
2360 | + worker_iter != incorporated_workers.end(); ++worker_iter) |
2361 | + { |
2362 | Worker* worker = *worker_iter; |
2363 | --unincorporated; |
2364 | |
2365 | if (req.check(*worker)) { |
2366 | - worker->reset_tasks(game); // forget everything you did |
2367 | - worker->set_location(this); // back in a economy |
2368 | + worker->reset_tasks(game); // forget everything you did |
2369 | + worker->set_location(this); // back in a economy |
2370 | incorporated_workers.erase(worker_iter); |
2371 | |
2372 | m_supply->remove_workers(ware, 1); |
2373 | @@ -725,7 +816,7 @@ |
2374 | // Create a new one |
2375 | // NOTE: This code lies about the TrainingAttributes of the new worker |
2376 | m_supply->remove_workers(ware, 1); |
2377 | - const WorkerDescr& workerdescr = *descr().tribe().get_worker_descr(ware); |
2378 | + const WorkerDescr & workerdescr = *descr().tribe().get_worker_descr(ware); |
2379 | return workerdescr.create(game, owner(), this, m_position); |
2380 | } |
2381 | } |
2382 | @@ -738,10 +829,13 @@ |
2383 | } |
2384 | } while (ware != INVALID_INDEX); |
2385 | |
2386 | - throw wexception("Warehouse::launch_worker: worker does not actually exist"); |
2387 | + throw wexception |
2388 | + ("Warehouse::launch_worker: worker does not actually exist"); |
2389 | } |
2390 | |
2391 | -void Warehouse::incorporate_worker(EditorGameBase& egbase, Worker* w) { |
2392 | + |
2393 | +void Warehouse::incorporate_worker(EditorGameBase & egbase, Worker* w) |
2394 | +{ |
2395 | assert(w != nullptr); |
2396 | assert(w->get_owner() == &owner()); |
2397 | |
2398 | @@ -767,10 +861,10 @@ |
2399 | |
2400 | // Incorporate the worker |
2401 | if (!m_incorporated_workers.count(worker_index)) |
2402 | - m_incorporated_workers[worker_index] = std::vector<Worker*>(); |
2403 | + m_incorporated_workers[worker_index] = std::vector<Worker *>(); |
2404 | m_incorporated_workers[worker_index].push_back(w); |
2405 | |
2406 | - w->set_location(nullptr); // no longer in an economy |
2407 | + w->set_location(nullptr); // no longer in an economy |
2408 | |
2409 | if (upcast(Game, game, &egbase)) { |
2410 | // Bind the worker into this house, hide him on the map. |
2411 | @@ -781,9 +875,9 @@ |
2412 | |
2413 | /// Create an instance of a ware and make sure it gets |
2414 | /// carried out of the warehouse. |
2415 | -WareInstance& Warehouse::launch_ware(Game& game, WareIndex const ware_index) { |
2416 | +WareInstance & Warehouse::launch_ware(Game & game, WareIndex const ware_index) { |
2417 | // Create the ware |
2418 | - WareInstance& ware = *new WareInstance(ware_index, descr().tribe().get_ware_descr(ware_index)); |
2419 | + WareInstance & ware = *new WareInstance(ware_index, descr().tribe().get_ware_descr(ware_index)); |
2420 | ware.init(game); |
2421 | do_launch_ware(game, ware); |
2422 | |
2423 | @@ -792,13 +886,15 @@ |
2424 | return ware; |
2425 | } |
2426 | |
2427 | + |
2428 | /// Get a carrier to actually move this ware out of the warehouse. |
2429 | -void Warehouse::do_launch_ware(Game& game, WareInstance& ware) { |
2430 | +void Warehouse::do_launch_ware(Game & game, WareInstance & ware) |
2431 | +{ |
2432 | // Create a carrier |
2433 | WareIndex const carrierid = descr().tribe().worker_index("carrier"); |
2434 | - const WorkerDescr& workerdescr = *descr().tribe().get_worker_descr(carrierid); |
2435 | + const WorkerDescr & workerdescr = *descr().tribe().get_worker_descr(carrierid); |
2436 | |
2437 | - Worker& worker = workerdescr.create(game, owner(), this, m_position); |
2438 | + Worker & worker = workerdescr.create(game, owner(), this, m_position); |
2439 | |
2440 | // Yup, this is cheating. |
2441 | if (m_supply->stock_workers(carrierid)) |
2442 | @@ -808,15 +904,23 @@ |
2443 | worker.start_task_dropoff(game, ware); |
2444 | } |
2445 | |
2446 | -void Warehouse::incorporate_ware(EditorGameBase& egbase, WareInstance* ware) { |
2447 | + |
2448 | +void Warehouse::incorporate_ware(EditorGameBase & egbase, WareInstance* ware) |
2449 | +{ |
2450 | m_supply->add_wares(ware->descr_index(), 1); |
2451 | ware->destroy(egbase); |
2452 | } |
2453 | |
2454 | + |
2455 | /// Called when a transfer for one of the idle Requests completes. |
2456 | -void Warehouse::request_cb( |
2457 | - Game& game, Request&, WareIndex const ware, Worker* const w, PlayerImmovable& target) { |
2458 | - Warehouse& wh = dynamic_cast<Warehouse&>(target); |
2459 | +void Warehouse::request_cb |
2460 | + (Game & game, |
2461 | + Request &, |
2462 | + WareIndex const ware, |
2463 | + Worker * const w, |
2464 | + PlayerImmovable & target) |
2465 | +{ |
2466 | + Warehouse & wh = dynamic_cast<Warehouse&>(target); |
2467 | |
2468 | if (w) { |
2469 | w->schedule_incorporate(game); |
2470 | @@ -833,35 +937,38 @@ |
2471 | /** |
2472 | * Receive a ware from a transfer that was not associated to a \ref Request. |
2473 | */ |
2474 | -void Warehouse::receive_ware(Game& /* game */, WareIndex ware) { |
2475 | +void Warehouse::receive_ware(Game & /* game */, WareIndex ware) |
2476 | +{ |
2477 | m_supply->add_wares(ware, 1); |
2478 | } |
2479 | |
2480 | /** |
2481 | * Receive a worker from a transfer that was not associated to a \ref Request. |
2482 | */ |
2483 | -void Warehouse::receive_worker(Game& game, Worker& worker) { |
2484 | +void Warehouse::receive_worker(Game & game, Worker & worker) |
2485 | +{ |
2486 | worker.schedule_incorporate(game); |
2487 | } |
2488 | |
2489 | -Building& WarehouseDescr::create_object() const { |
2490 | +Building & WarehouseDescr::create_object() const { |
2491 | return *new Warehouse(*this); |
2492 | } |
2493 | |
2494 | -bool Warehouse::can_create_worker(Game&, WareIndex const worker) const { |
2495 | + |
2496 | +bool Warehouse::can_create_worker(Game &, WareIndex const worker) const { |
2497 | if (!(worker < m_supply->get_workers().get_nrwareids())) |
2498 | - throw wexception("worker type %d does not exists (max is %d)", |
2499 | - worker, |
2500 | - m_supply->get_workers().get_nrwareids()); |
2501 | + throw wexception |
2502 | + ("worker type %d does not exists (max is %d)", |
2503 | + worker, m_supply->get_workers().get_nrwareids()); |
2504 | |
2505 | - const WorkerDescr& w_desc = *descr().tribe().get_worker_descr(worker); |
2506 | + const WorkerDescr & w_desc = *descr().tribe().get_worker_descr(worker); |
2507 | assert(&w_desc); |
2508 | if (!w_desc.is_buildable()) |
2509 | return false; |
2510 | |
2511 | // see if we have the resources |
2512 | for (const std::pair<std::string, uint8_t>& buildcost : w_desc.buildcost()) { |
2513 | - const std::string& input_name = buildcost.first; |
2514 | + const std::string & input_name = buildcost.first; |
2515 | WareIndex id_w = descr().tribe().ware_index(input_name); |
2516 | if (id_w != INVALID_INDEX) { |
2517 | if (m_supply->stock_wares(id_w) < buildcost.second) |
2518 | @@ -870,26 +977,27 @@ |
2519 | if (m_supply->stock_workers(id_w) < buildcost.second) |
2520 | return false; |
2521 | } else |
2522 | - throw wexception("worker type %s needs \"%s\" to be built but that is neither " |
2523 | - "a ware type nor a worker type defined in the tribe %s", |
2524 | - w_desc.descname().c_str(), |
2525 | - input_name.c_str(), |
2526 | - descr().tribe().name().c_str()); |
2527 | + throw wexception |
2528 | + ("worker type %s needs \"%s\" to be built but that is neither " |
2529 | + "a ware type nor a worker type defined in the tribe %s", |
2530 | + w_desc.descname().c_str(), input_name.c_str(), |
2531 | + descr().tribe().name().c_str()); |
2532 | } |
2533 | return true; |
2534 | } |
2535 | |
2536 | -void Warehouse::create_worker(Game& game, WareIndex const worker) { |
2537 | - assert(can_create_worker(game, worker)); |
2538 | - |
2539 | - const WorkerDescr& w_desc = *descr().tribe().get_worker_descr(worker); |
2540 | + |
2541 | +void Warehouse::create_worker(Game & game, WareIndex const worker) { |
2542 | + assert(can_create_worker (game, worker)); |
2543 | + |
2544 | + const WorkerDescr & w_desc = *descr().tribe().get_worker_descr(worker); |
2545 | |
2546 | for (const std::pair<std::string, uint8_t>& buildcost : w_desc.buildcost()) { |
2547 | - const std::string& input = buildcost.first; |
2548 | + const std::string & input = buildcost.first; |
2549 | WareIndex const id_ware = descr().tribe().ware_index(input); |
2550 | if (id_ware != INVALID_INDEX) { |
2551 | - remove_wares(id_ware, buildcost.second); |
2552 | - // update statistic accordingly |
2553 | + remove_wares (id_ware, buildcost.second); |
2554 | + //update statistic accordingly |
2555 | owner().ware_consumed(id_ware, buildcost.second); |
2556 | } else |
2557 | remove_workers(descr().tribe().safe_worker_index(input), buildcost.second); |
2558 | @@ -911,7 +1019,8 @@ |
2559 | * Return the number of workers of the given type that we plan to |
2560 | * create in this warehouse. |
2561 | */ |
2562 | -uint32_t Warehouse::get_planned_workers(Game& /* game */, WareIndex index) const { |
2563 | +uint32_t Warehouse::get_planned_workers(Game & /* game */, WareIndex index) const |
2564 | +{ |
2565 | for (const PlannedWorkers& pw : m_planned_workers) { |
2566 | if (pw.index == index) |
2567 | return pw.amount; |
2568 | @@ -925,21 +1034,23 @@ |
2569 | * |
2570 | * This is the current stock plus any incoming transfers. |
2571 | */ |
2572 | -std::vector<uint32_t> Warehouse::calc_available_for_worker(Game& /* game */, |
2573 | - WareIndex index) const { |
2574 | - const WorkerDescr& w_desc = *descr().tribe().get_worker_descr(index); |
2575 | +std::vector<uint32_t> Warehouse::calc_available_for_worker |
2576 | + (Game & /* game */, WareIndex index) const |
2577 | +{ |
2578 | + const WorkerDescr & w_desc = *descr().tribe().get_worker_descr(index); |
2579 | std::vector<uint32_t> available; |
2580 | |
2581 | for (const std::pair<std::string, uint8_t>& buildcost : w_desc.buildcost()) { |
2582 | - const std::string& input_name = buildcost.first; |
2583 | + const std::string & input_name = buildcost.first; |
2584 | WareIndex id_w = descr().tribe().ware_index(input_name); |
2585 | if (id_w != INVALID_INDEX) { |
2586 | available.push_back(get_wares().stock(id_w)); |
2587 | } else if ((id_w = descr().tribe().worker_index(input_name)) != INVALID_INDEX) { |
2588 | available.push_back(get_workers().stock(id_w)); |
2589 | } else |
2590 | - throw wexception( |
2591 | - "Economy::_create_requested_worker: buildcost inconsistency '%s'", input_name.c_str()); |
2592 | + throw wexception |
2593 | + ("Economy::_create_requested_worker: buildcost inconsistency '%s'", |
2594 | + input_name.c_str()); |
2595 | } |
2596 | |
2597 | for (const PlannedWorkers& pw : m_planned_workers) { |
2598 | @@ -955,12 +1066,14 @@ |
2599 | return available; |
2600 | } |
2601 | |
2602 | + |
2603 | /** |
2604 | * Set the amount of workers we plan to create |
2605 | * of the given \p index to \p amount. |
2606 | */ |
2607 | -void Warehouse::plan_workers(Game& game, WareIndex index, uint32_t amount) { |
2608 | - PlannedWorkers* pw = nullptr; |
2609 | +void Warehouse::plan_workers(Game & game, WareIndex index, uint32_t amount) |
2610 | +{ |
2611 | + PlannedWorkers * pw = nullptr; |
2612 | |
2613 | for (PlannedWorkers& planned_worker : m_planned_workers) { |
2614 | if (planned_worker.index == index) { |
2615 | @@ -978,17 +1091,22 @@ |
2616 | pw->index = index; |
2617 | pw->amount = 0; |
2618 | |
2619 | - const WorkerDescr& w_desc = *descr().tribe().get_worker_descr(pw->index); |
2620 | + const WorkerDescr & w_desc = *descr().tribe().get_worker_descr(pw->index); |
2621 | for (const std::pair<std::string, uint8_t>& buildcost : w_desc.buildcost()) { |
2622 | - const std::string& input_name = buildcost.first; |
2623 | + const std::string & input_name = buildcost.first; |
2624 | |
2625 | WareIndex id_w = descr().tribe().ware_index(input_name); |
2626 | if (id_w != INVALID_INDEX) { |
2627 | - pw->requests.push_back(new Request(*this, id_w, &Warehouse::request_cb, wwWARE)); |
2628 | + pw->requests.push_back |
2629 | + (new Request |
2630 | + (*this, id_w, &Warehouse::request_cb, wwWARE)); |
2631 | } else if ((id_w = descr().tribe().worker_index(input_name)) != INVALID_INDEX) { |
2632 | - pw->requests.push_back(new Request(*this, id_w, &Warehouse::request_cb, wwWORKER)); |
2633 | + pw->requests.push_back |
2634 | + (new Request |
2635 | + (*this, id_w, &Warehouse::request_cb, wwWORKER)); |
2636 | } else |
2637 | - throw wexception("plan_workers: bad buildcost '%s'", input_name.c_str()); |
2638 | + throw wexception |
2639 | + ("plan_workers: bad buildcost '%s'", input_name.c_str()); |
2640 | } |
2641 | } |
2642 | |
2643 | @@ -1000,8 +1118,10 @@ |
2644 | * See if we can create the workers of the given plan, |
2645 | * and update requests accordingly. |
2646 | */ |
2647 | -void Warehouse::_update_planned_workers(Game& game, Warehouse::PlannedWorkers& pw) { |
2648 | - const WorkerDescr& w_desc = *descr().tribe().get_worker_descr(pw.index); |
2649 | +void Warehouse::_update_planned_workers |
2650 | + (Game & game, Warehouse::PlannedWorkers & pw) |
2651 | +{ |
2652 | + const WorkerDescr & w_desc = *descr().tribe().get_worker_descr(pw.index); |
2653 | |
2654 | while (pw.amount && can_create_worker(game, pw.index)) { |
2655 | create_worker(game, pw.index); |
2656 | @@ -1010,7 +1130,7 @@ |
2657 | uint32_t idx = 0; |
2658 | for (const std::pair<std::string, uint8_t>& buildcost : w_desc.buildcost()) { |
2659 | |
2660 | - const std::string& input_name = buildcost.first; |
2661 | + const std::string & input_name = buildcost.first; |
2662 | uint32_t supply; |
2663 | |
2664 | WareIndex id_w = descr().tribe().ware_index(input_name); |
2665 | @@ -1019,12 +1139,14 @@ |
2666 | } else if ((id_w = descr().tribe().worker_index(input_name)) != INVALID_INDEX) { |
2667 | supply = m_supply->stock_workers(id_w); |
2668 | } else |
2669 | - throw wexception("_update_planned_workers: bad buildcost '%s'", input_name.c_str()); |
2670 | + throw wexception |
2671 | + ("_update_planned_workers: bad buildcost '%s'", input_name.c_str()); |
2672 | |
2673 | if (supply >= pw.amount * buildcost.second) |
2674 | pw.requests[idx]->set_count(0); |
2675 | else |
2676 | - pw.requests[idx]->set_count(pw.amount * buildcost.second - supply); |
2677 | + pw.requests[idx]->set_count |
2678 | + (pw.amount * buildcost.second - supply); |
2679 | ++idx; |
2680 | } |
2681 | |
2682 | @@ -1040,7 +1162,8 @@ |
2683 | * Needs to be called periodically, because some necessary supplies might arrive |
2684 | * due to idle transfers instead of by explicit request. |
2685 | */ |
2686 | -void Warehouse::_update_all_planned_workers(Game& game) { |
2687 | +void Warehouse::_update_all_planned_workers(Game & game) |
2688 | +{ |
2689 | uint32_t idx = 0; |
2690 | while (idx < m_planned_workers.size()) { |
2691 | _update_planned_workers(game, m_planned_workers[idx]); |
2692 | @@ -1054,35 +1177,51 @@ |
2693 | } |
2694 | } |
2695 | |
2696 | -void Warehouse::enable_spawn(Game& game, uint8_t const worker_types_without_cost_index) { |
2697 | - assert(m_next_worker_without_cost_spawn[worker_types_without_cost_index] == |
2698 | - static_cast<uint32_t>(never())); |
2699 | +void Warehouse::enable_spawn |
2700 | + (Game & game, uint8_t const worker_types_without_cost_index) |
2701 | +{ |
2702 | + assert |
2703 | + (m_next_worker_without_cost_spawn[worker_types_without_cost_index] |
2704 | + == |
2705 | + static_cast<uint32_t>(never())); |
2706 | m_next_worker_without_cost_spawn[worker_types_without_cost_index] = |
2707 | - schedule_act(game, WORKER_WITHOUT_COST_SPAWN_INTERVAL); |
2708 | + schedule_act(game, WORKER_WITHOUT_COST_SPAWN_INTERVAL); |
2709 | } |
2710 | -void Warehouse::disable_spawn(uint8_t const worker_types_without_cost_index) { |
2711 | - assert(m_next_worker_without_cost_spawn[worker_types_without_cost_index] != |
2712 | - static_cast<uint32_t>(never())); |
2713 | +void Warehouse::disable_spawn(uint8_t const worker_types_without_cost_index) |
2714 | +{ |
2715 | + assert |
2716 | + (m_next_worker_without_cost_spawn[worker_types_without_cost_index] |
2717 | + != |
2718 | + static_cast<uint32_t>(never())); |
2719 | m_next_worker_without_cost_spawn[worker_types_without_cost_index] = never(); |
2720 | } |
2721 | |
2722 | -bool Warehouse::can_attack() { |
2723 | + |
2724 | +bool Warehouse::can_attack() |
2725 | +{ |
2726 | return descr().get_conquers() > 0; |
2727 | } |
2728 | |
2729 | -void Warehouse::aggressor(Soldier& enemy) { |
2730 | +void Warehouse::aggressor(Soldier & enemy) |
2731 | +{ |
2732 | if (!descr().get_conquers()) |
2733 | return; |
2734 | |
2735 | - Game& game = dynamic_cast<Game&>(owner().egbase()); |
2736 | - Map& map = game.map(); |
2737 | - if (enemy.get_owner() == &owner() || enemy.get_battle() || |
2738 | - descr().get_conquers() <= map.calc_distance(enemy.get_position(), get_position())) |
2739 | + Game & game = dynamic_cast<Game&>(owner().egbase()); |
2740 | + Map & map = game.map(); |
2741 | + if |
2742 | + (enemy.get_owner() == &owner() || |
2743 | + enemy.get_battle() || |
2744 | + descr().get_conquers() |
2745 | + <= |
2746 | + map.calc_distance(enemy.get_position(), get_position())) |
2747 | return; |
2748 | |
2749 | - if (game.map().find_bobs(Area<FCoords>(map.get_fcoords(base_flag().get_position()), 2), |
2750 | - nullptr, |
2751 | - FindBobEnemySoldier(&owner()))) |
2752 | + if |
2753 | + (game.map().find_bobs |
2754 | + (Area<FCoords>(map.get_fcoords(base_flag().get_position()), 2), |
2755 | + nullptr, |
2756 | + FindBobEnemySoldier(&owner()))) |
2757 | return; |
2758 | |
2759 | WareIndex const soldier_index = descr().tribe().worker_index("soldier"); |
2760 | @@ -1091,17 +1230,18 @@ |
2761 | if (!count_workers(game, soldier_index, noreq)) |
2762 | return; |
2763 | |
2764 | - Soldier& defender = dynamic_cast<Soldier&>(launch_worker(game, soldier_index, noreq)); |
2765 | + Soldier & defender = dynamic_cast<Soldier&>(launch_worker(game, soldier_index, noreq)); |
2766 | defender.start_task_defense(game, false); |
2767 | } |
2768 | |
2769 | -bool Warehouse::attack(Soldier& enemy) { |
2770 | - Game& game = dynamic_cast<Game&>(owner().egbase()); |
2771 | +bool Warehouse::attack(Soldier & enemy) |
2772 | +{ |
2773 | + Game & game = dynamic_cast<Game&>(owner().egbase()); |
2774 | WareIndex const soldier_index = descr().tribe().worker_index("soldier"); |
2775 | Requirements noreq; |
2776 | |
2777 | if (count_workers(game, soldier_index, noreq)) { |
2778 | - Soldier& defender = dynamic_cast<Soldier&>(launch_worker(game, soldier_index, noreq)); |
2779 | + Soldier & defender = dynamic_cast<Soldier&>(launch_worker(game, soldier_index, noreq)); |
2780 | defender.start_task_defense(game, true); |
2781 | enemy.send_signal(game, "sleep"); |
2782 | return true; |
2783 | @@ -1112,36 +1252,45 @@ |
2784 | return false; |
2785 | } |
2786 | |
2787 | -void Warehouse::PlannedWorkers::cleanup() { |
2788 | +void Warehouse::PlannedWorkers::cleanup() |
2789 | +{ |
2790 | while (!requests.empty()) { |
2791 | delete requests.back(); |
2792 | requests.pop_back(); |
2793 | } |
2794 | } |
2795 | |
2796 | -Warehouse::StockPolicy Warehouse::get_ware_policy(WareIndex ware) const { |
2797 | +Warehouse::StockPolicy Warehouse::get_ware_policy(WareIndex ware) const |
2798 | +{ |
2799 | assert(ware < m_ware_policy.size()); |
2800 | return m_ware_policy[ware]; |
2801 | } |
2802 | |
2803 | -Warehouse::StockPolicy Warehouse::get_worker_policy(WareIndex ware) const { |
2804 | +Warehouse::StockPolicy Warehouse::get_worker_policy(WareIndex ware) const |
2805 | +{ |
2806 | assert(ware < m_worker_policy.size()); |
2807 | return m_worker_policy[ware]; |
2808 | } |
2809 | |
2810 | -Warehouse::StockPolicy Warehouse::get_stock_policy(WareWorker waretype, WareIndex wareindex) const { |
2811 | +Warehouse::StockPolicy Warehouse::get_stock_policy |
2812 | + (WareWorker waretype, WareIndex wareindex) const |
2813 | +{ |
2814 | if (waretype == wwWORKER) |
2815 | return get_worker_policy(wareindex); |
2816 | else |
2817 | return get_ware_policy(wareindex); |
2818 | } |
2819 | |
2820 | -void Warehouse::set_ware_policy(WareIndex ware, Warehouse::StockPolicy policy) { |
2821 | + |
2822 | +void Warehouse::set_ware_policy(WareIndex ware, Warehouse::StockPolicy policy) |
2823 | +{ |
2824 | assert(ware < m_ware_policy.size()); |
2825 | m_ware_policy[ware] = policy; |
2826 | } |
2827 | |
2828 | -void Warehouse::set_worker_policy(WareIndex ware, Warehouse::StockPolicy policy) { |
2829 | +void Warehouse::set_worker_policy |
2830 | + (WareIndex ware, Warehouse::StockPolicy policy) |
2831 | +{ |
2832 | assert(ware < m_worker_policy.size()); |
2833 | m_worker_policy[ware] = policy; |
2834 | } |
2835 | @@ -1150,7 +1299,8 @@ |
2836 | * Check if there are remaining wares with stock policy \ref SP_Remove, |
2837 | * and remove one of them if appropriate. |
2838 | */ |
2839 | -void Warehouse::check_remove_stock(Game& game) { |
2840 | +void Warehouse::check_remove_stock(Game & game) |
2841 | +{ |
2842 | if (base_flag().current_wares() < base_flag().total_capacity() / 2) { |
2843 | for (WareIndex ware = 0; ware < m_ware_policy.size(); ++ware) { |
2844 | if (get_ware_policy(ware) != SP_Remove || !get_wares().stock(ware)) |
2845 | @@ -1165,7 +1315,7 @@ |
2846 | if (get_worker_policy(widx) != SP_Remove || !get_workers().stock(widx)) |
2847 | continue; |
2848 | |
2849 | - Worker& worker = launch_worker(game, widx, Requirements()); |
2850 | + Worker & worker = launch_worker(game, widx, Requirements()); |
2851 | worker.start_task_leavebuilding(game, true); |
2852 | break; |
2853 | } |
2854 | @@ -1181,34 +1331,36 @@ |
2855 | /* |
2856 | * SoldierControl implementations |
2857 | */ |
2858 | -std::vector<Soldier*> Warehouse::present_soldiers() const { |
2859 | - std::vector<Soldier*> rv; |
2860 | +std::vector<Soldier *> Warehouse::present_soldiers() const |
2861 | +{ |
2862 | + std::vector<Soldier *> rv; |
2863 | |
2864 | WareIndex const ware = descr().tribe().safe_worker_index("soldier"); |
2865 | IncorporatedWorkers::const_iterator sidx = m_incorporated_workers.find(ware); |
2866 | |
2867 | if (sidx != m_incorporated_workers.end()) { |
2868 | - const WorkerList& soldiers = sidx->second; |
2869 | + const WorkerList & soldiers = sidx->second; |
2870 | |
2871 | - for (Worker* temp_soldier : soldiers) { |
2872 | - rv.push_back(static_cast<Soldier*>(temp_soldier)); |
2873 | + for (Worker * temp_soldier: soldiers) { |
2874 | + rv.push_back(static_cast<Soldier *>(temp_soldier)); |
2875 | } |
2876 | } |
2877 | |
2878 | return rv; |
2879 | } |
2880 | -int Warehouse::incorporate_soldier(EditorGameBase& egbase, Soldier& soldier) { |
2881 | +int Warehouse::incorporate_soldier(EditorGameBase & egbase, Soldier & soldier) { |
2882 | incorporate_worker(egbase, &soldier); |
2883 | return 0; |
2884 | } |
2885 | |
2886 | -int Warehouse::outcorporate_soldier(EditorGameBase& /* egbase */, Soldier& soldier) { |
2887 | +int Warehouse::outcorporate_soldier(EditorGameBase & /* egbase */, Soldier & soldier) { |
2888 | |
2889 | WareIndex const ware = descr().tribe().safe_worker_index("soldier"); |
2890 | if (m_incorporated_workers.count(ware)) { |
2891 | - WorkerList& soldiers = m_incorporated_workers[ware]; |
2892 | + WorkerList & soldiers = m_incorporated_workers[ware]; |
2893 | |
2894 | - WorkerList::iterator i = std::find(soldiers.begin(), soldiers.end(), &soldier); |
2895 | + WorkerList::iterator i = std::find |
2896 | + (soldiers.begin(), soldiers.end(), &soldier); |
2897 | |
2898 | soldiers.erase(i); |
2899 | m_supply->remove_workers(ware, 1); |
2900 | @@ -1221,10 +1373,13 @@ |
2901 | return 0; |
2902 | } |
2903 | |
2904 | -void Warehouse::log_general_info(const EditorGameBase& egbase) { |
2905 | +void Warehouse::log_general_info(const EditorGameBase & egbase) |
2906 | +{ |
2907 | Building::log_general_info(egbase); |
2908 | |
2909 | if (descr().get_isport()) |
2910 | molog("Port dock: %u\n", m_portdock ? m_portdock->serial() : 0); |
2911 | } |
2912 | + |
2913 | + |
2914 | } |
2915 | |
2916 | === modified file 'src/logic/worker.cc' |
2917 | --- src/logic/worker.cc 2014-12-11 12:38:10 +0000 |
2918 | +++ src/logic/worker.cc 2014-12-28 17:03:29 +0000 |
2919 | @@ -938,12 +938,24 @@ |
2920 | % rdescr->name().c_str() |
2921 | % _("A geologist found resources.")).str(); |
2922 | |
2923 | + Message::Type message_type = Message::Type::kGeologists; |
2924 | + if (rdescr->name() == "coal") |
2925 | + message_type = Message::Type::kGeologistsCoal; |
2926 | + else if (rdescr->name() == "gold") |
2927 | + message_type = Message::Type::kGeologistsGold; |
2928 | + else if (rdescr->name() == "granite") |
2929 | + message_type = Message::Type::kGeologistsGranite; |
2930 | + else if (rdescr->name() == "iron") |
2931 | + message_type = Message::Type::kGeologistsIron; |
2932 | + else if (rdescr->name() == "water") |
2933 | + message_type = Message::Type::kGeologistsWater; |
2934 | + |
2935 | // We should add a message to the player's message queue - but only, |
2936 | // if there is not already a similar one in list. |
2937 | owner().add_message_with_timeout |
2938 | (game, |
2939 | *new Message |
2940 | - ("geologist " + rdescr->name(), // e.g. "geologist gold" |
2941 | + (message_type, |
2942 | game.get_gametime(), |
2943 | rdescr->descname(), |
2944 | message, |
2945 | @@ -1843,7 +1855,7 @@ |
2946 | owner().add_message |
2947 | (game, |
2948 | *new Message |
2949 | - ("game engine", |
2950 | + (Message::Type::kGameLogic, |
2951 | game.get_gametime(), |
2952 | _("Worker got lost!"), |
2953 | message, |
2954 | |
2955 | === modified file 'src/map_io/map_players_messages_packet.cc' |
2956 | --- src/map_io/map_players_messages_packet.cc 2014-10-27 10:14:10 +0000 |
2957 | +++ src/map_io/map_players_messages_packet.cc 2014-12-28 17:03:29 +0000 |
2958 | @@ -22,6 +22,7 @@ |
2959 | #include <boost/format.hpp> |
2960 | |
2961 | #include "logic/game_data_error.h" |
2962 | +#include "logic/message.h" |
2963 | #include "logic/player.h" |
2964 | #include "map_io/coords_profile.h" |
2965 | #include "map_io/map_object_loader.h" |
2966 | @@ -64,14 +65,14 @@ |
2967 | "added it to the queue. This is only allowed during " |
2968 | "simulation, not at load. The following messge will be " |
2969 | "removed when the queue is reset:\n" |
2970 | - "\tsender : %s\n" |
2971 | + "\tstype : %u\n" |
2972 | "\ttitle : %s\n" |
2973 | "\tsent : %u\n" |
2974 | "\tposition: (%i, %i)\n" |
2975 | "\tstatus : %u\n" |
2976 | "\tbody : %s\n", |
2977 | p, |
2978 | - begin->second->sender ().c_str(), |
2979 | + begin->second->type (), |
2980 | begin->second->title ().c_str(), |
2981 | begin->second->sent (), |
2982 | begin->second->position().x, begin->second->position().y, |
2983 | @@ -98,13 +99,13 @@ |
2984 | "gametime is only %u", |
2985 | sent, gametime); |
2986 | |
2987 | - Message::Status status = Message::Archived; // default status |
2988 | + Message::Status status = Message::Status::kArchived; // default status |
2989 | if (char const * const status_string = s->get_string("status")) { |
2990 | try { |
2991 | if (!strcmp(status_string, "new")) |
2992 | - status = Message::New; |
2993 | + status = Message::Status::kNew; |
2994 | else if (!strcmp(status_string, "read")) |
2995 | - status = Message::Read; |
2996 | + status = Message::Status::kRead; |
2997 | else |
2998 | throw GameDataError |
2999 | ("expected %s but found \"%s\"", |
3000 | @@ -123,7 +124,7 @@ |
3001 | |
3002 | messages.add_message |
3003 | (*new Message |
3004 | - (s->get_string ("sender", ""), |
3005 | + (static_cast<Message::Type>(s->get_natural("type")), |
3006 | sent, |
3007 | s->get_name (), |
3008 | s->get_safe_string("body"), |
3009 | @@ -159,20 +160,19 @@ |
3010 | assert(message.sent() <= static_cast<uint32_t>(egbase.get_gametime())); |
3011 | |
3012 | Section & s = prof.create_section_duplicate(message.title().c_str()); |
3013 | - if (message.sender().size()) |
3014 | - s.set_string("sender", message.sender ()); |
3015 | - s.set_int ("sent", message.sent ()); |
3016 | - s.set_string ("body", message.body ()); |
3017 | - if (Coords const c = message.position()) |
3018 | + s.set_int ("type", static_cast<int32_t>(message.type())); |
3019 | + s.set_int ("sent", message.sent ()); |
3020 | + s.set_string ("body", message.body ()); |
3021 | + if (Coords const c = message.position()) |
3022 | set_coords("position", c, &s); |
3023 | switch (message.status()) { |
3024 | - case Message::New: |
3025 | + case Message::Status::kNew: |
3026 | s.set_string("status", "new"); |
3027 | break; |
3028 | - case Message::Read: |
3029 | + case Message::Status::kRead: |
3030 | s.set_string("status", "read"); |
3031 | break; |
3032 | - case Message::Archived: // The default status. Do not write. |
3033 | + case Message::Status::kArchived: // The default status. Do not write. |
3034 | break; |
3035 | default: |
3036 | assert(false); |
3037 | |
3038 | === modified file 'src/scripting/lua_game.cc' |
3039 | --- src/scripting/lua_game.cc 2014-11-18 19:30:39 +0000 |
3040 | +++ src/scripting/lua_game.cc 2014-12-28 17:03:29 +0000 |
3041 | @@ -28,6 +28,7 @@ |
3042 | #include "logic/campaign_visibility.h" |
3043 | #include "logic/constants.h" |
3044 | #include "logic/game_controller.h" |
3045 | +#include "logic/message.h" |
3046 | #include "logic/objective.h" |
3047 | #include "logic/path.h" |
3048 | #include "logic/player.h" |
3049 | @@ -202,7 +203,7 @@ |
3050 | lua_newtable(L); |
3051 | uint32_t cidx = 1; |
3052 | for (const std::pair<MessageId, Message *>& temp_message : p.messages()) { |
3053 | - if (temp_message.second->status() == Message::Archived) |
3054 | + if (temp_message.second->status() == Message::Status::kArchived) |
3055 | continue; |
3056 | |
3057 | lua_pushuint32(L, cidx ++); |
3058 | @@ -276,9 +277,6 @@ |
3059 | 'archived'. Default: "new" |
3060 | :type status: :class:`string` |
3061 | |
3062 | - :arg sender: sender name of this string. Default: "ScriptingEngine" |
3063 | - :type sender: :class:`string` |
3064 | - |
3065 | :arg popup: should the message window be opened for this message or not. |
3066 | Default: :const:`false` |
3067 | :type popup: :class:`boolean` |
3068 | @@ -291,8 +289,7 @@ |
3069 | std::string title = luaL_checkstring(L, 2); |
3070 | std::string body = luaL_checkstring(L, 3); |
3071 | Coords c = Coords::null(); |
3072 | - Message::Status st = Message::New; |
3073 | - std::string sender = "ScriptingEngine"; |
3074 | + Message::Status st = Message::Status::kNew; |
3075 | bool popup = false; |
3076 | |
3077 | if (n == 4) { |
3078 | @@ -305,18 +302,13 @@ |
3079 | lua_getfield(L, 4, "status"); |
3080 | if (!lua_isnil(L, -1)) { |
3081 | std::string s = luaL_checkstring(L, -1); |
3082 | - if (s == "new") st = Message::New; |
3083 | - else if (s == "read") st = Message::Read; |
3084 | - else if (s == "archived") st = Message::Archived; |
3085 | + if (s == "new") st = Message::Status::kNew; |
3086 | + else if (s == "read") st = Message::Status::kRead; |
3087 | + else if (s == "archived") st = Message::Status::kArchived; |
3088 | else report_error(L, "Unknown message status: %s", s.c_str()); |
3089 | } |
3090 | lua_pop(L, 1); |
3091 | |
3092 | - lua_getfield(L, 4, "sender"); |
3093 | - if (!lua_isnil(L, -1)) |
3094 | - sender = luaL_checkstring(L, -1); |
3095 | - lua_pop(L, 1); |
3096 | - |
3097 | lua_getfield(L, 4, "popup"); |
3098 | if (!lua_isnil(L, -1)) |
3099 | popup = luaL_checkboolean(L, -1); |
3100 | @@ -330,7 +322,7 @@ |
3101 | plr.add_message |
3102 | (game, |
3103 | *new Message |
3104 | - (sender, |
3105 | + (Message::Type::kScenario, |
3106 | game.get_gametime(), |
3107 | title, |
3108 | body, |
3109 | @@ -1048,7 +1040,6 @@ |
3110 | {nullptr, nullptr}, |
3111 | }; |
3112 | const PropertyType<LuaMessage> LuaMessage::Properties[] = { |
3113 | - PROP_RO(LuaMessage, sender), |
3114 | PROP_RO(LuaMessage, title), |
3115 | PROP_RO(LuaMessage, body), |
3116 | PROP_RO(LuaMessage, sent), |
3117 | @@ -1078,15 +1069,7 @@ |
3118 | PROPERTIES |
3119 | ========================================================== |
3120 | */ |
3121 | -/* RST |
3122 | - .. attribute:: sender |
3123 | |
3124 | - (RO) The name of the sender of this message |
3125 | -*/ |
3126 | -int LuaMessage::get_sender(lua_State * L) { |
3127 | - lua_pushstring(L, get(L, get_game(L)).sender()); |
3128 | - return 1; |
3129 | -} |
3130 | /* RST |
3131 | .. attribute:: title |
3132 | |
3133 | @@ -1140,19 +1123,19 @@ |
3134 | */ |
3135 | int LuaMessage::get_status(lua_State * L) { |
3136 | switch (get(L, get_game(L)).status()) { |
3137 | - case Message::New: lua_pushstring(L, "new"); break; |
3138 | - case Message::Read: lua_pushstring(L, "read"); break; |
3139 | - case Message::Archived: lua_pushstring(L, "archived"); break; |
3140 | + case Message::Status::kNew: lua_pushstring(L, "new"); break; |
3141 | + case Message::Status::kRead: lua_pushstring(L, "read"); break; |
3142 | + case Message::Status::kArchived: lua_pushstring(L, "archived"); break; |
3143 | default: report_error(L, "Unknown Message status encountered!"); |
3144 | } |
3145 | return 1; |
3146 | } |
3147 | int LuaMessage::set_status(lua_State * L) { |
3148 | - Message::Status status = Message::New; |
3149 | + Message::Status status = Message::Status::kNew; |
3150 | std::string s = luaL_checkstring(L, -1); |
3151 | - if (s == "new") status = Message::New; |
3152 | - else if (s == "read") status = Message::Read; |
3153 | - else if (s == "archived") status = Message::Archived; |
3154 | + if (s == "new") status = Message::Status::kNew; |
3155 | + else if (s == "read") status = Message::Status::kRead; |
3156 | + else if (s == "archived") status = Message::Status::kArchived; |
3157 | else report_error(L, "Invalid message status <%s>!", s.c_str()); |
3158 | |
3159 | get_plr(L, get_game(L)).messages().set_message_status(m_mid, status); |
3160 | |
3161 | === modified file 'src/scripting/lua_game.h' |
3162 | --- src/scripting/lua_game.h 2014-09-18 18:56:20 +0000 |
3163 | +++ src/scripting/lua_game.h 2014-12-28 17:03:29 +0000 |
3164 | @@ -161,7 +161,6 @@ |
3165 | /* |
3166 | * Properties |
3167 | */ |
3168 | - int get_sender(lua_State * L); |
3169 | int get_sent(lua_State * L); |
3170 | int get_title(lua_State * L); |
3171 | int get_body(lua_State * L); |
3172 | |
3173 | === modified file 'src/wui/game_message_menu.cc' |
3174 | --- src/wui/game_message_menu.cc 2014-11-30 18:49:38 +0000 |
3175 | +++ src/wui/game_message_menu.cc 2014-12-28 17:03:29 +0000 |
3176 | @@ -20,6 +20,7 @@ |
3177 | #include "wui/game_message_menu.h" |
3178 | |
3179 | #include <boost/bind.hpp> |
3180 | +#include <boost/format.hpp> |
3181 | |
3182 | #include "base/time_string.h" |
3183 | #include "graphic/graphic.h" |
3184 | @@ -45,11 +46,12 @@ |
3185 | (&plr, "messages", ®istry, 580, 375, _("Messages: Inbox")), |
3186 | message_body |
3187 | (this, |
3188 | - 5, 150, 570, 220, |
3189 | + 5, 154, 570, 216, |
3190 | "", UI::Align_Left, 1), |
3191 | mode(Inbox) |
3192 | { |
3193 | - list = new UI::Table<uintptr_t>(this, 5, 35, 570, 110); |
3194 | + |
3195 | + list = new UI::Table<uintptr_t>(this, 5, message_body.get_y() - 110, 570, 110); |
3196 | list->selected.connect(boost::bind(&GameMessageMenu::selected, this, _1)); |
3197 | list->double_clicked.connect(boost::bind(&GameMessageMenu::double_clicked, this, _1)); |
3198 | list->add_column (60, _("Select"), "", UI::Align_HCenter, true); |
3199 | @@ -58,39 +60,105 @@ |
3200 | list->add_column(120, _("Time sent")); |
3201 | list->focus(); |
3202 | |
3203 | + // Buttons for message types |
3204 | + m_geologistsbtn = |
3205 | + new UI::Button |
3206 | + (this, "filter_geologists_messages", |
3207 | + 5, 5, 34, 34, |
3208 | + g_gr->images().get("pics/but0.png"), |
3209 | + g_gr->images().get("pics/menu_geologist.png"), |
3210 | + "", |
3211 | + true); |
3212 | + m_geologistsbtn->sigclicked.connect |
3213 | + (boost::bind(&GameMessageMenu::filter_messages, this, Widelands::Message::Type::kGeologists)); |
3214 | + |
3215 | + m_economybtn = |
3216 | + new UI::Button |
3217 | + (this, "filter_economy_messages", |
3218 | + 2 * 5 + 34, 5, 34, 34, |
3219 | + g_gr->images().get("pics/but0.png"), |
3220 | + g_gr->images().get("pics/menu_build_flag.png"), |
3221 | + "", |
3222 | + true); |
3223 | + m_economybtn->sigclicked.connect |
3224 | + (boost::bind(&GameMessageMenu::filter_messages, this, Widelands::Message::Type::kEconomy)); |
3225 | + |
3226 | + m_seafaringbtn = |
3227 | + new UI::Button |
3228 | + (this, "filter_seafaring_messages", |
3229 | + 3 * 5 + 2 * 34, 5, 34, 34, |
3230 | + g_gr->images().get("pics/but0.png"), |
3231 | + g_gr->images().get("pics/start_expedition.png"), |
3232 | + "", |
3233 | + true); |
3234 | + m_seafaringbtn->sigclicked.connect |
3235 | + (boost::bind(&GameMessageMenu::filter_messages, this, Widelands::Message::Type::kSeafaring)); |
3236 | + |
3237 | + m_warfarebtn = |
3238 | + new UI::Button |
3239 | + (this, "filter_warfare_messages", |
3240 | + 4 * 5 + 3 * 34, 5, 34, 34, |
3241 | + g_gr->images().get("pics/but0.png"), |
3242 | + g_gr->images().get("pics/messages_warfare.png"), |
3243 | + "", |
3244 | + true); |
3245 | + m_warfarebtn->sigclicked.connect |
3246 | + (boost::bind(&GameMessageMenu::filter_messages, this, Widelands::Message::Type::kWarfare)); |
3247 | + |
3248 | + m_scenariobtn = |
3249 | + new UI::Button |
3250 | + (this, "filter_scenario_messages", |
3251 | + 5 * 5 + 4 * 34, 5, 34, 34, |
3252 | + g_gr->images().get("pics/but0.png"), |
3253 | + g_gr->images().get("pics/menu_objectives.png"), |
3254 | + "", |
3255 | + true); |
3256 | + m_scenariobtn->sigclicked.connect |
3257 | + (boost::bind(&GameMessageMenu::filter_messages, this, Widelands::Message::Type::kScenario)); |
3258 | + |
3259 | + m_message_filter = Widelands::Message::Type::kAllMessages; |
3260 | + set_filter_messages_tooltips(); |
3261 | + // End: Buttons for message types |
3262 | + |
3263 | UI::Button * clearselectionbtn = |
3264 | new UI::Button |
3265 | (this, "clear_selection", |
3266 | - 5, 5, 140, 25, |
3267 | - g_gr->images().get("pics/but0.png"), |
3268 | - _("Clear"), _("Clear selection")); |
3269 | + 5 * 5 + 6 * 34 + 17, 5, 34, 34, |
3270 | + g_gr->images().get("pics/but2.png"), |
3271 | + g_gr->images().get("pics/message_clear_selection.png"), |
3272 | + _("Clear selection")); |
3273 | clearselectionbtn->sigclicked.connect |
3274 | (boost::bind(&GameMessageMenu::do_clear_selection, this)); |
3275 | |
3276 | UI::Button * invertselectionbtn = |
3277 | new UI::Button |
3278 | (this, "invert_selection", |
3279 | - 150, 5, 140, 25, |
3280 | - g_gr->images().get("pics/but0.png"), |
3281 | - _("Invert"), _("Invert selection")); |
3282 | + 6 * 5 + 7 * 34 + 17, 5, 34, 34, |
3283 | + g_gr->images().get("pics/but2.png"), |
3284 | + g_gr->images().get("pics/message_selection_invert.png"), |
3285 | + _("Invert selection")); |
3286 | invertselectionbtn->sigclicked.connect |
3287 | (boost::bind(&GameMessageMenu::do_invert_selection, this)); |
3288 | |
3289 | m_archivebtn = |
3290 | new UI::Button |
3291 | (this, "archive_or_restore_selected_messages", |
3292 | - 295, 5, 25, 25, |
3293 | + 6 * 5 + 9 * 34 + 34, 5, 34, 34, |
3294 | g_gr->images().get("pics/but2.png"), |
3295 | g_gr->images().get("pics/message_archive.png"), |
3296 | - _("Archive selected messages")); |
3297 | + /** TRANSLATORS: %s is a tooltip, Del is the corresponding hotkey */ |
3298 | + (boost::format(_("Del: %s")) |
3299 | + /** TRANSLATORS: Tooltip in the messages window */ |
3300 | + % _("Archive selected messages")).str()); |
3301 | m_archivebtn->sigclicked.connect |
3302 | (boost::bind(&GameMessageMenu::archive_or_restore, this)); |
3303 | |
3304 | m_togglemodebtn = |
3305 | new UI::Button |
3306 | (this, "toggle_between_inbox_or_archive", |
3307 | - 325, 5, 190, 25, |
3308 | + 7 * 5 + 10 * 34 + 34, 5, 34, 34, |
3309 | g_gr->images().get("pics/but2.png"), |
3310 | + g_gr->images().get("pics/message_archived.png"), |
3311 | _("Show Archive")); |
3312 | m_togglemodebtn->sigclicked.connect |
3313 | (boost::bind(&GameMessageMenu::toggle_mode, this)); |
3314 | @@ -98,13 +166,24 @@ |
3315 | m_centerviewbtn = |
3316 | new UI::Button |
3317 | (this, "center_main_mapview_on_location", |
3318 | - 550, 5, 25, 25, |
3319 | + 580 - 5 - 34, 5, 34, 34, |
3320 | g_gr->images().get("pics/but2.png"), |
3321 | g_gr->images().get("pics/menu_goto.png"), |
3322 | - _("center main mapview on location"), |
3323 | + /** TRANSLATORS: %s is a tooltip, G is the corresponding hotkey */ |
3324 | + (boost::format(_("G: %s")) |
3325 | + /** TRANSLATORS: Tooltip in the messages window */ |
3326 | + % _("Center main mapview on location")).str(), |
3327 | false); |
3328 | m_centerviewbtn->sigclicked.connect(boost::bind(&GameMessageMenu::center_view, this)); |
3329 | |
3330 | + |
3331 | + m_display_message_type_label = |
3332 | + new UI::MultilineTextarea |
3333 | + (this, |
3334 | + 5, 375 - 5 - 34, 5 * 34, 40, |
3335 | + "<rt image=pics/message_new.png></rt>", |
3336 | + UI::Align::Align_BottomLeft, false); |
3337 | + |
3338 | if (get_usedefaultpos()) |
3339 | center_to_parent(); |
3340 | |
3341 | @@ -127,7 +206,7 @@ |
3342 | const Message * msgb = mq[MessageId((*list)[b])]; |
3343 | |
3344 | if (msga && msgb) { |
3345 | - return msga->status() == Message::New && msgb->status() != Message::New; |
3346 | + return msga->status() == Message::Status::kNew && msgb->status() != Message::Status::kNew; |
3347 | } |
3348 | return false; // shouldn't happen |
3349 | } |
3350 | @@ -144,7 +223,7 @@ |
3351 | assert(iplayer().player().messages()[id] == &message); |
3352 | assert(!list->find(id.value())); |
3353 | Message::Status const status = message.status(); |
3354 | - if ((mode == Archive) != (status == Message::Archived)) |
3355 | + if ((mode == Archive) != (status == Message::Status::kArchived)) |
3356 | toggle_mode(); |
3357 | UI::Table<uintptr_t>::EntryRecord & te = list->add(id.value(), true); |
3358 | update_record(te, message); |
3359 | @@ -159,7 +238,7 @@ |
3360 | for (uint32_t j = list->size(); j; --j) { |
3361 | MessageId m_id((*list)[j - 1]); |
3362 | if (Message const * const message = mq[m_id]) { |
3363 | - if ((mode == Archive) != (message->status() == Message::Archived)) { |
3364 | + if ((mode == Archive) != (message->status() == Message::Status::kArchived)) { |
3365 | list->remove(j - 1); |
3366 | } else { |
3367 | update_record(list->get_record(j - 1), *message); |
3368 | @@ -174,7 +253,7 @@ |
3369 | MessageId const id = temp_message.first; |
3370 | const Message & message = *temp_message.second; |
3371 | Message::Status const status = message.status(); |
3372 | - if ((mode == Archive) != (status == Message::Archived)) |
3373 | + if ((mode == Archive) != (status == Message::Status::kArchived)) |
3374 | continue; |
3375 | if (!list->find(id.value())) { |
3376 | UI::Table<uintptr_t>::EntryRecord & er = list->add(id.value()); |
3377 | @@ -183,6 +262,19 @@ |
3378 | } |
3379 | } |
3380 | |
3381 | + // Filter message type |
3382 | + if (m_message_filter != Message::Type::kAllMessages) { |
3383 | + set_display_message_type_label(m_message_filter); |
3384 | + for (uint32_t j = list->size(); j; --j) { |
3385 | + MessageId m_id((*list)[j - 1]); |
3386 | + if (Message const * const message = mq[m_id]) { |
3387 | + if (message->message_type_category() != m_message_filter) { |
3388 | + list->remove(j - 1); |
3389 | + } |
3390 | + } |
3391 | + } |
3392 | + } |
3393 | + |
3394 | if (list->size()) { |
3395 | if (!list->has_selection()) |
3396 | list->select(0); |
3397 | @@ -192,6 +284,7 @@ |
3398 | } else { |
3399 | m_centerviewbtn->set_enabled(false); |
3400 | message_body.set_text(std::string()); |
3401 | + set_display_message_type_label(Widelands::Message::Type::kNoMessages); |
3402 | } |
3403 | } |
3404 | |
3405 | @@ -201,7 +294,7 @@ |
3406 | { |
3407 | er.set_picture |
3408 | (ColStatus, |
3409 | - g_gr->images().get(status_picture_filename[message.status()])); |
3410 | + g_gr->images().get(status_picture_filename[static_cast<int>(message.status())])); |
3411 | er.set_string(ColTitle, message.title()); |
3412 | |
3413 | const uint32_t time = message.sent(); |
3414 | @@ -218,7 +311,7 @@ |
3415 | MessageId const id = MessageId((*list)[t]); |
3416 | if (Message const * const message = mq[id]) { |
3417 | // Maybe the message was removed since think? |
3418 | - if (message->status() == Message::New) { |
3419 | + if (message->status() == Message::Status::kNew) { |
3420 | Widelands::Game & game = iplayer().game(); |
3421 | game.send_player_command |
3422 | (*new Widelands::CmdMessageSetStatusRead |
3423 | @@ -226,6 +319,7 @@ |
3424 | } |
3425 | m_centerviewbtn->set_enabled(message->position()); |
3426 | message_body.set_text(message->body ()); |
3427 | + set_display_message_type_label(message->message_type_category()); |
3428 | return; |
3429 | } |
3430 | } |
3431 | @@ -247,19 +341,37 @@ |
3432 | { |
3433 | if (down) { |
3434 | switch (code.sym) { |
3435 | + // Don't forget to change the tooltips if any of these get reassigned |
3436 | case SDLK_g: |
3437 | if (m_centerviewbtn->enabled()) |
3438 | center_view(); |
3439 | return true; |
3440 | - |
3441 | + case SDLK_0: |
3442 | + filter_messages(Widelands::Message::Type::kAllMessages); |
3443 | + return true; |
3444 | + case SDLK_1: |
3445 | + filter_messages(Widelands::Message::Type::kGeologists); |
3446 | + return true; |
3447 | + case SDLK_2: |
3448 | + filter_messages(Widelands::Message::Type::kEconomy); |
3449 | + return true; |
3450 | + case SDLK_3: |
3451 | + filter_messages(Widelands::Message::Type::kSeafaring); |
3452 | + return true; |
3453 | + case SDLK_4: |
3454 | + filter_messages(Widelands::Message::Type::kWarfare); |
3455 | + return true; |
3456 | + case SDLK_5: |
3457 | + filter_messages(Widelands::Message::Type::kScenario); |
3458 | + return true; |
3459 | + case SDLK_DELETE: |
3460 | + archive_or_restore(); |
3461 | + return true; |
3462 | + case SDL_SCANCODE_KP_PERIOD: |
3463 | case SDLK_KP_PERIOD: |
3464 | if (code.mod & KMOD_NUM) |
3465 | break; |
3466 | /* no break */ |
3467 | - case SDLK_DELETE: |
3468 | - archive_or_restore(); |
3469 | - return true; |
3470 | - |
3471 | default: |
3472 | break; // not handled |
3473 | } |
3474 | @@ -336,6 +448,141 @@ |
3475 | } |
3476 | |
3477 | /** |
3478 | + * Show only messages of a certain type |
3479 | + * @param msgtype the types of messages to show |
3480 | + */ |
3481 | +void GameMessageMenu::filter_messages(Widelands::Message::Type const msgtype) { |
3482 | + switch (msgtype) { |
3483 | + case Widelands::Message::Type::kGeologists: |
3484 | + toggle_filter_messages_button(*m_geologistsbtn, msgtype); |
3485 | + break; |
3486 | + case Widelands::Message::Type::kEconomy: |
3487 | + toggle_filter_messages_button(*m_economybtn, msgtype); |
3488 | + break; |
3489 | + case Widelands::Message::Type::kSeafaring: |
3490 | + toggle_filter_messages_button(*m_seafaringbtn, msgtype); |
3491 | + break; |
3492 | + case Widelands::Message::Type::kWarfare: |
3493 | + toggle_filter_messages_button(*m_warfarebtn, msgtype); |
3494 | + break; |
3495 | + case Widelands::Message::Type::kScenario: |
3496 | + toggle_filter_messages_button(*m_scenariobtn, msgtype); |
3497 | + break; |
3498 | + default: |
3499 | + set_filter_messages_tooltips(); |
3500 | + m_message_filter = Widelands::Message::Type::kAllMessages; |
3501 | + m_geologistsbtn->set_perm_pressed(false); |
3502 | + m_economybtn->set_perm_pressed(false); |
3503 | + m_seafaringbtn->set_perm_pressed(false); |
3504 | + m_warfarebtn->set_perm_pressed(false); |
3505 | + m_scenariobtn->set_perm_pressed(false); |
3506 | + } |
3507 | + think(); |
3508 | +} |
3509 | + |
3510 | +/** |
3511 | + * Helper for filter_messages |
3512 | + */ |
3513 | +void GameMessageMenu::toggle_filter_messages_button(UI::Button & button, Widelands::Message::Type msgtype) { |
3514 | + set_filter_messages_tooltips(); |
3515 | + if (button.get_perm_pressed()) { |
3516 | + button.set_perm_pressed(false); |
3517 | + m_message_filter = Widelands::Message::Type::kAllMessages; |
3518 | + } else { |
3519 | + m_geologistsbtn->set_perm_pressed(false); |
3520 | + m_economybtn->set_perm_pressed(false); |
3521 | + m_seafaringbtn->set_perm_pressed(false); |
3522 | + m_warfarebtn->set_perm_pressed(false); |
3523 | + m_scenariobtn->set_perm_pressed(false); |
3524 | + button.set_perm_pressed(true); |
3525 | + m_message_filter = msgtype; |
3526 | + /** TRANSLATORS: %1% is a tooltip, %2% is the corresponding hotkey */ |
3527 | + button.set_tooltip((boost::format(_("%1% (Hotkey: %2%)")) |
3528 | + /** TRANSLATORS: Tooltip in the messages window */ |
3529 | + % _("Show all messages") |
3530 | + % "0").str()); |
3531 | + } |
3532 | +} |
3533 | + |
3534 | +/** |
3535 | + * Helper for filter_messages |
3536 | + */ |
3537 | +void GameMessageMenu::set_filter_messages_tooltips() { |
3538 | + m_geologistsbtn->set_tooltip((boost::format(_("%1% (Hotkey: %2%)")) |
3539 | + /** TRANSLATORS: Tooltip in the messages window */ |
3540 | + % _("Show geologists' messages only") |
3541 | + % "1").str()); |
3542 | + m_economybtn->set_tooltip((boost::format(_("%1% (Hotkey: %2%)")) |
3543 | + /** TRANSLATORS: Tooltip in the messages window */ |
3544 | + % _("Show economy messages only") |
3545 | + % "2").str()); |
3546 | + m_seafaringbtn->set_tooltip((boost::format(_("%1% (Hotkey: %2%)")) |
3547 | + /** TRANSLATORS: Tooltip in the messages window */ |
3548 | + % _("Show seafaring messages only") |
3549 | + % "3").str()); |
3550 | + m_warfarebtn->set_tooltip((boost::format(_("%1% (Hotkey: %2%)")) |
3551 | + /** TRANSLATORS: Tooltip in the messages window */ |
3552 | + % _("Show warfare messages only") |
3553 | + % "4").str()); |
3554 | + m_scenariobtn->set_tooltip((boost::format(_("%1% (Hotkey: %2%)")) |
3555 | + /** TRANSLATORS: Tooltip in the messages window */ |
3556 | + % _("Show scenario messages only") |
3557 | + % "5").str()); |
3558 | +} |
3559 | + |
3560 | +/** |
3561 | + * Update image and tooltip for message category label |
3562 | + */ |
3563 | +void GameMessageMenu::set_display_message_type_label(Widelands::Message::Type msgtype) { |
3564 | + std::string message_type_tooltip = ""; |
3565 | + std::string message_type_image = ""; |
3566 | + |
3567 | + switch (msgtype) { |
3568 | + case Widelands::Message::Type::kGeologists: |
3569 | + /** TRANSLATORS: This is a message's type */ |
3570 | + message_type_tooltip = _("Geologists"); |
3571 | + message_type_image = "<rt image=pics/menu_geologist.png></rt>"; |
3572 | + break; |
3573 | + case Widelands::Message::Type::kEconomy: |
3574 | + /** TRANSLATORS: This is a message's type */ |
3575 | + message_type_tooltip = _("Economy"); |
3576 | + message_type_image = "<rt image=pics/menu_build_flag.png></rt>"; |
3577 | + break; |
3578 | + case Widelands::Message::Type::kSeafaring: |
3579 | + /** TRANSLATORS: This is a message's type */ |
3580 | + message_type_tooltip = _("Seafaring"); |
3581 | + message_type_image = "<rt image=pics/start_expedition.png></rt>"; |
3582 | + break; |
3583 | + case Widelands::Message::Type::kWarfare: |
3584 | + /** TRANSLATORS: This is a message's type */ |
3585 | + message_type_tooltip = _("Warfare"); |
3586 | + message_type_image = "<rt image=pics/messages_warfare.png></rt>"; |
3587 | + break; |
3588 | + case Widelands::Message::Type::kScenario: |
3589 | + /** TRANSLATORS: This is a message's type */ |
3590 | + message_type_tooltip = _("Scenario"); |
3591 | + message_type_image = "<rt image=pics/menu_objectives.png></rt>"; |
3592 | + break; |
3593 | + case Widelands::Message::Type::kNoMessages: |
3594 | + /** TRANSLATORS: This show up instead of a message's type when there are no messages found */ |
3595 | + message_type_tooltip = _("No message found"); |
3596 | + break; |
3597 | + default: |
3598 | + /** TRANSLATORS: This is the default message type */ |
3599 | + message_type_tooltip = _("General"); |
3600 | + message_type_image = "<rt image=pics/message_new.png></rt>"; |
3601 | + } |
3602 | + |
3603 | + m_display_message_type_label->set_tooltip( |
3604 | + /** TRANSLATORS: %s is a message's type */ |
3605 | + (boost::format(_("Type of this message: %s")) |
3606 | + /** TRANSLATORS: Tooltip in the messages window */ |
3607 | + % message_type_tooltip).str()); |
3608 | + m_display_message_type_label->set_text(message_type_image); |
3609 | +} |
3610 | + |
3611 | + |
3612 | +/** |
3613 | * Clear the current selection of messages. |
3614 | */ |
3615 | void GameMessageMenu::do_clear_selection() |
3616 | @@ -359,15 +606,23 @@ |
3617 | mode = Archive; |
3618 | set_title(_("Messages: Archive")); |
3619 | m_archivebtn->set_pic(g_gr->images().get("pics/message_restore.png")); |
3620 | - m_archivebtn->set_tooltip(_("Restore selected messages")); |
3621 | - m_togglemodebtn->set_title(_("Show Inbox")); |
3622 | + /** TRANSLATORS: %s is a tooltip, Del is the corresponding hotkey */ |
3623 | + m_archivebtn->set_tooltip((boost::format(_("Del: %s")) |
3624 | + /** TRANSLATORS: Tooltip in the messages window */ |
3625 | + % _("Restore selected messages")).str()); |
3626 | + m_togglemodebtn->set_pic(g_gr->images().get("pics/message_new.png")); |
3627 | + m_togglemodebtn->set_tooltip(_("Show Inbox")); |
3628 | break; |
3629 | case Archive: |
3630 | mode = Inbox; |
3631 | set_title(_("Messages: Inbox")); |
3632 | m_archivebtn->set_pic(g_gr->images().get("pics/message_archive.png")); |
3633 | - m_archivebtn->set_tooltip(_("Archive selected messages")); |
3634 | - m_togglemodebtn->set_title(_("Show Archive")); |
3635 | + /** TRANSLATORS: %s is a tooltip, Del is the corresponding hotkey */ |
3636 | + m_archivebtn->set_tooltip((boost::format(_("Del: %s")) |
3637 | + /** TRANSLATORS: Tooltip in the messages window */ |
3638 | + % _("Archive selected messages")).str()); |
3639 | + m_togglemodebtn->set_pic(g_gr->images().get("pics/message_archived.png")); |
3640 | + m_togglemodebtn->set_tooltip(_("Show Archive")); |
3641 | break; |
3642 | default: |
3643 | assert(false); // there is nothing but Archive and Inbox |
3644 | |
3645 | === modified file 'src/wui/game_message_menu.h' |
3646 | --- src/wui/game_message_menu.h 2014-11-28 16:40:55 +0000 |
3647 | +++ src/wui/game_message_menu.h 2014-12-28 17:03:29 +0000 |
3648 | @@ -21,6 +21,7 @@ |
3649 | #define WL_WUI_GAME_MESSAGE_MENU_H |
3650 | |
3651 | #include "base/i18n.h" |
3652 | +#include "logic/message.h" |
3653 | #include "logic/message_queue.h" |
3654 | #include "ui_basic/button.h" |
3655 | #include "ui_basic/multilinetextarea.h" |
3656 | @@ -48,6 +49,7 @@ |
3657 | |
3658 | private: |
3659 | enum Cols {ColSelect, ColStatus, ColTitle, ColTimeSent}; |
3660 | + enum class ReadUnread: uint8_t {allMessages, readMessages, newMessages}; |
3661 | |
3662 | InteractivePlayer & iplayer() const; |
3663 | void selected(uint32_t); |
3664 | @@ -59,6 +61,10 @@ |
3665 | void archive_or_restore(); |
3666 | void toggle_mode(); |
3667 | void center_view(); |
3668 | + void filter_messages(Widelands::Message::Type); |
3669 | + void toggle_filter_messages_button(UI::Button &, Widelands::Message::Type); |
3670 | + void set_filter_messages_tooltips(); |
3671 | + void set_display_message_type_label(Widelands::Message::Type); |
3672 | void update_record(UI::Table<uintptr_t>::EntryRecord & er, const Widelands::Message &); |
3673 | |
3674 | UI::Table<uintptr_t> * list; |
3675 | @@ -67,6 +73,14 @@ |
3676 | UI::Button * m_togglemodebtn; |
3677 | UI::Button * m_centerviewbtn; |
3678 | Mode mode; |
3679 | + // Buttons for message types |
3680 | + UI::Button * m_geologistsbtn; |
3681 | + UI::Button * m_economybtn; |
3682 | + UI::Button * m_seafaringbtn; |
3683 | + UI::Button * m_warfarebtn; |
3684 | + UI::Button * m_scenariobtn; |
3685 | + Widelands::Message::Type m_message_filter; |
3686 | + UI::MultilineTextarea * m_display_message_type_label; |
3687 | }; |
3688 | |
3689 | #endif // end of include guard: WL_WUI_GAME_MESSAGE_MENU_H |
3690 | |
3691 | === modified file 'src/wui/interactive_player.cc' |
3692 | --- src/wui/interactive_player.cc 2014-12-03 08:14:35 +0000 |
3693 | +++ src/wui/interactive_player.cc 2014-12-28 17:03:29 +0000 |
3694 | @@ -254,7 +254,7 @@ |
3695 | std::string msg_tooltip = _("Messages"); |
3696 | if |
3697 | (uint32_t const nr_new_messages = |
3698 | - player().messages().nr_messages(Widelands::Message::New)) |
3699 | + player().messages().nr_messages(Widelands::Message::Status::kNew)) |
3700 | { |
3701 | msg_icon = "pics/menu_toggle_newmessage_menu.png"; |
3702 | msg_tooltip = |
3703 | |
3704 | === modified file 'test/maps/lua_persistence.wmf/scripting/test_persistence.lua' |
3705 | --- test/maps/lua_persistence.wmf/scripting/test_persistence.lua 2014-08-01 15:30:12 +0000 |
3706 | +++ test/maps/lua_persistence.wmf/scripting/test_persistence.lua 2014-12-28 17:03:29 +0000 |
3707 | @@ -49,7 +49,7 @@ |
3708 | objective.done = true |
3709 | |
3710 | p:send_message("dummy msg1", "dummy msg 1") |
3711 | - msg = p:send_message("hello nice", "World", {sender="blah", field = field }) |
3712 | + msg = p:send_message("hello nice", "World", {field = field }) |
3713 | player_slot = map.player_slots[1] |
3714 | |
3715 | myset = Set:new{ |
3716 | @@ -118,7 +118,6 @@ |
3717 | assert_table(msg) |
3718 | assert_equal("hello nice", msg.title) |
3719 | assert_equal("World", msg.body) |
3720 | - assert_equal("blah", msg.sender) |
3721 | assert_equal(field, msg.field) |
3722 | |
3723 | assert_table(map) |
3724 | |
3725 | === modified file 'test/maps/lua_testsuite.wmf/scripting/messages.lua' |
3726 | --- test/maps/lua_testsuite.wmf/scripting/messages.lua 2014-09-09 08:24:10 +0000 |
3727 | +++ test/maps/lua_testsuite.wmf/scripting/messages.lua 2014-12-28 17:03:29 +0000 |
3728 | @@ -13,7 +13,6 @@ |
3729 | local m = player1:send_message("Hallo", "World!") |
3730 | assert_equal("Hallo", m.title) |
3731 | assert_equal("World!", m.body) |
3732 | - assert_equal("ScriptingEngine", m.sender) |
3733 | assert_equal(0, m.sent) |
3734 | assert_equal(0, m.sent) |
3735 | assert_equal(nil, m.field) |
3736 | @@ -32,10 +31,6 @@ |
3737 | player1:send_message("Hallo", "World!", {status="nono"}) |
3738 | end) |
3739 | end |
3740 | -function messages_tests:test_sender() |
3741 | - local m = player1:send_message("Hallo", "World!", {sender="i am you"}) |
3742 | - assert_equal("i am you", m.sender) |
3743 | -end |
3744 | function messages_tests:test_field() |
3745 | local f = map:get_field(23,28) |
3746 | local m = player1:send_message("Hallo", "World!", {field = f}) |
3747 | |
3748 | === modified file 'txts/README.lua' |
3749 | --- txts/README.lua 2014-12-11 19:38:39 +0000 |
3750 | +++ txts/README.lua 2014-12-28 17:03:29 +0000 |
3751 | @@ -79,8 +79,14 @@ |
3752 | ) .. p(_ |
3753 | [[In the message window, the following additional shortcuts are available:]] |
3754 | ) .. p( |
3755 | -_ "G: jumps to the location corresponding to the current message" .. "<br>" |
3756 | -.. _"DELETE: archives the current message" |
3757 | +_ "0: shows all messages" .. "<br>" |
3758 | +.. _ "1: shows geologists' messages only" .. "<br>" |
3759 | +.. _ "2: shows economy messages only" .. "<br>" |
3760 | +.. _ "3: shows seafaring messages only" .. "<br>" |
3761 | +.. _ "4: shows warfare messages only" .. "<br>" |
3762 | +.. _ "5: shows scenario messages only" .. "<br>" |
3763 | +.. _ "G: jumps to the location corresponding to the current message" .. "<br>" |
3764 | +.. _"DELETE: archives/restores the current message" |
3765 | ) .. h2(_ |
3766 | [[Online Help]] |
3767 | ) .. p( _ |
I understand the design was discussed under bug report, but still 2 comments:
1. Current design is "one category only" - what about enabling and disabling freely? I mean you could be able to enable any number of categories.
2 mode "0: show all messages" shows a flag on the bottom and it is symbol of economy messages. I think "all messages" should have own icon, or no icon, or icons of all categories.
But generally it works as supposed....