Reintroduce multiple maps: per-map chunk directories + map_t name/mapSetMap
Move chunk assets from a single flat assetsraw/chunks (and assets/chunks) into per-map assetsraw/maps/<map>/chunks (assets/maps/<map>/chunks), so terrain mesh/model output no longer collides across maps sharing chunk coordinates. map_t gains a name[MAP_NAME_MAX] field plus mapSetMap()/ mapIsLoaded() (checks name[0] == '\0') in place of the old bool loaded flag; mapInit() now just resets state and mapSetMap() does the chunk grid load. Updated the chunk asset tool and the map editor's dev server/client to match.
This commit is contained in:
@@ -28,7 +28,25 @@ void mapChunkLoadingSlotClear(chunk_t *chunk) {
|
||||
|
||||
errorret_t mapInit() {
|
||||
memoryZero(&MAP, sizeof(map_t));
|
||||
MAP.loaded = true;
|
||||
errorOk();
|
||||
}
|
||||
|
||||
bool_t mapIsLoaded() {
|
||||
return MAP.name[0] != '\0';
|
||||
}
|
||||
|
||||
errorret_t mapSetMap(const char_t *map) {
|
||||
assertNotNull(map, "mapSetMap: map name cannot be NULL");
|
||||
assertStrLenMax(map, MAP_NAME_MAX, "Map name too long");
|
||||
|
||||
if(mapIsLoaded()) {
|
||||
for(chunkindex_t i = 0; i < MAP_CHUNK_COUNT; i++) {
|
||||
mapChunkUnload(&MAP.chunks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
memoryZero(&MAP, sizeof(map_t));
|
||||
stringCopy(MAP.name, map, MAP_NAME_MAX);
|
||||
|
||||
chunkindex_t i = 0;
|
||||
for(chunkunit_t z = 0; z < MAP_CHUNK_DEPTH; z++) {
|
||||
@@ -47,10 +65,6 @@ errorret_t mapInit() {
|
||||
errorOk();
|
||||
}
|
||||
|
||||
bool_t mapIsLoaded() {
|
||||
return MAP.loaded;
|
||||
}
|
||||
|
||||
errorret_t mapPositionSet(const chunkpos_t newPos) {
|
||||
if(!mapIsLoaded()) errorThrow("No map loaded");
|
||||
if(chunkPositionIsEqual(newPos, MAP.chunkPosition)) errorOk();
|
||||
@@ -132,6 +146,7 @@ errorret_t mapDispose() {
|
||||
for(chunkindex_t i = 0; i < MAP_CHUNK_COUNT; i++) {
|
||||
mapChunkUnload(&MAP.chunks[i]);
|
||||
}
|
||||
MAP.name[0] = '\0';
|
||||
errorOk();
|
||||
}
|
||||
|
||||
@@ -203,10 +218,11 @@ errorret_t mapChunkLoad(chunk_t *chunk) {
|
||||
|
||||
chunk->meshCount = 0;
|
||||
|
||||
char_t name[64];
|
||||
char_t name[MAP_FILE_PATH_MAX];
|
||||
stringFormat(
|
||||
name, sizeof(name),
|
||||
"chunks/%d_%d_%d.dcf",
|
||||
"maps/%s/chunks/%d_%d_%d.dcf",
|
||||
MAP.name,
|
||||
(int32_t)chunk->position.x,
|
||||
(int32_t)chunk->position.y,
|
||||
(int32_t)chunk->position.z
|
||||
@@ -241,10 +257,11 @@ void mapChunkLoadNext() {
|
||||
MAP.loadQueueCount--;
|
||||
MAP.loadingChunks[slot] = chunk;
|
||||
|
||||
char_t name[64];
|
||||
char_t name[MAP_FILE_PATH_MAX];
|
||||
stringFormat(
|
||||
name, sizeof(name),
|
||||
"chunks/%d_%d_%d.dcf",
|
||||
"maps/%s/chunks/%d_%d_%d.dcf",
|
||||
MAP.name,
|
||||
(int32_t)chunk->position.x,
|
||||
(int32_t)chunk->position.y,
|
||||
(int32_t)chunk->position.z
|
||||
|
||||
@@ -12,12 +12,18 @@
|
||||
|
||||
#define MAP_FILE_PATH_MAX 128
|
||||
|
||||
// Buffer size for a map's name, including the null terminator - so map
|
||||
// names are at most 9 characters.
|
||||
#define MAP_NAME_MAX 10
|
||||
|
||||
// Number of chunks that may be mid-load (asset locked & awaiting onLoaded/
|
||||
// onError) at the same time - everything past this waits in loadQueue.
|
||||
#define MAP_CHUNK_LOAD_CONCURRENCY 2
|
||||
|
||||
typedef struct map_s {
|
||||
bool_t loaded;
|
||||
// Name of the currently loaded map, or an empty string if none is
|
||||
// loaded (see mapIsLoaded).
|
||||
char_t name[MAP_NAME_MAX];
|
||||
|
||||
chunk_t chunks[MAP_CHUNK_COUNT];
|
||||
chunk_t *chunkOrder[MAP_CHUNK_COUNT];
|
||||
@@ -31,19 +37,30 @@ typedef struct map_s {
|
||||
extern map_t MAP;
|
||||
|
||||
/**
|
||||
* Initializes the map.
|
||||
*
|
||||
* Initializes the map subsystem. No map is loaded until mapSetMap is
|
||||
* called.
|
||||
*
|
||||
* @return An error code.
|
||||
*/
|
||||
errorret_t mapInit();
|
||||
|
||||
/**
|
||||
* Checks if a map is loaded.
|
||||
*
|
||||
*
|
||||
* @return true if a map is loaded, false otherwise.
|
||||
*/
|
||||
bool_t mapIsLoaded();
|
||||
|
||||
/**
|
||||
* Sets the active map by name, unloading the previously loaded map (if
|
||||
* any) first, then starts loading the new map's chunks around chunk
|
||||
* position (0, 0, 0).
|
||||
*
|
||||
* @param map The map's name, at most MAP_NAME_MAX - 1 characters.
|
||||
* @return An error code.
|
||||
*/
|
||||
errorret_t mapSetMap(const char_t *map);
|
||||
|
||||
/**
|
||||
* Updates the map.
|
||||
*
|
||||
|
||||
+1
-2
@@ -31,10 +31,9 @@ errorret_t rpgInit(void) {
|
||||
cutsceneSystemInit();
|
||||
errorChain(mapInit());
|
||||
rpgCameraInit();
|
||||
|
||||
|
||||
// Init test world
|
||||
errorChain(mapPositionSet((chunkpos_t){ 0, 0, 0 }));
|
||||
errorChain(mapSetMap("overworld"));
|
||||
|
||||
// The player is the one entity that isn't sourced from map/chunk data -
|
||||
// every other entity (NPCs, items) and map area comes from the loaded
|
||||
|
||||
Reference in New Issue
Block a user