1 /* 2 ** gamemap.h 3 ** 4 **--------------------------------------------------------------------------- 5 ** Copyright 2011 Braden Obrzut 6 ** All rights reserved. 7 ** 8 ** Redistribution and use in source and binary forms, with or without 9 ** modification, are permitted provided that the following conditions 10 ** are met: 11 ** 12 ** 1. Redistributions of source code must retain the above copyright 13 ** notice, this list of conditions and the following disclaimer. 14 ** 2. Redistributions in binary form must reproduce the above copyright 15 ** notice, this list of conditions and the following disclaimer in the 16 ** documentation and/or other materials provided with the distribution. 17 ** 3. The name of the author may not be used to endorse or promote products 18 ** derived from this software without specific prior written permission. 19 ** 20 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 **--------------------------------------------------------------------------- 31 ** 32 ** 33 */ 34 35 #ifndef __GAMEMAP_H__ 36 #define __GAMEMAP_H__ 37 38 #include "tarray.h" 39 #include "zstring.h" 40 #include "textures/textures.h" 41 #include "dobject.h" 42 43 class Thinker; 44 class UWMFParser; 45 46 enum 47 { 48 SLIDE_Normal, 49 SLIDE_Split, 50 SLIDE_Invert 51 }; 52 53 enum 54 { 55 AM_Visible = 0x1, 56 AM_DontOverlay = 0x2 57 }; 58 59 class GameMap 60 { 61 public: 62 struct Header 63 { 64 FString name; 65 unsigned int width; 66 unsigned int height; 67 unsigned int tileSize; 68 }; 69 struct Thing 70 { ThingThing71 Thing() : x(0), y(0), z(0), angle(0), type(0), ambush(false), 72 patrol(false) 73 { 74 skill[0] = skill[1] = skill[2] = skill[3] = false; 75 } 76 77 fixed x, y, z; 78 unsigned short angle; 79 unsigned int type; 80 bool ambush; 81 bool patrol; 82 bool skill[4]; 83 }; 84 struct Trigger 85 { TriggerTrigger86 Trigger() : x(0), y(0), z(0), active(true), action(0), 87 playerUse(false), playerCross(false), monsterUse(false), 88 isSecret(false), repeatable(false) 89 { 90 activate[0] = activate[1] = activate[2] = activate[3] = true; 91 arg[0] = arg[1] = arg[2] = arg[3] = arg[4] = 0; 92 } 93 94 unsigned int x, y, z; 95 // Stores if the trigger hasn't been used yet. 96 // Note that this is set to false on for repeatable actions as well so that secrets are only accounted for once. 97 bool active; 98 99 enum Side { East, North, West, South }; 100 unsigned int action; 101 bool activate[4]; 102 int arg[5]; 103 104 bool playerUse; 105 bool playerCross; 106 bool monsterUse; 107 bool isSecret; 108 bool repeatable; 109 }; 110 struct Tile 111 { TileTile112 Tile() : offsetVertical(false), offsetHorizontal(false), 113 mapped(0), dontOverlay(false) 114 { 115 overhead.SetInvalid(); 116 sideSolid[0] = sideSolid[1] = sideSolid[2] = sideSolid[3] = true; 117 } 118 119 enum Side { East, North, West, South }; 120 FTextureID texture[4]; 121 FTextureID overhead; 122 bool sideSolid[4]; 123 bool offsetVertical; 124 bool offsetHorizontal; 125 FName soundSequence; 126 127 unsigned int mapped; // filter level for always visible 128 bool dontOverlay; 129 }; 130 struct Sector 131 { 132 enum Flat { Floor, Ceiling }; 133 FTextureID texture[2]; 134 }; 135 struct Zone 136 { 137 unsigned short index; 138 }; 139 struct Plane 140 { 141 const GameMap *gm; 142 143 unsigned int depth; 144 struct Map 145 { MapPlane::Map146 Map() : tile(NULL), sector(NULL), zone(NULL), visible(false), 147 amFlags(0), thinker(NULL), slideStyle(0), 148 pushDirection(Tile::East), pushAmount(0), 149 pushReceptor(NULL), tag(0), nexttag(NULL) 150 { 151 slideAmount[0] = slideAmount[1] = slideAmount[2] = slideAmount[3] = 0; 152 sideSolid[0] = sideSolid[1] = sideSolid[2] = sideSolid[3] = true; 153 } 154 155 unsigned int GetX() const; 156 unsigned int GetY() const; 157 Map *GetAdjacent(Tile::Side dir, bool opposite=false) const; 158 void SetTile(const Tile *tile); 159 160 const Plane *plane; 161 162 const Tile *tile; 163 const Sector *sector; 164 const Zone *zone; 165 166 // So that the textures can change. 167 FTextureID texture[4]; 168 169 bool visible; 170 unsigned int amFlags; 171 TObjPtr<Thinker> thinker; 172 unsigned int slideAmount[4]; 173 unsigned int slideStyle; 174 bool sideSolid[4]; 175 TArray<Trigger> triggers; 176 Tile::Side pushDirection; 177 unsigned int pushAmount; 178 Map *pushReceptor; 179 180 unsigned int tag; 181 Plane::Map *nexttag; 182 }* map; 183 }; 184 185 GameMap(const FString &map); 186 ~GameMap(); 187 188 bool ActivateTrigger(Trigger &trig, Trigger::Side direction, AActor *activator); 189 void ClearVisibility(); GetHeader()190 const Header &GetHeader() const { return header; } 191 void GetHitlist(BYTE* hitlist) const; GetMarketLumpNum()192 int GetMarketLumpNum() const { return markerLump; } GetSpot(unsigned int x,unsigned int y,unsigned int z)193 Plane::Map *GetSpot(unsigned int x, unsigned int y, unsigned int z) const { return &GetPlane(z).map[y*header.width+x]; } 194 Plane::Map *GetSpotByTag(unsigned int tag, Plane::Map *start) const; GetZone(unsigned int index)195 const Zone &GetZone(unsigned int index) { return zonePalette[index]; } IsValid()196 bool IsValid() const { return valid; } IsValidTileCoordinate(unsigned int x,unsigned int y,unsigned int z)197 bool IsValidTileCoordinate(unsigned int x, unsigned int y, unsigned int z) const { return x < header.width && y < header.height && z < NumPlanes(); } 198 void LoadMap(bool loadingSave); NumPlanes()199 unsigned int NumPlanes() const { return planes.Size(); } GetPlane(unsigned int index)200 const Plane &GetPlane(unsigned int index) const { return planes[index]; } 201 void SpawnThings() const; 202 203 // Sound functions 204 bool CheckLink(const Zone *zone1, const Zone *zone2, bool recurse); 205 void LinkZones(const Zone *zone1, const Zone *zone2, bool open); 206 207 // Save lookups 208 const Tile *GetTile(unsigned int index) const; 209 unsigned int GetTileIndex(const Tile *tile) const; 210 const Sector *GetSector(unsigned int index) const; 211 unsigned int GetSectorIndex(const Sector *sector) const; 212 213 static bool CheckMapExists(const FString &map); 214 215 void PropagateMark(); 216 217 TMap<unsigned int, Plane::Map *> elevatorPosition; 218 private: 219 friend class UWMFParser; 220 friend FArchive &operator<< (FArchive &, GameMap *&); 221 222 Plane &NewPlane(); 223 Trigger &NewTrigger(unsigned int x, unsigned int y, unsigned int z); 224 void ReadPlanesData(); 225 void ReadUWMFData(); 226 void SetSpotTag(Plane::Map *spot, unsigned int tag); 227 void SetupLinks(); 228 void ScanTiles(); 229 bool TraverseLink(const Zone *src, const Zone *dest); 230 void UnloadLinks(); 231 232 FString map; 233 234 bool valid; 235 bool isWad; 236 bool isUWMF; 237 int markerLump; 238 int numLumps; 239 240 class FResourceFile *file; 241 class FileReader *lumps[1]; 242 243 // Actual map data 244 Header header; 245 TArray<Tile> tilePalette; 246 TArray<Sector> sectorPalette; 247 TArray<Zone> zonePalette; 248 TArray<Thing> things; 249 TArray<Plane> planes; 250 TMap<unsigned int, Plane::Map *> tagMap; 251 252 // Sound travel links. zoneTraversed is temporary array for recursive 253 // traversals. zoneLinks is the table of links (counts the number of 254 // links that are opened). 255 bool* zoneTraversed; 256 unsigned short** zoneLinks; 257 }; 258 259 typedef GameMap::Plane::Map * MapSpot; 260 261 // The following are mainly for easy access to enums 262 typedef GameMap::Plane MapPlane; 263 typedef GameMap::Sector MapSector; 264 typedef GameMap::Thing MapThing; 265 typedef GameMap::Tile MapTile; 266 typedef GameMap::Trigger MapTrigger; 267 typedef GameMap::Zone MapZone; 268 269 #include "farchive.h" 270 FArchive &operator<< (FArchive &arc, GameMap *&gm); 271 FArchive &operator<< (FArchive &arc, MapSpot &spot); 272 FArchive &operator<< (FArchive &arc, const MapSector *&tile); 273 FArchive &operator<< (FArchive &arc, const MapTile *&tile); 274 FArchive &operator<< (FArchive &arc, const MapZone *&zone); 275 FArchive &operator<< (FArchive &arc, MapTrigger &trigger); 276 277 #endif 278