123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777 |
- // SuperTux
- // Copyright (C) 2009 Ingo Ruhnke <grumbel@gmail.com>
- //
- // 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 <http://www.gnu.org/licenses/>.
- #include "object/bonus_block.hpp"
- #include <memory>
- #include "audio/sound_manager.hpp"
- #include "badguy/badguy.hpp"
- #include "badguy/crusher.hpp"
- #include "editor/editor.hpp"
- #include "math/vector.hpp"
- #include "object/bouncy_coin.hpp"
- #include "object/coin_explode.hpp"
- #include "object/coin_rain.hpp"
- #include "object/flower.hpp"
- #include "object/growup.hpp"
- #include "object/oneup.hpp"
- #include "object/player.hpp"
- #include "object/portable.hpp"
- #include "object/powerup.hpp"
- #include "object/rock.hpp"
- #include "object/specialriser.hpp"
- #include "object/star.hpp"
- #include "object/trampoline.hpp"
- #include "supertux/constants.hpp"
- #include "supertux/game_object_factory.hpp"
- #include "supertux/level.hpp"
- #include "supertux/sector.hpp"
- #include "util/reader_collection.hpp"
- #include "util/reader_mapping.hpp"
- #include "util/writer.hpp"
- #include "video/drawing_context.hpp"
- #include "video/surface.hpp"
- namespace {
- std::unique_ptr<MovingObject> to_moving_object(std::unique_ptr<GameObject> object)
- {
- if (dynamic_cast<MovingObject*>(object.get()) != nullptr) {
- return std::unique_ptr<MovingObject>(static_cast<MovingObject*>(object.release()));
- } else {
- return std::unique_ptr<MovingObject>();
- }
- }
- const float UPGRADE_SOUND_GAIN = 0.3f;
- } // namespace
- BonusBlock::BonusBlock(const Vector& pos, int tile_data) :
- Block(pos, "images/objects/bonus_block/bonusblock.sprite"),
- m_contents(),
- m_objects(),
- m_object(),
- m_hit_counter(1),
- m_script(),
- m_lightsprite(),
- m_coin_sprite(get_default_coin_sprite())
- {
- set_action("normal");
- m_contents = get_content_by_data(tile_data);
- preload_contents(tile_data);
- }
- BonusBlock::BonusBlock(const ReaderMapping& mapping) :
- Block(mapping, "images/objects/bonus_block/bonusblock.sprite"),
- m_contents(Content::COIN),
- m_objects(),
- m_object(),
- m_hit_counter(1),
- m_script(),
- m_lightsprite(),
- m_coin_sprite(get_default_coin_sprite())
- {
- parse_type(mapping);
- mapping.get("count", m_hit_counter);
- mapping.get("script", m_script);
- mapping.get("coin-sprite", m_coin_sprite);
- int data = 0;
- if (mapping.get("data", data))
- {
- m_contents = get_content_by_data(data);
- preload_contents(data);
- }
- std::string content;
- if (mapping.get("contents", content))
- {
- m_contents = get_content_from_string(content);
- if (m_contents == Content::CUSTOM)
- {
- std::optional<ReaderCollection> content_collection;
- if (mapping.get("custom-contents", content_collection))
- {
- const auto& object_specs = content_collection->get_objects();
- if (!object_specs.empty())
- {
- if (object_specs.size() > 1)
- log_warning << "Only one custom object allowed inside bonus blocks, ignoring the rest." << std::endl;
- const auto& spec = object_specs.at(0);
- auto game_object = GameObjectFactory::instance().create(spec.get_name(), spec.get_mapping());
- if (dynamic_cast<MovingObject*>(game_object.get()))
- set_object(std::move(game_object));
- else
- log_warning << "Only `MovingObject`s are allowed inside bonus blocks." << std::endl;
- }
- else
- {
- log_warning << "Custom object not set." << std::endl;
- }
- }
- else
- {
- log_warning << "Custom object not set." << std::endl;
- }
- }
- }
- if (!Editor::is_active() && m_contents == Content::CUSTOM && !m_object)
- throw std::runtime_error("Need to specify content object for custom block");
- if (m_contents == Content::LIGHT || m_contents == Content::LIGHT_ON)
- {
- SoundManager::current()->preload("sounds/switch.ogg");
- m_lightsprite = Surface::from_file("/images/objects/lightmap_light/bonusblock_light.png");
- if (m_contents == Content::LIGHT_ON)
- set_action("on");
- else
- set_action("off");
- }
- }
- void
- BonusBlock::add_object(std::unique_ptr<GameObject> object)
- {
- if (!m_objects.empty())
- throw std::runtime_error(_("Only one custom object is allowed inside bonus blocks."));
- set_object(std::move(object));
- }
- void
- BonusBlock::set_object(std::unique_ptr<GameObject> object)
- {
- m_object = object.get();
- m_objects.clear();
- m_objects.push_back(std::move(object));
- }
- GameObjectTypes
- BonusBlock::get_types() const
- {
- return {
- { "blue", _("Blue") },
- { "orange", _("Orange") },
- { "purple", _("Purple") },
- { "retro", _("Retro") }
- };
- }
- std::string
- BonusBlock::get_default_sprite_name() const
- {
- switch (m_type)
- {
- case ORANGE:
- return "images/objects/bonus_block/orangeblock.sprite";
- case PURPLE:
- return "images/objects/bonus_block/purpleblock.sprite";
- case RETRO:
- return "images/objects/bonus_block/retroblock.sprite";
- default:
- return m_default_sprite_name;
- }
- }
- void
- BonusBlock::on_type_change(int old_type)
- {
- Block::on_type_change(old_type);
- m_hit_counter = get_default_hit_counter();
- m_coin_sprite = get_default_coin_sprite();
- }
- int
- BonusBlock::get_default_hit_counter() const
- {
- switch (m_type)
- {
- case ORANGE:
- return 3;
- case PURPLE:
- return 5;
- default:
- return 1;
- }
- }
- std::string
- BonusBlock::get_default_coin_sprite() const
- {
- switch (m_type)
- {
- case RETRO:
- return "images/objects/coin/retro_coin.sprite";
- default:
- return "images/objects/coin/coin.sprite";
- }
- }
- BonusBlock::Content
- BonusBlock::get_content_by_data(int tile_data) const
- {
- // Warning: 'tile_data' can't be cast to 'Content', this manual
- // conversion is necessary.
- switch (tile_data) {
- case 1: return Content::COIN;
- case 2: return Content::FIREGROW;
- case 3: return Content::STAR;
- case 4: return Content::ONEUP;
- case 5: return Content::ICEGROW;
- case 6: return Content::LIGHT;
- case 7: return Content::TRAMPOLINE;
- case 8: return Content::PORTABLE_TRAMPOLINE; // Trampoline.
- case 9: return Content::ROCK; // Rock.
- case 10: return Content::RAIN;
- case 11: return Content::EXPLODE;
- case 12: return Content::POTION; // Red potion.
- case 13: return Content::AIRGROW;
- case 14: return Content::EARTHGROW;
- case 15: return Content::LIGHT_ON;
- case 16: return Content::RETROGROW;
- case 17: return Content::RETROSTAR;
- default:
- log_warning << "Invalid box contents" << std::endl;
- return Content::COIN;
- }
- }
- ObjectSettings
- BonusBlock::get_settings()
- {
- ObjectSettings result = Block::get_settings();
- result.add_script(_("Script"), &m_script, "script");
- result.add_int(_("Count"), &m_hit_counter, "count", get_default_hit_counter());
- result.add_enum(_("Content"), reinterpret_cast<int*>(&m_contents),
- { _("Coin"), _("Growth (fire flower)"), _("Growth (ice flower)"), _("Growth (air flower)"),
- _("Growth (earth flower)"), _("Growth (retro)"), _("Star"), _("Star (retro)"), _("Tux doll"), _("Custom"), _("Script"), _("Light"), _("Light (On)"),
- _("Trampoline"), _("Portable trampoline"), _("Coin rain"), _("Coin explosion"), _("Rock"), _("Potion") },
- { "coin", "firegrow", "icegrow", "airgrow", "earthgrow", "retrogrow", "star", "retrostar", "1up", "custom", "script", "light", "light-on",
- "trampoline", "portabletrampoline", "rain", "explode", "rock", "potion" },
- static_cast<int>(Content::COIN), "contents");
- if (m_contents == Content::CUSTOM)
- result.add_objects(_("Custom Content"), &m_objects, ObjectFactory::RegisteredObjectParam::OBJ_PARAM_DISPENSABLE,
- [this](auto obj) { add_object(std::move(obj)); }, "custom-contents");
- else if (m_contents == Content::COIN || m_contents == Content::RAIN || m_contents == Content::EXPLODE)
- result.add_sprite(_("Coin sprite"), &m_coin_sprite, "coin-sprite", get_default_coin_sprite());
- result.reorder({"script", "count", "contents", "custom-content", "coin-sprite", "sprite", "x", "y"});
- return result;
- }
- void
- BonusBlock::hit(Player& player)
- {
- try_open(&player);
- }
- HitResponse
- BonusBlock::collision(GameObject& other, const CollisionHit& hit_)
- {
- auto player = dynamic_cast<Player*> (&other);
- if (player) {
- if (player->m_does_buttjump ||
- (player->is_swimboosting() && player->get_bbox().get_bottom() < m_col.m_bbox.get_top() + SHIFT_DELTA))
- {
- try_drop(player);
- }
- }
- auto badguy = dynamic_cast<BadGuy*> (&other);
- if (badguy) {
- // Hit contains no information for collisions with blocks.
- // Badguy's bottom has to be below the top of the block
- // SHIFT_DELTA is required to slide over one tile gaps.
- if ( badguy->can_break() && ( badguy->get_bbox().get_bottom() > m_col.m_bbox.get_top() + SHIFT_DELTA ) ) {
- try_open(player);
- }
- }
- auto crusher = dynamic_cast<Crusher*> (&other);
- if (crusher)
- {
- try_open(player);
- }
- auto portable = dynamic_cast<Portable*> (&other);
- if (portable && !badguy) {
- auto moving = dynamic_cast<MovingObject*> (&other);
- if (moving->get_bbox().get_top() > m_col.m_bbox.get_bottom() - SHIFT_DELTA) {
- try_open(player);
- }
- }
- return Block::collision(other, hit_);
- }
- void
- BonusBlock::try_open(Player* player)
- {
- SoundManager::current()->play("sounds/brick.wav", get_pos());
- if (m_sprite->get_action() == "empty")
- return;
- if (player == nullptr)
- player = Sector::get().get_nearest_player(m_col.m_bbox);
- if (player == nullptr)
- return;
- Direction direction = (player->get_bbox().get_middle().x > m_col.m_bbox.get_middle().x) ? Direction::LEFT : Direction::RIGHT;
- bool play_upgrade_sound = false;
- switch (m_contents) {
- case Content::COIN:
- {
- Sector::get().add<BouncyCoin>(get_pos(), true, m_coin_sprite);
- SoundManager::current()->play("sounds/coin.wav", get_pos());
- player->get_status().add_coins(1, false);
- if (m_hit_counter != 0 && !m_parent_dispenser)
- Sector::get().get_level().m_stats.increment_coins();
- break;
- }
- case Content::FIREGROW:
- {
- raise_growup_bonus(player, FIRE_BONUS, direction);
- break;
- }
- case Content::ICEGROW:
- {
- raise_growup_bonus(player, ICE_BONUS, direction);
- break;
- }
- case Content::AIRGROW:
- {
- raise_growup_bonus(player, AIR_BONUS, direction);
- break;
- }
- case Content::EARTHGROW:
- {
- raise_growup_bonus(player, EARTH_BONUS, direction);
- break;
- }
- case Content::RETROGROW:
- {
- raise_growup_bonus(player, FIRE_BONUS, direction,
- "images/powerups/retro/mints.png", "images/powerups/retro/coffee.png");
- break;
- }
- case Content::STAR:
- {
- Sector::get().add<Star>(get_pos() + Vector(0, -32), direction);
- play_upgrade_sound = true;
- break;
- }
- case Content::RETROSTAR:
- {
- Sector::get().add<Star>(get_pos() + Vector(0, -32), direction,
- "images/powerups/retro/golden_herring.png");
- play_upgrade_sound = true;
- break;
- }
- case Content::ONEUP:
- {
- Sector::get().add<OneUp>(get_pos(), direction);
- play_upgrade_sound = true;
- break;
- }
- case Content::CUSTOM:
- {
- auto moving_obj_copy = to_moving_object(GameObjectFactory::instance().create(m_object->get_class_name(), get_pos() + Vector(0, -32),
- direction, m_object->save()));
- Sector::get().add<SpecialRiser>(get_pos(), std::move(moving_obj_copy), true);
- play_upgrade_sound = true;
- break;
- }
- case Content::SCRIPT:
- { break; } // This prevents default contents from being assumed because scripts always run.
- case Content::LIGHT:
- case Content::LIGHT_ON:
- {
- if (m_sprite->get_action() == "on")
- set_action("off");
- else
- set_action("on");
- SoundManager::current()->play("sounds/switch.ogg", get_pos());
- break;
- }
- case Content::TRAMPOLINE:
- {
- Sector::get().add<SpecialRiser>(get_pos(), std::make_unique<Trampoline>(get_pos(), Trampoline::STATIONARY), true);
- play_upgrade_sound = true;
- break;
- }
- case Content::PORTABLE_TRAMPOLINE:
- {
- Sector::get().add<SpecialRiser>(get_pos(), std::make_unique<Trampoline>(get_pos(), Trampoline::PORTABLE), true);
- play_upgrade_sound = true;
- break;
- }
- case Content::ROCK:
- {
- Sector::get().add<SpecialRiser>(get_pos(), std::make_unique<Rock>(get_pos()));
- break;
- }
- case Content::POTION:
- {
- Sector::get().add<SpecialRiser>(get_pos(), std::make_unique<PowerUp>(get_pos(), PowerUp::FLIP));
- break;
- }
- case Content::RAIN:
- {
- Sector::get().add<CoinRain>(get_pos(), true, !m_parent_dispenser, m_coin_sprite);
- play_upgrade_sound = true;
- break;
- }
- case Content::EXPLODE:
- {
- Sector::get().add<CoinExplode>(get_pos() + Vector (0, -40), !m_parent_dispenser, m_coin_sprite);
- play_upgrade_sound = true;
- break;
- }
- }
- if (play_upgrade_sound)
- SoundManager::current()->play("sounds/upgrade.wav", get_pos(), UPGRADE_SOUND_GAIN);
- if (!m_script.empty()) { // Scripts always run if defined.
- Sector::get().run_script(m_script, "BonusBlockScript");
- }
- start_bounce(player);
- if (m_hit_counter <= 0 || m_contents == Content::LIGHT || m_contents == Content::LIGHT_ON) { // Use 0 to allow infinite hits.
- } else if (m_hit_counter == 1) {
- set_action("empty");
- } else {
- m_hit_counter--;
- }
- }
- void
- BonusBlock::try_drop(Player *player)
- {
- SoundManager::current()->play("sounds/brick.wav", get_pos());
- if (m_sprite->get_action() == "empty")
- return;
- // Determine the area below the bonus block. If it's solid, send it up regardless (except for dolls).
- Rectf dest_;
- dest_.set_left(m_col.m_bbox.get_left() + 1);
- dest_.set_top(m_col.m_bbox.get_bottom() + 1);
- dest_.set_right(m_col.m_bbox.get_right() - 1);
- dest_.set_bottom(dest_.get_top() + 30);
- if (!Sector::get().is_free_of_statics(dest_, this, true) && !(m_contents == Content::ONEUP))
- {
- try_open(player);
- return;
- }
- if (player == nullptr)
- player = Sector::get().get_nearest_player(m_col.m_bbox);
- if (player == nullptr)
- return;
- Direction direction = (player->get_bbox().get_middle().x > m_col.m_bbox.get_middle().x) ? Direction::LEFT : Direction::RIGHT;
- bool countdown = false;
- bool play_upgrade_sound = false;
- switch (m_contents) {
- case Content::COIN:
- {
- try_open(player);
- break;
- }
- case Content::FIREGROW:
- {
- drop_growup_bonus(player, PowerUp::FIRE, direction, countdown);
- break;
- }
- case Content::ICEGROW:
- {
- drop_growup_bonus(player, PowerUp::ICE, direction, countdown);
- break;
- }
- case Content::AIRGROW:
- {
- drop_growup_bonus(player, PowerUp::AIR, direction, countdown);
- break;
- }
- case Content::EARTHGROW:
- {
- drop_growup_bonus(player, PowerUp::EARTH, direction, countdown);
- break;
- }
- case Content::RETROGROW:
- {
- drop_growup_bonus(player, PowerUp::COFFEE, direction, countdown,
- "images/powerups/retro/mints.png");
- break;
- }
- case Content::STAR:
- {
- Sector::get().add<Star>(get_pos() + Vector(0, 32), direction);
- play_upgrade_sound = true;
- countdown = true;
- break;
- }
- case Content::RETROSTAR:
- {
- Sector::get().add<Star>(get_pos() + Vector(0, 32), direction,
- "images/powerups/retro/golden_herring.png");
- play_upgrade_sound = true;
- countdown = true;
- break;
- }
- case Content::ONEUP:
- {
- Sector::get().add<OneUp>(get_pos(), Direction::DOWN);
- play_upgrade_sound = true;
- countdown = true;
- break;
- }
- case Content::CUSTOM:
- {
- // NOTE: Non-portable trampolines could be moved to Content::CUSTOM, but they should not drop.
- auto obj_copy = GameObjectFactory::instance().create(m_object->get_class_name(), get_pos() + Vector(0, 32),
- direction, m_object->save());
- Sector::get().add_object(std::move(obj_copy));
- play_upgrade_sound = true;
- countdown = true;
- break;
- }
- case Content::SCRIPT:
- {
- countdown = true;
- break;
- } // This prevents default contents from being assumed because scripts always run.
- case Content::LIGHT:
- case Content::LIGHT_ON:
- case Content::TRAMPOLINE:
- case Content::RAIN:
- {
- try_open(player);
- break;
- }
- case Content::ROCK:
- {
- Sector::get().add<Rock>(get_pos() + Vector(0, 32), "images/objects/rock/rock.sprite");
- countdown = true;
- break;
- }
- case Content::PORTABLE_TRAMPOLINE:
- {
- Sector::get().add<Trampoline>(get_pos() + Vector(0, 32), true);
- countdown = true;
- break;
- }
- case Content::POTION:
- {
- Sector::get().add<PowerUp>(get_pos() + Vector(0, 32), PowerUp::FLIP);
- countdown = true;
- break;
- }
- case Content::EXPLODE:
- {
- Sector::get().add<CoinExplode>(get_pos() + Vector (0, 40), !m_parent_dispenser, m_coin_sprite);
- play_upgrade_sound = true;
- countdown = true;
- break;
- }
- }
- if (play_upgrade_sound)
- SoundManager::current()->play("sounds/upgrade.wav", get_pos(), UPGRADE_SOUND_GAIN);
- if (!m_script.empty()) { // Scripts always run if defined.
- Sector::get().run_script(m_script, "powerup-script");
- }
- if (countdown) { // Only decrease the hit counter if try_open was not called.
- if (m_hit_counter == 1) {
- set_action("empty");
- } else {
- m_hit_counter--;
- }
- }
- }
- void
- BonusBlock::raise_growup_bonus(Player* player, const BonusType& bonus, const Direction& dir,
- const std::string& growup_sprite, const std::string& flower_sprite)
- {
- std::unique_ptr<MovingObject> obj;
- if (player->get_status().bonus[player->get_id()] == NO_BONUS)
- {
- obj = std::make_unique<GrowUp>(get_pos(), dir, growup_sprite);
- }
- else
- {
- obj = std::make_unique<Flower>(bonus, flower_sprite);
- }
- Sector::get().add<SpecialRiser>(get_pos(), std::move(obj));
- SoundManager::current()->play("sounds/upgrade.wav", get_pos(), UPGRADE_SOUND_GAIN);
- }
- void
- BonusBlock::drop_growup_bonus(Player* player, int type, const Direction& dir, bool& countdown,
- const std::string& growup_sprite)
- {
- if (player->get_status().bonus[player->get_id()] == NO_BONUS)
- {
- Sector::get().add<GrowUp>(get_pos() + Vector(0, 32), dir, growup_sprite);
- }
- else
- {
- Sector::get().add<PowerUp>(get_pos() + Vector(0, 32), type);
- }
- SoundManager::current()->play("sounds/upgrade.wav", get_pos(), UPGRADE_SOUND_GAIN);
- countdown = true;
- }
- void
- BonusBlock::draw(DrawingContext& context)
- {
- // Perform the regular drawing first.
- Block::draw(context);
- // Draw the light if the bonus block is in the "on" state.
- if (m_sprite->get_action() == "on")
- {
- Vector pos = get_pos() + (m_col.m_bbox.get_size().as_vector() - Vector(static_cast<float>(m_lightsprite->get_width()),
- static_cast<float>(m_lightsprite->get_height()))) / 2.0f;
- context.light().draw_surface(m_lightsprite, pos, 10);
- }
- }
- BonusBlock::Content
- BonusBlock::get_content_from_string(const std::string& contentstring) const
- {
- if (contentstring == "coin")
- return Content::COIN;
- else if (contentstring == "firegrow")
- return Content::FIREGROW;
- else if (contentstring == "icegrow")
- return Content::ICEGROW;
- else if (contentstring == "airgrow")
- return Content::AIRGROW;
- else if (contentstring == "earthgrow")
- return Content::EARTHGROW;
- else if (contentstring == "retrogrow")
- return Content::RETROGROW;
- else if (contentstring == "star")
- return Content::STAR;
- else if (contentstring == "retrostar")
- return Content::RETROSTAR;
- else if (contentstring == "1up")
- return Content::ONEUP;
- else if (contentstring == "custom")
- return Content::CUSTOM;
- else if (contentstring == "script") // Use this when the bonus block is intended to contain ONLY a script.
- return Content::SCRIPT;
- else if (contentstring == "light")
- return Content::LIGHT;
- else if (contentstring == "light-on")
- return Content::LIGHT_ON;
- else if (contentstring == "trampoline")
- return Content::TRAMPOLINE;
- else if (contentstring == "portabletrampoline")
- return Content::PORTABLE_TRAMPOLINE;
- else if (contentstring == "potion")
- return Content::POTION;
- else if (contentstring == "rock")
- return Content::ROCK;
- else if (contentstring == "rain")
- return Content::RAIN;
- else if (contentstring == "explode")
- return Content::EXPLODE;
- else
- {
- log_warning << "Invalid bonus block contents '" << contentstring << "'" << std::endl;
- return Content::COIN;
- }
- }
- void
- BonusBlock::preload_contents(int d)
- {
- switch (d)
- {
- case 6: // Light.
- case 15: // Light (On).
- SoundManager::current()->preload("sounds/switch.ogg");
- m_lightsprite=Surface::from_file("/images/objects/lightmap_light/bonusblock_light.png");
- break;
- case 7:
- // Uncomment the following line if this is to be moved to the "custom" case.
- // object = new Trampoline(get_pos(), false);
- break;
- case 8: // Trampoline.
- set_object(std::make_unique<Trampoline>(get_pos(), true));
- break;
- case 9: // Rock.
- set_object(std::make_unique<Rock>(get_pos(), "images/objects/rock/rock.sprite"));
- break;
- case 12: // Red potion.
- set_object(std::make_unique<PowerUp>(get_pos(), PowerUp::FLIP));
- break;
- default:
- break;
- }
- }
- /* EOF */
|