melee / ranged effects
[gemrb.git] / gemrb / core / Map.h
blobd6df6c787df591486d64ac41e416776f2026c0d7
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 class Map;
23 #ifndef MAP_H
24 #define MAP_H
26 #include "exports.h"
27 #include "globals.h"
29 #include "Bitmap.h"
30 #include "Image.h"
31 #include "IniSpawn.h"
32 #include "SpriteCover.h"
33 #include "Scriptable/ActorBlock.h"
35 #include <queue>
37 class Actor;
38 class Ambient;
39 class Animation;
40 class AnimationFactory;
41 class GameControl;
42 class Particles;
43 struct PathNode;
44 class Projectile;
45 class ScriptedAnimation;
46 class TileMap;
47 class Wall_Polygon;
49 //distance of actors from spawn point
50 #define SPAWN_RANGE 400
52 //area flags
53 #define AF_SAVE 1
54 #define AF_TUTORIAL 2
55 #define AF_DEADMAGIC 4
56 #define AF_DREAM 8
58 //area types
59 #define AT_OUTDOOR 1
60 #define AT_DAYNIGHT 2
61 #define AT_WEATHER 4
62 #define AT_CITY 8
63 #define AT_FOREST 0x10
64 #define AT_DUNGEON 0x20
65 #define AT_EXTENDED_NIGHT 0x40
66 #define AT_CAN_REST 0x80
68 //area animation flags
69 #define A_ANI_ACTIVE 1 //if not set, animation is invisible
70 #define A_ANI_BLEND 2 //blend
71 #define A_ANI_NO_SHADOW 4 //lightmap doesn't affect it
72 #define A_ANI_PLAYONCE 8 //stop after endframe
73 #define A_ANI_SYNC 16 //synchronised draw (skip frames if needed)
74 #define A_ANI_32 32
75 #define A_ANI_NO_WALL 64 //draw after walls (walls don't cover it)
76 #define A_ANI_NOT_IN_FOG 0x80 //not visible in fog of war
77 #define A_ANI_BACKGROUND 0x100 //draw before actors (actors cover it)
78 #define A_ANI_ALLCYCLES 0x200 //draw all cycles, not just the cycle specified
79 #define A_ANI_PALETTE 0x400 //has own palette set
80 #define A_ANI_MIRROR 0x800 //mirrored
81 #define A_ANI_COMBAT 0x1000 //draw in combat too
83 //creature area flags
84 #define AF_CRE_NOT_LOADED 1
85 #define AF_NAME_OVERRIDE 8
87 //getline flags
88 #define GL_NORMAL 0
89 #define GL_PASS 1
90 #define GL_REBOUND 2
92 //sparkle types
93 #define SPARKLE_PUFF 1
94 #define SPARKLE_EXPLOSION 2 //not in the original engine
95 #define SPARKLE_SHOWER 3
97 //in areas 10 is a magic number for resref counts
98 #define MAX_RESCOUNT 10
100 struct SongHeaderType {
101 ieDword SongList[MAX_RESCOUNT];
104 struct RestHeaderType {
105 ieDword Strref[MAX_RESCOUNT];
106 ieResRef CreResRef[MAX_RESCOUNT];
107 ieWord Difficulty;
108 ieWord CreatureNum;
109 ieWord Maximum;
110 ieWord Enabled;
111 ieWord DayChance;
112 ieWord NightChance;
113 ieDword sduration;
114 ieWord rwdist, owdist;
117 struct Entrance {
118 ieVariable Name;
119 Point Pos;
120 ieWord Face;
123 class MapNote {
124 public:
125 ieStrRef strref;
126 Point Pos;
127 ieWord color;
128 char *text;
129 MapNote() { text=NULL; }
130 ~MapNote() { if(text) free(text); }
133 class Spawn {
134 public:
135 ieVariable Name;
136 Point Pos;
137 ieResRef *Creatures;
138 unsigned int Count;
139 ieWord Difficulty;
140 ieWord Frequency;
141 ieWord Method;
142 ieDword sduration; //spawn duration
143 ieWord rwdist, owdist; //maximum walk distances
144 ieWord Maximum;
145 ieWord Enabled;
146 ieDword appearance;
147 ieWord DayChance;
148 ieWord NightChance;
149 Spawn() { Creatures=NULL; }
150 ~Spawn() { if(Creatures) free(Creatures); }
151 unsigned int GetCreatureCount() { return Count; }
154 class TerrainSounds {
155 public:
156 ieResRef Group;
157 ieResRef Sounds[16];
160 class SpawnGroup {
161 public:
162 ieResRef *ResRefs;
163 unsigned int Count;
164 unsigned int Level;
166 SpawnGroup(unsigned int size) {
167 ResRefs = (ieResRef *) calloc(size, sizeof(ieResRef) );
168 Count = size;
170 ~SpawnGroup() {
171 if (ResRefs) {
172 free(ResRefs);
177 class GEM_EXPORT AreaAnimation {
178 public:
179 Animation **animation;
180 int animcount;
181 //dwords, or stuff combining to a dword
182 Point Pos;
183 ieDword appearance;
184 ieDword Flags;
185 //these are on one dword
186 ieWord sequence;
187 ieWord frame;
188 //these are on one dword
189 ieWord transparency;
190 ieWordSigned height;
191 //these are on one dword
192 ieWord unknown3c;
193 ieByte skipcycle;
194 ieByte startchance;
195 ieDword unknown48;
196 //string values, not in any particular order
197 ieVariable Name;
198 ieResRef BAM; //not only for saving back (StaticSequence depends on this)
199 ieResRef PaletteRef;
200 Palette* palette;
201 SpriteCover** covers;
202 AreaAnimation();
203 ~AreaAnimation();
204 void InitAnimation();
205 void SetPalette(ieResRef PaletteRef);
206 void BlendAnimation();
207 bool Schedule(ieDword gametime);
208 void Draw(const Region &screen, Map *area);
209 private:
210 Animation *GetAnimationPiece(AnimationFactory *af, int animCycle);
213 enum AnimationObjectType {AOT_AREA, AOT_SCRIPTED, AOT_ACTOR, AOT_SPARK, AOT_PROJECTILE};
215 //i believe we need only the active actors/visible inactive actors queues
216 #define QUEUE_COUNT 2
218 //priorities when handling actors, we really ignore the third one
219 #define PR_SCRIPT 0
220 #define PR_DISPLAY 1
221 #define PR_IGNORE 2
223 typedef std::list<AreaAnimation*>::iterator aniIterator;
224 typedef std::list<ScriptedAnimation*>::iterator scaIterator;
225 typedef std::list<Projectile*>::iterator proIterator;
226 typedef std::list<Particles*>::iterator spaIterator;
228 class GEM_EXPORT Map : public Scriptable {
229 public:
230 TileMap* TMap;
231 Image* LightMap;
232 Bitmap* SearchMap;
233 Bitmap* HeightMap;
234 Sprite2D* SmallMap;
235 IniSpawn *INISpawn;
236 ieDword AreaFlags;
237 ieWord AreaType;
238 ieWord Rain, Snow, Fog, Lightning;
239 ieByte* ExploredBitmap;
240 ieByte* VisibleBitmap;
241 int version;
242 ieResRef WEDResRef;
243 bool MasterArea;
244 //this is set by the importer (not stored in the file)
245 bool DayNight;
246 //movies for day/night (only in ToB)
247 ieResRef Dream[2];
248 private:
249 ieStrRef trackString;
250 int trackFlag;
251 ieWord trackDiff;
252 unsigned short* MapSet;
253 unsigned short* SrchMap; //internal searchmap
254 std::queue< unsigned int> InternalStack;
255 unsigned int Width, Height;
256 std::list< AreaAnimation*> animations;
257 std::vector< Actor*> actors;
258 Wall_Polygon **Walls;
259 unsigned int WallCount;
260 std::list< ScriptedAnimation*> vvcCells;
261 std::list< Projectile*> projectiles;
262 std::list< Particles*> particles;
263 std::vector< Entrance*> entrances;
264 std::vector< Ambient*> ambients;
265 std::vector< MapNote*> mapnotes;
266 std::vector< Spawn*> spawns;
267 Actor** queue[QUEUE_COUNT];
268 int Qcount[QUEUE_COUNT];
269 unsigned int lastActorCount[QUEUE_COUNT];
270 public:
271 Map(void);
272 ~Map(void);
273 static void ReleaseMemory();
275 /** prints useful information on console */
276 void DebugDump(bool show_actors=0) const;
277 TileMap *GetTileMap() { return TMap; }
278 /* gets the signal of daylight changes */
279 bool ChangeMap(bool day_or_night);
280 void SeeSpellCast(Scriptable *caster, ieDword spell);
281 /* low level function to perform the daylight changes */
282 void ChangeTileMap(Image* lm, Sprite2D* sm);
283 /* sets all the auxiliary maps and the tileset */
284 void AddTileMap(TileMap* tm, Image* lm, Bitmap* sr, Sprite2D* sm, Bitmap* hm);
285 void UpdateScripts();
286 void ResolveTerrainSound(ieResRef &sound, Point &pos);
287 bool DoStepForActor(Actor *actor, int speed, ieDword time);
288 void UpdateEffects();
289 /* removes empty heaps and returns total itemcount */
290 int ConsolidateContainers();
291 /* transfers all piles (loose items) to another map */
292 void CopyGroundPiles(Map *othermap, const Point &Pos);
293 /* transfers all ever visible piles (loose items) to the specified position */
294 void MoveVisibleGroundPiles(const Point &Pos);
295 /* draws stationary vvc graphics */
296 //void DrawVideocells(Region screen);
297 void DrawHighlightables(Region screen);
298 void DrawMap(Region screen);
299 void PlayAreaSong(int SongType, bool restart = true, bool hard = false);
300 void AddAnimation(AreaAnimation* anim);
301 aniIterator GetFirstAnimation() { return animations.begin(); }
302 AreaAnimation* GetNextAnimation(aniIterator &iter)
304 if (iter == animations.end()) {
305 return NULL;
307 return *iter++;
309 AreaAnimation* GetAnimation(const char* Name);
310 size_t GetAnimationCount() const { return animations.size(); }
312 unsigned int GetWallCount() { return WallCount; }
313 Wall_Polygon *GetWallGroup(int i) { return Walls[i]; }
314 void SetWallGroups(unsigned int count, Wall_Polygon **walls)
316 WallCount = count;
317 Walls = walls;
319 SpriteCover* BuildSpriteCover(int x, int y, int xpos, int ypos,
320 unsigned int width, unsigned int height, int flag);
321 void ActivateWallgroups(unsigned int baseindex, unsigned int count, int flg);
322 void Shout(Actor* actor, int shoutID, unsigned int radius);
323 void ActorSpottedByPlayer(Actor *actor);
324 void AddActor(Actor* actor);
325 //returns true if an enemy is near P (used in resting/saving)
326 bool AnyEnemyNearPoint(const Point &p);
327 bool GetBlocked(unsigned int x, unsigned int y, unsigned int size);
328 unsigned int GetBlocked(unsigned int x, unsigned int y);
329 unsigned int GetBlocked(const Point &p);
330 Door *GetDoorByGlobalID(ieDword objectID);
331 Container *GetContainerByGlobalID(ieDword objectID);
332 InfoPoint *GetInfoPointByGlobalID(ieDword objectID);
333 Actor* GetActorByGlobalID(ieDword objectID);
334 Actor* GetActor(const Point &p, int flags);
335 Actor* GetActorInRadius(const Point &p, int flags, unsigned int radius);
336 Actor **GetAllActorsInRadius(const Point &p, int flags, unsigned int radius);
337 Actor* GetActor(const char* Name, int flags);
338 Actor* GetActor(int i, bool any);
339 Actor* GetActorByDialog(const char* resref);
340 Actor* GetActorByResource(const char* resref);
341 Actor* GetActorByScriptName(const char* name);
342 bool HasActor(Actor *actor);
343 void RemoveActor(Actor* actor);
344 //returns actors in rect (onlyparty could be more sophisticated)
345 int GetActorInRect(Actor**& actors, Region& rgn, bool onlyparty);
346 int GetActorCount(bool any) const;
347 //fix actors position if required
348 void JumpActors(bool jump);
349 //selects all selectable actors in the area
350 void SelectActors();
351 //if items == true, remove noncritical items from ground piles too
352 void PurgeArea(bool items);
354 SongHeaderType SongHeader;
355 RestHeaderType RestHeader;
357 //count of all projectiles that are saved
358 size_t GetProjectileCount(proIterator &iter);
359 //get the next projectile
360 Projectile *GetNextProjectile(proIterator &iter);
361 //count of unexploded projectiles that are saved
362 ieDword GetTrapCount(proIterator &iter);
363 //get the next saved projectile
364 Projectile* GetNextTrap(proIterator &iter);
365 //add a projectile to the area
366 void AddProjectile(Projectile* pro, const Point &source, ieWord actorID, bool fake);
367 void AddProjectile(Projectile* pro, const Point &source, const Point &dest);
369 //returns the duration of a VVC cell set in the area (point may be set to empty)
370 ieDword HasVVCCell(const ieResRef resource, const Point &p);
371 void AddVVCell(ScriptedAnimation* vvc);
372 bool CanFree();
373 int GetCursor( const Point &p);
374 //adds a sparkle puff of colour to a point in the area
375 //FragAnimID is an optional avatar animation ID (see avatars.2da) for
376 //fragment animation
377 void Sparkle(ieDword duration, ieDword color, ieDword type, const Point &pos, unsigned int FragAnimID = 0);
378 //removes or fades the sparkle puff at a point
379 void FadeSparkle(const Point &pos, bool forced);
381 //entrances
382 void AddEntrance(char* Name, int XPos, int YPos, short Face);
383 Entrance* GetEntrance(const char* Name);
384 Entrance* GetEntrance(int i) { return entrances[i]; }
385 int GetEntranceCount() const { return (int) entrances.size(); }
387 //containers
388 /* this function returns/creates a pile container at position */
389 Container* AddContainer(const char* Name, unsigned short Type,
390 Gem_Polygon* outline);
391 Container *GetPile(Point position);
392 void AddItemToLocation(const Point &position, CREItem *item);
394 int GetWidth() const { return Width; }
395 int GetHeight() const { return Height; }
396 int GetExploredMapSize() const;
397 /*fills the explored bitmap with setreset */
398 void Explore(int setreset);
399 /*fills the visible bitmap with setreset */
400 void SetMapVisibility(int setreset = 0);
401 /* set one fog tile as visible. x, y are tile coordinates */
402 void ExploreTile(const Point &Tile);
403 /* explore map from given point in map coordinates */
404 void ExploreMapChunk(const Point &Pos, int range, int los);
405 /* block or unblock searchmap with value */
406 void BlockSearchMap(const Point &Pos, unsigned int size, unsigned int value);
407 void ClearSearchMapFor(Movable *actor);
408 /* update VisibleBitmap by resolving vision of all explore actors */
409 void UpdateFog();
410 //PathFinder
411 /* Finds the nearest passable point */
412 void AdjustPosition(Point &goal, unsigned int radius=0);
413 /* Finds the path which leads the farthest from d */
414 PathNode* RunAway(const Point &s, const Point &d, unsigned int size, unsigned int PathLen, int flags);
415 /* Returns true if there is no path to d */
416 bool TargetUnreachable(const Point &s, const Point &d, unsigned int size);
417 /* returns true if there is enemy visible */
418 bool AnyPCSeesEnemy();
419 /* Finds straight path from s, length l and orientation o, f=1 passes wall, f=2 rebounds from wall*/
420 PathNode* GetLine(const Point &start, const Point &dest, int flags);
421 PathNode* GetLine(const Point &start, int Steps, int Orientation, int flags);
422 PathNode* GetLine(const Point &start, const Point &dest, int speed, int Orientation, int flags);
423 /* Finds the path which leads to near d */
424 PathNode* FindPathNear(const Point &s, const Point &d, unsigned int size, unsigned int MinDistance = 0, bool sight = true);
425 /* Finds the path which leads to d */
426 PathNode* FindPath(const Point &s, const Point &d, unsigned int size, int MinDistance = 0);
427 /* returns false if point isn't visible on visibility/explored map */
428 bool IsVisible(const Point &s, int explored);
429 /* returns false if point d cannot be seen from point d due to searchmap */
430 bool IsVisible(const Point &s, const Point &d);
431 /* returns edge direction of map boundary, only worldmap regions */
432 int WhichEdge(const Point &s);
434 //ambients
435 void AddAmbient(Ambient *ambient) { ambients.push_back(ambient); }
436 void SetupAmbients();
437 Ambient *GetAmbient(int i) { return ambients[i]; }
438 unsigned int GetAmbientCount() { return (unsigned int) ambients.size(); }
440 //mapnotes
441 void AddMapNote(const Point &point, int color, char *text, ieStrRef strref);
442 void RemoveMapNote(const Point &point);
443 MapNote *GetMapNote(int i) { return mapnotes[i]; }
444 MapNote *GetMapNote(const Point &point);
445 unsigned int GetMapNoteCount() { return (unsigned int) mapnotes.size(); }
446 //restheader
447 /* May spawn creature(s), returns true in case of an interrupted rest */
448 bool Rest(const Point &pos, int hours, int day);
449 /* Spawns creature(s) in radius of position */
450 void SpawnCreature(const Point &pos, const char *CreName, int radius = 0);
452 //spawns
453 void LoadIniSpawn();
454 Spawn *AddSpawn(char* Name, int XPos, int YPos, ieResRef *creatures, unsigned int count);
455 Spawn *GetSpawn(int i) { return spawns[i]; }
456 //returns spawn by name
457 Spawn *GetSpawn(const char *Name);
458 //returns spawn inside circle, checks for schedule and other
459 //conditions as well
460 Spawn *GetSpawnRadius(const Point &point, unsigned int radius);
461 unsigned int GetSpawnCount() { return (unsigned int) spawns.size(); }
462 void TriggerSpawn(Spawn *spawn);
463 //move some or all players to a new area
464 void MoveToNewArea(const char *area, const char *entrance, unsigned int direction, int EveryOne, Actor *actor);
465 bool HasWeather();
466 int GetWeather();
467 void ClearTrap(Actor *actor, ieDword InTrap);
468 void SetTrackString(ieStrRef strref, int flg, int difficulty);
469 //returns true if tracking failed
470 bool DisplayTrackString(Actor *actor);
471 unsigned int GetLightLevel(const Point &Pos);
472 private:
473 AreaAnimation *GetNextAreaAnimation(aniIterator &iter, ieDword gametime);
474 Particles *GetNextSpark(spaIterator &iter);
475 ScriptedAnimation *GetNextScriptedAnimation(scaIterator &iter);
476 Actor *GetNextActor(int &q, int &index);
477 void DrawSearchMap(const Region &screen);
478 void GenerateQueues();
479 void SortQueues();
480 //Actor* GetRoot(int priority, int &index);
481 void DeleteActor(int i);
482 void Leveldown(unsigned int px, unsigned int py, unsigned int& level,
483 Point &p, unsigned int& diff);
484 void SetupNode(unsigned int x, unsigned int y, unsigned int size, unsigned int Cost);
485 //actor uses travel region
486 void UseExit(Actor *pc, InfoPoint *ip);
487 //separated position adjustment, so their order could be randomised */
488 bool AdjustPositionX(Point &goal, unsigned int radius);
489 bool AdjustPositionY(Point &goal, unsigned int radius);
490 void DrawPortal(InfoPoint *ip, int enable);
493 #endif