X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fobject%2Fbonus_block.cpp;h=5f067766d8545da8a205c2f0c051589e044b8c14;hb=8eff855963e2699763d0d653dabc9b709f0d2ab0;hp=3f58dc526bca3e9675f439767f2a5370829a422e;hpb=559e879fe18d0ade6bae0476f1f62ff5b6756098;p=supertux.git diff --git a/src/object/bonus_block.cpp b/src/object/bonus_block.cpp index 3f58dc526..5f067766d 100644 --- a/src/object/bonus_block.cpp +++ b/src/object/bonus_block.cpp @@ -1,5 +1,5 @@ // SuperTux -// Copyright (C) 2009 Ingo Ruhnke +// Copyright (C) 2009 Ingo Ruhnke // // 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 @@ -19,7 +19,6 @@ #include "audio/sound_manager.hpp" #include "badguy/badguy.hpp" #include "lisp/list_iterator.hpp" -#include "object/broken_brick.hpp" #include "object/flower.hpp" #include "object/bouncy_coin.hpp" #include "object/coin_explode.hpp" @@ -41,10 +40,12 @@ #include BonusBlock::BonusBlock(const Vector& pos, int data) : - Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite")), + Block(SpriteManager::current()->create("images/objects/bonus_block/bonusblock.sprite")), contents(), - object(0), + object(), hit_counter(1), + sprite_name(), + script(), lightsprite() { bbox.set_pos(pos); @@ -55,15 +56,26 @@ BonusBlock::BonusBlock(const Vector& pos, int data) : case 3: contents = CONTENT_STAR; break; case 4: contents = CONTENT_1UP; break; case 5: contents = CONTENT_ICEGROW; break; - case 6: contents = CONTENT_LIGHT; - sound_manager->preload("sounds/switch.ogg"); + case 6: contents = CONTENT_LIGHT; + SoundManager::current()->preload("sounds/switch.ogg"); lightsprite=Surface::create("/images/objects/lightmap_light/bonusblock_light.png"); break; - case 7: contents = CONTENT_TRAMPOLINE; break; - case 8: contents = CONTENT_PORTTRAMPOLINE; break; - case 9: contents = CONTENT_ROCK; break; + case 7: contents = CONTENT_TRAMPOLINE; + //object = new Trampoline(get_pos(), false); //needed if this is to be moved to custom + break; + case 8: contents = CONTENT_CUSTOM; + object = std::make_shared(get_pos(), true); + break; + case 9: contents = CONTENT_CUSTOM; + object = std::make_shared(get_pos(), "images/objects/rock/rock.sprite"); + break; case 10: contents = CONTENT_RAIN; break; case 11: contents = CONTENT_EXPLODE; break; + case 12: contents = CONTENT_CUSTOM; + object = std::make_shared(get_pos(), "images/powerups/potions/red-potion.sprite"); + break; + case 13: contents = CONTENT_AIRGROW; break; + case 14: contents = CONTENT_EARTHGROW; break; default: log_warning << "Invalid box contents" << std::endl; contents = CONTENT_COIN; @@ -72,10 +84,12 @@ BonusBlock::BonusBlock(const Vector& pos, int data) : } BonusBlock::BonusBlock(const Reader& lisp) : - Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite")), + Block(SpriteManager::current()->create("images/objects/bonus_block/bonusblock.sprite")), contents(), object(0), hit_counter(1), + sprite_name(), + script(), lightsprite() { Vector pos; @@ -90,10 +104,10 @@ BonusBlock::BonusBlock(const Reader& lisp) : iter.value()->get(pos.y); } else if(token == "sprite") { iter.value()->get(sprite_name); - sprite = sprite_manager->create(sprite_name); + sprite = SpriteManager::current()->create(sprite_name); } else if(token == "count") { iter.value()->get(hit_counter); - } else if(token == "script") { // use when bonusblock is to contain ONLY a script + } else if(token == "script") { iter.value()->get(script); } else if(token == "contents") { std::string contentstring; @@ -104,23 +118,23 @@ BonusBlock::BonusBlock(const Reader& lisp) : contents = CONTENT_FIREGROW; } else if(contentstring == "icegrow") { contents = CONTENT_ICEGROW; + } else if(contentstring == "airgrow") { + contents = CONTENT_AIRGROW; + } else if(contentstring == "earthgrow") { + contents = CONTENT_EARTHGROW; } else if(contentstring == "star") { contents = CONTENT_STAR; } else if(contentstring == "1up") { contents = CONTENT_1UP; } else if(contentstring == "custom") { contents = CONTENT_CUSTOM; - } else if(contentstring == "script") { + } else if(contentstring == "script") { // use when bonusblock is to contain ONLY a script contents = CONTENT_SCRIPT; } else if(contentstring == "light") { contents = CONTENT_LIGHT; - sound_manager->preload("sounds/switch.ogg"); + SoundManager::current()->preload("sounds/switch.ogg"); } else if(contentstring == "trampoline") { contents = CONTENT_TRAMPOLINE; - } else if(contentstring == "porttrampoline") { - contents = CONTENT_PORTTRAMPOLINE; - } else if(contentstring == "rock") { - contents = CONTENT_ROCK; } else if(contentstring == "rain") { contents = CONTENT_RAIN; } else if(contentstring == "explode") { @@ -130,8 +144,8 @@ BonusBlock::BonusBlock(const Reader& lisp) : } } else { if(contents == CONTENT_CUSTOM) { - GameObject* game_object = ObjectFactory::instance().create(token, *(iter.lisp())); - object = dynamic_cast (game_object); + GameObjectPtr game_object = ObjectFactory::instance().create(token, *(iter.lisp())); + object = std::dynamic_pointer_cast(game_object); if(object == 0) throw std::runtime_error( "Only MovingObjects are allowed inside BonusBlocks"); @@ -151,7 +165,6 @@ BonusBlock::BonusBlock(const Reader& lisp) : BonusBlock::~BonusBlock() { - delete object; } void @@ -161,7 +174,7 @@ BonusBlock::hit(Player & player) } HitResponse -BonusBlock::collision(GameObject& other, const CollisionHit& hit){ +BonusBlock::collision(GameObject& other, const CollisionHit& hit_){ Player* player = dynamic_cast (&other); if (player) { @@ -185,14 +198,14 @@ BonusBlock::collision(GameObject& other, const CollisionHit& hit){ try_open(player); } } - return Block::collision(other, hit); + return Block::collision(other, hit_); } void BonusBlock::try_open(Player *player) { if(sprite->get_action() == "empty") { - sound_manager->play("sounds/brick.wav"); + SoundManager::current()->play("sounds/brick.wav"); return; } @@ -210,7 +223,7 @@ BonusBlock::try_open(Player *player) switch(contents) { case CONTENT_COIN: { - Sector::current()->add_object(new BouncyCoin(get_pos(), true)); + Sector::current()->add_object(std::make_shared(get_pos(), true)); player->get_status()->add_coins(1); if (hit_counter != 0) Sector::current()->get_level()->stats.coins++; @@ -220,49 +233,79 @@ BonusBlock::try_open(Player *player) case CONTENT_FIREGROW: { if(player->get_status()->bonus == NO_BONUS) { - SpecialRiser* riser = new SpecialRiser(get_pos(), new GrowUp(direction)); + auto riser = std::make_shared(get_pos(), std::make_shared(direction)); sector->add_object(riser); } else { - SpecialRiser* riser = new SpecialRiser( - get_pos(), new Flower(FIRE_BONUS)); + auto riser = std::make_shared( + get_pos(), std::make_shared(FIRE_BONUS)); sector->add_object(riser); } - sound_manager->play("sounds/upgrade.wav"); + SoundManager::current()->play("sounds/upgrade.wav"); break; } case CONTENT_ICEGROW: { if(player->get_status()->bonus == NO_BONUS) { - SpecialRiser* riser = new SpecialRiser(get_pos(), new GrowUp(direction)); + auto riser = std::make_shared(get_pos(), std::make_shared(direction)); + sector->add_object(riser); + } else { + auto riser = std::make_shared( + get_pos(), std::make_shared(ICE_BONUS)); + sector->add_object(riser); + } + SoundManager::current()->play("sounds/upgrade.wav"); + break; + } + + case CONTENT_AIRGROW: + { + if(player->get_status()->bonus == NO_BONUS) { + auto riser = std::make_shared(get_pos(), std::make_shared(direction)); + sector->add_object(riser); + } else { + auto riser = std::make_shared( + get_pos(), std::make_shared(AIR_BONUS)); + sector->add_object(riser); + } + SoundManager::current()->play("sounds/upgrade.wav"); + break; + } + + case CONTENT_EARTHGROW: + { + if(player->get_status()->bonus == NO_BONUS) { + auto riser = std::make_shared(get_pos(), std::make_shared(direction)); sector->add_object(riser); } else { - SpecialRiser* riser = new SpecialRiser( - get_pos(), new Flower(ICE_BONUS)); + auto riser = std::make_shared( + get_pos(), std::make_shared(EARTH_BONUS)); sector->add_object(riser); } - sound_manager->play("sounds/upgrade.wav"); + SoundManager::current()->play("sounds/upgrade.wav"); break; } case CONTENT_STAR: { - sector->add_object(new Star(get_pos() + Vector(0, -32), direction)); + sector->add_object(std::make_shared(get_pos() + Vector(0, -32), direction)); + SoundManager::current()->play("sounds/upgrade.wav"); break; } case CONTENT_1UP: { - sector->add_object(new OneUp(get_pos(), direction)); + sector->add_object(std::make_shared(get_pos(), direction)); + SoundManager::current()->play("sounds/upgrade.wav"); break; } case CONTENT_CUSTOM: { - SpecialRiser* riser = new SpecialRiser(get_pos(), object); + auto riser = std::make_shared(get_pos(), object); object = 0; sector->add_object(riser); - sound_manager->play("sounds/upgrade.wav"); + SoundManager::current()->play("sounds/upgrade.wav"); break; } @@ -275,51 +318,35 @@ BonusBlock::try_open(Player *player) sprite->set_action("off"); else sprite->set_action("on"); - sound_manager->play("sounds/switch.ogg"); + SoundManager::current()->play("sounds/switch.ogg"); break; } case CONTENT_TRAMPOLINE: { - SpecialRiser* riser = new SpecialRiser(get_pos(), new Trampoline(get_pos(), false)); - sector->add_object(riser); - sound_manager->play("sounds/upgrade.wav"); - break; - } - case CONTENT_PORTTRAMPOLINE: - { - SpecialRiser* riser = new SpecialRiser(get_pos(), new Trampoline(get_pos(), true)); - sector->add_object(riser); - sound_manager->play("sounds/upgrade.wav"); - break; - } - case CONTENT_ROCK: - { - SpecialRiser* riser = new SpecialRiser(get_pos(), - new Rock(get_pos(), "images/objects/rock/rock.sprite")); + auto riser = std::make_shared(get_pos(), std::make_shared(get_pos(), false)); sector->add_object(riser); - sound_manager->play("sounds/upgrade.wav"); + SoundManager::current()->play("sounds/upgrade.wav"); break; } - case CONTENT_RAIN: { hit_counter = 1; // multiple hits of coin rain is not allowed - Sector::current()->add_object(new CoinRain(get_pos(), true)); - sound_manager->play("sounds/upgrade.wav"); + Sector::current()->add_object(std::make_shared(get_pos(), true)); + SoundManager::current()->play("sounds/upgrade.wav"); break; } case CONTENT_EXPLODE: { hit_counter = 1; // multiple hits of coin explode is not allowed - Sector::current()->add_object(new CoinExplode(get_pos() + Vector (0, -40), 1)); - sound_manager->play("sounds/upgrade.wav"); + Sector::current()->add_object(std::make_shared(get_pos() + Vector (0, -40))); + SoundManager::current()->play("sounds/upgrade.wav"); break; } } if(script != "") { // scripts always run if defined std::istringstream stream(script); - Sector::current()->run_script(stream, "powerup-script"); + Sector::current()->run_script(stream, "BonusBlockScript"); } start_bounce(player); @@ -335,7 +362,7 @@ void BonusBlock::try_drop(Player *player) { if(sprite->get_action() == "empty") { - sound_manager->play("sounds/brick.wav"); + SoundManager::current()->play("sounds/brick.wav"); return; } @@ -343,12 +370,12 @@ BonusBlock::try_drop(Player *player) assert(sector); // First what's below the bonus block, if solid send it up anyway (excepting doll) - Rectf dest; - dest.p1.x = bbox.get_left() + 1; - dest.p1.y = bbox.get_bottom() + 1; - dest.p2.x = bbox.get_right() - 1; - dest.p2.y = dest.p1.y + 30; - if (!Sector::current()->is_free_of_statics(dest, this, true) && !(contents == CONTENT_1UP)) { + Rectf dest_; + dest_.p1.x = bbox.get_left() + 1; + dest_.p1.y = bbox.get_bottom() + 1; + dest_.p2.x = bbox.get_right() - 1; + dest_.p2.y = dest_.p1.y + 30; + if (!Sector::current()->is_free_of_statics(dest_, this, true) && !(contents == CONTENT_1UP)) { try_open(player); return; } @@ -361,6 +388,8 @@ BonusBlock::try_drop(Player *player) Direction direction = (player->get_bbox().get_middle().x > get_bbox().get_middle().x) ? LEFT : RIGHT; + bool countdown = false; + switch(contents) { case CONTENT_COIN: { @@ -370,37 +399,60 @@ BonusBlock::try_drop(Player *player) case CONTENT_FIREGROW: { - sector->add_object(new PowerUp(get_pos() + Vector(0, 32), "images/powerups/fireflower/fireflower.sprite")); - sound_manager->play("sounds/upgrade.wav"); + sector->add_object(std::make_shared(get_pos() + Vector(0, 32), "images/powerups/fireflower/fireflower.sprite")); + SoundManager::current()->play("sounds/upgrade.wav"); + countdown = true; break; } case CONTENT_ICEGROW: { - sector->add_object(new PowerUp(get_pos() + Vector(0, 32), "images/powerups/iceflower/iceflower.sprite")); - sound_manager->play("sounds/upgrade.wav"); + sector->add_object(std::make_shared(get_pos() + Vector(0, 32), "images/powerups/iceflower/iceflower.sprite")); + SoundManager::current()->play("sounds/upgrade.wav"); + countdown = true; + break; + } + + case CONTENT_AIRGROW: + { + sector->add_object(std::make_shared(get_pos() + Vector(0, 32), "images/powerups/airflower/airflower.sprite")); + SoundManager::current()->play("sounds/upgrade.wav"); + countdown = true; + break; + } + + case CONTENT_EARTHGROW: + { + sector->add_object(std::make_shared(get_pos() + Vector(0, 32), "images/powerups/earthflower/earthflower.sprite")); + SoundManager::current()->play("sounds/upgrade.wav"); + countdown = true; break; } case CONTENT_STAR: { - sector->add_object(new Star(get_pos() + Vector(0, 32), direction)); + sector->add_object(std::make_shared(get_pos() + Vector(0, 32), direction)); + SoundManager::current()->play("sounds/upgrade.wav"); + countdown = true; break; } case CONTENT_1UP: { - sector->add_object(new OneUp(get_pos(), DOWN)); + sector->add_object(std::make_shared(get_pos(), DOWN)); + SoundManager::current()->play("sounds/upgrade.wav"); + countdown = true; break; } case CONTENT_CUSTOM: { - //TODO: confirm this works + //NOTE: non-portable trampolines could be moved to CONTENT_CUSTOM, but they should not drop object->set_pos(get_pos() + Vector(0, 32)); sector->add_object(object); object = 0; - sound_manager->play("sounds/upgrade.wav"); + SoundManager::current()->play("sounds/upgrade.wav"); + countdown = true; break; } @@ -417,19 +469,6 @@ BonusBlock::try_drop(Player *player) try_open(player); break; } - case CONTENT_PORTTRAMPOLINE: - { - Sector::current()->add_object(new Trampoline(get_pos() + Vector (0, 32), true)); - sound_manager->play("sounds/upgrade.wav"); - break; - } - case CONTENT_ROCK: - { - Sector::current()->add_object(new Rock(get_pos() + Vector (0, 32), "images/objects/rock/rock.sprite")); - sound_manager->play("sounds/upgrade.wav"); - break; - } - case CONTENT_RAIN: { try_open(player); @@ -438,8 +477,9 @@ BonusBlock::try_drop(Player *player) case CONTENT_EXPLODE: { hit_counter = 1; // multiple hits of coin explode is not allowed - Sector::current()->add_object(new CoinExplode(get_pos() + Vector (0, 40), -1)); - sound_manager->play("sounds/upgrade.wav"); + Sector::current()->add_object(std::make_shared(get_pos() + Vector (0, 40))); + SoundManager::current()->play("sounds/upgrade.wav"); + countdown = true; break; } } @@ -449,39 +489,22 @@ BonusBlock::try_drop(Player *player) Sector::current()->run_script(stream, "powerup-script"); } - if(hit_counter <= 0 || contents == CONTENT_LIGHT){ //use 0 to allow infinite hits - }else if(hit_counter == 1){ - sprite->set_action("empty"); - }else{ - hit_counter--; + if(countdown){ // only decrease hit counter if try_open was not called + if(hit_counter == 1){ + sprite->set_action("empty"); + }else{ + hit_counter--; + } } } void -Block::break_me() -{ - Sector* sector = Sector::current(); - sector->add_object( - new BrokenBrick(sprite->clone(), get_pos(), Vector(-100, -400))); - sector->add_object( - new BrokenBrick(sprite->clone(), get_pos() + Vector(0, 16), - Vector(-150, -300))); - sector->add_object( - new BrokenBrick(sprite->clone(), get_pos() + Vector(16, 0), - Vector(100, -400))); - sector->add_object( - new BrokenBrick(sprite->clone(), get_pos() + Vector(16, 16), - Vector(150, -300))); - remove_me(); -} - -void BonusBlock::draw(DrawingContext& context){ - // draw regular sprite - sprite->draw(context, get_pos(), 10); - //Draw light if on. + // do the regular drawing first + Block::draw(context); + // then Draw the light if on. if(sprite->get_action() == "on") { - Vector pos = get_pos() + (bbox.get_size() - lightsprite->get_size()) / 2; + Vector pos = get_pos() + (bbox.get_size().as_vector() - lightsprite->get_size()) / 2; context.push_target(); context.set_target(DrawingContext::LIGHTMAP); context.draw_surface(lightsprite, pos, 10);