1 /**
2  ** objdollinf.h - Object Paperdoll information from 'paperdol_info.txt'.
3  **
4  ** Written: 06/01/2008 - Marzo
5  **/
6 
7 #ifndef INCL_OBJDOLLINF_H
8 #define INCL_OBJDOLLINF_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 <array>
32 #include <cstring>
33 #include <iosfwd>
34 
35 class Shape_info;
36 
37 /*
38  *  Information about an object's paperdoll.
39  *  This is meant to be stored in a totally ordered vector.
40  */
41 class Paperdoll_item : public Base_info {
42 private:
43 	short   world_frame;        // Frame in the world (-1 for all)
44 	short   spot;               // Spot placed in
45 	short   type;               // For weapons, the arm frame type to use.
46 	// For headgear, head frame to use.
47 	// Meaningless for all others.
48 	bool    translucent;        // If the paperdoll should be drawn translucently or not
49 	bool    gender;             // Is this object gender specific
50 
51 	short   shape;              // The shape (if -1 use world shape and frame)
52 	std::array<short, 4> frame; // The paperdoll frame and alternates.
53 public:
54 	friend class Shape_info;
55 	Paperdoll_item() = default;
56 	Paperdoll_item(short w, short sp, short ty, bool tr, bool g,
57 	               short sh, short fr0, short fr1, short fr2, short fr3,
58 	               bool p = false, bool m = false, bool s = false,
59 	               bool inv = false)
Base_info(m,p,inv,s)60 		: Base_info(m, p, inv, s), world_frame(w), spot(sp),
61 		  type(ty), translucent(tr), gender(g), shape(sh),
62 		  frame{fr0, fr1, fr2, fr3} {
63 	}
64 	// Read in from file.
65 	bool read(std::istream &in, int version, Exult_Game game);
66 	// Write out.
67 	void write(std::ostream &out, int shapenum, Exult_Game game);
invalidate()68 	void invalidate() {
69 		type = -255;
70 		set_invalid(true);
71 	}
get_world_frame()72 	int get_world_frame() const {
73 		return world_frame;
74 	}
get_object_spot()75 	int get_object_spot() const {
76 		return spot;
77 	}
get_spot_frame()78 	short get_spot_frame() const {
79 		return type;
80 	}
set_spot_frame(short f)81 	void set_spot_frame(short f) {
82 		if (type != f) {
83 			set_modified(true);
84 			type = f;
85 		}
86 	}
is_translucent()87 	bool is_translucent() const {
88 		return translucent;
89 	}
set_translucent(bool tf)90 	void set_translucent(bool tf) {
91 		if (translucent != tf) {
92 			set_modified(true);
93 			translucent = tf;
94 		}
95 	}
is_gender_based()96 	bool is_gender_based() const {
97 		return gender;
98 	}
set_gender(bool tf)99 	void set_gender(bool tf) {
100 		if (gender != tf) {
101 			set_modified(true);
102 			gender = tf;
103 		}
104 	}
get_paperdoll_shape()105 	int get_paperdoll_shape() const {
106 		return shape;
107 	}
set_paperdoll_shape(short s)108 	void set_paperdoll_shape(short s) {
109 		if (shape != s) {
110 			set_modified(true);
111 			shape = s;
112 		}
113 	}
get_paperdoll_baseframe()114 	int get_paperdoll_baseframe() const {
115 		return frame[0];
116 	}
get_paperdoll_frame(int num)117 	int get_paperdoll_frame(int num) const {
118 		if (num >= 0 && num < 4)
119 			return frame[num];
120 		return get_paperdoll_baseframe();
121 	}
set_paperdoll_frame(int num,short fr)122 	void set_paperdoll_frame(int num, short fr) {
123 		if (frame[num] != fr) {
124 			set_modified(true);
125 			frame[num] = fr;
126 		}
127 	}
128 	void set_paperdoll_frames(short f0, short f1 = -1,
129 	                          short f2 = -1, short f3 = -1) {
130 		set_paperdoll_frame(0, f0);
131 		set_paperdoll_frame(1, f1);
132 		set_paperdoll_frame(2, f2);
133 		set_paperdoll_frame(3, f3);
134 	}
135 	bool operator<(const Paperdoll_item &other) const {
136 		auto wf1 = static_cast<unsigned short>(world_frame);
137 		auto wf2 = static_cast<unsigned short>(other.world_frame);
138 		return (wf1 < wf2)
139 		       || (world_frame == other.world_frame && spot < other.spot);
140 	}
141 	bool operator==(const Paperdoll_item &other) const {
142 		return this == &other || (!(*this < other) && !(other < *this));
143 	}
144 	bool operator!=(const Paperdoll_item &other) const {
145 		return !(*this == other);
146 	}
set(const Paperdoll_item & other)147 	void set(const Paperdoll_item &other) {
148 		// Assumes *this == other.
149 		if (this != &other) {
150 			// Do NOT copy modified or static flags.
151 			set_patch(other.from_patch());
152 			set_invalid(other.is_invalid());
153 			set_spot_frame(other.type);
154 			set_translucent(other.translucent);
155 			set_gender(other.gender);
156 			set_paperdoll_shape(other.shape);
157 			if (frame != other.frame) {
158 				set_modified(true);
159 				frame = other.frame;
160 			}
161 		}
162 	}
163 	enum { is_binary = 0, entry_size = 0 };
164 };
165 
166 #endif
167