diff --git a/data/images/creatures/crusher/corrupted/krosh_corrupt.sprite b/data/images/creatures/crusher/corrupted/krosh_corrupt.sprite index f1783a7fa25..de7c29d7375 100644 --- a/data/images/creatures/crusher/corrupted/krosh_corrupt.sprite +++ b/data/images/creatures/crusher/corrupted/krosh_corrupt.sprite @@ -18,18 +18,24 @@ ) ) (action - (name "whites") + (name "left-eye") (hitbox 16 16 128 128) - (images "krosh_corrupt_whites.png") + (images "krosh_corrupt_eyes.png") ) (action - (name "lefteye") + (name "right-eye") (hitbox 16 16 128 128) (images "krosh_corrupt_eyes.png") ) (action - (name "righteye") + (name "whites") (hitbox 16 16 128 128) - (images "krosh_corrupt_eyes.png") + (images "krosh_corrupt_whites.png") + ) + + (linked-sprites + (left-eye "krosh_corrupt.sprite" "left-eye") + (right-eye "krosh_corrupt.sprite" "right-eye") + (whites "krosh_corrupt.sprite" "whites") ) ) diff --git a/data/images/creatures/crusher/corrupted/krush_corrupt.sprite b/data/images/creatures/crusher/corrupted/krush_corrupt.sprite index 7cd9c5a713e..ab1e729af85 100644 --- a/data/images/creatures/crusher/corrupted/krush_corrupt.sprite +++ b/data/images/creatures/crusher/corrupted/krush_corrupt.sprite @@ -18,18 +18,24 @@ ) ) (action - (name "whites") + (name "left-eye") (hitbox 8 8 64 64) - (images "krush_corrupt_whites.png") + (images "krush_corrupt_eyes.png") ) (action - (name "lefteye") + (name "right-eye") (hitbox 8 8 64 64) (images "krush_corrupt_eyes.png") ) (action - (name "righteye") + (name "whites") (hitbox 8 8 64 64) - (images "krush_corrupt_eyes.png") + (images "krush_corrupt_whites.png") + ) + + (linked-sprites + (left-eye "krush_corrupt.sprite" "left-eye") + (right-eye "krush_corrupt.sprite" "right-eye") + (whites "krush_corrupt.sprite" "whites") ) ) diff --git a/data/images/creatures/crusher/krosh_ice.sprite b/data/images/creatures/crusher/krosh_ice.sprite index e013731a958..32454d42468 100644 --- a/data/images/creatures/crusher/krosh_ice.sprite +++ b/data/images/creatures/crusher/krosh_ice.sprite @@ -18,18 +18,24 @@ ) ) (action - (name "whites") + (name "left-eye") (hitbox 4 4 128 128) - (images "krosh_ice_whites.png") + (images "krosh_ice_lefteye.png") ) (action - (name "lefteye") + (name "right-eye") (hitbox 4 4 128 128) - (images "krosh_ice_lefteye.png") + (images "krosh_ice_righteye.png") ) (action - (name "righteye") + (name "whites") (hitbox 4 4 128 128) - (images "krosh_ice_righteye.png") + (images "krosh_ice_whites.png") + ) + + (linked-sprites + (left-eye "krosh_ice.sprite" "left-eye") + (right-eye "krosh_ice.sprite" "right-eye") + (whites "krosh_ice.sprite" "whites") ) ) diff --git a/data/images/creatures/crusher/krosh_rock.sprite b/data/images/creatures/crusher/krosh_rock.sprite index e973843b109..ca847cc5248 100644 --- a/data/images/creatures/crusher/krosh_rock.sprite +++ b/data/images/creatures/crusher/krosh_rock.sprite @@ -18,18 +18,24 @@ ) ) (action - (name "whites") + (name "left-eye") (hitbox 4 4 128 128) - (images "krosh_rock_whites.png") + (images "krosh_rock_lefteye.png") ) (action - (name "lefteye") + (name "right-eye") (hitbox 4 4 128 128) - (images "krosh_rock_lefteye.png") + (images "krosh_rock_righteye.png") ) (action - (name "righteye") + (name "whites") (hitbox 4 4 128 128) - (images "krosh_rock_righteye.png") + (images "krosh_rock_whites.png") + ) + + (linked-sprites + (left-eye "krosh_rock.sprite" "left-eye") + (right-eye "krosh_rock.sprite" "right-eye") + (whites "krosh_rock.sprite" "whites") ) ) diff --git a/data/images/creatures/crusher/krush_ice.sprite b/data/images/creatures/crusher/krush_ice.sprite index 622eaacbd76..f35d6a4798a 100644 --- a/data/images/creatures/crusher/krush_ice.sprite +++ b/data/images/creatures/crusher/krush_ice.sprite @@ -18,18 +18,24 @@ ) ) (action - (name "whites") + (name "left-eye") (hitbox 3 3 64 64) - (images "krush_ice_whites.png") + (images "krush_ice_lefteye.png") ) (action - (name "lefteye") + (name "right-eye") (hitbox 3 3 64 64) - (images "krush_ice_lefteye.png") + (images "krush_ice_righteye.png") ) (action - (name "righteye") + (name "whites") (hitbox 3 3 64 64) - (images "krush_ice_righteye.png") + (images "krush_ice_whites.png") + ) + + (linked-sprites + (left-eye "krush_ice.sprite" "left-eye") + (right-eye "krush_ice.sprite" "right-eye") + (whites "krush_ice.sprite" "whites") ) ) diff --git a/data/images/creatures/crusher/krush_rock.sprite b/data/images/creatures/crusher/krush_rock.sprite index b38e4809690..b521f255984 100644 --- a/data/images/creatures/crusher/krush_rock.sprite +++ b/data/images/creatures/crusher/krush_rock.sprite @@ -20,18 +20,24 @@ ) ) (action - (name "whites") + (name "left-eye") (hitbox 3 3 64 64) - (images "krush_rock_whites.png") + (images "krush_rock_lefteye.png") ) (action - (name "lefteye") + (name "right-eye") (hitbox 3 3 64 64) - (images "krush_rock_lefteye.png") + (images "krush_rock_righteye.png") ) (action - (name "righteye") + (name "whites") (hitbox 3 3 64 64) - (images "krush_rock_righteye.png") + (images "krush_rock_whites.png") + ) + + (linked-sprites + (left-eye "krush_rock.sprite" "left-eye") + (right-eye "krush_rock.sprite" "right-eye") + (whites "krush_rock.sprite" "whites") ) ) diff --git a/data/images/objects/bonus_block/brick.sprite b/data/images/objects/bonus_block/brick.sprite index 0d8989344e6..217c2e0c612 100644 --- a/data/images/objects/bonus_block/brick.sprite +++ b/data/images/objects/bonus_block/brick.sprite @@ -39,4 +39,8 @@ (name "piece6") (fps 1) (images "../../tiles/blocks/brick_piece6.png")) - ) + + (linked-sprites + (break-particles "brick.sprite") + ) +) diff --git a/data/images/objects/bonus_block/brickIce.sprite b/data/images/objects/bonus_block/brickIce.sprite index 22a1e8ba6e5..a4afad6c1fc 100644 --- a/data/images/objects/bonus_block/brickIce.sprite +++ b/data/images/objects/bonus_block/brickIce.sprite @@ -10,33 +10,7 @@ (name "normal") (images "../../tiles/blocks/brick1.png")) - (action - (name "piece1") - (fps 1) - (images "../../tiles/blocks/brick_piece1.png")) - - (action - (name "piece2") - (fps 1) - (images "../../tiles/blocks/brick_piece2.png")) - - (action - (name "piece3") - (fps 1) - (images "../../tiles/blocks/brick_piece3.png")) - - (action - (name "piece4") - (fps 1) - (images "../../tiles/blocks/brick_piece4.png")) - - (action - (name "piece5") - (fps 1) - (images "../../tiles/blocks/brick_piece5.png")) - - (action - (name "piece6") - (fps 1) - (images "../../tiles/blocks/brick_piece6.png")) + (linked-sprites + (break-particles "brick.sprite") + ) ) diff --git a/data/images/objects/bonus_block/brickWeb.sprite b/data/images/objects/bonus_block/brickWeb.sprite index a01557a9049..4e44441e466 100644 --- a/data/images/objects/bonus_block/brickWeb.sprite +++ b/data/images/objects/bonus_block/brickWeb.sprite @@ -10,33 +10,7 @@ (name "normal") (images "../../tiles/blocks/brick2.png")) - (action - (name "piece1") - (fps 1) - (images "../../tiles/blocks/brick_piece1.png")) - - (action - (name "piece2") - (fps 1) - (images "../../tiles/blocks/brick_piece2.png")) - - (action - (name "piece3") - (fps 1) - (images "../../tiles/blocks/brick_piece3.png")) - - (action - (name "piece4") - (fps 1) - (images "../../tiles/blocks/brick_piece4.png")) - - (action - (name "piece5") - (fps 1) - (images "../../tiles/blocks/brick_piece5.png")) - - (action - (name "piece6") - (fps 1) - (images "../../tiles/blocks/brick_piece6.png")) + (linked-sprites + (break-particles "brick.sprite") + ) ) diff --git a/data/images/objects/bonus_block/heavy-brick.sprite b/data/images/objects/bonus_block/heavy-brick.sprite index 72a8834747b..56ceb2ce3e1 100644 --- a/data/images/objects/bonus_block/heavy-brick.sprite +++ b/data/images/objects/bonus_block/heavy-brick.sprite @@ -39,4 +39,8 @@ (name "piece6") (fps 1) (images "../../tiles/blocks/brick_piece12.png")) + + (linked-sprites + (break-particles "heavy-brick.sprite") + ) ) diff --git a/src/badguy/crusher.cpp b/src/badguy/crusher.cpp index c6eb6d8f92d..993d6538e91 100644 --- a/src/badguy/crusher.cpp +++ b/src/badguy/crusher.cpp @@ -65,7 +65,16 @@ Crusher::Crusher(const ReaderMapping& reader) : // TODO: Add distinct sounds for crusher hitting the ground and hitting Tux. SoundManager::current()->preload(not_ice() ? "sounds/thud.ogg" : "sounds/brick.wav"); set_state(m_state, true); - after_sprite_set(); +} + +MovingSprite::LinkedSprites +Crusher::get_linked_sprites() +{ + return { + { "left-eye", m_lefteye }, + { "right-eye", m_righteye }, + { "whites", m_whites } + }; } GameObjectTypes @@ -119,6 +128,13 @@ Crusher::on_type_change(int old_type) MovingSprite::on_type_change(old_type); } +void +Crusher::on_sprite_update() +{ + MovingSprite::on_sprite_update(); + set_state(m_state, true); +} + HitResponse Crusher::collision(GameObject& other, const CollisionHit& hit) { @@ -472,26 +488,17 @@ Crusher::draw(DrawingContext& context) const Vector draw_pos = get_pos() + draw_offset; m_sprite->draw(context.color(), draw_pos, m_layer + 2, m_flip); - if (m_sprite->has_action("whites")) - { - // Draw crusher's eyes slightly behind. - m_lefteye->draw(context.color(), draw_pos + eye_position(false), m_layer + 1, m_flip); - m_righteye->draw(context.color(), draw_pos + eye_position(true), m_layer + 1, m_flip); - // Draw the whites of crusher's eyes even further behind. - m_whites->draw(context.color(), draw_pos, m_layer, m_flip); - } + + // Draw crusher's eyes slightly behind. + m_lefteye->draw(context.color(), draw_pos + eye_position(false), m_layer + 1, m_flip); + m_righteye->draw(context.color(), draw_pos + eye_position(true), m_layer + 1, m_flip); + // Draw the whites of crusher's eyes even further behind. + m_whites->draw(context.color(), draw_pos, m_layer, m_flip); if (m_light_sprite) m_light_sprite->draw(context.light(), m_col.m_bbox.get_middle() + draw_offset, m_layer + 3); } -void -Crusher::after_editor_set() -{ - MovingSprite::after_editor_set(); - after_sprite_set(); -} - ObjectSettings Crusher::get_settings() { @@ -585,26 +592,6 @@ Crusher::set_state(CrusherState state_, bool force) m_state = state_; } -void -Crusher::after_sprite_set() -{ - if (!m_sprite->has_action("whites")) - { - m_lefteye.reset(); - m_righteye.reset(); - m_whites.reset(); - } - else - { - m_lefteye = m_sprite->clone(); - m_lefteye->set_action("lefteye"); - m_righteye = m_sprite->clone(); - m_righteye->set_action("righteye"); - m_whites = m_sprite->clone(); - m_whites->set_action("whites"); - } -} - Vector Crusher::eye_position(bool right) const { diff --git a/src/badguy/crusher.hpp b/src/badguy/crusher.hpp index a0dd52a3c91..4911fc6ca04 100644 --- a/src/badguy/crusher.hpp +++ b/src/badguy/crusher.hpp @@ -63,9 +63,6 @@ class Crusher final : public MovingSprite virtual void update(float dt_sec) override; virtual void draw(DrawingContext& context) override; - virtual void after_editor_set() override; - virtual bool is_sideways() const { return m_sideways; } - static std::string class_name() { return "crusher"; } virtual std::string get_class_name() const override { return class_name(); } static std::string display_name() { return _("Crusher"); } @@ -78,17 +75,23 @@ class Crusher final : public MovingSprite virtual void on_flip(float height) override; + virtual bool is_sideways() const { return m_sideways; } + Physic& get_physic() { return m_physic; } bool is_big() const { return m_ic_size == LARGE; } CrusherState get_state() const { return m_state; } +protected: + LinkedSprites get_linked_sprites() override; + + void on_sprite_update() override; + private: void spawn_roots(Direction direction); bool found_victim() const; bool not_ice() const; void set_state(CrusherState state, bool force = false); - void after_sprite_set(); Vector eye_position(bool right) const; void on_type_change(int old_type) override; diff --git a/src/object/block.cpp b/src/object/block.cpp index a51e65f4906..39ca94c7078 100644 --- a/src/object/block.cpp +++ b/src/object/block.cpp @@ -186,14 +186,17 @@ Block::break_me() const auto gravity = Sector::get().get_gravity() * 100; Vector pos = get_pos() + Vector(16.0f, 16.0f); - for (const char* action : {"piece1", "piece2", "piece3", "piece4", "piece5", "piece6"}) + if (m_sprite->has_linked_sprite("break-particles")) { - Vector velocity(graphicsRandom.randf(-100, 100), - graphicsRandom.randf(-400, -300)); - Sector::get().add(m_sprite->clone(), action, - pos, ANCHOR_MIDDLE, - velocity, Vector(0, gravity), - m_layer); + for (const char* action : {"piece1", "piece2", "piece3", "piece4", "piece5", "piece6"}) + { + Vector velocity(graphicsRandom.randf(-100, 100), + graphicsRandom.randf(-400, -300)); + Sector::get().add(m_sprite->create_linked_sprite("break-particles"), action, + pos, ANCHOR_MIDDLE, + velocity, Vector(0, gravity), + m_layer); + } } remove_me(); diff --git a/src/sprite/sprite.cpp b/src/sprite/sprite.cpp index 25e456855be..06876da976a 100644 --- a/src/sprite/sprite.cpp +++ b/src/sprite/sprite.cpp @@ -237,6 +237,13 @@ Sprite::create_linked_light_sprite() const return sprite; } +bool +Sprite::has_linked_sprite(const std::string& key) const +{ + return m_action->linked_sprites.find(key) != m_action->linked_sprites.end() || + m_data.linked_sprites.find(key) != m_data.linked_sprites.end(); +} + const SpriteData::LinkedSprite& Sprite::get_linked_sprite(const std::string& key) const { diff --git a/src/sprite/sprite.hpp b/src/sprite/sprite.hpp index 3bff5637dce..8885089d01c 100644 --- a/src/sprite/sprite.hpp +++ b/src/sprite/sprite.hpp @@ -93,6 +93,7 @@ class Sprite final SpritePtr create_linked_light_sprite() const; /** Get linked sprite by key */ + bool has_linked_sprite(const std::string& key) const; const SpriteData::LinkedSprite& get_linked_sprite(const std::string& key) const; SpritePtr create_linked_sprite(const std::string& key) const; diff --git a/src/supertux/menu/async_dialog.hpp b/src/supertux/menu/async_dialog.hpp deleted file mode 100644 index 202eaa8f534..00000000000 --- a/src/supertux/menu/async_dialog.hpp +++ /dev/null @@ -1,76 +0,0 @@ -// SuperTux -// Copyright (C) 2024 Vankata453 -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#ifndef HEADER_SUPERTUX_SUPERTUX_MENU_ASYNC_DIALOG_HPP -#define HEADER_SUPERTUX_SUPERTUX_MENU_ASYNC_DIALOG_HPP - -#include "gui/dialog.hpp" - -#include -#include - -#include "gui/menu_manager.hpp" - -template -class AsyncDialog final : public Dialog -{ -public: - AsyncDialog(const std::string& text, std::future future, std::function callback); - - void update() override; - -private: - std::future m_future; - const std::function m_callback; - -private: - AsyncDialog(const AsyncDialog&) = delete; - AsyncDialog& operator=(const AsyncDialog&) = delete; -}; - - -/** SOURCE */ - -template -inline std::unique_ptr> make_async_dialog(Args&&... args) -{ - return std::make_unique>(std::forward(args)...); -} - -template -AsyncDialog::AsyncDialog(const std::string& text, std::future future, std::function callback) : - m_future(std::move(future)), - m_callback(std::move(callback)) -{ - set_text(text); -} - -template -void -AsyncDialog::update() -{ - using namespace std::chrono_literals; - - if (m_future.wait_for(0ms) != std::future_status::ready) - return; - - m_callback(std::move(m_future.get())); - MenuManager::instance().set_dialog({}); -} - -#endif - -/* EOF */