Map exec
This commit is contained in:
1 parent
7940f4c487
commit
726233e55f
29 files changed
+152
-33
No files matched your search
+3
-1
@@ -1,6 +1,7 @@
|
||||
module('platform')
|
||||
module('input')
|
||||
module('scene')
|
||||
module('map')
|
||||
|
||||
-- Default Input bindings.
|
||||
if PLATFORM == "psp" then
|
||||
@@ -37,4 +38,5 @@ else
|
||||
end
|
||||
end
|
||||
|
||||
sceneSet('map')
|
||||
sceneSet('map')
|
||||
mapLoad('map/testmap/testmap.dmf')
|
||||
@@ -3,4 +3,4 @@
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
add_asset(MAP map.json)
|
||||
add_subdirectory(testmap)
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"mapName": "Test"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# Copyright (c) 2025 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
add_asset(MAP testmap.json)
|
||||
add_asset(SCRIPT testmap.lua)
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"name": "Test"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
print('Test Map Script Run')
|
||||
@@ -1 +1 @@
|
||||
print('map')
|
||||
-- Map Scene
|
||||
@@ -89,5 +89,5 @@ static const assettypedef_t ASSET_TYPE_DEFINITIONS[ASSET_TYPE_COUNT] = {
|
||||
.header = "DSF",
|
||||
.loadStrategy = ASSET_LOAD_STRAT_CUSTOM,
|
||||
.custom = assetScriptHandler
|
||||
}
|
||||
},
|
||||
};
|
||||
+28
-2
@@ -11,6 +11,7 @@
|
||||
#include "asset/asset.h"
|
||||
#include "rpg/entity/entity.h"
|
||||
#include "util/string.h"
|
||||
#include "script/scriptcontext.h"
|
||||
|
||||
map_t MAP;
|
||||
|
||||
@@ -44,6 +45,19 @@ errorret_t mapLoad(const char_t *path, const chunkpos_t position) {
|
||||
// Store the map file path
|
||||
stringCopy(MAP.filePath, path, MAP_FILE_PATH_MAX);
|
||||
|
||||
// Determine directory path (it is dirname)
|
||||
stringCopy(MAP.dirPath, path, MAP_FILE_PATH_MAX);
|
||||
char_t *last = stringFindLastChar(MAP.dirPath, '/');
|
||||
if(last == NULL) errorThrow("Invalid map file path");
|
||||
|
||||
// Store filename, sans extension
|
||||
stringCopy(MAP.fileName, last + 1, MAP_FILE_PATH_MAX);
|
||||
*last = '\0'; // Terminate to get directory path
|
||||
|
||||
last = stringFindLastChar(MAP.fileName, '.');
|
||||
if(last == NULL) errorThrow("Map file name has no extension");
|
||||
*last = '\0'; // Terminate to remove extension
|
||||
|
||||
// Reset map position
|
||||
MAP.chunkPosition = position;
|
||||
|
||||
@@ -64,6 +78,18 @@ errorret_t mapLoad(const char_t *path, const chunkpos_t position) {
|
||||
}
|
||||
|
||||
// Execute map script.
|
||||
char_t scriptPath[MAP_FILE_PATH_MAX + 16];
|
||||
stringFormat(
|
||||
scriptPath, sizeof(scriptPath), "%s/%s.dsf",
|
||||
MAP.dirPath, MAP.fileName
|
||||
);
|
||||
if(assetFileExists(scriptPath)) {
|
||||
scriptcontext_t ctx;
|
||||
errorChain(scriptContextInit(&ctx));
|
||||
errorChain(scriptContextExecFile(&ctx, scriptPath));
|
||||
scriptContextDispose(&ctx);
|
||||
}
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
@@ -183,8 +209,8 @@ errorret_t mapChunkLoad(chunk_t* chunk) {
|
||||
memorySet(chunk->entities, 0xFF, sizeof(chunk->entities));
|
||||
|
||||
// Get chunk filepath.
|
||||
snprintf(buffer, sizeof(buffer), "%s/%d_%d_%d.dcf",
|
||||
MAP.filePath,
|
||||
snprintf(buffer, sizeof(buffer), "%s/chunks/%d_%d_%d.dcf",
|
||||
MAP.dirPath,
|
||||
chunk->position.x,
|
||||
chunk->position.y,
|
||||
chunk->position.z
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
|
||||
typedef struct map_s {
|
||||
char_t filePath[MAP_FILE_PATH_MAX];
|
||||
char_t dirPath[MAP_FILE_PATH_MAX];
|
||||
char_t fileName[MAP_FILE_PATH_MAX];
|
||||
|
||||
chunk_t chunks[MAP_CHUNK_COUNT];
|
||||
chunk_t *chunkOrder[MAP_CHUNK_COUNT];
|
||||
chunkpos_t chunkPosition;
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "script/scriptcontext.h"
|
||||
#include "debug/debug.h"
|
||||
#include "assert/assert.h"
|
||||
#include "rpg/world/map.h"
|
||||
|
||||
int32_t moduleMapLoad(lua_State *L) {
|
||||
assertNotNull(L, "Lua state cannot be NULL");
|
||||
|
||||
if(!lua_isstring(L, 1)) {
|
||||
luaL_error(L, "Expected string map filename");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Potentially provide up to 3 params
|
||||
chunkpos_t initial = { .x = 0, .y = 0, .z = 0 };
|
||||
if(lua_isnumber(L, 2)) {
|
||||
initial.x = (chunkunit_t)luaL_checkinteger(L, 2);
|
||||
}
|
||||
if(lua_isnumber(L, 3)) {
|
||||
initial.y = (chunkunit_t)luaL_checkinteger(L, 3);
|
||||
}
|
||||
if(lua_isnumber(L, 4)) {
|
||||
initial.z = (chunkunit_t)luaL_checkinteger(L, 4);
|
||||
}
|
||||
|
||||
// Load the map.
|
||||
errorret_t ret = mapLoad(luaL_checkstring(L, 1), initial);
|
||||
if(ret.code != ERROR_OK) {
|
||||
luaL_error(L, "Failed to load map");
|
||||
errorCatch(errorPrint(ret));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void moduleMapSystem(scriptcontext_t *context) {
|
||||
assertNotNull(context, "Script context cannot be NULL");
|
||||
|
||||
scriptContextRegFunc(context, "mapLoad", moduleMapLoad);
|
||||
}
|
||||
@@ -10,12 +10,14 @@
|
||||
#include "script/module/moduleinput.h"
|
||||
#include "script/module/moduleplatform.h"
|
||||
#include "script/module/modulescene.h"
|
||||
#include "script/module/modulemap.h"
|
||||
|
||||
const scriptmodule_t SCRIPT_MODULE_LIST[] = {
|
||||
{ .name = "system", .callback = moduleSystem },
|
||||
{ .name = "input", .callback = moduleInput },
|
||||
{ .name = "platform", .callback = modulePlatform },
|
||||
{ .name = "scene", .callback = moduleScene },
|
||||
{ .name = "map", .callback = moduleMapSystem },
|
||||
};
|
||||
|
||||
#define SCRIPT_MODULE_COUNT ( \
|
||||
|
||||
@@ -57,6 +57,17 @@ char_t * stringToken(char_t *str, const char_t *delim) {
|
||||
return strtok(str, delim);
|
||||
}
|
||||
|
||||
char_t * stringFindLastChar(const char_t *str, const char_t c) {
|
||||
assertNotNull(str, "str must not be NULL");
|
||||
char_t *last = NULL;
|
||||
for(const char_t *p = str; *p != '\0'; p++) {
|
||||
if(*p == c) {
|
||||
last = (char_t *)p;
|
||||
}
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
int32_t stringFormat(
|
||||
char_t *dest,
|
||||
const size_t destSize,
|
||||
|
||||
@@ -64,6 +64,16 @@ void stringTrim(char_t *str);
|
||||
*/
|
||||
char_t * stringToken(char_t *str, const char_t *delim);
|
||||
|
||||
/**
|
||||
* Finds the last occurrence of a character in a string.
|
||||
*
|
||||
* @param str The string to search.
|
||||
* @param c The character to find.
|
||||
* @return A pointer to the last occurrence of the character in the string, or
|
||||
* NULL if not found.
|
||||
*/
|
||||
char_t * stringFindLastChar(const char_t *str, const char_t c);
|
||||
|
||||
/**
|
||||
* Formats a string.
|
||||
*
|
||||
|
||||
@@ -111,11 +111,11 @@ def processMap(asset):
|
||||
|
||||
map = Map(None)
|
||||
map.load(asset['path'])
|
||||
dir = map.getMapDirectory()
|
||||
chunksDir = map.getChunkDirectory()
|
||||
|
||||
files = os.listdir(dir)
|
||||
files = os.listdir(chunksDir)
|
||||
if len(files) == 0:
|
||||
print(f"Error: No chunk files found in map directory {dir}.")
|
||||
print(f"Error: No chunk files found in {chunksDir}.")
|
||||
sys.exit(1)
|
||||
|
||||
chunkFiles = []
|
||||
@@ -133,21 +133,22 @@ def processMap(asset):
|
||||
result = processChunk(chunk)
|
||||
chunkFiles.extend(result['files'])
|
||||
|
||||
outMap = {
|
||||
'files': chunkFiles
|
||||
}
|
||||
return assetCache(asset['path'], outMap)
|
||||
|
||||
# List files
|
||||
chunkFiles = []
|
||||
for fileName in os.listdir(asset['path']):
|
||||
if not fileName.endswith('.json'):
|
||||
continue
|
||||
result = processChunk(os.path.join(asset['path'], fileName))
|
||||
chunkFiles.extend(result['files'])
|
||||
# Map file
|
||||
outBuffer = bytearray()
|
||||
outBuffer.extend(b'DMF')
|
||||
outBuffer.extend(len(chunkFiles).to_bytes(4, 'little'))
|
||||
|
||||
# DMF (Dusk Map file)
|
||||
fileRelative = getAssetRelativePath(asset['path'])
|
||||
fileNameWithoutExt = os.path.splitext(os.path.basename(fileRelative))[0]
|
||||
outputMapRelative = os.path.join(os.path.dirname(fileRelative), f"{fileNameWithoutExt}.dmf")
|
||||
outputMapPath = os.path.join(args.output_assets, outputMapRelative)
|
||||
os.makedirs(os.path.dirname(outputMapPath), exist_ok=True)
|
||||
with open(outputMapPath, "wb") as f:
|
||||
f.write(outBuffer)
|
||||
|
||||
outMap = {
|
||||
'files': chunkFiles
|
||||
}
|
||||
|
||||
outMap['files'].append(outputMapPath)
|
||||
return assetCache(asset['path'], outMap)
|
||||
+4
-4
@@ -131,12 +131,12 @@ class Chunk:
|
||||
return self.dirty
|
||||
|
||||
def getFilename(self):
|
||||
if not self.map or not hasattr(self.map, 'getMapDirectory'):
|
||||
if not self.map or not hasattr(self.map, 'getChunkDirectory'):
|
||||
return None
|
||||
dir_path = self.map.getMapDirectory()
|
||||
if dir_path is None:
|
||||
dirPath = self.map.getChunkDirectory()
|
||||
if dirPath is None:
|
||||
return None
|
||||
return f"{dir_path}/{self.x}_{self.y}_{self.z}.json"
|
||||
return f"{dirPath}/{self.x}_{self.y}_{self.z}.json"
|
||||
|
||||
def draw(self):
|
||||
self.vertexBuffer.draw()
|
||||
|
||||
+11
-4
@@ -1,4 +1,5 @@
|
||||
import json
|
||||
import sys
|
||||
from dusk.event import Event
|
||||
from PyQt5.QtWidgets import QFileDialog, QMessageBox
|
||||
from PyQt5.QtCore import QTimer
|
||||
@@ -129,11 +130,17 @@ class Map:
|
||||
return self.mapFileName if self.mapFileName and os.path.exists(self.mapFileName) else None
|
||||
|
||||
def getMapDirectory(self):
|
||||
fname = self.getMapFilename()
|
||||
if not fname or not fname.endswith('.json'):
|
||||
if self.mapFileName is None:
|
||||
return None
|
||||
return fname[:-5] # Remove '.json' extension
|
||||
|
||||
dirname = os.path.dirname(self.mapFileName)
|
||||
return dirname
|
||||
|
||||
def getChunkDirectory(self):
|
||||
dirName = self.getMapDirectory()
|
||||
if dirName is None:
|
||||
return None
|
||||
return os.path.join(dirName, 'chunks')
|
||||
|
||||
def anyChunksDirty(self):
|
||||
for chunk in self.chunks.values():
|
||||
if chunk.isDirty():
|
||||
|
||||
Reference in new issue
Block a user