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.
29 #include "ActorBlock.h"
33 #include "SpriteCover.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
; }
160 SpawnGroup(unsigned int size
) {
161 ResRefs
= (ieResRef
*) calloc(size
, sizeof(ieResRef
) );
171 class GEM_EXPORT AreaAnimation
{
173 Animation
**animation
;
175 //dwords, or stuff combining to a dword
179 //these are on one dword
182 //these are on one dword
185 //these are on one dword
190 //string values, not in any particular order
192 ieResRef BAM
; //not only for saving back (StaticSequence depends on this)
195 SpriteCover
** covers
;
198 void InitAnimation();
199 void SetPalette(ieResRef PaletteRef
);
200 void BlendAnimation();
201 bool Schedule(ieDword gametime
);
202 void Draw(const Region
&screen
, Map
*area
);
204 Animation
*GetAnimationPiece(AnimationFactory
*af
, int animCycle
);
207 enum AnimationObjectType
{AOT_AREA
, AOT_SCRIPTED
, AOT_ACTOR
, AOT_SPARK
, AOT_PROJECTILE
};
209 //i believe we need only the active actors/visible inactive actors queues
210 #define QUEUE_COUNT 2
212 //priorities when handling actors, we really ignore the third one
217 typedef std::list
<AreaAnimation
*>::iterator aniIterator
;
218 typedef std::list
<ScriptedAnimation
*>::iterator scaIterator
;
219 typedef std::list
<Projectile
*>::iterator proIterator
;
220 typedef std::list
<Particles
*>::iterator spaIterator
;
222 class GEM_EXPORT Map
: public Scriptable
{
232 ieWord Rain
, Snow
, Fog
, Lightning
;
233 ieByte
* ExploredBitmap
;
234 ieByte
* VisibleBitmap
;
237 ieWord localActorCounter
;
239 //this is set by the importer (not stored in the file)
241 //movies for day/night (only in ToB)
244 ieStrRef trackString
;
247 unsigned short* MapSet
;
248 std::queue
< unsigned int> InternalStack
;
249 unsigned int Width
, Height
;
250 std::list
< AreaAnimation
*> animations
;
251 std::vector
< Actor
*> actors
;
252 Wall_Polygon
**Walls
;
253 unsigned int WallCount
;
254 std::list
< ScriptedAnimation
*> vvcCells
;
255 std::list
< Projectile
*> projectiles
;
256 std::list
< Particles
*> particles
;
257 std::vector
< Entrance
*> entrances
;
258 std::vector
< Ambient
*> ambients
;
259 std::vector
< MapNote
*> mapnotes
;
260 std::vector
< Spawn
*> spawns
;
261 Actor
** queue
[QUEUE_COUNT
];
262 int Qcount
[QUEUE_COUNT
];
263 unsigned int lastActorCount
[QUEUE_COUNT
];
267 static void ReleaseMemory();
269 /** prints useful information on console */
270 void DebugDump(bool show_actors
=0) const;
271 TileMap
*GetTileMap() { return TMap
; }
272 /* gets the signal of daylight changes */
273 bool ChangeMap(bool day_or_night
);
274 void SeeSpellCast(Scriptable
*caster
, ieDword spell
);
275 /* low level function to perform the daylight changes */
276 void ChangeTileMap(Image
* lm
, Sprite2D
* sm
);
277 /* sets all the auxiliary maps and the tileset */
278 void AddTileMap(TileMap
* tm
, Image
* lm
, Bitmap
* sr
, Sprite2D
* sm
, Bitmap
* hm
);
279 void UpdateScripts();
280 bool DoStepForActor(Actor
*actor
, int speed
, ieDword time
);
281 void UpdateEffects();
282 /* removes empty heaps and returns total itemcount */
283 int ConsolidateContainers();
284 /* transfers all piles (loose items) to another map */
285 void CopyGroundPiles(Map
*othermap
, const Point
&Pos
);
286 /* draws stationary vvc graphics */
287 //void DrawVideocells(Region screen);
288 void DrawHighlightables(Region screen
);
289 void DrawMap(Region screen
);
290 void PlayAreaSong(int SongType
, bool restart
= true);
291 void AddAnimation(AreaAnimation
* anim
);
292 aniIterator
GetFirstAnimation() { return animations
.begin(); }
293 AreaAnimation
* GetNextAnimation(aniIterator
&iter
)
295 if (iter
== animations
.end()) {
300 AreaAnimation
* GetAnimation(const char* Name
);
301 size_t GetAnimationCount() const { return animations
.size(); }
303 unsigned int GetWallCount() { return WallCount
; }
304 Wall_Polygon
*GetWallGroup(int i
) { return Walls
[i
]; }
305 void SetWallGroups(unsigned int count
, Wall_Polygon
**walls
)
310 SpriteCover
* BuildSpriteCover(int x
, int y
, int xpos
, int ypos
,
311 unsigned int width
, unsigned int height
, int flag
);
312 void ActivateWallgroups(unsigned int baseindex
, unsigned int count
, int flg
);
313 void Shout(Actor
* actor
, int shoutID
, unsigned int radius
);
314 void ActorSpottedByPlayer(Actor
*actor
);
315 void AddActor(Actor
* actor
);
316 //returns true if an enemy is near P (used in resting/saving)
317 bool AnyEnemyNearPoint(const Point
&p
);
318 bool GetBlocked(unsigned int x
, unsigned int y
, unsigned int size
);
319 unsigned char GetBlocked(unsigned int x
, unsigned int y
);
320 unsigned char GetBlocked(const Point
&p
);
321 Actor
* GetActorByGlobalID(ieDword objectID
);
322 Actor
* GetActor(const Point
&p
, int flags
);
323 Actor
* GetActorInRadius(const Point
&p
, int flags
, unsigned int radius
);
324 Actor
**GetAllActorsInRadius(const Point
&p
, int flags
, unsigned int radius
);
325 Actor
* GetActor(const char* Name
, int flags
);
326 Actor
* GetActor(int i
, bool any
);
327 Actor
* GetActorByDialog(const char* resref
);
328 Actor
* GetActorByResource(const char* resref
);
329 bool HasActor(Actor
*actor
);
330 void RemoveActor(Actor
* actor
);
331 //returns actors in rect (onlyparty could be more sophisticated)
332 int GetActorInRect(Actor
**& actors
, Region
& rgn
, bool onlyparty
);
333 int GetActorCount(bool any
) const;
334 //fix actors position if required
335 void JumpActors(bool jump
);
336 //if items == true, remove noncritical items from ground piles too
337 void PurgeArea(bool items
);
339 SongHeaderType SongHeader
;
340 RestHeaderType RestHeader
;
342 //count of all projectiles that are saved
343 size_t GetProjectileCount(proIterator
&iter
);
344 //get the next projectile
345 Projectile
*GetNextProjectile(proIterator
&iter
);
346 //count of unexploded projectiles that are saved
347 ieDword
GetTrapCount(proIterator
&iter
);
348 //get the next saved projectile
349 Projectile
* GetNextTrap(proIterator
&iter
);
350 //add a projectile to the area
351 void AddProjectile(Projectile
* pro
, const Point
&source
, const Point
&dest
);
352 void AddProjectile(Projectile
* pro
, const Point
&source
, ieWord actorID
);
354 //returns the duration of a VVC cell set in the area (point may be set to empty)
355 ieDword
HasVVCCell(const ieResRef resource
, const Point
&p
);
356 void AddVVCell(ScriptedAnimation
* vvc
);
358 int GetCursor( const Point
&p
);
359 //adds a sparkle puff of colour to a point in the area
360 //FragAnimID is an optional avatar animation ID (see avatars.2da) for
362 void Sparkle(ieDword color
, ieDword type
, const Point
&pos
, unsigned int FragAnimID
= 0);
363 //removes or fades the sparkle puff at a point
364 void FadeSparkle(const Point
&pos
, bool forced
);
367 void AddEntrance(char* Name
, int XPos
, int YPos
, short Face
);
368 Entrance
* GetEntrance(const char* Name
);
369 Entrance
* GetEntrance(int i
) { return entrances
[i
]; }
370 int GetEntranceCount() const { return (int) entrances
.size(); }
373 /* this function returns/creates a pile container at position */
374 Container
* AddContainer(const char* Name
, unsigned short Type
,
375 Gem_Polygon
* outline
);
376 Container
*GetPile(Point position
);
377 void AddItemToLocation(const Point
&position
, CREItem
*item
);
379 int GetWidth() const { return Width
; }
380 int GetHeight() const { return Height
; }
381 int GetExploredMapSize() const;
382 /*fills the explored bitmap with setreset */
383 void Explore(int setreset
);
384 /*fills the visible bitmap with setreset */
385 void SetMapVisibility(int setreset
= 0);
386 /* set one fog tile as visible. x, y are tile coordinates */
387 void ExploreTile(const Point
&Tile
);
388 /* explore map from given point in map coordinates */
389 void ExploreMapChunk(const Point
&Pos
, int range
, int los
);
390 /* block or unblock searchmap with value */
391 void BlockSearchMap(const Point
&Pos
, unsigned int size
, unsigned int value
);
392 void ClearSearchMapFor(Movable
*actor
);
393 /* update VisibleBitmap by resolving vision of all explore actors */
396 /* Finds the nearest passable point */
397 void AdjustPosition(Point
&goal
, unsigned int radius
=0);
398 /* Finds the path which leads the farthest from d */
399 PathNode
* RunAway(const Point
&s
, const Point
&d
, unsigned int size
, unsigned int PathLen
, int flags
);
400 /* Returns true if there is no path to d */
401 bool TargetUnreachable(const Point
&s
, const Point
&d
, unsigned int size
);
402 /* returns true if there is enemy visible */
403 bool AnyPCSeesEnemy();
404 /* Finds straight path from s, length l and orientation o, f=1 passes wall, f=2 rebounds from wall*/
405 PathNode
* GetLine(const Point
&start
, const Point
&dest
, int flags
);
406 PathNode
* GetLine(const Point
&start
, int Steps
, int Orientation
, int flags
);
407 PathNode
* GetLine(const Point
&start
, const Point
&dest
, int speed
, int Orientation
, int flags
);
408 /* Finds the path which leads to near d */
409 PathNode
* FindPathNear(const Point
&s
, const Point
&d
, unsigned int size
, unsigned int MinDistance
= 0, bool sight
= true);
410 /* Finds the path which leads to d */
411 PathNode
* FindPath(const Point
&s
, const Point
&d
, unsigned int size
, int MinDistance
= 0);
412 /* returns false if point isn't visible on visibility/explored map */
413 bool IsVisible(const Point
&s
, int explored
);
414 /* returns false if point d cannot be seen from point d due to searchmap */
415 bool IsVisible(const Point
&s
, const Point
&d
);
416 /* returns edge direction of map boundary, only worldmap regions */
417 int WhichEdge(const Point
&s
);
420 void AddAmbient(Ambient
*ambient
) { ambients
.push_back(ambient
); }
421 void SetupAmbients();
422 Ambient
*GetAmbient(int i
) { return ambients
[i
]; }
423 unsigned int GetAmbientCount() { return (unsigned int) ambients
.size(); }
426 void AddMapNote(const Point
&point
, int color
, char *text
, ieStrRef strref
);
427 void RemoveMapNote(const Point
&point
);
428 MapNote
*GetMapNote(int i
) { return mapnotes
[i
]; }
429 MapNote
*GetMapNote(const Point
&point
);
430 unsigned int GetMapNoteCount() { return (unsigned int) mapnotes
.size(); }
432 /* May spawn creature(s), returns true in case of an interrupted rest */
433 bool Rest(const Point
&pos
, int hours
, int day
);
434 /* Spawns creature(s) in radius of position */
435 void SpawnCreature(const Point
&pos
, const char *CreName
, int radius
= 0);
439 Spawn
*AddSpawn(char* Name
, int XPos
, int YPos
, ieResRef
*creatures
, unsigned int count
);
440 Spawn
*GetSpawn(int i
) { return spawns
[i
]; }
441 //returns spawn by name
442 Spawn
*GetSpawn(const char *Name
);
443 //returns spawn inside circle, checks for schedule and other
445 Spawn
*GetSpawnRadius(const Point
&point
, unsigned int radius
);
446 unsigned int GetSpawnCount() { return (unsigned int) spawns
.size(); }
447 void TriggerSpawn(Spawn
*spawn
);
448 //move some or all players to a new area
449 void MoveToNewArea(const char *area
, const char *entrance
, unsigned int direction
, int EveryOne
, Actor
*actor
);
452 void ClearTrap(Actor
*actor
, ieDword InTrap
);
453 void SetTrackString(ieStrRef strref
, int flg
, int difficulty
);
454 //returns true if tracking failed
455 bool DisplayTrackString(Actor
*actor
);
456 unsigned int GetLightLevel(const Point
&Pos
);
458 AreaAnimation
*GetNextAreaAnimation(aniIterator
&iter
, ieDword gametime
);
459 Particles
*GetNextSpark(spaIterator
&iter
);
460 ScriptedAnimation
*GetNextScriptedAnimation(scaIterator
&iter
);
461 Actor
*GetNextActor(int &q
, int &index
);
462 void DrawSearchMap(const Region
&screen
);
463 void GenerateQueues();
465 //Actor* GetRoot(int priority, int &index);
466 void DeleteActor(int i
);
467 void Leveldown(unsigned int px
, unsigned int py
, unsigned int& level
,
468 Point
&p
, unsigned int& diff
);
469 void SetupNode(unsigned int x
, unsigned int y
, unsigned int size
, unsigned int Cost
);
470 //actor uses travel region
471 void UseExit(Actor
*pc
, InfoPoint
*ip
);
472 //separated position adjustment, so their order could be randomised */
473 bool AdjustPositionX(Point
&goal
, unsigned int radius
);
474 bool AdjustPositionY(Point
&goal
, unsigned int radius
);
475 void DrawPortal(InfoPoint
*ip
, int enable
);