1 /*
2  * Copyright (C) 2002-2020 by the Widelands Development Team
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  *
18  */
19 
20 #ifndef WL_LOGIC_MAP_OBJECTS_BOB_H
21 #define WL_LOGIC_MAP_OBJECTS_BOB_H
22 
23 #include "base/macros.h"
24 #include "base/vector.h"
25 #include "economy/route.h"
26 #include "graphic/animation/diranimations.h"
27 #include "logic/map_objects/info_to_draw.h"
28 #include "logic/map_objects/map_object.h"
29 #include "logic/map_objects/map_object_program.h"
30 #include "logic/map_objects/walkingdir.h"
31 #include "logic/path.h"
32 #include "logic/widelands_geometry.h"
33 
34 namespace Widelands {
35 
36 class Bob;
37 
38 /**
39  * Implement MapObjectDescr for the following \ref Bob class.
40  */
41 class BobDescr : public MapObjectDescr {
42 public:
43 	friend struct MapBobdataPacket;
44 
45 	BobDescr(const std::string& init_descname,
46 	         const MapObjectType type,
47 	         MapObjectDescr::OwnerType owner_type,
48 	         const LuaTable& table);
49 
~BobDescr()50 	~BobDescr() override {
51 	}
52 
53 	Bob& create(EditorGameBase&, Player* owner, const Coords&) const;
54 
get_owner_type()55 	MapObjectDescr::OwnerType get_owner_type() const {
56 		return owner_type_;
57 	}
58 
movecaps()59 	virtual uint32_t movecaps() const {
60 		return 0;
61 	}
62 	uint32_t vision_range() const;
63 
64 protected:
65 	virtual Bob& create_object() const = 0;
66 
67 private:
68 	const MapObjectDescr::OwnerType owner_type_;
69 	const uint32_t vision_range_;
70 	DISALLOW_COPY_AND_ASSIGN(BobDescr);
71 };
72 
73 /**
74  * Bobs are moving map objects: Animals, humans, ships...
75  *
76  * The name comes from original Settlers2 terminology.
77  *
78  * \par Bobs, Tasks and their signalling
79  *
80  * Bobs have a call-stack of "tasks". The top-most \ref Task is the one that is
81  * currently being executed.
82  *
83  * Upon initialization, an object has no Task at all. A CMD_ACT will be
84  * scheduled automatically. When it is executed, \ref init_auto_task() is
85  * called to automatically select a fallback Task.
86  *
87  * However, the creator of the Bob can choose to push a specific Task
88  * immediately after creating the Bob. This will override the fallback
89  * behaviour. init_auto_task() is also called when the final task is popped
90  * from the stack.
91  *
92  * All state information that a Task uses must be stored in the State structure
93  * returned by get_state(). Every Task on the Task stack has its own
94  * State structure, i.e. push_task() does not destroy the current Task's State.
95  *
96  * In order to start a new sub-task, you have to call \ref push_task(), and then
97  * fill the State structure returned by get_state() with any parameters that the
98  * Task may need.
99  *
100  * A Task is ended by \ref pop_task(). Note, however, that pop_task() can only
101  * be called from a Task's update() function. If you want to interrupt the
102  * current \ref Task for some reason, you should call \ref send_signal().
103  * The signal semantics are explained below in more detail.
104  *
105  * To implement a new Task, you need to create a new Task object with an
106  * update() function. This update() function is called in one of the following
107  * situations:
108  * \li a timeout set by \ref schedule_act() has occurred
109  * \li the task has just been started via \ref push_task()
110  * \li the child task has ended via \ref pop_task()
111  * \li a signal has been sent via \ref send_signal()
112  * It is the responsibility of the update() function to distinguish between
113  * these situations as appropriate.
114  *
115  * One of the following things must happen during update():
116  * \li Call schedule_act() to schedule the next call to update()
117  * \li Call skip_act() if you really don't want to act until a signal occurs.
118  * \li Call pop_task() to end the current task
119  * \li Send a new signal via \ref send_signal(). Note that in this case,
120  *     the update() function will be called again after some delay, and it
121  *     remains the responsibility of the update() function to deal with the
122  *     signal.
123  * The last case is mostly useful when signals are sent from functions that
124  * can be called at any time, such as \ref set_location().
125  *
126  * Whenever \ref send_signal() is called, any current signal is overwritten
127  * by the new signal and the signal_immediate() functions of all Tasks on the
128  * stack are called if available. Note that these functions are not supposed
129  * to perform any actions besides bookkeeping actions that must be performed
130  * in all situations (for example, one might zero some pointer in
131  * signal_immediate() to avoid dangling pointers).
132  *
133  * Then, \ref send_signal() schedules a future call to the top-most task's
134  * update() function. Often, update() functions will just call \ref pop_task()
135  * and leave the signal handling to their parent tasks. To ultimately handle
136  * a signal, the update() function must call \ref signal_handled().
137  *
138  * If a task maintains state outside of its \ref State structure, it may have
139  * to do certain bookkeeping tasks whenever the task is popped from the stack.
140  * To this end, a task may have a \ref Task::pop method. If this method
141  * exists, it is always called just before the task is popped from the stack.
142  */
143 class Bob : public MapObject {
144 public:
145 	friend class Map;
146 	friend struct MapBobdataPacket;
147 	friend struct MapBobPacket;
148 
149 	struct State;
150 	using Ptr = void (Bob::*)(Game&, State&);
151 	using PtrSignal = void (Bob::*)(Game&, State&, const std::string&);
152 
153 	/// \see struct Bob for in-depth explanation
154 	struct Task {
155 		char const* name;
156 
157 		/**
158 		 * Called to update the current task and schedule the next
159 		 * actions etc.
160 		 *
161 		 * \see Bob for in-depth explanation
162 		 */
163 		Ptr update;
164 
165 		/**
166 		 * Called by \ref send_signal() to perform bookkeeping tasks that
167 		 * must be performed immediately. May be zero.
168 		 */
169 		PtrSignal signal_immediate;
170 
171 		/**
172 		 * Called by \ref pop_task() just before the task is popped from
173 		 * the task. Must only perform bookkeeping tasks. May be zero.
174 		 */
175 		Ptr pop;
176 
177 		bool unique;  /// At most 1 of this task type can be on the stack.
178 	};
179 
180 	/**
181 	 * The current state of a task on the stack.
182 	 *
183 	 * If you think in terms of functions, \ref Task represents the code
184 	 * of a function, while \ref State represents the stackframe of an
185 	 * actual execution of the function.
186 	 *
187 	 * \see class Bob for in-depth explanation
188 	 */
189 	struct State {
190 		explicit State(const Task* const the_task = nullptr)
taskState191 		   : task(the_task),
192 		     ivar1(0),
193 		     ivar2(0),
194 		     ivar3(0),
195 		     coords(Coords::null()),
196 		     path(nullptr),
197 		     route(nullptr),
198 		     program(nullptr) {
199 		}
200 
201 		const Task* task;
202 		int32_t ivar1;
203 		int32_t ivar2;
204 		int32_t ivar3;
205 		ObjectPointer objvar1;
206 		std::string svar1;
207 
208 		Coords coords;
209 		DirAnimations diranims;
210 		Path* path;
211 		Route* route;
212 		const MapObjectProgram* program;  ///< pointer to current program
213 	};
214 
MO_DESCR(BobDescr)215 	MO_DESCR(BobDescr)
216 
217 	uint32_t get_current_anim() const {
218 		return anim_;
219 	}
get_animstart()220 	int32_t get_animstart() const {
221 		return animstart_;
222 	}
223 
224 	bool init(EditorGameBase&) override;
225 	void cleanup(EditorGameBase&) override;
226 	void act(Game&, uint32_t data) override;
227 	void schedule_destroy(Game&);
228 	void schedule_act(Game&, uint32_t tdelta);
229 	void skip_act();
230 	Vector2f calc_drawpos(const EditorGameBase&, const Vector2f& field_on_dst, float scale) const;
231 	void set_owner(Player*);
232 
233 	void set_position(EditorGameBase&, const Coords&);
get_position()234 	const FCoords& get_position() const {
235 		return position_;
236 	}
get_next_bob()237 	Bob* get_next_bob() const {
238 		return linknext_;
239 	}
240 
241 	/// Check whether this bob should be able to move onto the given node.
242 	///
243 	/// \param commit indicates whether this function is called from the
244 	///    \ref start_walk function, i.e. whether the bob will actually move
245 	///    onto the \p to node if this function allows it to.
246 	virtual bool check_node_blocked(Game&, const FCoords&, bool commit);
247 
248 	// Draws the bob onto the screen with 'field_on_dst' being the position of
249 	// the field associated with this bob (if it is walking, that is its
250 	// starting field) in pixel space of 'dst' (including scale). The 'scale' is
251 	// required to draw the bob in the right size.
252 	virtual void draw(const EditorGameBase&,
253 	                  const InfoToDraw& info_to_draw,
254 	                  const Vector2f& field_on_dst,
255 	                  const Coords& coords,
256 	                  float scale,
257 	                  RenderTarget* dst) const;
258 
259 	// For debug
260 	void log_general_info(const EditorGameBase&) const override;
261 
262 	// default tasks
263 	void reset_tasks(Game&);
264 
265 	// TODO(feature-Hasi50): correct (?) Send a signal that may switch to some other \ref Task
266 	void send_signal(Game&, char const*);
267 	void start_task_idle(Game&, uint32_t anim, int32_t timeout);
268 	bool is_idle();
269 
270 	/// This can fail (and return false). Therefore the caller must check the
271 	/// result and find something else for the bob to do. Otherwise there will
272 	/// be a "failed to act" error.
273 	bool start_task_movepath(Game&,
274 	                         const Coords& dest,
275 	                         const int32_t persist,
276 	                         const DirAnimations&,
277 	                         const bool forceonlast = false,
278 	                         const int32_t only_step = -1,
279 	                         const bool forceall = false) __attribute__((warn_unused_result));
280 
281 	/// This can fail (and return false). Therefore the caller must check the
282 	/// result and find something else for the bob to do. Otherwise there will
283 	/// be a "failed to act" error.
284 	void start_task_movepath(Game&,
285 	                         const Path&,
286 	                         const DirAnimations&,
287 	                         const bool forceonlast = false,
288 	                         const int32_t only_step = -1);
289 
290 	bool start_task_movepath(Game&,
291 	                         const Path&,
292 	                         const int32_t index,
293 	                         const DirAnimations&,
294 	                         const bool forceonlast = false,
295 	                         const int32_t only_step = -1) __attribute__((warn_unused_result));
296 
297 	void start_task_move(Game& game, int32_t dir, const DirAnimations&, bool);
298 
299 	// higher level handling (task-based)
top_state()300 	State& top_state() {
301 		assert(stack_.size());
302 		return *stack_.rbegin();
303 	}
get_state()304 	State* get_state() {
305 		return stack_.size() ? &*stack_.rbegin() : nullptr;
306 	}
307 
get_signal()308 	std::string get_signal() {
309 		return signal_;
310 	}
311 	State* get_state(const Task&);
312 	State const* get_state(const Task&) const;
313 	void push_task(Game& game, const Task& task, uint32_t tdelta = 10);
314 	void pop_task(Game&);
315 
316 	void signal_handled();
317 
318 	/// Automatically select a task.
init_auto_task(Game &)319 	virtual void init_auto_task(Game&) {
320 	}
321 
322 	// low level animation and walking handling
323 	void set_animation(EditorGameBase&, uint32_t anim);
324 
325 	/// \return true if we're currently walking
is_walking()326 	bool is_walking() {
327 		return walking_ != IDLE;
328 	}
329 
330 	/**
331 	 * This is a hack that should not be used, if possible.
332 	 * It is only introduced here because profiling showed
333 	 * that soldiers spend a lot of time in the node blocked check.
334 	 */
get_next_on_field()335 	Bob* get_next_on_field() const {
336 		return linknext_;
337 	}
338 
339 protected:
340 	explicit Bob(const BobDescr& descr);
341 	~Bob() override;
342 
343 private:
344 	void do_act(Game&);
345 	void do_pop_task(Game&);
346 	void idle_update(Game&, State&);
347 	void movepath_update(Game&, State&);
348 	void move_update(Game&, State&);
349 
350 	int32_t start_walk(Game& game, WalkingDir, uint32_t anim, bool force = false);
351 
352 	/**
353 	 * Call this from your task_act() function that was scheduled after
354 	 * start_walk().
355 	 */
end_walk()356 	void end_walk() {
357 		walking_ = IDLE;
358 	}
359 
360 	static Task const taskIdle;
361 	static Task const taskMovepath;
362 	static Task const taskMove;
363 
364 	FCoords position_;  ///< where are we right now?
365 	Bob* linknext_;     ///< next object on this node
366 	Bob** linkpprev_;
367 	uint32_t anim_;
368 	int32_t animstart_;  ///< gametime when the animation was started
369 	WalkingDir walking_;
370 	int32_t walkstart_;  ///< start time (used for interpolation)
371 	int32_t walkend_;    ///< end time (used for interpolation)
372 
373 	// Task framework variables
374 	std::vector<State> stack_;
375 
376 	/**
377 	 * Every time a Bob acts, this counter is incremented.
378 	 *
379 	 * All scheduled \ref Cmd_Act are given this ID as data, so that
380 	 * only the earliest \ref Cmd_Act issued during one act phase is actually
381 	 * executed. Subsequent \ref Cmd_Act could interfere and are eliminated.
382 	 */
383 	uint32_t actid_;
384 
385 	/**
386 	 * Whether something was scheduled during this act phase.
387 	 *
388 	 * The only purpose of this variable is to act as an integrity check to avoid
389 	 * Bobs that hang themselves up. So e.g. \ref skip_act() also sets this
390 	 * to \c true, even though it technically doesn't schedule anything.
391 	 */
392 	bool actscheduled_;
393 	bool in_act_;  ///< if do_act is currently running
394 	std::string signal_;
395 
396 	// saving and loading
397 protected:
398 	struct Loader : public MapObject::Loader {
399 	public:
400 		Loader();
401 
402 		void load(FileRead&);
403 		void load_pointers() override;
404 		void load_finish() override;
405 
406 	protected:
407 		virtual const Task* get_task(const std::string& name);
408 		virtual const MapObjectProgram* get_program(const std::string& name);
409 
410 	private:
411 		struct LoadState {
412 			uint32_t objvar1;
413 			Route::LoadData route;
414 		};
415 
416 		std::vector<LoadState> states;
417 	};
418 
419 public:
has_new_save_support()420 	bool has_new_save_support() override {
421 		return true;
422 	}
423 
424 	void save(EditorGameBase&, MapObjectSaver&, FileWrite&) override;
425 	// Pure Bobs cannot be loaded
426 };
427 }  // namespace Widelands
428 
429 #endif  // end of include guard: WL_LOGIC_MAP_OBJECTS_BOB_H
430