1 /**
2  ** weaponinf.h - Information from 'weapons.dat'.
3  **
4  ** Written: 06/01/2008 - Marzo
5  **/
6 
7 #ifndef INCL_WEAPONINF_H
8 #define INCL_WEAPONINF_H    1
9 
10 /*
11 Copyright (C) 2008 The Exult Team
12 
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License
15 as published by the Free Software Foundation; either version 2
16 of the License, or (at your option) any later version.
17 
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 GNU General Public License for more details.
22 
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26 */
27 
28 #include "baseinf.h"
29 #include "exult_constants.h"
30 
31 #include <iosfwd>
32 
33 class Shape_info;
34 
35 /*
36  *  Specific information about weapons from 'weapons.dat'.
37  */
38 class Weapon_info : public Base_info {
39 public:
40 	// Actor frames to show when attacking with weapon:
41 	enum Actor_frames {
42 	    reach = 0,
43 	    raise = 1,
44 	    fast_swing = 2,
45 	    slow_swing = 3
46 	};
47 	// The weapon kind:
48 	enum Weapon_uses {
49 	    melee = 0,
50 	    poor_thrown = 1,
51 	    good_thrown = 2,
52 	    ranged = 3
53 	};
54 	// Type of ammo used by weapon:
55 	enum Weapon_ammo {
56 	    self_ammo = -1,
57 	    quality_ammo = -2,
58 	    quantity_ammo = -3
59 	};
60 private:
61 	static Weapon_info default_info;    // For shapes not found.
62 	char damage;            // Damage points (positive).
63 	unsigned char powers;       // Poison, sleep, charm. flags.
64 	unsigned char damage_type;  // See Damage_type above.
65 	unsigned char actor_frames; // Frames for NPC when using (from
66 	//   Actor_frames above).  Low 2 bits
67 	//   are for 'strike', next 2 are for
68 	//   shooting/throwing.
69 	short ammo;         // Shape # of ammo. consumed, or
70 	//   -1 = weapon is ammo.
71 	//   -2 = consummes weapon quality.
72 	//   -3 = consumes weapon quantity if ranged.
73 	short projectile;       // Projectile shape, or
74 	//  -1 = no projectile shown.
75 	//  -3 = use weapon shape as sprite shape.
76 	bool m_autohit;         // Weapon always hits.
77 	bool m_lucky;           // Easier to hit with.
78 	bool m_explodes;        // Explodes on impact.
79 	bool m_no_blocking;     // Can move through walls.
80 	bool m_delete_depleted; // Delete ammo == -2 weapon when quality reaches 0.
81 	bool m_returns;         // Boomerang, magic axe.
82 	bool m_need_target;     // If false, can be used to attack a tile.
83 	short missile_speed;    // # of steps taken by the missile each cycle.
84 	short rotation_speed;   // Added to frame # each cycle (misslies only).
85 	int usecode;            // Usecode function, or 0.
86 	unsigned char uses;     // 0 = hand-hand, 1 = poor throwable,
87 	//   2 = good throwable, 3 = missile-firing.
88 	unsigned char range;        // Distance weapon can be used.
89 	short sfx, hitsfx;      // Sound when using/hit, or -1.
90 public:
91 	friend class Shape_info;
92 	// Read in from file.
93 	bool read(std::istream &in, int version, Exult_Game game);
94 	// Write out.
95 	void write(std::ostream &out, int shapenum, Exult_Game game);
96 	enum { is_binary = 1, entry_size = 21 };
97 	static const Weapon_info *get_default();
get_damage()98 	int get_damage() const {
99 		return damage;
100 	}
get_damage_type()101 	int get_damage_type() const {
102 		return damage_type;
103 	}
set_damage(int dmg,int dmgtype)104 	void set_damage(int dmg, int dmgtype) {
105 		if (damage != dmg || damage_type != dmgtype) {
106 			set_modified(true);
107 			damage = dmg;
108 			damage_type = dmgtype;
109 		}
110 	}
get_powers()111 	unsigned char get_powers() const {
112 		return powers;
113 	}
set_powers(unsigned char p)114 	void set_powers(unsigned char p) {
115 		if (powers != p) {
116 			set_modified(true);
117 			powers = p;
118 		}
119 	}
get_actor_frames(bool projectile)120 	unsigned char get_actor_frames(bool projectile) const {
121 		return !projectile ? (actor_frames & 3) : (actor_frames >> 2) & 3;
122 	}
set_actor_frames(unsigned char f)123 	void set_actor_frames(unsigned char f) {
124 		if (actor_frames != f) {
125 			set_modified(true);
126 			actor_frames = f;
127 		}
128 	}
get_ammo_consumed()129 	int get_ammo_consumed() const {
130 		return ammo;
131 	}
get_ammo()132 	int get_ammo() const {          // Raw value, for map-editor.
133 		return ammo;
134 	}
set_ammo(int a)135 	void set_ammo(int a) {          // Raw value, for map-editor.
136 		if (ammo != a) {
137 			set_modified(true);
138 			ammo = a;
139 		}
140 	}
uses_charges()141 	bool uses_charges() const {
142 		return ammo == -2;
143 	}
uses_ammo_on_ranged()144 	bool uses_ammo_on_ranged() const {
145 		return ammo != -1;
146 	}
is_thrown()147 	bool is_thrown() const
148 	// Figured this out from printing out values:
149 	{
150 		return ammo == -3 && uses != 0 && uses != 3;
151 	}
returns()152 	bool returns() const {
153 		return m_returns;
154 	}
set_returns(bool tf)155 	void set_returns(bool tf) {
156 		if (m_returns != tf) {
157 			set_modified(true);
158 			m_returns = tf;
159 		}
160 	}
explodes()161 	bool explodes() const {
162 		return m_explodes;
163 	}
set_explodes(bool tf)164 	void set_explodes(bool tf) {
165 		if (m_explodes != tf) {
166 			set_modified(true);
167 			m_explodes = tf;
168 		}
169 	}
no_blocking()170 	bool no_blocking() const {
171 		return m_no_blocking;
172 	}
set_no_blocking(bool tf)173 	void set_no_blocking(bool tf) {
174 		if (m_no_blocking != tf) {
175 			set_modified(true);
176 			m_no_blocking = tf;
177 		}
178 	}
autohits()179 	bool autohits() const {
180 		return m_autohit;
181 	}
set_autohits(bool tf)182 	void set_autohits(bool tf) {
183 		if (m_autohit != tf) {
184 			set_modified(true);
185 			m_autohit = tf;
186 		}
187 	}
lucky()188 	bool lucky() const {
189 		return m_lucky;
190 	}
set_lucky(bool tf)191 	void set_lucky(bool tf) {
192 		if (m_lucky != tf) {
193 			set_modified(true);
194 			m_lucky = tf;
195 		}
196 	}
delete_depleted()197 	bool delete_depleted() const {
198 		return m_delete_depleted;
199 	}
set_delete_depleted(bool tf)200 	void set_delete_depleted(bool tf) {
201 		if (m_delete_depleted != tf) {
202 			set_modified(true);
203 			m_delete_depleted = tf;
204 		}
205 	}
needs_target()206 	bool needs_target() const {
207 		return m_need_target;
208 	}
set_needs_target(bool tf)209 	void set_needs_target(bool tf) {
210 		if (m_need_target != tf) {
211 			set_modified(true);
212 			m_need_target = tf;
213 		}
214 	}
get_uses()215 	unsigned char get_uses() const {
216 		return uses;
217 	}
set_uses(unsigned char u)218 	void set_uses(unsigned char u) {
219 		if (uses != u) {
220 			set_modified(true);
221 			uses = u;
222 		}
223 	}
get_range()224 	int get_range() const {         // Raw # (for map-editor).
225 		return range;
226 	}
set_range(int r)227 	void set_range(int r) {
228 		if (range != r) {
229 			set_modified(true);
230 			range = r;
231 		}
232 	}
get_striking_range()233 	int get_striking_range() const {
234 		return uses < 3 ? range : 0;
235 	}
get_projectile_range()236 	int get_projectile_range() const {  // +++Guess for thrown weapons.
237 		return uses == 3 ? range : -1;
238 	}
get_projectile()239 	int get_projectile() const {
240 		return projectile;
241 	}
set_projectile(int p)242 	void set_projectile(int p) {
243 		if (projectile != p) {
244 			set_modified(true);
245 			projectile = p;
246 		}
247 	}
get_missile_speed()248 	int get_missile_speed() const {
249 		return missile_speed;
250 	}
set_missile_speed(int s)251 	void set_missile_speed(int s) {
252 		if (missile_speed != s) {
253 			set_modified(true);
254 			missile_speed = s;
255 		}
256 	}
get_rotation_speed()257 	int get_rotation_speed() const {
258 		return rotation_speed;
259 	}
set_rotation_speed(int s)260 	void set_rotation_speed(int s) {
261 		if (rotation_speed != s) {
262 			set_modified(true);
263 			rotation_speed = s;
264 		}
265 	}
get_usecode()266 	int get_usecode() const {
267 		return usecode;
268 	}
set_usecode(int u)269 	void set_usecode(int u) {
270 		if (usecode != u) {
271 			set_modified(true);
272 			usecode = u;
273 		}
274 	}
get_sfx()275 	int get_sfx() const {       // Return sound-effects #, or -1.
276 		return sfx;
277 	}
get_hitsfx()278 	int get_hitsfx() const {
279 		return hitsfx;
280 	}
set_sfxs(int s,int hits)281 	void set_sfxs(int s, int hits) {
282 		if (sfx != s || hitsfx != hits) {
283 			set_modified(true);
284 			sfx = s;
285 			hitsfx = hits;
286 		}
287 	}
get_info_flag()288 	static int get_info_flag() {
289 		return 1;
290 	}
291 	int get_base_strength() const;
292 	int get_base_xp_value() const;
293 };
294 
295 #endif
296