Merge lp:~widelands-dev/widelands/bug1132466 into lp:widelands

Proposed by Nicolai Hähnle
Status: Merged
Merged at revision: 6522
Proposed branch: lp:~widelands-dev/widelands/bug1132466
Merge into: lp:widelands
Diff against target: 238 lines (+70/-32)
5 files modified
src/logic/playercommand.cc (+1/-2)
src/logic/soldier.cc (+6/-1)
src/logic/soldier.h (+3/-1)
src/logic/worker.cc (+57/-27)
src/logic/worker.h (+3/-1)
To merge this branch: bzr merge lp:~widelands-dev/widelands/bug1132466
Reviewer Review Type Date Requested Status
SirVer Approve
Review via email: mp+150244@code.launchpad.net

Commit message

Fix bug #1132466 and a potential cheat related to evicting soldiers

The worker leavebuilding task now deals more robustly with situations in which the evicted worker is currently outside of the building.

Furthermore, it is no longer possible to evict soldiers whose current position on the map is not their assigned building (i.e., their location). Note that this was not possible with the standard user interface anyway, but a cheater could have modified her version of the game such that an eviction player command would be sent automatically for her soldiers when they reach low HP during a battle. Such soldiers would have immediately stopped battle and returned home.

To post a comment you must log in.
Revision history for this message
SirVer (sirver) wrote :

lgtm.

review: Approve
Revision history for this message
Nicolai Hähnle (nha) wrote :

Thank you. However, I just realized myself that the eviction still has a problem that I would like to fix first: When evicting a worker that is in the middle of walking, the reset_tasks() approach that is being taken right now causes the worker to be "warped".

Revision history for this message
Nicolai Hähnle (nha) wrote :

This fixes the warping issue, and seems to be the correct of doing it.

Revision history for this message
SirVer (sirver) wrote :

+ const Coords flagpos = baseflag.get_position();
can this be a const reference? Haven't checked.

