From 256d7764bb1023aceef4d8bac4079b2d61e0b800 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 15 Dec 2024 16:39:59 +0100 Subject: [PATCH 01/11] allow cmake configuration with -DWITHOUT_LUA=1 --- CMakeLists.txt | 20 ++++++++++---- CMakeSettings.json | 4 +-- src/CMakeLists.txt | 64 ++++++++++++++++++++++++------------------- src/bind_eressea.c | 15 +--------- src/console.c | 2 +- src/gmtool.c | 17 ++++++++++-- src/helpers.c | 65 ++++++++++++++------------------------------ src/laws.c | 39 +++++++++++++++++++++++--- src/magic.c | 9 ++++-- src/main.c | 19 +++++++++++-- src/orderfile.c | 23 ++++++++++++++++ src/orderfile.h | 1 + src/processing.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++ src/processing.h | 3 ++ 14 files changed, 242 insertions(+), 107 deletions(-) create mode 100644 src/processing.c create mode 100644 src/processing.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c5a258519..2756e74d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,11 @@ endif (WIN32) project (server C) set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") +SET (USE_LUA TRUE) +if (WITHOUT_LUA) +SET (USE_LUA FALSE) +endif (WITHOUT_LUA) + if (MSVC) find_package (PDCurses) if (NOT PDCURSES_FOUND) @@ -33,9 +38,18 @@ if (NOT CURSES_FOUND) endif (NOT CURSES_FOUND) find_package (EXPAT REQUIRED) -find_package (Lua 5.2 REQUIRED) find_package (Utf8Proc REQUIRED) +if (USE_LUA) +find_package (Lua 5.2 REQUIRED) +endif(USE_LUA) + +if (LUA_FOUND) +find_program(TOLUA_EXECUTABLE tolua REQUIRED) +find_library(TOLUA_LIBRARY tolua REQUIRED) +find_path(TOLUA_INCLUDE_DIR NAMES tolua.h HINTS ${LUA_INCLUDE_DIR} REQUIRED) +endif (LUA_FOUND) + find_library(SQLITE3_LIBRARY sqlite3 REQUIRED) find_path(SQLITE3_INCLUDE_DIR NAMES sqlite3.h REQUIRED) @@ -45,10 +59,6 @@ find_path(CJSON_INCLUDE_DIR NAMES cJSON.h PATH_SUFFIXES cjson REQUIRED) find_library(INIPARSER_LIBRARY iniparser REQUIRED) find_path(INIPARSER_INCLUDE_DIR NAMES iniparser.h PATH_SUFFIXES iniparser REQUIRED) -find_program(TOLUA_EXECUTABLE tolua REQUIRED) -find_library(TOLUA_LIBRARY tolua REQUIRED) -find_path(TOLUA_INCLUDE_DIR NAMES tolua.h HINTS ${LUA_INCLUDE_DIR} REQUIRED) - if (MSVC) set (HAVE_STRDUP 0) set (HAVE_STRLCAT 0) diff --git a/CMakeSettings.json b/CMakeSettings.json index fd080fc01..bf3f8152b 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -7,7 +7,7 @@ "inheritEnvironments": [ "msvc_x64_x64" ], "buildRoot": "${projectDir}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", - "cmakeCommandArgs": "", + "cmakeCommandArgs": "-DWITHOUT_LUA=1", "buildCommandArgs": "-v", "ctestCommandArgs": "", "variables": [ @@ -77,4 +77,4 @@ "cmakeToolchain": "${env.VCPKG_ROOT}\\scripts\\buildsystems\\vcpkg.cmake" } ] -} +} \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f71b8cc6a..e4045f64c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,25 +41,17 @@ add_subdirectory(triggers) add_subdirectory(modules) add_subdirectory(races) -macro(ADD_LUA_MODULE MODULE_NAME FILES) - add_library (${MODULE_NAME} SHARED ${FILES}) - set_target_properties(${MODULE_NAME} - PROPERTIES - PREFIX "" +if (TOLUA_EXECUTABLE) + set (_TOLUA_FILES + log.pkg.c + locale.pkg.c + config.pkg.c + process.pkg.c + game.pkg.c + eressea.pkg.c + settings.pkg.c ) -endmacro(ADD_LUA_MODULE) - -set (_TOLUA_FILES - log.pkg.c - locale.pkg.c - config.pkg.c - process.pkg.c - game.pkg.c - eressea.pkg.c - settings.pkg.c -) -if (TOLUA_EXECUTABLE) macro(TOLUA_BINDING _NAME _FILES) set(_PKGFILE ${_NAME}.pkg) set(_SRCFILE ${_PKGFILE}.c) @@ -154,11 +146,12 @@ set(CHECK_SRC checker.c ) +if (LUA_FOUND) set(SERVER_SRC bind_building.c - bind_config.c bind_eressea.c bind_faction.c + bind_gmtool.c bind_locale.c bind_message.c bind_monsters.c @@ -172,18 +165,26 @@ set(SERVER_SRC bindings.c console.c helpers.c - signals.c - main.c - ) +) +else(LUA_FOUND) +set(SERVER_SRC + processing.c +) +endif(LUA_FOUND) if (CURSES_FOUND) set (SERVER_SRC ${SERVER_SRC} - bind_gmtool.c + bind_config.c gmtool.c listbox.c ) endif(CURSES_FOUND) +set (SERVER_SRC ${SERVER_SRC} + main.c + signals.c +) + add_library(version STATIC ${VERSION_SRC}) if(DEFINED ERESSEA_VERSION) target_compile_definitions(version PRIVATE ERESSEA_VERSION="${ERESSEA_VERSION}") @@ -216,20 +217,26 @@ endif (HAVE_LIBM) add_library(game ${ERESSEA_SRC}) target_include_directories (game PUBLIC ${INIPARSER_INCLUDE_DIR}) -target_include_directories (game PUBLIC ${TOLUA_INCLUDE_DIR}) -target_include_directories (game PUBLIC ${LUA_INCLUDE_DIR}) target_link_libraries(game ${EXTRA_LIBS} parser version) add_executable(eressea ${SERVER_SRC}) target_link_libraries(eressea game - ${TOLUA_LIBRARY} - ${LUA_LIBRARIES} ${STORAGE_LIBRARIES} ${CJSON_LIBRARY} ${INIPARSER_LIBRARY} ) +if (LUA_FOUND) +target_compile_definitions(game PRIVATE HAVE_LUA) +target_compile_definitions(eressea PRIVATE HAVE_LUA) +target_include_directories (game PUBLIC ${TOLUA_INCLUDE_DIR}) +target_include_directories (game PUBLIC ${LUA_INCLUDE_DIR}) +target_link_libraries(eressea + ${TOLUA_LIBRARY} + ${LUA_LIBRARIES} +) + add_test(NAME lua-core COMMAND eressea -v1 ../scripts/run-tests.lua WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests) @@ -242,6 +249,7 @@ add_test(NAME lua-e3 COMMAND eressea -v1 ../scripts/run-tests-e3.lua WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests) set_property(TEST lua-e3 PROPERTY RUN_SERIAL) +set_tests_properties(lua-core lua-e2 lua-e3 PROPERTIES LABELS "lua;ci-only") find_program(LUAROCKS_EXECUTABLE luarocks) if(LUAROCKS_EXECUTABLE) @@ -252,7 +260,7 @@ string(REPLACE ";" "\;" LUA_CPATH "${LR_CPATH}") set_tests_properties(lua-core lua-e2 lua-e3 PROPERTIES ENVIRONMENT "LUA_PATH=${LUA_PATH};LUA_CPATH=${LUA_CPATH}") endif(LUAROCKS_EXECUTABLE) -set_tests_properties(lua-core lua-e2 lua-e3 PROPERTIES LABELS "lua;ci-only") +endif (LUA_FOUND) set(TESTS_SRC alchemy.test.c @@ -362,7 +370,7 @@ target_compile_definitions(game PRIVATE USE_SQLITE) if (READLINE_FOUND) target_include_directories (eressea PRIVATE ${READLINE_INCLUDE_DIR}) target_link_libraries(eressea ${READLINE_LIBRARY}) -target_compile_definitions(eressea PRIVATE DUSE_READLINE) +target_compile_definitions(eressea PRIVATE USE_READLINE) endif (READLINE_FOUND) if (CURSES_FOUND) diff --git a/src/bind_eressea.c b/src/bind_eressea.c index ba2e65a7f..6f7507775 100755 --- a/src/bind_eressea.c +++ b/src/bind_eressea.c @@ -41,20 +41,7 @@ int eressea_write_game(const char * filename) { } int eressea_read_orders(const char * filename) { - if (filename) { - FILE *F = fopen(filename, "r"); - int result; - - if (!F) { - perror(filename); - return -1; - } - log_info("reading orders from %s", filename); - result = parseorders(F); - fclose(F); - return result; - } - return -1; + return readorders(filename); } int eressea_export_json(const char * filename, int flags) { diff --git a/src/console.c b/src/console.c index 1d982da21..0838aa269 100644 --- a/src/console.c +++ b/src/console.c @@ -24,7 +24,7 @@ #define lua_strlen(L, idx) lua_rawlen(L, idx) #endif -#ifdef LUA_USE_READLINE +#ifdef USE_READLINE #include #include #include diff --git a/src/gmtool.c b/src/gmtool.c index 3a7b70c75..b1b6df05f 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -2,8 +2,10 @@ #define _CRT_SECURE_NO_WARNINGS #endif #include +#ifdef USE_LUA #include - +#include "console.h" +#endif #include "gmtool.h" #include @@ -30,7 +32,6 @@ #include "util/rng.h" #include "gmtool_structs.h" -#include "console.h" #include "listbox.h" #include "teleport.h" @@ -1098,12 +1099,14 @@ static bool confirm(WINDOW * win, const char *q) { static int exec_key_binding(int keycode) { +#ifdef USE_LUA struct lua_State* L = global.vm_state; lua_getglobal(L, "gmtool_on_keypressed"); if (lua_isfunction(L, -1)) { lua_pushinteger(L, keycode); return lua_pcall(L, 1, 1, 0); } +#endif return -1; } @@ -1475,6 +1478,7 @@ static void handlekey(state * st, int c) } while (c == 0); break; case 'L': +#ifdef USE_LUA if (global.vm_state) { move(0, 0); refresh(); @@ -1485,6 +1489,9 @@ static void handlekey(state * st, int c) st->wnd_status->update |= 1; st->wnd_map->update |= 3; } +#else + beep(); +#endif break; case 12: /* Ctrl-L */ clear(); @@ -1743,7 +1750,9 @@ void run_mapper(void) init_curses(); curs_set(1); +#ifdef USE_LUA set_readline(curses_readline); +#endif assert(stdscr); getbegyx(stdscr, x, y); width = getmaxx(stdscr); @@ -1826,7 +1835,9 @@ void run_mapper(void) handlekey(st, c); } g_quit = 0; +#ifdef USE_LUA set_readline(NULL); +#endif curs_set(1); endwin(); /* FIXME: reset logging @@ -1838,6 +1849,7 @@ void run_mapper(void) } +#ifdef USE_LUA int curses_readline(struct lua_State *L, char *buffer, size_t size, const char *prompt) @@ -1846,6 +1858,7 @@ curses_readline(struct lua_State *L, char *buffer, size_t size, askstring(hstatus, prompt, buffer, size); return buffer[0] != 0; } +#endif void seed_players(newfaction **players, bool new_island) { diff --git a/src/helpers.c b/src/helpers.c index f4e45817c..6437b4e07 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -7,7 +7,6 @@ #include #include -#include #include #include #include @@ -263,58 +262,34 @@ lua_changeresource(unit * u, const struct resource_type *rtype, int delta) /** callback for an item-use function written in lua. */ static int lua_use_item(unit *u, const item_type *itype, const char * fname, int amount, struct order *ord) -{ - lua_State *L = (lua_State *)global.vm_state; - - lua_getglobal(L, fname); - if (lua_isfunction(L, -1)) { - tolua_pushusertype(L, (void *)u, "unit"); - lua_pushinteger(L, amount); - lua_pushstring(L, getstrtoken()); - tolua_pushusertype(L, (void *)ord, "order"); - if (lua_pcall(L, 4, 1, 0) != 0) { - const char *error = lua_tostring(L, -1); - log_error("use(%s) calling '%s': %s.\n", unitname(u), fname, error); - } - else { - int result = (int)lua_tonumber(L, -1); - lua_pop(L, 1); - return result; - } - } - else { - log_error("use_item(%s) calling '%s': not a function.\n", unitname(u), fname); - } - lua_pop(L, 1); - return EUNUSABLE; -} - -static int -use_item_callback(unit *u, const item_type *itype, int amount, struct order *ord) { int len; char fname[64]; len = snprintf(fname, sizeof(fname), "use_%s", itype->rtype->_name); if (len > 0 && (size_t)len < sizeof(fname)) { - int(*callout)(unit *, const item_type *, int, struct order *); - - /* check if we have a register_item_use function */ - callout = (int(*)(unit *, const item_type *, int, struct order *))get_function(fname); - if (callout) { - return callout(u, itype, amount, ord); + lua_State *L = (lua_State *)global.vm_state; + lua_getglobal(L, fname); + if (lua_isfunction(L, -1)) { + tolua_pushusertype(L, (void *)u, "unit"); + lua_pushinteger(L, amount); + lua_pushstring(L, getstrtoken()); + tolua_pushusertype(L, (void *)ord, "order"); + if (lua_pcall(L, 4, 1, 0) != 0) { + const char *error = lua_tostring(L, -1); + log_error("use(%s) calling '%s': %s.\n", unitname(u), fname, error); + } + else { + int result = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + return result; + } } - - /* if the item is a potion, try use_potion, - * the generic function for potions that add an effect: */ - if (itype->flags & ITF_POTION) { - return use_potion(u, itype, amount, ord); + else { + log_error("use_item(%s) calling '%s': not a function.\n", unitname(u), fname); } - - /* finally, check if we have a matching lua function */ - return lua_use_item(u, itype, fname, amount, ord); + lua_pop(L, 1); } - return EUNUSABLE; } @@ -357,7 +332,7 @@ void register_tolua_helpers(void) callbacks.equip_unit = lua_equipunit; callbacks.cast_spell = lua_callspell; - callbacks.use_item = use_item_callback; + callbacks.use_item = lua_use_item; callbacks.produce_resource = produce_resource_lua; callbacks.limit_resource = limit_resource_lua; diff --git a/src/laws.c b/src/laws.c index bb32248aa..8797cf6a3 100644 --- a/src/laws.c +++ b/src/laws.c @@ -34,11 +34,13 @@ /* kernel includes */ #include "kernel/alliance.h" #include "kernel/ally.h" +#include +#include "kernel/building.h" #include "kernel/calendar.h" #include "kernel/callbacks.h" #include "kernel/connection.h" #include "kernel/curse.h" -#include "kernel/building.h" +#include #include "kernel/faction.h" #include "kernel/group.h" #include "kernel/item.h" @@ -58,9 +60,8 @@ #include "kernel/unit.h" /* util includes */ -#include #include -#include +#include #include #include "util/keyword.h" #include @@ -3011,6 +3012,36 @@ void new_units(void) } } +static int callback_use(unit *u, const item_type *itype, int amount, struct order *ord) +{ + int len; + char fname[64]; + + /* if the item is a potion, try use_potion, + * the generic function for potions that add an effect: + */ + if (itype->flags & ITF_POTION) { + return use_potion(u, itype, amount, ord); + } + + len = snprintf(fname, sizeof(fname), "use_%s", itype->rtype->_name); + if (len > 0 && (size_t)len < sizeof(fname)) { + int(*callout)(unit *, const item_type *, int, struct order *); + + /* check if we have a register_item_use function */ + callout = (int(*)(unit *, const item_type *, int, struct order *))get_function(fname); + if (callout) { + return callout(u, itype, amount, ord); + } + } + /* finally, check if we have a matching lua function */ + if (callbacks.use_item) { + return callbacks.use_item(u, itype, amount, ord); + } + + return EUNUSABLE; +} + static int use_item(unit * u, const item_type * itype, int amount, struct order *ord) { int i; @@ -3025,7 +3056,7 @@ static int use_item(unit * u, const item_type * itype, int amount, struct order } if (itype->flags & ITF_CANUSE) { - int result = callbacks.use_item(u, itype, amount, ord); + int result = callback_use(u, itype, amount, ord); if (result > 0) { use_pooled(u, itype->rtype, GET_DEFAULT, result); } diff --git a/src/magic.c b/src/magic.c index 85a0dd484..485effdce 100644 --- a/src/magic.c +++ b/src/magic.c @@ -2942,11 +2942,14 @@ int cast_spell(struct castorder *co) } fun = get_spellcast(sp->sname); - if (!fun) { - log_debug("no spell function for %s, try callback", sp->sname); + if (fun) { + return fun(co); + } + log_debug("no spell function for %s, try callback", sp->sname); + if (callbacks.cast_spell) { return callbacks.cast_spell(co, fname); } - return fun(co); + return -1; } const char *magic_name(magic_t mtype, const struct locale *lang) diff --git a/src/main.c b/src/main.c index 207dface9..effee575b 100644 --- a/src/main.c +++ b/src/main.c @@ -17,10 +17,13 @@ #ifdef USE_CURSES #include "gmtool.h" #endif - -#include "signals.h" +#ifdef USE_LUA #include "bindings.h" +#else +#include "processing.h" +#endif +#include "signals.h" #include #include @@ -273,8 +276,10 @@ void locale_init(void) int main(int argc, char **argv) { - int err = 0; +#ifdef USE_LUA lua_State *L; +#endif + int err = 0; dictionary *d = NULL; setup_signal_handler(); message_handle_missing(MESSAGE_MISSING_REPLACE); @@ -290,16 +295,24 @@ int main(int argc, char **argv) locale_init(); +#ifdef USE_LUA L = lua_init(d); +#endif game_init(); +#ifdef USE_LUA bind_monsters(L); err = eressea_run(L, luafile); if (err) { log_error("script %s failed with code %d\n", luafile, err); return err; } +#else + run_turn(); +#endif game_done(); +#ifdef USE_LUA lua_done(L); +#endif log_close(); stats_write(stdout, ""); stats_close(); diff --git a/src/orderfile.c b/src/orderfile.c index 74d2e0860..dd6881da5 100644 --- a/src/orderfile.c +++ b/src/orderfile.c @@ -1,3 +1,8 @@ +#ifdef _MSC_VER +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif +#endif #include "orderfile.h" #include "kernel/calendar.h" @@ -195,3 +200,21 @@ int parseorders(FILE *F) parser_free(parser); return err; } + +int readorders(const char *filename) +{ + if (filename) { + FILE *F = fopen(filename, "r"); + int result; + + if (!F) { + perror(filename); + return -1; + } + log_info("reading orders from %s", filename); + result = parseorders(F); + fclose(F); + return result; + } + return -1; +} diff --git a/src/orderfile.h b/src/orderfile.h index fd59ca29e..ce9545cb8 100644 --- a/src/orderfile.h +++ b/src/orderfile.h @@ -28,3 +28,4 @@ void parser_set_unit(parser_state *state, struct unit *u); void parser_set_faction(parser_state *state, struct faction *f); int parseorders(FILE* F); +int readorders(const char *filename); diff --git a/src/processing.c b/src/processing.c new file mode 100644 index 000000000..e12fa5af8 --- /dev/null +++ b/src/processing.c @@ -0,0 +1,68 @@ +#include "processing.h" + +#include "bind_config.h" +#include "eressea.h" +#include "laws.h" +#include "orderfile.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +void run_turn(void) +{ + char path[PATH_MAX]; + const char *install_path = config_get("config.install"); + const char *rules = config_get("config.rules"); + int lastturn; + /* + * TODO: + * lua_changeresource replacement (see resources.lua) + * default equipment sets (see equipment.lua) + * replace the lua callbacks in helpers.c (see callbacks.h) + * spells that have lua-only implmentations (see spells.lua) + */ + + if (0 != config_read( + path_join(path_join("conf", rules, path, sizeof(path)), "config.json", path, sizeof(path)), + install_path)) + { + log_fatal("could not read JSON data"); + } + free_gamedata(); + init_resources(); + init_locales(init_locale); + + lastturn = turn; + if (lastturn < 0) { + lastturn = current_turn(); + } + turn = lastturn; + snprintf(path, sizeof(path), "%d.dat", turn); + if (0 != readgame(path)) { + log_fatal("could not read game data %s", path); + } + turn_begin(); + // plan_monsters(); + + snprintf(path, sizeof(path), "orders.%d", turn); + if (0 != readorders(path)) { + log_fatal("could not read game data %s", path); + } + turn_process(); + + turn_end(); + remove_empty_factions(); + snprintf(path, sizeof(path), "%d.dat", turn); + if (0 != writegame(path)) { + log_fatal("could not write game data %s", path); + } +} diff --git a/src/processing.h b/src/processing.h new file mode 100644 index 000000000..40863b602 --- /dev/null +++ b/src/processing.h @@ -0,0 +1,3 @@ +#pragma once + +void run_turn(void); From f5a7fb7154c82e791743e7ae0da43b0b0fc61abf Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 15 Dec 2024 16:51:08 +0100 Subject: [PATCH 02/11] rename preprocessor variables use HAVE_* consistenly --- CMakeLists.txt | 8 ++++---- README.md | 6 ++++++ src/CMakeLists.txt | 5 ++--- src/bindings.c | 2 +- src/console.c | 2 +- src/gmtool.c | 12 ++++++------ src/helpers.c | 13 +++++++------ src/main.c | 16 ++++++++-------- 8 files changed, 35 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2756e74d0..32de904fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,9 +11,9 @@ endif (WIN32) project (server C) set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") -SET (USE_LUA TRUE) +SET (USING_LUA TRUE) if (WITHOUT_LUA) -SET (USE_LUA FALSE) +SET (USING_LUA FALSE) endif (WITHOUT_LUA) if (MSVC) @@ -40,9 +40,9 @@ endif (NOT CURSES_FOUND) find_package (EXPAT REQUIRED) find_package (Utf8Proc REQUIRED) -if (USE_LUA) +if (USING_LUA) find_package (Lua 5.2 REQUIRED) -endif(USE_LUA) +endif(USING_LUA) if (LUA_FOUND) find_program(TOLUA_EXECUTABLE tolua REQUIRED) diff --git a/README.md b/README.md index e72cd4ae7..84d36cd59 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,12 @@ install all of them: liblua5.2-dev libtolua-dev libncurses5-dev libsqlite3-dev \ libcjson-dev libiniparser-dev libexpat1-dev libutf8proc-dev +If your system for some reason doesn't have Lua or the tolua library, +you can run cmake with -DWITHOUT_LUA=1 to build the server without the +Lua extensions. This is very much untested, and it breaks any items +or spells that have their actions implemented as Lua scripts, as well +as the Lua integration tests. + ## How to check out and build the Eressea server This repository relies heavily on the use of submodules, and it pulls in diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e4045f64c..0eff6d948 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -365,18 +365,17 @@ target_include_directories (game PUBLIC ${UTF8PROC_INCLUDE_DIR}) target_include_directories (game PRIVATE ${SQLITE3_INCLUDE_DIR}) target_link_libraries(eressea ${SQLITE3_LIBRARY}) target_link_libraries(test_eressea ${SQLITE3_LIBRARY}) -target_compile_definitions(game PRIVATE USE_SQLITE) if (READLINE_FOUND) target_include_directories (eressea PRIVATE ${READLINE_INCLUDE_DIR}) target_link_libraries(eressea ${READLINE_LIBRARY}) -target_compile_definitions(eressea PRIVATE USE_READLINE) +target_compile_definitions(eressea PRIVATE HAVE_READLINE) endif (READLINE_FOUND) if (CURSES_FOUND) target_include_directories (eressea PRIVATE ${CURSES_INCLUDE_DIRS}) target_link_libraries(eressea ${CURSES_LIBRARY}) -target_compile_definitions(eressea PRIVATE USE_CURSES) +target_compile_definitions(eressea PRIVATE HAVE_CURSES) endif(CURSES_FOUND) if (EXPAT_FOUND) diff --git a/src/bindings.c b/src/bindings.c index 0719c3624..fe8cbbaaf 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -1050,7 +1050,7 @@ lua_State *lua_init(const dictionary *inifile) { tolua_unit_open(L); tolua_message_open(L); tolua_order_open(L); -#ifdef USE_CURSES +#ifdef HAVE_CURSES tolua_gmtool_open(L); #endif tolua_storage_open(L); diff --git a/src/console.c b/src/console.c index 0838aa269..f2f5170fb 100644 --- a/src/console.c +++ b/src/console.c @@ -24,7 +24,7 @@ #define lua_strlen(L, idx) lua_rawlen(L, idx) #endif -#ifdef USE_READLINE +#ifdef HAVE_READLINE #include #include #include diff --git a/src/gmtool.c b/src/gmtool.c index b1b6df05f..495b1b31d 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -2,7 +2,7 @@ #define _CRT_SECURE_NO_WARNINGS #endif #include -#ifdef USE_LUA +#ifdef HAVE_LUA #include #include "console.h" #endif @@ -1099,7 +1099,7 @@ static bool confirm(WINDOW * win, const char *q) { static int exec_key_binding(int keycode) { -#ifdef USE_LUA +#ifdef HAVE_LUA struct lua_State* L = global.vm_state; lua_getglobal(L, "gmtool_on_keypressed"); if (lua_isfunction(L, -1)) { @@ -1478,7 +1478,7 @@ static void handlekey(state * st, int c) } while (c == 0); break; case 'L': -#ifdef USE_LUA +#ifdef HAVE_LUA if (global.vm_state) { move(0, 0); refresh(); @@ -1750,7 +1750,7 @@ void run_mapper(void) init_curses(); curs_set(1); -#ifdef USE_LUA +#ifdef HAVE_LUA set_readline(curses_readline); #endif assert(stdscr); @@ -1835,7 +1835,7 @@ void run_mapper(void) handlekey(st, c); } g_quit = 0; -#ifdef USE_LUA +#ifdef HAVE_LUA set_readline(NULL); #endif curs_set(1); @@ -1849,7 +1849,7 @@ void run_mapper(void) } -#ifdef USE_LUA +#ifdef HAVE_LUA int curses_readline(struct lua_State *L, char *buffer, size_t size, const char *prompt) diff --git a/src/helpers.c b/src/helpers.c index 6437b4e07..4198afd2a 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -5,20 +5,21 @@ #include "alchemy.h" #include "magic.h" -#include -#include -#include +#include #include #include #include #include +#include #include #include -#include -#include +#include +#include #include #include +#include +#include #include @@ -261,7 +262,7 @@ lua_changeresource(unit * u, const struct resource_type *rtype, int delta) /** callback for an item-use function written in lua. */ static int -lua_use_item(unit *u, const item_type *itype, const char * fname, int amount, struct order *ord) +lua_use_item(unit *u, const item_type *itype, int amount, struct order *ord) { int len; char fname[64]; diff --git a/src/main.c b/src/main.c index effee575b..cb2df8a48 100644 --- a/src/main.c +++ b/src/main.c @@ -14,10 +14,10 @@ #include #include "eressea.h" -#ifdef USE_CURSES +#ifdef HAVE_CURSES #include "gmtool.h" #endif -#ifdef USE_LUA +#ifdef HAVE_LUA #include "bindings.h" #else #include "processing.h" @@ -61,7 +61,7 @@ static void load_inifile(void) verbosity = config_get_int("game.verbose", 2); memdebug = config_get_int("game.memcheck", memdebug); -#ifdef USE_CURSES +#ifdef HAVE_CURSES /* only one value in the [editor] section */ force_color = config_get_int("editor.color", force_color); #endif @@ -188,7 +188,7 @@ static int parse_args(int argc, char **argv) "Copyright (C) 2023 Enno Rehling et al.\n", eressea_version()); return 1; -#ifdef USE_CURSES +#ifdef HAVE_CURSES } else if (strcmp(argi + 2, "color") == 0) { /* force the editor to have colors */ @@ -276,7 +276,7 @@ void locale_init(void) int main(int argc, char **argv) { -#ifdef USE_LUA +#ifdef HAVE_LUA lua_State *L; #endif int err = 0; @@ -295,11 +295,11 @@ int main(int argc, char **argv) locale_init(); -#ifdef USE_LUA +#ifdef HAVE_LUA L = lua_init(d); #endif game_init(); -#ifdef USE_LUA +#ifdef HAVE_LUA bind_monsters(L); err = eressea_run(L, luafile); if (err) { @@ -310,7 +310,7 @@ int main(int argc, char **argv) run_turn(); #endif game_done(); -#ifdef USE_LUA +#ifdef HAVE_LUA lua_done(L); #endif log_close(); From e85f9478e0bbdf40dcf668e446282cc6449c2335 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 15 Dec 2024 17:15:04 +0100 Subject: [PATCH 03/11] configure file and documentation update --- README.md | 4 ++-- configure | 4 ++-- s/cmake-init | 4 ++++ src/main.c | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 84d36cd59..79db0f3bb 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,8 @@ install all of them: libcjson-dev libiniparser-dev libexpat1-dev libutf8proc-dev If your system for some reason doesn't have Lua or the tolua library, -you can run cmake with -DWITHOUT_LUA=1 to build the server without the -Lua extensions. This is very much untested, and it breaks any items +you can run configure with the --no-lua option to build the code +without Lua extensions. This is very much untested, and it breaks any items or spells that have their actions implemented as Lua scripts, as well as the Lua integration tests. diff --git a/configure b/configure index d7df79c8a..5c8e24339 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #!/bin/sh git submodule update --init -ln -sf conf/eressea.ini -s/cmake-init +ln -sf conf/eressea.ini . +s/cmake-init "$@" echo "configuration complete. run s/build to build the server" diff --git a/s/cmake-init b/s/cmake-init index 8bab2b742..c56e5dcbd 100755 --- a/s/cmake-init +++ b/s/cmake-init @@ -1,5 +1,6 @@ #!/bin/sh +WITHOUT_LUA=OFF ERESSEA_DB=memory pkg-config --exists sqlite3 && ERESSEA_DB=sqlite @@ -41,6 +42,8 @@ elif [ "$1" = "--with-sqlite" ] ; then ERESSEA_DB=sqlite elif [ "$1" = "--with-memory" ] ; then ERESSEA_DB=memory +elif [ "$1" = "--no-lua" ] ; then +WITHOUT_LUA=ON fi shift 1 done @@ -77,6 +80,7 @@ SET (ERESSEA_DB "$ERESSEA_DB" CACHE STRING "Database driver") SET (CMAKE_BUILD_TYPE "$BUILD" CACHE STRING "") SET (CMAKE_LIBRARY_PATH "$LIBRARY_PATH" CACHE PATH "") SET (CMAKE_PREFIX_PATH "$PREFIX_PATH" CACHE PATH "") +SET (WITHOUT_LUA "$PREFIX_PATH" CACHE BOOL $WITHOUT_LUA) HEREDOC set -e diff --git a/src/main.c b/src/main.c index cb2df8a48..5035f370d 100644 --- a/src/main.c +++ b/src/main.c @@ -27,8 +27,9 @@ #include #include +#ifdef HAVE_LUA #include - +#endif #include #include #include From 244f37d6af9c8cc100843e509f66ea2650fb32a7 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 15 Dec 2024 17:25:40 +0100 Subject: [PATCH 04/11] fix non-effect potions, iwyu --- s/cmake-init | 2 +- src/bind_eressea.c | 1 - src/helpers.c | 1 - src/laws.c | 14 +++++++------- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/s/cmake-init b/s/cmake-init index c56e5dcbd..7c4630113 100755 --- a/s/cmake-init +++ b/s/cmake-init @@ -80,7 +80,7 @@ SET (ERESSEA_DB "$ERESSEA_DB" CACHE STRING "Database driver") SET (CMAKE_BUILD_TYPE "$BUILD" CACHE STRING "") SET (CMAKE_LIBRARY_PATH "$LIBRARY_PATH" CACHE PATH "") SET (CMAKE_PREFIX_PATH "$PREFIX_PATH" CACHE PATH "") -SET (WITHOUT_LUA "$PREFIX_PATH" CACHE BOOL $WITHOUT_LUA) +SET (WITHOUT_LUA $WITHOUT_LUA CACHE BOOL "") HEREDOC set -e diff --git a/src/bind_eressea.c b/src/bind_eressea.c index 6f7507775..4c6c43c58 100755 --- a/src/bind_eressea.c +++ b/src/bind_eressea.c @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/src/helpers.c b/src/helpers.c index 4198afd2a..10537a37b 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -2,7 +2,6 @@ #include "helpers.h" #include "vortex.h" -#include "alchemy.h" #include "magic.h" #include diff --git a/src/laws.c b/src/laws.c index 8797cf6a3..19baad8e9 100644 --- a/src/laws.c +++ b/src/laws.c @@ -3017,13 +3017,6 @@ static int callback_use(unit *u, const item_type *itype, int amount, struct orde int len; char fname[64]; - /* if the item is a potion, try use_potion, - * the generic function for potions that add an effect: - */ - if (itype->flags & ITF_POTION) { - return use_potion(u, itype, amount, ord); - } - len = snprintf(fname, sizeof(fname), "use_%s", itype->rtype->_name); if (len > 0 && (size_t)len < sizeof(fname)) { int(*callout)(unit *, const item_type *, int, struct order *); @@ -3034,6 +3027,13 @@ static int callback_use(unit *u, const item_type *itype, int amount, struct orde return callout(u, itype, amount, ord); } } + /* if the item is a potion, try use_potion, + * the generic function for potions that add an effect: + */ + if (itype->flags & ITF_POTION) { + return use_potion(u, itype, amount, ord); + } + /* finally, check if we have a matching lua function */ if (callbacks.use_item) { return callbacks.use_item(u, itype, amount, ord); From 50bda34a2ddcd7dbecf3bdecf22d8d4b8951953a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 15 Dec 2024 19:25:01 +0100 Subject: [PATCH 05/11] fix getopt usage (gnu only) --- CMakeLists.txt | 4 +-- s/cmake-init | 66 ++++++++++++++++++-------------------------------- 2 files changed, 26 insertions(+), 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 32de904fb..028991792 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,9 +11,9 @@ endif (WIN32) project (server C) set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") -SET (USING_LUA TRUE) +set (USING_LUA TRUE) if (WITHOUT_LUA) -SET (USING_LUA FALSE) + SET (USING_LUA FALSE) endif (WITHOUT_LUA) if (MSVC) diff --git a/s/cmake-init b/s/cmake-init index 7c4630113..ddedbc317 100755 --- a/s/cmake-init +++ b/s/cmake-init @@ -4,48 +4,30 @@ WITHOUT_LUA=OFF ERESSEA_DB=memory pkg-config --exists sqlite3 && ERESSEA_DB=sqlite -GETOPT=getopt -GETOPT_LONG=1 - -if [ "Darwin" = "$(uname)" ] ; then - if [ -x "/usr/local/opt/gnu-getopt/bin/getopt" ] ; then - GETOPT="/usr/local/opt/gnu-getopt/bin/getopt" - else - GETOPT_LONG=0 - fi -fi - -if [ $GETOPT_LONG -eq 1 ]; then - options=$(${GETOPT} -o d: -l db: -- "$@") -else # assume GNU getopt (long arguments) - options=$(${GETOPT} d: "$@") -fi - -# Parse command line arguments +usage() +{ + echo "usage: $0 --help --db=DB" +} +options=$(getopt -a -l help,no-lua,db: 'hd:' "$@") +if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi eval set -- "$options" -until [ -z "$1" ] ; do - case $1 in - -d|--db) - ERESSEA_DB=$2 - shift - ;; - --) shift; break;; - (-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;; - (*) break;; - esac - shift -done -while [ ! -z "$1" ] ; do -if [ "$1" = "--with-db" ] ; then -ERESSEA_DB=db -elif [ "$1" = "--with-sqlite" ] ; then -ERESSEA_DB=sqlite -elif [ "$1" = "--with-memory" ] ; then -ERESSEA_DB=memory -elif [ "$1" = "--no-lua" ] ; then -WITHOUT_LUA=ON -fi -shift 1 + +while true; do + case "$1" in + --no-lua) + WITHOUT_LUA=ON ;; + --help | -h) + usage + ;; + --db | -d) + ERESSEA_DB="$2" + shift + ;; + --) + break + ;; + esac + shift done git submodule update --init @@ -86,6 +68,6 @@ HEREDOC set -e cd $BIN_DIR -cmake -C config.cmake .. $* +cmake -C config.cmake .. cd $OLDPWD From 84edd75847d84c98044d0402f59433d6c2170937 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 15 Dec 2024 21:50:03 +0100 Subject: [PATCH 06/11] change how -c works (include name of the ini file) move rules from [lua] section to [game] --- src/processing.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/processing.c b/src/processing.c index e12fa5af8..81c9b285d 100644 --- a/src/processing.c +++ b/src/processing.c @@ -21,7 +21,7 @@ void run_turn(void) { char path[PATH_MAX]; const char *install_path = config_get("config.install"); - const char *rules = config_get("config.rules"); + const char *config_path = config_get("game.rules"); int lastturn; /* * TODO: @@ -30,9 +30,12 @@ void run_turn(void) * replace the lua callbacks in helpers.c (see callbacks.h) * spells that have lua-only implmentations (see spells.lua) */ + if (!config_path) { + log_fatal("game.rules is null"); + } if (0 != config_read( - path_join(path_join("conf", rules, path, sizeof(path)), "config.json", path, sizeof(path)), + path_join(path_join("conf", config_path, path, sizeof(path)), "config.json", path, sizeof(path)), install_path)) { log_fatal("could not read JSON data"); From d76ab94cb24145b55343922864e99f08a58f5283 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 16 Dec 2024 12:08:48 +0100 Subject: [PATCH 07/11] missing dragon growl translation --- res/translations/strings.en.po | 3 +++ 1 file changed, 3 insertions(+) diff --git a/res/translations/strings.en.po b/res/translations/strings.en.po index e85881311..0e3a7f8ff 100644 --- a/res/translations/strings.en.po +++ b/res/translations/strings.en.po @@ -4142,6 +4142,9 @@ msgstr "Tshrrrk..." msgid "growl2" msgstr "Shhhhhh..." +msgid "growl3" +msgstr "Raaaar..." + msgctxt "skill" msgid "bow" msgstr "bow" From 44bfc22531d32a7885790ca5e3616b04cb2bb49d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 16 Dec 2024 12:09:14 +0100 Subject: [PATCH 08/11] plan monsters --- src/processing.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/processing.c b/src/processing.c index 81c9b285d..c1ef4f102 100644 --- a/src/processing.c +++ b/src/processing.c @@ -3,6 +3,7 @@ #include "bind_config.h" #include "eressea.h" #include "laws.h" +#include "monsters.h" #include "orderfile.h" #include @@ -54,7 +55,7 @@ void run_turn(void) log_fatal("could not read game data %s", path); } turn_begin(); - // plan_monsters(); + plan_monsters(get_monsters()); snprintf(path, sizeof(path), "orders.%d", turn); if (0 != readorders(path)) { From b4f60b84e8feaefa3b0874a5b337dec24e198051 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 16 Dec 2024 15:18:56 +0100 Subject: [PATCH 09/11] warn about missing callback --- src/exparse.c | 6 +++++- src/processing.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/exparse.c b/src/exparse.c index 2e5fb2e5b..c684b3719 100644 --- a/src/exparse.c +++ b/src/exparse.c @@ -805,7 +805,11 @@ static void start_resources(parseinfo *pi, const XML_Char *el, const XML_Char ** name = attr[i + 1]; } else if (xml_strequal(attr[i], "value")) { - fun = get_function(attr[i + 1]); + const char *value = attr[i + 1]; + fun = get_function(value); + if (!fun) { + log_warning("no such resource function: %s", value); + } } else { handle_bad_input(pi, el, attr[i]); diff --git a/src/processing.c b/src/processing.c index c1ef4f102..a8db09bf7 100644 --- a/src/processing.c +++ b/src/processing.c @@ -35,6 +35,7 @@ void run_turn(void) log_fatal("game.rules is null"); } + init_resources(); if (0 != config_read( path_join(path_join("conf", config_path, path, sizeof(path)), "config.json", path, sizeof(path)), install_path)) @@ -42,7 +43,6 @@ void run_turn(void) log_fatal("could not read JSON data"); } free_gamedata(); - init_resources(); init_locales(init_locale); lastturn = turn; From e442826e991e2e824809c9e8e5450227c4a5759c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 16 Dec 2024 17:36:37 +0100 Subject: [PATCH 10/11] some debug output for cmake configuration issues --- CMakeLists.txt | 2 + CMakeSettings.json | 3 +- scripts/eressea/xmlconf.lua | 2 +- src/kernel/item.h | 452 ++++++++++++++++++------------------ 4 files changed, 225 insertions(+), 234 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 028991792..c6045ec2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,8 @@ find_package (Utf8Proc REQUIRED) if (USING_LUA) find_package (Lua 5.2 REQUIRED) +else(USING_LUA) +message("Building without Lua") endif(USING_LUA) if (LUA_FOUND) diff --git a/CMakeSettings.json b/CMakeSettings.json index bf3f8152b..5d6116b48 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -7,7 +7,6 @@ "inheritEnvironments": [ "msvc_x64_x64" ], "buildRoot": "${projectDir}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", - "cmakeCommandArgs": "-DWITHOUT_LUA=1", "buildCommandArgs": "-v", "ctestCommandArgs": "", "variables": [ @@ -44,7 +43,7 @@ "configurationType": "RelWithDebInfo", "buildRoot": "${projectDir}\\build\\${name}", "installRoot": "${projectDir}\\install\\${name}", - "cmakeCommandArgs": "", + "cmakeCommandArgs": "-DWITHOUT_LUA=1", "buildCommandArgs": "", "ctestCommandArgs": "", "inheritEnvironments": [ "msvc_x64_x64" ], diff --git a/scripts/eressea/xmlconf.lua b/scripts/eressea/xmlconf.lua index 335845177..c0bce5717 100644 --- a/scripts/eressea/xmlconf.lua +++ b/scripts/eressea/xmlconf.lua @@ -2,7 +2,7 @@ local rules = 'conf' if config.rules then rules = rules .. '/' .. config.rules - assert(0 == eressea.config.read(rules .. '/config.json', config.install), "could not read JSON data") + assert(0 == eressea.config.read(rules .. '/config.json', config.install), "could not read JSON data from " .. rules) end eressea.game.reset() diff --git a/src/kernel/item.h b/src/kernel/item.h index 26d7db88c..dff5adb62 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -1,81 +1,76 @@ -#ifndef H_KRNL_ITEM -#define H_KRNL_ITEM +#pragma once #include #include "skill.h" -#ifdef __cplusplus -extern "C" { -#endif - - struct unit; - struct attrib; - struct attrib_type; - struct race; - struct region; - struct resource_type; - struct locale; - struct troop; - struct item; - struct order; - struct storage; - struct gamedata; - struct rawmaterial_type; - struct resource_mod; - struct weapon_type; - - typedef struct item { - struct item *next; - const struct item_type *type; - int number; - } item; - - typedef struct resource { - const struct resource_type *type; - int number; - struct resource *next; - } resource; - - /* bitfield values for resource_type::flags */ +struct unit; +struct attrib; +struct attrib_type; +struct race; +struct region; +struct resource_type; +struct locale; +struct troop; +struct item; +struct order; +struct storage; +struct gamedata; +struct rawmaterial_type; +struct resource_mod; +struct weapon_type; + +typedef struct item { + struct item *next; + const struct item_type *type; + int number; +} item; + +typedef struct resource { + const struct resource_type *type; + int number; + struct resource *next; +} resource; + +/* bitfield values for resource_type::flags */ #define RTF_NONE 0 #define RTF_ITEM (1<<0) /* this resource is an item */ #define RTF_LIMITED (1<<1) /* a resource that's freely available, but in - * limited supply */ + * limited supply */ #define RTF_POOLED (1<<2) /* resource is available in pool */ - /* flags for resource_type::name() */ +/* flags for resource_type::name() */ #define NMF_PLURAL 0x01 #define NMF_APPEARANCE 0x02 - void item_done(void); - - typedef bool(*wtype_attack)(const struct troop *, - const struct weapon_type *, int *); - typedef int(*rtype_uchange) (struct unit * user, - const struct resource_type * rtype, int delta); - typedef char *(*rtype_name) (const struct resource_type * rtype, int flags); - - typedef struct resource_type { - /* --- constants --- */ - char *_name; /* wie es heisst */ - unsigned int flags; - /* --- functions --- */ - rtype_uchange uchange; - rtype_name name; - struct rawmaterial_type *raw; - struct resource_mod *modifiers; - /* --- pointers --- */ - struct item_type *itype; - struct luxury_type *ltype; - struct weapon_type *wtype; - struct armor_type *atype; - } resource_type; - - const char *resourcename(const resource_type * rtype, int flags); - const resource_type *findresourcetype(const char *name, - const struct locale *lang); - - /* bitfield values for item_type::flags */ +void item_done(void); + +typedef bool(*wtype_attack)(const struct troop *, + const struct weapon_type *, int *); +typedef int(*rtype_uchange) (struct unit * user, + const struct resource_type * rtype, int delta); +typedef char *(*rtype_name) (const struct resource_type * rtype, int flags); + +typedef struct resource_type { + /* --- constants --- */ + char *_name; /* wie es heisst */ + unsigned int flags; + /* --- functions --- */ + rtype_uchange uchange; + rtype_name name; + struct rawmaterial_type *raw; + struct resource_mod *modifiers; + /* --- pointers --- */ + struct item_type *itype; + struct luxury_type *ltype; + struct weapon_type *wtype; + struct armor_type *atype; +} resource_type; + +const char *resourcename(const resource_type * rtype, int flags); +const resource_type *findresourcetype(const char *name, + const struct locale *lang); + +/* bitfield values for item_type::flags */ #define ITF_NONE 0x0000 #define ITF_HERB 0x0001 /* this item is a herb */ #define ITF_CURSED 0x0002 /* cursed object, cannot be given away */ @@ -86,33 +81,33 @@ extern "C" { #define ITF_CANUSE 0x0040 /* can be used with use_item_fun callout */ #define ITF_POTION 0x0080 /* is a potion (for use_potion) */ - /* error codes for item_type::use */ +/* error codes for item_type::use */ #define ECUSTOM -1 #define ENOITEM -2 #define ENOSKILL -3 #define EUNUSABLE -4 - typedef struct item_type { - resource_type *rtype; - /* --- constants --- */ - unsigned int flags; - int weight; - int capacity; - int mask_allow; - int mask_deny; - struct construction *construction; - char *_appearance[2]; /* wie es fuer andere aussieht */ - int score; - } item_type; - - const item_type *finditemtype(const char *name, const struct locale *lang); - - typedef struct luxury_type { - struct luxury_type *next; - const item_type *itype; - int price; - } luxury_type; - extern luxury_type *luxurytypes; +typedef struct item_type { + resource_type *rtype; + /* --- constants --- */ + unsigned int flags; + int weight; + int capacity; + int mask_allow; + int mask_deny; + struct construction *construction; + char *_appearance[2]; /* wie es fuer andere aussieht */ + int score; +} item_type; + +const item_type *finditemtype(const char *name, const struct locale *lang); + +typedef struct luxury_type { + struct luxury_type *next; + const item_type *itype; + int price; +} luxury_type; +extern luxury_type *luxurytypes; #define WMF_WALKING 0x0001 #define WMF_RIDING 0x0002 @@ -130,25 +125,25 @@ extern "C" { #define WMF_SKILL 0x2000 #define WMF_MISSILE_TARGET 0x4000 - struct race_list; - typedef struct weapon_mod { - int value; - int flags; - int race_mask; - } weapon_mod; +struct race_list; +typedef struct weapon_mod { + int value; + int flags; + int race_mask; +} weapon_mod; #define ATF_NONE 0x00 #define ATF_SHIELD 0x01 #define ATF_LAEN 0x02 - typedef struct armor_type { - const item_type *itype; - unsigned int flags; - double penalty; - double projectile; /* chance, dass ein projektil abprallt */ - variant magres; - int prot; - } armor_type; +typedef struct armor_type { + const item_type *itype; + unsigned int flags; + double penalty; + double projectile; /* chance, dass ein projektil abprallt */ + variant magres; + int prot; +} armor_type; #define WTF_NONE 0x00 #define WTF_MISSILE 0x01 @@ -161,132 +156,127 @@ extern "C" { #define WTF_HORSEBONUS 0x80 #define WTF_USESHIELD 0x100 - typedef struct weapon_type { - const item_type *itype; - char *damage[2]; - unsigned int flags; - skill_t skill; - int offmod; - int defmod; - variant magres; - unsigned char reload; /* time to reload this weapon */ - weapon_mod *modifiers; - /* --- functions --- */ - bool(*attack) (const struct troop *, const struct weapon_type *, - int *deaths); - } weapon_type; - - resource_type *rt_find(const char *name); - item_type *it_find(const char *name); - - void it_set_appearance(item_type *itype, const char *appearance); - - const item_type *resource2item(const resource_type * rtype); - const resource_type *item2resource(const item_type * i); - - const weapon_type *resource2weapon(const resource_type * i); - const luxury_type *resource2luxury(const resource_type * i); - - item **i_find(item ** pi, const item_type * it); - item *const *i_findc(item * const *pi, const item_type * it); - item *i_add(item ** pi, item * it); - void i_merge(item ** pi, item ** si); - item *i_remove(item ** pi, item * it); - void i_free(item * i); - void i_freeall(item ** i); - item *i_new(const item_type * it, int number); - - void read_items(struct storage *store, struct item **it); - void write_items(struct storage *store, struct item *it); - - /* convenience: */ - void item_add(item* itm, int delta); - item *i_change(item ** items, const item_type * it, int delta); - int i_get(const item * items, const item_type * it); - - /* creation */ - resource_type *rt_get_or_create(const char *name); - item_type *it_get_or_create(resource_type *rtype); - luxury_type *new_luxurytype(item_type * itype, int price); - weapon_type *new_weapontype(item_type * itype, int wflags, - variant magres, const char *damage[], int offmod, int defmod, unsigned char reload, - skill_t sk); - void free_wtype(struct weapon_type *wtype); - armor_type *new_armortype(item_type * itype, double penalty, - variant magres, int prot, unsigned int flags); - void free_atype(struct armor_type *wtype); - /* these constants are used with get_resourcetype. - * The order of the enum is not important for stored data. - * The resourcenames array must be updated to match. - */ - - typedef enum { - /* SPECIAL */ - R_SILVER, - R_AURA, /* Aura */ - R_PERMAURA, /* Permanente Aura */ - R_LIFE, - R_PEASANT, - R_SAPLING, - R_MALLORN_SAPLING, - R_TREE, - R_MALLORN_TREE, - /* ITEMS: */ - R_SEED, - R_MALLORN_SEED, - R_IRON, - R_STONE, - R_HORSE, - R_AMULET_OF_HEALING, - R_AMULET_OF_TRUE_SEEING, - R_RING_OF_INVISIBILITY, - R_RING_OF_POWER, - R_CHASTITY_BELT, - R_EOG, - R_FEENSTIEFEL, - R_BIRTHDAYAMULET, - R_PEGASUS, - R_UNICORN, - R_CHARGER, - R_DOLPHIN, - R_RING_OF_NIMBLEFINGER, - R_TROLLBELT, - R_AURAKULUM, - R_SPHERE_OF_INVISIBILITY, - R_BAG_OF_HOLDING, - R_SACK_OF_CONSERVATION, - R_TACTICCRYSTAL, - R_WATER_OF_LIFE, - /* SONSTIGE */ - - MAX_RESOURCES, /* do not use outside item.c ! */ - NORESOURCE = -1 - } resource_t; - - extern const struct item_type *oldpotiontype[]; - extern struct attrib_type at_showitem; /* show this potion's description */ - - void show_item(struct unit * u, const struct item_type * itype); - - const struct resource_type *get_resourcetype(resource_t rt); - struct item *item_spoil(const struct race *rc, int size); - - int get_item(const struct unit * u, const struct item_type *itype); - int get_money(const struct unit *); - int set_money(struct unit *, int); - int change_money(struct unit *, int); - - void register_resources(void); - void init_resources(void); - void init_oldpotions(void); - void register_item_give(int(*foo) (struct unit *, struct unit *, - const struct item_type *, int, struct order *), const char *name); - void register_item_use(int(*foo) (struct unit *, - const struct item_type *, int, struct order *), const char *name); - - void free_resources(void); - -#ifdef __cplusplus -} -#endif -#endif /* _ITEM_H */ +typedef struct weapon_type { + const item_type *itype; + char *damage[2]; + unsigned int flags; + skill_t skill; + int offmod; + int defmod; + variant magres; + unsigned char reload; /* time to reload this weapon */ + weapon_mod *modifiers; + /* --- functions --- */ + bool(*attack) (const struct troop *, const struct weapon_type *, + int *deaths); +} weapon_type; + +resource_type *rt_find(const char *name); +item_type *it_find(const char *name); + +void it_set_appearance(item_type *itype, const char *appearance); + +const item_type *resource2item(const resource_type * rtype); +const resource_type *item2resource(const item_type * i); + +const weapon_type *resource2weapon(const resource_type * i); +const luxury_type *resource2luxury(const resource_type * i); + +item **i_find(item ** pi, const item_type * it); +item *const *i_findc(item * const *pi, const item_type * it); +item *i_add(item ** pi, item * it); +void i_merge(item ** pi, item ** si); +item *i_remove(item ** pi, item * it); +void i_free(item * i); +void i_freeall(item ** i); +item *i_new(const item_type * it, int number); + +void read_items(struct storage *store, struct item **it); +void write_items(struct storage *store, struct item *it); + +/* convenience: */ +void item_add(item* itm, int delta); +item *i_change(item ** items, const item_type * it, int delta); +int i_get(const item * items, const item_type * it); + +/* creation */ +resource_type *rt_get_or_create(const char *name); +item_type *it_get_or_create(resource_type *rtype); +luxury_type *new_luxurytype(item_type * itype, int price); +weapon_type *new_weapontype(item_type * itype, int wflags, + variant magres, const char *damage[], int offmod, int defmod, unsigned char reload, + skill_t sk); +void free_wtype(struct weapon_type *wtype); +armor_type *new_armortype(item_type * itype, double penalty, + variant magres, int prot, unsigned int flags); +void free_atype(struct armor_type *wtype); +/* these constants are used with get_resourcetype. + * The order of the enum is not important for stored data. + * The resourcenames array must be updated to match. + */ + +typedef enum { + /* SPECIAL */ + R_SILVER, + R_AURA, /* Aura */ + R_PERMAURA, /* Permanente Aura */ + R_LIFE, + R_PEASANT, + R_SAPLING, + R_MALLORN_SAPLING, + R_TREE, + R_MALLORN_TREE, + /* ITEMS: */ + R_SEED, + R_MALLORN_SEED, + R_IRON, + R_STONE, + R_HORSE, + R_AMULET_OF_HEALING, + R_AMULET_OF_TRUE_SEEING, + R_RING_OF_INVISIBILITY, + R_RING_OF_POWER, + R_CHASTITY_BELT, + R_EOG, + R_FEENSTIEFEL, + R_BIRTHDAYAMULET, + R_PEGASUS, + R_UNICORN, + R_CHARGER, + R_DOLPHIN, + R_RING_OF_NIMBLEFINGER, + R_TROLLBELT, + R_AURAKULUM, + R_SPHERE_OF_INVISIBILITY, + R_BAG_OF_HOLDING, + R_SACK_OF_CONSERVATION, + R_TACTICCRYSTAL, + R_WATER_OF_LIFE, + /* SONSTIGE */ + + MAX_RESOURCES, /* do not use outside item.c ! */ + NORESOURCE = -1 +} resource_t; + +extern const struct item_type *oldpotiontype[]; +extern struct attrib_type at_showitem; /* show this potion's description */ + +void show_item(struct unit * u, const struct item_type * itype); + +const struct resource_type *get_resourcetype(resource_t rt); +struct item *item_spoil(const struct race *rc, int size); + +int get_item(const struct unit * u, const struct item_type *itype); +int get_money(const struct unit *); +int set_money(struct unit *, int); +int change_money(struct unit *, int); + +void register_resources(void); +void init_resources(void); +void init_oldpotions(void); +void register_item_give(int(*foo) (struct unit *, struct unit *, + const struct item_type *, int, struct order *), const char *name); +void register_item_use(int(*foo) (struct unit *, + const struct item_type *, int, struct order *), const char *name); + +void free_resources(void); From 17c0be718e0ea3cd7860eb3961dfe266662c0038 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 16 Dec 2024 17:42:32 +0100 Subject: [PATCH 11/11] warn when Lua script cannot be used --- src/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main.c b/src/main.c index 5035f370d..e56651a43 100644 --- a/src/main.c +++ b/src/main.c @@ -308,6 +308,9 @@ int main(int argc, char **argv) return err; } #else + if (luafile) { + log_error("Lua is disabled, cannot execute %s", luafile); + } run_turn(); #endif game_done();