Map exec
Build Dusk / build-linux (push) Successful in 1m40s
Build Dusk / build-psp (push) Failing after 1m38s

This commit is contained in:
YourWishes committed 2025-12-26 20:38:24 +10:00
1 parent 7940f4c487
commit 726233e55f
29 files changed
+149 -30

No files matched your search

+2
View File
@@ -1,6 +1,7 @@
module('platform')
module('input')
module('scene')
module('map')
-- Default Input bindings.
if PLATFORM == "psp" then
@@ -38,3 +39,4 @@ else
end
sceneSet('map')
mapLoad('map/testmap/testmap.dmf')
+1 -1
View File
@@ -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)
-3
View File
@@ -1,3 +0,0 @@
{
"mapName": "Test"
}
+7
View File
@@ -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.
+3
View File
@@ -0,0 +1,3 @@
{
"name": "Test"
}
+1
View File
@@ -0,0 +1 @@
print('Test Map Script Run')
+1 -1
View File
@@ -1 +1 @@
print('map')
-- Map Scene
+1 -1
View File
@@ -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
View File
@@ -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
+3
View File
@@ -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;
+49
View File
@@ -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);
}
+2
View File
@@ -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 ( \
+11
View File
@@ -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,
+10
View File
@@ -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.
*
+16 -15
View File
@@ -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)
# Map file
outBuffer = bytearray()
outBuffer.extend(b'DMF')
outBuffer.extend(len(chunkFiles).to_bytes(4, 'little'))
# 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'])
# 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
View File
@@ -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()
+10 -3
View File
@@ -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,10 +130,16 @@ 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():