X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fbadguy%2Figel.cpp;h=382aff4c75b9dba906272ee8944ecf730c7d09f6;hb=12a28b64dcce9c7ff706451b4f3aecd201cc8a5f;hp=880096548d5f6bafd3e2ac40036a5fb2167205ac;hpb=be79a2085027d3c990b621d1cf58fafaba1bcc67;p=supertux.git diff --git a/src/badguy/igel.cpp b/src/badguy/igel.cpp index 880096548..382aff4c7 100644 --- a/src/badguy/igel.cpp +++ b/src/badguy/igel.cpp @@ -1,12 +1,10 @@ -// $Id: igel.cpp 3478 2006-04-30 23:14:15Z sommer $ -// // SuperTux - Badguy "Igel" // Copyright (C) 2006 Christoph Sommer // -// 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 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 @@ -14,77 +12,49 @@ // 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 +// along with this program. If not, see . -#include "igel.hpp" -#include "object/block.hpp" -#include "sector.hpp" +#include "badguy/igel.hpp" #include "object/bullet.hpp" +#include "supertux/sector.hpp" + +#include "supertux/object_factory.hpp" namespace { - const float WALKSPEED = 80; /**< speed at which we walk around */ - const float TURN_RECOVER_TIME = 0.5; /**< seconds before we will again turn around when shot at */ - const float RANGE_OF_VISION = 256; /**< range in px at which we can see bullets */ -} -Igel::Igel(const lisp::Lisp& reader) - : state(STATE_NORMAL) -{ - reader.get("x", start_position.x); - reader.get("y", start_position.y); - sprite = sprite_manager->create("images/creatures/igel/igel.sprite"); - bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height()); - set_direction = false; -} +const float WALKSPEED = 80; /**< speed at which we walk around */ +const float TURN_RECOVER_TIME = 0.5; /**< seconds before we will again turn around when shot at */ +const float RANGE_OF_VISION = 256; /**< range in px at which we can see bullets */ -Igel::Igel(float pos_x, float pos_y, Direction d) - : state(STATE_NORMAL) -{ - start_position.x = pos_x; - start_position.y = pos_y; - sprite = sprite_manager->create("images/creatures/igel/igel.sprite"); - bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height()); - set_direction = true; - initial_direction = d; -} +} // namespace -void -Igel::write(lisp::Writer& writer) +Igel::Igel(const Reader& reader) : + WalkingBadguy(reader, "images/creatures/igel/igel.sprite", "walking-left", "walking-right"), + turn_recover_timer() { - writer.start_list("igel"); - - writer.write_float("x", start_position.x); - writer.write_float("y", start_position.y); - - writer.end_list("igel"); + walk_speed = WALKSPEED; + max_drop_height = 16; } -void -Igel::activate() +Igel::Igel(const Vector& pos, Direction d) : + WalkingBadguy(pos, d, "images/creatures/igel/igel.sprite", "walking-left", "walking-right"), + turn_recover_timer() { - if (set_direction) {dir = initial_direction;} - - be_normal(); + walk_speed = WALKSPEED; + max_drop_height = 16; } void Igel::be_normal() { - state = STATE_NORMAL; - sprite->set_action(dir == LEFT ? "walking-left" : "walking-right"); - - physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED); + initialize(); } void Igel::turn_around() { - dir = (dir == LEFT ? RIGHT : LEFT); + WalkingBadguy::turn_around(); turn_recover_timer.start(TURN_RECOVER_TIME); - be_normal(); } bool @@ -93,108 +63,59 @@ Igel::can_see(const MovingObject& o) Rect mb = get_bbox(); Rect ob = o.get_bbox(); - bool inReach_left = (ob.p2.x >= mb.p1.x-((dir == LEFT) ? RANGE_OF_VISION : 0)); - bool inReach_right = (ob.p1.x <= mb.p2.x+((dir == RIGHT) ? RANGE_OF_VISION : 0)); + bool inReach_left = ((ob.p2.x < mb.p1.x) && (ob.p2.x >= mb.p1.x-((dir == LEFT) ? RANGE_OF_VISION : 0))); + bool inReach_right = ((ob.p1.x > mb.p2.x) && (ob.p1.x <= mb.p2.x+((dir == RIGHT) ? RANGE_OF_VISION : 0))); bool inReach_top = (ob.p2.y >= mb.p1.y); bool inReach_bottom = (ob.p1.y <= mb.p2.y); - return (inReach_left && inReach_right && inReach_top && inReach_bottom); + return ((inReach_left || inReach_right) && inReach_top && inReach_bottom); } void Igel::active_update(float elapsed_time) { - switch (state) { - - case STATE_NORMAL: - if (might_fall()) { - // turn around when we are at a ledge - turn_around(); - } - else if (!turn_recover_timer.started()) { - // turn around when we see a Bullet - Sector* sector = Sector::current(); - for (Sector::GameObjects::iterator i = sector->gameobjects.begin(); i != sector->gameobjects.end(); ++i) { - Bullet* bullet = dynamic_cast(*i); - if (bullet) { - if (can_see(*bullet)) turn_around(); - } - } - } - break; - - } - - BadGuy::active_update(elapsed_time); -} - -HitResponse -Igel::collision_solid(GameObject& , const CollisionHit& hit) -{ - if(fabsf(hit.normal.y) > .5) { // floor or roof - physic.set_velocity_y(0); - return CONTINUE; + bool wants_to_flee = false; + + // check if we see a fire bullet + Sector* sector = Sector::current(); + for (Sector::GameObjects::iterator i = sector->gameobjects.begin(); i != sector->gameobjects.end(); ++i) { + Bullet* bullet = dynamic_cast(*i); + if (!bullet) continue; + if (bullet->get_type() != FIRE_BONUS) continue; + if (can_see(*bullet)) wants_to_flee = true; } - // hit left or right - switch(state) { - - case STATE_NORMAL: - turn_around(); - break; - + // if we flee, handle this ourselves + if (wants_to_flee && (!turn_recover_timer.started())) { + turn_around(); + BadGuy::active_update(elapsed_time); + return; } - return CONTINUE; + // else adhere to default behaviour + WalkingBadguy::active_update(elapsed_time); } HitResponse -Igel::collision_badguy(BadGuy& , const CollisionHit& hit) +Igel::collision_bullet(Bullet& bullet, const CollisionHit& hit) { - if(fabsf(hit.normal.y) > .5) { // floor or roof - physic.set_velocity_y(0); - return CONTINUE; - } - - // hit left or right - switch(state) { - - case STATE_NORMAL: - turn_around(); - break; - + // default reaction if hit on front side + if (((dir == LEFT) && hit.left) || ((dir == RIGHT) && hit.right)) { + return BadGuy::collision_bullet(bullet, hit); } - return CONTINUE; -} - -HitResponse -Igel::collision_bullet(Bullet& , const CollisionHit& hit) -{ - // die if hit on front side - if (((dir == LEFT) && (hit.normal.x > 0)) || ((dir == RIGHT) && (hit.normal.x < 0))) { - kill_fall(); - return ABORT_MOVE; - } - - // else ignore bullet + // else make bullet ricochet and ignore the hit + bullet.ricochet(*this, hit); return FORCE_MOVE; } bool -Igel::collision_squished(Player& ) +Igel::collision_squished(GameObject& ) { - switch(state) { - - case STATE_NORMAL: - // this will hurt - return false; - break; - - } - - kill_fall(); - return true; + // this will hurt + return false; } -IMPLEMENT_FACTORY(Igel, "igel") +IMPLEMENT_FACTORY(Igel, "igel"); + +/* EOF */