From: LMH Date: Tue, 16 Jul 2013 15:16:05 +0000 (-1000) Subject: New BadGuy: GoldBomb - a bomb that throws a bunch of coins when exploding. X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=29ec866f6472779b2559f23f969b0317e348beb8;p=supertux.git New BadGuy: GoldBomb - a bomb that throws a bunch of coins when exploding. Note: these coins are currently counted in level statistics. Also goldbomb is not allowed to be dispensed at this time. --- diff --git a/data/images/creatures/gold_bomb/exploding-left-0.png b/data/images/creatures/gold_bomb/exploding-left-0.png new file mode 100644 index 000000000..943315f69 Binary files /dev/null and b/data/images/creatures/gold_bomb/exploding-left-0.png differ diff --git a/data/images/creatures/gold_bomb/exploding-left-1.png b/data/images/creatures/gold_bomb/exploding-left-1.png new file mode 100644 index 000000000..21d1967f6 Binary files /dev/null and b/data/images/creatures/gold_bomb/exploding-left-1.png differ diff --git a/data/images/creatures/gold_bomb/exploding-left-2.png b/data/images/creatures/gold_bomb/exploding-left-2.png new file mode 100644 index 000000000..54f9c9f33 Binary files /dev/null and b/data/images/creatures/gold_bomb/exploding-left-2.png differ diff --git a/data/images/creatures/gold_bomb/exploding-left-3.png b/data/images/creatures/gold_bomb/exploding-left-3.png new file mode 100644 index 000000000..3c0477bcf Binary files /dev/null and b/data/images/creatures/gold_bomb/exploding-left-3.png differ diff --git a/data/images/creatures/gold_bomb/exploding-left-4.png b/data/images/creatures/gold_bomb/exploding-left-4.png new file mode 100644 index 000000000..4e763bbb2 Binary files /dev/null and b/data/images/creatures/gold_bomb/exploding-left-4.png differ diff --git a/data/images/creatures/gold_bomb/gold_bomb.sprite b/data/images/creatures/gold_bomb/gold_bomb.sprite new file mode 100644 index 000000000..df1ed18cd --- /dev/null +++ b/data/images/creatures/gold_bomb/gold_bomb.sprite @@ -0,0 +1,68 @@ +(supertux-sprite + (action + (name "left") + (fps 10.0) + (hitbox 5 8 32 32) + (images "left-0.png" + "left-1.png" + "left-2.png" + "left-1.png")) + + (action + (name "right") + (fps 10.0) + (hitbox 5 8 32 32) + (mirror-action "left")) + + (action + (name "iced-left") + (hitbox 5 8 31.8 31.8) + (images "iced-left.png")) + + (action + (name "iced-right") + (hitbox 5 8 31.8 31.8) + (mirror-action "iced-left")) + + (action + (name "ticking-left") + (fps 10.0) + (hitbox 5 8 32 32) + (images "exploding-left-0.png" + "exploding-left-1.png" + "exploding-left-2.png" + "exploding-left-3.png" + "exploding-left-4.png" + "exploding-left-3.png" + "exploding-left-2.png" + "exploding-left-1.png" + "exploding-left-0.png" + "exploding-left-1.png" + "exploding-left-2.png" + "exploding-left-3.png" + "exploding-left-4.png" + "exploding-left-3.png" + "exploding-left-2.png" + "exploding-left-1.png" + "exploding-left-0.png" + "exploding-left-2.png" + "exploding-left-4.png" + "exploding-left-2.png" + "exploding-left-0.png" + "exploding-left-2.png" + "exploding-left-4.png" + "exploding-left-2.png" + "exploding-left-0.png" + "exploding-left-4.png" + "exploding-left-0.png" + "exploding-left-4.png" + )) + + + (action + (name "ticking-right") + (fps 10.0) + (hitbox 5 8 32 32) + (mirror-action "ticking-left")) + +) diff --git a/data/images/creatures/gold_bomb/iced-left.png b/data/images/creatures/gold_bomb/iced-left.png new file mode 100644 index 000000000..22f5afa1c Binary files /dev/null and b/data/images/creatures/gold_bomb/iced-left.png differ diff --git a/data/images/creatures/gold_bomb/left-0.png b/data/images/creatures/gold_bomb/left-0.png new file mode 100644 index 000000000..392222100 Binary files /dev/null and b/data/images/creatures/gold_bomb/left-0.png differ diff --git a/data/images/creatures/gold_bomb/left-1.png b/data/images/creatures/gold_bomb/left-1.png new file mode 100644 index 000000000..58f39f3c6 Binary files /dev/null and b/data/images/creatures/gold_bomb/left-1.png differ diff --git a/data/images/creatures/gold_bomb/left-2.png b/data/images/creatures/gold_bomb/left-2.png new file mode 100644 index 000000000..6c2cb05d2 Binary files /dev/null and b/data/images/creatures/gold_bomb/left-2.png differ diff --git a/src/badguy/bomb.cpp b/src/badguy/bomb.cpp index 75dcf4299..0283fb595 100644 --- a/src/badguy/bomb.cpp +++ b/src/badguy/bomb.cpp @@ -123,6 +123,7 @@ Bomb::ungrab(MovingObject& object, Direction dir) this->dir = dir; // portable objects are usually pushed away from Tux when dropped, but we // don't want that, so we set the position + //FIXME: why don't we want that? shouldn't behavior be consistent? set_pos(object.get_pos() + Vector(dir == LEFT ? -16 : 16, get_bbox().get_height()*0.66666 - 32)); set_colgroup_active(COLGROUP_MOVING); grabbed = false; diff --git a/src/badguy/dispenser.cpp b/src/badguy/dispenser.cpp index da9514b51..cb4a923fa 100644 --- a/src/badguy/dispenser.cpp +++ b/src/badguy/dispenser.cpp @@ -199,6 +199,10 @@ Dispenser::launch_badguy() log_warning << "random is outdated; use a list of badguys to select from." << std::endl; return; } + if(badguy == "goldbomb") { + log_warning << "goldbomb is not allowed to be dispensed" << std::endl; + return; + } try { GameObject *game_object; diff --git a/src/badguy/goldbomb.cpp b/src/badguy/goldbomb.cpp new file mode 100644 index 000000000..f87f6059b --- /dev/null +++ b/src/badguy/goldbomb.cpp @@ -0,0 +1,240 @@ +// SuperTux BadGuy GoldBomb - a bomb that throws up coins when exploding +// Copyright (C) 2006 Matthias Braun +// Copyright (C) 2013 LMH +// +// 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 "audio/sound_manager.hpp" +#include "badguy/goldbomb.hpp" +#include "object/coin_explode.hpp" +#include "object/explosion.hpp" +#include "object/player.hpp" +#include "object/portable.hpp" +#include "sprite/sprite.hpp" +#include "sprite/sprite_manager.hpp" +#include "supertux/object_factory.hpp" +#include "supertux/sector.hpp" +#include "util/reader.hpp" + +GoldBomb::GoldBomb(const Reader& reader) : + WalkingBadguy(reader, "images/creatures/gold_bomb/gold_bomb.sprite", "left", "right"), + tstate(STATE_NORMAL), + grabbed(false), + grabber(NULL) +{ + walk_speed = 80; + max_drop_height = 16; + + //Prevent stutter when Tux jumps on Gold Bomb + sound_manager->preload("sounds/explosion.wav"); + + //Check if we need another sprite + if( !reader.get( "sprite", sprite_name ) ){ + return; + } + if( sprite_name == "" ){ + sprite_name = "images/creatures/gold_bomb/gold_bomb.sprite"; + return; + } + //Replace sprite + sprite = sprite_manager->create( sprite_name ); +} + +void +GoldBomb::collision_solid(const CollisionHit& hit) +{ + if(tstate == STATE_TICKING) { + if(hit.bottom) { + physic.set_velocity_y(0); + physic.set_velocity_x(0); + }else if (hit.left || hit.right) + physic.set_velocity_x(-physic.get_velocity_x()); + else if (hit.top) + physic.set_velocity_y(0); + return; + } + WalkingBadguy::collision_solid(hit); +} + +HitResponse +GoldBomb::collision(GameObject& object, const CollisionHit& hit) +{ + if(tstate == STATE_TICKING) + return ABORT_MOVE; + if(grabbed) + return FORCE_MOVE; + return WalkingBadguy::collision(object, hit); +} + +HitResponse +GoldBomb::collision_player(Player& player, const CollisionHit& hit) +{ + if(tstate == STATE_TICKING) + return ABORT_MOVE; + if(grabbed) + return FORCE_MOVE; + return WalkingBadguy::collision_player(player, hit); +} + +HitResponse +GoldBomb::collision_badguy(BadGuy& badguy, const CollisionHit& hit) +{ + if(tstate == STATE_TICKING) + return ABORT_MOVE; + return WalkingBadguy::collision_badguy(badguy, hit); +} + +bool +GoldBomb::collision_squished(GameObject& object) +{ + Player* player = dynamic_cast(&object); + if(player && player->is_invincible()) { + player->bounce(*this); + kill_fall(); + return true; + } + if(is_valid() && tstate == STATE_NORMAL) { + tstate = STATE_TICKING; + frozen = false; + set_action(dir == LEFT ? "ticking-left" : "ticking-right", 1); + physic.set_velocity_x(0); + + if (player) + player->bounce(*this); + + ticking.reset(sound_manager->create_sound_source("sounds/fizz.wav")); + ticking->set_position(get_pos()); + ticking->set_looping(true); + ticking->set_gain(2.0); + ticking->set_reference_distance(32); + ticking->play(); + } + return true; +} + +void +GoldBomb::active_update(float elapsed_time) +{ + if(tstate == STATE_TICKING) { + ticking->set_position(get_pos()); + if(sprite->animation_done()) { + kill_fall(); + } + else if (!grabbed) { + movement = physic.get_movement(elapsed_time); + } + return; + } + if(grabbed) + return; + WalkingBadguy::active_update(elapsed_time); +} + +void +GoldBomb::kill_fall() +{ + if(tstate == STATE_TICKING) + ticking->stop(); + + // Make the player let go before we explode, otherwise the player is holding + // an invalid object. There's probably a better way to do this than in the + // GoldBomb class. + if (grabber != NULL) { + Player* player = dynamic_cast(grabber); + + if (player) + player->stop_grabbing(); + } + + if(is_valid()) { + remove_me(); + Sector::current()->add_object(new Explosion(get_bbox().get_middle())); + Sector::current()->add_object(new CoinExplode(get_pos() + Vector (0, -40), 1)); + } + + run_dead_script(); +} + +void +GoldBomb::grab(MovingObject& object, const Vector& pos, Direction dir) +{ + if(tstate == STATE_TICKING){ + movement = pos - get_pos(); + this->dir = dir; + + // We actually face the opposite direction of Tux here to make the fuse more + // visible instead of hiding it behind Tux + sprite->set_action_continued(dir == LEFT ? "ticking-right" : "ticking-left"); + set_colgroup_active(COLGROUP_DISABLED); + grabbed = true; + grabber = &object; + } + else if(frozen){ + movement = pos - get_pos(); + this->dir = dir; + sprite->set_action(dir == LEFT ? "iced-left" : "iced-right"); + set_colgroup_active(COLGROUP_DISABLED); + grabbed = true; + } +} + +void +GoldBomb::ungrab(MovingObject& object, Direction dir) +{ + int toss_velocity_x = 0; + int toss_velocity_y = 0; + Player* player = dynamic_cast (&object); + + // toss upwards + if(dir == UP) + toss_velocity_y += -500; + + // toss to the side when moving sideways + if(player && player->physic.get_velocity_x()*(dir == LEFT ? -1 : 1) > 1) { + toss_velocity_x += (dir == LEFT) ? -200 : 200; + toss_velocity_y = (toss_velocity_y < -200) ? toss_velocity_y : -200; + // toss farther when running + if(player && player->physic.get_velocity_x()*(dir == LEFT ? -1 : 1) > 200) + toss_velocity_x += player->physic.get_velocity_x()-(190*(dir == LEFT ? -1 : 1)); + } + log_warning << toss_velocity_x << toss_velocity_y << std::endl;//// + + //set_pos(object.get_pos() + Vector((dir == LEFT ? -33 : 33), get_bbox().get_height()*0.66666 - 32)); + physic.set_velocity(toss_velocity_x, toss_velocity_y); + set_colgroup_active(COLGROUP_MOVING); + grabbed = false; +} + +void +GoldBomb::freeze() +{ + if(tstate == STATE_NORMAL){ + WalkingBadguy::freeze(); + sprite->set_action(dir == LEFT ? "iced-left" : "iced-right"); + } +} + +bool +GoldBomb::is_freezable() const +{ + return true; +} + +bool +GoldBomb::is_portable() const +{ + return (frozen || (tstate == STATE_TICKING)); +} + +/* EOF */ diff --git a/src/badguy/goldbomb.hpp b/src/badguy/goldbomb.hpp new file mode 100644 index 000000000..d82d28e5a --- /dev/null +++ b/src/badguy/goldbomb.hpp @@ -0,0 +1,67 @@ +// SuperTux BadGuy GoldBomb - a bomb that throws up coins when exploding +// Copyright (C) 2006 Matthias Braun +// Copyright (C) 2013 LMH +// +// 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_BADGUY_GOLDBOMB_HPP +#define HEADER_SUPERTUX_BADGUY_GOLDBOMB_HPP + +#include "audio/sound_source.hpp" +#include "badguy/walking_badguy.hpp" +#include "object/portable.hpp" + +class GoldBomb : public WalkingBadguy, public Portable +{ +public: + GoldBomb(const Reader& reader); + + void collision_solid(const CollisionHit& hit); + HitResponse collision(GameObject& object, const CollisionHit& hit); + HitResponse collision_player(Player& player, const CollisionHit& hit); + HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit); + + void active_update(float elapsed_time); + + void grab(MovingObject& object, const Vector& pos, Direction dir); + void ungrab(MovingObject& object, Direction dir); + bool is_portable() const; + + void freeze(); + bool is_freezable() const; + + void kill_fall(); + +protected: + bool collision_squished(GameObject& object); + +private: + GoldBomb(const GoldBomb&); + GoldBomb& operator=(const GoldBomb&); + enum Ticking_State { + STATE_NORMAL, + STATE_TICKING + }; + + Ticking_State tstate; + bool grabbed; + MovingObject* grabber; + + std::auto_ptr ticking; +}; + +#endif + +/* EOF */ diff --git a/src/supertux/level.cpp b/src/supertux/level.cpp index fbd16c3bb..0d78d531d 100644 --- a/src/supertux/level.cpp +++ b/src/supertux/level.cpp @@ -16,6 +16,7 @@ #include "supertux/level.hpp" +#include "badguy/goldbomb.hpp" #include "lisp/list_iterator.hpp" #include "lisp/parser.hpp" #include "object/bonus_block.hpp" @@ -210,15 +211,10 @@ Level::get_total_coins() total_coins += 10; continue; } -#if 0 - // FIXME: do we want this? q.v. src/object/oneup.cpp - else if (block->contents == BonusBlock::CONTENT_1UP) - { - total_coins += 100; - continue; - } -#endif } + GoldBomb *goldbomb = dynamic_cast (*o); + if(goldbomb) + total_coins += 10; } } return total_coins; diff --git a/src/supertux/object_factory.cpp b/src/supertux/object_factory.cpp index 42fe3445a..d08e1f768 100644 --- a/src/supertux/object_factory.cpp +++ b/src/supertux/object_factory.cpp @@ -37,6 +37,7 @@ #include "badguy/flame.hpp" #include "badguy/flyingsnowball.hpp" #include "badguy/ghosttree.hpp" +#include "badguy/goldbomb.hpp" #include "badguy/haywire.hpp" #include "badguy/igel.hpp" #include "badguy/jumpy.hpp" @@ -189,6 +190,7 @@ ObjectFactory::init_factories() add_factory("flame"); add_factory("flyingsnowball"); add_factory("ghosttree"); + add_factory("goldbomb"); add_factory("haywire"); add_factory("igel"); add_factory("jumpy");