Added story flags
All checks were successful
Build Dusk / run-tests (push) Successful in 1m27s
Build Dusk / build-linux (push) Successful in 1m13s
Build Dusk / build-psp (push) Successful in 1m46s

This commit is contained in:
2026-02-03 15:16:21 -06:00
parent 94e2cc6210
commit 22398ddcef
15 changed files with 292 additions and 8 deletions

View File

@@ -31,10 +31,9 @@ else
inputBind("enter", INPUT_ACTION_ACCEPT)
inputBind("e", INPUT_ACTION_ACCEPT)
inputBind("escape", INPUT_ACTION_CANCEL)
inputBind("q", INPUT_ACTION_CANCEL)
inputBind("z", INPUT_ACTION_RAGEQUIT)
inputBind("escape", INPUT_ACTION_RAGEQUIT)
end
end

View File

@@ -16,7 +16,6 @@ end
function sceneUpdate()
end
function sceneRender()
cameraPushMatrix(camera)

View File

@@ -62,6 +62,7 @@ add_subdirectory(locale)
# add_subdirectory(rpg)
add_subdirectory(scene)
add_subdirectory(script)
add_subdirectory(story)
add_subdirectory(thread)
add_subdirectory(time)
add_subdirectory(ui)

View File

@@ -11,5 +11,6 @@ add_subdirectory(item)
add_subdirectory(locale)
add_subdirectory(system)
add_subdirectory(scene)
add_subdirectory(story)
add_subdirectory(time)
add_subdirectory(ui)

View File

@@ -0,0 +1,10 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
modulestoryflag.c
)

View File

@@ -0,0 +1,109 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "modulestoryflag.h"
#include "assert/assert.h"
#include "story/storyflag.h"
void moduleStoryFlag(scriptcontext_t *context) {
assertNotNull(context, "Script context cannot be NULL");
lua_register(context->luaState, "storyFlagGet", moduleStoryFlagGet);
lua_register(context->luaState, "storyFlagSet", moduleStoryFlagSet);
lua_register(
context->luaState, "storyFlagIncrement", moduleStoryFlagIncrement
);
lua_register(
context->luaState, "storyFlagDecrement", moduleStoryFlagDecrement
);
}
int moduleStoryFlagGet(lua_State *L) {
assertNotNull(L, "Lua state cannot be NULL");
// Require story flag ID argument
if(!lua_isnumber(L, 1)) {
luaL_error(L, "Expected flag ID.");
return 0;
}
storyflag_t flag = (storyflag_t)lua_tointeger(L, 1);
if(flag <= STORY_FLAG_NULL || flag >= STORY_FLAG_COUNT) {
luaL_error(L, "Invalid flag ID %d", flag);
return 0;
}
storyflagvalue_t value = storyFlagGet(flag);
lua_pushinteger(L, value);
return 1;
}
int moduleStoryFlagSet(lua_State *L) {
assertNotNull(L, "Lua state cannot be NULL");
// Require story flag ID argument
if(!lua_isnumber(L, 1)) {
luaL_error(L, "Expected flag ID.");
return 0;
}
// Require story flag value argument
if(!lua_isnumber(L, 2)) {
luaL_error(L, "Expected flag value.");
return 0;
}
storyflag_t flag = (storyflag_t)lua_tointeger(L, 1);
if(flag <= STORY_FLAG_NULL || flag >= STORY_FLAG_COUNT) {
luaL_error(L, "Invalid flag ID %d", flag);
return 0;
}
storyflagvalue_t value = (storyflagvalue_t)lua_tointeger(L, 2);
storyFlagSet(flag, value);
return 0;
}
int moduleStoryFlagIncrement(lua_State *L) {
assertNotNull(L, "Lua state cannot be NULL");
// Require story flag ID argument
if(!lua_isnumber(L, 1)) {
luaL_error(L, "Expected flag ID.");
return 0;
}
storyflag_t flag = (storyflag_t)lua_tointeger(L, 1);
if(flag <= STORY_FLAG_NULL || flag >= STORY_FLAG_COUNT) {
luaL_error(L, "Invalid flag ID %d", flag);
return 0;
}
storyflagvalue_t value = storyFlagGet(flag);
storyFlagSet(flag, value + 1);
return 0;
}
int moduleStoryFlagDecrement(lua_State *L) {
assertNotNull(L, "Lua state cannot be NULL");
// Require story flag ID argument
if(!lua_isnumber(L, 1)) {
luaL_error(L, "Expected flag ID.");
return 0;
}
storyflag_t flag = (storyflag_t)lua_tointeger(L, 1);
if(flag <= STORY_FLAG_NULL || flag >= STORY_FLAG_COUNT) {
luaL_error(L, "Invalid flag ID %d", flag);
return 0;
}
storyflagvalue_t value = storyFlagGet(flag);
storyFlagSet(flag, value - 1);
return 0;
}

View File

