1 /*
2    Copyright (C) 2003 - 2018 by David White <dave@whitevine.net>
3    Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY.
11 
12    See the COPYING file for more details.
13 */
14 
15 /**
16  *  @file
17  *  Display units performing various actions: moving, attacking, and dying.
18  */
19 
20 #pragma once
21 
22 #include "fake_unit_ptr.hpp"
23 #include "map/location.hpp"
24 #include "units/animation.hpp"
25 
26 class attack_type;
27 class game_board;
28 class game_display;
29 class unit;
30 
31 /**
32  *  Contains a number of free functions which display units
33  *
34  *  performing various on-screen actions - moving, attacking, and dying.
35  */
36 namespace unit_display
37 {
38 
39 /**
40  * A class to encapsulate the steps of drawing a unit's move.
41  * If control over how far the unit moves is not needed, move_unit() may
42  * be a more convenient interface.
43  */
44 class unit_mover {
45 public:
46 	unit_mover(const unit_mover&) = delete;
47 	unit_mover& operator=(const unit_mover&) = delete;
48 
49 	explicit unit_mover(const std::vector<map_location>& path, bool animate=true, bool force_scroll=false);
50 	~unit_mover();
51 
52 	void start(unit_ptr u);
53 	void proceed_to(unit_ptr u, size_t path_index, bool update=false, bool wait=true);
54 	void wait_for_anims();
55 	void finish(unit_ptr u, map_location::DIRECTION dir = map_location::NDIRECTIONS);
56 
57 private: // functions
58 	void replace_temporary(unit_ptr u);
59 	void update_shown_unit();
60 
61 private: // data
62 	game_display * const disp_;
63 	const bool can_draw_;
64 	const bool animate_;
65 	const bool force_scroll_;
66 	unit_animator animator_;
67 	int wait_until_;	/// The animation potential to wait until. INT_MIN for no wait; INT_MAX to wait for end.
68 	unit_ptr shown_unit_;	/// The unit to be (re-)shown after an animation finishes.
69 	const std::vector<map_location>& path_;
70 	size_t current_;
71 	fake_unit_ptr temp_unit_ptr_;
72 	bool was_hidden_;
73 	bool is_enemy_;
74 };
75 
76 
77 /**
78  * Display a unit moving along a given path.
79  */
80 void move_unit(const std::vector<map_location>& path, unit_ptr u,
81 	bool animate=true,
82 	map_location::DIRECTION dir=map_location::NDIRECTIONS,
83 	bool force_scroll=false);
84 
85 /**
86  * Play a pre-fight animation
87  * First unit is the attacker, second unit the defender
88  */
89 void unit_draw_weapon( const map_location& loc, unit& u, const_attack_ptr attack=nullptr, const_attack_ptr secondary_attack=nullptr,const map_location& defender_loc = map_location::null_location(), unit * defender=nullptr);
90 
91 /**
92  * Play a post-fight animation
93  * Both unit can be set to null, only valid units will play their animation
94  */
95 void unit_sheath_weapon( const map_location& loc, unit* u=nullptr, const_attack_ptr attack=nullptr, const_attack_ptr secondary_attack=nullptr,const map_location& defender_loc = map_location::null_location(), unit * defender=nullptr);
96 
97 /**
98  * Show a unit fading out.
99  *
100  * Note: this only shows the effect, it doesn't actually kill the unit.
101  */
102  void unit_die( const map_location& loc, unit& u,
103 	const_attack_ptr attack=nullptr, const_attack_ptr secondary_attack=nullptr,
104 	const map_location& winner_loc=map_location::null_location(),
105 	unit* winner=nullptr);
106 
107 
108 /**
109  *  Make the unit on tile 'a' attack the unit on tile 'b'.
110  *
111  *  The 'damage' will be subtracted from the unit's hitpoints,
112  *  and a die effect will be displayed if the unit dies.
113  *
114  *  @retval	true                  if the defending unit is dead, should be
115  *                                removed from the playing field.
116  */
117 void unit_attack(display * disp, game_board & board, //TODO: Would be nice if this could be purely a display function and defer damage dealing to its caller
118 	const map_location& a, const map_location& b, int damage,
119 	const attack_type& attack, const_attack_ptr secondary_attack,
120 	int swing, const std::string& hit_text, int drain_amount, const std::string& att_text, const std::vector<std::string>* extra_hit_sounds=nullptr);
121 
122 
123 void unit_recruited(const map_location& loc,
124 	const map_location& leader_loc=map_location::null_location());
125 
126 /**
127  * This will use a poisoning anim if healing<0.
128  */
129 void unit_healing(unit &healed, const std::vector<unit *> &healers, int healing,
130                   const std::string & extra_text="");
131 
132 }
133