From: Ryan Flegel Date: Mon, 9 Jun 2008 00:34:21 +0000 (+0000) Subject: Based off of mathnerd314's patch to fix issue #327 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=1a36ad149a4ee89a601d523878d168ed3b68ae62;p=supertux.git Based off of mathnerd314's patch to fix issue #327 - Dispensers can now support multiple badguys instead of just 'random' - badguys can be dispensed randomly or in sequence - dispenser type must now be specified as 'dropper', 'rocket-launcher' or 'cannon'. defaults to 'dropper' if not specified. SVN-Revision: 5539 --- diff --git a/data/levels/test/snowslope.stl b/data/levels/test/snowslope.stl index 4f70c75c2..510c59143 100644 --- a/data/levels/test/snowslope.stl +++ b/data/levels/test/snowslope.stl @@ -31,7 +31,7 @@ (y 709) (random #t) (type "cannon") - (badguy "kamikazesnowball") + (badguy "captainsnowball" "kamikazesnowball") ) (fish (x 1954) diff --git a/data/levels/test_old/direction.stl b/data/levels/test_old/direction.stl index f49da019c..0f25b1ba0 100644 --- a/data/levels/test_old/direction.stl +++ b/data/levels/test_old/direction.stl @@ -164,6 +164,7 @@ (y 128) ) (dispenser + (type "rocket-launcher") (badguy "mrrocket") (cycle 1) (direction "left") @@ -171,6 +172,7 @@ (y 996.4092) ) (dispenser + (type "rocket-launcher") (badguy "mrrocket") (cycle 1) (direction "right") diff --git a/data/levels/test_old/noloktest.stl b/data/levels/test_old/noloktest.stl index 4e41281f4..1f458b1c9 100644 --- a/data/levels/test_old/noloktest.stl +++ b/data/levels/test_old/noloktest.stl @@ -49,7 +49,7 @@ (speed 0.5)) (spawnpoint (name "main2") (x 100) (y 100)) (secretarea (x 100) (y 100) (message "You found a secret area!")) - (dispenser (x 700) (y 500) (badguy "mrrocket") (cycle 2)) + (dispenser (x 700) (y 500) (type "rocket-launcher") (badguy "mrrocket") (cycle 2)) (jumpy (x 500) (y 400)) (tilemap (z-pos -100) diff --git a/data/levels/world2/christoph9.stl b/data/levels/world2/christoph9.stl index 973162a18..5add1411f 100644 --- a/data/levels/world2/christoph9.stl +++ b/data/levels/world2/christoph9.stl @@ -20,66 +20,77 @@ (cycle 3) (x 1824) (y 2348) + (type "rocket-launcher") (badguy "mrrocket") ) (dispenser (cycle 3) (x 4315.086) (y 588.6605) + (type "rocket-launcher") (badguy "mrrocket") ) (dispenser (cycle 3) (x 2844.737) (y 556.2125) + (type "rocket-launcher") (badguy "mrrocket") ) (dispenser (cycle 3) (x 5498.62) (y 1931.435) + (type "rocket-launcher") (badguy "mrrocket") ) (dispenser (cycle 4) (x 5499.327) (y 2347.921) + (type "rocket-launcher") (badguy "mrrocket") ) (dispenser (cycle 3) (x 1825.651) (y 1004.293) + (type "rocket-launcher") (badguy "mrrocket") ) (dispenser (cycle 4) (x 5499.327) (y 2571.367) + (type "rocket-launcher") (badguy "mrrocket") ) (dispenser (cycle 3) (x 5435.688) (y 1997.196) + (type "rocket-launcher") (badguy "mrrocket") ) (dispenser (cycle 3) (x 1849.266) (y 1932.47) + (type "rocket-launcher") (badguy "mrrocket") ) (dispenser (cycle 3) (x 1825.237) (y 1324.32) + (type "rocket-launcher") (badguy "mrrocket") ) (dispenser (cycle 3) (x 1825.944) (y 1164.807) + (type "rocket-launcher") (badguy "mrrocket") ) (firefly diff --git a/data/levels/world2/level2.stl b/data/levels/world2/level2.stl index d1143575e..19757174c 100644 --- a/data/levels/world2/level2.stl +++ b/data/levels/world2/level2.stl @@ -22,6 +22,7 @@ (x 10239) (y 165) (direction left) + (type "rocket-launcher") (badguy "mrrocket") ) (door diff --git a/src/badguy/captainsnowball.cpp b/src/badguy/captainsnowball.cpp index f1b433fc1..1c74ebb3d 100644 --- a/src/badguy/captainsnowball.cpp +++ b/src/badguy/captainsnowball.cpp @@ -30,8 +30,9 @@ namespace{ CaptainSnowball::CaptainSnowball(const lisp::Lisp& reader) : WalkingBadguy(reader, "images/creatures/snowball/cpt-snowball.sprite", "left", "right") { - walk_speed = WALK_SPEED; // peg leg - max_drop_height = -1;// eye patch + walk_speed = BOARDING_SPEED; + max_drop_height = -1; + physic.set_velocity_y(-400); } CaptainSnowball::CaptainSnowball(const Vector& pos, Direction d) diff --git a/src/badguy/dispenser.cpp b/src/badguy/dispenser.cpp index 2a9d03e9e..d7c7b4eaf 100644 --- a/src/badguy/dispenser.cpp +++ b/src/badguy/dispenser.cpp @@ -21,16 +21,6 @@ #include "dispenser.hpp" #include "object/bullet.hpp" -#include "badguy/bouncing_snowball.hpp" -#include "badguy/snowball.hpp" -#include "badguy/mrbomb.hpp" -#include "badguy/mriceblock.hpp" -#include "badguy/mrrocket.hpp" -#include "badguy/poisonivy.hpp" -#include "badguy/snail.hpp" -#include "badguy/skullyhop.hpp" -#include "badguy/captainsnowball.hpp" -#include "badguy/kamikazesnowball.hpp" #include "random_generator.hpp" Dispenser::Dispenser(const lisp::Lisp& reader) @@ -39,21 +29,32 @@ Dispenser::Dispenser(const lisp::Lisp& reader) set_colgroup_active(COLGROUP_MOVING_STATIC); sound_manager->preload("sounds/squish.wav"); reader.get("cycle", cycle); - reader.get("badguy", badguy); + reader.get_vector("badguy", badguys); + random = false; // default + reader.get("random", random); + type = "dropper"; //default + reader.get("type", type); + next_badguy = 0; autotarget = false; swivel = false; broken = false; - if (badguy == "mrrocket") { - sprite->set_action(dir == LEFT ? "working-left" : "working-right"); - set_colgroup_active(COLGROUP_MOVING); //if this were COLGROUP_MOVING_STATIC MrRocket would explode on launch. - if( start_dir == AUTO ){ + + if (badguys.size() <= 0) + throw std::runtime_error("No badguys in dispenser."); + + if (type == "rocket-launcher") { + sprite->set_action(dir == LEFT ? "working-left" : "working-right"); + set_colgroup_active(COLGROUP_MOVING); //if this were COLGROUP_MOVING_STATIC MrRocket would explode on launch. + + if (start_dir == AUTO) { autotarget = true; - } - } else if ( badguy == "kamikazesnowball" || badguy == "captainsnowball" ) { - sprite->set_action("working"); + } + } else if (type == "cannon") { + sprite->set_action("working"); } else { sprite->set_action("dropper"); } + bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height()); countMe = false; } @@ -66,7 +67,9 @@ Dispenser::write(lisp::Writer& writer) writer.write_float("x", start_position.x); writer.write_float("y", start_position.y); writer.write_float("cycle", cycle); - writer.write_string("badguy", badguy); + writer.write_bool("random", random); + writer.write_string("type", type); + writer.write_string_vector("badguy", badguys); writer.end_list("dispenser"); } @@ -100,9 +103,10 @@ Dispenser::collision_squished(GameObject& object) { //Cannon launching MrRocket can be broken by jumping on it //other dispencers are not that fragile. - if (broken || badguy != "mrrocket") { + if (broken || type != "rocket-launcher") { return false; } + sprite->set_action(dir == LEFT ? "broken-left" : "broken-right"); dispense_timer.start(0); set_colgroup_active(COLGROUP_MOVING_STATIC); // Tux can stand on broken cannon. @@ -168,7 +172,6 @@ Dispenser::active_update(float ) } } -// Add themed randomizer void Dispenser::launch_badguy() { @@ -181,39 +184,31 @@ Dispenser::launch_badguy() launchdir = (player->get_pos().x > get_pos().x) ? RIGHT : LEFT; } } - if (badguy == "snowball") - Sector::current()->add_object(new SnowBall(Vector(get_pos().x, get_pos().y+32), launchdir)); - else if (badguy == "bouncingsnowball") - Sector::current()->add_object(new BouncingSnowball(Vector(get_pos().x, get_pos().y+32), launchdir)); - else if (badguy == "mrbomb") - Sector::current()->add_object(new MrBomb(Vector(get_pos().x, get_pos().y+32), launchdir)); - else if (badguy == "mriceblock") - Sector::current()->add_object(new MrIceBlock(Vector(get_pos().x, get_pos().y+32), launchdir)); - else if (badguy == "snail") - Sector::current()->add_object(new Snail(Vector(get_pos().x, get_pos().y+32), launchdir)); - else if (badguy == "mrrocket") - Sector::current()->add_object(new MrRocket(Vector(get_pos().x+(launchdir == LEFT ? -32 : 32), get_pos().y), launchdir)); - else if (badguy == "captainsnowball") - Sector::current()->add_object(new CaptainSnowball(Vector(get_pos().x+(launchdir == LEFT ? -32 : 32), get_pos().y), launchdir)); - else if (badguy == "kamikazesnowball") - Sector::current()->add_object(new KamikazeSnowball(Vector(get_pos().x+(launchdir == LEFT ? -32 : 32), get_pos().y), launchdir)); - else if (badguy == "poisonivy") - Sector::current()->add_object(new PoisonIvy(Vector(get_pos().x, get_pos().y+32), launchdir)); - else if (badguy == "skullyhop") - Sector::current()->add_object(new SkullyHop(Vector(get_pos().x, get_pos().y+44), launchdir)); - else if (badguy == "random") - { - switch (systemRandom.rand(7)) - { - case 0: Sector::current()->add_object(new SnowBall(Vector(get_pos().x, get_pos().y+32), launchdir)); break; - case 1: Sector::current()->add_object(new BouncingSnowball(Vector(get_pos().x, get_pos().y+32), launchdir)); break; - case 2: Sector::current()->add_object(new MrBomb(Vector(get_pos().x, get_pos().y+32), launchdir)); break; - case 3: Sector::current()->add_object(new MrIceBlock(Vector(get_pos().x, get_pos().y+32), launchdir)); break; - case 4: Sector::current()->add_object(new PoisonIvy(Vector(get_pos().x, get_pos().y+32), launchdir)); break; - case 5: Sector::current()->add_object(new Snail(Vector(get_pos().x, get_pos().y+32), launchdir)); break; - case 6: Sector::current()->add_object(new SkullyHop(Vector(get_pos().x, get_pos().y+44), launchdir)); break; + + if (badguys.size() > 1) { + if (random) { + next_badguy = systemRandom.rand(badguys.size()); + } + else { + next_badguy++; + + if (next_badguy >= badguys.size()) + next_badguy = 0; } } + + std::string badguy = badguys[next_badguy]; + GameObject* badguy_object = NULL; + + if (type == "dropper") + badguy_object = create_badguy_object(badguy, Vector(get_pos().x, get_pos().y+32), launchdir); + else if (type == "cannon") + badguy_object = create_badguy_object(badguy, Vector(get_pos().x + (launchdir == LEFT ? -32 : 32), get_pos().y), launchdir); + else if (type == "rocket-launcher") + badguy_object = create_badguy_object(badguy, Vector(get_pos().x + (launchdir == LEFT ? -32 : 32), get_pos().y), launchdir); + + if (badguy_object) + Sector::current()->add_object(badguy_object); } } diff --git a/src/badguy/dispenser.hpp b/src/badguy/dispenser.hpp index 38a26fe31..106607806 100644 --- a/src/badguy/dispenser.hpp +++ b/src/badguy/dispenser.hpp @@ -44,11 +44,14 @@ protected: HitResponse collision(GameObject& other, const CollisionHit& hit); void launch_badguy(); float cycle; - std::string badguy; + std::vector badguys; + unsigned int next_badguy; Timer dispense_timer; bool autotarget; bool swivel; bool broken; + bool random; + std::string type; }; #endif diff --git a/src/direction.cpp b/src/direction.cpp new file mode 100644 index 000000000..4ab1ccb67 --- /dev/null +++ b/src/direction.cpp @@ -0,0 +1,45 @@ +// $Id: direction.hpp 5006 2007-05-23 15:27:56Z tuxdev $ +// +// SuperTux +// Copyright (C) 2008 Ryan Flegel +// +// 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 2 +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. + +#include "direction.hpp" + +std::ostream& operator<<(std::ostream& o, const Direction& dir) +{ + switch (dir) + { + case AUTO: + o << "auto"; + break; + case LEFT: + o << "left"; + break; + case RIGHT: + o << "right"; + break; + case UP: + o << "up"; + break; + case DOWN: + o << "down"; + break; + } + + return o; +} diff --git a/src/direction.hpp b/src/direction.hpp index e665d2073..f4df937ea 100644 --- a/src/direction.hpp +++ b/src/direction.hpp @@ -20,6 +20,10 @@ #ifndef SUPERTUX_DIRECTION_H #define SUPERTUX_DIRECTION_H +#include + enum Direction { AUTO, LEFT, RIGHT, UP, DOWN }; +std::ostream& operator<<(std::ostream& o, const Direction& dir); + #endif diff --git a/src/object_factory.cpp b/src/object_factory.cpp index fe89724c4..667a12f36 100644 --- a/src/object_factory.cpp +++ b/src/object_factory.cpp @@ -42,13 +42,27 @@ GameObject* create_object(const std::string& name, const lisp::Lisp& reader) GameObject* create_object(const std::string& name, const Vector& pos) { std::stringstream lisptext; - lisptext << "(" << name - << " (x " << pos.x << ")" + lisptext << "((x " << pos.x << ")" << " (y " << pos.y << "))"; lisp::Parser parser; const lisp::Lisp* lisp = parser.parse(lisptext, "create_object"); - GameObject* object = create_object(name, *lisp); + GameObject* object = create_object(name, *(lisp->get_car())); return object; } + +GameObject* create_badguy_object(const std::string& name, const Vector& pos, const Direction dir) +{ + std::stringstream lisptext; + lisptext << "((x " << pos.x << ")" + << " (y " << pos.y << ")" + << " (direction " << dir << "))"; + + lisp::Parser parser; + const lisp::Lisp* lisp = parser.parse(lisptext, "create_object"); + GameObject* object = create_object(name, *(lisp->get_car())); + + return object; +} + diff --git a/src/object_factory.hpp b/src/object_factory.hpp index 0e0d0d350..40445d322 100644 --- a/src/object_factory.hpp +++ b/src/object_factory.hpp @@ -23,6 +23,8 @@ #include #include +#include "direction.hpp" + namespace lisp { class Lisp; } class Vector; class GameObject; @@ -48,6 +50,7 @@ public: GameObject* create_object(const std::string& name, const lisp::Lisp& reader); GameObject* create_object(const std::string& name, const Vector& pos); +GameObject* create_badguy_object(const std::string& name, const Vector& pos, Direction dir = LEFT); /** comment from Matze: * Yes I know macros are evil, but in this specific case they save