@@ -0,0 +1,48 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "script/scriptcontext.h"
/**
* Register story flag module functions to the given script context.
*
* @param context The script context to register story flag module functions to.
*/
void moduleStoryFlag(scriptcontext_t *context);
/**
* Script binding for getting the value of a story flag.
*
* @param L The Lua state.
* @return Number of return values on the Lua stack.
*/
int moduleStoryFlagGet(lua_State *L);
/**
* Script binding for setting the value of a story flag.
*
* @param L The Lua state.
* @return Number of return values on the Lua stack.
*/
int moduleStoryFlagSet(lua_State *L);
/**
* Script binding for incrementing a story flag.
*
* @param L The Lua state.
* @return Number of return values on the Lua stack.
*/
int moduleStoryFlagIncrement(lua_State *L);
/**
* Script binding for decrementing a story flag.
*
* @param L The Lua state.
* @return Number of return values on the Lua stack.
*/
int moduleStoryFlagDecrement(lua_State *L);

View File

@@ -21,6 +21,7 @@
#include "script/module/ui/moduleui.h"
#include "script/module/display/moduletext.h"
#include "script/module/display/modulescreen.h"
#include "script/module/story/modulestoryflag.h"
#include "util/string.h"
const scriptmodule_t SCRIPT_MODULE_LIST[] = {
@@ -39,6 +40,7 @@ const scriptmodule_t SCRIPT_MODULE_LIST[] = {
{ .name = "ui", .callback = moduleUi },
{ .name = "text", .callback = moduleText },
{ .name = "screen", .callback = moduleScreen },
{ .name = "storyflag", .callback = moduleStoryFlag },
};
#define SCRIPT_MODULE_COUNT ( \

18
src/story/CMakeLists.txt Normal file
View File

@@ -0,0 +1,18 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
storyflag.c
)
dusk_run_python(
dusk_story_defs
tools.story.csv
--csv ${CMAKE_CURRENT_SOURCE_DIR}/storyflag.csv
--header-file ${DUSK_GENERATED_HEADERS_DIR}/story/storyflagvalue.h
)
add_dependencies(${DUSK_LIBRARY_TARGET_NAME} dusk_story_defs)

14
src/story/storyflag.c Normal file
View File

@@ -0,0 +1,14 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "storyflag.h"
#include "assert/assert.h"
void storyFlagSet(const storyflag_t flag, const storyflagvalue_t value) {
assertTrue(flag > STORY_FLAG_NULL && flag < STORY_FLAG_COUNT, "Bad Flag");
STORY_FLAG_VALUES[flag] = value;
}

2
src/story/storyflag.csv Normal file
View File

@@ -0,0 +1,2 @@
id,description,initial
test,"Test flag for debugging purposes",1
1 id description initial
2 test Test flag for debugging purposes 1

25
src/story/storyflag.h Normal file
View File

@@ -0,0 +1,25 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "story/storyflagvalue.h"
/**
* Gets the value of a story flag.
*
* @param flag The story flag to get.
* @return The value of the story flag.
*/
#define storyFlagGet(flag) (STORY_FLAG_VALUES[(flag)])
/**
* Sets the value of a story flag.
*
* @param flag The story flag to set.
* @param value The value to set the story flag to.
*/
void storyFlagSet(const storyflag_t flag, const storyflagvalue_t value);

11
src/story/storyflagdefs.h Normal file
View File

@@ -0,0 +1,11 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef uint8_t storyflagvalue_t;

View File

@@ -11,10 +11,6 @@ args = parser.parse_args()
def csvIdToEnumName(itemId):
return "ITEM_ID_" + itemId.upper()
# Load up CSV file.
outHeader = "#pragma once\n"
outHeader += '#include "dusk.h"\n\n'
itemIds = []
itemTypes = []
itemRowById = {}

View File

@@ -0,0 +1,49 @@
import argparse
import os
import csv
from tools.util.type import detectType, stringToCType, typeToCType
parser = argparse.ArgumentParser(description="Story CSV to .h defines")
parser.add_argument("--csv", required=True, help="Path to story CSV file")
parser.add_argument("--header-file", required=True, help="Path to output .h file")
args = parser.parse_args()
def idToEnum(id):
return "STORY_FLAG_" + id.upper().replace(" ", "_")
# Load up CSV file.
outHeader = "#pragma once\n"
outHeader += '#include "story/storyflagdefs.h"\n\n'
with open(args.csv, newline="", encoding="utf-8") as csvfile:
reader = csv.DictReader(csvfile)
# CSV must have id column
if "id" not in reader.fieldnames:
raise Exception("CSV file must have 'id' column")
# Generate enum
outHeader += "typedef enum {\n"
outHeader += " STORY_FLAG_NULL,\n\n"
for row in reader:
id = idToEnum(row["id"].strip())
outHeader += f" {id},\n"
outHeader += "\n STORY_FLAG_COUNT\n"
outHeader += "} storyflag_t;\n\n"
# Generate flag values
csvfile.seek(0)
reader = csv.DictReader(csvfile)
outHeader += "static storyflagvalue_t STORY_FLAG_VALUES[STORY_FLAG_COUNT] = {\n"
for row in reader:
id = idToEnum(row["id"].strip())
initial = row.get("initial", "0").strip() or "0"
outHeader += f" [{id}] = {initial},\n"
outHeader += "};\n"
os.makedirs(os.path.dirname(args.header_file), exist_ok=True)
# Write header
with open(args.header_file, "w", encoding="utf-8") as headerFile:
headerFile.write(outHeader)