ScummVM API documentation
character.h
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 modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (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, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#ifndef MM1_DATA_CHAR_H
23#define MM1_DATA_CHAR_H
24
25#include "common/array.h"
26#include "common/serializer.h"
27#include "mm/mm1/data/items.h"
28#include "mm/shared/xeen/sprites.h"
29
30namespace MM {
31namespace MM1 {
32
33#define INVENTORY_COUNT 6
34#define MAX_LEVEL 200
35#define NUM_PORTRAITS 12
36
37enum CharacterClass {
38 KNIGHT = 1, PALADIN = 2, ARCHER = 3, CLERIC = 4,
39 SORCERER = 5, ROBBER = 6, NONE = 0
40};
41
42enum Race {
43 HUMAN = 1, ELF = 2, DWARF = 3, GNOME = 4, HALF_ORC = 5
44};
45
46enum Alignment {
47 GOOD = 1, NEUTRAL = 2, EVIL = 3
48};
49
50enum Sex {
51 MALE = 1, FEMALE = 2, YES_PLEASE = 3
52};
53
54enum Condition {
55 FINE = 0, BAD_CONDITION = 0x80, ERADICATED = 0xff,
56 DEAD = 0x40, STONE = 0x20,
57 UNCONSCIOUS = 0x40, PARALYZED = 0x20, POISONED = 0x10,
58 DISEASED = 8, SILENCED = 4, BLINDED = 2, ASLEEP = 1
59};
60
61enum ConditionEnum {
62 HEART_BROKEN = 1,
63 C_BLINDED = 2, // WEAK condition in Xeen
64 C_POISONED = 3,
65 C_DISEASED = 4,
66 C_ASLEEP = 8,
67 DEPRESSED = 9,
68 C_SILENCED = 10, // CONFUSED condition in Xeen
69 C_PARALYZED = 11,
70 C_UNCONSCIOUS = 12,
71 C_DEAD = 13,
72 C_STONE = 14,
73 C_ERADICATED = 15,
74 C_GOOD = 16
75};
76
77enum Resistance {
78 RESISTANCE_MAGIC = 0, RESISTANCE_FIRE = 1, RESISTANCE_COLD = 2,
79 RESISTANCE_ELECTRICITY = 3, RESISTANCE_ACID = 4,
80 RESISTANCE_FEAR = 5, RESISTANCE_POISON = 6,
81 RESISTANCE_PSYCHIC = 7, RESISTANCE_15 = 15
82};
83
84enum CharFlags0 {
85 CHARFLAG0_COURIER1 = 1,
86 CHARFLAG0_COURIER2 = 2,
87 CHARFLAG0_COURIER3 = 4,
88 CHARFLAG0_ZOM_CLUE = 8,
89 CHARFLAG0_ZAM_CLUE = 0x10,
90 CHARFLAG0_FOUND_CHEST = 0x20,
91 CHARFLAG0_40 = 0x40,
92 CHARFLAG0_DOG_STATUE = 0x80
93};
94
95enum CharFlags1 {
96 CHARFLAG1_1 = 1,
97 CHARFLAG1_2 = 2,
98 CHARFLAG1_4 = 4,
99 CHARFLAG1_8 = 8,
100 CHARFLAG1_10 = 0x10,
101 CHARFLAG1_20 = 0x20,
102 CHARFLAG1_40 = 0x40,
103 CHARFLAG1_WORTHY = 0x80
104};
105
106enum CharFlags2 {
107 CHARFLAG2_1 = 1,
108 CHARFLAG2_2 = 2,
109 CHARFLAG2_4 = 4,
110 CHARFLAG2_8 = 8,
111 CHARFLAG2_10 = 0x10,
112 CHARFLAG2_20 = 0x20,
113 CHARFLAG2_40 = 0x40,
114 CHARFLAG2_80 = 0x80
115};
116
117enum CharFlags4 {
118 CHARFLAG4_ASSIGNED = 8,
119 CHARFLAG4_SIGN = 7,
120 CHARFLAG4_COLOR = 0xf,
121 CHARFLAG4_80 = 0x80
122};
123
124enum CharFlags5 {
125 CHARFLAG5_1 = 1,
126 CHARFLAG5_2 = 2,
127 CHARFLAG5_4 = 4,
128 CHARFLAG5_8 = 8,
129 CHARFLAG5_10 = 0x10,
130 CHARFLAG5_20 = 0x20,
131 CHARFLAG5_40 = 0x40,
132 CHARFLAG5_80 = 0x80
133};
134
135enum CharFlags6 {
136 CHARFLAG6_1 = 1,
137 CHARFLAG6_2 = 2,
138 CHARFLAG6_4 = 4,
139 CHARFLAG6_8 = 8,
140 CHARFLAG6_10 = 0x10,
141 CHARFLAG6_20 = 0x20,
142 CHARFLAG6_40 = 0x40,
143 CHARFLAG6_80 = 0x80
144};
145
146enum CharFlags7 {
147 CHARFLAG7_1 = 1,
148 CHARFLAG7_2 = 2,
149 CHARFLAG7_4 = 4,
150 CHARFLAG7_8 = 8,
151 CHARFLAG7_10 = 0x10,
152 CHARFLAG7_20 = 0x20,
153 CHARFLAG7_40 = 0x40,
154 CHARFLAG7_80 = 0x80
155};
156
157enum CharFlags8 {
158 CHARFLAG8_1 = 1,
159 CHARFLAG8_2 = 2,
160 CHARFLAG8_4 = 4,
161 CHARFLAG8_8 = 8,
162 CHARFLAG8_10 = 0x10,
163 CHARFLAG8_20 = 0x20,
164 CHARFLAG8_40 = 0x40,
165 CHARFLAG8_80 = 0x80
166};
167
168enum CharFlags9 {
169 CHARFLAG9_1 = 1,
170 CHARFLAG9_2 = 2,
171 CHARFLAG9_4 = 4,
172 CHARFLAG9_8 = 8,
173 CHARFLAG9_10 = 0x10,
174 CHARFLAG9_20 = 0x20,
175 CHARFLAG9_40 = 0x40,
176 CHARFLAG9_80 = 0x80
177};
178
179enum CharFlags10 {
180 CHARFLAG10_1 = 1,
181 CHARFLAG10_2 = 2,
182 CHARFLAG10_4 = 4,
183 CHARFLAG10_8 = 8,
184 CHARFLAG10_10 = 0x10,
185 CHARFLAG10_20 = 0x20,
186 CHARFLAG10_40 = 0x40,
187 CHARFLAG10_80 = 0x80
188};
189
190enum CharFlags11 {
191 CHARFLAG11_GOT_ENDURANCE = 1,
192 CHARFLAG11_PERSONALITY = 2,
193 CHARFLAG11_GOT_INTELLIGENCE = 4,
194 CHARFLAG11_GOT_MIGHT = 8,
195 CHARFLAG11_GOT_ACCURACY = 0x10,
196 CHARFLAG11_GOT_SPEED = 0x20,
197 CHARFLAG11_GOT_LUCK = 0x40,
198 CHARFLAG11_CLERICS = 0x80
199};
200
201enum CharFlags12 {
202 CHARFLAG12_1 = 1,
203 CHARFLAG12_2 = 2,
204 CHARFLAG12_4 = 4,
205 CHARFLAG12_8 = 8,
206 CHARFLAG12_10 = 0x10,
207 CHARFLAG12_20 = 0x20,
208 CHARFLAG12_40 = 0x40,
209 CHARFLAG12_80 = 0x80
210};
211
212enum CharFlags13 {
213 CHARFLAG13_1 = 1,
214 CHARFLAG13_2 = 2,
215 CHARFLAG13_4 = 4,
216 CHARFLAG13_8 = 8,
217 CHARFLAG13_10 = 0x10,
218 CHARFLAG13_20 = 0x20,
219 CHARFLAG13_ALAMAR = 0x40,
220 CHARFLAG13_80 = 0x80
221};
222
224public:
225 struct Entry {
226 byte _id = 0;
227 byte _charges = 0;
228 operator bool() const { return _id != 0; }
229// bool operator!() const { return !_id; }
230// operator byte() const { return _id; }
231 };
232private:
234
238 typedef bool (*CategoryFn)(byte id);
239 bool hasCategory(CategoryFn fn) const;
240
244 int getFreeSlot() const;
245
246public:
247 Inventory() {
248 clear();
249 }
250 Entry &operator[](uint idx) {
251 assert(idx < INVENTORY_COUNT);
252 return _items[idx];
253 }
254 const Entry &operator[](uint idx) const {
255 assert(idx < INVENTORY_COUNT);
256 return _items[idx];
257 }
258
262 void synchronize(Common::Serializer &s, bool ids);
263
267 void clear();
268
272 bool empty() const;
273
277 bool full() const;
278
282 uint size() const;
283
287 uint add(byte id, byte charges);
288
292 void removeAt(uint idx);
293
297 void remove(Entry *e);
298
302 int indexOf(Entry *e) const;
303
307 int indexOf(byte itemId) const;
308
314
319 bool hasWeapon() const { return hasCategory(isWeapon); }
320 bool hasMissile() const { return hasCategory(isMissile); }
321 bool hasTwoHanded() const { return hasCategory(isTwoHanded); }
322 bool hasArmor() const { return hasCategory(isArmor); }
323 bool hasShield() const { return hasCategory(isShield); }
324
325 size_t getPerformanceTotal() const;
326};
327
333 uint8 _current = 0;
334 uint8 _base = 0;
335
336 operator uint8() const { return _current; }
337 AttributePair &operator=(byte v) {
338 _base = _current = v;
339 return *this;
340 }
341 AttributePair &operator++() {
342 if (_base < 255)
343 _current = ++_base;
344 return *this;
345 }
346 AttributePair &operator--() {
347 if (_base > 0)
348 _current = --_base;
349 return *this;
350 }
351 void clear() { _current = _base = 0; }
352 void reset() { _current = _base; }
353 void synchronize(Common::Serializer &s) {
354 s.syncAsByte(_base);
355 s.syncAsByte(_current);
356 }
357
358 size_t getPerformanceTotal() const {
359 return (size_t)_base + (size_t)_current;
360 }
361};
362
364 uint16 _current = 0;
365 uint16 _base = 0;
366
367 void clear() { _current = _base = 0; }
368 AttributePair16 &operator=(byte v) {
369 _base = _current = v;
370 return *this;
371 }
372 operator uint16() const {
373 return _current;
374 }
375 void synchronize(Common::Serializer &s) {
376 s.syncAsUint16LE(_base);
377 s.syncAsUint16LE(_current);
378 }
379
380 size_t getPerformanceTotal() const {
381 return (_base & 0xff) + (_base >> 8) +
382 (_current & 0xff) + (_current >> 8);
383 }
384};
385
387 AttributePair _magic;
388 AttributePair _fire;
389 AttributePair _cold;
390 AttributePair _electricity;
391 AttributePair _acid;
392 AttributePair _fear;
393 AttributePair _poison;
394 AttributePair _psychic;
395};
396
399 AttributePair _arr[8];
400
401 Resistances();
402
407
408 size_t getPerformanceTotal() const;
409};
410
412public:
413 AttributePair _intelligence;
414 AttributePair _might;
415 AttributePair _personality;
416 AttributePair _endurance;
417 AttributePair _speed;
418 AttributePair _accuracy;
419 AttributePair _luck;
420 AttributePair _level;
421
422 AttributePair &getAttribute(uint i) {
423 return *_attributes[i];
424 }
425private:
426 AttributePair *_attributes[8] = {
427 &_intelligence, &_might, &_personality, &_endurance,
428 &_speed, &_accuracy, &_luck, &_level
429 };
430};
431
433 char _name[16] = { 0 };
434 Sex _sex = MALE;
435 Alignment _alignmentInitial = GOOD;
436 Alignment _alignment = GOOD;
437 Race _race = HUMAN;
438 CharacterClass _class = NONE;
439
440 byte _age = 18;
441 int _ageDayCtr = 0;
442 AttributePair16 _sp;
443 AttributePair _spellLevel;
444 AttributePair _ac;
445
446 uint32 _exp = 0;
447 uint16 _gems = 0;
448 uint16 _hpCurrent = 0, _hp = 0, _hpMax = 0;
449 uint32 _gold = 0;
450 uint8 _food = 0;
451 uint8 _condition = 0;
452 Inventory _equipped;
453 Inventory _backpack;
454 Resistances _resistances;
455
456 AttributePair _physicalAttr, _missileAttr;
457 byte _trapCtr = 0;
458 byte _quest = 0;
459 byte _worthiness = 0;
460 byte _alignmentCtr = 0;
461 byte _flags[14];
462
463 byte _portrait = 0;
464 Shared::Xeen::SpriteResource _faceSprites;
465
466 // Non persistent fields
467 byte _numDrinks = 0;
468 // Combat fields
469 bool _checked = false;
470 bool _canAttack = false;
471 int _nonCombatSpell = -1;
472 int _combatSpell = -1;
473
477 int spellNumber() const;
478
482 void setSpellNumber(int spellNum);
483
484 Character();
485
491 void synchronize(Common::Serializer &s, int portraitNum = -1);
492
496 bool operator==(const Character &rhs) const {
497 return !strcmp(_name, rhs._name);
498 }
499
503 void clear();
504
509
515
519 enum TradeResult { TRADE_SUCCESS, TRADE_NO_ITEM, TRADE_FULL };
520 TradeResult trade(int whoTo, int itemIndex);
521
526 int _numHP;
527 int _numSpells;
528 };
529 LevelIncrease increaseLevel();
530
534 enum BuyResult { BUY_SUCCESS, BUY_NOT_ENOUGH_GOLD, BUY_BACKPACK_FULL };
535 BuyResult buyItem(byte itemId);
536
542
546 void updateAC();
547
551 void updateSP();
552
553 void updateResistances();
554
559
563 void rest();
564
568 bool hasItem(byte itemId) const;
569
575 size_t getPerformanceTotal() const;
576
581
587
591 bool canLevelUp() const;
592
597 byte statColor(int amount, int threshold) const;
598
602 byte conditionColor() const;
603
608 ConditionEnum worstCondition() const;
609
613 static Common::String getConditionString(ConditionEnum cond);
614
618 bool hasBadCondition() const {
619 return (_condition & BAD_CONDITION) != 0;
620 }
621};
622
624 CharacterClass _class;
625 Sex _sex;
626 Common::String _name;
627};
628
629} // namespace MM1
630} // namespace MM
631
632#endif
Definition: serializer.h:80
Definition: str.h:59
Definition: character.h:223
int indexOf(byte itemId) const
bool full() const
void remove(Entry *e)
void synchronize(Common::Serializer &s, bool ids)
bool hasWeapon() const
Definition: character.h:319
int indexOf(Entry *e) const
void removeCharge(Entry *e)
bool empty() const
uint add(byte id, byte charges)
void removeAt(uint idx)
uint size() const
Definition: sprites.h:52
Definition: detection.h:27
Definition: character.h:363
Definition: character.h:332
Definition: character.h:525
Definition: character.h:432
static Common::String getConditionString(ConditionEnum cond)
uint32 experienceForNextLevel() const
BuyResult
Definition: character.h:534
bool operator==(const Character &rhs) const
Definition: character.h:496
int spellNumber() const
ConditionEnum worstCondition() const
TradeResult
Definition: character.h:519
bool hasItem(byte itemId) const
byte conditionColor() const
Common::String getConditionString() const
void setSpellNumber(int spellNum)
byte statColor(int amount, int threshold) const
bool hasBadCondition() const
Definition: character.h:618
size_t getPerformanceTotal() const
bool canLevelUp() const
void synchronize(Common::Serializer &s, int portraitNum=-1)
Definition: character.h:225
Definition: character.h:411
Definition: character.h:386
Definition: character.h:623
Definition: character.h:397
void synchronize(Common::Serializer &s)