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