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