diff --git a/.gitignore b/.gitignore index 1c82088..ca37570 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,5 @@ backup *.dll *.world coverage +coverage/* .venv diff --git a/.vimrc_proj b/.vimrc_proj index 2b745b4..1d04d48 100644 --- a/.vimrc_proj +++ b/.vimrc_proj @@ -1 +1 @@ -set makeprg=meson\ compile\ -C\ . +set makeprg=make\ -f\ ../Makefile\ build diff --git a/Makefile b/Makefile index 9e0fc75..ece7c1d 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +ROOT_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) + all: build test reset: @@ -8,10 +10,19 @@ else endif %.cpp : %.rl - ragel -o $@ $< + ragel -I $(ROOT_DIR) -G1 -o $@ $< -build: lel_parser.cpp - meson compile -j 10 -C builddir +%.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 release_build: meson --wipe builddir -Db_ndebug=true --buildtype release @@ -25,8 +36,8 @@ tracy_build: meson setup --wipe builddir --buildtype debugoptimized -Dtracy_enable=true -Dtracy:on_demand=true meson compile -j 10 -C builddir -test: build - ./builddir/runtests +test: + ./builddir/runtests -d yes run: build test ifeq '$(OS)' 'Windows_NT' @@ -49,10 +60,13 @@ clean: meson compile --clean -C builddir debug_test: build - gdb --nx -x .gdbinit --ex run --args builddir/runtests -e + gdb --nx -x .gdbinit --ex run --ex bt --ex q --args builddir/runtests -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 diff --git a/ai.hpp b/ai.hpp index 9886b97..3933b5e 100644 --- a/ai.hpp +++ b/ai.hpp @@ -34,6 +34,7 @@ namespace ai { void update(); void dump(); + std::string to_string(); }; struct AIManager { diff --git a/ai_debug.cpp b/ai_debug.cpp index d107fbc..351df2b 100644 --- a/ai_debug.cpp +++ b/ai_debug.cpp @@ -61,4 +61,14 @@ namespace ai { 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/assets/ai.json b/assets/ai.json index c58acb7..446231e 100644 --- a/assets/ai.json +++ b/assets/ai.json @@ -9,7 +9,8 @@ "have_item": 6, "have_healing": 7, "detect_enemy": 8, - "tough_personality": 9 + "tough_personality": 9, + "cant_move": 10 }, "actions": [ { @@ -22,6 +23,7 @@ "enemy_found": false }, "effects": { + "in_combat": true, "enemy_found": true } }, @@ -32,7 +34,8 @@ "tough_personality": false, "in_combat": true, "have_healing": false, - "health_good": false + "health_good": false, + "cant_move": false }, "effects": { "in_combat": false @@ -63,13 +66,24 @@ "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": 0, + "cost": 1, "needs": { "have_item": true, "have_healing": true, - "in_combat": false, "health_good": false }, "effects": { @@ -118,6 +132,7 @@ ["find_enemy", "kill_enemy", "collect_items", + "find_healing", "use_healing"], "Enemy::actions": ["find_enemy", "run_away", "kill_enemy", "use_healing"] diff --git a/assets/armored_knight_1-256.png b/assets/armored_knight_1-256.png deleted file mode 100644 index b8617eb..0000000 Binary files a/assets/armored_knight_1-256.png and /dev/null differ diff --git a/assets/armored_knight_1-512.png b/assets/armored_knight_1-512.png deleted file mode 100644 index a8f780a..0000000 Binary files a/assets/armored_knight_1-512.png and /dev/null differ diff --git a/assets/axe_ranger-256.png b/assets/axe_ranger-256.png deleted file mode 100644 index a63718d..0000000 Binary files a/assets/axe_ranger-256.png and /dev/null differ diff --git a/assets/blood_splatter-256.png b/assets/blood_splatter-256.png deleted file mode 100644 index fb76a8d..0000000 Binary files a/assets/blood_splatter-256.png and /dev/null differ diff --git a/assets/devils_fingers_background.jpg b/assets/bossfights/devils_fingers_background.jpg similarity index 100% rename from assets/devils_fingers_background.jpg rename to assets/bossfights/devils_fingers_background.jpg diff --git a/assets/devils_fingers_sprite.png b/assets/bossfights/devils_fingers_sprite.png similarity index 100% rename from assets/devils_fingers_sprite.png rename to assets/bossfights/devils_fingers_sprite.png diff --git a/assets/devils_fingers_stage.png b/assets/bossfights/devils_fingers_stage.png similarity index 100% rename from assets/devils_fingers_stage.png rename to assets/bossfights/devils_fingers_stage.png diff --git a/assets/down_the_well.jpg b/assets/bossfights/down_the_well.jpg similarity index 100% rename from assets/down_the_well.jpg rename to assets/bossfights/down_the_well.jpg diff --git a/assets/rat_king_2_frame_animation.png b/assets/bossfights/rat_king_2_frame_animation.png similarity index 100% rename from assets/rat_king_2_frame_animation.png rename to assets/bossfights/rat_king_2_frame_animation.png diff --git a/assets/rat_king_boss_fight_background.jpg b/assets/bossfights/rat_king_boss_fight_background.jpg similarity index 100% rename from assets/rat_king_boss_fight_background.jpg rename to assets/bossfights/rat_king_boss_fight_background.jpg diff --git a/assets/rat_king_boss_fight_sprite.png b/assets/bossfights/rat_king_boss_fight_sprite.png similarity index 100% rename from assets/rat_king_boss_fight_sprite.png rename to assets/bossfights/rat_king_boss_fight_sprite.png diff --git a/assets/tunnel_with_rocks.png b/assets/bossfights/tunnel_with_rocks.png similarity index 100% rename from assets/tunnel_with_rocks.png rename to assets/bossfights/tunnel_with_rocks.png diff --git a/assets/tunnel_with_rocks_stage.png b/assets/bossfights/tunnel_with_rocks_stage.png similarity index 100% rename from assets/tunnel_with_rocks_stage.png rename to assets/bossfights/tunnel_with_rocks_stage.png diff --git a/assets/ceiling_test-256.png b/assets/ceiling_test-256.png deleted file mode 100644 index 4bcac90..0000000 Binary files a/assets/ceiling_test-256.png and /dev/null differ diff --git a/assets/ceiling_test-512.png b/assets/ceiling_test-512.png deleted file mode 100644 index c1ad1f3..0000000 Binary files a/assets/ceiling_test-512.png and /dev/null differ diff --git a/assets/ceiling_worm-256.png b/assets/ceiling_worm-256.png deleted file mode 100644 index 805dafe..0000000 Binary files a/assets/ceiling_worm-256.png and /dev/null differ diff --git a/assets/cinqueda_1-256.png b/assets/cinqueda_1-256.png deleted file mode 100644 index f40dd84..0000000 Binary files a/assets/cinqueda_1-256.png and /dev/null differ diff --git a/assets/cinqueda_1-512.png b/assets/cinqueda_1-512.png deleted file mode 100644 index 772abd2..0000000 Binary files a/assets/cinqueda_1-512.png and /dev/null differ diff --git a/assets/config.json b/assets/config.json index e2977e3..a38faba 100644 --- a/assets/config.json +++ b/assets/config.json @@ -22,293 +22,207 @@ "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" + "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" }, "sprites": { "gold_savior": - {"path": "assets/gold_savior-256.png", + {"path": "assets/sprites/gold_savior.png", "frame_width": 256, "frame_height": 256 }, "armored_knight": - {"path": "assets/armored_knight_1-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "sword": - {"path": "assets/cinqueda_1-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "rat_with_sword": - {"path": "assets/rat_with_sword-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "rat_king": - {"path": "assets/rat_king-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "rat_king_boss": - {"path": "assets/rat_king_2_frame_animation.png", - "frame_width": 720, - "frame_height": 720 - }, - "barrel_small": - {"path": "assets/wood_barrel_small-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "torch_pillar": - {"path": "assets/torch_pillar-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "torch_crappy": - {"path": "assets/torch_crappy-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "torch_horizontal_floor": - {"path": "assets/torch_horizontal_floor-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "evil_eye": - {"path": "assets/evil_eye-sprites.png", - "frame_width": 256, - "frame_height": 256 - }, - "peasant_girl": - {"path": "assets/undead_peasant-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "grave_stone": - {"path": "assets/grave_stone-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "floor": - {"path": "assets/floor_tile_test-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "ceiling": - {"path": "assets/ceiling_test-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "healing_potion_small": - {"path": "assets/healing_potion_small-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "well_down": - {"path": "assets/well_down-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "rope_vines_up": - {"path": "assets/rope_vines_up-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "tripwire_trap": - {"path": "assets/tripwire_trap-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "cinqueda": - {"path": "assets/cinqueda_1-256.png", - "frame_width": 256, - "frame_height": 256 - }, - "blood_splatter": - {"path": "assets/blood_splatter-256.png", + {"path": "assets/sprites/armored_knight_1.png", "frame_width": 256, "frame_height": 256 }, "axe_ranger": - {"path": "assets/axe_ranger-256.png", + {"path": "assets/sprites/axe_ranger.png", "frame_width": 256, "frame_height": 256 }, "hairy_spider": - {"path": "assets/hairy_spider-256.png", + {"path": "assets/sprites/hairy_spider.png", "frame_width": 256, "frame_height": 256 }, - "down_the_well": - {"path": "assets/down_the_well.jpg", - "frame_width": 900, - "frame_height": 600 + "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/rat_king_boss_fight_background.jpg", + {"path": "assets/bossfights/rat_king_boss_fight_background.jpg", "frame_width": 1080, "frame_height": 720 }, "devils_fingers_background": - {"path": "assets/devils_fingers_background.jpg", + {"path": "assets/bossfights/devils_fingers_background.jpg", "frame_width": 1080, "frame_height": 720 }, "devils_fingers_sprite": - {"path": "assets/devils_fingers_sprite.png", + {"path": "assets/bossfights/devils_fingers_sprite.png", "frame_width": 720, "frame_height": 720 }, "devils_fingers_stage": - {"path": "assets/devils_fingers_stage.png", + {"path": "assets/bossfights/devils_fingers_stage.png", "frame_width": 1080, "frame_height": 720 }, "tunnel_with_rocks": - {"path": "assets/tunnel_with_rocks.png", + {"path": "assets/bossfights/tunnel_with_rocks.png", "frame_width": 1080, "frame_height": 720 }, "tunnel_with_rocks_stage": - {"path": "assets/tunnel_with_rocks_stage.png", + {"path": "assets/bossfights/tunnel_with_rocks_stage.png", "frame_width": 1080, "frame_height": 720 }, "ritual_crafting_area": - {"path": "assets/ritual_crafting_area.png", - "frame_width": 380, - "frame_height": 720 - }, - "the_ritual_circle": - {"path": "assets/the_ritual_circle.png", - "frame_width": 380, - "frame_height": 380 - }, - "paper_ui_background": - {"path": "assets/paper_ui_background.png", + {"path": "assets/ui/ritual_crafting_area.png", "frame_width": 380, "frame_height": 720 }, "full_screen_paper": - {"path": "assets/full_screen_paper.png", + {"path": "assets/ui/full_screen_paper.png", "frame_width": 1280, "frame_height": 720 }, - "broken_locket-64": - {"path": "assets/rituals/broken_locket-64.png", - "frame_width": 64, - "frame_height": 64 + "broken_locket": + {"path": "assets/items/broken_locket.png", + "frame_width": 256, + "frame_height": 256 }, - "broken_locket-128": - {"path": "assets/rituals/broken_locket-128.png", - "frame_width": 128, - "frame_height": 128 + "broken_pen_knife": + {"path": "assets/items/broken_pen_knife.png", + "frame_width": 256, + "frame_height": 256 }, - "broken_pen_knife-64": - {"path": "assets/rituals/broken_pen_knife-64.png", - "frame_width": 64, - "frame_height": 64 + "broken_yoyo": + {"path": "assets/items/broken_yoyo.png", + "frame_width": 256, + "frame_height": 256 }, - "broken_pen_knife-128": - {"path": "assets/rituals/broken_pen_knife-128.png", - "frame_width": 128, - "frame_height": 128 + "chess_pawn": + {"path": "assets/items/chess_pawn.png", + "frame_width": 256, + "frame_height": 256 }, - "broken_yoyo-64": - {"path": "assets/rituals/broken_yoyo-64.png", - "frame_width": 64, - "frame_height": 64 + "dirty_kerchief": + {"path": "assets/items/dirty_kerchief.png", + "frame_width": 256, + "frame_height": 256 }, - "broken_yoyo-128": - {"path": "assets/rituals/broken_yoyo-128.png", - "frame_width": 128, - "frame_height": 128 + "leather_pouch": + {"path": "assets/items/leather_pouch.png", + "frame_width": 256, + "frame_height": 256 }, - "chess_pawn-64": - {"path": "assets/rituals/chess_pawn-64.png", - "frame_width": 64, - "frame_height": 64 + "mushroom": + {"path": "assets/items/mushroom.png", + "frame_width": 256, + "frame_height": 256 }, - "chess_pawn-128": - {"path": "assets/rituals/chess_pawn-128.png", - "frame_width": 128, - "frame_height": 128 + "pocket_watch": + {"path": "assets/items/pocket_watch.png", + "frame_width": 256, + "frame_height": 256 }, - "dirty_kerchief-64": - {"path": "assets/rituals/dirty_kerchief-64.png", - "frame_width": 64, - "frame_height": 64 + "rusty_nails": + {"path": "assets/items/rusty_nails.png", + "frame_width": 256, + "frame_height": 256 }, - "dirty_kerchief-128": - {"path": "assets/rituals/dirty_kerchief-128.png", - "frame_width": 128, - "frame_height": 128 + "severed_finger": + {"path": "assets/items/severed_finger.png", + "frame_width": 256, + "frame_height": 256 }, - "leather_pouch-64": - {"path": "assets/rituals/leather_pouch-64.png", - "frame_width": 64, - "frame_height": 64 + "stone_doll_cursed": + {"path": "assets/items/stone_doll_cursed.png", + "frame_width": 256, + "frame_height": 256 }, - "leather_pouch-128": - {"path": "assets/rituals/leather_pouch-128.png", - "frame_width": 128, - "frame_height": 128 + "dubious_combination": + {"path": "assets/items/dubious_combination.png", + "frame_width": 256, + "frame_height": 256 }, - "mushroom-64": - {"path": "assets/rituals/mushroom-64.png", - "frame_width": 64, - "frame_height": 64 + "dead_body": + {"path": "assets/sprites/dead_body.png", + "frame_width": 256, + "frame_height": 256 }, - "mushroom-128": - {"path": "assets/rituals/mushroom-128.png", - "frame_width": 128, - "frame_height": 128 - }, - "pocket_watch-64": - {"path": "assets/rituals/pocket_watch-64.png", - "frame_width": 64, - "frame_height": 64 - }, - "pocket_watch-128": - {"path": "assets/rituals/pocket_watch-128.png", - "frame_width": 128, - "frame_height": 128 - }, - "rusty_nails-64": - {"path": "assets/rituals/rusty_nails-64.png", - "frame_width": 64, - "frame_height": 64 - }, - "rusty_nails-128": - {"path": "assets/rituals/rusty_nails-128.png", - "frame_width": 128, - "frame_height": 128 - }, - "severed_finger-64": - {"path": "assets/rituals/severed_finger-64.png", - "frame_width": 64, - "frame_height": 64 - }, - "severed_finger-128": - {"path": "assets/rituals/severed_finger-128.png", - "frame_width": 128, - "frame_height": 128 - }, - "stone_doll_cursed-64": - {"path": "assets/rituals/stone_doll_cursed-64.png", - "frame_width": 64, - "frame_height": 64 - }, - "stone_doll_cursed-128": - {"path": "assets/rituals/stone_doll_cursed-128.png", - "frame_width": 128, - "frame_height": 128 + "dead_body_lootable": + {"path": "assets/sprites/dead_body_lootable.png", + "frame_width": 256, + "frame_height": 256 } }, "worldgen": { "enemy_probability": 50, - "empty_room_probability": 1, "device_probability": 10 }, "graphics": { @@ -324,9 +238,12 @@ "W": 8592, "NW": 8598 }, - "test_rituals": [ - { "has_spikes": true, "active": true }, - { "has_magick": true, "active": true }, - { "has_magick": true, "shiny_bauble": true, "active": true } - ] + "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 d0d2335..58b7897 100644 --- a/assets/devices.json +++ b/assets/devices.json @@ -7,13 +7,13 @@ "inventory_count": 0, "randomized": false, "components": [ - {"_type": "Tile", "display": 10949, - "foreground": [24, 205, 189], - "background": [24, 205, 189] + {"_type": "Tile", "display": 6105, + "foreground": "devices/fg:stairs_down", + "background": "devices/bg:stairs_down" }, {"_type": "Device", - "config": {"test": true}, - "events": ["Events::GUI::STAIRS_DOWN"]}, + "config": {}, + "events": ["STAIRS_DOWN"]}, {"_type": "Sprite", "name": "well_down", "width": 256, "height": 256, "scale": 1.0} ] }, @@ -25,12 +25,12 @@ "placement": "fixed", "components": [ {"_type": "Tile", "display": 8793, - "foreground": [24, 205, 189], - "background": [24, 205, 189] + "foreground": "devices/fg:stairs_up", + "background": "devices/fg:stairs_up" }, {"_type": "Device", - "config": {"test": true}, - "events": ["Events::GUI::STAIRS_UP"]}, + "config": {}, + "events": ["STAIRS_UP"]}, {"_type": "Sprite", "name": "rope_vines_up", "width": 256, "height": 256, "scale": 1.0} ] }, @@ -40,14 +40,66 @@ "description": "Watch where you're going.", "inventory_count": 0, "components": [ - {"_type": "Tile", "display": 6855, - "foreground": [24, 205, 189], - "background": [24, 205, 189] + {"_type": "Tile", "display": 95, + "foreground": "devices/fg:tripwire", + "background": "devices/bg:tripwire" }, - {"_type": "Device", - "config": {"test": true}, - "events": ["Events::GUI::TRAP"]}, + {"_type": "Device", "config": {}, "events": ["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/enemies.json b/assets/enemies.json index c666d24..5fbd8a1 100644 --- a/assets/enemies.json +++ b/assets/enemies.json @@ -2,22 +2,40 @@ "PLAYER_TILE": { "placement": "fixed", "components": [ - {"_type": "Tile", "display": 42603, - "foreground": [255, 200, 125], - "background": [30, 20, 75] + {"_type": "Tile", "display": 10733, + "foreground": "enemies/fg:player", + "background": "color:transparent" }, {"_type": "Combat", "hp": 200, "max_hp": 200, "damage": 10, "dead": false}, {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, - {"_type": "LightSource", "strength": 45, "radius": 2.0} + {"_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"} ] }, "KNIGHT": { "components": [ - {"_type": "Tile", "display": 2189, - "foreground": [131, 213, 238], - "background": [30, 20, 75] + {"_type": "Tile", "display": 2216, + "foreground": "enemies/fg:knight", + "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}, @@ -29,28 +47,30 @@ "AXE_RANGER": { "components": [ {"_type": "Tile", "display": 1898, - "foreground": [156, 172, 197], - "background": [30, 20, 75] + "foreground": "enemies/fg:axe_ranger", + "background": "color:transparent" }, {"_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": "Sprite", "name": "axe_ranger", "width": 256, "height": 256, "scale": 1.0}, - {"_type": "Animation", "easing": 3, "ease_rate": 0.5, "scale": 0.1, "simple": false, "frames": 2, "speed": 0.6, "stationary": false}, + {"_type": "Animation", "easing": 3, "ease_rate": 0.5, "scale": 0.1, "simple": true, "frames": 1, "speed": 0.6, "stationary": false}, {"_type": "Sound", "attack": "Sword_Hit_2", "death": "Ranger_1"} ] }, "RAT_GIANT": { "components": [ {"_type": "Tile", "display": 2220, - "foreground": [205, 164, 246], - "background": [30, 20, 75] + "foreground": "enemies/fg:rat_giant", + "background": "color:transparent" }, {"_type": "Combat", "hp": 50, "max_hp": 50, "damage": 2, "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": false}, + {"_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": "Sprite", "name": "rat_with_sword", "width": 256, "height": 256, "scale": 1.0}, {"_type": "Sound", "attack": "Small_Rat", "death": "Creature_Death_1"} @@ -59,10 +79,11 @@ "SPIDER_GIANT_HAIRY": { "components": [ {"_type": "Tile", "display": 1218, - "foreground": [205, 164, 246], - "background": [30, 20, 75] + "foreground": "enemies/fg:spider_giant", + "background": "color:transparent" }, {"_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}, diff --git a/assets/evil_eye-sprites.png b/assets/evil_eye-sprites.png deleted file mode 100644 index eb07d29..0000000 Binary files a/assets/evil_eye-sprites.png and /dev/null differ diff --git a/assets/evil_eye_test-256.png b/assets/evil_eye_test-256.png deleted file mode 100644 index c6364c3..0000000 Binary files a/assets/evil_eye_test-256.png and /dev/null differ diff --git a/assets/evil_eye_test-512.png b/assets/evil_eye_test-512.png deleted file mode 100644 index 0c9ee45..0000000 Binary files a/assets/evil_eye_test-512.png and /dev/null differ diff --git a/assets/floor_tile_test-256.png b/assets/floor_tile_test-256.png deleted file mode 100644 index 56a2c5e..0000000 Binary files a/assets/floor_tile_test-256.png and /dev/null differ diff --git a/assets/floor_tile_test-512.png b/assets/floor_tile_test-512.png deleted file mode 100644 index 26df65f..0000000 Binary files a/assets/floor_tile_test-512.png and /dev/null differ diff --git a/assets/gold_savior-256.png b/assets/gold_savior-256.png deleted file mode 100644 index c2da3eb..0000000 Binary files a/assets/gold_savior-256.png and /dev/null differ diff --git a/assets/grave_stone-256.png b/assets/grave_stone-256.png deleted file mode 100644 index 4bd9d4b..0000000 Binary files a/assets/grave_stone-256.png and /dev/null differ diff --git a/assets/hairy_spider-256.png b/assets/hairy_spider-256.png deleted file mode 100644 index be2b67f..0000000 Binary files a/assets/hairy_spider-256.png and /dev/null differ diff --git a/assets/hanging_brazier-256.png b/assets/hanging_brazier-256.png deleted file mode 100644 index 005defd..0000000 Binary files a/assets/hanging_brazier-256.png and /dev/null differ diff --git a/assets/healing_potion_small-256.png b/assets/healing_potion_small-256.png deleted file mode 100644 index 0a6c770..0000000 Binary files a/assets/healing_potion_small-256.png and /dev/null differ diff --git a/assets/icons.json b/assets/icons.json new file mode 100644 index 0000000..904cd97 --- /dev/null +++ b/assets/icons.json @@ -0,0 +1,12 @@ +{ + "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 new file mode 100644 index 0000000..491579a Binary files /dev/null and b/assets/icons/healing_potion_small.png differ diff --git a/assets/icons/torch_horizontal_floor.png b/assets/icons/torch_horizontal_floor.png new file mode 100644 index 0000000..2382d7f Binary files /dev/null and b/assets/icons/torch_horizontal_floor.png differ diff --git a/assets/items.json b/assets/items.json index 53df9a8..5c25db3 100644 --- a/assets/items.json +++ b/assets/items.json @@ -7,58 +7,13 @@ "components": [ {"_type": "LightSource", "strength": 50, "radius": 2.5}, {"_type": "Tile", "display": 3848, - "foreground": [24, 120, 189], - "background": [230,120, 120] + "foreground": "items/fg:flame", + "background": "color:transparent" }, {"_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": 7735, - "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": 43754, - "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": 1918, - "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", @@ -66,27 +21,12 @@ "inventory_count": 1, "components": [ {"_type": "Tile", "display": 1003, - "foreground": [255, 205, 189], - "background": [255, 205, 189] + "foreground": "items/fg:potion", + "background": "color:transparent" }, {"_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": 8687, - "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 new file mode 100644 index 0000000..5c138c2 Binary files /dev/null and b/assets/items/broken_locket.png differ diff --git a/assets/items/broken_pen_knife.png b/assets/items/broken_pen_knife.png new file mode 100644 index 0000000..e802d87 Binary files /dev/null and b/assets/items/broken_pen_knife.png differ diff --git a/assets/items/broken_yoyo.png b/assets/items/broken_yoyo.png new file mode 100644 index 0000000..e848cb2 Binary files /dev/null and b/assets/items/broken_yoyo.png differ diff --git a/assets/items/chess_pawn.png b/assets/items/chess_pawn.png new file mode 100644 index 0000000..c79180b Binary files /dev/null and b/assets/items/chess_pawn.png differ diff --git a/assets/items/cinqueda.png b/assets/items/cinqueda.png new file mode 100644 index 0000000..abf4e34 Binary files /dev/null and b/assets/items/cinqueda.png differ diff --git a/assets/items/dirty_kerchief.png b/assets/items/dirty_kerchief.png new file mode 100644 index 0000000..8618ada Binary files /dev/null and b/assets/items/dirty_kerchief.png differ diff --git a/assets/items/dubious_combination.png b/assets/items/dubious_combination.png new file mode 100644 index 0000000..8247a59 Binary files /dev/null and b/assets/items/dubious_combination.png differ diff --git a/assets/items/healing_postion_small.png b/assets/items/healing_postion_small.png new file mode 100644 index 0000000..a2c6f54 Binary files /dev/null and b/assets/items/healing_postion_small.png differ diff --git a/assets/items/healing_potion_small.png b/assets/items/healing_potion_small.png new file mode 100644 index 0000000..b3c8558 Binary files /dev/null and b/assets/items/healing_potion_small.png differ diff --git a/assets/items/leather_pouch.png b/assets/items/leather_pouch.png new file mode 100644 index 0000000..dc57254 Binary files /dev/null and b/assets/items/leather_pouch.png differ diff --git a/assets/items/mushroom.png b/assets/items/mushroom.png new file mode 100644 index 0000000..f6e8bc4 Binary files /dev/null and b/assets/items/mushroom.png differ diff --git a/assets/items/pocket_watch.png b/assets/items/pocket_watch.png new file mode 100644 index 0000000..07821f7 Binary files /dev/null and b/assets/items/pocket_watch.png differ diff --git a/assets/items/rusty_nails.png b/assets/items/rusty_nails.png new file mode 100644 index 0000000..f1eb884 Binary files /dev/null and b/assets/items/rusty_nails.png differ diff --git a/assets/items/severed_finger.png b/assets/items/severed_finger.png new file mode 100644 index 0000000..187def8 Binary files /dev/null and b/assets/items/severed_finger.png differ diff --git a/assets/items/stone_doll_cursed.png b/assets/items/stone_doll_cursed.png new file mode 100644 index 0000000..e99ef76 Binary files /dev/null and b/assets/items/stone_doll_cursed.png differ diff --git a/assets/items/torch_crappy.png b/assets/items/torch_crappy.png new file mode 100644 index 0000000..c31ee6d Binary files /dev/null and b/assets/items/torch_crappy.png differ diff --git a/assets/items/torch_horizontal_floor.png b/assets/items/torch_horizontal_floor.png new file mode 100644 index 0000000..474ede9 Binary files /dev/null and b/assets/items/torch_horizontal_floor.png differ diff --git a/assets/items/wood_barrel_small.png b/assets/items/wood_barrel_small.png new file mode 100644 index 0000000..a172fd1 Binary files /dev/null and b/assets/items/wood_barrel_small.png differ diff --git a/assets/map_tiles.json b/assets/map_tiles.json new file mode 100644 index 0000000..a0e2623 --- /dev/null +++ b/assets/map_tiles.json @@ -0,0 +1,140 @@ +[ + { + "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 new file mode 100644 index 0000000..67c5ae3 Binary files /dev/null and b/assets/map_tiles.png differ diff --git a/assets/palette.json b/assets/palette.json new file mode 100644 index 0000000..3fde82c --- /dev/null +++ b/assets/palette.json @@ -0,0 +1,81 @@ +{ + "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/paper_ui_background.png b/assets/paper_ui_background.png deleted file mode 100644 index 13013f7..0000000 Binary files a/assets/paper_ui_background.png and /dev/null differ diff --git a/assets/rat-king-boss-fight-test-small.jpg b/assets/rat-king-boss-fight-test-small.jpg deleted file mode 100644 index 5ad3dd6..0000000 Binary files a/assets/rat-king-boss-fight-test-small.jpg and /dev/null differ diff --git a/assets/rat_king-256.png b/assets/rat_king-256.png deleted file mode 100644 index a2315c4..0000000 Binary files a/assets/rat_king-256.png and /dev/null differ diff --git a/assets/rat_with_sword-256.png b/assets/rat_with_sword-256.png deleted file mode 100644 index 86e8ecb..0000000 Binary files a/assets/rat_with_sword-256.png and /dev/null differ diff --git a/assets/rituals.json b/assets/rituals.json index e24c464..6b34963 100644 --- a/assets/rituals.json +++ b/assets/rituals.json @@ -169,5 +169,34 @@ "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/dubious_combination-128.png b/assets/rituals/dubious_combination-128.png new file mode 100644 index 0000000..7a752b4 Binary files /dev/null and b/assets/rituals/dubious_combination-128.png differ diff --git a/assets/rituals/dubious_combination-64.png b/assets/rituals/dubious_combination-64.png new file mode 100644 index 0000000..6068cc6 Binary files /dev/null and b/assets/rituals/dubious_combination-64.png differ diff --git a/assets/rope_vines_up-256.png b/assets/rope_vines_up-256.png deleted file mode 100644 index 31159e9..0000000 Binary files a/assets/rope_vines_up-256.png and /dev/null differ diff --git a/assets/shaders/flame_trash.frag b/assets/shaders/flame_trash.frag index efcceca..092e4fd 100644 --- a/assets/shaders/flame_trash.frag +++ b/assets/shaders/flame_trash.frag @@ -1,8 +1,10 @@ +#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, @@ -26,7 +28,7 @@ float noise(in vec2 st) { (d - b) * u.x * u.y; } -float fbm(in vec2 st, int octaves=8) { +float fbm(in vec2 st) { float v = 0.0; float a = 0.5; vec2 shift = vec2(100.0); @@ -47,7 +49,7 @@ void main() { vec3 color = vec3(0.0); float speed = u_time * 10.0; - float value = cos(u_time) * cos(u_time); + float value = 0.8; // cos(u_time) * cos(u_time); vec2 q = vec2(0.0); q.x = fbm(st + 0.00 * speed); diff --git a/assets/shaders/lightning_attack.frag b/assets/shaders/lightning_attack.frag index 577cd14..eb41295 100644 --- a/assets/shaders/lightning_attack.frag +++ b/assets/shaders/lightning_attack.frag @@ -1,8 +1,10 @@ +#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, @@ -26,7 +28,7 @@ float noise(in vec2 st) { (d - b) * u.x * u.y; } -float fbm(in vec2 st, int octaves=8) { +float fbm(in vec2 st) { float v = 0.0; float a = 0.5; vec2 shift = vec2(100.0); diff --git a/assets/sounds/fireball_01.ogg b/assets/sounds/fireball_01.ogg index 5346559..d819833 100644 Binary files a/assets/sounds/fireball_01.ogg and b/assets/sounds/fireball_01.ogg differ diff --git a/assets/sounds/hp_status_00.ogg b/assets/sounds/hp_status_00.ogg new file mode 100644 index 0000000..dad539b Binary files /dev/null and b/assets/sounds/hp_status_00.ogg differ diff --git a/assets/sounds/hp_status_10.ogg b/assets/sounds/hp_status_10.ogg new file mode 100644 index 0000000..08c1dc2 Binary files /dev/null and b/assets/sounds/hp_status_10.ogg differ diff --git a/assets/sounds/hp_status_30.ogg b/assets/sounds/hp_status_30.ogg new file mode 100644 index 0000000..b9c8ddc Binary files /dev/null and b/assets/sounds/hp_status_30.ogg differ diff --git a/assets/sounds/hp_status_60.ogg b/assets/sounds/hp_status_60.ogg new file mode 100644 index 0000000..84849dc Binary files /dev/null and b/assets/sounds/hp_status_60.ogg differ diff --git a/assets/sounds/hp_status_80.ogg b/assets/sounds/hp_status_80.ogg new file mode 100644 index 0000000..fd2d2b6 Binary files /dev/null and b/assets/sounds/hp_status_80.ogg differ diff --git a/assets/sprites/armored_knight_1.png b/assets/sprites/armored_knight_1.png new file mode 100644 index 0000000..d32e3f8 Binary files /dev/null and b/assets/sprites/armored_knight_1.png differ diff --git a/assets/sprites/axe_ranger.png b/assets/sprites/axe_ranger.png new file mode 100644 index 0000000..ecd3a5d Binary files /dev/null and b/assets/sprites/axe_ranger.png differ diff --git a/assets/sprites/dead_body.png b/assets/sprites/dead_body.png new file mode 100644 index 0000000..8337eda Binary files /dev/null and b/assets/sprites/dead_body.png differ diff --git a/assets/sprites/dead_body_lootable.png b/assets/sprites/dead_body_lootable.png new file mode 100644 index 0000000..69666a9 Binary files /dev/null and b/assets/sprites/dead_body_lootable.png differ diff --git a/assets/sprites/gold_savior.png b/assets/sprites/gold_savior.png new file mode 100644 index 0000000..4c2b640 Binary files /dev/null and b/assets/sprites/gold_savior.png differ diff --git a/assets/sprites/grave_stone.png b/assets/sprites/grave_stone.png new file mode 100644 index 0000000..4891a30 Binary files /dev/null and b/assets/sprites/grave_stone.png differ diff --git a/assets/sprites/hairy_spider.png b/assets/sprites/hairy_spider.png new file mode 100644 index 0000000..6cee0fb Binary files /dev/null and b/assets/sprites/hairy_spider.png differ diff --git a/assets/sprites/peasant_girl_2.png b/assets/sprites/peasant_girl_2.png new file mode 100644 index 0000000..9288fb9 Binary files /dev/null and b/assets/sprites/peasant_girl_2.png differ diff --git a/assets/sprites/rat_with_sword.png b/assets/sprites/rat_with_sword.png new file mode 100644 index 0000000..bcb52d0 Binary files /dev/null and b/assets/sprites/rat_with_sword.png differ diff --git a/assets/sprites/rope_vines_up.png b/assets/sprites/rope_vines_up.png new file mode 100644 index 0000000..230d2e8 Binary files /dev/null and b/assets/sprites/rope_vines_up.png differ diff --git a/assets/sprites/torch_pillar.png b/assets/sprites/torch_pillar.png new file mode 100644 index 0000000..813aa76 Binary files /dev/null and b/assets/sprites/torch_pillar.png differ diff --git a/assets/sprites/tripwire_trap.png b/assets/sprites/tripwire_trap.png new file mode 100644 index 0000000..edf206b Binary files /dev/null and b/assets/sprites/tripwire_trap.png differ diff --git a/assets/sprites/undead_peasant.png b/assets/sprites/undead_peasant.png new file mode 100644 index 0000000..097227a Binary files /dev/null and b/assets/sprites/undead_peasant.png differ diff --git a/assets/sprites/well_down.png b/assets/sprites/well_down.png new file mode 100644 index 0000000..fe5e74b Binary files /dev/null and b/assets/sprites/well_down.png differ diff --git a/assets/styles.json b/assets/styles.json new file mode 100644 index 0000000..b1822d4 --- /dev/null +++ b/assets/styles.json @@ -0,0 +1,17 @@ +[ + { + "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 new file mode 100644 index 0000000..156cd17 Binary files /dev/null and b/assets/textures/ceiling_black.png differ diff --git a/assets/textures/ceiling_blue_light.png b/assets/textures/ceiling_blue_light.png new file mode 100644 index 0000000..def9a8e Binary files /dev/null and b/assets/textures/ceiling_blue_light.png differ diff --git a/assets/textures/floor_gray_stone.png b/assets/textures/floor_gray_stone.png new file mode 100644 index 0000000..b8d92e9 Binary files /dev/null and b/assets/textures/floor_gray_stone.png differ diff --git a/assets/textures/glowing_moss_wall.png b/assets/textures/glowing_moss_wall.png new file mode 100644 index 0000000..8bbf40a Binary files /dev/null and b/assets/textures/glowing_moss_wall.png differ diff --git a/assets/textures/gray_stone_floor_light.png b/assets/textures/gray_stone_floor_light.png new file mode 100644 index 0000000..388f63d Binary files /dev/null and b/assets/textures/gray_stone_floor_light.png differ diff --git a/assets/textures/lava_floor.png b/assets/textures/lava_floor.png new file mode 100644 index 0000000..da8b46c Binary files /dev/null and b/assets/textures/lava_floor.png differ diff --git a/assets/textures/wall_plain.png b/assets/textures/wall_plain.png new file mode 100644 index 0000000..40286ea Binary files /dev/null and b/assets/textures/wall_plain.png differ diff --git a/assets/textures/wood_wall.png b/assets/textures/wood_wall.png new file mode 100644 index 0000000..8f745c8 Binary files /dev/null and b/assets/textures/wood_wall.png differ diff --git a/assets/the_ritual_circle.png b/assets/the_ritual_circle.png deleted file mode 100644 index 8f6d447..0000000 Binary files a/assets/the_ritual_circle.png and /dev/null differ diff --git a/assets/tiles.json b/assets/tiles.json index b586dab..c45d559 100644 --- a/assets/tiles.json +++ b/assets/tiles.json @@ -1,23 +1,69 @@ { - "FLOOR_TILE": { - "texture": "assets/floor_tile_test-256.png", - "foreground": [40, 15, 125], - "background": [200, 15, 75], - "collision": false, - "display": 10398 + "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 }, - "WALL_PLAIN": { - "texture": "assets/wall_texture_test-256.png", - "foreground": [230, 20, 30], - "background": [230, 20, 120], - "collision": true, - "display": 9608 + "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_VINES": { - "texture": "assets/wall_with_vines-256.png", - "foreground": [230, 20, 30], - "background": [230, 20, 120], - "collision": false, - "display": 35 + "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 } } diff --git a/assets/torch_crappy-256.png b/assets/torch_crappy-256.png deleted file mode 100644 index 9e7bcdc..0000000 Binary files a/assets/torch_crappy-256.png and /dev/null differ diff --git a/assets/torch_horizontal_floor-256.png b/assets/torch_horizontal_floor-256.png deleted file mode 100644 index 3c7c718..0000000 Binary files a/assets/torch_horizontal_floor-256.png and /dev/null differ diff --git a/assets/torch_pillar-256.png b/assets/torch_pillar-256.png deleted file mode 100644 index 9431f04..0000000 Binary files a/assets/torch_pillar-256.png and /dev/null differ diff --git a/assets/torch_pillar-512.png b/assets/torch_pillar-512.png deleted file mode 100644 index d7f580e..0000000 Binary files a/assets/torch_pillar-512.png and /dev/null differ diff --git a/assets/tripwire_trap-256.png b/assets/tripwire_trap-256.png deleted file mode 100644 index 1a6b4c0..0000000 Binary files a/assets/tripwire_trap-256.png and /dev/null differ diff --git a/assets/full_screen_paper.png b/assets/ui/UI/full_screen_paper.png similarity index 100% rename from assets/full_screen_paper.png rename to assets/ui/UI/full_screen_paper.png diff --git a/assets/ui/UI/ritual_crafting_area.png b/assets/ui/UI/ritual_crafting_area.png new file mode 100644 index 0000000..120d921 Binary files /dev/null and b/assets/ui/UI/ritual_crafting_area.png differ diff --git a/assets/ui/full_screen_paper.png b/assets/ui/full_screen_paper.png new file mode 100644 index 0000000..12b5cfd Binary files /dev/null and b/assets/ui/full_screen_paper.png differ diff --git a/assets/ritual_crafting_area.png b/assets/ui/ritual_crafting_area.png similarity index 100% rename from assets/ritual_crafting_area.png rename to assets/ui/ritual_crafting_area.png diff --git a/assets/undead_peasant-256.png b/assets/undead_peasant-256.png deleted file mode 100644 index eed23a3..0000000 Binary files a/assets/undead_peasant-256.png and /dev/null differ diff --git a/assets/undead_peasant-spritesheet.png b/assets/undead_peasant-spritesheet.png deleted file mode 100644 index bb82572..0000000 Binary files a/assets/undead_peasant-spritesheet.png and /dev/null differ diff --git a/assets/wall_simple-256.png b/assets/wall_simple-256.png deleted file mode 100644 index 6c76722..0000000 Binary files a/assets/wall_simple-256.png and /dev/null differ diff --git a/assets/wall_texture_test-256.png b/assets/wall_texture_test-256.png deleted file mode 100644 index 217c625..0000000 Binary files a/assets/wall_texture_test-256.png and /dev/null differ diff --git a/assets/wall_texture_test-512.png b/assets/wall_texture_test-512.png deleted file mode 100644 index e68dd88..0000000 Binary files a/assets/wall_texture_test-512.png and /dev/null differ diff --git a/assets/wall_with_pillars-256.png b/assets/wall_with_pillars-256.png deleted file mode 100644 index 7715274..0000000 Binary files a/assets/wall_with_pillars-256.png and /dev/null differ diff --git a/assets/wall_with_vines-256.png b/assets/wall_with_vines-256.png deleted file mode 100644 index da524ac..0000000 Binary files a/assets/wall_with_vines-256.png and /dev/null differ diff --git a/assets/well_down-256.png b/assets/well_down-256.png deleted file mode 100644 index 514de63..0000000 Binary files a/assets/well_down-256.png and /dev/null differ diff --git a/assets/wood_barrel_large-256.png b/assets/wood_barrel_large-256.png deleted file mode 100644 index 6cf2732..0000000 Binary files a/assets/wood_barrel_large-256.png and /dev/null differ diff --git a/assets/wood_barrel_large-512.png b/assets/wood_barrel_large-512.png deleted file mode 100644 index 37b1898..0000000 Binary files a/assets/wood_barrel_large-512.png and /dev/null differ diff --git a/assets/wood_barrel_small-256.png b/assets/wood_barrel_small-256.png deleted file mode 100644 index 43aede2..0000000 Binary files a/assets/wood_barrel_small-256.png and /dev/null differ diff --git a/assets/wood_wall-256.png b/assets/wood_wall-256.png deleted file mode 100644 index 6851bdc..0000000 Binary files a/assets/wood_wall-256.png and /dev/null differ diff --git a/assets/wood_wall-512.png b/assets/wood_wall-512.png deleted file mode 100644 index 8924713..0000000 Binary files a/assets/wood_wall-512.png and /dev/null differ diff --git a/autowalker.cpp b/autowalker.cpp index 62fb052..9f5ac9d 100644 --- a/autowalker.cpp +++ b/autowalker.cpp @@ -1,14 +1,23 @@ #include "autowalker.hpp" -#include "inventory.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; +}; template -int number_left(gui::FSM& fsm) { +int number_left() { int count = 0; + auto world = GameDB::current_world(); + auto player = GameDB::the_player(); - fsm.$level.world->query( + world->query( [&](const auto ent, auto&, auto&) { - if(ent != fsm.$level.player) { + if(ent != player) { count++; } }); @@ -17,31 +26,31 @@ int number_left(gui::FSM& fsm) { } template -Pathing compute_paths(gui::FSM& fsm) { - auto& walls_original = fsm.$level.map->$walls; - auto walls_copy = walls_original; +Pathing compute_paths() { + auto& level = GameDB::current_level(); + auto walls_copy = level.map->$walls; Pathing paths{matrix::width(walls_copy), matrix::height(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); - } 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); + System::multi_path(level, 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.$status_ui.log(msg); + fsm.$map_ui.log(msg); } void Autowalker::status(std::wstring msg) { @@ -53,18 +62,13 @@ void Autowalker::close_status() { } Pathing Autowalker::path_to_enemies() { - return compute_paths(fsm); + return compute_paths(); } Pathing Autowalker::path_to_items() { - return compute_paths(fsm); + return compute_paths(); } -Pathing Autowalker::path_to_devices() { - return compute_paths(fsm); -} - - void Autowalker::handle_window_events() { fsm.$window.handleEvents( [&](const sf::Event::KeyPressed &) { @@ -87,126 +91,87 @@ void Autowalker::process_combat() { if(fsm.in_state(gui::State::ATTACKING)) { send_event(gui::Event::TICK); } else { - send_event(gui::Event::ATTACK);; + send_event(gui::Event::ATTACK); } } } -Point Autowalker::get_current_position() { - auto& player_position = fsm.$level.world->get(fsm.$level.player); - return player_position.location; -} - -void Autowalker::path_fail(Matrix& bad_paths, Point pos) { +void Autowalker::path_fail(const std::string& msg, Matrix& bad_paths, Point pos) { + dbc::log(msg); status(L"PATH FAIL"); - log(L"Autowalk failed to find a path."); 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); } bool Autowalker::path_player(Pathing& paths, Point& target_out) { - bool found = paths.random_walk(target_out, false, PATHING_TOWARD, 4, 8); + auto& level = GameDB::current_level(); + auto found = paths.find_path(target_out, PATHING_TOWARD, false); - if(!found) { + if(found == PathingResult::FAIL) { // failed to find a linear path, try diagonal - if(!paths.random_walk(target_out, false, PATHING_TOWARD, 8, 8)) { - path_fail(paths.$paths, target_out); + if(paths.find_path(target_out, PATHING_TOWARD, true) == PathingResult::FAIL) { + path_fail("random_walk", paths.$paths, target_out); return false; } } - if(!fsm.$level.map->can_move(target_out)) { - path_fail(paths.$paths, target_out); + if(!level.map->can_move(target_out)) { + path_fail("level_map->can_move", paths.$paths, target_out); return false; } return true; } -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); +void Autowalker::rotate_player(Point target) { + auto &player = GameDB::player_position(); - int facing = fsm.$main_ui.$compass_dir; - int target_facing = 0; - - /* This is a massive pile of garbage. Need a way - * to determine player facing direction without - * hacking into the compass, and also do accurate - * turns. - */ - 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 if(delta_x == 1 && delta_y == -1) { - // north east - target_facing = 7; - } else if(delta_x == 1 && delta_y == 1) { - // south east - target_facing = 1; - } else if(delta_x == -1 && delta_y == 1) { - // south west - target_facing = 3; - } else if(delta_x == -1 && delta_y == -1) { - // north west - target_facing = 5; - } else { - dbc::sentinel( - fmt::format("got more than 8 direction result: " - "current={},{} " - "target={},{} " - "delta={},{} ", - current.x, current.y, - target.x, target.y, - delta_x, delta_y)); + if(target == player.location) { + dbc::log("player stuck at a locatoin"); + fsm.autowalking = false; + return; } - auto dir = facing > target_facing ? gui::Event::ROTATE_LEFT : gui::Event::ROTATE_RIGHT; + auto dir = System::shortest_rotate(player.location, player.aiming_at, target); + + for(int i = 0; player.aiming_at != target; i++) { + if(i > 10) { + dbc::log("HIT OVER ROTATE BUG!"); + break; + } - while(facing != target_facing) { send_event(dir); - facing = fsm.$main_ui.$compass_dir; + + while(fsm.in_state(gui::State::ROTATING) || + fsm.in_state(gui::State::COMBAT_ROTATE)) + { + send_event(gui::Event::TICK); + } } - while(fsm.in_state(gui::State::ROTATING)) send_event(gui::Event::TICK); - - dbc::check(fsm.$main_ui.$compass_dir == target_facing, - "player isn't facing the correct direction"); + fsm.autowalking = player.aiming_at == target; } -struct InventoryStats { - int healing = 0; - int other = 0; -}; +void Autowalker::update_state(ai::EntityAI& player_ai) { + int enemy_count = number_left(); + int item_count = number_left(); -ai::State Autowalker::update_state(ai::State start) { - int enemy_count = number_left(fsm); - int item_count = number_left(fsm); + player_ai.set_state("no_more_enemies", enemy_count == 0); + player_ai.set_state("no_more_items", item_count == 0); - ai::set(start, "no_more_enemies", enemy_count == 0); - ai::set(start, "no_more_items", item_count == 0); - ai::set(start, "enemy_found", - fsm.in_state(gui::State::IN_COMBAT) || - fsm.in_state(gui::State::ATTACKING)); - ai::set(start, "health_good", player_health_good()); - ai::set(start, "in_combat", + 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(); - ai::set(start, "have_item", inv.other > 0 || inv.healing > 0); - ai::set(start, "have_healing", inv.healing > 0); + player_ai.set_state("have_item", inv.other > 0 || inv.healing > 0); + player_ai.set_state("have_healing", inv.healing > 0); - return start; + player_ai.update(); } void Autowalker::handle_boss_fight() { @@ -214,51 +179,102 @@ void Autowalker::handle_boss_fight() { 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) { - start = update_state(start); - auto a_plan = ai::plan("Host::actions", start, goal); - auto action = a_plan.script.front(); + ai::EntityAI player_ai("Host::actions", start, goal); + update_state(player_ai); + auto level = GameDB::current_level(); - if(action.name == "find_enemy") { - // this is where to test if enemy found and update state + if(player_ai.wants_to("find_enemy")) { status(L"FINDING ENEMY"); auto paths = path_to_enemies(); - process_move(paths); - send_event(gui::Event::ATTACK); - } else if(action.name == "kill_enemy") { + 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"); - // TODO: find the enemy and then rotate toward them - Point current = get_current_position(); if(fsm.in_state(gui::State::IN_COMBAT)) { - rotate_player(current, {current.x - 1, current.y - 1}); - dbc::log("TODO: you should find the enemy and face them instead of THIS GARBAGE!"); + if(face_enemy()) { + process_combat(); + } } - - process_combat(); - } else if(action.name == "use_healing") { + } else if(player_ai.wants_to("use_healing")) { status(L"USING HEALING"); player_use_healing(); - } else if(action.name == "collect_items") { - status(L"COLLECTING ITEMS"); + } 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(); - process_move(paths); - // path to the items and get them all - } else if(action == ai::FINAL_ACTION) { + + 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; - ai::dump_script("AUTOWALK", start, a_plan.script); } else { close_status(); - dbc::log(fmt::format("Unknown action: {}", action.name)); + 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); + } +} void Autowalker::autowalk() { handle_window_events(); @@ -267,6 +283,10 @@ void Autowalker::autowalk() { return; } + craft_weapon(); + open_map(); + face_enemy(); + int move_attempts = 0; auto start = ai::load_state("Host::initial_state"); @@ -277,65 +297,166 @@ void Autowalker::autowalk() { handle_boss_fight(); handle_player_walk(start, goal); + close_map(); + move_attempts++; } while(move_attempts < 100 && fsm.autowalking); } -void Autowalker::process_move(Pathing& paths) { - Point current = get_current_position(); - Point target = current; +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; - if(!path_player(paths, target)) { + // ... 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; + return false; } - rotate_player(current, target); + if(rayview->aiming_at != target_out) rotate_player(target_out); - send_event(gui::Event::MOVE_FORWARD); - while(fsm.in_state(gui::State::MOVING)) send_event(gui::Event::TICK); + 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::send_event(gui::Event ev) { - fsm.event(ev); +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::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); fsm.render(); fsm.handle_world_events(); } bool Autowalker::player_health_good() { - auto combat = fsm.$level.world->get(fsm.$level.player); - return float(combat.hp) / float(combat.max_hp) > 0.5f; + 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() { - auto& inventory = fsm.$level.world->get(fsm.$level.player); InventoryStats stats; + auto& level = GameDB::current_level(); + auto& inventory = level.world->get(level.player); - for(auto& item : inventory.items) { - if(item.data["id"] == "POTION_HEALING_SMALL") { - stats.healing += item.count; - } else { - stats.other += item.count; - } + 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& inventory = fsm.$level.world->get(fsm.$level.player); - // find the healing slot - for(size_t slot = 0; slot < inventory.count(); slot++) { - auto& item = inventory.get(slot); - if(item.data["id"] == "POTION_HEALING_SMALL") { - inventory.use(fsm.$level, slot); - fsm.$status_ui.update(); - return; - } + 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 984bdcd..5a51016 100644 --- a/autowalker.hpp +++ b/autowalker.hpp @@ -1,7 +1,7 @@ #pragma once #include "ai.hpp" - -#include "gui_fsm.hpp" +#include "gui/fsm.hpp" +#include struct InventoryStats; @@ -9,34 +9,46 @@ 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) {} + : fsm(fsm), rayview(fsm.$main_ui.$rayview) {} 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); + void send_event(gui::Event ev, std::any data={}); void process_combat(); + bool process_move(Pathing& paths, std::function cb); bool path_player(Pathing& paths, Point &target_out); - void path_fail(Matrix& bad_paths, Point pos); - Point get_current_position(); - void rotate_player(Point current, Point target); - void process_move(Pathing& paths); + 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(); - ai::State update_state(ai::State start); + void update_state(ai::EntityAI& player_ai); + DinkyECS::Entity camera_aim(); Pathing path_to_enemies(); Pathing path_to_items(); - Pathing path_to_devices(); + 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); }; diff --git a/backend.cpp b/backend.cpp new file mode 100644 index 0000000..ef0e8e3 --- /dev/null +++ b/backend.cpp @@ -0,0 +1,78 @@ +#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 new file mode 100644 index 0000000..fc36f35 --- /dev/null +++ b/backend.hpp @@ -0,0 +1,20 @@ +#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 index e6066e7..4709f3d 100644 --- a/battle.cpp +++ b/battle.cpp @@ -15,8 +15,10 @@ namespace combat { 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); } } diff --git a/camera.cpp b/camera.cpp deleted file mode 100644 index 2293cd6..0000000 --- a/camera.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "camera.hpp" -#include -#include - -Point CameraLOL::plan_move(int dir, bool strafe) { - t = 0.0; - if(strafe) { - target_x = rayview.$pos_x + int(-rayview.$dir_y * 1.5 * dir); - target_y = rayview.$pos_y + int(rayview.$dir_x * 1.5 * dir); - } else { - target_x = rayview.$pos_x + int(rayview.$dir_x * 1.5 * dir); - target_y = rayview.$pos_y + int(rayview.$dir_y * 1.5 * dir); - } - - return {size_t(target_x), size_t(target_y)}; -} - -void CameraLOL::plan_rotate(int dir) { - t = 0.0; - double angle_dir = std::numbers::pi * 0.25 * dir; - - target_dir_x = rayview.$dir_x * cos(angle_dir) - rayview.$dir_y * sin(angle_dir); - target_dir_y = rayview.$dir_x * sin(angle_dir) + rayview.$dir_y * cos(angle_dir); - - target_plane_x = rayview.$plane_x * cos(angle_dir) - rayview.$plane_y * sin(angle_dir); - target_plane_y = rayview.$plane_x * sin(angle_dir) + rayview.$plane_y * cos(angle_dir); -} - -bool CameraLOL::play_rotate() { - t += rot_speed; - rayview.$dir_x = std::lerp(rayview.$dir_x, target_dir_x, t); - rayview.$dir_y = std::lerp(rayview.$dir_y, target_dir_y, t); - rayview.$plane_x = std::lerp(rayview.$plane_x, target_plane_x, t); - rayview.$plane_y = std::lerp(rayview.$plane_y, target_plane_y, t); - - return t >= 1.0; -} - -bool CameraLOL::play_move() { - t += move_speed; - rayview.$pos_x = std::lerp(rayview.$pos_x, target_x, t); - rayview.$pos_y = std::lerp(rayview.$pos_y, target_y, t); - return t >= 1.0; -} - -void CameraLOL::abort_plan() { - target_x = rayview.$pos_x; - target_y = rayview.$pos_y; -} - -Point CameraLOL::aimed_at() { - return { - size_t(rayview.$pos_x + rayview.$dir_x), - size_t(rayview.$pos_y + rayview.$dir_y) - }; -} diff --git a/camera.hpp b/camera.hpp index d403045..9bd8edc 100644 --- a/camera.hpp +++ b/camera.hpp @@ -1,8 +1,6 @@ #pragma once -#include "raycaster.hpp" struct CameraLOL { - Raycaster& rayview; double t = 0.0; double move_speed = 0.1; double rot_speed = 0.06; @@ -12,16 +10,4 @@ struct CameraLOL { double target_dir_y = 0.0; double target_plane_x = 0.0; double target_plane_y = 0.0; - - CameraLOL(Raycaster& rv) : - rayview(rv) {} - - Point plan_move(int dir, bool strafe); - void plan_rotate(int dir); - - bool play_rotate(); - bool play_move(); - - void abort_plan(); - Point aimed_at(); }; diff --git a/color.hpp b/color.hpp deleted file mode 100644 index 4026ba5..0000000 --- a/color.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include - -namespace ColorValue { - const sf::Color BLACK{0, 0, 0}; - const sf::Color DARK_DARK{10, 10, 10}; - const sf::Color DARK_MID{30, 30, 30}; - const sf::Color DARK_LIGHT{60, 60, 60}; - const sf::Color MID{100, 100, 100}; - const sf::Color LIGHT_DARK{150, 150, 150}; - const sf::Color LIGHT_MID{200, 200, 200}; - const sf::Color LIGHT_LIGHT{230, 230, 230}; - const sf::Color WHITE{255, 255, 255}; - const sf::Color TRANSPARENT = sf::Color::Transparent; -} diff --git a/combat_ui.cpp b/combat_ui.cpp deleted file mode 100644 index 37def37..0000000 --- a/combat_ui.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "combat_ui.hpp" -#include "constants.hpp" -#include "color.hpp" -#include "rituals.hpp" -#include - -namespace gui { - using namespace guecs; - - CombatUI::CombatUI(GameLevel level) : - $level(level) - { - $gui.position(COMBAT_UI_X, COMBAT_UI_Y, COMBAT_UI_WIDTH, COMBAT_UI_HEIGHT); - $gui.layout( - "[*%(100,150)button_0 | *%(100,150)button_1 | *%(100,150)button_2 | *%(100,150)button_3]"); - } - - DinkyECS::Entity CombatUI::make_button(std::string name, std::wstring label, Events::GUI event, int action, const std::string &icon_name, - const std::string &sound, const std::string &effect_name) - { - (void)label; - auto button = $gui.entity(name); - $gui.set(button, {icon_name}); - // $gui.set(button, {}); - // $gui.set