X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fobject%2Fbonus_block.cpp;h=2b03e5c5e6d09b8c00b7ce103748846aa67e9a48;hb=b88dc6c0a778a019bf0b1f28c2cc9d624d9bbdbd;hp=36d755812de87b26b9aa30928794d3c813886e65;hpb=d4020fbad1a693156ae5ad310fdcf0f90e3f315f;p=supertux.git diff --git a/src/object/bonus_block.cpp b/src/object/bonus_block.cpp index 36d755812..2b03e5c5e 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 @@ -28,6 +28,7 @@ #include "object/oneup.hpp" #include "object/player.hpp" #include "object/portable.hpp" +#include "object/powerup.hpp" #include "object/specialriser.hpp" #include "object/star.hpp" #include "object/trampoline.hpp" @@ -40,10 +41,12 @@ #include BonusBlock::BonusBlock(const Vector& pos, int data) : - Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite")), + Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite")), contents(), object(0), hit_counter(1), + sprite_name(), + script(), lightsprite() { bbox.set_pos(pos); @@ -54,15 +57,24 @@ 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; + sound_manager->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 = new Trampoline(get_pos(), true); + break; + case 9: contents = CONTENT_CUSTOM; + object = new Rock(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 = new PowerUp(get_pos(), "images/powerups/potions/red-potion.sprite"); + break; default: log_warning << "Invalid box contents" << std::endl; contents = CONTENT_COIN; @@ -75,6 +87,8 @@ BonusBlock::BonusBlock(const Reader& lisp) : contents(), object(0), hit_counter(1), + sprite_name(), + script(), lightsprite() { Vector pos; @@ -92,7 +106,7 @@ BonusBlock::BonusBlock(const Reader& lisp) : sprite = sprite_manager->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; @@ -109,17 +123,13 @@ BonusBlock::BonusBlock(const Reader& lisp) : 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"); } 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") { @@ -165,7 +175,7 @@ BonusBlock::collision(GameObject& other, const CollisionHit& hit){ Player* player = dynamic_cast (&other); if (player) { if (player->does_buttjump) - try_open(player); + try_drop(player); } BadGuy* badguy = dynamic_cast (&other); @@ -200,7 +210,7 @@ BonusBlock::try_open(Player *player) if (player == NULL) player = sector->player; - + if (player == NULL) return; @@ -247,12 +257,14 @@ BonusBlock::try_open(Player *player) case CONTENT_STAR: { sector->add_object(new Star(get_pos() + Vector(0, -32), direction)); + sound_manager->play("sounds/upgrade.wav"); break; } case CONTENT_1UP: { sector->add_object(new OneUp(get_pos(), direction)); + sound_manager->play("sounds/upgrade.wav"); break; } @@ -284,34 +296,142 @@ BonusBlock::try_open(Player *player) sound_manager->play("sounds/upgrade.wav"); break; } - case CONTENT_PORTTRAMPOLINE: + case CONTENT_RAIN: { - SpecialRiser* riser = new SpecialRiser(get_pos(), new Trampoline(get_pos(), true)); - sector->add_object(riser); + 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"); break; } - case CONTENT_ROCK: + case CONTENT_EXPLODE: { - SpecialRiser* riser = new SpecialRiser(get_pos(), - new Rock(get_pos(), "images/objects/rock/rock.sprite")); - sector->add_object(riser); + hit_counter = 1; // multiple hits of coin explode is not allowed + Sector::current()->add_object(new CoinExplode(get_pos() + Vector (0, -40))); sound_manager->play("sounds/upgrade.wav"); break; } + } - case CONTENT_RAIN: + if(script != "") { // scripts always run if defined + std::istringstream stream(script); + Sector::current()->run_script(stream, "BonusBlockScript"); + } + + start_bounce(player); + 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--; + } +} + +void +BonusBlock::try_drop(Player *player) +{ + if(sprite->get_action() == "empty") { + sound_manager->play("sounds/brick.wav"); + return; + } + + Sector* sector = Sector::current(); + 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)) { + try_open(player); + return; + } + + if (player == NULL) + player = sector->player; + + if (player == NULL) + return; + + Direction direction = (player->get_bbox().get_middle().x > get_bbox().get_middle().x) ? LEFT : RIGHT; + + bool countdown = false; + + switch(contents) { + case CONTENT_COIN: { - hit_counter = 1; // multiple hits of coin rain is not allowed - Sector::current()->add_object(new CoinRain(get_pos(), true)); + try_open(player); + break; + } + + case CONTENT_FIREGROW: + { + sector->add_object(new PowerUp(get_pos() + Vector(0, 32), "images/powerups/fireflower/fireflower.sprite")); sound_manager->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"); + countdown = true; + break; + } + + case CONTENT_STAR: + { + sector->add_object(new Star(get_pos() + Vector(0, 32), direction)); + sound_manager->play("sounds/upgrade.wav"); + countdown = true; + break; + } + + case CONTENT_1UP: + { + sector->add_object(new OneUp(get_pos(), DOWN)); + sound_manager->play("sounds/upgrade.wav"); + countdown = true; + break; + } + + case CONTENT_CUSTOM: + { + //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"); + countdown = true; + break; + } + + case CONTENT_SCRIPT: + { break; } // because scripts always run, this prevents default contents from being assumed + + case CONTENT_LIGHT: + { + try_open(player); + break; + } + case CONTENT_TRAMPOLINE: + { + try_open(player); + break; + } + case CONTENT_RAIN: + { + try_open(player); 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)); + Sector::current()->add_object(new CoinExplode(get_pos() + Vector (0, 40))); sound_manager->play("sounds/upgrade.wav"); + countdown = true; break; } } @@ -321,12 +441,12 @@ BonusBlock::try_open(Player *player) Sector::current()->run_script(stream, "powerup-script"); } - start_bounce(player); - 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--; + } } } @@ -350,9 +470,9 @@ Block::break_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; context.push_target();