still lgtm.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/logic/playercommand.cc'
2--- src/logic/playercommand.cc 2013-02-04 21:52:38 +0000
3+++ src/logic/playercommand.cc 2013-02-25 17:40:30 +0000
4@@ -638,8 +638,7 @@
5 {
6 upcast(Worker, worker, game.objects().get_object(serial));
7 if (worker && worker->owner().player_number() == sender()) {
8- worker->reset_tasks(game);
9- worker->start_task_gowarehouse(game);
10+ worker->evict(game);
11 }
12 }
13
14
15=== modified file 'src/logic/soldier.cc'
16--- src/logic/soldier.cc 2013-02-10 19:36:24 +0000
17+++ src/logic/soldier.cc 2013-02-25 17:40:30 +0000
18@@ -1,5 +1,5 @@
19 /*
20- * Copyright (C) 2002-2004, 2006-2011 by the Widelands Development Team
21+ * Copyright (C) 2002-2004, 2006-2013 by the Widelands Development Team
22 *
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License
25@@ -347,6 +347,11 @@
26 Worker::cleanup(egbase);
27 }
28
29+bool Soldier::is_evict_allowed()
30+{
31+ return !isOnBattlefield();
32+}
33+
34 /*
35 * Set this soldiers level. Automatically sets the new values
36 */
37
38=== modified file 'src/logic/soldier.h'
39--- src/logic/soldier.h 2013-02-10 19:36:24 +0000
40+++ src/logic/soldier.h 2013-02-25 17:40:30 +0000
41@@ -1,5 +1,5 @@
42 /*
43- * Copyright (C) 2002-2004, 2006-2010 by the Widelands Development Team
44+ * Copyright (C) 2002-2004, 2006-2013 by the Widelands Development Team
45 *
46 * This program is free software; you can redistribute it and/or
47 * modify it under the terms of the GNU General Public License
48@@ -287,6 +287,8 @@
49 // May be this can be moved this to bob when finished
50 static Task const taskDie;
51
52+ virtual bool is_evict_allowed();
53+
54 private:
55 uint32_t m_hp_current;
56 uint32_t m_hp_level;
57
58=== modified file 'src/logic/worker.cc'
59--- src/logic/worker.cc 2013-02-11 18:01:26 +0000
60+++ src/logic/worker.cc 2013-02-25 17:40:30 +0000
61@@ -1441,30 +1441,20 @@
62 }
63 }
64
65- // If our location is a building, make sure we're actually in it.
66- // If we're a building's worker, and we've just been released from
67- // the building, we may be somewhere else entirely (e.g. lumberjack, soldier)
68- // or we may be on the building's flag for a fetch_from_flag or dropoff
69- // task.
70+ // If our location is a building, our position may be somewhere else:
71+ // We may be on the building's flag for a fetch_from_flag or dropoff task.
72+ // We may also be somewhere else entirely (e.g. lumberjack, soldier).
73 // Similarly for flags.
74- if (dynamic_cast<Building const *>(location)) {
75- BaseImmovable * const position = map[get_position()].get_immovable();
76-
77- if (position != location) {
78- if (upcast(Flag, flag, position)) {
79- location = flag;
80- set_location(flag);
81- } else
82- return set_location(0);
83- }
84+ if (upcast(Building, building, location)) {
85+ if (building->get_position() != get_position())
86+ return start_task_leavebuilding(game, true);
87 } else if (upcast(Flag, flag, location)) {
88 BaseImmovable * const position = map[get_position()].get_immovable();
89
90 if (position != flag) {
91 if (position == flag->get_building()) {
92- upcast(Building, building, position);
93- set_location(building);
94- location = building;
95+ location = flag->get_building();
96+ set_location(location);
97 } else
98 return set_location(0);
99 }
100@@ -1681,6 +1671,7 @@
101 *
102 * ivar1 - 0: no task has failed; 1: currently in buildingwork;
103 * 2: signal failure of buildingwork
104+ * ivar2 - whether the worker is to be evicted
105 */
106 const Bob::Task Worker::taskBuildingwork = {
107 "buildingwork",
108@@ -1697,7 +1688,9 @@
109 void Worker::start_task_buildingwork(Game & game)
110 {
111 push_task(game, taskBuildingwork);
112- top_state().ivar1 = 0;
113+ State & state = top_state();
114+ state.ivar1 = 0;
115+ state.ivar2 = 0;
116 }
117
118
119@@ -1710,6 +1703,9 @@
120 if (state.ivar1 == 1)
121 state.ivar1 = (signal == "fail") * 2;
122
123+ if (state.ivar2 == 1)
124+ return pop_task(game); // evict worker
125+
126 // Return to building, if necessary
127 upcast(Building, building, get_location(game));
128 if (!building)
129@@ -1743,6 +1739,23 @@
130 send_signal(game, "update");
131 }
132
133+/**
134+ * Evict the worker from its current building.
135+ */
136+void Worker::evict(Game & game)
137+{
138+ if (State * state = get_state(taskBuildingwork)) {
139+ if (is_evict_allowed()) {
140+ state->ivar2 = 1;
141+ send_signal(game, "evict");
142+ }
143+ }
144+}
145+
146+bool Worker::is_evict_allowed()
147+{
148+ return true;
149+}
150
151 /**
152 * Return to our owning building.
153@@ -1998,9 +2011,7 @@
154
155 // Always leave buildings in an orderly manner,
156 // even when no warehouses are left to return to
157- if
158- (location->get_type() == BUILDING &&
159- get_position() == static_cast<Building *>(location)->get_position())
160+ if (location->get_type() == BUILDING)
161 return start_task_leavebuilding(game, true);
162
163 if (!get_economy()->warehouses().size()) {
164@@ -2384,14 +2395,19 @@
165 else if (signal.size())
166 return pop_task(game);
167
168- if (upcast(Building, building, game.map().get_immovable(get_position()))) {
169+ upcast(Building, building, get_location(game));
170+ if (!building)
171+ return pop_task(game);
172+
173+ Flag & baseflag = building->base_flag();
174+
175+ if (get_position() == building->get_position()) {
176 assert(building == state.objvar1.get(game));
177-
178 if (!building->leave_check_and_wait(game, *this))
179 return skip_act();
180
181 if (state.ivar1)
182- set_location(&building->base_flag());
183+ set_location(&baseflag);
184
185 return
186 start_task_move
187@@ -2399,8 +2415,22 @@
188 WALK_SE,
189 &descr().get_right_walk_anims(does_carry_ware()),
190 true);
191- } else
192- return pop_task(game);
193+ } else {
194+ const Coords flagpos = baseflag.get_position();
195+
196+ if (state.ivar1)
197+ set_location(&baseflag);
198+
199+ if (get_position() == flagpos)
200+ return pop_task(game);
201+
202+ if (!start_task_movepath(game, flagpos, 0, descr().get_right_walk_anims(does_carry_ware()))) {
203+ molog("[leavebuilding]: outside of building, but failed to walk back to flag");
204+ set_location(0);
205+ return pop_task(game);
206+ }
207+ return;
208+ }
209 }
210
211
212
213=== modified file 'src/logic/worker.h'
214--- src/logic/worker.h 2013-02-10 19:36:24 +0000
215+++ src/logic/worker.h 2013-02-25 17:40:30 +0000
216@@ -1,5 +1,5 @@
217 /*
218- * Copyright (C) 2002-2004, 2006-2010 by the Widelands Development Team
219+ * Copyright (C) 2002-2004, 2006-2013 by the Widelands Development Team
220 *
221 * This program is free software; you can redistribute it and/or
222 * modify it under the terms of the GNU General Public License
223@@ -171,6 +171,7 @@
224
225 void start_task_buildingwork(Game &);
226 void update_task_buildingwork(Game &);
227+ void evict(Game &);
228
229 void start_task_return(Game & game, bool dropitem);
230 void start_task_program(Game & game, const std::string & programname);
231@@ -192,6 +193,7 @@
232 void start_task_scout(Game &, uint16_t, uint32_t);
233
234 protected:
235+ virtual bool is_evict_allowed();
236 void draw_inner(const Editor_Game_Base &, RenderTarget &, Point) const;
237 virtual void draw(const Editor_Game_Base &, RenderTarget &, Point) const;
238 virtual void init_auto_task(Game &);

Subscribers

People subscribed via source and target branches

to status/vote changes: