diff --git a/.gitignore b/.gitignore index ca37570..20a7cf2 100644 --- a/.gitignore +++ b/.gitignore @@ -27,5 +27,3 @@ backup *.dll *.world coverage -coverage/* -.venv diff --git a/.vimrc_proj b/.vimrc_proj index 1d04d48..2b745b4 100644 --- a/.vimrc_proj +++ b/.vimrc_proj @@ -1 +1 @@ -set makeprg=make\ -f\ ../Makefile\ build +set makeprg=meson\ compile\ -C\ . diff --git a/Makefile b/Makefile index ece7c1d..6144bd3 100644 --- a/Makefile +++ b/Makefile @@ -1,72 +1,47 @@ -ROOT_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) - all: build test reset: -ifeq '$(OS)' 'Windows_NT' powershell -executionpolicy bypass .\scripts\reset_build.ps1 -else - sh -x ./scripts/reset_build.sh -endif %.cpp : %.rl - ragel -I $(ROOT_DIR) -G1 -o $@ $< + ragel -o $@ $< -%.dot: %.rl - ragel -Vp -I $(ROOT_DIR) -o $@ $< - -%.png: %.dot - dot -Tpng $< -o $@ - -build: - meson compile -j 10 -C $(ROOT_DIR)/builddir - -asset_build: - ./builddir/icongen +build: ansi_parser.cpp lel_parser.cpp + meson compile -j 10 -C builddir release_build: meson --wipe builddir -Db_ndebug=true --buildtype release meson compile -j 10 -C builddir debug_build: - meson setup --wipe builddir -Db_ndebug=true --buildtype debugoptimized + meson setup --wipe builddir --buildtype debug meson compile -j 10 -C builddir tracy_build: meson setup --wipe builddir --buildtype debugoptimized -Dtracy_enable=true -Dtracy:on_demand=true meson compile -j 10 -C builddir -test: - ./builddir/runtests -d yes +test: build + ./builddir/runtests run: build test -ifeq '$(OS)' 'Windows_NT' powershell "cp ./builddir/zedcaster.exe ." ./zedcaster -else - ./builddir/zedcaster -endif debug: build - gdb --nx -x .gdbinit --ex run --args builddir/zedcaster + gdb --nx -x .gdbinit --ex run --args builddir/zedcaster.exe debug_run: build - gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/zedcaster + gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/zedcaster.exe -debug_walk: build test - gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/zedcaster t +debug_walk: build + gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/zedcaster.exe t clean: meson compile --clean -C builddir debug_test: build - gdb --nx -x .gdbinit --ex run --ex bt --ex q --args builddir/runtests -e + gdb --nx -x .gdbinit --ex run --args builddir/runtests.exe -e win_installer: - powershell 'start "C:\Program Files (x86)\solicus\InstallForge\bin\ifbuilderenvx86.exe" scripts\win_installer.ifp' - -coverage_report: - powershell 'scripts/coverage_report.ps1' - -money: - scc --exclude-dir subprojects + powershell 'start "C:\Program Files (x86)\solicus\InstallForge\bin\ifbuilderenvx86.exe" win_installer.ifp' diff --git a/README.md b/README.md index d489c31..d1304d8 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,8 @@ See? That's how Free Speech works. You don't need a LICENSE. On all platforms you'll need these components: * [Meson](https://mesonbuild.com/) -- which needs Python. -* C++ Compiler -- Tested with Clang and GCC 14.2.0. You can use my [Windows C++ Setup Guide](https://git.learnjsthehardway.com/learn-code-the-hard-way/lcthw-windows-installers) which features an automated installer for Windows. +* C++ Compiler -- Tested with Clang and G++. You can use my [Windows C++ Setup Guide](https://git.learnjsthehardway.com/learn-code-the-hard-way/lcthw-windows-installers) which features an automated installer for Windows. * [GNU make](https://www.gnu.org/software/make/) -- For the convenience Makefile. On Windows you should have this if you used my setup scripts. Otherwise `winget install ezwinports.make` will set you up. -* [Ninja](https://ninja-build.org/) -- Meson uses this to do builds on most systems. * [git](https://git-scm.com/) -- Which should be on almost every platform, and is installed by default with my Windows setup scripts. ### Windows Instructions @@ -89,7 +88,7 @@ cd raycaster # first compile takes a while make -./builddir/zedcaster +./builddir/raycaster ``` You don't need `make run` because Linux and OSX are sane operating systems that don't lock every @@ -128,18 +127,6 @@ I would also like statistics that show it's better, not just your word. It's early so probably a bunch of bugs. -## Linux Build Notes - -Libraries Needed: - -* libxi-dev -* libfreetype-dev - -It uses c++ so you may need to install a libg++ or libc++ for your system. Usually this is all you -need: - -apt install build-essential - ## OSX Build Notes * Quite a bad experience. Need to install Python, cmake, meson, and ninja all which are in homebrew but if you don't use homebrew then this is a problem. diff --git a/ai.cpp b/ai.cpp deleted file mode 100644 index c6b93e6..0000000 --- a/ai.cpp +++ /dev/null @@ -1,212 +0,0 @@ -#include "dbc.hpp" -#include "ai.hpp" - -namespace ai { - using namespace nlohmann; - using namespace dbc; - - static AIManager AIMGR; - static bool initialized = false; - - inline void validate_profile(nlohmann::json& profile) { - for(auto& [name_key, value] : profile.items()) { - check(value < STATE_MAX, - fmt::format("profile field {} has value {} greater than STATE_MAX {}", (std::string)name_key, (int)value, STATE_MAX)); - } - } - - Action config_action(AIProfile& profile, nlohmann::json& config) { - check(config.contains("name"), "config_action: action config missing name"); - check(config.contains("cost"), "config_action: action config missing cost"); - - Action result(config["name"], config["cost"]); - - check(config.contains("needs"), - fmt::format("config_action: no 'needs' field", result.name)); - check(config.contains("effects"), - fmt::format("config_action: no 'effects' field", result.name)); - - for(auto& [name_key, value] : config["needs"].items()) { - check(profile.contains(name_key), fmt::format("config_action({}): profile does not have need named {}", result.name, name_key)); - result.needs(profile.at(name_key), bool(value)); - } - - for(auto& [name_key, value] : config["effects"].items()) { - check(profile.contains(name_key), fmt::format("config_action({}): profile does not have effect named {}", result.name, name_key)); - - result.effect(profile.at(name_key), bool(value)); - } - - return result; - } - - State config_state(AIProfile& profile, nlohmann::json& config) { - State result; - - for(auto& [name_key, value] : config.items()) { - check(profile.contains(name_key), fmt::format("config_state: profile does not have name {}", name_key)); - - int name_id = profile.at(name_key); - result[name_id] = bool(value); - } - - return result; - } - - /* - * This is only used in tests so I can load different fixtures. - */ - void reset() { - initialized = false; - AIMGR.actions.clear(); - AIMGR.states.clear(); - AIMGR.scripts.clear(); - AIMGR.profile = json({}); - } - - void init(std::string config_path) { - if(!initialized) { - Config config(config_path); - - // profile specifies what keys (bitset indexes) are allowed - // and how they map to the bitset of State - validate_profile(config["profile"]); - - // relies on json conversion? - AIMGR.profile = config["profile"]; - - // load all actions - auto& actions = config["actions"]; - for(auto& action_vars : actions) { - auto the_action = config_action(AIMGR.profile, action_vars); - AIMGR.actions.insert_or_assign(the_action.name, the_action); - } - - // load all states - auto& states = config["states"]; - for(auto& [name, state_vars] : states.items()) { - auto the_state = config_state(AIMGR.profile, state_vars); - AIMGR.states.insert_or_assign(name, the_state); - } - - auto& scripts = config["scripts"]; - for(auto& [script_name, action_names] : scripts.items()) { - std::vector the_script; - - for(auto name : action_names) { - check(AIMGR.actions.contains(name), - fmt::format("ai::init(): script {} uses action {} that doesn't exist", - (std::string)script_name, (std::string)name)); - - the_script.push_back(AIMGR.actions.at(name)); - } - - AIMGR.scripts.insert_or_assign(script_name, the_script); - } - initialized = true; - } else { - dbc::sentinel("DOUBLE INIT: AI manager should only be intialized once if not in tests."); - } - } - - void check_valid_action(std::string name, std::string msg) { - dbc::check(AIMGR.actions.contains(name), - fmt::format("{} tried to access action that doesn't exist {}", - msg, name)); - } - - State load_state(std::string state_name) { - check(initialized, "you forgot to initialize the AI first."); - check(AIMGR.states.contains(state_name), fmt::format( - "ai::load_state({}): state does not exist in config", - state_name)); - - return AIMGR.states.at(state_name); - } - - Action load_action(std::string action_name) { - check(initialized, "you forgot to initialize the AI first."); - check(AIMGR.states.contains(action_name), fmt::format( - "ai::load_action({}): action does not exist in config", - action_name)); - return AIMGR.actions.at(action_name); - } - - std::vector load_script(std::string script_name) { - check(AIMGR.scripts.contains(script_name), fmt::format( - "ai::load_script(): no script named {} configured", script_name)); - return AIMGR.scripts.at(script_name); - } - - ActionPlan plan(std::string script_name, State start, State goal) { - // BUG: could probably memoize here, since: - // same script+same start+same goal will/should produce the same results - - check(initialized, "you forgot to initialize the AI first."); - auto script = load_script(script_name); - return plan_actions(script, start, goal); - } - - int state_id(std::string name) { - check(AIMGR.profile.contains(name), fmt::format( - "ai::state_id({}): id is not configured in profile", - name)); - return AIMGR.profile.at(name); - } - - void set(State& state, std::string name, bool value) { - // resort by best fit - state.set(state_id(name), value); - } - - bool test(State state, std::string name) { - return state.test(state_id(name)); - } - - void EntityAI::fit_sort() { - if(active()) { - std::sort(plan.script.begin(), plan.script.end(), - [&](auto& l, auto& r) { - int l_cost = l.cost + ai::distance_to_goal(start, goal); - int r_cost = r.cost + ai::distance_to_goal(start, goal); - return l_cost < r_cost; - }); - } - } - - std::string& EntityAI::wants_to() { - return plan.script[0].name; - } - - bool EntityAI::wants_to(std::string name) { - ai::check_valid_action(name, "EntityAI::wants_to"); - return plan.script.size() > 0 && plan.script[0].name == name; - } - - bool EntityAI::active() { - if(plan.script.size() == 1) { - return plan.script[0] != FINAL_ACTION; - } else { - return plan.script.size() != 0; - } - } - - void EntityAI::set_state(std::string name, bool setting) { - fit_sort(); - ai::set(start, name, setting); - } - - bool EntityAI::get_state(std::string name) { - return ai::test(start, name); - } - - void EntityAI::update() { - plan = ai::plan(script, start, goal); - fit_sort(); - } - - AIProfile* profile() { - return &AIMGR.profile; - } - -} diff --git a/ai.hpp b/ai.hpp deleted file mode 100644 index 3933b5e..0000000 --- a/ai.hpp +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once -#include -#include "matrix.hpp" -#include -#include -#include -#include -#include "config.hpp" -#include "goap.hpp" - -namespace ai { - struct EntityAI { - std::string script; - ai::State start; - ai::State goal; - ai::ActionPlan plan; - - EntityAI(std::string script, ai::State start, ai::State goal) : - script(script), start(start), goal(goal) - { - } - - EntityAI() {}; - - bool wants_to(std::string name); - std::string& wants_to(); - void fit_sort(); - - bool active(); - - void set_state(std::string name, bool setting); - bool get_state(std::string name); - - void update(); - - void dump(); - std::string to_string(); - }; - - struct AIManager { - AIProfile profile; - std::unordered_map actions; - std::unordered_map states; - std::unordered_map> scripts; - }; - - /* This is really only used in test to load different fixtures. */ - void reset(); - void init(std::string config_path); - - Action config_action(AIProfile& profile, nlohmann::json& config); - State config_state(AIProfile& profile, nlohmann::json& config); - - int state_id(std::string name); - State load_state(std::string state_name); - Action load_action(std::string action_name); - std::vector load_script(std::string script_name); - - void set(State& state, std::string name, bool value=true); - bool test(State state, std::string name); - ActionPlan plan(std::string script_name, State start, State goal); - - /* Mostly used for debugging and validation. */ - void check_valid_action(std::string name, std::string msg); -} diff --git a/ai_debug.cpp b/ai_debug.cpp deleted file mode 100644 index 351df2b..0000000 --- a/ai_debug.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "ai.hpp" -#include "ai_debug.hpp" - -namespace ai { - - /* - * Yeah this is weird but it's only to debug things like - * the preconditions which are weirdly done. - */ - void dump_only(State state, bool matching, bool show_as) { - AIProfile* profile = ai::profile(); - for(auto& [name, name_id] : *profile) { - if(state.test(name_id) == matching) { - fmt::println("\t{}={}", name, show_as); - } - } - } - - void dump_state(State state) { - AIProfile* profile = ai::profile(); - for(auto& [name, name_id] : *profile) { - fmt::println("\t{}={}", name, - state.test(name_id)); - } - } - - void dump_action(Action& action) { - fmt::println(" --ACTION: {}, cost={}", action.name, action.cost); - - fmt::println(" PRECONDS:"); - dump_only(action.$positive_preconds, true, true); - dump_only(action.$negative_preconds, true, false); - - fmt::println(" EFFECTS:"); - dump_only(action.$positive_effects, true, true); - dump_only(action.$negative_effects, true, false); - } - - State dump_script(std::string msg, State start, Script& script) { - fmt::println("--SCRIPT DUMP: {}", msg); - fmt::println("# STATE BEFORE:"); - dump_state(start); - fmt::print("% ACTIONS PLANNED:"); - for(auto& action : script) { - fmt::print("{} ", action.name); - } - fmt::print("\n"); - - for(auto& action : script) { - dump_action(action); - - start = action.apply_effect(start); - fmt::println(" ## STATE AFTER:"); - dump_state(start); - } - - return start; - } - - void EntityAI::dump() { - dump_script(script, start, plan.script); - } - - std::string EntityAI::to_string() { - AIProfile* profile = ai::profile(); - std::string result = wants_to(); - - for(auto& [name, name_id] : *profile) { - result += fmt::format("\n{}={}", name, start.test(name_id)); - } - - return result; - } -} diff --git a/ai_debug.hpp b/ai_debug.hpp deleted file mode 100644 index 27f3b54..0000000 --- a/ai_debug.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "goap.hpp" - -namespace ai { - AIProfile* profile(); - void dump_only(State state, bool matching, bool show_as); - void dump_state(State state); - void dump_action(Action& action); - State dump_script(std::string msg, State start, Script& script); -} diff --git a/scratchpad/amt/main.cpp b/amt/main.cpp similarity index 100% rename from scratchpad/amt/main.cpp rename to amt/main.cpp diff --git a/scratchpad/amt/matrix.hpp b/amt/matrix.hpp similarity index 100% rename from scratchpad/amt/matrix.hpp rename to amt/matrix.hpp diff --git a/scratchpad/amt/pixel.hpp b/amt/pixel.hpp similarity index 100% rename from scratchpad/amt/pixel.hpp rename to amt/pixel.hpp diff --git a/scratchpad/amt/raycaster.cpp b/amt/raycaster.cpp similarity index 99% rename from scratchpad/amt/raycaster.cpp rename to amt/raycaster.cpp index c440355..4658c29 100644 --- a/scratchpad/amt/raycaster.cpp +++ b/amt/raycaster.cpp @@ -68,6 +68,7 @@ void Raycaster::position_camera(float player_x, float player_y) { void Raycaster::draw_pixel_buffer() { view_texture.update(pixels.to_raw_buf(), {(unsigned int)$width, (unsigned int)$height}, {0, 0}); + // BUG: can I do this once and just update it? $window.draw(view_sprite); } diff --git a/scratchpad/amt/raycaster.hpp b/amt/raycaster.hpp similarity index 100% rename from scratchpad/amt/raycaster.hpp rename to amt/raycaster.hpp diff --git a/scratchpad/amt/texture.cpp b/amt/texture.cpp similarity index 100% rename from scratchpad/amt/texture.cpp rename to amt/texture.cpp diff --git a/scratchpad/amt/texture.hpp b/amt/texture.hpp similarity index 100% rename from scratchpad/amt/texture.hpp rename to amt/texture.hpp diff --git a/scratchpad/amt/thread.hpp b/amt/thread.hpp similarity index 100% rename from scratchpad/amt/thread.hpp rename to amt/thread.hpp diff --git a/animation.cpp b/animation.cpp deleted file mode 100644 index db431ac..0000000 --- a/animation.cpp +++ /dev/null @@ -1,117 +0,0 @@ -#include "animation.hpp" - -namespace components { - void Animation::play() { - if(!playing) { - current = 0; - subframe = 0.0f; - playing = true; - } - } - - float Animation::twitching() { - float tick = ease::sine(float(frames) / subframe * ease_rate); - - switch(easing) { - case ease::NONE: - return 0.0; - case ease::SINE: - return tick; - case ease::OUT_CIRC: - return ease::out_circ(tick); - case ease::OUT_BOUNCE: - return ease::sine(ease::out_bounce(tick)); - case ease::IN_OUT_BACK: - return ease::sine(ease::in_out_back(tick)); - default: - dbc::sentinel( - fmt::format("Invalid easing {} given to animation", - int(easing))); - } - } - - void Animation::step(sf::Vector2f& scale_out, sf::Vector2f& pos_out, sf::IntRect& rect_out) { - if(playing && current < frames) { - float tick = twitching(); - scale_out.x = std::lerp(scale_out.x, scale_out.x + scale, tick); - scale_out.y = std::lerp(scale_out.y, scale_out.y + scale, tick); - - if(stationary) { - pos_out.y = pos_out.y - (pos_out.y * scale_out.y - pos_out.y); - } - - if(!simple) { - rect_out.position.x += current * frame_width; - } - - subframe += speed; - current = int(subframe); - } else if(!looped) { - playing = false; - current = frames - 1; - subframe = float(frames - 1); - - if(!simple) { - rect_out.position.x += current * frame_width; - } - } else { - playing = false; - current = 0; - subframe = 0.0f; - } - } -} - - -namespace animation { - using namespace components; - using namespace textures; - - static AnimationManager MGR; - static bool initialized = false; - - bool apply(Animation& anim, SpriteTexture& target) { - auto size = target.texture->getSize(); - anim.frame_width = int(size.x) / (unsigned int)anim.frames; - sf::IntRect rect{{0,0}, {anim.frame_width, int(size.y)}}; - sf::Vector2f scale{1.0, 1.0}; - sf::Vector2f pos{0, 0}; - - anim.step(scale, pos, rect); - - target.sprite->setTextureRect(rect); - target.sprite->setPosition(pos); - target.sprite->setScale(scale); - - return anim.playing; - } - - void rotate(sf::Sprite& target, float degrees) { - target.rotate(sf::degrees(degrees)); - } - - void center(sf::Sprite& target, sf::Vector2f pos) { - auto bounds = target.getLocalBounds(); - target.setPosition({pos.x + bounds.size.x / 2, - pos.y + bounds.size.y / 2}); - target.setOrigin({bounds.size.x / 2, bounds.size.y / 2}); - } - - void init() { - if(!initialized) { - Config config("assets/animations.json"); - - for(auto& [name, data] : config.json().items()) { - auto anim = components::convert(data); - MGR.animations.insert_or_assign(name, anim); - } - - initialized = true; - } - } - - Animation load(std::string name) { - dbc::check(initialized, "You forgot to initialize animation."); - return MGR.animations.at(name); - } -} diff --git a/animation.hpp b/animation.hpp deleted file mode 100644 index 18264bb..0000000 --- a/animation.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include "components.hpp" -#include "textures.hpp" -#include "easings.hpp" - -namespace animation { - struct AnimationManager { - std::unordered_map animations; - }; - - bool apply(components::Animation& anim, textures::SpriteTexture& target); - void rotate(sf::Sprite& target, float degrees); - void center(sf::Sprite& target, sf::Vector2f pos); - - void init(); - components::Animation load(std::string name); -} diff --git a/ansi_parser.cpp b/ansi_parser.cpp new file mode 100644 index 0000000..19f4d7c --- /dev/null +++ b/ansi_parser.cpp @@ -0,0 +1,376 @@ + +#line 1 "ansi_parser.rl" +#include +#include +#include "dbc.hpp" +#include +#include "ansi_parser.hpp" +#include + +using namespace fmt; + + +#line 122 "ansi_parser.rl" + + + +#line 13 "ansi_parser.cpp" +static const char _ansi_parser_actions[] = { + 0, 1, 0, 1, 3, 1, 4, 1, + 5, 1, 6, 1, 7, 1, 8, 1, + 9, 1, 10, 1, 11, 1, 15, 1, + 16, 2, 1, 12, 2, 1, 13, 2, + 6, 7, 2, 16, 5, 3, 1, 14, + 2 +}; + +static const char _ansi_parser_key_offsets[] = { + 0, 0, 1, 2, 11, 12, 14, 17, + 18, 22, 23, 27, 28, 29, 30, 31, + 33, 36, 38, 41, 43, 46, 47, 50, + 51, 52, 53, 54, 55 +}; + +static const int _ansi_parser_trans_keys[] = { + 27, 91, 48, 49, 50, 51, 52, 55, + 57, 53, 54, 109, 48, 109, 34, 48, + 55, 109, 50, 52, 55, 109, 109, 49, + 56, 57, 109, 109, 59, 50, 59, 48, + 57, 59, 48, 57, 48, 57, 59, 48, + 57, 48, 57, 109, 48, 57, 109, 56, + 57, 109, 59, 50, 109, 109, 27, 27, + 0 +}; + +static const char _ansi_parser_single_lengths[] = { + 0, 1, 1, 7, 1, 2, 3, 1, + 4, 1, 4, 1, 1, 1, 1, 0, + 1, 0, 1, 0, 1, 1, 3, 1, + 1, 1, 1, 1, 1 +}; + +static const char _ansi_parser_range_lengths[] = { + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0 +}; + +static const char _ansi_parser_index_offsets[] = { + 0, 0, 2, 4, 13, 15, 18, 22, + 24, 29, 31, 36, 38, 40, 42, 44, + 46, 49, 51, 54, 56, 59, 61, 65, + 67, 69, 71, 73, 75 +}; + +static const char _ansi_parser_trans_targs[] = { + 2, 1, 3, 0, 4, 5, 8, 10, + 22, 26, 6, 7, 0, 28, 0, 6, + 28, 0, 7, 7, 7, 0, 28, 0, + 7, 7, 9, 28, 0, 28, 0, 11, + 12, 21, 28, 0, 28, 0, 13, 0, + 14, 0, 15, 0, 16, 0, 17, 16, + 0, 18, 0, 19, 18, 0, 20, 0, + 28, 20, 0, 28, 0, 23, 25, 28, + 0, 24, 0, 14, 0, 28, 0, 28, + 0, 2, 1, 2, 1, 0 +}; + +static const char _ansi_parser_trans_actions[] = { + 0, 7, 0, 0, 21, 21, 21, 21, + 21, 21, 21, 21, 0, 31, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 17, 0, 15, 0, 0, + 0, 0, 0, 0, 19, 0, 0, 0, + 3, 0, 0, 0, 1, 0, 25, 0, + 0, 1, 0, 28, 0, 0, 1, 0, + 37, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 5, 0, 11, 0, 13, + 0, 0, 7, 23, 34, 0 +}; + +static const char _ansi_parser_eof_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 23 +}; + +static const int ansi_parser_start = 27; +static const int ansi_parser_first_final = 27; +static const int ansi_parser_error = 0; + +static const int ansi_parser_en_main = 27; + + +#line 125 "ansi_parser.rl" + +#include + +ANSIParser::ANSIParser(sf::Color default_fg, sf::Color default_bg) : + $default_fg(default_fg), + $default_bg(default_bg) +{ +} + +bool ANSIParser::parse(std::wstring_view codes, ColorCB color_cb, WriteCB write_cb) { + const wchar_t *start = nullptr; + int cs = 0; + unsigned int value = 0; + const wchar_t *p = codes.data(); + const wchar_t *pe = p + codes.size(); + const wchar_t *eof = pe; + sf::Color bgcolor($default_bg); + sf::Color color($default_fg); + sf::Color* target = &color; + + +#line 120 "ansi_parser.cpp" + { + cs = ansi_parser_start; + } + +#line 146 "ansi_parser.rl" + +#line 123 "ansi_parser.cpp" + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const int *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _ansi_parser_trans_keys + _ansi_parser_key_offsets[cs]; + _trans = _ansi_parser_index_offsets[cs]; + + _klen = _ansi_parser_single_lengths[cs]; + if ( _klen > 0 ) { + const int *_lower = _keys; + const int *_mid; + const int *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _ansi_parser_range_lengths[cs]; + if ( _klen > 0 ) { + const int *_lower = _keys; + const int *_mid; + const int *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + cs = _ansi_parser_trans_targs[_trans]; + + if ( _ansi_parser_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _ansi_parser_actions + _ansi_parser_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +#line 14 "ansi_parser.rl" + { + start = p; + } + break; + case 1: +#line 18 "ansi_parser.rl" + { + value = 0; + size_t len = p - start; + dbc::check(start[0] != '-', "negative numbers not supported"); + + switch(len) { + case 10: value += (start[len-10] - '0') * 1000000000; [[fallthrough]]; + case 9: value += (start[len- 9] - '0') * 100000000; [[fallthrough]]; + case 8: value += (start[len- 8] - '0') * 10000000; [[fallthrough]]; + case 7: value += (start[len- 7] - '0') * 1000000; [[fallthrough]]; + case 6: value += (start[len- 6] - '0') * 100000; [[fallthrough]]; + case 5: value += (start[len- 5] - '0') * 10000; [[fallthrough]]; + case 4: value += (start[len- 4] - '0') * 1000; [[fallthrough]]; + case 3: value += (start[len- 3] - '0') * 100; [[fallthrough]]; + case 2: value += (start[len- 2] - '0') * 10; [[fallthrough]]; + case 1: value += (start[len- 1] - '0'); + break; + default: + dbc::sentinel("can't process > 10 digits"); + } + } + break; + case 2: +#line 40 "ansi_parser.rl" + { + color_cb(color, bgcolor); + } + break; + case 3: +#line 43 "ansi_parser.rl" + { + target = &color; + } + break; + case 4: +#line 46 "ansi_parser.rl" + { + target = &bgcolor; + } + break; + case 5: +#line 50 "ansi_parser.rl" + { + write_cb((*p)); + } + break; + case 6: +#line 54 "ansi_parser.rl" + { + color = $default_fg; + color_cb(color, bgcolor); + } + break; + case 7: +#line 58 "ansi_parser.rl" + { + bgcolor = $default_bg; + color_cb(color, bgcolor); + } + break; + case 8: +#line 62 "ansi_parser.rl" + { + color = $default_bg; + bgcolor = $default_fg; + color_cb(color, bgcolor); + } + break; + case 9: +#line 67 "ansi_parser.rl" + { + color = $default_fg; + bgcolor = $default_bg; + color_cb(color, bgcolor); + } + break; + case 10: +#line 72 "ansi_parser.rl" + { + color = sf::Color(100,100,100); + color_cb(color, bgcolor); + } + break; + case 11: +#line 76 "ansi_parser.rl" + { + color = sf::Color::Red; + color_cb(color, bgcolor); + } + break; + case 12: +#line 81 "ansi_parser.rl" + { target->r = value; } + break; + case 13: +#line 82 "ansi_parser.rl" + { target->g = value; } + break; + case 14: +#line 83 "ansi_parser.rl" + { target->b = value; } + break; + case 15: +#line 84 "ansi_parser.rl" + { value = 0; } + break; + case 16: +#line 85 "ansi_parser.rl" + {} + break; +#line 296 "ansi_parser.cpp" + } + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + const char *__acts = _ansi_parser_actions + _ansi_parser_eof_actions[cs]; + unsigned int __nacts = (unsigned int) *__acts++; + while ( __nacts-- > 0 ) { + switch ( *__acts++ ) { + case 16: +#line 85 "ansi_parser.rl" + {} + break; +#line 314 "ansi_parser.cpp" + } + } + } + + _out: {} + } + +#line 147 "ansi_parser.rl" + + bool good = pe - p == 0; + + if(!good) { + p -= 10; + // dear cthuhlu, save me from the pain that is wstring + for(int i = 0; i < 100; i++) { + try { + print("{}", p[i] == 0x1B ? '^' : char(p[i])); + } catch(...) { + print("?=", int(p[i])); + } + } + } + + (void)ansi_parser_first_final; + (void)ansi_parser_error; + (void)ansi_parser_en_main; + + + return good; +} diff --git a/ansi_parser.hpp b/ansi_parser.hpp new file mode 100644 index 0000000..9dd054c --- /dev/null +++ b/ansi_parser.hpp @@ -0,0 +1,23 @@ +#pragma once +#include +#include +#include +#include + +typedef std::function ColorCB; + +typedef std::function WriteCB; + +class ANSIParser { + sf::Color $default_fg; + sf::Color $default_bg; + std::wstring_convert> $converter; + +public: + ANSIParser(sf::Color default_fg, sf::Color default_bg); + + // disable copying + ANSIParser(ANSIParser& ap) = delete; + + bool parse(std::wstring_view codes, ColorCB color_cb, WriteCB write_cb); +}; diff --git a/ansi_parser.rl b/ansi_parser.rl new file mode 100644 index 0000000..cc2219e --- /dev/null +++ b/ansi_parser.rl @@ -0,0 +1,167 @@ +#include +#include +#include "dbc.hpp" +#include +#include "ansi_parser.hpp" +#include + +using namespace fmt; + +%%{ + machine ansi_parser; + alphtype int; + + action tstart { + start = fpc; + } + + action number { + value = 0; + size_t len = fpc - start; + dbc::check(start[0] != '-', "negative numbers not supported"); + + switch(len) { + case 10: value += (start[len-10] - '0') * 1000000000; [[fallthrough]]; + case 9: value += (start[len- 9] - '0') * 100000000; [[fallthrough]]; + case 8: value += (start[len- 8] - '0') * 10000000; [[fallthrough]]; + case 7: value += (start[len- 7] - '0') * 1000000; [[fallthrough]]; + case 6: value += (start[len- 6] - '0') * 100000; [[fallthrough]]; + case 5: value += (start[len- 5] - '0') * 10000; [[fallthrough]]; + case 4: value += (start[len- 4] - '0') * 1000; [[fallthrough]]; + case 3: value += (start[len- 3] - '0') * 100; [[fallthrough]]; + case 2: value += (start[len- 2] - '0') * 10; [[fallthrough]]; + case 1: value += (start[len- 1] - '0'); + break; + default: + dbc::sentinel("can't process > 10 digits"); + } + } + + action color_out { + color_cb(color, bgcolor); + } + action is_fg { + target = &color; + } + action is_bg { + target = &bgcolor; + } + + action out { + write_cb(fc); + } + + action reset_fg { + color = $default_fg; + color_cb(color, bgcolor); + } + action reset_bg { + bgcolor = $default_bg; + color_cb(color, bgcolor); + } + action invert { + color = $default_bg; + bgcolor = $default_fg; + color_cb(color, bgcolor); + } + action reset_invert { + color = $default_fg; + bgcolor = $default_bg; + color_cb(color, bgcolor); + } + action half_bright { + color = sf::Color(100,100,100); + color_cb(color, bgcolor); + } + action red_text { + color = sf::Color::Red; + color_cb(color, bgcolor); + } + + action red { target->r = value; } + action blue { target->g = value; } + action green { target->b = value; } + action start { value = 0; } + action end {} + action log { println("command {}", (char)fc); } + + ESC = 0x1B; + start = ESC "["; + fg = "38;" %is_fg; + bg = "48;" %is_bg; + reset = ("39" %reset_fg | "49" %reset_bg); + num = digit+ >tstart %number; + color256 = "5;"; + color24b = "2;"; + + ansi = ( + start %start + ( + reset | + "0" %reset_fg %reset_bg | + "1" | + "2" %half_bright | + "3" | + "4" | + "5" | + "6" | + "7" %invert | + "31" %red_text | + "22" | + "24" | + "27" %reset_invert | + "9" ["0"-"7"] | + "10" ["0"-"7"] | + (fg|bg) (color24b num %red ";" num %blue ";" num %green ) %color_out + ) "m" %end + ); + + other = (any+ @out -- ESC)*; + + main := (other :> ansi)**; +}%% + +%% write data; + +#include + +ANSIParser::ANSIParser(sf::Color default_fg, sf::Color default_bg) : + $default_fg(default_fg), + $default_bg(default_bg) +{ +} + +bool ANSIParser::parse(std::wstring_view codes, ColorCB color_cb, WriteCB write_cb) { + const wchar_t *start = nullptr; + int cs = 0; + unsigned int value = 0; + const wchar_t *p = codes.data(); + const wchar_t *pe = p + codes.size(); + const wchar_t *eof = pe; + sf::Color bgcolor($default_bg); + sf::Color color($default_fg); + sf::Color* target = &color; + + %% write init; + %% write exec; + + bool good = pe - p == 0; + + if(!good) { + p -= 10; + // dear cthuhlu, save me from the pain that is wstring + for(int i = 0; i < 100; i++) { + try { + print("{}", p[i] == 0x1B ? '^' : char(p[i])); + } catch(...) { + print("?=", int(p[i])); + } + } + } + + (void)ansi_parser_first_final; + (void)ansi_parser_error; + (void)ansi_parser_en_main; + + return good; +} diff --git a/assets/ai.json b/assets/ai.json deleted file mode 100644 index 446231e..0000000 --- a/assets/ai.json +++ /dev/null @@ -1,140 +0,0 @@ -{ - "profile": { - "enemy_found": 0, - "enemy_dead": 1, - "health_good": 2, - "no_more_items": 3, - "no_more_enemies": 4, - "in_combat": 5, - "have_item": 6, - "have_healing": 7, - "detect_enemy": 8, - "tough_personality": 9, - "cant_move": 10 - }, - "actions": [ - { - "name": "find_enemy", - "cost": 5, - "needs": { - "detect_enemy": true, - "in_combat": false, - "no_more_enemies": false, - "enemy_found": false - }, - "effects": { - "in_combat": true, - "enemy_found": true - } - }, - { - "name": "run_away", - "cost": 0, - "needs": { - "tough_personality": false, - "in_combat": true, - "have_healing": false, - "health_good": false, - "cant_move": false - }, - "effects": { - "in_combat": false - } - }, - { - "name": "kill_enemy", - "cost": 10, - "needs": { - "no_more_enemies": false, - "in_combat": true, - "enemy_found": true, - "enemy_dead": false - }, - - "effects": { - "enemy_dead": true - } - }, - { - "name": "collect_items", - "cost": 5, - "needs": { - "no_more_enemies": true, - "no_more_items": false - }, - "effects": { - "no_more_items": true - } - }, - { - "name": "find_healing", - "cost": 2, - "needs": { - "have_healing": false, - "in_combat": false, - "health_good": false - }, - "effects": { - "health_good": true - } - }, - { - "name": "use_healing", - "cost": 1, - "needs": { - "have_item": true, - "have_healing": true, - "health_good": false - }, - "effects": { - "health_good": true - } - } - ], - "states": { - "Host::initial_state": { - "enemy_found": false, - "enemy_dead": false, - "health_good": true, - "no_more_items": false, - "no_more_enemies": false, - "in_combat": false, - "have_item": false, - "have_healing": false, - "detect_enemy": true, - "tough_personality": true - }, - "Host::final_state": { - "enemy_found": true, - "enemy_dead": true, - "health_good": true, - "no_more_items": true, - "in_combat": false, - "no_more_enemies": true - }, - "Enemy::initial_state": { - "detect_enemy": false, - "tough_personality": true, - "enemy_found": false, - "enemy_dead": false, - "health_good": true, - "in_combat": false - }, - "Enemy::final_state": { - "detect_enemy": true, - "enemy_found": true, - "enemy_dead": true, - "health_good": true - } - }, - "scripts": { - "Host::actions": - ["find_enemy", - "kill_enemy", - "collect_items", - "find_healing", - "use_healing"], - "Enemy::actions": - ["find_enemy", "run_away", "kill_enemy", "use_healing"] - } -} diff --git a/assets/animations.json b/assets/animations.json deleted file mode 100644 index bfcb8b8..0000000 --- a/assets/animations.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "ritual_blanket": { - "_type": "Animation", - "easing": 0, - "ease_rate": 0.5, - "scale": 1.0, - "simple": false, - "frames": 3, - "speed": 0.2, - "stationary": true - } -} diff --git a/assets/armored_knight_1-256.png b/assets/armored_knight_1-256.png new file mode 100644 index 0000000..b8617eb Binary files /dev/null and b/assets/armored_knight_1-256.png differ diff --git a/assets/armored_knight_1-512.png b/assets/armored_knight_1-512.png new file mode 100644 index 0000000..a8f780a Binary files /dev/null and b/assets/armored_knight_1-512.png differ diff --git a/assets/axe_ranger-256.png b/assets/axe_ranger-256.png new file mode 100644 index 0000000..e5387f3 Binary files /dev/null and b/assets/axe_ranger-256.png differ diff --git a/assets/blood_splatter-256.png b/assets/blood_splatter-256.png new file mode 100644 index 0000000..d80a65f Binary files /dev/null and b/assets/blood_splatter-256.png differ diff --git a/assets/bosses.json b/assets/bosses.json index 2d18cdb..9e1bfa8 100644 --- a/assets/bosses.json +++ b/assets/bosses.json @@ -3,7 +3,7 @@ "components": [ {"_type": "BossFight", "background": "boss_fight_background", - "stage": null, + "stage": false, "weapon_sound": "Sword_Hit_2" }, {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false}, @@ -24,7 +24,7 @@ "components": [ {"_type": "BossFight", "background": "devils_fingers_background", - "stage": "devils_fingers_stage", + "stage": false, "weapon_sound": "Sword_Hit_2" }, {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false}, diff --git a/assets/ceiling_test-256.png b/assets/ceiling_test-256.png new file mode 100644 index 0000000..4bcac90 Binary files /dev/null and b/assets/ceiling_test-256.png differ diff --git a/assets/ceiling_test-512.png b/assets/ceiling_test-512.png new file mode 100644 index 0000000..c1ad1f3 Binary files /dev/null and b/assets/ceiling_test-512.png differ diff --git a/assets/ceiling_worm-256.png b/assets/ceiling_worm-256.png new file mode 100644 index 0000000..805dafe Binary files /dev/null and b/assets/ceiling_worm-256.png differ diff --git a/assets/cinqueda_1-256.png b/assets/cinqueda_1-256.png new file mode 100644 index 0000000..f40dd84 Binary files /dev/null and b/assets/cinqueda_1-256.png differ diff --git a/assets/cinqueda_1-512.png b/assets/cinqueda_1-512.png new file mode 100644 index 0000000..772abd2 Binary files /dev/null and b/assets/cinqueda_1-512.png differ diff --git a/assets/config.json b/assets/config.json index a38faba..ab53aec 100644 --- a/assets/config.json +++ b/assets/config.json @@ -17,233 +17,45 @@ "Marmot_Scream_1": "assets/sounds/Creature_Sounds-Marmot_Scream_1.ogg", "blank": "assets/sounds/blank.ogg", "pickup": "assets/sounds/pickup.ogg", - "ambient_1": "assets/sounds/ambient_1.ogg", - "ui_click": "assets/sounds/ui_click.ogg", - "ui_hover": "assets/sounds/ui_hover.ogg", - "punch_cartoony": "assets/sounds/punch_cartoony.ogg", - "electric_shock_01": "assets/sounds/electric_shock_01.ogg", - "fireball_01": "assets/sounds/fireball_01.ogg", - "hp_status_80": "assets/sounds/hp_status_80.ogg", - "hp_status_60": "assets/sounds/hp_status_60.ogg", - "hp_status_30": "assets/sounds/hp_status_30.ogg", - "hp_status_10": "assets/sounds/hp_status_10.ogg", - "hp_status_00": "assets/sounds/hp_status_00.ogg" + "ambient_1": "assets/sounds/ambient_1.ogg" }, "sprites": { - "gold_savior": - {"path": "assets/sprites/gold_savior.png", - "frame_width": 256, - "frame_height": 256 - }, - "armored_knight": - {"path": "assets/sprites/armored_knight_1.png", - "frame_width": 256, - "frame_height": 256 - }, - "axe_ranger": - {"path": "assets/sprites/axe_ranger.png", - "frame_width": 256, - "frame_height": 256 - }, - "hairy_spider": - {"path": "assets/sprites/hairy_spider.png", - "frame_width": 256, - "frame_height": 256 - }, - "rat_with_sword": - {"path": "assets/sprites/rat_with_sword.png", - "frame_width": 256, - "frame_height": 256 - }, - "rat_king_boss": - {"path": "assets/bossfights/rat_king_2_frame_animation.png", - "frame_width": 720, - "frame_height": 720 - }, - "barrel_small": - {"path": "assets/items/wood_barrel_small.png", - "frame_width": 256, - "frame_height": 256 - }, - "torch_pillar": - {"path": "assets/sprites/torch_pillar.png", - "frame_width": 256, - "frame_height": 256 - }, - "torch_crappy": - {"path": "assets/items/torch_crappy.png", - "frame_width": 256, - "frame_height": 256 - }, - "torch_horizontal_floor": - {"path": "assets/items/torch_horizontal_floor.png", - "frame_width": 256, - "frame_height": 256 - }, - "peasant_girl": - {"path": "assets/sprites/peasant_girl_2.png", - "frame_width": 256, - "frame_height": 256 - }, - "grave_stone": - {"path": "assets/sprites/grave_stone.png", - "frame_width": 256, - "frame_height": 256 - }, - "healing_potion_small": - {"path": "assets/items/healing_potion_small.png", - "frame_width": 256, - "frame_height": 256 - }, - "well_down": - {"path": "assets/sprites/well_down.png", - "frame_width": 256, - "frame_height": 256 - }, - "rope_vines_up": - {"path": "assets/sprites/rope_vines_up.png", - "frame_width": 256, - "frame_height": 256 - }, - "tripwire_trap": - {"path": "assets/sprites/tripwire_trap.png", - "frame_width": 256, - "frame_height": 256 - }, - "boss_fight_background": - {"path": "assets/bossfights/rat_king_boss_fight_background.jpg", - "frame_width": 1080, - "frame_height": 720 - }, - "devils_fingers_background": - {"path": "assets/bossfights/devils_fingers_background.jpg", - "frame_width": 1080, - "frame_height": 720 - }, - "devils_fingers_sprite": - {"path": "assets/bossfights/devils_fingers_sprite.png", - "frame_width": 720, - "frame_height": 720 - }, - "devils_fingers_stage": - {"path": "assets/bossfights/devils_fingers_stage.png", - "frame_width": 1080, - "frame_height": 720 - }, - "tunnel_with_rocks": - {"path": "assets/bossfights/tunnel_with_rocks.png", - "frame_width": 1080, - "frame_height": 720 - }, - "tunnel_with_rocks_stage": - {"path": "assets/bossfights/tunnel_with_rocks_stage.png", - "frame_width": 1080, - "frame_height": 720 - }, - "ritual_crafting_area": - {"path": "assets/ui/ritual_crafting_area.png", - "frame_width": 380, - "frame_height": 720 - }, - "full_screen_paper": - {"path": "assets/ui/full_screen_paper.png", - "frame_width": 1280, - "frame_height": 720 - }, - "broken_locket": - {"path": "assets/items/broken_locket.png", - "frame_width": 256, - "frame_height": 256 - }, - "broken_pen_knife": - {"path": "assets/items/broken_pen_knife.png", - "frame_width": 256, - "frame_height": 256 - }, - "broken_yoyo": - {"path": "assets/items/broken_yoyo.png", - "frame_width": 256, - "frame_height": 256 - }, - "chess_pawn": - {"path": "assets/items/chess_pawn.png", - "frame_width": 256, - "frame_height": 256 - }, - "dirty_kerchief": - {"path": "assets/items/dirty_kerchief.png", - "frame_width": 256, - "frame_height": 256 - }, - "leather_pouch": - {"path": "assets/items/leather_pouch.png", - "frame_width": 256, - "frame_height": 256 - }, - "mushroom": - {"path": "assets/items/mushroom.png", - "frame_width": 256, - "frame_height": 256 - }, - "pocket_watch": - {"path": "assets/items/pocket_watch.png", - "frame_width": 256, - "frame_height": 256 - }, - "rusty_nails": - {"path": "assets/items/rusty_nails.png", - "frame_width": 256, - "frame_height": 256 - }, - "severed_finger": - {"path": "assets/items/severed_finger.png", - "frame_width": 256, - "frame_height": 256 - }, - "stone_doll_cursed": - {"path": "assets/items/stone_doll_cursed.png", - "frame_width": 256, - "frame_height": 256 - }, - "dubious_combination": - {"path": "assets/items/dubious_combination.png", - "frame_width": 256, - "frame_height": 256 - }, - "dead_body": - {"path": "assets/sprites/dead_body.png", - "frame_width": 256, - "frame_height": 256 - }, - "dead_body_lootable": - {"path": "assets/sprites/dead_body_lootable.png", - "frame_width": 256, - "frame_height": 256 - } + "armored_knight": "assets/armored_knight_1-256.png", + "sword": "assets/cinqueda_1-512.png", + "rat_with_sword": "assets/rat_with_sword-256.png", + "rat_king": "assets/rat_king-256.png", + "rat_king_boss": "assets/rat_king_2_frame_animation.png", + "barrel_small": "assets/wood_barrel_small-256.png", + "hanging_brazier": "assets/hanging_brazier-256.png", + "torch_pillar": "assets/torch_pillar-256.png", + "torch_crappy": "assets/torch_crappy-256.png", + "torch_horizontal_floor": "assets/torch_horizontal_floor-256.png", + "evil_eye": "assets/evil_eye-sprites.png", + "peasant_girl": "assets/undead_peasant-256.png", + "grave_stone": "assets/grave_stone-256.png", + "floor": "assets/floor_tile_test-256.png", + "ceiling": "assets/ceiling_test-256.png", + "healing_potion_small": "assets/healing_potion_small-256.png", + "well_down": "assets/well_down-256.png", + "rope_vines_up": "assets/rope_vines_up-256.png", + "tripwire_trap": "assets/tripwire_trap-256.png", + "cinqueda": "assets/cinqueda_1-256.png", + "left_gui": "assets/left_gui.png", + "blood_splatter": "assets/blood_splatter-256.png", + "trash_button": "assets/trash_button.png", + "axe_ranger": "assets/axe_ranger-256.png", + "hairy_spider": "assets/hairy_spider-256.png", + "down_the_well": "assets/down_the_well.jpg", + "boss_fight_background": "assets/rat_king_boss_fight_background.jpg", + "devils_fingers_background": "assets/devils_fingers_background.jpg", + "devils_fingers_sprite": "assets/devils_fingers_sprite.png", + "devils_fingers_stage": "assets/devils_fingers_stage.png", + "tunnel_with_rocks": "assets/tunnel_with_rocks.png", + "tunnel_with_rocks_stage": "assets/tunnel_with_rocks_stage.png" }, "worldgen": { - "enemy_probability": 50, + "enemy_probability": 80, + "empty_room_probability": 10, "device_probability": 10 - }, - "graphics": { - "smooth_textures": false - }, - "compass": { - "N": 65514, - "NE": 8663, - "E": 8594, - "SE": 8600, - "S": 65516, - "SW": 8665, - "W": 8592, - "NW": 8598 - }, - "theme": { - "NOTE": "colors are in assets/palette.json", - "padding": 3, - "border_px": 1, - "text_size": 20, - "label_size": 20, - "font_file_name": "assets/text.otf" } } diff --git a/assets/devices.json b/assets/devices.json index 58b7897..44482fc 100644 --- a/assets/devices.json +++ b/assets/devices.json @@ -7,13 +7,13 @@ "inventory_count": 0, "randomized": false, "components": [ - {"_type": "Tile", "display": 6105, - "foreground": "devices/fg:stairs_down", - "background": "devices/bg:stairs_down" + {"_type": "Tile", "display": "\u2ac5", + "foreground": [24, 205, 189], + "background": [24, 205, 189] }, {"_type": "Device", - "config": {}, - "events": ["STAIRS_DOWN"]}, + "config": {"test": true}, + "events": ["Events::GUI::STAIRS_DOWN"]}, {"_type": "Sprite", "name": "well_down", "width": 256, "height": 256, "scale": 1.0} ] }, @@ -24,13 +24,13 @@ "inventory_count": 0, "placement": "fixed", "components": [ - {"_type": "Tile", "display": 8793, - "foreground": "devices/fg:stairs_up", - "background": "devices/fg:stairs_up" + {"_type": "Tile", "display": "\u2259", + "foreground": [24, 205, 189], + "background": [24, 205, 189] }, {"_type": "Device", - "config": {}, - "events": ["STAIRS_UP"]}, + "config": {"test": true}, + "events": ["Events::GUI::STAIRS_UP"]}, {"_type": "Sprite", "name": "rope_vines_up", "width": 256, "height": 256, "scale": 1.0} ] }, @@ -40,66 +40,14 @@ "description": "Watch where you're going.", "inventory_count": 0, "components": [ - {"_type": "Tile", "display": 95, - "foreground": "devices/fg:tripwire", - "background": "devices/bg:tripwire" + {"_type": "Tile", "display": "\u1ac7", + "foreground": [24, 205, 189], + "background": [24, 205, 189] }, - {"_type": "Device", "config": {}, "events": ["TRAP"]}, + {"_type": "Device", + "config": {"test": true}, + "events": ["Events::GUI::TRAP"]}, {"_type": "Sprite", "name": "tripwire_trap", "width": 256, "height": 256, "scale": 1.0} ] - }, - "BARREL_SMALL": { - "id": "BARREL_SMALL", - "name": "Small Barrel", - "description": "A small rotten barrel that may hold things.", - "components": [ - {"_type": "Tile", "display": 85, - "foreground": "devices/fg:barrel", - "background": "devices/bg:barrel" - }, - {"_type": "Device", "config": {}, "events": ["LOOT_CONTAINER"]}, - {"_type": "Sprite", "name": "barrel_small", "width": 256, "height": 256, "scale": 1.0}, - {"_type": "Sound", "attack": "pickup", "death": "blank"} - ] - }, - "GRAVE_STONE": { - "id": "GRAVE_STONE", - "name": "Grave Stone", - "description": "Something died here. Was this your doing?", - "components": [ - {"_type": "Tile", "display": 8687, - "foreground": "devices/fg:grave_stone", - "background": "devices/bg:grave_stone" - }, - {"_type": "Device", "config": {}, "events": ["LOOT_CONTAINER"]}, - {"_type": "Sprite", "name": "grave_stone", "width": 256, "height": 256, "scale": 1.0}, - {"_type": "Sound", "attack": "pickup", "death": "blank"} - ] - }, - "DEAD_BODY_LOOTABLE": { - "id": "DEAD_BODY_LOOTABLE", - "name": "Grave Stone", - "description": "Something died here. Was this your doing?", - "components": [ - {"_type": "Tile", "display": 1890, - "foreground": "devices/fg:dead_body_lootable", - "background": "devices/bg:dead_body_lootable" - }, - {"_type": "Device", "config": {}, "events": ["LOOT_CONTAINER"]}, - {"_type": "Sprite", "name": "dead_body_lootable", "width": 256, "height": 256, "scale": 1.0}, - {"_type": "Sound", "attack": "pickup", "death": "blank"} - ] - }, - "DEAD_BODY": { - "id": "DEAD_BODY", - "name": "Something Dead", - "description": "You can't loot this, weirdo.", - "components": [ - {"_type": "Tile", "display": 1939, - "foreground": "devices/fg:dead_body", - "background": "devices/bg:dead_body" - }, - {"_type": "Sprite", "name": "dead_body", "width": 256, "height": 256, "scale": 1.0} - ] } } diff --git a/assets/bossfights/devils_fingers_background.jpg b/assets/devils_fingers_background.jpg similarity index 100% rename from assets/bossfights/devils_fingers_background.jpg rename to assets/devils_fingers_background.jpg diff --git a/assets/bossfights/devils_fingers_sprite.png b/assets/devils_fingers_sprite.png similarity index 100% rename from assets/bossfights/devils_fingers_sprite.png rename to assets/devils_fingers_sprite.png diff --git a/assets/bossfights/devils_fingers_stage.png b/assets/devils_fingers_stage.png similarity index 100% rename from assets/bossfights/devils_fingers_stage.png rename to assets/devils_fingers_stage.png diff --git a/assets/bossfights/down_the_well.jpg b/assets/down_the_well.jpg similarity index 100% rename from assets/bossfights/down_the_well.jpg rename to assets/down_the_well.jpg diff --git a/assets/enemies.json b/assets/enemies.json index 5fbd8a1..ca46990 100644 --- a/assets/enemies.json +++ b/assets/enemies.json @@ -2,43 +2,24 @@ "PLAYER_TILE": { "placement": "fixed", "components": [ - {"_type": "Tile", "display": 10733, - "foreground": "enemies/fg:player", - "background": "color:transparent" + {"_type": "Tile", "display": "\ua66b", + "foreground": [255, 200, 125], + "background": [30, 20, 75] }, {"_type": "Combat", "hp": 200, "max_hp": 200, "damage": 10, "dead": false}, {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, - {"_type": "Collision", "has": true}, - {"_type": "LightSource", "strength": 35, "radius": 2.0} - ] - }, - "GOLD_SAVIOR": { - "components": [ - {"_type": "Tile", "display": 42586, - "foreground": "enemies/fg:gold_savior", - "background": "color:transparent" - }, - {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 1, "dead": false}, - {"_type": "Collision", "has": true}, - {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, - {"_type": "EnemyConfig", "ai_script": "Enemy::actions", "ai_start_name": "Enemy::initial_state", "ai_goal_name": "Enemy::final_state"}, - {"_type": "Personality", "hearing_distance": 5, "tough": true}, - {"_type": "Animation", "easing": 1, "ease_rate": 0.2, "scale": 0.1, "simple": true, "frames": 10, "speed": 0.3, "stationary": false}, - {"_type": "Sprite", "name": "gold_savior", "width": 256, "height": 256, "width": 256, "height": 256, "scale": 1.0}, - {"_type": "Sound", "attack": "Sword_Hit_2", "death": "Humanoid_Death_1"} + {"_type": "LightSource", "strength": 45, "radius": 2.0} ] }, "KNIGHT": { "components": [ - {"_type": "Tile", "display": 2216, - "foreground": "enemies/fg:knight", - "background": "color:transparent" + {"_type": "Tile", "display": "\u088d", + "foreground": [131, 213, 238], + "background": [30, 20, 75] }, {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 1, "dead": false}, - {"_type": "Collision", "has": true}, {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, - {"_type": "EnemyConfig", "ai_script": "Enemy::actions", "ai_start_name": "Enemy::initial_state", "ai_goal_name": "Enemy::final_state"}, - {"_type": "Personality", "hearing_distance": 5, "tough": true}, + {"_type": "EnemyConfig", "hearing_distance": 5}, {"_type": "Animation", "easing": 1, "ease_rate": 0.2, "scale": 0.1, "simple": true, "frames": 10, "speed": 0.3, "stationary": false}, {"_type": "Sprite", "name": "armored_knight", "width": 256, "height": 256, "width": 256, "height": 256, "scale": 1.0}, {"_type": "Sound", "attack": "Sword_Hit_2", "death": "Humanoid_Death_1"} @@ -46,47 +27,41 @@ }, "AXE_RANGER": { "components": [ - {"_type": "Tile", "display": 1898, - "foreground": "enemies/fg:axe_ranger", - "background": "color:transparent" + {"_type": "Tile", "display": "\u076a", + "foreground": [156, 172, 197], + "background": [30, 20, 75] }, {"_type": "Combat", "hp": 40, "max_hp": 40, "damage": 10, "dead": false}, - {"_type": "Collision", "has": true}, {"_type": "Motion", "dx": 0, "dy": 0, "random": true}, - {"_type": "EnemyConfig", "ai_script": "Enemy::actions", "ai_start_name": "Enemy::initial_state", "ai_goal_name": "Enemy::final_state"}, - {"_type": "Personality", "hearing_distance": 5, "tough": true}, + {"_type": "EnemyConfig", "hearing_distance": 5}, {"_type": "Sprite", "name": "axe_ranger", "width": 256, "height": 256, "scale": 1.0}, - {"_type": "Animation", "easing": 3, "ease_rate": 0.5, "scale": 0.1, "simple": true, "frames": 1, "speed": 0.6, "stationary": false}, + {"_type": "Animation", "easing": 3, "ease_rate": 0.5, "scale": 0.1, "simple": false, "frames": 2, "speed": 0.6, "stationary": false}, {"_type": "Sound", "attack": "Sword_Hit_2", "death": "Ranger_1"} ] }, "RAT_GIANT": { "components": [ - {"_type": "Tile", "display": 2220, - "foreground": "enemies/fg:rat_giant", - "background": "color:transparent" + {"_type": "Tile", "display": "\u08ac", + "foreground": [205, 164, 246], + "background": [30, 20, 75] }, - {"_type": "Combat", "hp": 50, "max_hp": 50, "damage": 2, "dead": false}, - {"_type": "Collision", "has": true}, + {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false}, {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, - {"_type": "EnemyConfig", "ai_script": "Enemy::actions", "ai_start_name": "Enemy::initial_state", "ai_goal_name": "Enemy::final_state"}, - {"_type": "Personality", "hearing_distance": 5, "tough": true}, - {"_type": "Animation", "easing": 3, "ease_rate": 0.5, "scale": 0.1, "simple": true, "frames": 1, "speed": 1.0, "stationary": false}, + {"_type": "EnemyConfig", "hearing_distance": 10}, + {"_type": "Animation", "easing": 3, "ease_rate": 0.5, "scale": 0.1, "simple": true, "frames": 10, "speed": 1.0, "stationary": false}, {"_type": "Sprite", "name": "rat_with_sword", "width": 256, "height": 256, "scale": 1.0}, {"_type": "Sound", "attack": "Small_Rat", "death": "Creature_Death_1"} ] }, "SPIDER_GIANT_HAIRY": { "components": [ - {"_type": "Tile", "display": 1218, - "foreground": "enemies/fg:spider_giant", - "background": "color:transparent" + {"_type": "Tile", "display": "\u08ea", + "foreground": [205, 164, 246], + "background": [30, 20, 75] }, {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false}, - {"_type": "Collision", "has": true}, {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, - {"_type": "EnemyConfig", "ai_script": "Enemy::actions", "ai_start_name": "Enemy::initial_state", "ai_goal_name": "Enemy::final_state"}, - {"_type": "Personality", "hearing_distance": 5, "tough": true}, + {"_type": "EnemyConfig", "hearing_distance": 10}, {"_type": "Animation", "easing": 2, "ease_rate": 0.5, "scale": 0.1, "simple": true, "frames": 10, "speed": 1.0, "stationary": false}, {"_type": "Sprite", "name": "hairy_spider", "width": 256, "height": 256, "scale": 1.0}, {"_type": "Sound", "attack": "Spider_1", "death": "Spider_2"} diff --git a/assets/evil_eye-sprites.png b/assets/evil_eye-sprites.png new file mode 100644 index 0000000..4a38728 Binary files /dev/null and b/assets/evil_eye-sprites.png differ diff --git a/assets/evil_eye_test-256.png b/assets/evil_eye_test-256.png new file mode 100644 index 0000000..c6364c3 Binary files /dev/null and b/assets/evil_eye_test-256.png differ diff --git a/assets/evil_eye_test-512.png b/assets/evil_eye_test-512.png new file mode 100644 index 0000000..0c9ee45 Binary files /dev/null and b/assets/evil_eye_test-512.png differ diff --git a/assets/floor_tile_test-256.png b/assets/floor_tile_test-256.png new file mode 100644 index 0000000..56a2c5e Binary files /dev/null and b/assets/floor_tile_test-256.png differ diff --git a/assets/floor_tile_test-512.png b/assets/floor_tile_test-512.png new file mode 100644 index 0000000..26df65f Binary files /dev/null and b/assets/floor_tile_test-512.png differ diff --git a/assets/grave_stone-256.png b/assets/grave_stone-256.png new file mode 100644 index 0000000..4bd9d4b Binary files /dev/null and b/assets/grave_stone-256.png differ diff --git a/assets/hairy_spider-256.png b/assets/hairy_spider-256.png new file mode 100644 index 0000000..be2b67f Binary files /dev/null and b/assets/hairy_spider-256.png differ diff --git a/assets/hanging_brazier-256.png b/assets/hanging_brazier-256.png new file mode 100644 index 0000000..005defd Binary files /dev/null and b/assets/hanging_brazier-256.png differ diff --git a/assets/healing_potion_small-256.png b/assets/healing_potion_small-256.png new file mode 100644 index 0000000..0a6c770 Binary files /dev/null and b/assets/healing_potion_small-256.png differ diff --git a/assets/icons.json b/assets/icons.json deleted file mode 100644 index 904cd97..0000000 --- a/assets/icons.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "healing_potion_small": - {"path": "assets/icons/healing_potion_small.png", - "frame_width": 96, - "frame_height": 96 - }, - "torch_horizontal_floor": - {"path": "assets/icons/torch_horizontal_floor.png", - "frame_width": 96, - "frame_height": 96 - } -} diff --git a/assets/icons/healing_potion_small.png b/assets/icons/healing_potion_small.png deleted file mode 100644 index 491579a..0000000 Binary files a/assets/icons/healing_potion_small.png and /dev/null differ diff --git a/assets/icons/torch_horizontal_floor.png b/assets/icons/torch_horizontal_floor.png deleted file mode 100644 index 2382d7f..0000000 Binary files a/assets/icons/torch_horizontal_floor.png and /dev/null differ diff --git a/assets/items.json b/assets/items.json index 5c25db3..5bb7d4d 100644 --- a/assets/items.json +++ b/assets/items.json @@ -6,27 +6,87 @@ "inventory_count": 1, "components": [ {"_type": "LightSource", "strength": 50, "radius": 2.5}, - {"_type": "Tile", "display": 3848, - "foreground": "items/fg:flame", - "background": "color:transparent" + {"_type": "Tile", "display": "\u0f08", + "foreground": [24, 120, 189], + "background": [230,120, 120] }, {"_type": "Sprite", "name": "torch_horizontal_floor", "width": 256, "height": 256, "scale": 1.0}, {"_type": "Sound", "attack": "pickup", "death": "blank"} ] }, + "SWORD_RUSTY": { + "id": "SWORD_RUSTY", + "name": "Rusty Junk Sword", + "description": "A sword left to rot in a deep hole where it acquired a patina of dirt and tetanus. You aren't sure if it's more deadly for you to hold it or for the people you stab with it.", + "inventory_count": 1, + "components": [ + {"_type": "Weapon", "damage": 15}, + {"_type": "Tile", "display": "\u1e37", + "foreground": [24, 120, 189], + "background": [24, 120, 189] + }, + {"_type": "Sprite", "name": "cinqueda", "width": 256, "height": 256, "scale": 1.0}, + {"_type": "Sound", "attack": "pickup", "death": "blank"} + ] + }, + "BARREL_SMALL": { + "id": "BARREL_SMALL", + "name": "Small Barrel", + "description": "A small rotten barrel that may hold things.", + "components": [ + {"_type": "Tile", "display": "\uaaea", + "foreground": [150, 100, 189], + "background": [150, 100, 189] + }, + {"_type": "Loot", "amount": 10}, + {"_type": "Sprite", "name": "barrel_small", "width": 256, "height": 256, "scale": 1.0}, + {"_type": "Sound", "attack": "pickup", "death": "blank"} + ], + "inventory_count": 1 + }, + "TORCH_PILLAR": { + "id": "TORCH_PILLAR", + "name": "Light Hanging from Ceiling", + "description": "Light Hanging from Ceiling", + "inventory_count": 0, + "components": [ + {"_type": "Tile", "display": "\u077e", + "foreground": [24, 205, 210], + "background": [24, 205, 210] + }, + {"_type": "LightSource", "strength": 50, "radius": 2.8}, + {"_type": "Sprite", "name": "torch_pillar", "width": 256, "height": 256, "scale": 1.0}, + {"_type": "Sound", "attack": "pickup", "death": "blank"} + ] + }, "POTION_HEALING_SMALL": { "id": "POTION_HEALING_SMALL", "name": "Small Healing Potion", "description": "A small healing potion.", "inventory_count": 1, "components": [ - {"_type": "Tile", "display": 1003, - "foreground": "items/fg:potion", - "background": "color:transparent" + {"_type": "Tile", "display": "\u03eb", + "foreground": [255, 205, 189], + "background": [255, 205, 189] }, {"_type": "Curative", "hp": 20}, {"_type": "Sprite", "name": "healing_potion_small", "width": 256, "height": 256, "scale": 1.0}, {"_type": "Sound", "attack": "pickup", "death": "blank"} ] + }, + "GRAVE_STONE": { + "id": "GRAVE_STONE", + "name": "Grave Stone", + "description": "Something died here. Was this your doing?", + "inventory_count": 1, + "components": [ + {"_type": "Tile", "display": "\u21ef", + "foreground": [32, 123, 164], + "background": [24, 205, 189] + }, + {"_type": "Loot", "amount": 10}, + {"_type": "Sprite", "name": "grave_stone", "width": 256, "height": 256, "scale": 1.0}, + {"_type": "Sound", "attack": "pickup", "death": "blank"} + ] } } diff --git a/assets/items/broken_locket.png b/assets/items/broken_locket.png deleted file mode 100644 index 5c138c2..0000000 Binary files a/assets/items/broken_locket.png and /dev/null differ diff --git a/assets/items/broken_pen_knife.png b/assets/items/broken_pen_knife.png deleted file mode 100644 index e802d87..0000000 Binary files a/assets/items/broken_pen_knife.png and /dev/null differ diff --git a/assets/items/broken_yoyo.png b/assets/items/broken_yoyo.png deleted file mode 100644 index e848cb2..0000000 Binary files a/assets/items/broken_yoyo.png and /dev/null differ diff --git a/assets/items/chess_pawn.png b/assets/items/chess_pawn.png deleted file mode 100644 index c79180b..0000000 Binary files a/assets/items/chess_pawn.png and /dev/null differ diff --git a/assets/items/cinqueda.png b/assets/items/cinqueda.png deleted file mode 100644 index abf4e34..0000000 Binary files a/assets/items/cinqueda.png and /dev/null differ diff --git a/assets/items/dirty_kerchief.png b/assets/items/dirty_kerchief.png deleted file mode 100644 index 8618ada..0000000 Binary files a/assets/items/dirty_kerchief.png and /dev/null differ diff --git a/assets/items/dubious_combination.png b/assets/items/dubious_combination.png deleted file mode 100644 index 8247a59..0000000 Binary files a/assets/items/dubious_combination.png and /dev/null differ diff --git a/assets/items/healing_postion_small.png b/assets/items/healing_postion_small.png deleted file mode 100644 index a2c6f54..0000000 Binary files a/assets/items/healing_postion_small.png and /dev/null differ diff --git a/assets/items/healing_potion_small.png b/assets/items/healing_potion_small.png deleted file mode 100644 index b3c8558..0000000 Binary files a/assets/items/healing_potion_small.png and /dev/null differ diff --git a/assets/items/leather_pouch.png b/assets/items/leather_pouch.png deleted file mode 100644 index dc57254..0000000 Binary files a/assets/items/leather_pouch.png and /dev/null differ diff --git a/assets/items/mushroom.png b/assets/items/mushroom.png deleted file mode 100644 index f6e8bc4..0000000 Binary files a/assets/items/mushroom.png and /dev/null differ diff --git a/assets/items/pocket_watch.png b/assets/items/pocket_watch.png deleted file mode 100644 index 07821f7..0000000 Binary files a/assets/items/pocket_watch.png and /dev/null differ diff --git a/assets/items/rusty_nails.png b/assets/items/rusty_nails.png deleted file mode 100644 index f1eb884..0000000 Binary files a/assets/items/rusty_nails.png and /dev/null differ diff --git a/assets/items/severed_finger.png b/assets/items/severed_finger.png deleted file mode 100644 index 187def8..0000000 Binary files a/assets/items/severed_finger.png and /dev/null differ diff --git a/assets/items/stone_doll_cursed.png b/assets/items/stone_doll_cursed.png deleted file mode 100644 index e99ef76..0000000 Binary files a/assets/items/stone_doll_cursed.png and /dev/null differ diff --git a/assets/items/torch_crappy.png b/assets/items/torch_crappy.png deleted file mode 100644 index c31ee6d..0000000 Binary files a/assets/items/torch_crappy.png and /dev/null differ diff --git a/assets/items/torch_horizontal_floor.png b/assets/items/torch_horizontal_floor.png deleted file mode 100644 index 474ede9..0000000 Binary files a/assets/items/torch_horizontal_floor.png and /dev/null differ diff --git a/assets/items/wood_barrel_small.png b/assets/items/wood_barrel_small.png deleted file mode 100644 index a172fd1..0000000 Binary files a/assets/items/wood_barrel_small.png and /dev/null differ diff --git a/assets/left_gui.png b/assets/left_gui.png new file mode 100644 index 0000000..a16cdac Binary files /dev/null and b/assets/left_gui.png differ diff --git a/assets/map_tiles.json b/assets/map_tiles.json deleted file mode 100644 index a0e2623..0000000 --- a/assets/map_tiles.json +++ /dev/null @@ -1,140 +0,0 @@ -[ - { - "centered": false, - "display": 35, - "x": 0, - "y": 0 - }, - { - "centered": false, - "display": 8284, - "x": 64, - "y": 0 - }, - { - "centered": false, - "display": 11590, - "x": 128, - "y": 0 - }, - { - "centered": false, - "display": 10899, - "x": 192, - "y": 0 - }, - { - "centered": false, - "display": 9256, - "x": 256, - "y": 0 - }, - { - "centered": false, - "display": 9608, - "x": 320, - "y": 0 - }, - { - "centered": false, - "display": 10747, - "x": 384, - "y": 0 - }, - { - "centered": false, - "display": 8285, - "x": 448, - "y": 0 - }, - { - "centered": true, - "display": 1003, - "x": 512, - "y": 0 - }, - { - "centered": true, - "display": 3848, - "x": 576, - "y": 0 - }, - { - "centered": true, - "display": 85, - "x": 0, - "y": 64 - }, - { - "centered": true, - "display": 1939, - "x": 64, - "y": 64 - }, - { - "centered": true, - "display": 1890, - "x": 128, - "y": 64 - }, - { - "centered": true, - "display": 8687, - "x": 192, - "y": 64 - }, - { - "centered": true, - "display": 6105, - "x": 256, - "y": 64 - }, - { - "centered": true, - "display": 8793, - "x": 320, - "y": 64 - }, - { - "centered": true, - "display": 95, - "x": 384, - "y": 64 - }, - { - "centered": true, - "display": 1898, - "x": 448, - "y": 64 - }, - { - "centered": true, - "display": 42586, - "x": 512, - "y": 64 - }, - { - "centered": true, - "display": 2216, - "x": 576, - "y": 64 - }, - { - "centered": true, - "display": 10733, - "x": 0, - "y": 128 - }, - { - "centered": true, - "display": 2220, - "x": 64, - "y": 128 - }, - { - "centered": true, - "display": 1218, - "x": 128, - "y": 128 - } -] diff --git a/assets/map_tiles.png b/assets/map_tiles.png deleted file mode 100644 index 67c5ae3..0000000 Binary files a/assets/map_tiles.png and /dev/null differ diff --git a/assets/palette.json b/assets/palette.json deleted file mode 100644 index 3fde82c..0000000 --- a/assets/palette.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "color": { - "transparent": [100, 100, 100, 100], - "BAD": [255, 0, 0] - }, - "gui/theme": { - "black": [0, 0, 0, 255], - "dark_dark": [10, 10, 10, 255], - "dark_mid": [30, 30, 30, 255], - "dark_light": [60, 60, 60, 255], - "mid": [100, 100, 100, 255], - "light_dark": [150, 150, 150, 255], - "light_mid": [200, 200, 200, 255], - "light_light": [230, 230, 230, 255], - "white": [255, 255, 255, 255], - "fill_color": "gui/theme:dark_mid", - "text_color": "gui/theme:light_light", - "bg_color": "gui/theme:mid", - "border_color": "gui/theme:dark_dark", - "bg_color_dark": "gui/theme:black" - }, - "map/theme": { - "black": [0, 0, 0, 255], - "dark_dark": [10, 10, 10, 255], - "dark_mid": [30, 30, 30, 255], - "dark_light": [60, 60, 60, 255], - "mid": [100, 100, 100, 255], - "light_dark": [150, 150, 150, 255], - "light_mid": [200, 200, 200, 255], - "light_light": [230, 230, 230, 255], - "white": [255, 255, 255, 255] - }, - "items/fg": { - "flame": "map/theme:white", - "potion": "map/theme:white" - }, - "enemies/fg": { - "player": "map/theme:white", - "gold_savior": "map/theme:white", - "knight": "map/theme:white", - "axe_ranger": "map/theme:white", - "rat_giant": "map/theme:white", - "spider_giant": "map/theme:white" - }, - "tiles/fg": { - "floor_tile": "map/theme:mid", - "wall_plain": "map/theme:dark_mid", - "wall_moss": "map/theme:dark_light", - "ceiling_black": "color:transparent", - "lava_floor": [200, 100, 100], - "gray_stone_floor_light": [40, 60, 180], - "wood_wall": "map/theme:dark_mid" - }, - "tiles/bg": { - "floor_tile": "map/theme:dark_dark", - "wall_plain": "map/theme:dark_dark", - "wall_moss": "map/theme:light_dark", - "ceiling_black": "color:transparent", - "lava_floor": "map/theme:dark_dark", - "gray_stone_floor_light": "map/theme:dark_mid", - "wood_wall": "map/theme:dark_dark" - }, - "devices/fg": { - "stairs_down": [24, 205, 189], - "stairs_up": [24, 205, 189], - "tripwire": [24, 205, 189], - "barrel": [150, 100, 189], - "grave_stone": [32, 123, 164], - "dead_body": [32, 123, 164], - "dead_body_lootable": [32, 123, 164] - }, - "devices/bg": { - "stairs_down": [24, 205, 189], - "stairs_up": [24, 205, 189], - "tripwire": [24, 205, 189], - "barrel": [150, 100, 189], - "grave_stone": [24, 205, 189], - "dead_body": [24, 205, 189], - "dead_body_lootable": [24, 205, 189] - } -} diff --git a/assets/rat-king-boss-fight-test-small.jpg b/assets/rat-king-boss-fight-test-small.jpg new file mode 100644 index 0000000..5ad3dd6 Binary files /dev/null and b/assets/rat-king-boss-fight-test-small.jpg differ diff --git a/assets/rat_king-256.png b/assets/rat_king-256.png new file mode 100644 index 0000000..a2315c4 Binary files /dev/null and b/assets/rat_king-256.png differ diff --git a/assets/bossfights/rat_king_2_frame_animation.png b/assets/rat_king_2_frame_animation.png similarity index 100% rename from assets/bossfights/rat_king_2_frame_animation.png rename to assets/rat_king_2_frame_animation.png diff --git a/assets/bossfights/rat_king_boss_fight_background.jpg b/assets/rat_king_boss_fight_background.jpg similarity index 100% rename from assets/bossfights/rat_king_boss_fight_background.jpg rename to assets/rat_king_boss_fight_background.jpg diff --git a/assets/bossfights/rat_king_boss_fight_sprite.png b/assets/rat_king_boss_fight_sprite.png similarity index 100% rename from assets/bossfights/rat_king_boss_fight_sprite.png rename to assets/rat_king_boss_fight_sprite.png diff --git a/assets/rat_with_sword-256.png b/assets/rat_with_sword-256.png new file mode 100644 index 0000000..86e8ecb Binary files /dev/null and b/assets/rat_with_sword-256.png differ diff --git a/assets/rituals.json b/assets/rituals.json deleted file mode 100644 index 6b34963..0000000 --- a/assets/rituals.json +++ /dev/null @@ -1,202 +0,0 @@ -{ - "profile": { - "has_spikes": 0, - "has_magick": 1, - "shiny_bauble": 2, - "cursed_item": 3, - "$does_physical": 4, - "$does_magick": 5, - "$does_damage": 6, - "$user_cursed": 7, - "$does_healing": 8, - "$damage_boost": 9, - "$large_boost": 10, - "$is_complete": 11 - }, - "actions": [ - { - "name": "pierce_type", - "cost": 100, - "needs": { - "has_spikes": true, - "$is_complete": false - }, - "effects": { - "$does_physical": true, - "$does_damage": true - } - }, - { - "name": "magick_type", - "cost": 100, - "needs": { - "$is_complete": false, - "has_magick": true - }, - "effects": { - "$does_magick": true, - "$does_damage": true - } - }, - { - "name": "combined", - "cost": 0, - "needs": { - "$does_damage": true - }, - "effects": { - "$is_complete": true - } - }, - { - "name": "boost_magick", - "cost": 0, - "needs": { - "shiny_bauble": true, - "$does_magick": true, - "$does_damage": true, - "$is_complete": false, - "$user_cursed": false - }, - "effects": { - "$damage_boost": true - } - }, - { - "name": "boost_damage_large", - "cost": 0, - "needs": { - "$user_cursed": true, - "$is_complete": false, - "$does_damage": true - }, - "effects": { - "$large_boost": true - } - }, - { - "name": "curses_user", - "cost": 1000, - "needs": { - "$is_complete": false, - "cursed_item": true - }, - "effects": { - "$user_cursed": true - } - }, - { - "name": "heals_user", - "cost": 0, - "needs": { - "cursed_item": true, - "$does_damage": false - }, - "effects": { - "$does_healing": true, - "$is_complete": true - } - } - ], - "states": { - "initial": { - "shiny_bauble": false, - "cursed_item": false, - "has_spikes": false, - "has_magick": false, - "$user_cursed": false, - "$does_damage": false, - "$is_complete": false, - "$does_healing": false, - "$does_magick": false, - "$does_physical": false, - "$large_boost": false, - "$damage_boost": false - }, - "final": { - "$user_cursed": true, - "$does_damage": true, - "$is_complete": true, - "$does_healing": true, - "$does_magick": true, - "$does_physical": true, - "$large_boost": true, - "$damage_boost": true - } - }, - "scripts": { - "actions": [ - "boost_magick", - "pierce_type", - "magick_type", - "heals_user", - "curses_user", - "boost_damage_large", - "combined" - ] - }, - "effects": { - "boost_magick": { - "damage": 10, - "kind": 2, - "element": 2, - "probability": 1.0 - }, - "pierce_type": { - "damage": 11, - "kind": 1, - "probability": 1.0 - }, - "magick_type": { - "damage": 12, - "kind": 2, - "element": 1, - "probability": 1.0 - }, - "heals_user": { - "damage": 13, - "probability": 1.0 - }, - "curses_user": { - "damage": 14, - "probability": 0.5 - }, - "boost_damage_large": { - "damage": 15, - "probability": 1.0 - }, - "combined": { - "damage": 16, - "probability": 1.0 - } - }, - "junk": { - "chess_pawn": { - "name": "chess_pawn", - "provides": ["cursed_item"] - }, - "dirty_kerchief": { - "name": "dirty_kerchief", - "provides": ["has_magick"] - }, - "mushroom": { - "name": "mushroom", - "provides": ["has_magick"] - }, - "pocket_watch": { - "name": "pocket_watch", - "provides": ["shiny_bauble"] - }, - "rusty_nails": { - "name": "rusty_nails", - "provides": ["has_spikes"] - }, - "severed_finger": { - "name": "severed_finger", - "provides": ["cursed_item"] - } - }, - "starting_junk": [ - "pocket_watch", "mushroom", "rusty_nails" - ] -} diff --git a/assets/rituals/broken_locket-128.png b/assets/rituals/broken_locket-128.png deleted file mode 100644 index b74c845..0000000 Binary files a/assets/rituals/broken_locket-128.png and /dev/null differ diff --git a/assets/rituals/broken_locket-64.png b/assets/rituals/broken_locket-64.png deleted file mode 100644 index c4b692e..0000000 Binary files a/assets/rituals/broken_locket-64.png and /dev/null differ diff --git a/assets/rituals/broken_pen_knife-128.png b/assets/rituals/broken_pen_knife-128.png deleted file mode 100644 index b82e363..0000000 Binary files a/assets/rituals/broken_pen_knife-128.png and /dev/null differ diff --git a/assets/rituals/broken_pen_knife-64.png b/assets/rituals/broken_pen_knife-64.png deleted file mode 100644 index b1cde5f..0000000 Binary files a/assets/rituals/broken_pen_knife-64.png and /dev/null differ diff --git a/assets/rituals/broken_yoyo-128.png b/assets/rituals/broken_yoyo-128.png deleted file mode 100644 index c2f1630..0000000 Binary files a/assets/rituals/broken_yoyo-128.png and /dev/null differ diff --git a/assets/rituals/broken_yoyo-64.png b/assets/rituals/broken_yoyo-64.png deleted file mode 100644 index d900691..0000000 Binary files a/assets/rituals/broken_yoyo-64.png and /dev/null differ diff --git a/assets/rituals/chess_pawn-128.png b/assets/rituals/chess_pawn-128.png deleted file mode 100644 index b730d4f..0000000 Binary files a/assets/rituals/chess_pawn-128.png and /dev/null differ diff --git a/assets/rituals/chess_pawn-64.png b/assets/rituals/chess_pawn-64.png deleted file mode 100644 index 6f0e6bc..0000000 Binary files a/assets/rituals/chess_pawn-64.png and /dev/null differ diff --git a/assets/rituals/dirty_kerchief-128.png b/assets/rituals/dirty_kerchief-128.png deleted file mode 100644 index 86d091a..0000000 Binary files a/assets/rituals/dirty_kerchief-128.png and /dev/null differ diff --git a/assets/rituals/dirty_kerchief-64.png b/assets/rituals/dirty_kerchief-64.png deleted file mode 100644 index f9bb1eb..0000000 Binary files a/assets/rituals/dirty_kerchief-64.png and /dev/null differ diff --git a/assets/rituals/dubious_combination-128.png b/assets/rituals/dubious_combination-128.png deleted file mode 100644 index 7a752b4..0000000 Binary files a/assets/rituals/dubious_combination-128.png and /dev/null differ diff --git a/assets/rituals/dubious_combination-64.png b/assets/rituals/dubious_combination-64.png deleted file mode 100644 index 6068cc6..0000000 Binary files a/assets/rituals/dubious_combination-64.png and /dev/null differ diff --git a/assets/rituals/leather_pouch-128.png b/assets/rituals/leather_pouch-128.png deleted file mode 100644 index 0f6ea12..0000000 Binary files a/assets/rituals/leather_pouch-128.png and /dev/null differ diff --git a/assets/rituals/leather_pouch-64.png b/assets/rituals/leather_pouch-64.png deleted file mode 100644 index 552935d..0000000 Binary files a/assets/rituals/leather_pouch-64.png and /dev/null differ diff --git a/assets/rituals/mushroom-128.png b/assets/rituals/mushroom-128.png deleted file mode 100644 index 8cc7723..0000000 Binary files a/assets/rituals/mushroom-128.png and /dev/null differ diff --git a/assets/rituals/mushroom-64.png b/assets/rituals/mushroom-64.png deleted file mode 100644 index 3eac5d3..0000000 Binary files a/assets/rituals/mushroom-64.png and /dev/null differ diff --git a/assets/rituals/pocket_watch-128.png b/assets/rituals/pocket_watch-128.png deleted file mode 100644 index fb20d80..0000000 Binary files a/assets/rituals/pocket_watch-128.png and /dev/null differ diff --git a/assets/rituals/pocket_watch-64.png b/assets/rituals/pocket_watch-64.png deleted file mode 100644 index ecddcd7..0000000 Binary files a/assets/rituals/pocket_watch-64.png and /dev/null differ diff --git a/assets/rituals/rusty_nails-128.png b/assets/rituals/rusty_nails-128.png deleted file mode 100644 index feddbfc..0000000 Binary files a/assets/rituals/rusty_nails-128.png and /dev/null differ diff --git a/assets/rituals/rusty_nails-64.png b/assets/rituals/rusty_nails-64.png deleted file mode 100644 index 7f7d8a1..0000000 Binary files a/assets/rituals/rusty_nails-64.png and /dev/null differ diff --git a/assets/rituals/severed_finger-128.png b/assets/rituals/severed_finger-128.png deleted file mode 100644 index 1672175..0000000 Binary files a/assets/rituals/severed_finger-128.png and /dev/null differ diff --git a/assets/rituals/severed_finger-64.png b/assets/rituals/severed_finger-64.png deleted file mode 100644 index bea8dc0..0000000 Binary files a/assets/rituals/severed_finger-64.png and /dev/null differ diff --git a/assets/rituals/stone_doll_cursed-128.png b/assets/rituals/stone_doll_cursed-128.png deleted file mode 100644 index e88b7e0..0000000 Binary files a/assets/rituals/stone_doll_cursed-128.png and /dev/null differ diff --git a/assets/rituals/stone_doll_cursed-64.png b/assets/rituals/stone_doll_cursed-64.png deleted file mode 100644 index ac753d9..0000000 Binary files a/assets/rituals/stone_doll_cursed-64.png and /dev/null differ diff --git a/assets/rope_vines_up-256.png b/assets/rope_vines_up-256.png new file mode 100644 index 0000000..31159e9 Binary files /dev/null and b/assets/rope_vines_up-256.png differ diff --git a/assets/shaders.json b/assets/shaders.json deleted file mode 100644 index 7a03ad7..0000000 --- a/assets/shaders.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "ui_shader": { - "file_name": "assets/shaders/ui_shader.frag", - "type": "fragment" - }, - "ERROR": { - "file_name": "assets/shaders/ui_error.frag", - "type": "fragment" - }, - "rayview_sprites": { - "file_name": "assets/shaders/rayview_sprites.frag", - "type": "fragment" - }, - "flame": { - "file_name": "assets/shaders/flame_trash.frag", - "type": "fragment" - }, - "lightning": { - "file_name": "assets/shaders/lightning_attack.frag", - "type": "fragment" - } -} diff --git a/assets/shaders/flame_trash.frag b/assets/shaders/flame_trash.frag deleted file mode 100644 index 092e4fd..0000000 --- a/assets/shaders/flame_trash.frag +++ /dev/null @@ -1,79 +0,0 @@ -#version 120 -uniform vec2 u_resolution; -uniform float u_time; -uniform sampler2D source; -uniform float u_mouse; -uniform float value = 0.2; -uniform int octaves=8; - -float random (in vec2 st) { - return fract(sin(dot(st.xy, - vec2(12.9898,78.233)))* - 43758.5453123); -} - -float noise(in vec2 st) { - vec2 i = floor(st); - vec2 f = fract(st); - - float a = random(i); - float b = random(i + vec2(1.0, 0.0)); - float c = random(i + vec2(0.0, 1.0)); - float d = random(i + vec2(1.0, 1.0)); - - vec2 u = f * f * (3.0 - 2.0 * f); - - return mix(a, b, u.x) + - (c - a) * u.y * (1.0 - u.x) + - (d - b) * u.x * u.y; -} - -float fbm(in vec2 st) { - float v = 0.0; - float a = 0.5; - vec2 shift = vec2(100.0); - mat2 rot = mat2(cos(0.5), sin(0.5), - -sin(0.5), cos(0.5)); - - for(int i = 0; i < octaves; i++) { - v += a * noise(st); - st = rot * st * 2.0 + shift; - a *= 0.5; - } - - return v; -} - -void main() { - vec2 st = gl_FragCoord.xy/u_resolution.xy * 3.0; - vec3 color = vec3(0.0); - - float speed = u_time * 10.0; - float value = 0.8; // cos(u_time) * cos(u_time); - - vec2 q = vec2(0.0); - q.x = fbm(st + 0.00 * speed); - q.y = fbm(st + vec2(1.0)); - - vec2 r = vec2(0,0); - r.x += fbm( st + 1.0*q + vec2(1.0, 0.0)+ 0.15* speed ); - r.y += fbm( st + 1.0*q + vec2(-1.0, 0.0)+ 0.126* speed); - - float f = fbm(st * r); - - color = mix(vec3(0.666667,0.619608, 0.122777), - vec3(0.666667,0.666667,0.498039), - clamp((f*f)*4.0,0.0,1.0)); - - color = mix(color, - vec3(0.666667, 0.122222, 0.0666667), - clamp(length(r.x), 0.0, 1.0)); - - color *= (f*f*f+0.5*f*f+0.6*f) * value; - - vec4 pixel = texture2D(source, gl_TexCoord[0].xy); - - float mask = color.r * pixel.a; - - gl_FragColor = gl_Color * vec4(color, mask) + pixel; -} diff --git a/assets/shaders/lightning_attack.frag b/assets/shaders/lightning_attack.frag deleted file mode 100644 index eb41295..0000000 --- a/assets/shaders/lightning_attack.frag +++ /dev/null @@ -1,79 +0,0 @@ -#version 120 -uniform vec2 u_resolution; -uniform float u_time; -uniform sampler2D source; -uniform float u_mouse; -uniform float value = 0.2; -uniform int octaves=8; - -float random (in vec2 st) { - return fract(sin(dot(st.xy, - vec2(12.9898,78.233)))* - 43758.5453123); -} - -float noise(in vec2 st) { - vec2 i = floor(st); - vec2 f = fract(st); - - float a = random(i); - float b = random(i + vec2(1.0, 0.0)); - float c = random(i + vec2(0.0, 1.0)); - float d = random(i + vec2(1.0, 1.0)); - - vec2 u = f * f * (3.0 - 2.0 * f); - - return mix(a, b, u.x) + - (c - a) * u.y * (1.0 - u.x) + - (d - b) * u.x * u.y; -} - -float fbm(in vec2 st) { - float v = 0.0; - float a = 0.5; - vec2 shift = vec2(100.0); - mat2 rot = mat2(cos(0.5), sin(0.5), - -sin(0.5), cos(0.5)); - - for(int i = 0; i < octaves; i++) { - v += a * noise(st); - st = rot * st * 2.0 + shift; - a *= 0.5; - } - - return v; -} - -void main() { - vec2 st = gl_FragCoord.xy/u_resolution.xy * 3.0; - vec3 color = vec3(0.0); - - float speed = u_time * 40.0; - float value = cos(u_time) * cos(u_time); - - vec2 q = vec2(0.0); - q.x = fbm(st + 0.00 * speed); - q.y = fbm(st + vec2(1.0)); - - vec2 r = vec2(0,0); - r.x += fbm( st + 1.0*q + vec2(1.0, 0.0)+ 0.15* speed ); - r.y += fbm( st + 1.0*q + vec2(-1.0, 0.0)+ 0.126* speed); - - float f = fbm(st / r); - - color = mix(vec3(0.122777,0.619608, 0.666667), - vec3(0.498039,0.666667,0.666667), - clamp((f*f)*4.0,0.0,1.0)); - - color = mix(color, - vec3(0.0666667, 0.122222, 0.666667), - clamp(length(r.x), 0.0, 1.0)); - - color *= (f*f*f+0.5*f*f+0.6*f) * value; - - vec4 pixel = texture2D(source, gl_TexCoord[0].xy); - - float mask = color.r * pixel.a; - - gl_FragColor = gl_Color * vec4(color, mask) + pixel; -} diff --git a/assets/shaders/ui_error.frag b/assets/shaders/ui_error.frag deleted file mode 100644 index 29ccc8c..0000000 --- a/assets/shaders/ui_error.frag +++ /dev/null @@ -1,18 +0,0 @@ -uniform vec2 u_resolution; -uniform vec2 u_mouse; -uniform float u_duration; -uniform float u_time; -uniform float u_time_end; -uniform sampler2D texture; -uniform bool is_shape; - -void main() { - if(is_shape) { - vec4 color = vec4(1.0, 0.0, 0.0, 1.0); - gl_FragColor = gl_Color * color; - } else { - vec4 pixel = texture2D(texture, gl_TexCoord[0].xy); - vec4 color = vec4(1.0, 0.0, 0.0, 1.0); - gl_FragColor = gl_Color * color * pixel; - } -} diff --git a/assets/shaders/ui_shader.frag b/assets/shaders/ui_shader.frag deleted file mode 100644 index 73b77b4..0000000 --- a/assets/shaders/ui_shader.frag +++ /dev/null @@ -1,29 +0,0 @@ -uniform vec2 u_resolution; -uniform vec2 u_mouse; -uniform float u_duration; -uniform float u_time; -uniform float u_time_end; -uniform sampler2D texture; -uniform bool is_shape; -uniform bool hover; - -vec4 blink() { - if(hover) { - return vec4(0.95, 0.95, 1.0, 1.0); - } else { - float tick = (u_time_end - u_time) / u_duration; - float blink = mix(0.5, 1.0, tick); - return vec4(blink, blink, blink, 1.0); - } -} - -void main() { - vec4 color = blink(); - - if(!is_shape) { - vec4 pixel = texture2D(texture, gl_TexCoord[0].xy); - color *= pixel; - } - - gl_FragColor = gl_Color * color; -} diff --git a/assets/shaders/ui_shape_shader.frag b/assets/shaders/ui_shape_shader.frag deleted file mode 100644 index c16d6ea..0000000 --- a/assets/shaders/ui_shape_shader.frag +++ /dev/null @@ -1,12 +0,0 @@ -uniform vec2 u_resolution; -uniform vec2 u_mouse; -uniform float u_duration; -uniform float u_time; -uniform float u_time_end; - -void main() { - float tick = (u_time_end - u_time) / u_duration; - float blink = smoothstep(1.0, 0.5, tick); - vec4 color = vec4(blink, blink, blink, 1.0); - gl_FragColor = gl_Color * color; -} diff --git a/assets/sounds/electric_shock_01.ogg b/assets/sounds/electric_shock_01.ogg deleted file mode 100644 index d9d3b0b..0000000 Binary files a/assets/sounds/electric_shock_01.ogg and /dev/null differ diff --git a/assets/sounds/fireball_01.ogg b/assets/sounds/fireball_01.ogg deleted file mode 100644 index d819833..0000000 Binary files a/assets/sounds/fireball_01.ogg and /dev/null differ diff --git a/assets/sounds/hp_status_00.ogg b/assets/sounds/hp_status_00.ogg deleted file mode 100644 index dad539b..0000000 Binary files a/assets/sounds/hp_status_00.ogg and /dev/null differ diff --git a/assets/sounds/hp_status_10.ogg b/assets/sounds/hp_status_10.ogg deleted file mode 100644 index 08c1dc2..0000000 Binary files a/assets/sounds/hp_status_10.ogg and /dev/null differ diff --git a/assets/sounds/hp_status_30.ogg b/assets/sounds/hp_status_30.ogg deleted file mode 100644 index b9c8ddc..0000000 Binary files a/assets/sounds/hp_status_30.ogg and /dev/null differ diff --git a/assets/sounds/hp_status_60.ogg b/assets/sounds/hp_status_60.ogg deleted file mode 100644 index 84849dc..0000000 Binary files a/assets/sounds/hp_status_60.ogg and /dev/null differ diff --git a/assets/sounds/hp_status_80.ogg b/assets/sounds/hp_status_80.ogg deleted file mode 100644 index fd2d2b6..0000000 Binary files a/assets/sounds/hp_status_80.ogg and /dev/null differ diff --git a/assets/sounds/punch_cartoony.ogg b/assets/sounds/punch_cartoony.ogg deleted file mode 100644 index 1a812cc..0000000 Binary files a/assets/sounds/punch_cartoony.ogg and /dev/null differ diff --git a/assets/sounds/ui_click.ogg b/assets/sounds/ui_click.ogg deleted file mode 100644 index 7ff2e8c..0000000 Binary files a/assets/sounds/ui_click.ogg and /dev/null differ diff --git a/assets/sounds/ui_hover.ogg b/assets/sounds/ui_hover.ogg deleted file mode 100644 index be6e679..0000000 Binary files a/assets/sounds/ui_hover.ogg and /dev/null differ diff --git a/assets/sprites/armored_knight_1.png b/assets/sprites/armored_knight_1.png deleted file mode 100644 index d32e3f8..0000000 Binary files a/assets/sprites/armored_knight_1.png and /dev/null differ diff --git a/assets/sprites/axe_ranger.png b/assets/sprites/axe_ranger.png deleted file mode 100644 index ecd3a5d..0000000 Binary files a/assets/sprites/axe_ranger.png and /dev/null differ diff --git a/assets/sprites/dead_body.png b/assets/sprites/dead_body.png deleted file mode 100644 index 8337eda..0000000 Binary files a/assets/sprites/dead_body.png and /dev/null differ diff --git a/assets/sprites/dead_body_lootable.png b/assets/sprites/dead_body_lootable.png deleted file mode 100644 index 69666a9..0000000 Binary files a/assets/sprites/dead_body_lootable.png and /dev/null differ diff --git a/assets/sprites/gold_savior.png b/assets/sprites/gold_savior.png deleted file mode 100644 index 4c2b640..0000000 Binary files a/assets/sprites/gold_savior.png and /dev/null differ diff --git a/assets/sprites/grave_stone.png b/assets/sprites/grave_stone.png deleted file mode 100644 index 4891a30..0000000 Binary files a/assets/sprites/grave_stone.png and /dev/null differ diff --git a/assets/sprites/hairy_spider.png b/assets/sprites/hairy_spider.png deleted file mode 100644 index 6cee0fb..0000000 Binary files a/assets/sprites/hairy_spider.png and /dev/null differ diff --git a/assets/sprites/peasant_girl_2.png b/assets/sprites/peasant_girl_2.png deleted file mode 100644 index 9288fb9..0000000 Binary files a/assets/sprites/peasant_girl_2.png and /dev/null differ diff --git a/assets/sprites/rat_with_sword.png b/assets/sprites/rat_with_sword.png deleted file mode 100644 index bcb52d0..0000000 Binary files a/assets/sprites/rat_with_sword.png and /dev/null differ diff --git a/assets/sprites/rope_vines_up.png b/assets/sprites/rope_vines_up.png deleted file mode 100644 index 230d2e8..0000000 Binary files a/assets/sprites/rope_vines_up.png and /dev/null differ diff --git a/assets/sprites/torch_pillar.png b/assets/sprites/torch_pillar.png deleted file mode 100644 index 813aa76..0000000 Binary files a/assets/sprites/torch_pillar.png and /dev/null differ diff --git a/assets/sprites/tripwire_trap.png b/assets/sprites/tripwire_trap.png deleted file mode 100644 index edf206b..0000000 Binary files a/assets/sprites/tripwire_trap.png and /dev/null differ diff --git a/assets/sprites/undead_peasant.png b/assets/sprites/undead_peasant.png deleted file mode 100644 index 097227a..0000000 Binary files a/assets/sprites/undead_peasant.png and /dev/null differ diff --git a/assets/sprites/well_down.png b/assets/sprites/well_down.png deleted file mode 100644 index fe5e74b..0000000 Binary files a/assets/sprites/well_down.png and /dev/null differ diff --git a/assets/styles.json b/assets/styles.json deleted file mode 100644 index b1822d4..0000000 --- a/assets/styles.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "name": "Mossy Blue Ceiling", - "floor": "gray_stone_floor_light", - "walls": "wall_moss" - }, - { - "name": "Plain", - "floor": "floor_tile", - "walls": "wall_plain" - }, - { - "name": "Wood Walls", - "floor": "floor_tile", - "walls": "wood_wall" - } -] diff --git a/assets/textures/ceiling_black.png b/assets/textures/ceiling_black.png deleted file mode 100644 index 156cd17..0000000 Binary files a/assets/textures/ceiling_black.png and /dev/null differ diff --git a/assets/textures/ceiling_blue_light.png b/assets/textures/ceiling_blue_light.png deleted file mode 100644 index def9a8e..0000000 Binary files a/assets/textures/ceiling_blue_light.png and /dev/null differ diff --git a/assets/textures/floor_gray_stone.png b/assets/textures/floor_gray_stone.png deleted file mode 100644 index b8d92e9..0000000 Binary files a/assets/textures/floor_gray_stone.png and /dev/null differ diff --git a/assets/textures/glowing_moss_wall.png b/assets/textures/glowing_moss_wall.png deleted file mode 100644 index 8bbf40a..0000000 Binary files a/assets/textures/glowing_moss_wall.png and /dev/null differ diff --git a/assets/textures/gray_stone_floor_light.png b/assets/textures/gray_stone_floor_light.png deleted file mode 100644 index 388f63d..0000000 Binary files a/assets/textures/gray_stone_floor_light.png and /dev/null differ diff --git a/assets/textures/lava_floor.png b/assets/textures/lava_floor.png deleted file mode 100644 index da8b46c..0000000 Binary files a/assets/textures/lava_floor.png and /dev/null differ diff --git a/assets/textures/wall_plain.png b/assets/textures/wall_plain.png deleted file mode 100644 index 40286ea..0000000 Binary files a/assets/textures/wall_plain.png and /dev/null differ diff --git a/assets/textures/wood_wall.png b/assets/textures/wood_wall.png deleted file mode 100644 index 8f745c8..0000000 Binary files a/assets/textures/wood_wall.png and /dev/null differ diff --git a/assets/tiles.json b/assets/tiles.json index c45d559..969b072 100644 --- a/assets/tiles.json +++ b/assets/tiles.json @@ -1,69 +1,23 @@ { - "floor_tile": { - "texture": "assets/textures/floor_gray_stone.png", - "display": 8284, - "ceiling": "ceiling_black", - "light": 0, - "foreground": "tiles/fg:floor_tile", - "background": "tiles/bg:floor_tile", - "id": 0 + "FLOOR_TILE": { + "texture": "assets/floor_tile_test-256.png", + "foreground": [40, 15, 125], + "background": [200, 15, 75], + "collision": false, + "display":"\u289e" }, - "wall_plain": { - "texture": "assets/textures/wall_plain.png", - "display": 9608, - "light": 0, - "foreground": "tiles/fg:wall_plain", - "background": "tiles/bg:wall_plain", - "id": 1 + "WALL_PLAIN": { + "texture": "assets/wall_texture_test-256.png", + "foreground": [230, 20, 30], + "background": [230, 20, 120], + "collision": true, + "display": "\ua5b8" }, - "wall_moss": { - "texture": "assets/textures/glowing_moss_wall.png", - "display": 9256, - "light": 20, - "foreground": "tiles/fg:wall_moss", - "background": "tiles/bg:wall_moss", - "id": 2 - }, - "ceiling_black": { - "texture": "assets/textures/ceiling_black.png", - "display": 35, - "light": 0, - "foreground": "tiles/fg:ceiling_black", - "background": "tiles/bg:ceiling_black", - "id": 4 - }, - "lava_floor": { - "texture": "assets/textures/lava_floor.png", - "display": 10899, - "ceiling": "ceiling_black", - "light": 20, - "foreground": "tiles/fg:lava_floor", - "background": "tiles/bg:lava_floor", - "id": 5 - }, - "gray_stone_floor_light": { - "texture": "assets/textures/gray_stone_floor_light.png", - "display": 11590, - "ceiling": "zBUGceiling_blue_light", - "light": 40, - "foreground": "tiles/fg:gray_stone_floor_light", - "background": "tiles/bg:gray_stone_floor_light", - "id": 6 - }, - "wood_wall": { - "texture": "assets/textures/wood_wall.png", - "display": 10747, - "light": 0, - "foreground": "tiles/fg:wood_wall", - "background": "tiles/bg:wood_wall", - "id": 7 - }, - "zBUGceiling_blue_light": { - "texture": "assets/textures/ceiling_blue_light.png", - "display": 8285, - "light": 0, - "foreground": "color:BAD", - "background": "color:BAD", - "id": 8 + "WALL_VINES": { + "texture": "assets/wall_with_vines-256.png", + "foreground": [230, 20, 30], + "background": [230, 20, 120], + "collision": false, + "display":"\u0799" } } diff --git a/assets/torch_crappy-256.png b/assets/torch_crappy-256.png new file mode 100644 index 0000000..9e7bcdc Binary files /dev/null and b/assets/torch_crappy-256.png differ diff --git a/assets/torch_horizontal_floor-256.png b/assets/torch_horizontal_floor-256.png new file mode 100644 index 0000000..3c7c718 Binary files /dev/null and b/assets/torch_horizontal_floor-256.png differ diff --git a/assets/torch_pillar-256.png b/assets/torch_pillar-256.png new file mode 100644 index 0000000..9431f04 Binary files /dev/null and b/assets/torch_pillar-256.png differ diff --git a/assets/torch_pillar-512.png b/assets/torch_pillar-512.png new file mode 100644 index 0000000..d7f580e Binary files /dev/null and b/assets/torch_pillar-512.png differ diff --git a/assets/trash_button.png b/assets/trash_button.png new file mode 100644 index 0000000..ba823ae Binary files /dev/null and b/assets/trash_button.png differ diff --git a/assets/tripwire_trap-256.png b/assets/tripwire_trap-256.png new file mode 100644 index 0000000..1a6b4c0 Binary files /dev/null and b/assets/tripwire_trap-256.png differ diff --git a/assets/bossfights/tunnel_with_rocks.png b/assets/tunnel_with_rocks.png similarity index 100% rename from assets/bossfights/tunnel_with_rocks.png rename to assets/tunnel_with_rocks.png diff --git a/assets/bossfights/tunnel_with_rocks_stage.png b/assets/tunnel_with_rocks_stage.png similarity index 100% rename from assets/bossfights/tunnel_with_rocks_stage.png rename to assets/tunnel_with_rocks_stage.png diff --git a/assets/ui/UI/full_screen_paper.png b/assets/ui/UI/full_screen_paper.png deleted file mode 100644 index 12b5cfd..0000000 Binary files a/assets/ui/UI/full_screen_paper.png and /dev/null differ diff --git a/assets/ui/UI/ritual_crafting_area.png b/assets/ui/UI/ritual_crafting_area.png deleted file mode 100644 index 120d921..0000000 Binary files a/assets/ui/UI/ritual_crafting_area.png and /dev/null differ diff --git a/assets/ui/full_screen_paper.png b/assets/ui/full_screen_paper.png deleted file mode 100644 index 12b5cfd..0000000 Binary files a/assets/ui/full_screen_paper.png and /dev/null differ diff --git a/assets/ui/ritual_crafting_area.png b/assets/ui/ritual_crafting_area.png deleted file mode 100644 index ac8db7d..0000000 Binary files a/assets/ui/ritual_crafting_area.png and /dev/null differ diff --git a/assets/undead_peasant-256.png b/assets/undead_peasant-256.png new file mode 100644 index 0000000..eed23a3 Binary files /dev/null and b/assets/undead_peasant-256.png differ diff --git a/assets/undead_peasant-spritesheet.png b/assets/undead_peasant-spritesheet.png new file mode 100644 index 0000000..9da3fc6 Binary files /dev/null and b/assets/undead_peasant-spritesheet.png differ diff --git a/assets/wall_simple-256.png b/assets/wall_simple-256.png new file mode 100644 index 0000000..6c76722 Binary files /dev/null and b/assets/wall_simple-256.png differ diff --git a/assets/wall_texture_test-256.png b/assets/wall_texture_test-256.png new file mode 100644 index 0000000..217c625 Binary files /dev/null and b/assets/wall_texture_test-256.png differ diff --git a/assets/wall_texture_test-512.png b/assets/wall_texture_test-512.png new file mode 100644 index 0000000..e68dd88 Binary files /dev/null and b/assets/wall_texture_test-512.png differ diff --git a/assets/wall_with_pillars-256.png b/assets/wall_with_pillars-256.png new file mode 100644 index 0000000..7715274 Binary files /dev/null and b/assets/wall_with_pillars-256.png differ diff --git a/assets/wall_with_vines-256.png b/assets/wall_with_vines-256.png new file mode 100644 index 0000000..da524ac Binary files /dev/null and b/assets/wall_with_vines-256.png differ diff --git a/assets/well_down-256.png b/assets/well_down-256.png new file mode 100644 index 0000000..514de63 Binary files /dev/null and b/assets/well_down-256.png differ diff --git a/assets/wood_barrel_large-256.png b/assets/wood_barrel_large-256.png new file mode 100644 index 0000000..6cf2732 Binary files /dev/null and b/assets/wood_barrel_large-256.png differ diff --git a/assets/wood_barrel_large-512.png b/assets/wood_barrel_large-512.png new file mode 100644 index 0000000..37b1898 Binary files /dev/null and b/assets/wood_barrel_large-512.png differ diff --git a/assets/wood_barrel_small-256.png b/assets/wood_barrel_small-256.png new file mode 100644 index 0000000..43aede2 Binary files /dev/null and b/assets/wood_barrel_small-256.png differ diff --git a/assets/wood_wall-256.png b/assets/wood_wall-256.png new file mode 100644 index 0000000..6851bdc Binary files /dev/null and b/assets/wood_wall-256.png differ diff --git a/assets/wood_wall-512.png b/assets/wood_wall-512.png new file mode 100644 index 0000000..8924713 Binary files /dev/null and b/assets/wood_wall-512.png differ diff --git a/autowalker.cpp b/autowalker.cpp index 9f5ac9d..31b6e9a 100644 --- a/autowalker.cpp +++ b/autowalker.cpp @@ -1,85 +1,53 @@ #include "autowalker.hpp" -#include "ai_debug.hpp" -#include "gui/ritual_ui.hpp" -#include "game_level.hpp" -#include "systems.hpp" - -struct InventoryStats { - int healing = 0; - int other = 0; -}; +#include "inventory.hpp" template -int number_left() { - int count = 0; - auto world = GameDB::current_world(); - auto player = GameDB::the_player(); - - world->query( - [&](const auto ent, auto&, auto&) { - if(ent != player) { - count++; - } - }); - - return count; -} - -template -Pathing compute_paths() { - auto& level = GameDB::current_level(); - auto walls_copy = level.map->$walls; +Pathing compute_paths(gui::FSM& fsm, int& count_out) { + auto& walls_original = fsm.$level.map->$walls; + auto walls_copy = walls_original; Pathing paths{matrix::width(walls_copy), matrix::height(walls_copy)}; + count_out = 0; - System::multi_path(level, paths, walls_copy); + fsm.$level.world->query( + [&](const auto ent, auto& position) { + if(ent != fsm.$level.player) { + if(fsm.$level.world->has(ent)) { + paths.set_target(position.location); + count_out = count_out + 1; + } else { + // this will mark that spot as a wall so we don't path there temporarily + walls_copy[position.location.y][position.location.x] = WALL_PATH_LIMIT; + } + } + }); + + paths.compute_paths(walls_copy); return paths; } -DinkyECS::Entity Autowalker::camera_aim() { - auto& level = GameDB::current_level(); - auto player_pos = GameDB::player_position(); - - // what happens if there's two things at that spot - if(level.collision->something_there(player_pos.aiming_at)) { - return level.collision->get(player_pos.aiming_at); - } else { - return DinkyECS::NONE; - } -} - -void Autowalker::log(std::wstring msg) { - fsm.$map_ui.log(msg); -} - -void Autowalker::status(std::wstring msg) { - fsm.$main_ui.$overlay_ui.show_text("bottom", msg); -} - -void Autowalker::close_status() { - fsm.$main_ui.$overlay_ui.close_text("bottom"); -} - Pathing Autowalker::path_to_enemies() { - return compute_paths(); + return compute_paths(fsm, enemy_count); } Pathing Autowalker::path_to_items() { - return compute_paths(); + return compute_paths(fsm, item_count); } -void Autowalker::handle_window_events() { +Pathing Autowalker::path_to_devices() { + return compute_paths(fsm, device_count); +} + +void Autowalker::window_events() { fsm.$window.handleEvents( [&](const sf::Event::KeyPressed &) { fsm.autowalking = false; - close_status(); - log(L"Aborting autowalk."); + fmt::println("ABORT AUTOWALK"); }, [&](const sf::Event::MouseButtonPressed &) { fsm.autowalking = false; - close_status(); - log(L"Aborting autowalk."); + fmt::println("ABORT AUTOWALK"); } ); } @@ -96,367 +64,161 @@ void Autowalker::process_combat() { } } -void Autowalker::path_fail(const std::string& msg, Matrix& bad_paths, Point pos) { - dbc::log(msg); - status(L"PATH FAIL"); - matrix::dump("MOVE FAIL PATHS", bad_paths, pos.x, pos.y); - log(L"Autowalk failed to find a path."); - send_event(gui::Event::STAIRS_DOWN); +Point Autowalker::get_current_position() { + auto& player_position = fsm.$level.world->get(fsm.$level.player); + return player_position.location; } bool Autowalker::path_player(Pathing& paths, Point& target_out) { - auto& level = GameDB::current_level(); - auto found = paths.find_path(target_out, PATHING_TOWARD, false); + bool found = paths.random_walk(target_out, false, PATHING_TOWARD); - if(found == PathingResult::FAIL) { - // failed to find a linear path, try diagonal - if(paths.find_path(target_out, PATHING_TOWARD, true) == PathingResult::FAIL) { - path_fail("random_walk", paths.$paths, target_out); - return false; - } + if(!found) { + dbc::log("no neighbor found, aborting autowalk"); + return false; } - if(!level.map->can_move(target_out)) { - path_fail("level_map->can_move", paths.$paths, target_out); + if(!fsm.$level.map->can_move(target_out)) { + dbc::log("neighbors is telling me to go to a bad spot."); return false; } return true; } -void Autowalker::rotate_player(Point target) { - auto &player = GameDB::player_position(); +void Autowalker::rotate_player(Point current, Point target) { + int delta_x = int(target.x) - int(current.x); + int delta_y = int(target.y) - int(current.y); - if(target == player.location) { - dbc::log("player stuck at a locatoin"); - fsm.autowalking = false; + int facing = fsm.$main_ui.$compass_dir; + int target_facing = 0; + + if(delta_x == -1 && delta_y == 0) { + // west + target_facing = 4; + } else if(delta_x == 1 && delta_y == 0) { + // east + target_facing = 0; + } else if(delta_x == 0 && delta_y == 1) { + // south + target_facing = 2; + } else if(delta_x == 0 && delta_y == -1) { + // north + target_facing = 6; + } else { + dbc::sentinel( + fmt::format("got more than 4 direction result: " + "current={},{} " + "target={},{} " + "delta={},{} ", + current.x, current.y, + target.x, target.y, + delta_x, delta_y)); + } + + auto dir = facing > target_facing ? gui::Event::ROTATE_LEFT : gui::Event::ROTATE_RIGHT; + + while(facing != target_facing) { + send_event(dir); + facing = fsm.$main_ui.$compass_dir; + } + + dbc::check(fsm.$main_ui.$compass_dir == target_facing, + "player isn't facing the correct direction"); +} + +void Autowalker::show_map_overlay(matrix::Matrix& map, Point current) { + auto debug = fsm.$level.world->get_the(); + if(!debug.FPS) { + fsm.$main_ui.$overlay_ui.close_text("top_right"); return; } - auto dir = System::shortest_rotate(player.location, player.aiming_at, target); + std::string map_overlay; + for(matrix::box it{map, current.x, current.y, 6}; it.next();) { + if(it.x == it.left) map_overlay += "\n"; + int cell = map[it.y][it.x]; - for(int i = 0; player.aiming_at != target; i++) { - if(i > 10) { - dbc::log("HIT OVER ROTATE BUG!"); - break; - } - - send_event(dir); - - while(fsm.in_state(gui::State::ROTATING) || - fsm.in_state(gui::State::COMBAT_ROTATE)) - { - send_event(gui::Event::TICK); - } - } - - fsm.autowalking = player.aiming_at == target; -} - -void Autowalker::update_state(ai::EntityAI& player_ai) { - int enemy_count = number_left(); - int item_count = number_left(); - - player_ai.set_state("no_more_enemies", enemy_count == 0); - player_ai.set_state("no_more_items", item_count == 0); - - player_ai.set_state("enemy_found", found_enemy()); - player_ai.set_state("health_good", player_health_good()); - - player_ai.set_state("in_combat", - fsm.in_state(gui::State::IN_COMBAT) || - fsm.in_state(gui::State::ATTACKING)); - - auto inv = player_item_count(); - player_ai.set_state("have_item", inv.other > 0 || inv.healing > 0); - player_ai.set_state("have_healing", inv.healing > 0); - - player_ai.update(); -} - -void Autowalker::handle_boss_fight() { - // skip the boss fight for now - if(fsm.in_state(gui::State::NEXT_LEVEL)) { - // eventually we'll have AI handle this too - send_event(gui::Event::STAIRS_DOWN); - face_enemy(); - } -} - -void Autowalker::handle_player_walk(ai::State& start, ai::State& goal) { - ai::EntityAI player_ai("Host::actions", start, goal); - update_state(player_ai); - auto level = GameDB::current_level(); - - if(player_ai.wants_to("find_enemy")) { - status(L"FINDING ENEMY"); - auto paths = path_to_enemies(); - process_move(paths, [&](auto target) -> bool { - return level.collision->occupied(target); - }); - face_enemy(); - } else if(player_ai.wants_to("kill_enemy")) { - status(L"KILLING ENEMY"); - - if(fsm.in_state(gui::State::IN_COMBAT)) { - if(face_enemy()) { - process_combat(); + if(it.x == current.x && it.y == current.y) { + map_overlay += fmt::format("{:x}<", cell); + } else if(cell == WALL_PATH_LIMIT) { + map_overlay += fmt::format("# "); + } else if(cell > 15) { + map_overlay += fmt::format("* "); + } else { + map_overlay += fmt::format("{:x} ", cell); } - } - } else if(player_ai.wants_to("use_healing")) { - status(L"USING HEALING"); - player_use_healing(); - } else if(player_ai.wants_to("collect_items") || player_ai.wants_to("find_healing")) { - fmt::println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); - status(player_ai.wants_to("collect_items") ? L"COLLECTING ITEMS" : L"FIND HEALING"); - player_ai.dump(); - - auto paths = path_to_items(); - - bool found_it = process_move(paths, [&](auto target) -> bool { - if(!level.collision->something_there(target)) return false; - - auto entity = level.collision->get(target); - return ( - level.world->has(entity) || - level.world->has(entity)); - }); - - if(found_it) pickup_item(); - fmt::println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - } else if(!player_ai.active()) { - close_status(); - log(L"FINAL ACTION! Autowalk done."); - fsm.autowalking = false; - } else { - close_status(); - dbc::log(fmt::format("Unknown action: {}", player_ai.to_string())); } -} -void Autowalker::craft_weapon() { - if(!weapon_crafted) { - auto& ritual_ui = fsm.$status_ui.$ritual_ui; - fsm.$status_ui.$gui.click_on("ritual_ui"); - - while(!ritual_ui.in_state(gui::ritual::State::OPENED)) { - send_event(gui::Event::TICK); - } - - ritual_ui.$gui.click_on("inv_slot0"); - send_event(gui::Event::TICK); - ritual_ui.$gui.click_on("inv_slot1"); - send_event(gui::Event::TICK); - - while(!ritual_ui.in_state(gui::ritual::State::CRAFTING)) { - send_event(gui::Event::TICK); - } - - ritual_ui.$gui.click_on("result_image", true); - send_event(gui::Event::TICK); - - ritual_ui.$gui.click_on("ritual_ui"); - send_event(gui::Event::TICK); - weapon_crafted = true; - } -} - -void Autowalker::open_map() { - if(!map_opened_once) { - if(!fsm.$map_open) { - send_event(gui::Event::MAP_OPEN); - map_opened_once = true; - } - } -} - -void Autowalker::close_map() { - if(fsm.$map_open) { - send_event(gui::Event::MAP_OPEN); - } + fsm.$main_ui.$overlay_ui.show_text("top_right", map_overlay); } void Autowalker::autowalk() { - handle_window_events(); - if(!fsm.autowalking) { - close_status(); + window_events(); + if(!fsm.autowalking) return; + + process_combat(); + auto paths = path_to_enemies(); + + if(enemy_count == 0) { + dbc::log("Killed everything, now finding items."); + paths = path_to_items(); + } + + if(enemy_count == 0 && item_count == 0) { + dbc::log("No more items, find the exit."); + paths = path_to_devices(); + } + + if(enemy_count == 0 && + item_count == 0 && + device_count == 0) + { + fsm.autowalking = false; + dbc::log("no more enemies, items, or devices."); return; } - craft_weapon(); - open_map(); - face_enemy(); + Point current = get_current_position(); + Point target = current; + + show_map_overlay(paths.$paths, current); + + + if(!path_player(paths, target)) { + dbc::log("no paths found, aborting autowalk"); + fsm.autowalking = false; + return; + } + + rotate_player(current, target); int move_attempts = 0; - - auto start = ai::load_state("Host::initial_state"); - auto goal = ai::load_state("Host::final_state"); - do { - handle_window_events(); - handle_boss_fight(); - handle_player_walk(start, goal); - - close_map(); - + process_combat(); + process_move(); + // BUG: sometimes in idle but there's an enemy near but combat hasn't started + // for now just toss out an ATTACK and it'll be ignored or cause combat + send_event(gui::Event::ATTACK); move_attempts++; - } while(move_attempts < 100 && fsm.autowalking); + } while(move_attempts < 100 && !player_has_moved(target)); } -bool Autowalker::process_move(Pathing& paths, std::function is_that_it) { - // target has to start at the player location then... - auto target_out = GameDB::player_position().location; - - // ... target gets modified as an out parameter to find the path - if(!path_player(paths, target_out)) { - close_status(); - log(L"No paths found, aborting autowalk."); - return false; - } - - if(rayview->aiming_at != target_out) rotate_player(target_out); - - bool found_it = is_that_it(target_out); - - if(!found_it) { - send_event(gui::Event::MOVE_FORWARD); - while(fsm.in_state(gui::State::MOVING)) send_event(gui::Event::TICK); - } - - return found_it; +void Autowalker::process_move() { + send_event(gui::Event::MOVE_FORWARD); + while(fsm.in_state(gui::State::MOVING)) send_event(gui::Event::TICK); } -bool Autowalker::found_enemy() { - auto& level = GameDB::current_level(); - auto player = GameDB::player_position(); - - for(matrix::compass it{level.map->$walls, player.location.x, player.location.y}; it.next();) { - Point aim{it.x, it.y}; - auto aimed_ent = level.collision->occupied_by(player.aiming_at); - if(aim != player.aiming_at || aimed_ent == DinkyECS::NONE) continue; - - if(level.world->has(aimed_ent)) return true; - } - - return false; +bool Autowalker::player_has_moved(Point target) { + Point current = get_current_position(); + return current.x == target.x && current.y == target.y; } -bool Autowalker::found_item() { - auto world = GameDB::current_world(); - auto aimed_at = camera_aim(); - return aimed_at != DinkyECS::NONE && world->has(aimed_at); -} - -void Autowalker::send_event(gui::Event ev, std::any data) { - fsm.event(ev, data); +void Autowalker::send_event(gui::Event ev) { + fsm.event(ev); fsm.render(); fsm.handle_world_events(); } -bool Autowalker::player_health_good() { - auto world = GameDB::current_world(); - auto player = GameDB::the_player(); - auto combat = world->get(player); - float health = float(combat.hp) / float(combat.max_hp); - fmt::println("!!!!!!!!!! HEALTH: {}", health); - return health > 0.5f; -} - -InventoryStats Autowalker::player_item_count() { - InventoryStats stats; - auto& level = GameDB::current_level(); - auto& inventory = level.world->get(level.player); - - if(inventory.has("pocket_r")) { - stats.other += 1; - stats.healing += 1; - } - - if(inventory.has("pocket_l")) { - stats.other += 1; - stats.healing += 1; - } - - return stats; -} - -void Autowalker::player_use_healing() { - auto& level = GameDB::current_level(); - auto& inventory = level.world->get(level.player); - - if(inventory.has("pocket_r")) { - auto gui_id = fsm.$status_ui.$gui.entity("pocket_r"); - send_event(gui::Event::USE_ITEM, gui_id); - } - - if(inventory.has("pocket_l")) { - auto gui_id = fsm.$status_ui.$gui.entity("pocket_l"); - send_event(gui::Event::USE_ITEM, gui_id); - } -} - void Autowalker::start_autowalk() { fsm.autowalking = true; } - -void Autowalker::face_target(Point target) { - if(rayview->aiming_at != target) rotate_player(target); -} - -bool Autowalker::face_enemy() { - auto& level = GameDB::current_level(); - auto player_at = GameDB::player_position(); - - auto [found, neighbors] = level.collision->neighbors(player_at.location, true); - - if(found) { - auto enemy_pos = level.world->get(neighbors[0]); - face_target(enemy_pos.location); - } else { - dbc::log("No enemies nearby, moving on."); - } - - return found; -} - -void Autowalker::click_inventory(const std::string& name, guecs::Modifiers mods) { - auto& cell = fsm.$status_ui.$gui.cell_for(name); - fsm.$status_ui.mouse(cell.mid_x, cell.mid_y, mods); - fsm.handle_world_events(); -} - -void Autowalker::pocket_potion(GameDB::Level &level) { - auto& inventory = level.world->get(level.player); - - if(inventory.has("pocket_r") && inventory.has("pocket_l")) { - player_use_healing(); - } - - send_event(gui::Event::AIM_CLICK); - - if(inventory.has("pocket_r")) { - click_inventory("pocket_l", {1 << guecs::ModBit::left}); - } else { - click_inventory("pocket_r", {1 << guecs::ModBit::left}); - } -} - -void Autowalker::pickup_item() { - auto& level = GameDB::current_level(); - auto& player_pos = GameDB::player_position(); - auto collision = level.collision; - - if(collision->something_there(player_pos.aiming_at)) { - auto entity = collision->get(player_pos.aiming_at); - fmt::println("AIMING AT entity {} @ {},{}", - entity, player_pos.aiming_at.x, player_pos.aiming_at.y); - - if(level.world->has(entity)) { - pocket_potion(level); - status(L"A POTION"); - } else { - send_event(gui::Event::AIM_CLICK); - status(L"I DON'T KNOW"); - } - } -} diff --git a/autowalker.hpp b/autowalker.hpp index 5a51016..7e9b519 100644 --- a/autowalker.hpp +++ b/autowalker.hpp @@ -1,54 +1,28 @@ #pragma once -#include "ai.hpp" -#include "gui/fsm.hpp" -#include -struct InventoryStats; +#include "gui_fsm.hpp" struct Autowalker { int enemy_count = 0; int item_count = 0; int device_count = 0; - bool map_opened_once = false; - bool weapon_crafted = false; gui::FSM& fsm; - std::shared_ptr rayview; Autowalker(gui::FSM& fsm) - : fsm(fsm), rayview(fsm.$main_ui.$rayview) {} + : fsm(fsm) {} void autowalk(); void start_autowalk(); - void craft_weapon(); - void open_map(); - void close_map(); - bool found_enemy(); - bool found_item(); - - void handle_window_events(); - void handle_boss_fight(); - void handle_player_walk(ai::State& start, ai::State& goal); - - void send_event(gui::Event ev, std::any data={}); + void send_event(gui::Event ev); + void window_events(); void process_combat(); - bool process_move(Pathing& paths, std::function cb); bool path_player(Pathing& paths, Point &target_out); - void path_fail(const std::string& msg, Matrix& bad_paths, Point pos); - void rotate_player(Point target); - void log(std::wstring msg); - void status(std::wstring msg); - void close_status(); - bool player_health_good(); - void player_use_healing(); - InventoryStats player_item_count(); - void update_state(ai::EntityAI& player_ai); - DinkyECS::Entity camera_aim(); - + Point get_current_position(); + void rotate_player(Point current, Point target); + bool player_has_moved(Point target); + void process_move(); Pathing path_to_enemies(); Pathing path_to_items(); - void face_target(Point target); - bool face_enemy(); - void pickup_item(); - void pocket_potion(GameDB::Level &level); - void click_inventory(const std::string& name, guecs::Modifiers mods); + Pathing path_to_devices(); + void show_map_overlay(matrix::Matrix& map, Point current); }; diff --git a/backend.cpp b/backend.cpp deleted file mode 100644 index ef0e8e3..0000000 --- a/backend.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "backend.hpp" -#include "shaders.hpp" -#include "sound.hpp" -#include "textures.hpp" -#include "config.hpp" -#include "palette.hpp" - -namespace sfml { - using namespace nlohmann; - - guecs::SpriteTexture Backend::get_sprite(const string& name) { - auto sp = textures::get_sprite(name); - return {sp.sprite, sp.texture, sp.frame_size}; - } - - guecs::SpriteTexture Backend::get_icon(const string& name) { - auto sp = textures::get_icon(name); - return {sp.sprite, sp.texture, sp.frame_size}; - } - - Backend::Backend() { - sound::init(); - shaders::init(); - textures::init(); - } - - void Backend::sound_play(const string& name) { - sound::play(name); - } - - void Backend::sound_stop(const string& name) { - sound::stop(name); - } - - std::shared_ptr Backend::get_shader(const std::string& name) { - return shaders::get(name); - } - - bool Backend::shader_updated() { - if(shaders::updated($shaders_version)) { - $shaders_version = shaders::version(); - return true; - } else { - return false; - } - } - - guecs::Theme Backend::theme() { - palette::init(); - auto config = Config("assets/config.json")["theme"]; - - guecs::Theme theme { - .BLACK=palette::get("gui/theme:black"), - .DARK_DARK=palette::get("gui/theme:dark_dark"), - .DARK_MID=palette::get("gui/theme:dark_mid"), - .DARK_LIGHT=palette::get("gui/theme:dark_light"), - .MID=palette::get("gui/theme:mid"), - .LIGHT_DARK=palette::get("gui/theme:light_dark"), - .LIGHT_MID=palette::get("gui/theme:light_mid"), - .LIGHT_LIGHT=palette::get("gui/theme:light_light"), - .WHITE=palette::get("gui/theme:white"), - .TRANSPARENT = palette::get("color:transparent") - }; - - theme.PADDING = config["padding"]; - theme.BORDER_PX = config["border_px"]; - theme.TEXT_SIZE = config["text_size"]; - theme.LABEL_SIZE = config["label_size"]; - theme.FILL_COLOR = palette::get("gui/theme:fill_color"); - theme.TEXT_COLOR = palette::get("gui/theme:text_color"); - theme.BG_COLOR = palette::get("gui/theme:bg_color"); - theme.BORDER_COLOR = palette::get("gui/theme:border_color"); - theme.BG_COLOR_DARK = palette::get("gui/theme:bg_color_dark"); - theme.FONT_FILE_NAME = Config::path_to(config["font_file_name"]).string(); - - return theme; - } -} diff --git a/backend.hpp b/backend.hpp deleted file mode 100644 index fc36f35..0000000 --- a/backend.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "guecs/ui.hpp" - -namespace sfml { - using std::string; - - class Backend : public guecs::Backend { - int $shaders_version = 0; - - public: - - Backend(); - guecs::SpriteTexture get_sprite(const string& name); - guecs::SpriteTexture get_icon(const string& name); - void sound_play(const string& name); - void sound_stop(const string& name); - std::shared_ptr get_shader(const std::string& name); - bool shader_updated(); - guecs::Theme theme(); - }; -} diff --git a/battle.cpp b/battle.cpp deleted file mode 100644 index 4709f3d..0000000 --- a/battle.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "rituals.hpp" -#include "battle.hpp" - -namespace combat { - void BattleEngine::add_enemy(Combatant enemy) { - combatants.try_emplace(enemy.entity, enemy); - } - - bool BattleEngine::plan() { - int active = 0; - - for(auto& [entity, enemy] : combatants) { - enemy.ai.update(); - active += enemy.ai.active(); - - if(enemy.ai.active()) { - if(enemy.ai.wants_to("kill_enemy")) { - fmt::println(">> enemy {} wants to KILL", entity); - pending_actions.emplace_back(enemy, BattleAction::ATTACK); - } else if(enemy.ai.wants_to("run_away")) { - fmt::println(">> enemy {} wants to RUN", entity); - pending_actions.emplace_back(enemy, BattleAction::ESCAPE); - } - } - } - - return active > 0; - } - - std::optional BattleEngine::next() { - if(pending_actions.size() == 0) return std::nullopt; - - auto ba = pending_actions.back(); - pending_actions.pop_back(); - return std::make_optional(ba); - } - - void BattleEngine::dump() { - for(auto& [entity, enemy] : combatants) { - fmt::println("\n\n###### ENTITY #{}", entity); - enemy.ai.dump(); - } - } - - void BattleEngine::set(DinkyECS::Entity entity, std::string state, bool setting) { - dbc::check(combatants.contains(entity), "invalid combatant given to BattleEngine"); - auto& action = combatants.at(entity); - action.ai.set_state(state, setting); - } - - void BattleEngine::set_all(std::string state, bool setting) { - for(auto& [ent, action] : combatants) { - action.ai.set_state(state, setting); - } - } - - void BattleEngine::queue(DinkyECS::Entity entity, BattleAction action) { - dbc::check(combatants.contains(entity), "invalid combatant given to BattleEngine"); - auto& enemy = combatants.at(entity); - pending_actions.emplace_back(enemy, action); - } -} diff --git a/battle.hpp b/battle.hpp deleted file mode 100644 index 2aeb6f5..0000000 --- a/battle.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include "rituals.hpp" -#include "config.hpp" -#include "dinkyecs.hpp" -#include -#include "components.hpp" - -namespace combat { - - struct Combatant { - DinkyECS::Entity entity; - ai::EntityAI &ai; - components::Combat &combat; - }; - - enum class BattleAction { - ATTACK, BLOCK, ESCAPE - }; - - struct BattleResult { - Combatant &state; - BattleAction action; - }; - - struct BattleEngine { - std::unordered_map combatants; - std::vector pending_actions; - - void add_enemy(Combatant ba); - bool plan(); - std::optional next(); - void dump(); - void set(DinkyECS::Entity entity, std::string state, bool setting); - void set_all(std::string state, bool setting); - void queue(DinkyECS::Entity entity, BattleAction action); - }; -} diff --git a/gui/boss_fight_ui.cpp b/boss_fight_ui.cpp similarity index 73% rename from gui/boss_fight_ui.cpp rename to boss_fight_ui.cpp index c749651..e92bcc8 100644 --- a/gui/boss_fight_ui.cpp +++ b/boss_fight_ui.cpp @@ -1,7 +1,6 @@ -#include "gui/boss_fight_ui.hpp" +#include "boss_fight_ui.hpp" #include "easings.hpp" #include "sound.hpp" -#include namespace gui { using namespace guecs; @@ -14,17 +13,17 @@ namespace gui { $status.position(0, 0, BOSS_VIEW_X, SCREEN_HEIGHT); $status.layout( "[main_status]" - "[=status_3|=status_4]" - "[=status_5|=status_6]" - "[=status_7|=status_8]"); + "[(150)status_3|(150)status_4]" + "[(150)status_5|(150)status_6]" + "[(150)status_7|(150)status_8]"); $overlay.position(BOSS_VIEW_X, BOSS_VIEW_Y, BOSS_VIEW_WIDTH, BOSS_VIEW_HEIGHT); - $overlay.layout("[=overlay_1|=overlay_2|=overlay_4]" - "[=overlay_5|=overlay_6|=overlay_8]" - "[=overlay_9|=overlay_10|=overlay_12]" - "[=overlay_13|=overlay_14|=overlay_16]"); + $overlay.layout("[overlay_1|overlay_2|overlay_4]" + "[overlay_5|overlay_6|overlay_8]" + "[overlay_9|overlay_10|overlay_12]" + "[overlay_13|overlay_14|overlay_16]"); $sounds = $world->get($boss_id); $combat = $world->get($boss_id); @@ -33,9 +32,9 @@ namespace gui { void BossFightUI::configure_sprite() { $sprite_config = $world->get($boss_id); $animation = $world->get($boss_id); - $animation.frame_width = $sprite_config.width; + $animation.texture_width = $sprite_config.width; - $boss_image = textures::get_sprite($sprite_config.name); + $boss_image = textures::get($sprite_config.name); sf::IntRect frame_rect{{0,0},{$sprite_config.width,$sprite_config.height}}; $boss_image.sprite->setTextureRect(frame_rect); $boss_image.sprite->setScale({$sprite_config.scale, $sprite_config.scale}); @@ -52,13 +51,13 @@ namespace gui { void BossFightUI::configure_background() { auto& boss = $world->get($boss_id); - $boss_background = textures::get_sprite(boss.background); + $boss_background = textures::get(boss.background); $boss_background.sprite->setPosition({BOSS_VIEW_X, BOSS_VIEW_Y}); - $status.set($status.MAIN, {$status.$parser}); + $status.world().set_the({$status.$parser}); if(boss.stage) { $boss_has_stage = true; - $boss_stage = textures::get_sprite(*boss.stage); + $boss_stage = textures::get(*boss.stage); $boss_stage.sprite->setPosition({BOSS_VIEW_X, BOSS_VIEW_Y}); } } @@ -68,14 +67,12 @@ namespace gui { auto button = $status.entity(name); $status.set(button, {}); $status.set(button, { - [this, name](auto){ - dbc::log(fmt::format("STATUS: {}", name)); - } + [this, name](auto, auto){ fmt::println("STATUS: {}", name); } }); if(name == "main_status") { - $status.set(button, {fmt::format(L"HP: {}", $combat.hp)}); + $status.set(button, {fmt::format("HP: {}", $combat.hp)}); } else { - $status.set(button, {L"Attack"}); + $status.set