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  * Based on the original sources
23  *   Faery Tale II -- The Halls of the Dead
24  *   (c) 1993-1996 The Wyrmkeep Entertainment Co.
25  */
26 
27 #ifndef SAGA2_PLAYER_H
28 #define SAGA2_PLAYER_H
29 
30 #include "saga2/actor.h"
31 
32 namespace Saga2 {
33 
34 #define FTA_JULIAN  (PlayerActorID)0
35 #define FTA_PHILIP  (PlayerActorID)1
36 #define FTA_KEVIN   (PlayerActorID)2
37 
38 /* ======================================================================= *
39    PlayerActor -- data specific to possible center actors
40  * ======================================================================= */
41 
42 class ContainerNode;
43 
44 class PlayerActor {
45 	friend class Actor;
46 
47 	friend void initPlayerActors(void);
48 	friend void cleanupPlayerActors(void);
49 
50 	ObjectID        actorID;            // ID of player's actor
51 
52 public:
53 	int16           portraitType;       // Integer representing portrait state
54 	// for this player actor
55 	uint16          flags;              // various flags
56 
57 	ActorAttributes baseStats;          // Base stats for this actor
58 	enum PlayerActorFlags {
59 		playerAggressive        = (1 << 0), // Player is in aggressive mode
60 		playerBanded            = (1 << 1), // Player is banded
61 		playerHasCartography    = (1 << 2)  // Player has ability to map
62 	};
63 
64 	// recovery information
65 	enum Recovery {
66 		baseManaRec             = 1,
67 		attribPointsPerUpdate   = 1,
68 		attribPointsPerValue    = 10
69 	};
70 
71 	enum {
72 		vitalityLevelBump       = 50
73 	};
74 
75 	//  Container node for ready containers
76 	ContainerNode           *readyNode;
77 
78 	// mana 'experience' pool
79 	int16   manaMemory[numManas];
80 
81 	// attrib recovery pools
82 	uint8   attribRecPools[numSkills];
83 
84 	// skills 'expericene' pool
85 	uint8   attribMemPools[numSkills];
86 
87 	// vitality pool
88 	uint8 vitalityMemory;
89 
90 	//  Flag indicating wether the user has been notified that this player
91 	//  actor has been attacked since the last combat
92 	bool notifiedOfAttack;
93 
94 	//  Constructor
PlayerActor(ObjectID a)95 	PlayerActor(ObjectID a) :  actorID(a), portraitType(0), flags(0), readyNode(NULL),
96 			vitalityMemory(0), notifiedOfAttack(false) {
97 
98 		assert(ActorAttributes::skillFracPointsPerLevel > 0);    // this is used in a divide
99 
100 		memset(&baseStats, 0, sizeof(baseStats));
101 
102 		for (int i = 0; i < numManas; i++)
103 			manaMemory[i] = 0;
104 
105 		for (int i = 0; i < numSkills; i++) {
106 			attribRecPools[i] = 0;
107 			attribMemPools[i] = 0;
108 		}
109 	}
110 
111 	// gets level of skill
112 	int8 getSkillLevel(SkillProto *, bool base = false);
113 
114 	// get the actorAttributes allskills index from proto
115 	uint8 getStatIndex(SkillProto *);
116 
117 	// get the effective stats of this player actor
118 	ActorAttributes *getEffStats(void);
119 
120 	// these update a players baseStat skills
121 	void skillAdvance(uint8 stat,
122 	                  uint8 advanceChance,
123 	                  uint8 points,
124 	                  uint8 useMult = 1);
125 
126 	void skillAdvance(SkillProto *proto,
127 	                  uint8 points,
128 	                  uint8 useMult = 1);
129 
130 	void skillAdvance(ActorSkillID stat,
131 	                  uint8 points,
132 	                  uint8 useMult = 1);
133 
134 	void vitalityAdvance(uint8 points);
135 
136 	//  Return Actor structure pointer
getActor(void)137 	Actor *getActor(void) {
138 		return (Actor *)GameObject::objectAddress(actorID);
139 	}
140 
141 	//  Return Actor's object ID
getActorID(void)142 	ObjectID getActorID(void) {
143 		return actorID;
144 	}
145 
146 	//  Set player to be aggressive
setAggression(void)147 	void setAggression(void) {
148 		flags |= playerAggressive;
149 	}
150 
151 	//  Set player to not aggressive
clearAggression(void)152 	void clearAggression(void) {
153 		flags &= ~playerAggressive;
154 	}
155 
156 	//  Determine if actor is in aggressive state
isAggressive(void)157 	bool isAggressive(void) {
158 		return (flags & playerAggressive) != 0;
159 	}
160 
161 	//  Set the player to be banded
setBanded(void)162 	void setBanded(void) {
163 		flags |= playerBanded;
164 	}
165 
166 	//  Set the player to not be banded
clearBanded(void)167 	void clearBanded(void) {
168 		flags &= ~playerBanded;
169 	}
170 
171 	//  Determine if this player actor is banded
isBanded(void)172 	bool isBanded(void) {
173 		return (flags & playerBanded) != 0;
174 	}
175 
176 	//  Resolve the banding state of this actor
177 	void resolveBanding(void);
178 
179 	//  Re-evaluate the portrait type for this player actor
180 	void recalcPortraitType(void);
181 
182 	//  Return the integer representing the portrait type for this
183 	//  player actor
getPortraitType(void)184 	int16 getPortraitType(void) {
185 		return portraitType;
186 	}
187 
188 	// figures out what what ( if any ) changes are required to
189 	// the charaters vitality
190 	void recoveryUpdate(void);
191 	void manaUpdate(void);
192 	void AttribUpdate(void);
193 	void stdAttribUpdate(uint8 &stat, uint8 baseStat, int16 index);
194 
195 	// get this player actor's base stats
getBaseStats(void)196 	ActorAttributes &getBaseStats(void) {
197 		return baseStats;
198 	}
199 
200 	//  Notify the user of attack if necessary
201 	void handleAttacked(void);
202 
203 	//  Simply reset the attack notification flag
resetAttackNotification(void)204 	void resetAttackNotification(void) {
205 		notifiedOfAttack = false;
206 	}
207 };
208 
209 //  Return a pointer to a PlayerActor given it's ID
210 PlayerActor *getPlayerActorAddress(PlayerActorID id);
211 
212 //  Return a PlayerActor ID given it's address
213 PlayerActorID getPlayerActorID(PlayerActor *p);
214 
215 //  Return a pointer to the center actor
216 Actor *getCenterActor(void);
217 //  Return the center actor's object ID
218 ObjectID getCenterActorID(void);
219 //  Return the center actor's player actor ID
220 PlayerActorID getCenterActorPlayerID(void);
221 
222 //  Set a new center actor based upon the PlayerActor ID
223 void setCenterActor(PlayerActorID newCenter);
224 
225 //  Set a new center actor based upon the address of the actor's struct
226 void setCenterActor(Actor *newCenter);
227 
228 //  Set a new center actor based upon the address of the PlayerActor
229 //  struct
230 void setCenterActor(PlayerActor *newCenter);
231 
232 //  Get the coordinates of the center actor
233 TilePoint centerActorCoords(void);
234 
235 //  Set a player actor's aggression
236 void setAggression(PlayerActorID player, bool aggression);
237 
238 //  Set the center actor's aggression
setCenterActorAggression(bool aggression)239 inline void setCenterActorAggression(bool aggression) {
240 	setAggression(getCenterActorPlayerID(), aggression);
241 }
242 
243 //  Determine the state of a player actor's aggression
244 bool isAggressive(PlayerActorID player);
245 
246 //  Determine if center actor is aggressive
isCenterActorAggressive(void)247 inline bool isCenterActorAggressive(void) {
248 	return isAggressive(getCenterActorPlayerID());
249 }
250 
251 //  Set a player actor's banding
252 void setBanded(PlayerActorID player, bool banded);
253 
254 //  Determine if a player actor is banded
255 bool isBanded(PlayerActorID player);
256 
257 //  Globally enable or disable player actor banding
258 void setBrotherBanding(bool enabled);
259 
260 //  Adjust the player actors aggression setting based upon their
261 //  proximity to enemies
262 void autoAdjustAggression(void);
263 
264 //  Calculate the portrait for this brother's current state.
265 void recalcPortraitType(PlayerActorID id);
266 
267 //  Returns an integer value representing this player actor's portrait
268 //  state
269 int16 getPortraitType(PlayerActorID id);
270 
271 bool actorToPlayerID(Actor *a, PlayerActorID &result);
272 bool actorIDToPlayerID(ObjectID id, PlayerActorID &result);
273 
274 void handlePlayerActorDeath(PlayerActorID id);
275 
276 //  Transport the center actor and the banded brothers who have a path
277 //  the the center actor
278 void transportCenterBand(const Location &loc);
279 
280 void handlePlayerActorAttacked(PlayerActorID id);
281 
282 void handleEndOfCombat(void);
283 
284 /* ======================================================================= *
285    PlayerActor list management function prototypes
286  * ======================================================================= */
287 
288 
289 //  Initialize the player actor list
290 void initPlayerActors(void);
291 
292 void savePlayerActors(Common::OutSaveFile *out);
293 void loadPlayerActors(Common::InSaveFile *in);
294 
295 //  Cleanup the player actor list
296 void cleanupPlayerActors(void);
297 
298 /* ======================================================================= *
299    CenterActor management function prototypes
300  * ======================================================================= */
301 
302 //  Initialize the center actor ID and view object ID
303 void initCenterActor(void);
304 
305 void saveCenterActor(Common::OutSaveFile *outS);
306 void loadCenterActor(Common::InSaveFile *in);
307 
308 //  Do nothing
cleanupCenterActor(void)309 inline void cleanupCenterActor(void) {}
310 
311 /* ======================================================================= *
312    PlayerActor iteration class
313  * ======================================================================= */
314 
315 class PlayerActorIterator {
316 protected:
317 	int16               index;
318 
319 public:
PlayerActorIterator(void)320 	PlayerActorIterator(void) {
321 		index = 0;
322 	}
323 
324 	PlayerActor *first(void);
325 	PlayerActor *next(void);
326 };
327 
328 //  Iterates through all player actors that are not dead.
329 
330 class LivingPlayerActorIterator : public PlayerActorIterator {
331 
332 public:
LivingPlayerActorIterator(void)333 	LivingPlayerActorIterator(void) {}
334 
335 	PlayerActor *first(void);
336 	PlayerActor *next(void);
337 };
338 
339 } // end of namespace Saga2
340 
341 #endif
342