diff --git a/assets/animation.json b/assets/animation.json index 3ce25a6..6af1f22 100644 --- a/assets/animation.json +++ b/assets/animation.json @@ -97,6 +97,39 @@ "open": [], "close": [] } + }, + "ag_bot": { + "sheet": { + "frames": 1, + "frame_width": 846, + "frame_height": 1022 + }, + "sequences": { + "idle": {"frames": [0], "durations": [50] } + }, + "transforms": { + "basic": { + "min_x": 1.0, + "min_y": 1.0, + "max_x": 1.0, + "max_y": 1.0, + "flipped": false, + "scaled": true, + "toggled": false, + "looped": false, + "relative": false, + "easing": "none", + "motion": "move_none" + } + }, + "forms": { + "idle": ["idle", "basic"] + }, + "sounds": { + "idle": [], + "open": [], + "close": [] + } }, "hands_sword_attack": { "sheet": { diff --git a/assets/config.json b/assets/config.json index 4fff41e..c8c51a5 100644 --- a/assets/config.json +++ b/assets/config.json @@ -12,6 +12,16 @@ "frame_width": 256, "frame_height": 256 }, + "ag_bot": + {"path": "assets/sprites/ag_bot.png", + "frame_width": 846, + "frame_height": 1022 + }, + "ag_bot_speech": + {"path": "assets/sprites/ag_bot_speech.png", + "frame_width": 424, + "frame_height": 358 + }, "repair_kit": {"path": "assets/items/repair_kit.png", "frame_width": 256, diff --git a/assets/scenes.json b/assets/scenes.json index 3d7d4c4..2f052c8 100644 --- a/assets/scenes.json +++ b/assets/scenes.json @@ -21,12 +21,36 @@ }, "STARTING": { "layout": [ - "[=text]" + "[_|*%(200, 200)ag_bot|_|*%(200,100)speech|_|_]", + "[_|_|_ |*%(200,100)buttons|_|_]" ], "background": "starting_scene", "actors": [ + { + "name": "ag_bot", + "sprite": "ag_bot", + "cell": "ag_bot", + "scale_x": 0.65, + "scale_y": 0.65, + "x": -40, + "y": 70, + "at_mid": false, + "flipped": false + } ], "fixtures": [ + { + "name": "ag_bot_speech", + "sprite": "ag_bot_speech", + "scale_x": 1.0, + "scale_y": 1.0, + "flipped": false, + "cell": "speech", + "x": 0, + "y": 0, + "at_mid": false, + "flipped": false + } ] }, "WIN": { diff --git a/assets/scenes/starting_scene.png b/assets/scenes/starting_scene.png index 661a945..028dda4 100644 Binary files a/assets/scenes/starting_scene.png and b/assets/scenes/starting_scene.png differ diff --git a/assets/sprites/ag_bot.png b/assets/sprites/ag_bot.png new file mode 100644 index 0000000..14e84ab Binary files /dev/null and b/assets/sprites/ag_bot.png differ diff --git a/assets/sprites/ag_bot_speech.png b/assets/sprites/ag_bot_speech.png new file mode 100644 index 0000000..1fe75f4 Binary files /dev/null and b/assets/sprites/ag_bot_speech.png differ diff --git a/assets/sprites/rat_with_sword.png b/assets/sprites/rat_with_sword.png deleted file mode 100644 index 0d5763b..0000000 Binary files a/assets/sprites/rat_with_sword.png and /dev/null differ diff --git a/src/game/worldbuilder.cpp b/src/game/worldbuilder.cpp index 777029e..5132226 100644 --- a/src/game/worldbuilder.cpp +++ b/src/game/worldbuilder.cpp @@ -196,11 +196,8 @@ void WorldBuilder::place_stairs(DinkyECS::World& world, GameConfig& config) { auto& device_config = config.devices.json(); auto entity_data = device_config["STAIRS_DOWN"]; - // auto at_end = $map.$dead_ends.back(); - configure_entity_in_map(world, entity_data, { - player_pos.location.x+1, - player_pos.location.y - }); + auto at_end = $map.$dead_ends.back(); + configure_entity_in_map(world, entity_data, at_end); } void WorldBuilder::configure_starting_items(DinkyECS::World &world) { diff --git a/src/graphics/animation.cpp b/src/graphics/animation.cpp index 95e5c10..d5ad181 100644 --- a/src/graphics/animation.cpp +++ b/src/graphics/animation.cpp @@ -249,13 +249,12 @@ namespace animation { sequence.INVARIANT(); } - Animation load(const std::string &file, const std::string &anim_name) { + std::optional maybe_load(const std::string &file, const std::string &anim_name) { using nlohmann::json; std::ifstream infile(file); auto data = json::parse(infile); - dbc::check(data.contains(anim_name), - $F("{} animation config does not have animation {}", file, anim_name)); + if(!data.contains(anim_name)) return std::nullopt; Animation anim; animation::from_json(data[anim_name], anim); @@ -269,6 +268,15 @@ namespace animation { return anim; } + Animation load(const std::string &file, const std::string &anim_name) { + auto anim = maybe_load(file, anim_name); + + dbc::check(anim != std::nullopt, + $F("FAILED to load animation {} from file {}", anim_name, file)); + + return *anim; + } + void Sequence::INVARIANT(const std::source_location location) { dbc::check(frames.size() == durations.size(), $F("frames.size={} doesn't match durations.size={}", @@ -297,8 +305,12 @@ namespace animation { void configure(DinkyECS::World& world, DinkyECS::Entity entity) { auto sprite = world.get_if(entity); - if(sprite != nullptr && has(sprite->name)) { - world.set(entity, animation::load("assets/animation.json", sprite->name)); + // sprite doesn't exist, abort + if(sprite == nullptr) return; + + // lazy load any animations + if(auto anim = animation::maybe_load("assets/animation.json", sprite->name)) { + world.set(entity, *anim); } } diff --git a/src/graphics/animation.hpp b/src/graphics/animation.hpp index d188eb0..faf8170 100644 --- a/src/graphics/animation.hpp +++ b/src/graphics/animation.hpp @@ -134,6 +134,7 @@ namespace animation { }; Animation load(const std::string &file, const std::string &anim_name); + std::optional maybe_load(const std::string &file, const std::string &anim_name); // BUG: brought over from animation to finish the refactor, but these may not be needed or maybe they go in system.cpp? bool has(const std::string& name); diff --git a/src/graphics/scene.cpp b/src/graphics/scene.cpp index 5c7ba6a..c237d27 100644 --- a/src/graphics/scene.cpp +++ b/src/graphics/scene.cpp @@ -18,10 +18,13 @@ namespace scene { bool flipped = config["flipped"]; // BUG: put the .json file to load as a default/optional arg - auto anim = animation::load("./assets/animation.json", sprite_name); - anim.play(); + auto anim = animation::maybe_load("./assets/animation.json", sprite_name); - anim.transform.flipped = flipped; + if(anim) { + // only start it if there's an animation set + anim->play(); + anim->transform.flipped = flipped; + } std::string cell = config["cell"]; std::string name = config["name"]; @@ -103,7 +106,7 @@ namespace scene { for(auto& actor : $actors) { view.draw(*actor.st.sprite, actor.effect.get()); - if(actor.anim.playing) view.draw(actor.text); + if(actor.anim && actor.anim->playing) view.draw(actor.text); } $camera.render(view); @@ -126,20 +129,25 @@ namespace scene { void Engine::animate_actor(const std::string& actor, const std::string& form) { auto& config = actor_config(actor); - config.anim.set_form(form); - if(!config.anim.playing) { - config.anim.play(); + // no animation set, abort + if(!config.anim) return; + + config.anim->set_form(form); + + if(!config.anim->playing) { + config.anim->play(); } } inline void this_is_stupid_refactor(std::vector& elements) { for(auto& element : elements) { - if(element.anim.playing) { - element.anim.update(); - element.anim.motion(*element.st.sprite, element.pos, element.scale); - element.anim.apply(*element.st.sprite); - if(element.effect != nullptr) element.anim.apply_effect(element.effect); + // skip any without animation + if(element.anim && element.anim->playing) { + element.anim->update(); + element.anim->motion(*element.st.sprite, element.pos, element.scale); + element.anim->apply(*element.st.sprite); + if(element.effect != nullptr) element.anim->apply_effect(element.effect); } } } @@ -178,8 +186,12 @@ namespace scene { } void Engine::set_end_cb(std::function cb) { + for(auto& actor : $actors) { - actor.anim.onLoop = [&,cb](auto& seq, auto& tr) -> bool { + // no animation set so no point doing a end cb + if(!actor.anim) continue; + + actor.anim->onLoop = [&,cb](auto& seq, auto& tr) -> bool { seq.current = tr.toggled ? seq.frame_count - 1 : 0; cb(); actor.effect = nullptr; diff --git a/src/graphics/scene.hpp b/src/graphics/scene.hpp index 1f9449f..e0b0b9c 100644 --- a/src/graphics/scene.hpp +++ b/src/graphics/scene.hpp @@ -17,7 +17,7 @@ namespace scene { struct Element { std::string name; textures::SpriteTexture st; - animation::Animation anim; + std::optional anim; std::string cell; sf::Vector2f scale{1.0f, 1.0f}; sf::Vector2f pos{0.0f, 0.0f}; diff --git a/tests/pathing.cpp b/tests/pathing.cpp index 1265dc1..53e574b 100644 --- a/tests/pathing.cpp +++ b/tests/pathing.cpp @@ -47,7 +47,5 @@ TEST_CASE("multiple targets can path", "[pathing]") { if(found == PathingResult::FOUND) { fmt::println("FOUND!"); - } else if(found == PathingResult::FAIL && !diag) { - REQUIRE(found != PathingResult::FAIL); } }