Move EventMgr to GUI.
[gemrb.git] / gemrb / core / Game.h
blob9ded83830191ce23dbd9fe185a7ba813216a6586
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 "Particles.h"
39 #include "Variables.h"
40 #include "Scriptable/Actor.h"
42 #include <vector>
44 //the length of a round in game ticks?
45 //default (ROUND_SIZE) is 6 seconds: 15 (AI_UPDATE_TIME)*6 (ROUND_SECODS)=90
46 #define ROUND_SIZE 90
47 #define ROUND_SECONDS 6
48 #define ROUND_PER_TURN 10
50 //the size of the bestiary register
51 #define BESTIARY_SIZE 260
53 //ShareXP flags
54 #define SX_DIVIDE 1 //divide XP among team members
55 #define SX_CR 2 //use challenge rating resolution
57 //joinparty flags
58 #define JP_JOIN 1 //refresh join time
59 #define JP_INITPOS 2 //init startpos
61 //protagonist mode
62 #define PM_NO 0 //no death checks
63 #define PM_YES 1 //if protagonist dies, game over
64 #define PM_TEAM 2 //if team dies, game over
66 // Flags bits for SelectActor()
67 // !!! Keep these synchronized with GUIDefines.py !!!
68 #define SELECT_NORMAL 0x00
69 #define SELECT_REPLACE 0x01 // when selecting actor, deselect all others
70 #define SELECT_QUIET 0x02 // do not run handler when changing selection
72 // Flags bits for EveryoneNearPoint()
73 #define ENP_CANMOVE 1 // also check if the PC can move
74 #define ENP_ONLYSELECT 2 // check only selected PC
76 // GUI Control Status flags (saved in game)
77 #define CS_PARTY_AI 1 //enable party AI
78 #define CS_MEDIUM 2 //medium dialog
79 #define CS_LARGE 6 //large dialog, both bits set
80 #define CS_DIALOGSIZEMASK 6
81 #define CS_DIALOG 8 //dialog is running
82 #define CS_HIDEGUI 16 //hide all gui
83 #define CS_ACTION 32 //hide action pane
84 #define CS_PORTRAIT 64 //hide portrait pane
85 #define CS_MAPNOTES 128 //hide mapnotes
87 //Weather bits
88 #define WB_NORMAL 0
89 #define WB_RAIN 1
90 #define WB_SNOW 2
91 #define WB_FOG 3
92 #define WB_MASK 7
93 #define WB_LIGHTNING 8
94 #define WB_HASWEATHER 0x40
95 #define WB_START 0x80
97 //Rest flags
98 #define REST_NOAREA 1 //no area check
99 #define REST_NOSCATTER 2 //no scatter check
100 #define REST_NOMOVE 4 //no movement check
101 #define REST_NOCRITTER 8 //no hostiles check
103 * @struct PCStruct
104 * Information about party member.
107 struct PCStruct {
108 ieWord Selected;
109 ieWord PartyOrder;
110 ieDword OffsetToCRE;
111 ieDword CRESize;
112 ieResRef CREResRef;
113 ieDword Orientation;
114 ieResRef Area;
115 ieWord XPos;
116 ieWord YPos;
117 ieWord ViewXPos;
118 ieWord ViewYPos;
119 ieWord ModalState;
120 ieWord Happiness;
121 unsigned char Unknown2c[96];
122 ieWord QuickWeaponSlot[MAX_QUICKWEAPONSLOT];
123 ieWord QuickWeaponHeader[MAX_QUICKWEAPONSLOT];
124 ieResRef QuickSpellResRef[MAX_QSLOTS];
125 ieWord QuickItemSlot[MAX_QUICKITEMSLOT];
126 ieWord QuickItemHeader[MAX_QUICKITEMSLOT];
127 char Name[32];
128 ieDword TalkCount;
129 ieByte QSlots[MAX_QSLOTS];
130 ieByte QuickSpellClass[MAX_QSLOTS];
133 #define IE_GAM_JOURNAL 0
134 #define IE_GAM_QUEST_UNSOLVED 1
135 #define IE_GAM_QUEST_DONE 2
136 #define IE_GAM_JOURNAL_USER 3
139 * @struct GAMJournalEntry
140 * Single entry in a journal
143 struct GAMJournalEntry {
144 ieStrRef Text;
145 ieDword GameTime; // in game time seconds
146 ieByte Chapter;
147 ieByte unknown09;
148 ieByte Section;
149 ieByte Group; // this is a GemRB extension
152 // Saved location of party member.
153 struct GAMLocationEntry {
154 ieResRef AreaResRef;
155 Point Pos;
158 #define MAX_CRLEVEL 32
160 typedef int CRRow[MAX_CRLEVEL];
163 * @class Game
164 * Object representing current game state, mostly party.
167 class GEM_EXPORT Game : public Scriptable {
168 public:
169 Game(void);
170 ~Game(void);
171 private:
172 std::vector< Actor*> PCs;
173 std::vector< Actor*> NPCs;
174 std::vector< Map*> Maps;
175 std::vector< GAMJournalEntry*> Journals;
176 std::vector< GAMLocationEntry*> savedpositions;
177 std::vector< GAMLocationEntry*> planepositions;
178 std::vector< char*> mastarea;
179 std::vector< ieDword> Attackers;
180 CRRow *crtable;
181 ieResRef restmovies[8];
182 ieResRef daymovies[8];
183 ieResRef nightmovies[8];
184 int MapIndex;
185 public:
186 std::vector< Actor*> selected;
187 int version;
188 int Expansion;
189 Variables* kaputz;
190 ieByte* beasts;
191 ieByte* mazedata; //only in PST
192 ieResRef Familiars[9];
193 ieDword CombatCounter;
194 ieDword StateOverrideFlag, StateOverrideTime;
195 ieDword BanterBlockFlag, BanterBlockTime;
197 /** Index of PC selected in non-walking environment (shops, inventory...) */
198 int SelectedSingle;
199 /** 0 if the protagonist's death doesn't cause game over */
200 /** 1 if the protagonist's death causes game over */
201 /** 2 if no check is needed (pst) */
202 int protagonist;
203 /** if party size exceeds this amount, a callback will be called */
204 size_t partysize;
205 ieDword Ticks;
206 ieDword interval; // 1000/AI_UPDATE (a tenth of a round in ms)
207 ieDword GameTime;
208 ieDword LastScriptUpdate; // GameTime at which UpdateScripts last ran
209 ieDword RealTime;
210 ieWord WhichFormation;
211 ieWord Formations[5];
212 ieDword PartyGold;
213 ieWord NpcInParty;
214 ieWord WeatherBits;
215 ieDword Unknown48;
216 ieDword Reputation;
217 ieDword ControlStatus;// used in bg2, iwd (where you can switch panes off)
218 ieResRef AnotherArea;
219 ieResRef CurrentArea;
220 ieResRef LoadMos;
221 Actor *timestop_owner;
222 ieDword timestop_end;
223 Particles *weather;
224 int event_timer;
225 EventHandler event_handler; //like in Control
226 private:
227 /** reads the challenge rating table */
228 void LoadCRTable();
229 public:
230 /** Returns the PC's slot count for partyID */
231 int FindPlayer(unsigned int partyID);
232 /** Returns actor by slot */
233 Actor* GetPC(unsigned int slot, bool onlyalive);
234 /** Finds an actor in party by party ID, returns Actor, if not there, returns NULL*/
235 Actor* FindPC(unsigned int partyID);
236 Actor* FindNPC(unsigned int partyID);
237 /** Finds an actor in party, returns slot, if not there, returns -1*/
238 int InParty(Actor* pc) const;
239 /** Finds an actor in store, returns slot, if not there, returns -1*/
240 int InStore(Actor* pc) const;
241 /** Finds an actor in party by scripting name*/
242 Actor* FindPC(const char *deathvar);
243 /** Finds an actor in store by scripting name*/
244 Actor* FindNPC(const char *deathvar);
245 /** Sets the area and position of the actor to the starting position */
246 void InitActorPos(Actor *actor);
247 /** Joins party */
248 int JoinParty(Actor* pc, int join=JP_JOIN);
249 /** Return current party size */
250 int GetPartySize(bool onlyalive) const;
251 /** Returns the npcs count */
252 int GetNPCCount() const { return (int)NPCs.size(); }
253 /** Sends the hotkey trigger to all selected pcs */
254 void SetHotKey(unsigned long Key);
255 /** Select PC for non-walking environment (shops, inventory, ...) */
256 bool SelectPCSingle(int index);
257 /** Get index of selected PC for non-walking env (shops, inventory, ...) */
258 int GetSelectedPCSingle() const;
259 /** (De)selects actor. */
260 bool SelectActor( Actor* actor, bool select, unsigned flags );
262 /** Return current party level count for xp calculations */
263 int GetPartyLevel(bool onlyalive) const;
264 /** Reassigns inparty numbers, call it after party creation */
265 void ConsolidateParty();
266 /** Removes actor from party (if in there) */
267 int LeaveParty(Actor* pc);
268 /** Returns slot*/
269 int DelPC(unsigned int slot, bool autoFree = false);
270 int DelNPC(unsigned int slot, bool autoFree = false);
271 /** Returns map in index */
272 Map* GetMap(unsigned int index) const;
273 /** Returns a map from area name, loads it if needed
274 * use it for the biggest safety, change = true will change the current map */
275 Map* GetMap(const char *areaname, bool change);
276 /** Returns slot of the map if found */
277 int FindMap(const char *ResRef);
278 int AddMap(Map* map);
279 /** Determine if area is master area*/
280 bool MasterArea(const char *area);
281 /** Dynamically adding an area to master areas*/
282 void SetMasterArea(const char *area);
283 /** Returns slot of the map, if it was already loaded,
284 * don't load it again, set changepf == true,
285 * if you want to change the pathfinder too. */
286 int LoadMap(const char* ResRef);
287 int DelMap(unsigned int index, int forced = 0);
288 int AddNPC(Actor* npc);
289 Actor* GetNPC(unsigned int Index);
290 void SwapPCs(unsigned int Index1, unsigned int Index2);
291 bool IsDay();
292 void InAttack(ieDword globalID);
293 void OutAttack(ieDword globalID);
294 int AttackersOf(ieDword globalID, Map *area) const;
296 //journal entries
297 void DeleteJournalEntry(ieStrRef strref);
298 void DeleteJournalGroup(int Group);
299 /** Adds a journal entry from dialog data.
300 * Time and chapter are calculated on the fly
301 * Returns false if the entry already exists */
302 bool AddJournalEntry(ieStrRef strref, int section, int group);
303 /** Adds a journal entry while loading the .gam structure */
304 void AddJournalEntry(GAMJournalEntry* entry);
305 unsigned int GetJournalCount() const;
306 GAMJournalEntry* FindJournalEntry(ieStrRef strref);
307 GAMJournalEntry* GetJournalEntry(unsigned int Index);
309 unsigned int GetSavedLocationCount() const;
310 void ClearSavedLocations();
311 GAMLocationEntry* GetSavedLocationEntry(unsigned int Index);
313 unsigned int GetPlaneLocationCount() const;
314 void ClearPlaneLocations();
315 GAMLocationEntry* GetPlaneLocationEntry(unsigned int Index);
317 char *GetFamiliar(unsigned int Index);
319 bool IsBeastKnown(unsigned int Index) const {
320 if (!beasts) {
321 return false;
323 if (Index>=BESTIARY_SIZE) {
324 return false;
326 return beasts[Index] != 0;
328 void SetBeastKnown(unsigned int Index) {
329 if (!beasts) {
330 return;
332 if (Index>=BESTIARY_SIZE) {
333 return;
335 beasts[Index] = 1;
337 ieWord GetFormation() const {
338 if (WhichFormation>4) {
339 return 0;
341 return Formations[WhichFormation];
343 size_t GetAttackerCount() const {
344 return Attackers.size();
347 /** converts challenge rating to xp */
348 int GetXPFromCR(int cr);
349 /** shares XP among all party members */
350 void ShareXP(int XP, int flags);
351 /** returns true if we should start the party overflow window */
352 bool PartyOverflow() const;
353 /** returns true if actor is an attacker or being attacked */
354 bool PCInCombat(Actor *actor) const;
355 /** returns true if any pc is attacker or being attacked */
356 bool AnyPCInCombat() const;
357 /** returns true if the party death condition is true */
358 bool EveryoneDead() const;
359 /** returns true if no one moves */
360 bool EveryoneStopped() const;
361 bool EveryoneNearPoint(Map *map, const Point &p, int flags) const;
362 /** returns true if a PC just died */
363 int PartyMemberDied() const;
364 /** a party member just died now */
365 void PartyMemberDied(Actor *);
366 /** Increments chapter variable and refreshes kill stats */
367 void IncrementChapter();
368 /** Sets party reputation */
369 void SetReputation(ieDword r);
370 /** Sets the gamescreen control status (pane states, dialog textarea size) */
371 void SetControlStatus(int value, int operation);
372 /** Sets party size (1-32000) */
373 void SetPartySize(int value);
374 /** Sets a guiscript function to happen after x AI cycles have elapsed */
375 void SetTimedEvent(EventHandler func, int count);
376 /** Sets protagonist mode to 0-none,1-protagonist,2-team */
377 void SetProtagonistMode(int value);
378 void StartRainOrSnow(bool conditional, int weather);
379 size_t GetLoadedMapCount() const { return Maps.size(); }
380 /** Adds or removes gold */
381 void AddGold(ieDword add);
382 /** Adds ticks to game time */
383 void AdvanceTime(ieDword add);
384 /** Runs the script engine on the global script and the area scripts
385 areas run scripts on door, infopoint, container, actors too */
386 void UpdateScripts();
387 /** runs area functionality, sets partyrested trigger */
388 void RestParty(int checks, int dream, int hp);
389 /** timestop effect initiated by actor */
390 void TimeStop(Actor *actor, ieDword end);
391 /** gets the colour which should be applied over the game area,
392 may return NULL */
393 const Color *GetGlobalTint() const;
394 /** draw weather */
395 void DrawWeather(const Region &screen, bool update);
396 /** updates current area music */
397 void ChangeSong(bool force = true);
398 /** sets expansion mode */
399 void SetExpansion(int exp);
400 /** Dumps information about the object */
401 void DebugDump();
402 /** Finds an actor by global ID */
403 Actor *GetActorByGlobalID(ieWord objectID);
404 private:
405 bool DetermineStartPosType(const TableMgr *strta);
406 ieResRef *GetDream(Map *area);
407 void PlayerDream();
410 #endif // ! GAME_H