1 /* 2 * gamemap.h - Game map data. 3 * 4 * Copyright (C) 1998-1999 Jeffrey S. Freedman 5 * Copyright (C) 2000-2013 The Exult Team 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 */ 21 22 #ifndef GAMEMAP_H 23 #define GAMEMAP_H 24 25 #include "chunks.h" 26 #include "exult_constants.h" 27 #include "flags.h" 28 #include "tiles.h" 29 30 #include <cassert> 31 #include <fstream> 32 #include <iostream> 33 #include <memory> 34 #include <string> // STL string 35 #include <vector> 36 37 class Chunk_terrain; 38 class Map_patch_collection; 39 class Game_object; 40 class Ireg_game_object; 41 class Ifix_game_object; 42 class Egg_object; 43 class Shape_info; 44 class Shapes_vga_file; 45 class IDataSource; 46 class ODataSource; 47 class Shape; 48 using Ireg_game_object_shared = std::shared_ptr<Ireg_game_object>; 49 using Ifix_game_object_shared = std::shared_ptr<Ifix_game_object>; 50 51 #define IREG_EXTENDED 254 // For shape #'s > 1023. 52 #define IREG_EXTENDED2 253 // For lift > 15. 53 54 /* 55 * The game map: 56 */ 57 class Game_map { 58 int num; // Map #. Index in gwin->maps. 59 // Flat chunk areas: 60 static std::vector<Chunk_terrain *> *chunk_terrains; 61 static std::ifstream *chunks; // "u7chunks" file. 62 static bool v2_chunks; // True if 3 bytes/entry. 63 static bool read_all_terrain; // True if we've read them all. 64 static bool chunk_terrains_modified; 65 bool didinit; 66 bool map_modified; // True if any map changes from 67 // map-editing. 68 // Chunk_terrain index for each chunk: 69 short terrain_map[c_num_chunks][c_num_chunks]; 70 // A list of objects in each chunk: 71 std::unique_ptr<Map_chunk> objects[c_num_chunks][c_num_chunks]; 72 bool schunk_read[144]; // Flag for reading in each "ifix". 73 bool schunk_modified[144]; // Flag for modified "ifix". 74 char *schunk_cache[144]; 75 int schunk_cache_sizes[144]; 76 int caching_out; // >0 in 'cache_out_schunk'. 77 std::unique_ptr<Map_patch_collection> map_patches; 78 79 Map_chunk *create_chunk(int cx, int cy); 80 static Chunk_terrain *read_terrain(int chunk_num); 81 82 // Create a 192x192 viewable map. 83 void create_minimap(Shape *minimaps, const unsigned char *chunk_pixels); 84 void cache_out_schunk(int schunk); 85 public: 86 Game_map(int n); 87 ~Game_map(); 88 static void init_chunks(); 89 void init(); // Set up map. 90 static void clear_chunks(); 91 void clear(); // Clear out old map. 92 void read_map_data(); // Read in 'ifix', 'ireg', etc. is_v2_chunks()93 static bool is_v2_chunks() { 94 return v2_chunks; 95 } is_caching_out()96 bool is_caching_out() const { 97 return caching_out > 0; 98 } get_num()99 int get_num() const { 100 return num; 101 } get_terrain_num(int cx,int cy)102 inline short get_terrain_num(int cx, int cy) const { 103 return terrain_map[cx][cy]; 104 } get_map_patches()105 inline Map_patch_collection& get_map_patches() { 106 return *map_patches; 107 } set_map_modified()108 void set_map_modified() { 109 map_modified = true; 110 } was_map_modified()111 bool was_map_modified() const { 112 return map_modified; 113 } was_chunk_terrain_modified()114 static bool was_chunk_terrain_modified() { 115 return chunk_terrains_modified; 116 } set_chunk_terrains_modified()117 static void set_chunk_terrains_modified() { 118 chunk_terrains_modified = true; 119 } is_chunk_read(int cx,int cy)120 bool is_chunk_read(int cx, int cy) { 121 return cx < c_num_chunks && cy < c_num_chunks && 122 schunk_read[12 * (cy / c_chunks_per_schunk) + 123 cx / c_chunks_per_schunk]; 124 } ensure_chunk_read(int cx,int cy)125 void ensure_chunk_read(int cx, int cy) { 126 if (cx < c_num_chunks && cy < c_num_chunks) { 127 int sc = 12 * (cy/c_chunks_per_schunk) + cx/c_chunks_per_schunk; 128 if (!schunk_read[sc]) 129 get_superchunk_objects(sc); 130 } 131 } set_ifix_modified(int cx,int cy)132 void set_ifix_modified(int cx, int cy) { 133 map_modified = true; 134 schunk_modified[12 * (cy / c_chunks_per_schunk) + 135 cx / c_chunks_per_schunk] = true; 136 } 137 // Get objs. list for a chunk. get_chunk_unsafe(int cx,int cy)138 Map_chunk *get_chunk_unsafe(int cx, int cy) { 139 return objects[cx][cy].get(); 140 } 141 // Get/create objs. list for a chunk. get_chunk_unchecked(int cx,int cy)142 Map_chunk *get_chunk_unchecked(int cx, int cy) { 143 Map_chunk *list = get_chunk_unsafe(cx, cy); 144 return list ? list : create_chunk(cx, cy); 145 } 146 // Get/create objs. list for a chunk. get_chunk(int cx,int cy)147 Map_chunk *get_chunk(int cx, int cy) { 148 assert((cx >= 0) && (cx < c_num_chunks) && 149 (cy >= 0) && (cy < c_num_chunks)); 150 return get_chunk_unchecked(cx, cy); 151 } get_chunk_safely(int cx,int cy)152 Map_chunk *get_chunk_safely(int cx, int cy) { 153 if (cx >= 0 && cx < c_num_chunks && 154 cy >= 0 && cy < c_num_chunks) { 155 return get_chunk_unchecked(cx, cy); 156 } 157 return nullptr; 158 } 159 // Get "map" superchunk objs/scenery. 160 void get_map_objects(int schunk); 161 // Get "chunk" objects/scenery. 162 void get_chunk_objects(int cx, int cy); 163 static void get_all_terrain(); // Read in all terrains. 164 // Get desired terrain. get_terrain(int tnum)165 static Chunk_terrain *get_terrain(int tnum) { 166 Chunk_terrain *ter = (*chunk_terrains)[tnum]; 167 return ter ? ter : read_terrain(tnum); 168 } get_num_chunk_terrains()169 inline int get_num_chunk_terrains() const { 170 return chunk_terrains->size(); 171 } 172 // Set new terrain chunk. 173 void set_chunk_terrain(int cx, int cy, int chunknum); 174 char *get_mapped_name(const char *from, char *to); 175 // Get ifixxxx/iregxx name. 176 char *get_schunk_file_name(const char *prefix, int schunk, char *fname); 177 static void write_chunk_terrains(); 178 void write_static(); // Write to 'static' directory. 179 // Write (static) map objects. 180 void write_ifix_objects(int schunk); 181 // Get "ifix" objects for a superchunk. 182 void get_ifix_objects(int schunk); 183 // Get "ifix" objs. for given chunk. 184 void get_ifix_chunk_objects(IDataSource *ifix, int vers, 185 long filepos, int len, int cx, int cy); 186 static void write_attributes(ODataSource *ireg, 187 std::vector<std::pair<const char *, int> > &attlist); 188 // Write scheduled script for obj. 189 static void write_scheduled(ODataSource *ireg, Game_object *obj, 190 bool write_mark = false); 191 static int write_string(ODataSource *ireg, const char *str); 192 void write_ireg(); // Write modified ireg files. 193 // Write moveable objects to file. 194 void write_ireg_objects(int schunk); 195 // Write moveable objects to datasource. 196 void write_ireg_objects(int schunk, ODataSource *ireg); 197 // Get moveable objects. 198 void get_ireg_objects(int schunk); 199 // Read scheduled script(s) for obj. 200 void read_special_ireg(IDataSource *ireg, Game_object *obj); 201 void read_ireg_objects(IDataSource *ireg, int scx, int scy, 202 Game_object *container = nullptr, 203 unsigned long flags = (1 << Obj_flags::okay_to_take)); 204 Ireg_game_object_shared create_ireg_object(const Shape_info &info, int shnum, 205 int frnum, int tilex, int tiley, int lift); 206 Ireg_game_object_shared create_ireg_object(int shnum, int frnum); 207 Ifix_game_object_shared create_ifix_object(int shnum, int frnum); 208 // Get all superchunk objects. 209 void get_superchunk_objects(int schunk); 210 bool is_tile_occupied(Tile_coord const &tile); 211 // Locate chunk with desired terrain. 212 bool locate_terrain(int tnum, int &cx, int &cy, bool upwards = false); 213 static bool swap_terrains(int tnum); // Swap adjacent terrain #'s. 214 // Insert new terrain after 'tnum'. 215 static bool insert_terrain(int tnum, bool dup = false); 216 static bool delete_terrain(int tnum); 217 static void commit_terrain_edits(); // End terrain-editing mode. 218 static void abort_terrain_edits(); 219 // Search entire game for unused. 220 void find_unused_shapes(unsigned char *found, int foundlen); 221 // Locate shape (for EStudio). 222 Game_object *locate_shape(int shapenum, bool upwards, 223 Game_object *start, int frnum, int qual); 224 static bool write_minimap(); 225 226 // Do a cache out. (cx, cy) is the center 227 void cache_out(int cx, int cy); 228 }; 229 230 #endif 231