diff --git a/animation.cpp b/animation.cpp index 7075ba8..c901119 100644 --- a/animation.cpp +++ b/animation.cpp @@ -72,7 +72,7 @@ namespace animation { bool apply(Animation& anim, sf::Sprite& sprite) { sf::IntRect rect{{0,0}, {anim.frame_width, anim.frame_height}}; - sf::Vector2f scale{1.0, 1.0}; + sf::Vector2f scale{anim.scale, anim.scale}; sf::Vector2f pos{0, 0}; anim.step(scale, pos, rect); diff --git a/assets/animations.json b/assets/animations.json index 2ba620e..16725d3 100644 --- a/assets/animations.json +++ b/assets/animations.json @@ -49,6 +49,16 @@ "speed": 0.2, "stationary": true }, + "peasant_girl_rear_view": { + "_type": "Animation", + "easing": 3, + "ease_rate": 0.2, + "scale": 0.5, + "simple": true, + "frames": 1, + "speed": 0.03, + "stationary": true + }, "gold_savior": { "_type": "Animation", "easing": 1, diff --git a/assets/config.json b/assets/config.json index 1ebfcc2..b2da914 100644 --- a/assets/config.json +++ b/assets/config.json @@ -239,6 +239,11 @@ {"path": "assets/hands/female_hand.png", "frame_width": 900, "frame_height": 600 + }, + "peasant_girl_rear_view": + {"path": "assets/sprites/peasant_girl_rear_view_01.png", + "frame_width": 400, + "frame_height": 543 } }, "worldgen": { @@ -267,6 +272,6 @@ "font_file_name": "assets/text.otf" }, "player": { - "hands": "male_hand" + "hands": "female_hand" } } diff --git a/assets/hands/male_hand.png b/assets/hands/male_hand.png index 76c5906..41b2ba3 100644 Binary files a/assets/hands/male_hand.png and b/assets/hands/male_hand.png differ diff --git a/boss/ui.cpp b/boss/ui.cpp new file mode 100644 index 0000000..588c8d7 --- /dev/null +++ b/boss/ui.cpp @@ -0,0 +1,27 @@ +#include "boss/ui.hpp" + +namespace boss { + UI::UI(shared_ptr world, Entity boss_id) { + (void)world; + (void)boss_id; + } + + void UI::init() { + + } + + void UI::render(sf::RenderWindow& window) { + (void)window; + } + + bool UI::mouse(float x, float y, guecs::Modifiers mods) { + (void)x; + (void)y; + (void)mods; + return false; + } + + bool UI::boss_dead() { + return true; + } +} diff --git a/boss/ui.hpp b/boss/ui.hpp new file mode 100644 index 0000000..86f2ac7 --- /dev/null +++ b/boss/ui.hpp @@ -0,0 +1,20 @@ +#pragma once +#include "dinkyecs.hpp" +#include +#include +#include + +namespace boss { + using std::shared_ptr; + using namespace DinkyECS; + + struct UI { + + UI(shared_ptr world, Entity boss_id); + + void init(); + void render(sf::RenderWindow& window); + bool mouse(float x, float y, guecs::Modifiers mods); + bool boss_dead(); + }; +} diff --git a/game_level.cpp b/game_level.cpp index 243a16f..aead2a5 100644 --- a/game_level.cpp +++ b/game_level.cpp @@ -5,6 +5,7 @@ #include "systems.hpp" #include "components.hpp" #include "rituals.hpp" +#include "textures.hpp" using lighting::LightRender; using std::shared_ptr, std::make_shared; @@ -47,7 +48,6 @@ namespace GameDB { }; } - size_t new_level(std::shared_ptr prev_world) { dbc::check(initialized, "Forgot to call GameDB::init()"); auto world = clone_load_world(prev_world); @@ -88,7 +88,7 @@ namespace GameDB { return current_level().world; } - shared_ptr create_bossfight() { + shared_ptr create_bossfight() { dbc::check(initialized, "Forgot to call GameDB::init()"); auto prev_world = current_world(); dbc::check(prev_world != nullptr, "Starter world for boss fights can't be null."); @@ -103,10 +103,9 @@ namespace GameDB { auto boss_id = world->entity(); components::configure_entity(*world, boss_id, boss_data["components"]); - return make_shared(world, boss_id); + return make_shared(world, boss_id); } - Level& create_level() { dbc::check(initialized, "Forgot to call GameDB::init()"); dbc::check(LDB->current_level < LDB->levels.size(), "attempt to get next level when at end"); diff --git a/game_level.hpp b/game_level.hpp index 3cc50e7..595846b 100644 --- a/game_level.hpp +++ b/game_level.hpp @@ -1,7 +1,7 @@ #pragma once #include "dinkyecs.hpp" -#include "gui/boss_fight_ui.hpp" +#include "boss/ui.hpp" #include "dinkyecs.hpp" #include "lights.hpp" #include "map.hpp" @@ -22,7 +22,7 @@ namespace GameDB { std::shared_ptr collision = nullptr; }; - std::shared_ptr create_bossfight(); + std::shared_ptr create_bossfight(); Level& create_level(); void init(); diff --git a/gui/boss_fight_ui.cpp b/gui/boss_fight_ui.cpp deleted file mode 100644 index c749651..0000000 --- a/gui/boss_fight_ui.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include "gui/boss_fight_ui.hpp" -#include "easings.hpp" -#include "sound.hpp" -#include - -namespace gui { - using namespace guecs; - - BossFightUI::BossFightUI(shared_ptr world, DinkyECS::Entity boss_id) - : $world(world), - $boss_id(boss_id), - $config(world->get_the()) - { - $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]"); - - $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]"); - - $sounds = $world->get($boss_id); - $combat = $world->get($boss_id); - } - - void BossFightUI::configure_sprite() { - $sprite_config = $world->get($boss_id); - $animation = $world->get($boss_id); - $animation.frame_width = $sprite_config.width; - - $boss_image = textures::get_sprite($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}); - - auto bounds = $boss_image.sprite->getLocalBounds(); - auto bg_bounds = $boss_background.sprite->getLocalBounds(); - float x_diff = bg_bounds.size.x / 2; - - $boss_pos = {float(BOSS_VIEW_X) + x_diff, bounds.size.y / 2}; - $boss_image.sprite->setOrigin({bounds.size.x / 2, bounds.size.y / 2}); - $boss_image.sprite->setPosition($boss_pos); - } - - void BossFightUI::configure_background() { - auto& boss = $world->get($boss_id); - - $boss_background = textures::get_sprite(boss.background); - $boss_background.sprite->setPosition({BOSS_VIEW_X, BOSS_VIEW_Y}); - $status.set($status.MAIN, {$status.$parser}); - - if(boss.stage) { - $boss_has_stage = true; - $boss_stage = textures::get_sprite(*boss.stage); - $boss_stage.sprite->setPosition({BOSS_VIEW_X, BOSS_VIEW_Y}); - } - } - - void BossFightUI::configure_gui() { - for(auto& [name, cell] : $status.cells()) { - auto button = $status.entity(name); - $status.set(button, {}); - $status.set(button, { - [this, name](auto){ - dbc::log(fmt::format("STATUS: {}", name)); - } - }); - if(name == "main_status") { - $status.set(button, {fmt::format(L"HP: {}", $combat.hp)}); - } else { - $status.set(button, {L"Attack"}); - } - } - $status.init(); - - for(auto& [name, cell] : $overlay.cells()) { - auto region = $overlay.entity(name); - $overlay.set(region, { - [this, name](auto){ - dbc::log(fmt::format("OVERLAY: {}", name)); - } - }); - } - - $overlay.init(); - } - - void BossFightUI::init() { - // background must come first - configure_background(); - configure_sprite(); - configure_gui(); - } - - void BossFightUI::bounce_boss(sf::RenderWindow& window) { - sf::IntRect frame_rect{{0,0},{$sprite_config.width,$sprite_config.height}}; - sf::Vector2f scale{$sprite_config.scale, $sprite_config.scale}; - sf::Vector2f pos{$boss_pos.x, $boss_pos.y}; - - $animation.step(scale, pos, frame_rect); - $boss_image.sprite->setScale(scale); - - if($animation.stationary) $boss_image.sprite->setPosition(pos); - - if(!sound::playing($sounds.attack) && $animation.current == 1) { - sound::play($sounds.attack); - } - - $boss_image.sprite->setTextureRect(frame_rect); - window.draw(*$boss_image.sprite); - } - - void BossFightUI::render(sf::RenderWindow& window) { - window.draw(*$boss_background.sprite); - - if($boss_hit) { - bounce_boss(window); - } else { - window.draw(*$boss_image.sprite); - } - - if($boss_has_stage) { - window.draw(*$boss_stage.sprite); - } - - if($combat.hp == 0) { - $overlay.show_text("overlay_1", L"YOU WON!"); - $overlay.show_text("overlay_4", L"CLICK TO CONTINUE..."); - } - - $status.render(window); - $overlay.render(window); - } - - bool BossFightUI::mouse(float x, float y, guecs::Modifiers mods) { - if($status.mouse(x, y, mods)) { - dbc::log("STATUS button pressed"); - } - - if($overlay.mouse(x, y, mods)) { - $animation.play(); - sound::play("Sword_Hit_1"); - $boss_hit = !$boss_hit; - $combat.hp--; - } - - return false; - } -} diff --git a/gui/boss_fight_ui.hpp b/gui/boss_fight_ui.hpp deleted file mode 100644 index 614f6de..0000000 --- a/gui/boss_fight_ui.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once -#include -#include -#include -#include "textures.hpp" -#include "components.hpp" -#include - -// aspect ratio of art is 3/2 so 1.5 -// possible sizes: 900/600; 1620/1080; 1800/1200 -// To calculate it do short side * 1.5 so 1080 * 1.5 == 1620 -// -// Side panel = 300/1080 - -namespace gui { - using std::string; - - class BossFightUI { - public: - sf::Clock $clock; - bool $boss_hit = false; - sf::Vector2f $boss_pos; - components::Combat $combat; - components::Sprite $sprite_config; - components::Sound $sounds; - components::Animation $animation; - guecs::UI $status; - guecs::UI $overlay; - textures::SpriteTexture $boss_image; - textures::SpriteTexture $boss_background; - bool $boss_has_stage = false; - textures::SpriteTexture $boss_stage; - std::shared_ptr $world = nullptr; - DinkyECS::Entity $boss_id; - components::GameConfig& $config; - - BossFightUI(std::shared_ptr world, DinkyECS::Entity boss_id); - - void init(); - void render(sf::RenderWindow& window); - bool mouse(float x, float y, guecs::Modifiers mods); - void bounce_boss(sf::RenderWindow& window); - bool boss_dead() { return $combat.hp < 0; } - void configure_sprite(); - void configure_background(); - void configure_gui(); - }; -} diff --git a/gui/fsm.hpp b/gui/fsm.hpp index 93efaa6..bba7002 100644 --- a/gui/fsm.hpp +++ b/gui/fsm.hpp @@ -7,7 +7,7 @@ #include "gui/combat_ui.hpp" #include "gui/status_ui.hpp" #include "gui/loot_ui.hpp" -#include "gui/boss_fight_ui.hpp" +#include "boss/ui.hpp" #include "gui/map_view.hpp" #include "events.hpp" #include "gui/event_router.hpp" @@ -36,7 +36,7 @@ namespace gui { int $temp_attack_id = 0; DebugUI $debug_ui; MainUI $main_ui; - std::shared_ptr $boss_fight_ui = nullptr; + std::shared_ptr $boss_fight_ui = nullptr; CombatUI $combat_ui; StatusUI $status_ui; MapViewUI $map_ui; diff --git a/meson.build b/meson.build index d4edac4..873a2dd 100644 --- a/meson.build +++ b/meson.build @@ -86,13 +86,13 @@ sources = [ 'autowalker.cpp', 'backend.cpp', 'battle.cpp', - 'palette.cpp', + 'boss/ui.cpp', 'combat.cpp', 'components.cpp', 'config.cpp', 'dbc.cpp', + 'game_level.cpp', 'goap.cpp', - 'gui/boss_fight_ui.cpp', 'gui/combat_ui.cpp', 'gui/debug_ui.cpp', 'gui/dnd_loot.cpp', @@ -111,6 +111,7 @@ sources = [ 'map.cpp', 'matrix.cpp', 'maze.cpp', + 'palette.cpp', 'pathing.cpp', 'rand.cpp', 'raycaster.cpp', @@ -123,7 +124,6 @@ sources = [ 'systems.cpp', 'textures.cpp', 'worldbuilder.cpp', - 'game_level.cpp', ] executable('runtests', sources + [ diff --git a/tests/map.cpp b/tests/map.cpp index ab1fa94..b3364b9 100644 --- a/tests/map.cpp +++ b/tests/map.cpp @@ -6,6 +6,7 @@ #include "game_level.hpp" #include "systems.hpp" #include +#include "textures.hpp" using namespace fmt; using namespace nlohmann; diff --git a/tests/matrix.cpp b/tests/matrix.cpp index ff6e9eb..fc19e53 100644 --- a/tests/matrix.cpp +++ b/tests/matrix.cpp @@ -9,6 +9,7 @@ #include #include "map.hpp" #include +#include "textures.hpp" using namespace nlohmann; using namespace fmt;