factored out the EFFv2 saving into EFFImporter
[gemrb.git] / gemrb / core / Game.h
blob1e4f9b9ea487083729db01b450e7f1d4f092583f
1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 The GemRB Project
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 /**
22 * @file Game.h
23 * Declares Game class, object representing current game state.
24 * @author The GemRB Project
28 class Game;
30 #ifndef GAME_H
31 #define GAME_H
33 #include "exports.h"
34 #include "ie_types.h"
36 #include "Callback.h"
37 #include "Map.h"
38 #include "Variables.h"
39 #include "Scriptable/Actor.h"
41 #include <vector>
43 class Particles;
45 //the size of the bestiary register
46 #define BESTIARY_SIZE 260
48 //ShareXP flags
49 #define SX_DIVIDE 1 //divide XP among team members
50 #define SX_CR 2 //use challenge rating resolution
52 //joinparty flags
53 #define JP_JOIN 1 //refresh join time
54 #define JP_INITPOS 2 //init startpos
55 #define JP_SELECT 4 //select the actor after joining
57 //protagonist mode
58 #define PM_NO 0 //no death checks
59 #define PM_YES 1 //if protagonist dies, game over
60 #define PM_TEAM 2 //if team dies, game over
62 // Flags bits for SelectActor()
63 // !!! Keep these synchronized with GUIDefines.py !!!
64 #define SELECT_NORMAL 0x00
65 #define SELECT_REPLACE 0x01 // when selecting actor, deselect all others
66 #define SELECT_QUIET 0x02 // do not run handler when changing selection
68 // Flags bits for EveryoneNearPoint()
69 #define ENP_CANMOVE 1 // also check if the PC can move
70 #define ENP_ONLYSELECT 2 // check only selected PC
72 // GUI Control Status flags (saved in game)
73 #define CS_PARTY_AI 1 //enable party AI
74 #define CS_MEDIUM 2 //medium dialog
75 #define CS_LARGE 6 //large dialog, both bits set
76 #define CS_DIALOGSIZEMASK 6
77 #define CS_DIALOG 8 //dialog is running
78 #define CS_HIDEGUI 16 //hide all gui
79 #define CS_ACTION 32 //hide action pane
80 #define CS_PORTRAIT 64 //hide portrait pane
81 #define CS_MAPNOTES 128 //hide mapnotes
83 //Weather bits
84 #define WB_NORMAL 0
85 #define WB_RAIN 1
86 #define WB_SNOW 2
87 #define WB_FOG 3
88 #define WB_MASK 7
89 #define WB_LIGHTNING 8
90 #define WB_HASWEATHER 0x40
91 #define WB_START 0x80
93 //Rest flags
94 #define REST_NOAREA 1 //no area check
95 #define REST_NOSCATTER 2 //no scatter check
96 #define REST_NOMOVE 4 //no movement check
97 #define REST_NOCRITTER 8 //no hostiles check
99 //Song types (hardcoded)
100 #define SONG_DAY 0
101 #define SONG_NIGHT 1
102 #define SONG_BATTLE 3
105 * @struct PCStruct
106 * Information about party member.
109 struct PCStruct {
110 ieWord Selected;
111 ieWord PartyOrder;
112 ieDword OffsetToCRE;
113 ieDword CRESize;
114 ieResRef CREResRef;
115 ieDword Orientation;
116 ieResRef Area;
117 ieWord XPos;
118 ieWord YPos;
119 ieWord ViewXPos;
120 ieWord ViewYPos;
121 ieWord ModalState;
122 ieWord Happiness;
123 ieDword Interact[MAX_INTERACT];
124 ieWord QuickWeaponSlot[MAX_QUICKWEAPONSLOT];
125 ieWord QuickWeaponHeader[MAX_QUICKWEAPONSLOT];
126 ieResRef QuickSpellResRef[MAX_QSLOTS];
127 ieWord QuickItemSlot[MAX_QUICKITEMSLOT];
128 ieWord QuickItemHeader[MAX_QUICKITEMSLOT];
129 char Name[32];
130 ieDword TalkCount;
131 ieByte QSlots[GUIBT_COUNT];
132 ieByte QuickSpellClass[MAX_QSLOTS];
135 #define IE_GAM_JOURNAL 0
136 #define IE_GAM_QUEST_UNSOLVED 1
137 #define IE_GAM_QUEST_DONE 2
138 #define IE_GAM_JOURNAL_USER 3
141 * @struct GAMJournalEntry
142 * Single entry in a journal
145 struct GAMJournalEntry {
146 ieStrRef Text;
147 ieDword GameTime; // in game time seconds
148 ieByte Chapter;
149 ieByte unknown09;
150 ieByte Section;
151 ieByte Group; // this is a GemRB extension
154 // Saved location of party member.
155 struct GAMLocationEntry {
156 ieResRef AreaResRef;
157 Point Pos;
160 #define MAX_CRLEVEL 32
162 typedef int CRRow[MAX_CRLEVEL];
165 * @class Game
166 * Object representing current game state, mostly party.
169 class GEM_EXPORT Game : public Scriptable {
170 public:
171 Game(void);
172 ~Game(void);
173 private:
174 std::vector< Actor*> PCs;
175 std::vector< Actor*> NPCs;
176 std::vector< Map*> Maps;
177 std::vector< GAMJournalEntry*> Journals;
178 std::vector< GAMLocationEntry*> savedpositions;
179 std::vector< GAMLocationEntry*> planepositions;
180 std::vector< char*> mastarea;
181 std::vector< ieDword> Attackers;
182 CRRow *crtable;
183 ieResRef restmovies[8];
184 ieResRef daymovies[8];
185 ieResRef nightmovies[8];
186 int MapIndex;
187 public:
188 std::vector< Actor*> selected;
189 int version;
190 Variables* kaputz;
191 ieByte* beasts;
192 ieByte* mazedata; //only in PST
193 ieResRef Familiars[9];
194 ieDword CombatCounter;
195 ieDword StateOverrideFlag, StateOverrideTime;
196 ieDword BanterBlockFlag, BanterBlockTime;
198 /** Index of PC selected in non-walking environment (shops, inventory...) */
199 int SelectedSingle;
200 /** 0 if the protagonist's death doesn't cause game over */
201 /** 1 if the protagonist's death causes game over */
202 /** 2 if no check is needed (pst) */
203 int protagonist;
204 /** if party size exceeds this amount, a callback will be called */
205 size_t partysize;
206 ieDword Ticks;
207 ieDword interval; // 1000/AI_UPDATE (a tenth of a round in ms)
208 ieDword GameTime;
209 ieDword LastScriptUpdate; // GameTime at which UpdateScripts last ran
210 ieDword RealTime;
211 ieWord WhichFormation;
212 ieWord Formations[5];
213 ieDword PartyGold;
214 ieWord NpcInParty;
215 ieWord WeatherBits;
216 ieDword Unknown48; //still unknown
217 ieDword Reputation;
218 ieDword ControlStatus; // used in bg2, iwd (where you can switch panes off)
219 ieDword Expansion; // mostly used by BG2. IWD games set it to 3 on newgame
220 ieResRef AnotherArea;
221 ieResRef CurrentArea;
222 ieResRef PreviousArea; //move here if the worldmap exit is illegal?
223 ieResRef LoadMos;
224 Actor *timestop_owner;
225 ieDword timestop_end;
226 Particles *weather;
227 int event_timer;
228 EventHandler event_handler; //like in Control
229 bool hasInfra;
230 private:
231 /** reads the challenge rating table */
232 void LoadCRTable();
233 public:
234 /** Returns the PC's slot count for partyID */
235 int FindPlayer(unsigned int partyID);
236 /** Returns actor by slot */
237 Actor* GetPC(unsigned int slot, bool onlyalive);
238 /** Finds an actor in party by party ID, returns Actor, if not there, returns NULL*/
239 Actor* FindPC(unsigned int partyID);
240 Actor* FindNPC(unsigned int partyID);
241 /** Finds a global actor by global ID */
242 Actor* GetGlobalActorByGlobalID(ieDword globalID);
243 /** Finds an actor in party, returns slot, if not there, returns -1*/
244 int InParty(Actor* pc) const;
245 /** Finds an actor in store, returns slot, if not there, returns -1*/
246 int InStore(Actor* pc) const;
247 /** Finds an actor in party by scripting name*/
248 Actor* FindPC(const char *deathvar);
249 /** Finds an actor in store by scripting name*/
250 Actor* FindNPC(const char *deathvar);
251 /** Sets the area and position of the actor to the starting position */
252 void InitActorPos(Actor *actor);
253 /** Joins party */
254 int JoinParty(Actor* pc, int join=JP_JOIN);
255 /** Return current party size */
256 int GetPartySize(bool onlyalive) const;
257 /** Returns the npcs count */
258 int GetNPCCount() const { return (int)NPCs.size(); }
259 /** Sends the hotkey trigger to all selected pcs */
260 void SetHotKey(unsigned long Key);
261 /** Select PC for non-walking environment (shops, inventory, ...) */
262 bool SelectPCSingle(int index);
263 /** Get index of selected PC for non-walking env (shops, inventory, ...) */
264 int GetSelectedPCSingle() const;
265 /** (De)selects actor. */
266 bool SelectActor( Actor* actor, bool select, unsigned flags );
268 /** Return current party level count for xp calculations */
269 int GetPartyLevel(bool onlyalive) const;
270 /** Reassigns inparty numbers, call it after party creation */
271 void ConsolidateParty();
272 /** Removes actor from party (if in there) */
273 int LeaveParty(Actor* pc);
274 /** Returns slot*/
275 int DelPC(unsigned int slot, bool autoFree = false);
276 int DelNPC(unsigned int slot, bool autoFree = false);
277 /** Returns map in index */
278 Map* GetMap(unsigned int index) const;
279 /** Returns a map from area name, loads it if needed
280 * use it for the biggest safety, change = true will change the current map */
281 Map* GetMap(const char *areaname, bool change);
282 /** Returns slot of the map if found */
283 int FindMap(const char *ResRef);
284 int AddMap(Map* map);
285 /** Determine if area is master area*/
286 bool MasterArea(const char *area);
287 /** Dynamically adding an area to master areas*/
288 void SetMasterArea(const char *area);
289 /** Returns slot of the map, if it was already loaded,
290 * don't load it again, set changepf == true,
291 * if you want to change the pathfinder too. */
292 int LoadMap(const char* ResRef, bool loadscreen);
293 int DelMap(unsigned int index, int forced = 0);
294 int AddNPC(Actor* npc);
295 Actor* GetNPC(unsigned int Index);
296 void SwapPCs(unsigned int Index1, unsigned int Index2);
297 bool IsDay();
298 void InAttack(ieDword globalID);
299 void OutAttack(ieDword globalID);
300 int AttackersOf(ieDword globalID, Map *area) const;
302 //journal entries
303 /** Deletes one or all journal entries if strref is -1 */
304 void DeleteJournalEntry(ieStrRef strref);
305 /** Delete entries of the same group */
306 void DeleteJournalGroup(int Group);
307 /** Adds a journal entry from dialog data.
308 * Time and chapter are calculated on the fly
309 * Returns false if the entry already exists */
310 bool AddJournalEntry(ieStrRef strref, int section, int group);
311 /** Adds a journal entry while loading the .gam structure */
312 void AddJournalEntry(GAMJournalEntry* entry);
313 unsigned int GetJournalCount() const;
314 GAMJournalEntry* FindJournalEntry(ieStrRef strref);
315 GAMJournalEntry* GetJournalEntry(unsigned int Index);
317 //saved locations
318 unsigned int GetSavedLocationCount() const;
319 void ClearSavedLocations();
320 GAMLocationEntry* GetSavedLocationEntry(unsigned int Index);
322 //plane locations
323 unsigned int GetPlaneLocationCount() const;
324 void ClearPlaneLocations();
325 GAMLocationEntry* GetPlaneLocationEntry(unsigned int Index);
327 char *GetFamiliar(unsigned int Index);
329 bool IsBeastKnown(unsigned int Index) const {
330 if (!beasts) {
331 return false;
333 if (Index>=BESTIARY_SIZE) {
334 return false;
336 return beasts[Index] != 0;
338 void SetBeastKnown(unsigned int Index) {
339 if (!beasts) {
340 return;
342 if (Index>=BESTIARY_SIZE) {
343 return;
345 beasts[Index] = 1;
347 ieWord GetFormation() const {
348 if (WhichFormation>4) {
349 return 0;
351 return Formations[WhichFormation];
353 size_t GetAttackerCount() const {
354 return Attackers.size();
357 /** converts challenge rating to xp */
358 int GetXPFromCR(int cr);
359 /** shares XP among all party members */
360 void ShareXP(int XP, int flags);
361 /** returns true if we should start the party overflow window */
362 bool PartyOverflow() const;
363 /** returns true if actor is an attacker or being attacked */
364 bool PCInCombat(Actor *actor) const;
365 /** returns true if any pc is attacker or being attacked */
366 bool AnyPCInCombat() const;
367 /** returns true if the party death condition is true */
368 bool EveryoneDead() const;
369 /** returns true if no one moves */
370 bool EveryoneStopped() const;
371 bool EveryoneNearPoint(Map *map, const Point &p, int flags) const;
372 /** returns true if a PC just died */
373 int PartyMemberDied() const;
374 /** a party member just died now */
375 void PartyMemberDied(Actor *);
376 /** Increments chapter variable and refreshes kill stats */
377 void IncrementChapter();
378 /** Sets party reputation */
379 void SetReputation(ieDword r);
380 /** Sets the gamescreen control status (pane states, dialog textarea size) */
381 void SetControlStatus(int value, int operation);
382 /** Sets party size (1-32000) */
383 void SetPartySize(int value);
384 /** Sets a guiscript function to happen after x AI cycles have elapsed */
385 void SetTimedEvent(EventHandler func, int count);
386 /** Sets protagonist mode to 0-none,1-protagonist,2-team */
387 void SetProtagonistMode(int value);
388 void StartRainOrSnow(bool conditional, int weather);
389 size_t GetLoadedMapCount() const { return Maps.size(); }
390 /** Adds or removes gold */
391 void AddGold(ieDword add);
392 /** Adds ticks to game time */
393 void AdvanceTime(ieDword add);
394 /** Runs the script engine on the global script and the area scripts
395 areas run scripts on door, infopoint, container, actors too */
396 void UpdateScripts();
397 /** runs area functionality, sets partyrested trigger */
398 void RestParty(int checks, int dream, int hp);
399 /** timestop effect initiated by actor */
400 void TimeStop(Actor *actor, ieDword end);
401 /** gets the colour which should be applied over the game area,
402 may return NULL */
403 const Color *GetGlobalTint() const;
404 /** returns true if party has infravision */
405 bool PartyHasInfravision() const { return hasInfra; }
406 /** draw weather */
407 void DrawWeather(const Region &screen, bool update);
408 /** updates current area music */
409 void ChangeSong(bool always = true, bool force = true);
410 /** sets expansion mode */
411 void SetExpansion(ieDword value);
412 /** Dumps information about the object */
413 void DebugDump();
414 /** Finds an actor by global ID */
415 Actor *GetActorByGlobalID(ieDword objectID);
416 /** updates the infravision info */
417 void Infravision();
418 private:
419 bool DetermineStartPosType(const TableMgr *strta);
420 ieResRef *GetDream(Map *area);
421 void PlayerDream();
424 #endif // ! GAME_H