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.
32 #include "SpriteCover.h"
33 #include "Scriptable/ActorBlock.h"
40 class AnimationFactory
;
45 class ScriptedAnimation
;
49 //distance of actors from spawn point
50 #define SPAWN_RANGE 400
55 #define AF_DEADMAGIC 4
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)
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
84 #define AF_CRE_NOT_LOADED 1
85 #define AF_NAME_OVERRIDE 8
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
];
114 ieWord rwdist
, owdist
;
129 MapNote() { text
=NULL
; }
130 ~MapNote() { if(text
) free(text
); }
142 ieDword sduration
; //spawn duration
143 ieWord rwdist
, owdist
; //maximum walk distances
149 Spawn() { Creatures
=NULL
; }
150 ~Spawn() { if(Creatures
) free(Creatures
); }
151 unsigned int GetCreatureCount() { return Count
; }
154 class TerrainSounds
{
166 SpawnGroup(unsigned int size
) {
167 ResRefs
= (ieResRef
*) calloc(size
, sizeof(ieResRef
) );
177 class GEM_EXPORT AreaAnimation
{
179 Animation
**animation
;
181 //dwords, or stuff combining to a dword
185 //these are on one dword
188 //these are on one dword
191 //these are on one dword
196 //string values, not in any particular order
198 ieResRef BAM
; //not only for saving back (StaticSequence depends on this)
201 SpriteCover
** covers
;
204 void InitAnimation();
205 void SetPalette(ieResRef PaletteRef
);
206 void BlendAnimation();
207 bool Schedule(ieDword gametime
);
208 void Draw(const Region
&screen
, Map
*area
);
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
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
{
238 ieWord Rain
, Snow
, Fog
, Lightning
;
239 ieByte
* ExploredBitmap
;
240 ieByte
* VisibleBitmap
;
244 //this is set by the importer (not stored in the file)
246 //movies for day/night (only in ToB)
249 ieStrRef trackString
;
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
];
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()) {
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
)
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
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
);
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
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
);
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(); }
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 */
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
);
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(); }
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(); }
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);
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
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
);
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
);
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();
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
);