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 ULTIMA4_GAME_PLAYER_H
24 #define ULTIMA4_GAME_PLAYER_H
25 
26 #include "ultima/ultima4/game/creature.h"
27 #include "ultima/ultima4/map/direction.h"
28 #include "ultima/ultima4/core/observable.h"
29 #include "ultima/ultima4/filesys/savegame.h"
30 #include "ultima/ultima4/game/script.h"
31 #include "ultima/ultima4/map/tile.h"
32 #include "ultima/ultima4/core/types.h"
33 
34 namespace Ultima {
35 namespace Ultima4 {
36 
37 class Armor;
38 class Party;
39 class Weapon;
40 
41 typedef Std::vector<class PartyMember *> PartyMemberVector;
42 
43 #define ALL_PLAYERS -1
44 
45 enum KarmaAction {
46 	KA_FOUND_ITEM,
47 	KA_STOLE_CHEST,
48 	KA_GAVE_TO_BEGGAR,
49 	KA_GAVE_ALL_TO_BEGGAR,
50 	KA_BRAGGED,
51 	KA_HUMBLE,
52 	KA_HAWKWIND,
53 	KA_MEDITATION,
54 	KA_BAD_MANTRA,
55 	KA_ATTACKED_GOOD,
56 	KA_FLED_EVIL,
57 	KA_FLED_GOOD,
58 	KA_HEALTHY_FLED_EVIL,
59 	KA_KILLED_EVIL,
60 	KA_SPARED_GOOD,
61 	KA_DONATED_BLOOD,
62 	KA_DIDNT_DONATE_BLOOD,
63 	KA_CHEAT_REAGENTS,
64 	KA_DIDNT_CHEAT_REAGENTS,
65 	KA_USED_SKULL,
66 	KA_DESTROYED_SKULL
67 };
68 
69 enum HealType {
70 	HT_NONE,
71 	HT_CURE,
72 	HT_FULLHEAL,
73 	HT_RESURRECT,
74 	HT_HEAL,
75 	HT_CAMPHEAL,
76 	HT_INNHEAL
77 };
78 
79 enum InventoryItem {
80 	INV_NONE,
81 	INV_WEAPON,
82 	INV_ARMOR,
83 	INV_FOOD,
84 	INV_REAGENT,
85 	INV_GUILDITEM,
86 	INV_HORSE
87 };
88 
89 enum CannotJoinError {
90 	JOIN_SUCCEEDED,
91 	JOIN_NOT_EXPERIENCED,
92 	JOIN_NOT_VIRTUOUS
93 };
94 
95 enum EquipError {
96 	EQUIP_SUCCEEDED,
97 	EQUIP_NONE_LEFT,
98 	EQUIP_CLASS_RESTRICTED
99 };
100 
101 /**
102  * PartyMember class
103  */
104 class PartyMember : public Creature, public Script::Provider {
105 public:
106 	PartyMember(Party *p, SaveGamePlayerRecord *pr);
107 	virtual ~PartyMember();
108 
109 	/**
110 	 * Notify the party that this player has changed somehow
111 	 */
112 	void notifyOfChange();
113 
114 	/**
115 	 * Used to translate script values into something useful
116 	 */
117 	Common::String translate(Std::vector<Common::String> &parts) override;
118 
119 	// Accessor methods
120 	int getHp() const override;
getMaxHp()121 	int getMaxHp() const {
122 		return _player->_hpMax;
123 	}
getExp()124 	int getExp() const {
125 		return _player->_xp;
126 	}
getStr()127 	int getStr() const {
128 		return _player->_str;
129 	}
getDex()130 	int getDex() const {
131 		return _player->_dex;
132 	}
getInt()133 	int getInt() const {
134 		return _player->_intel;
135 	}
getMp()136 	int getMp() const {
137 		return _player->_mp;
138 	}
139 
140 	/**
141 	 * Determine the most magic points a character could have
142 	 * given his class and intelligence.
143 	 */
144 	int getMaxMp() const;
145 
146 	const Weapon *getWeapon() const;
147 	const Armor *getArmor() const;
148 	Common::String getName() const override;
149 	SexType getSex() const;
150 	ClassType getClass() const;
151 	CreatureStatus getState() const override;
152 
153 	/**
154 	 * Determine what level a character has.
155 	 */
156 	int getRealLevel() const;
157 
158 	/**
159 	 * Determine the highest level a character could have with the number
160 	 * of experience points he has.
161 	 */
162 	int getMaxLevel() const;
163 
164 	/**
165 	 * Adds a status effect to the player
166 	 */
167 	void addStatus(StatusType status) override;
168 
169 	/**
170 	 * Adjusts the player's mp by 'pts'
171 	 */
172 	void adjustMp(int pts);
173 
174 	/**
175 	 * Advances the player to the next level if they have enough experience
176 	 */
177 	void advanceLevel();
178 
179 	/**
180 	 * Apply an effect to the party member
181 	 */
182 	void applyEffect(TileEffect effect);
183 
184 	/**
185 	 * Award a player experience points.  Maxs out the players xp at 9999.
186 	 */
187 	void awardXp(int xp);
188 
189 	/**
190 	 * Perform a certain type of healing on the party member
191 	 */
192 	bool heal(HealType type);
193 
194 	/**
195 	 * Remove status effects from the party member
196 	 */
197 	void removeStatus(StatusType status) override;
198 
199 	void setHp(int hp) override;
200 	void setMp(int mp);
201 	EquipError setArmor(const Armor *a);
202 	EquipError setWeapon(const Weapon *w);
203 
204 	/**
205 	 * Applies damage to a player, and changes status to dead if hit
206 	 * points drop below zero.
207 	 *
208 	 * Byplayer is ignored for now, since it should always be false for U4.  (Is
209 	 * there anything special about being killed by a party member in U5?)  Also
210 	 * keeps interface consistent for virtual base function Creature::applydamage()
211 	 */
212 	bool applyDamage(int damage, bool byplayer = false) override;
213 	int getAttackBonus() const override;
214 	int getDefense() const override;
215 	bool dealDamage(Creature *m, int damage) override;
216 
217 	/**
218 	 * Calculate damage for an attack.
219 	 */
220 	int getDamage();
221 
222 	/**
223 	 * Returns the tile that will be displayed when the party
224 	 * member's attack hits
225 	 */
226 	const Common::String &getHitTile() const override;
227 
228 	/**
229 	 * Returns the tile that will be displayed when the party
230 	 * member's attack fails
231 	 */
232 	const Common::String &getMissTile() const override;
233 	bool isDead();
234 	bool isDisabled();
235 
236 	/**
237 	 * Lose the equipped weapon for the player (flaming oil, ranged daggers, etc.)
238 	 * Returns the number of weapons left of that type, including the one in
239 	 * the players hand
240 	 */
241 	int  loseWeapon();
242 
243 	/**
244 	 * Put the party member to sleep
245 	 */
246 	virtual void putToSleep() override;
247 
248 	/**
249 	 * Wakes up the party member
250 	 */
251 	void wakeUp() override;
252 
253 protected:
254 	static MapTile tileForClass(int klass);
255 
256 	SaveGamePlayerRecord *_player;
257 	class Party *_party;
258 };
259 
260 /**
261  * Party class
262  */
263 class PartyEvent {
264 public:
265 	enum Type {
266 		GENERIC,
267 		LOST_EIGHTH,
268 		ADVANCED_LEVEL,
269 		STARVING,
270 		TRANSPORT_CHANGED,
271 		PLAYER_KILLED,
272 		ACTIVE_PLAYER_CHANGED,
273 		MEMBER_JOINED,
274 		PARTY_REVIVED,
275 		INVENTORY_ADDED
276 	};
277 
PartyEvent(Type type,PartyMember * partyMember)278 	PartyEvent(Type type, PartyMember *partyMember) : _type(type), _player(partyMember) { }
279 
280 	Type _type;
281 	PartyMember *_player;
282 };
283 
284 typedef Std::vector<PartyMember *> PartyMemberVector;
285 
286 class Party : public Observable<Party *, PartyEvent &>, public Script::Provider {
287 	friend class PartyMember;
288 public:
289 	Party(SaveGame *saveGame);
290 	virtual ~Party();
291 
292 	/**
293 	 * Notify the party that something about it has changed
294 	 */
295 	void notifyOfChange(PartyMember *partyMember = 0, PartyEvent::Type = PartyEvent::GENERIC);
296 
297 	// Used to translate script values into something useful
298 	Common::String translate(Std::vector<Common::String> &parts) override;
299 
300 	void adjustFood(int food);
301 	void adjustGold(int gold);
302 
303 	/**
304 	 * Adjusts the avatar's karma level for the given action.  Notify
305 	 * observers with a lost eighth event if the player has lost
306 	 * avatarhood.
307 	 */
308 	void adjustKarma(KarmaAction action);
309 
310 	/**
311 	 * Apply effects to the entire party
312 	 */
313 	void applyEffect(TileEffect effect);
314 
315 	/**
316 	 * Attempt to elevate in the given virtue
317 	 */
318 	bool attemptElevation(Virtue virtue);
319 
320 	/**
321 	 * Burns a torch's duration down a certain number of turns
322 	 */
323 	void burnTorch(int turns = 1);
324 
325 	/**
326 	 * Returns true if the party can enter the shrine
327 	 */
328 	bool canEnterShrine(Virtue virtue);
329 
330 	/**
331 	 * Returns true if the person can join the party
332 	 */
333 	bool canPersonJoin(Common::String name, Virtue *v);
334 
335 	/**
336 	 * Damages the party's ship
337 	 */
338 	void damageShip(uint pts);
339 
340 	/**
341 	 * Donates 'quantity' gold. Returns true if the donation succeeded,
342 	 * or false if there was not enough gold to make the donation
343 	 */
344 	bool donate(int quantity);
345 
346 	/**
347 	 * Ends the party's turn
348 	 */
349 	void endTurn();
350 
351 	/**
352 	 * Adds a chest worth of gold to the party's inventory
353 	 */
354 	int  getChest();
355 
356 	/**
357 	 * Returns the number of turns a currently lit torch will last (or 0 if no torch lit)
358 	 */
359 	int  getTorchDuration() const;
360 
361 	/**
362 	 * Heals the ship's hull strength by 'pts' points
363 	 */
364 	void healShip(uint pts);
365 
366 	/**
367 	 * Returns true if the balloon is currently in the air
368 	 */
369 	bool isFlying() const;
370 
371 	/**
372 	 * Whether or not the party can make an action.
373 	 */
374 	bool isImmobilized();
375 
376 	/**
377 	 * Whether or not all the party members are dead.
378 	 */
379 	bool isDead();
380 
381 	/**
382 	 * Returns true if the person with that name
383 	 * is already in the party
384 	 */
385 	bool isPersonJoined(Common::String name);
386 
387 	/**
388 	 * Attempts to add the person to the party.
389 	 * Returns JOIN_SUCCEEDED if successful.
390 	 */
391 	CannotJoinError join(Common::String name);
392 
393 	/**
394 	 * Lights a torch with a default duration of 100
395 	 */
396 	bool lightTorch(int duration = 100, bool loseTorch = true);
397 
398 	/**
399 	 * Extinguishes a torch
400 	 */
401 	void quenchTorch();
402 
403 	/**
404 	 * Revives the party after the entire party has been killed
405 	 */
406 	void reviveParty();
407 	MapTile getTransport() const;
408 	void setTransport(MapTile transport);
409 	void setShipHull(int str);
410 
411 	Direction getDirection() const;
412 	void setDirection(Direction dir);
413 
414 	void adjustReagent(int reagent, int amt);
415 	int getReagent(int reagent) const;
416 	short *getReagentPtr(int reagent) const;
417 
418 	void setActivePlayer(int p);
419 	int getActivePlayer() const;
420 
421 	void swapPlayers(int p1, int p2);
422 
423 	/**
424 	 * Returns the size of the party
425 	 */
426 	int size() const;
427 
428 	/**
429 	 * Returns a pointer to the party member indicated
430 	 */
431 	PartyMember *member(int index) const;
432 
433 private:
434 	void syncMembers();
435 	PartyMemberVector _members;
436 	SaveGame *_saveGame;
437 	MapTile _transport;
438 	int _torchDuration;
439 	int _activePlayer;
440 #ifdef IOS_ULTIMA4
441 	friend void U4IOS::syncPartyMembersWithSaveGame();
442 #endif
443 };
444 
445 bool isPartyMember(Object *punknown);
446 
447 } // End of namespace Ultima4
448 } // End of namespace Ultima
449 
450 #endif
451