1 /* GemRB - Infinity Engine Emulator
2  * Copyright (C) 2003 The GemRB Project
3  *
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.
8 
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.
13 
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.
17  *
18  *
19  */
20 
21 #ifndef MAP_H
22 #define MAP_H
23 
24 #include "exports.h"
25 #include "globals.h"
26 
27 #include "Interface.h"
28 #include "Scriptable/Scriptable.h"
29 #include "PathFinder.h"
30 
31 #include <algorithm>
32 #include <queue>
33 #include <unordered_map>
34 
35 template <class V> class FibonacciHeap;
36 
37 namespace GemRB {
38 
39 class Actor;
40 class Ambient;
41 class Animation;
42 class AnimationFactory;
43 class Bitmap;
44 class CREItem;
45 class GameControl;
46 class Image;
47 class IniSpawn;
48 class MapReverb;
49 class Palette;
50 using PaletteHolder = Holder<Palette>;
51 class Particles;
52 struct PathNode;
53 class Projectile;
54 class ScriptedAnimation;
55 class SpriteCover;
56 class TileMap;
57 class VEFObject;
58 class Wall_Polygon;
59 
60 //distance of actors from spawn point
61 #define SPAWN_RANGE       400
62 
63 //spawn flags
64 #define SPF_NOSPAWN		0x0001	//if set don't span if WAIT is set
65 #define SPF_ONCE		0x0002	//only spawn a single time
66 #define SPF_WAIT		0x0004	//spawn temporarily disabled
67 
68 //area flags (pst uses them only for resting purposes!)
69 #define AF_NOSAVE         1
70 #define AF_TUTORIAL       2 // pst: "You cannot rest here."
71 #define AF_DEADMAGIC      4 // pst: "You cannot rest right now.", TODO iwd2: LOCKBATTLEMUSIC in areaflag.ids
72 //                        6 // pst: "You must obtain permission to rest here."
73 #define AF_DREAM          8 // unused in pst
74 /* TODO: implement these EE bits (plus PST:EE merged both worlds, bleargh)
75 #define AF_NOFATALITY    16 // Player1 death does not end the game
76 #define AF_NOREST        32 // Resting not allowed
77 #define AF_NOTRAVEL      64 // Travel not allowed
78 */
79 
80 //area types
81 #define AT_OUTDOOR        1
82 #define AT_DAYNIGHT       2
83 #define AT_WEATHER        4
84 #define AT_CITY           8
85 #define AT_FOREST         0x10
86 #define AT_DUNGEON        0x20
87 #define AT_EXTENDED_NIGHT 0x40
88 #define AT_CAN_REST_INDOORS 0x80
89 //...
90 #define AT_PST_DAYNIGHT 0x400
91 
92 //area animation flags
93 #define A_ANI_ACTIVE          1        //if not set, animation is invisible
94 #define A_ANI_BLEND           2        //blend
95 #define A_ANI_NO_SHADOW       4        //lightmap doesn't affect it
96 #define A_ANI_PLAYONCE        8        //stop after endframe
97 #define A_ANI_SYNC            16       //synchronised draw (skip frames if needed)
98 #define A_ANI_RANDOM_START    32       //starts with a random frame in the start range
99 #define A_ANI_NO_WALL         64       //draw after walls (walls don't cover it)
100 #define A_ANI_NOT_IN_FOG      0x80     //not visible in fog of war
101 #define A_ANI_BACKGROUND      0x100    //draw before actors (actors cover it)
102 #define A_ANI_ALLCYCLES       0x200    //draw all cycles, not just the cycle specified
103 #define A_ANI_PALETTE         0x400    //has own palette set
104 #define A_ANI_MIRROR          0x800    //mirrored
105 #define A_ANI_COMBAT          0x1000   //draw in combat too
106 #define A_ANI_PSTBIT14        0x2000   // PST-only: unknown and rare, see #163 for area list
107 // TODO: BGEE extended flags:
108 // 0x2000: Use WBM resref
109 // 0x4000: Draw stenciled (can be used to stencil animations using the water overlay mask of the tileset, eg. to give water surface a more natural look)
110 // 0x8000: Use PVRZ resref
111 
112 #define ANI_PRI_BACKGROUND	-9999
113 
114 //creature area flags
115 #define AF_CRE_NOT_LOADED 1
116 #define AF_NAME_OVERRIDE  8
117 //same flags in IWD2
118 #define AF_SEEN_PARTY     2
119 #define AF_INVULNERABLE   4
120 #define AF_ENABLED        8
121 
122 //direction flags (used in AreaLinks)
123 #define ADIRF_NORTH       0x01
124 #define ADIRF_EAST        0x02
125 #define ADIRF_SOUTH       0x04
126 #define ADIRF_WEST        0x08
127 #define ADIRF_CENTER      0x10 //not in the original engine
128 
129 //getline flags
130 #define GL_NORMAL         0
131 #define GL_PASS           1
132 #define GL_REBOUND        2
133 
134 //sparkle types
135 #define SPARKLE_PUFF      1
136 #define SPARKLE_EXPLOSION 2  //not in the original engine
137 #define SPARKLE_SHOWER    3
138 
139 //in areas 10 is a magic number for resref counts
140 #define MAX_RESCOUNT 10
141 
142 struct SongHeaderType {
143 	ieDword SongList[MAX_RESCOUNT];
144 	// used in bg1, set for a few copied areas in bg2 (but no files!)
145 	// everyone else uses the normal ARE ambients instead
146 	ieResRef MainDayAmbient1;
147 	ieResRef MainDayAmbient2; // except for one case, all Ambient2 are longer versions
148 	ieDword MainDayAmbientVol;
149 	ieResRef MainNightAmbient1;
150 	ieResRef MainNightAmbient2;
151 	ieDword MainNightAmbientVol;
152 	ieDword reverbID;
153 };
154 
155 struct RestHeaderType {
156 	ieDword Strref[MAX_RESCOUNT];
157 	ieResRef CreResRef[MAX_RESCOUNT];
158 	ieWord Difficulty;
159 	ieWord CreatureNum;
160 	ieWord Maximum;
161 	ieWord Enabled;
162 	ieWord DayChance;
163 	ieWord NightChance;
164 	ieDword sduration;
165 	ieWord rwdist, owdist;
166 };
167 
168 struct Entrance {
169 	ieVariable Name;
170 	Point Pos;
171 	ieWord Face;
172 };
173 
174 class MapNote {
swap(MapNote & mn)175 	void swap(MapNote& mn) {
176 		if (&mn == this) return;
177 		std::swap(strref, mn.strref);
178 		std::swap(color, mn.color);
179 		std::swap(text, mn.text);
180 		std::swap(Pos, mn.Pos);
181 	}
182 public:
183 	// FIXME: things can get messed up by exposing these (specifically strref and text)
184 	ieStrRef strref;
185 	ieWord color;
186 	String* text;
187 	Point Pos;
188 	bool readonly;
189 
190 	MapNote& operator=( MapNote mn ) {
191 		// note the pass by value
192 		mn.swap(*this);
193 		return *this;
194 	}
195 
MapNote(const MapNote & mn)196 	MapNote( const MapNote& mn )
197 	: strref(mn.strref), color(mn.color), Pos(mn.Pos), readonly(mn.readonly) {
198 		if (mn.text) {
199 			text = new String(*mn.text);
200 		} else {
201 			text = NULL;
202 		}
203 	}
204 
MapNote(String * text,ieWord c,bool readonly)205 	MapNote(String* text, ieWord c, bool readonly)
206 	: strref(-1), text(text), readonly(readonly)
207 	{
208 		color = Clamp<ieWord>(c, 0, 8);
209 		//update custom strref
210 		char* mbstring = MBCStringFromString(*text);
211 		if (mbstring) {
212 			strref = core->UpdateString(-1, mbstring);
213 			free(mbstring);
214 		} else {
215 			strref = core->UpdateString(-1, "?");
216 			Log(WARNING, "Map", "Failed to update string from map note, possibly an enconding issue.");
217 		}
218 	}
219 
MapNote(ieStrRef ref,ieWord c,bool readonly)220 	MapNote(ieStrRef ref, ieWord c, bool readonly)
221 	: strref(ref), readonly(readonly)
222 	{
223 		color = Clamp<ieWord>(c, 0, 8);
224 		text = core->GetString(ref);
225 	}
226 
~MapNote()227 	~MapNote() {
228 		delete text;
229 	}
230 
GetColor()231 	const Color& GetColor() const {
232 		static const Color colors[]={
233 		 ColorBlack,
234 		 ColorGray,
235 		 ColorViolet,
236 		 ColorGreen,
237 		 ColorOrange,
238 		 ColorRed,
239 		 ColorBlue,
240 		 ColorBlueDark,
241 		 ColorGreenDark
242 		};
243 
244 		return colors[color];
245 	}
246 };
247 
248 class Spawn {
249 public:
250 	ieVariable Name;
251 	Point Pos;
252 	ieResRef *Creatures;
253 	unsigned int Count;
254 	ieWord Difficulty;
255 	ieWord Frequency;
256 	ieWord Method;
257 	ieDword sduration;      //spawn duration
258 	ieWord rwdist, owdist;  //maximum walk distances
259 	ieWord Maximum;
260 	ieWord Enabled;
261 	ieDword appearance;
262 	ieWord DayChance;
263 	ieWord NightChance;
264 	ieDword NextSpawn;
265 	// TODO: EE added several extra fields: Spawn frequency (another?), Countdown, Spawn weights for all Creatures
266 	Spawn();
~Spawn()267 	~Spawn() { if(Creatures) free(Creatures); }
GetCreatureCount()268 	unsigned int GetCreatureCount() const { return Count; }
269 };
270 
271 class TerrainSounds {
272 public:
273 	ieResRef Group;
274 	ieResRef Sounds[16];
275 };
276 
277 class SpawnGroup {
278 public:
279 	ieResRef *ResRefs;
280 	unsigned int Count;
281 	unsigned int Level;
282 
SpawnGroup(unsigned int size)283 	SpawnGroup(unsigned int size) {
284 		ResRefs = (ieResRef *) calloc(size, sizeof(ieResRef) );
285 		Count = size;
286 		Level = 0;
287 	}
~SpawnGroup()288 	~SpawnGroup() {
289 		if (ResRefs) {
290 			free(ResRefs);
291 		}
292 	}
293 };
294 
295 class GEM_EXPORT AreaAnimation {
296 public:
297 	Animation **animation;
298 	int animcount;
299 	//dwords, or stuff combining to a dword
300 	Point Pos;
301 	ieDword appearance;
302 	ieDword Flags;
303 	// flags that must be touched by PST a bit only
304 	ieDword originalFlags;
305 	//these are on one dword
306 	ieWord sequence;
307 	ieWord frame;
308 	//these are on one dword
309 	ieWord transparency;
310 	ieWordSigned height;
311 	//these are on one dword
312 	ieWord startFrameRange;
313 	ieByte skipcycle;
314 	ieByte startchance;
315 	ieDword unknown48;
316 	//string values, not in any particular order
317 	ieVariable Name;
318 	ieResRef BAM; //not only for saving back (StaticSequence depends on this)
319 	ieResRef PaletteRef;
320 	// TODO: EE stores also the width/height for WBM and PVRZ resources (see Flags bit 13/15)
321 	PaletteHolder palette;
322 	AreaAnimation();
323 	AreaAnimation(const AreaAnimation *src);
324 	~AreaAnimation();
325 	void InitAnimation();
326 	void SetPalette(ieResRef PaletteRef);
327 	void BlendAnimation();
328 	bool Schedule(ieDword gametime) const;
329 	Region DrawingRegion() const;
330 	void Draw(const Region &screen, Color tint, BlitFlags flags) const;
331 	int GetHeight() const;
332 private:
333 	Animation *GetAnimationPiece(AnimationFactory *af, int animCycle);
334 };
335 
336 enum AnimationObjectType {AOT_AREA, AOT_SCRIPTED, AOT_ACTOR, AOT_SPARK, AOT_PROJECTILE, AOT_PILE};
337 
338 //i believe we need only the active actors/visible inactive actors queues
339 #define QUEUE_COUNT 2
340 
341 //priorities when handling actors, we really ignore the third one
342 #define PR_SCRIPT  0
343 #define PR_DISPLAY 1
344 #define PR_IGNORE  2
345 
346 enum MAP_DEBUG_FLAGS : uint32_t {
347 	DEBUG_SHOW_INFOPOINTS   	= 0x01,
348 	DEBUG_SHOW_CONTAINERS   	= 0x02,
349 	DEBUG_SHOW_DOORS			= 0x04,
350 	DEBUG_SHOW_DOORS_SECRET		= 0x08,
351 	DEBUG_SHOW_DOORS_DISABLED	= 0x10,
352 	DEBUG_SHOW_DOORS_ALL		= (DEBUG_SHOW_DOORS|DEBUG_SHOW_DOORS_SECRET|DEBUG_SHOW_DOORS_DISABLED),
353 	DEBUG_SHOW_LIGHTMAP     	= 0x20,
354 	DEBUG_SHOW_WALLS			= 0x40,
355 	DEBUG_SHOW_WALLS_ANIM_COVER	= 0x80,
356 	DEBUG_SHOW_WALLS_ALL		= (DEBUG_SHOW_WALLS|DEBUG_SHOW_WALLS_ANIM_COVER),
357 	DEBUG_SHOW_SEARCHMAP		= 0x0100,
358 	DEBUG_SHOW_FOG_UNEXPLORED	= 0x0200,
359 	DEBUG_SHOW_FOG_INVISIBLE	= 0x0400,
360 	DEBUG_SHOW_FOG_ALL			= (DEBUG_SHOW_FOG_UNEXPLORED|DEBUG_SHOW_FOG_INVISIBLE),
361 };
362 
363 typedef std::list<AreaAnimation*>::const_iterator aniIterator;
364 typedef std::list<VEFObject*>::const_iterator scaIterator;
365 typedef std::list<Projectile*>::const_iterator proIterator;
366 typedef std::list<Particles*>::const_iterator spaIterator;
367 
368 
369 class GEM_EXPORT Map : public Scriptable {
370 public:
371 	TileMap* TMap;
372 	Image* LightMap;
373 	Bitmap* HeightMap;
374 	Holder<Sprite2D> SmallMap;
375 	IniSpawn *INISpawn;
376 	ieDword AreaFlags;
377 	ieWord AreaType;
378 	ieWord Rain, Snow, Fog, Lightning;
379 	ieByte* ExploredBitmap;
380 	ieByte* VisibleBitmap;
381 	int version;
382 	ieResRef WEDResRef;
383 	bool MasterArea;
384 	//this is set by the importer (not stored in the file)
385 	bool DayNight;
386 	//movies for day/night (only in ToB)
387 	ieResRef Dream[2];
388 	Holder<Sprite2D> Background;
389 	ieDword BgDuration;
390 	ieDword LastGoCloser;
391 	MapReverb *reverb;
392 
393 private:
394 	uint32_t debugFlags = 0;
395 	ieStrRef trackString;
396 	int trackFlag;
397 	ieWord trackDiff;
398 	PathMapFlags* SrchMap; //internal searchmap
399 	unsigned short* MaterialMap;
400 	unsigned int Width, Height;
401 	std::list< AreaAnimation*> animations;
402 	std::vector< Actor*> actors;
403 	std::vector<WallPolygonGroup> wallGroups;
404 	std::list< VEFObject*> vvcCells;
405 	std::list< Projectile*> projectiles;
406 	std::list< Particles*> particles;
407 	std::vector< Entrance*> entrances;
408 	std::vector< Ambient*> ambients;
409 	std::vector<MapNote> mapnotes;
410 	std::vector< Spawn*> spawns;
411 	Actor** queue[QUEUE_COUNT];
412 	int Qcount[QUEUE_COUNT];
413 	unsigned int lastActorCount[QUEUE_COUNT];
414 	bool hostiles_visible = false;
415 
416 	VideoBufferPtr wallStencil;
417 	Region stencilViewport;
418 
419 	std::unordered_map<const void*, std::pair<VideoBufferPtr, Region>> objectStencils;
420 
421 public:
422 	Map(void);
423 	~Map(void) override;
424 	static void ReleaseMemory();
425 	static void NormalizeDeltas(double &dx, double &dy, const double &factor = 1);
426 
427 	/** prints useful information on console */
428 	void dump(bool show_actors=0) const;
GetTileMap()429 	TileMap *GetTileMap() const { return TMap; }
430 	/* gets the signal of daylight changes */
431 	bool ChangeMap(bool day_or_night);
432 	void SeeSpellCast(Scriptable *caster, ieDword spell) const;
433 	/* low level function to perform the daylight changes */
434 	void ChangeTileMap(Image *lm, Holder<Sprite2D> sm);
435 	/* sets all the auxiliary maps and the tileset */
436 	void AddTileMap(TileMap *tm, Image *lm, Bitmap *sr, Holder<Sprite2D> sm, Bitmap *hm);
437 	void AutoLockDoors() const;
438 	void UpdateScripts();
439 	void ResolveTerrainSound(ieResRef &sound, const Point &pos) const;
440 	void DoStepForActor(Actor *actor, ieDword time) const;
441 	void UpdateEffects();
442 	/* removes empty heaps and returns total itemcount */
443 	int ConsolidateContainers();
444 	/* transfers all piles (loose items) to another map */
445 	void CopyGroundPiles(Map *othermap, const Point &Pos) const;
446 	/* transfers all ever visible piles (loose items) to the specified position */
447 	void MoveVisibleGroundPiles(const Point &Pos);
448 
449 	void DrawMap(const Region& viewport, uint32_t debugFlags);
450 	void PlayAreaSong(int SongType, bool restart = true, bool hard = false) const;
451 	void AddAnimation(AreaAnimation* anim);
GetFirstAnimation()452 	aniIterator GetFirstAnimation() const { return animations.begin(); }
GetNextAnimation(aniIterator & iter)453 	AreaAnimation *GetNextAnimation(aniIterator &iter) const
454 	{
455 		if (iter == animations.end()) {
456 			return NULL;
457 		}
458 		return *iter++;
459 	}
460 	AreaAnimation *GetAnimation(const char *Name) const;
GetAnimationCount()461 	size_t GetAnimationCount() const { return animations.size(); }
462 
SetWallGroups(std::vector<WallPolygonGroup> && walls)463 	void SetWallGroups(std::vector<WallPolygonGroup>&& walls)
464 	{
465 		wallGroups = std::move(walls);
466 	}
467 	bool BehindWall(const Point&, const Region&) const;
468 	void Shout(const Actor* actor, int shoutID, bool global) const;
469 	void ActorSpottedByPlayer(const Actor *actor) const;
470 	bool HandleAutopauseForVisible(Actor *actor, bool) const;
471 	void InitActors();
472 	void InitActor(const Actor *actor);
473 	void AddActor(Actor* actor, bool init);
474 	//counts the summons already in the area
475 	int CountSummons(ieDword flag, ieDword sex) const;
476 	//returns true if an enemy is near P (used in resting/saving)
477 	bool AnyEnemyNearPoint(const Point &p) const;
478 	PathMapFlags GetBlockedInRadius(unsigned int px, unsigned int py, unsigned int size, bool stopOnImpassable = true) const;
479 	PathMapFlags GetBlocked(unsigned int x, unsigned int y) const;
480 	PathMapFlags GetBlocked(unsigned int x, unsigned int y, int size) const;
481 	PathMapFlags GetBlockedNavmap(unsigned int x, unsigned int y) const;
482 	PathMapFlags GetBlockedNavmap(const Point &c) const;
483 	Scriptable *GetScriptableByGlobalID(ieDword objectID);
484 	Door *GetDoorByGlobalID(ieDword objectID) const;
485 	Container *GetContainerByGlobalID(ieDword objectID) const;
486 	InfoPoint *GetInfoPointByGlobalID(ieDword objectID) const;
487 	Actor* GetActorByGlobalID(ieDword objectID) const;
488 	Actor* GetActorInRadius(const Point &p, int flags, unsigned int radius) const;
489 	std::vector<Actor *> GetAllActorsInRadius(const Point &p, int flags, unsigned int radius, const Scriptable *see = NULL) const;
GetAllActors()490 	const std::vector<Actor *> &GetAllActors() const { return actors; }
491 	int GetActorsInRect(Actor**& actorlist, const Region& rgn, int excludeFlags) const;
492 	Actor* GetActor(const char* Name, int flags) const;
493 	Actor* GetActor(int i, bool any) const;
494 	Actor* GetActor(const Point &p, int flags, const Movable *checker = NULL) const;
495 	Scriptable *GetActorByDialog(const char *resref) const;
496 	Scriptable *GetItemByDialog(ieResRef resref) const;
497 	Actor *GetActorByResource(const char *resref) const;
498 	Actor *GetActorByScriptName(const char *name) const;
499 	bool HasActor(const Actor *actor) const;
500 	bool SpawnsAlive() const;
501 	void RemoveActor(Actor* actor);
502 
503 	int GetActorCount(bool any) const;
504 	//fix actors position if required
505 	void JumpActors(bool jump);
506 	//selects all selectable actors in the area
507 	void SelectActors() const;
508 	//if items == true, remove noncritical items from ground piles too
509 	void PurgeArea(bool items);
510 
511 	SongHeaderType SongHeader;
512 	RestHeaderType RestHeader;
513 	int AreaDifficulty;
514 
515 	//count of all projectiles that are saved
516 	size_t GetProjectileCount(proIterator &iter) const;
517 	//get the next projectile
518 	Projectile *GetNextProjectile(const proIterator &iter) const;
519 	//count of unexploded projectiles that are saved
520 	int GetTrapCount(proIterator &iter) const;
521 	//get the next saved projectile
522 	Projectile *GetNextTrap(proIterator &iter) const;
523 	//add a projectile to the area
524 	void AddProjectile(Projectile *pro, const Point &source, ieDword actorID, bool fake);
525 	void AddProjectile(Projectile* pro, const Point &source, const Point &dest);
526 
527 	//returns the duration of a VVC cell set in the area (point may be set to empty)
528 	ieDword HasVVCCell(const ieResRef resource, const Point &p) const;
529 	void AddVVCell(VEFObject* vvc);
530 	bool CanFree();
531 	int GetCursor(const Point &p) const;
532 	//adds a sparkle puff of colour to a point in the area
533 	//FragAnimID is an optional avatar animation ID (see avatars.2da) for
534 	//fragment animation
535 	void Sparkle(ieDword duration, ieDword color, ieDword type, const Point &pos, unsigned int FragAnimID = 0, int Zpos = 0);
536 	//removes or fades the sparkle puff at a point
537 	void FadeSparkle(const Point &pos, bool forced) const;
538 
539 	//entrances
540 	void AddEntrance(const char* Name, int XPos, int YPos, short Face);
541 	Entrance *GetEntrance(const char *Name) const;
GetEntrance(int i)542 	Entrance *GetEntrance(int i) const { return entrances[i]; }
GetEntranceCount()543 	int GetEntranceCount() const { return (int) entrances.size(); }
544 
545 	//containers
546 	/* this function returns/creates a pile container at position */
547 	Container* AddContainer(const char* Name, unsigned short Type,
548 							std::shared_ptr<Gem_Polygon> outline);
549 	Container *GetPile(Point position);
550 	void AddItemToLocation(const Point &position, CREItem *item);
551 
GetWidth()552 	int GetWidth() const { return Width; }
GetHeight()553 	int GetHeight() const { return Height; }
554 	Size GetSize() const;
555 	int GetExploredMapSize() const;
556 	void FillExplored(bool explored);
557 	/* set one fog tile as visible. x, y are tile coordinates */
558 	void ExploreTile(const Point&);
559 	/* explore map from given point in map coordinates */
560 	void ExploreMapChunk(const Point &Pos, int range, int los);
561 	/* block or unblock searchmap with value */
562 	void BlockSearchMap(const Point &Pos, unsigned int size, PathMapFlags value);
563 	void ClearSearchMapFor(const Movable *actor);
564 	/* update VisibleBitmap by resolving vision of all explore actors */
565 	void UpdateFog();
566 	//PathFinder
567 	/* Finds the nearest passable point */
568 	void AdjustPosition(Point &goal, unsigned int radiusx = 0, unsigned int radiusy = 0, int size = -1) const;
569 	void AdjustPositionNavmap(Point &goal, unsigned int radiusx = 0, unsigned int radiusy = 0) const;
570 	/* Finds the path which leads the farthest from d */
571 	PathNode* RunAway(const Point &s, const Point &d, unsigned int size, int maxPathLength, bool backAway, const Actor *caller) const;
572 	PathNode* RandomWalk(const Point &s, int size, int radius, const Actor *caller) const;
573 	/* Returns true if there is no path to d */
574 	bool TargetUnreachable(const Point &s, const Point &d, unsigned int size, bool actorsAreBlocking = false) const;
575 	/* returns true if there is enemy visible */
576 	bool AnyPCSeesEnemy() const;
577 	/* Finds straight path from s, length l and orientation o, f=1 passes wall, f=2 rebounds from wall*/
578 	PathNode* GetLine(const Point &start, const Point &dest, int flags) const;
579 	PathNode* GetLine(const Point &start, int steps, unsigned int orient) const;
580 	PathNode* GetLine(const Point &start, int Steps, int Orientation, int flags) const;
581 	PathNode* GetLine(const Point &start, const Point &dest, int speed, int Orientation, int flags) const;
582 	/* Finds the path which leads to near d */
583 	PathNode* FindPath(const Point &s, const Point &d, unsigned int size, unsigned int minDistance = 0, int flags = PF_SIGHT, const Actor *caller = NULL) const;
584 
585 	bool IsVisible(const Point &p) const;
586 	bool IsExplored(const Point &p) const;
587 	bool IsVisibleLOS(const Point &s, const Point &d, const Actor *caller = NULL) const;
588 	bool IsWalkableTo(const Point &s, const Point &d, bool actorsAreBlocking, const Actor *caller) const;
589 
590 	/* returns edge direction of map boundary, only worldmap regions */
591 	int WhichEdge(const Point &s) const;
592 
593 	//ambients
AddAmbient(Ambient * ambient)594 	void AddAmbient(Ambient *ambient) { ambients.push_back(ambient); }
595 	void SetupAmbients() const;
GetAmbient(int i)596 	Ambient *GetAmbient(int i) const { return ambients[i]; }
597 	ieWord GetAmbientCount(bool toSave = false) const;
598 
599 	//mapnotes
600 	void AddMapNote(const Point &point, ieWord color, String* text, bool readonly = false);
601 	void AddMapNote(const Point &point, ieWord color, ieStrRef strref, bool readonly = false);
602 	void AddMapNote(const Point &point, const MapNote& note);
603 	void RemoveMapNote(const Point &point);
GetMapNote(int i)604 	const MapNote &GetMapNote(int i) const { return mapnotes[i]; }
605 	const MapNote *MapNoteAtPoint(const Point &point, unsigned int radius) const;
GetMapNoteCount()606 	unsigned int GetMapNoteCount() const { return (unsigned int) mapnotes.size(); }
607 	//restheader
608 	/* May spawn creature(s), returns the remaining number of (unrested) hours for interrupted rest */
609 	int CheckRestInterruptsAndPassTime(const Point &pos, int hours, int day);
610 	/* Spawns creature(s) in radius of position */
611 	bool SpawnCreature(const Point &pos, const char *creResRef, int radiusx = 0, int radiusy = 0, ieWord rwdist = 0, int *difficulty = NULL, unsigned int *creCount = NULL);
612 
613 	//spawns
614 	void LoadIniSpawn();
615 	Spawn *AddSpawn(char* Name, int XPos, int YPos, ieResRef *creatures, unsigned int count);
GetSpawn(int i)616 	Spawn *GetSpawn(int i) const { return spawns[i]; }
617 	//returns spawn by name
618 	Spawn *GetSpawn(const char *Name) const;
619 	//returns spawn inside circle, checks for schedule and other
620 	//conditions as well
621 	Spawn *GetSpawnRadius(const Point &point, unsigned int radius) const;
GetSpawnCount()622 	unsigned int GetSpawnCount() const { return (unsigned int) spawns.size(); }
623 	void TriggerSpawn(Spawn *spawn);
624 
625 	//move some or all players to a new area
626 	void MoveToNewArea(const char *area, const char *entrance, unsigned int direction, int EveryOne, Actor *actor) const;
627 	bool HasWeather() const;
628 	int GetWeather() const;
629 	void ClearTrap(Actor *actor, ieDword InTrap) const;
630 
631 	//tracking stuff
632 	void SetTrackString(ieStrRef strref, int flg, int difficulty);
633 	//returns true if tracking failed
634 	bool DisplayTrackString(const Actor *actor) const;
635 
636 	unsigned int GetLightLevel(const Point &Pos) const;
637 	PathMapFlags GetInternalSearchMap(int x, int y) const;
638 	void SetInternalSearchMap(int x, int y, PathMapFlags value);
639 	void SetBackground(const ieResRef &bgResref, ieDword duration);
640 	void SetupReverbInfo();
641 
642 private:
643 	AreaAnimation *GetNextAreaAnimation(aniIterator &iter, ieDword gametime) const;
644 	Particles *GetNextSpark(const spaIterator &iter) const;
645 	VEFObject *GetNextScriptedAnimation(const scaIterator &iter) const;
646 	Actor *GetNextActor(int &q, int &index) const;
647 	Container *GetNextPile (int &index) const;
648 
649 	void RedrawScreenStencil(const Region& vp, const WallPolygonGroup& walls);
650 	void DrawStencil(const VideoBufferPtr& stencilBuffer, const Region& vp, const WallPolygonGroup& walls) const;
651 	WallPolygonSet WallsIntersectingRegion(Region, bool includeDisabled = false, const Point* loc = nullptr) const;
652 
653 	void SetDrawingStencilForObject(const void*, const Region&, const WallPolygonSet&, const Point& viewPortOrigin);
654 	BlitFlags SetDrawingStencilForScriptable(const Scriptable*, const Region& viewPort);
655 	BlitFlags SetDrawingStencilForAreaAnimation(const AreaAnimation*, const Region& viewPort);
656 
657 	void DrawSearchMap(const Region &vp) const;
658 	void DrawPortal(const InfoPoint *ip, int enable);
659 	void DrawHighlightables(const Region& viewport) const;
660 	void DrawFogOfWar(const ieByte* explored_mask, const ieByte* visible_mask, const Region& viewport);
661 	Size FogMapSize() const;
662 	bool FogTileUncovered(const Point &p, const uint8_t*) const;
663 	Point ConvertPointToFog(const Point &p) const;
664 
665 	void GenerateQueues();
666 	void SortQueues() const;
667 	//Actor* GetRoot(int priority, int &index);
668 	void DeleteActor(int i);
669 	//actor uses travel region
670 	void UseExit(Actor *pc, InfoPoint *ip);
671 	//separated position adjustment, so their order could be randomised
672 	bool AdjustPositionX(Point &goal, unsigned int radiusx,  unsigned int radiusy, int size = -1) const;
673 	bool AdjustPositionY(Point &goal, unsigned int radiusx,  unsigned int radiusy, int size = -1) const;
674 
675 	void UpdateSpawns() const;
676 	PathMapFlags GetBlockedInLine(const Point &s, const Point &d, bool stopOnImpassable, const Actor *caller = NULL) const;
677 
678 };
679 
680 }
681 
682 #endif
683