1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11 
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16 
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef XEEN_CHARACTER_H
24 #define XEEN_CHARACTER_H
25 
26 #include "common/scummsys.h"
27 #include "common/array.h"
28 #include "common/rect.h"
29 #include "common/serializer.h"
30 #include "xeen/combat.h"
31 #include "xeen/item.h"
32 #include "xeen/sprites.h"
33 
34 namespace Xeen {
35 
36 #define INV_ITEMS_TOTAL 9
37 #define SPELLS_PER_CLASS 39
38 #define AWARDS_TOTAL 88
39 #define WARZONE_AWARD 9
40 
41 enum Award {
42 	SHANGRILA_GUILD_MEMBER = 5, GOOBER = 76, SUPER_GOOBER = 77,
43 	CASTLEVIEW_GUILD_MEMBER = 83, SANDCASTER_GUILD_MEMBER = 84,
44 	LAKESIDE_GUILD_MEMBER = 85, NECROPOLIS_GUILD_MEMBER = 86, OLYMPUS_GUILD_MEMBER = 87
45 };
46 
47 enum Sex { MALE = 0, FEMALE = 1, YES_PLEASE = 2 };
48 
49 enum Race { HUMAN = 0, ELF = 1, DWARF = 2, GNOME = 3, HALF_ORC = 4 };
50 
51 enum CharacterClass {
52 	CLASS_KNIGHT = 0, CLASS_PALADIN = 1, CLASS_ARCHER = 2, CLASS_CLERIC = 3,
53 	CLASS_SORCERER = 4, CLASS_ROBBER = 5, CLASS_NINJA = 6, CLASS_BARBARIAN = 7,
54 	CLASS_DRUID = 8, CLASS_RANGER = 9, TOTAL_CLASSES = 10
55 };
56 
57 enum HatesClass {
58 	HATES_DWARF = 12, HATES_PARTY = 15, HATES_NOBODY = 16
59 };
60 
61 enum Attribute {
62 	MIGHT = 0, INTELLECT = 1, PERSONALITY = 2, ENDURANCE = 3, SPEED = 4,
63 	ACCURACY = 5, LUCK = 6, TOTAL_ATTRIBUTES = 7
64 };
65 
66 enum Skill {
67 	THIEVERY = 0, ARMS_MASTER = 1, ASTROLOGER = 2, BODYBUILDER = 3,
68 	CARTOGRAPHER = 4, CRUSADER = 5, DIRECTION_SENSE = 6, LINGUIST = 7,
69 	MERCHANT = 8, MOUNTAINEER = 9, NAVIGATOR = 10, PATHFINDER = 11,
70 	PRAYER_MASTER = 12, PRESTIDIGITATION = 13, SWIMMING = 14, TRACKING = 15,
71 	SPOT_DOORS = 16, DANGER_SENSE = 17
72 };
73 
74 enum Condition {
75 	CURSED = 0, HEART_BROKEN = 1, WEAK = 2, POISONED = 3,
76 	DISEASED = 4, INSANE = 5, IN_LOVE = 6, DRUNK = 7, ASLEEP = 8,
77 	DEPRESSED = 9, CONFUSED = 10, PARALYZED = 11, UNCONSCIOUS = 12,
78 	DEAD = 13, STONED = 14, ERADICATED = 15,
79 	NO_CONDITION = 16
80 };
81 
82 enum QuickAction {
83 	QUICK_ATTACK = 0, QUICK_SPELL = 1, QUICK_BLOCK = 2, QUICK_RUN = 3
84 };
85 
86 enum SpellsCategory {
87 	SPELLCAT_INVALID = -1, SPELLCAT_CLERICAL = 0, SPELLCAT_WIZARDRY = 1, SPELLCAT_DRUIDIC = 2
88 };
89 
90 
91 class XeenEngine;
92 
93 class AttributePair {
94 public:
95 	int _permanent;
96 	int _temporary;
97 public:
98 	AttributePair();
99 	void synchronize(Common::Serializer &s);
100 };
101 
102 class Character {
103 private:
104 	/**
105 	 * Modifies a passed attribute value based on player's condition
106 	 */
107 	int conditionMod(Attribute attrib) const;
108 public:
109 	Common::String _name;
110 	Sex _sex;
111 	Race _race;
112 	int _xeenSide;
113 	CharacterClass _class;
114 	AttributePair _might;
115 	AttributePair _intellect;
116 	AttributePair _personality;
117 	AttributePair _endurance;
118 	AttributePair _speed;
119 	AttributePair _accuracy;
120 	AttributePair _luck;
121 	int _ACTemp;
122 	AttributePair _level;
123 	uint _birthDay;
124 	int _tempAge;
125 	int _skills[18];
126 	int _awards[128];
127 	bool _spells[SPELLS_PER_CLASS];
128 	int _lloydMap;
129 	Common::Point _lloydPosition;
130 	bool _hasSpells;
131 	int8 _currentSpell;
132 	QuickAction _quickOption;
133 	WeaponItems _weapons;
134 	ArmorItems _armor;
135 	AccessoryItems _accessories;
136 	MiscItems _misc;
137 	InventoryItemsGroup _items;
138 	int _lloydSide;
139 	AttributePair _fireResistence;
140 	AttributePair _coldResistence;
141 	AttributePair _electricityResistence;
142 	AttributePair _poisonResistence;
143 	AttributePair _energyResistence;
144 	AttributePair _magicResistence;
145 	int _conditions[16];
146 	int _townUnknown;
147 	int _savedMazeId;
148 	int _currentHp;
149 	int _currentSp;
150 	uint _birthYear;
151 	uint32 _experience;
152 	int _currentAdventuringSpell;
153 	int _currentCombatSpell;
154 
155 	SpriteResource *_faceSprites;
156 	int _rosterId;
157 public:
158 	static int _itemType;
159 public:
160 	/**
161 	 * Constructor
162 	 */
163 	Character();
164 
165 	/**
166 	 * Constructor
167 	 */
168 	Character(const Character &src);
169 
170 	/**
171 	 * Equality operator
172 	 */
173 	bool operator==(const Character &src) const { return src._rosterId == _rosterId; }
174 
175 	/**
176 	 * Inequality operator
177 	 */
178 	bool operator!=(const Character &src) const { return src._rosterId != _rosterId; }
179 
180 	/**
181 	 * Clears the data for a character
182 	 */
183 	void clear();
184 
185 	/**
186 	 * Assignment operator
187 	 */
188 	Character &operator=(const Character &src);
189 
190 	/**
191 	 * Synchronizes data for the character
192 	 */
193 	void synchronize(Common::Serializer &s);
194 
195 	/**
196 	 * Returns the worst condition the character is suffering from
197 	 */
198 	Condition worstCondition() const;
199 
200 	/**
201 	 * Returns whether the given character has a disabling condition, but still alive
202 	 */
203 	bool isDisabled() const;
204 
205 	/**
206 	 * Returns whether the given character has a disabling condition, or is dead
207 	 */
208 	bool isDisabledOrDead() const;
209 
210 	/**
211 	 * Returns whether the given character has a dead condition
212 	 */
213 	bool isDead() const;
214 
215 	/**
216 	 * Get the character's age
217 	 */
218 	int getAge(bool ignoreTemp = false) const;
219 
220 	/**
221 	 * Gets the maximum hit points for a character
222 	 */
223 	int getMaxHP() const;
224 
225 	/**
226 	 * Gets the maximum spell points for a character
227 	 */
228 	int getMaxSP() const;
229 
230 	/**
231 	 * Get the effective value of a given stat for the character
232 	 */
233 	uint getStat(Attribute attrib, bool baseOnly = false) const;
234 
235 	/**
236 	 * Return the color number to use for a given stat value in the character
237 	 * info or quick reference dialogs
238 	 */
239 	static int statColor(int amount, int threshold);
240 
241 	/**
242 	 * Returns the bonus the character gets for stats
243 	 */
244 	int statBonus(uint statValue) const;
245 
246 	/**
247 	 * Returns true if the character passes a saving throw for a given attack type
248 	 */
249 	bool charSavingThrow(DamageType attackType) const;
250 
251 	/**
252 	 * Returns true if the character is unable to perform any action
253 	 */
254 	bool noActions();
255 
256 	/**
257 	 * Sets an award status
258 	 */
259 	void setAward(int awardId, bool value);
260 
261 	/**
262 	 * Returns true if a character has a given award
263 	 */
264 	bool hasAward(int awardId) const;
265 
266 	/**
267 	 * Returns the number of times a character has received a given award
268 	 */
269 	int getAwardCount(int awardId) const;
270 
271 	/**
272 	 * Returns the character's armor class
273 	 */
274 	int getArmorClass(bool baseOnly = false) const;
275 
276 	/**
277 	 * Returns the thievery skill level, adjusted by class and race
278 	 */
279 	int getThievery() const;
280 
281 	uint getCurrentLevel() const;
282 
283 	/**
284 	 * Scans the character's inventory for the given item
285 	 */
286 	int itemScan(int itemId) const;
287 
288 	/**
289 	 * Sets various attributes of a character
290 	 */
291 	void setValue(int id, uint value);
292 
293 	/**
294 	 * Returns true if the character is a member of the current town's guild
295 	 */
296 	bool guildMember() const;
297 
298 	/**
299 	 * Returns the experience required to reach the next level
300 	 */
301 	uint experienceToNextLevel() const;
302 
303 	/**
304 	 * Returns the next level the character will reach
305 	 */
306 	uint nextExperienceLevel() const;
307 
308 	/**
309 	 * Returns the character's current experience
310 	 */
311 	uint getCurrentExperience() const;
312 
313 	/**
314 	 * Returns the number of skills the character has
315 	 */
316 	int getNumSkills() const;
317 
318 	/**
319 	 * Returns the number of awards the character has
320 	 */
321 	int getNumAwards() const;
322 
323 	/**
324 	 * Creates an item and adds it to the inventory
325 	 */
326 	ItemCategory makeItem(int p1, int itemIndex, int p3);
327 
328 	/**
329 	 * Add hit points to a character
330 	 */
331 	void addHitPoints(int amount);
332 
333 	/**
334 	 * Remove hit points from the character
335 	 */
336 	void subtractHitPoints(int amount);
337 
338 	/**
339 	 * Returns true if the character has the Xeen Slayer Sword
340 	 */
341 	bool hasSlayerSword() const;
342 
343 	/**
344 	 * Returns true if the character has a missile weapon, such as a bow
345 	 */
346 	bool hasMissileWeapon() const;
347 
348 	/**
349 	 * Returns the spells category for the character's class
350 	 */
351 	SpellsCategory getSpellsCategory() const;
352 
353 	/**
354 	 * Returns an expense factor for purchasing spells by certain character classes
355 	 */
getSpellsExpenseFactor()356 	int getSpellsExpenseFactor() const {
357 		return (_class == CLASS_PALADIN || _class == CLASS_ARCHER || _class == CLASS_RANGER) ? 1 : 0;
358 	}
359 
360 	/**
361 	 * Clears the character of any currently set conditions
362 	 */
363 	void clearConditions();
364 };
365 
366 class CharacterArray : public Common::Array<Character> {
367 public:
368 	/**
369 	 * Returns the index of a given character in the array
370 	 */
371 	int indexOf(const Character &c);
372 };
373 
374 } // End of namespace Xeen
375 
376 #endif /* XEEN_CHARACTER_H */
377