diff --git a/src/badguy/badguy.cpp b/src/badguy/badguy.cpp index a59fe916861..537e886e981 100644 --- a/src/badguy/badguy.cpp +++ b/src/badguy/badguy.cpp @@ -1085,7 +1085,7 @@ BadGuy::after_editor_set() } else { - std::string action_str = dir_to_string(m_dir); + std::string action_str = dir_to_string(m_start_dir); if (m_sprite->has_action("editor-" + action_str)) { set_action("editor-" + action_str); diff --git a/src/object/bumper.cpp b/src/object/bumper.cpp index b267cf646f6..0fd0caa3fd2 100644 --- a/src/object/bumper.cpp +++ b/src/object/bumper.cpp @@ -1,93 +1,103 @@ -// Copyright (C) 2020 Daniel Ward -// -// 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 . - -#include "object/bumper.hpp" - -#include "audio/sound_manager.hpp" -#include "object/player.hpp" -#include "sprite/sprite.hpp" -#include "sprite/sprite_manager.hpp" -#include "supertux/flip_level_transformer.hpp" -#include "supertux/sector.hpp" -#include "util/reader_mapping.hpp" - -namespace { -const std::string TRAMPOLINE_SOUND = "sounds/trampoline.wav"; -const float BOUNCE_Y = -450.0f; -const float BOUNCE_X = 700.0f; -} - -Bumper::Bumper(const ReaderMapping& reader) : - MovingSprite(reader, "images/objects/trampoline/bumper.sprite", LAYER_OBJECTS, COLGROUP_MOVING), - physic(), - left() -{ - reader.get("left", left); - set_action(left ? "left-normal" : "right-normal"); - physic.enable_gravity(false); -} - -ObjectSettings -Bumper::get_settings() -{ - ObjectSettings result = MovingSprite::get_settings(); - - result.add_bool(_("Facing Left"), &left, "left", false); - - result.reorder({"left", "sprite", "x", "y"}); - - return result; -} - -void -Bumper::update(float dt_sec) -{ - if (m_sprite->animation_done()) - { - set_action(left ? "left-normal" : "right-normal"); - } - m_col.set_movement(physic.get_movement (dt_sec)); -} - -HitResponse -Bumper::collision(GameObject& other, const CollisionHit& hit) -{ - auto player = dynamic_cast (&other); - if (player) - { - float BOUNCE_DIR = left ? -BOUNCE_X : BOUNCE_X; - player->get_physic().set_velocity(0.f, player->is_swimming() ? 0.f : BOUNCE_Y); - player->sideways_push(BOUNCE_DIR); - SoundManager::current()->play(TRAMPOLINE_SOUND, get_pos()); - set_action((left ? "left-swinging" : "right-swinging"), 1); - } - - auto bumper = dynamic_cast (&other); - if (bumper) - { - physic.set_velocity_y(0); - return FORCE_MOVE; - } - return ABORT_MOVE; -} - -void -Bumper::on_flip(float height) -{ - MovingSprite::on_flip(height); - FlipLevelTransformer::transform_flip(m_flip); -} - -/* EOF */ +// Copyright (C) 2020 Daniel Ward +// +// 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 . + +#include "object/bumper.hpp" + +#include "audio/sound_manager.hpp" +#include "object/player.hpp" +#include "sprite/sprite.hpp" +#include "sprite/sprite_manager.hpp" +#include "supertux/flip_level_transformer.hpp" +#include "supertux/sector.hpp" +#include "util/reader_mapping.hpp" + +namespace { +const std::string TRAMPOLINE_SOUND = "sounds/trampoline.wav"; +const float BOUNCE_Y = -450.0f; +const float BOUNCE_X = 700.0f; +} + +Bumper::Bumper(const ReaderMapping& reader) : + MovingSprite(reader, "images/objects/trampoline/bumper.sprite", LAYER_OBJECTS, COLGROUP_MOVING), + m_physic(), + m_facing_left() +{ + reader.get("left", m_facing_left); + set_action(m_facing_left ? "left-normal" : "right-normal"); + m_physic.enable_gravity(false); +} + +ObjectSettings +Bumper::get_settings() +{ + ObjectSettings result = MovingSprite::get_settings(); + + result.add_bool(_("Facing Left"), &m_facing_left, "left", false); + result.reorder({"left", "sprite", "x", "y"}); + return result; +} + +void +Bumper::update(float dt_sec) +{ + if (m_sprite->animation_done()) + { + set_action(m_facing_left ? "left-normal" : "right-normal"); + } + m_col.set_movement(m_physic.get_movement (dt_sec)); +} + +HitResponse +Bumper::collision(GameObject& other, const CollisionHit& hit) +{ + auto player = dynamic_cast (&other); + if (player) + { + float BOUNCE_DIR = m_facing_left ? -BOUNCE_X : BOUNCE_X; + player->get_physic().set_velocity(0.f, player->is_swimming() ? 0.f : BOUNCE_Y); + player->sideways_push(BOUNCE_DIR); + SoundManager::current()->play(TRAMPOLINE_SOUND, get_pos()); + set_action((m_facing_left ? "left-swinging" : "right-swinging"), 1); + } + auto bumper = dynamic_cast (&other); + if (bumper) + { + m_physic.set_velocity_y(0); + return FORCE_MOVE; + } + return ABORT_MOVE; +} + +Physic& +Bumper::get_physic() +{ + return m_physic; +} + +void +Bumper::after_editor_set() +{ + MovingSprite::after_editor_set(); + set_action(m_facing_left ? "left-normal" : "right-normal"); +} + +void +Bumper::on_flip(float height) +{ + MovingSprite::on_flip(height); + FlipLevelTransformer::transform_flip(m_flip); +} + +/* EOF */ diff --git a/src/object/bumper.hpp b/src/object/bumper.hpp index 0d755131f26..65258cffac7 100644 --- a/src/object/bumper.hpp +++ b/src/object/bumper.hpp @@ -1,53 +1,56 @@ -// Copyright (C) 2020 Daniel Ward -// -// 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_OBJECT_BUMPER_HPP -#define HEADER_SUPERTUX_OBJECT_BUMPER_HPP - -#include "object/moving_sprite.hpp" -#include "supertux/physic.hpp" - -class Player; - -class Bumper final : public MovingSprite -{ -public: - Bumper(const ReaderMapping& reader); - - virtual ObjectSettings get_settings() override; - - virtual void update(float dt_sec) override; - virtual HitResponse collision(GameObject& other, const CollisionHit& hit) override; - - static std::string class_name() { return "bumper"; } - virtual std::string get_class_name() const override { return class_name(); } - static std::string display_name() { return _("Bumper"); } - virtual std::string get_display_name() const override { return display_name(); } - - virtual void on_flip(float height) override; - - Physic physic; - -private: - bool left; - -private: - Bumper(const Bumper&) = delete; - Bumper& operator=(const Bumper&) = delete; -}; - -#endif - -/* EOF */ +// Copyright (C) 2020 Daniel Ward +// +// 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_OBJECT_BUMPER_HPP +#define HEADER_SUPERTUX_OBJECT_BUMPER_HPP + +#include "object/moving_sprite.hpp" + +#include "supertux/physic.hpp" + +class Player; + +class Bumper final : public MovingSprite +{ +public: + Bumper(const ReaderMapping& reader); + + virtual ObjectSettings get_settings() override; + + virtual void update(float dt_sec) override; + virtual HitResponse collision(GameObject& other, const CollisionHit& hit) override; + + static std::string class_name() { return "bumper"; } + virtual std::string get_class_name() const override { return class_name(); } + static std::string display_name() { return _("Bumper"); } + virtual std::string get_display_name() const override { return display_name(); } + + virtual void after_editor_set() override; + virtual void on_flip(float height) override; + + Physic& get_physic(); + +private: + Physic m_physic; + bool m_facing_left; + +private: + Bumper(const Bumper&) = delete; + Bumper& operator=(const Bumper&) = delete; +}; + +#endif + +/* EOF */ diff --git a/src/object/conveyor_belt.cpp b/src/object/conveyor_belt.cpp index 8bbf7a81b9e..97af510e8a3 100644 --- a/src/object/conveyor_belt.cpp +++ b/src/object/conveyor_belt.cpp @@ -128,6 +128,7 @@ ConveyorBelt::after_editor_set() if (m_length <= 0) m_length = 1; + set_action(dir_to_string(m_dir)); } void diff --git a/src/object/fallblock.cpp b/src/object/fallblock.cpp index a311e9c21de..4cf0c254012 100644 --- a/src/object/fallblock.cpp +++ b/src/object/fallblock.cpp @@ -1,174 +1,174 @@ -// Copyright (C) 2020 Daniel Ward -// -// 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 . - -#include "object/fallblock.hpp" - -#include "audio/sound_manager.hpp" -#include "object/bumper.hpp" -#include "object/player.hpp" -#include "object/camera.hpp" -#include "sprite/sprite.hpp" -#include "supertux/flip_level_transformer.hpp" -#include "supertux/sector.hpp" -#include "supertux/tile.hpp" -#include "math/random.hpp" -#include "util/reader_mapping.hpp" - -FallBlock::FallBlock(const ReaderMapping& reader) : - MovingSprite(reader, "images/objects/fallblock/cave-4x4.sprite", LAYER_OBJECTS, COLGROUP_STATIC), - state(IDLE), - physic(), - timer() -{ - SoundManager::current()->preload("sounds/cracking.wav"); - SoundManager::current()->preload("sounds/thud.ogg"); - physic.enable_gravity(false); -} - -void -FallBlock::update(float dt_sec) -{ - switch (state) - { - case IDLE: - set_group(COLGROUP_STATIC); - if (found_victim_down()) - { - state = SHAKE; - SoundManager::current()->play("sounds/cracking.wav", get_pos()); - timer.start(0.5f); - } - break; - case SHAKE: - if (timer.check()) - { - state = FALL; - physic.reset(); - physic.enable_gravity(true); - } - break; - case FALL: - m_col.set_movement(physic.get_movement (dt_sec)); - set_group(COLGROUP_MOVING_STATIC); - break; - case LAND: - m_col.set_movement(physic.get_movement (dt_sec)); - set_group(COLGROUP_MOVING_STATIC); - break; - } - for (auto& bumper : Sector::get().get_objects_by_type()) - { - Rectf bumper_bbox = bumper.get_bbox(); - if ((bumper_bbox.get_left() < (m_col.m_bbox.get_right() + 8)) - && (bumper_bbox.get_right() > (m_col.m_bbox.get_left() - 8)) - && (bumper_bbox.get_bottom() > (m_col.m_bbox.get_top() - 8)) - && (bumper_bbox.get_top() < (m_col.m_bbox.get_bottom() + 8))) - { - switch (state) - { - case IDLE: - break; - case SHAKE: - break; - case FALL: - bumper.physic.enable_gravity(true); - break; - case LAND: - bumper.physic.enable_gravity(false); - bumper.physic.set_gravity_modifier(0.f); - bumper.physic.set_velocity_y(0.f); - bumper.physic.reset(); - break; - } - } - } -} - -HitResponse -FallBlock::collision(GameObject& other, const CollisionHit& hit) -{ - auto fallblock = dynamic_cast (&other); - if (fallblock && hit.bottom && (state == FALL || state == LAND)) - { - physic.set_velocity_y(0.0f); - return CONTINUE; - } - - auto player = dynamic_cast(&other); - if (state == IDLE && player && player->get_bbox().get_bottom() < m_col.m_bbox.get_top()) - { - state = SHAKE; - SoundManager::current()->play("sounds/cracking.wav", get_pos()); - timer.start(0.5f); - } - return FORCE_MOVE; -} - -void -FallBlock::collision_solid(const CollisionHit& hit) -{ - if (hit.top || hit.bottom || hit.crush) - { - physic.set_velocity(0.0f, 0.0f); - } - - if (state == FALL && hit.bottom) - { - Sector::get().get_camera().shake(0.125f, 0.0f, 10.0f); - SoundManager::current()->play("sounds/thud.ogg", get_pos()); - state = LAND; - } -} - -void -FallBlock::draw(DrawingContext& context) -{ - Vector pos = get_pos(); - // shaking - if (state == SHAKE) - { - pos.x += static_cast(graphicsRandom.rand(-8, 8)); - pos.y += static_cast(graphicsRandom.rand(-5, 5)); - } - MovingSprite::draw(context); -} - -bool -FallBlock::found_victim_down() const -{ - if (auto* player = Sector::get().get_nearest_player(m_col.m_bbox)) - { - const Rectf& player_bbox = player->get_bbox(); - Rectf crush_area_down = Rectf(m_col.m_bbox.get_left()+1, m_col.m_bbox.get_bottom(), - m_col.m_bbox.get_right()-1, std::max(m_col.m_bbox.get_bottom(),player_bbox.get_top()-1)); - if ((player_bbox.get_top() >= m_col.m_bbox.get_bottom()) - && (player_bbox.get_right() > (m_col.m_bbox.get_left() - 4)) - && (player_bbox.get_left() < (m_col.m_bbox.get_right() + 4)) - && (Sector::get().is_free_of_statics(crush_area_down, this, false))) - { - return true; - } - } - return false; -} - -void -FallBlock::on_flip(float height) -{ - MovingSprite::on_flip(height); - FlipLevelTransformer::transform_flip(m_flip); -} - -/* EOF */ +// Copyright (C) 2020 Daniel Ward +// +// 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 . + +#include "object/fallblock.hpp" + +#include "audio/sound_manager.hpp" +#include "object/bumper.hpp" +#include "object/player.hpp" +#include "object/camera.hpp" +#include "sprite/sprite.hpp" +#include "supertux/flip_level_transformer.hpp" +#include "supertux/sector.hpp" +#include "supertux/tile.hpp" +#include "math/random.hpp" +#include "util/reader_mapping.hpp" + +FallBlock::FallBlock(const ReaderMapping& reader) : + MovingSprite(reader, "images/objects/fallblock/cave-4x4.sprite", LAYER_OBJECTS, COLGROUP_STATIC), + m_state(IDLE), + m_physic(), + m_timer() +{ + SoundManager::current()->preload("sounds/cracking.wav"); + SoundManager::current()->preload("sounds/thud.ogg"); + m_physic.enable_gravity(false); +} + +void +FallBlock::update(float dt_sec) +{ + switch (m_state) + { + case IDLE: + set_group(COLGROUP_STATIC); + if (found_victim_down()) + { + m_state = SHAKE; + SoundManager::current()->play("sounds/cracking.wav", get_pos()); + m_timer.start(0.5f); + } + break; + case SHAKE: + if (m_timer.check()) + { + m_state = FALL; + m_physic.reset(); + m_physic.enable_gravity(true); + } + break; + case FALL: + m_col.set_movement(m_physic.get_movement (dt_sec)); + set_group(COLGROUP_MOVING_STATIC); + break; + case LAND: + m_col.set_movement(m_physic.get_movement (dt_sec)); + set_group(COLGROUP_MOVING_STATIC); + break; + } + for (auto& bumper : Sector::get().get_objects_by_type()) + { + Rectf bumper_bbox = bumper.get_bbox(); + if ((bumper_bbox.get_left() < (m_col.m_bbox.get_right() + 8)) + && (bumper_bbox.get_right() > (m_col.m_bbox.get_left() - 8)) + && (bumper_bbox.get_bottom() > (m_col.m_bbox.get_top() - 8)) + && (bumper_bbox.get_top() < (m_col.m_bbox.get_bottom() + 8))) + { + switch (m_state) + { + case IDLE: + break; + case SHAKE: + break; + case FALL: + bumper.get_physic().enable_gravity(true); + break; + case LAND: + bumper.get_physic().enable_gravity(false); + bumper.get_physic().set_gravity_modifier(0.f); + bumper.get_physic().set_velocity_y(0.f); + bumper.get_physic().reset(); + break; + } + } + } +} + +HitResponse +FallBlock::collision(GameObject& other, const CollisionHit& hit) +{ + auto fallblock = dynamic_cast (&other); + if (fallblock && hit.bottom && (m_state == FALL || m_state == LAND)) + { + m_physic.set_velocity_y(0.0f); + return CONTINUE; + } + + auto player = dynamic_cast(&other); + if (m_state == IDLE && player && player->get_bbox().get_bottom() < m_col.m_bbox.get_top()) + { + m_state = SHAKE; + SoundManager::current()->play("sounds/cracking.wav", get_pos()); + m_timer.start(0.5f); + } + return FORCE_MOVE; +} + +void +FallBlock::collision_solid(const CollisionHit& hit) +{ + if (hit.top || hit.bottom || hit.crush) + { + m_physic.set_velocity(0.0f, 0.0f); + } + + if (m_state == FALL && hit.bottom) + { + Sector::get().get_camera().shake(0.125f, 0.0f, 10.0f); + SoundManager::current()->play("sounds/thud.ogg", get_pos()); + m_state = LAND; + } +} + +void +FallBlock::draw(DrawingContext& context) +{ + Vector pos = get_pos(); + // shaking + if (m_state == SHAKE) + { + pos.x += static_cast(graphicsRandom.rand(-8, 8)); + pos.y += static_cast(graphicsRandom.rand(-5, 5)); + } + MovingSprite::draw(context); +} + +bool +FallBlock::found_victim_down() const +{ + if (auto* player = Sector::get().get_nearest_player(m_col.m_bbox)) + { + const Rectf& player_bbox = player->get_bbox(); + Rectf crush_area_down = Rectf(m_col.m_bbox.get_left()+1, m_col.m_bbox.get_bottom(), + m_col.m_bbox.get_right()-1, std::max(m_col.m_bbox.get_bottom(),player_bbox.get_top()-1)); + if ((player_bbox.get_top() >= m_col.m_bbox.get_bottom()) + && (player_bbox.get_right() > (m_col.m_bbox.get_left() - 4)) + && (player_bbox.get_left() < (m_col.m_bbox.get_right() + 4)) + && (Sector::get().is_free_of_statics(crush_area_down, this, false))) + { + return true; + } + } + return false; +} + +void +FallBlock::on_flip(float height) +{ + MovingSprite::on_flip(height); + FlipLevelTransformer::transform_flip(m_flip); +} + +/* EOF */ diff --git a/src/object/fallblock.hpp b/src/object/fallblock.hpp index b84b4222921..ab3b6c4a03e 100644 --- a/src/object/fallblock.hpp +++ b/src/object/fallblock.hpp @@ -1,69 +1,70 @@ -// Copyright (C) 2020 Daniel Ward -// -// 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_OBJECT_FALLBLOCK_HPP -#define HEADER_SUPERTUX_OBJECT_FALLBLOCK_HPP - -#include "object/moving_sprite.hpp" -#include "supertux/physic.hpp" -#include "supertux/timer.hpp" - -class Player; - -class FallBlock : public MovingSprite - -{ -public: - FallBlock(const ReaderMapping& reader); - - virtual void update(float dt_sec) override; - - virtual HitResponse collision(GameObject& other, const CollisionHit& hit) override; - virtual void collision_solid(const CollisionHit& hit) override; - - virtual void draw(DrawingContext& context) override; - - static std::string class_name() { return "fallblock"; } - virtual std::string get_class_name() const override { return class_name(); } - static std::string display_name() { return _("Falling Platform"); } - virtual std::string get_display_name() const override { return display_name(); } - - virtual void on_flip(float height) override; - -protected: - enum State - { - IDLE, - SHAKE, - FALL, - LAND - }; - -private: - State state; - - Physic physic; - Timer timer; - - bool found_victim_down() const; - -private: - FallBlock(const FallBlock&) = delete; - FallBlock& operator=(const FallBlock&) = delete; -}; - -#endif - -/* EOF */ +// Copyright (C) 2020 Daniel Ward +// +// 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_OBJECT_FALLBLOCK_HPP +#define HEADER_SUPERTUX_OBJECT_FALLBLOCK_HPP + +#include "object/moving_sprite.hpp" + +#include "supertux/physic.hpp" +#include "supertux/timer.hpp" + +class Player; + +class FallBlock : public MovingSprite + +{ +public: + FallBlock(const ReaderMapping& reader); + + virtual void update(float dt_sec) override; + + virtual HitResponse collision(GameObject& other, const CollisionHit& hit) override; + virtual void collision_solid(const CollisionHit& hit) override; + + virtual void draw(DrawingContext& context) override; + + static std::string class_name() { return "fallblock"; } + virtual std::string get_class_name() const override { return class_name(); } + static std::string display_name() { return _("Falling Platform"); } + virtual std::string get_display_name() const override { return display_name(); } + + virtual void on_flip(float height) override; + +protected: + enum State + { + IDLE, + SHAKE, + FALL, + LAND + }; + +private: + State m_state; + + Physic m_physic; + Timer m_timer; + +private: + bool found_victim_down() const; + + FallBlock(const FallBlock&) = delete; + FallBlock& operator=(const FallBlock&) = delete; +}; + +#endif + +/* EOF */