X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fbadguy%2Fkugelblitz.cpp;h=c1c774270ff66a842c42d915e63f1d3af50c271d;hb=79dacf66079bc6c0817d947c4ae922c8d4f75575;hp=d04f4e406cbd43c60d1a83cea3f66de0c716b13a;hpb=f2a72a6f94a20302df2a2d5675ba7a7b0f633c81;p=supertux.git diff --git a/src/badguy/kugelblitz.cpp b/src/badguy/kugelblitz.cpp index d04f4e406..c1c774270 100644 --- a/src/badguy/kugelblitz.cpp +++ b/src/badguy/kugelblitz.cpp @@ -1,84 +1,123 @@ -// $Id: Kugelblitz.cpp 2654 2005-06-29 14:16:22Z wansti $ -// // SuperTux -// Copyright (C) 2005 Marek Moeckel +// Copyright (C) 2006 Matthias Braun // -// 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 // 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 +// along with this program. If not, see . + +#include "badguy/kugelblitz.hpp" + +#include -#include "kugelblitz.hpp" +#include "math/random_generator.hpp" +#include "object/camera.hpp" +#include "object/player.hpp" +#include "sprite/sprite.hpp" +#include "sprite/sprite_manager.hpp" +#include "supertux/object_factory.hpp" +#include "supertux/sector.hpp" +#include "util/reader.hpp" -Kugelblitz::Kugelblitz(const lisp::Lisp& reader) - : groundhit_pos_set(false) +#define LIFETIME 5 +#define MOVETIME 0.75 +#define BASE_SPEED 200 +#define RAND_SPEED 150 + +Kugelblitz::Kugelblitz(const Reader& reader) : + BadGuy(reader, "images/creatures/kugelblitz/kugelblitz.sprite"), + pos_groundhit(), + groundhit_pos_set(false), + dying(), + movement_timer(), + lifetime(), + direction(), + state(), + light(0.0f,0.0f,0.0f), + lightsprite(sprite_manager->create("images/objects/lightmap_light/lightmap_light.sprite")) { reader.get("x", start_position.x); - start_position.y = 0; //place above visible area - bbox.set_size(63.8, 63.8); - sprite = sprite_manager->create("kugelblitz"); sprite->set_action("falling"); physic.enable_gravity(false); + countMe = false; + + lightsprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE)); + lightsprite->set_color(Color(0.2f, 0.1f, 0.0f)); } void -Kugelblitz::write(lisp::Writer& writer) +Kugelblitz::initialize() { - writer.start_list("kugelblitz"); - - writer.write_float("x", start_position.x); - writer.write_float("y", start_position.y); - - writer.end_list("kugelblitz"); + physic.set_velocity_y(300); + physic.set_velocity_x(-20); //fall a little to the left + direction = 1; + dying = false; } void -Kugelblitz::activate() +Kugelblitz::collision_solid(const CollisionHit& chit) { - physic.set_velocity_y(-300); - physic.set_velocity_x(-20); //fall a little to the left + hit(chit); } HitResponse -Kugelblitz::collision_solid(GameObject& other, const CollisionHit& chit) +Kugelblitz::collision_player(Player& player, const CollisionHit& ) { - return hit(chit); + if(player.is_invincible()) { + explode(); + return ABORT_MOVE; + } + // hit from above? + if(player.get_movement().y - get_movement().y > 0 && player.get_bbox().p2.y < + (get_bbox().p1.y + get_bbox().p2.y) / 2) { + // if it's not is it possible to squish us, then this will hurt + if(!collision_squished(player)) + player.kill(false); + explode(); + return FORCE_MOVE; + } + player.kill(false); + explode(); + return FORCE_MOVE; } HitResponse Kugelblitz::collision_badguy(BadGuy& other , const CollisionHit& chit) { - //Let the Kugelblitz explode, too? + //Let the Kugelblitz explode, too? The problem with that is that + //two Kugelblitzes would cancel each other out on contact... other.kill_fall(); return hit(chit); } HitResponse -Kugelblitz::hit(const CollisionHit& chit) +Kugelblitz::hit(const CollisionHit& hit) { // hit floor? - if(chit.normal.y < -.5) { + if(hit.bottom) { if (!groundhit_pos_set) { - pos_groundhit = get_pos(); //I'm leaving this in, we might need it here, too + pos_groundhit = get_pos(); groundhit_pos_set = true; } sprite->set_action("flying"); physic.set_velocity_y(0); - physic.set_velocity_x(100); + //Set random initial speed and direction + direction = gameRandom.rand(2)? 1: -1; + int speed = (BASE_SPEED + (gameRandom.rand(RAND_SPEED))) * direction; + physic.set_velocity_x(speed); + movement_timer.start(MOVETIME); + lifetime.start(LIFETIME); - } else if(chit.normal.y < .5) { // bumped on roof + } else if(hit.top) { // bumped on roof physic.set_velocity_y(0); } @@ -88,7 +127,95 @@ Kugelblitz::hit(const CollisionHit& chit) void Kugelblitz::active_update(float elapsed_time) { + if (lifetime.check()) { + explode(); + } + else { + if (groundhit_pos_set) { + if (movement_timer.check()) { + if (direction == 1) direction = -1; else direction = 1; + int speed = (BASE_SPEED + (gameRandom.rand(RAND_SPEED))) * direction; + physic.set_velocity_x(speed); + movement_timer.start(MOVETIME); + } + } + /* + if (Sector::current()->solids->get_tile_at(get_pos())->getAttributes() == 16) { + //HIT WATER + Sector::current()->add_object(new Electrifier(75,1421,1.5)); + Sector::current()->add_object(new Electrifier(76,1422,1.5)); + explode(); + } + if (Sector::current()->solids->get_tile_at(get_pos())->getAttributes() == 48) { + //HIT ELECTRIFIED WATER + explode(); + } + */ + } BadGuy::active_update(elapsed_time); } -IMPLEMENT_FACTORY(Kugelblitz, "kugelblitz") +void +Kugelblitz::draw(DrawingContext& context) +{ + sprite->draw(context, get_pos(), layer); + + //Only draw light in dark areas + context.get_light( get_bbox().get_middle(), &light ); + if (light.red + light.green < 2.0){ + context.push_target(); + context.set_target(DrawingContext::LIGHTMAP); + sprite->draw(context, get_pos(), layer); + lightsprite->draw(context, get_bbox().get_middle(), 0); + context.pop_target(); + } +} + +void +Kugelblitz::kill_fall() +{ +} + +void +Kugelblitz::explode() +{ + if (!dying) { + sprite->set_action("pop"); + lifetime.start(0.2f); + dying = true; + } + else remove_me(); +} + +void +Kugelblitz::try_activate() +{ + // Much smaller offscreen distances to pop out of nowhere and surprise Tux + float X_OFFSCREEN_DISTANCE = 400; + float Y_OFFSCREEN_DISTANCE = 600; + + Player* player = get_nearest_player(); + if (!player) return; + Vector dist = player->get_bbox().get_middle() - get_bbox().get_middle(); + if ((fabsf(dist.x) <= X_OFFSCREEN_DISTANCE) && (fabsf(dist.y) <= Y_OFFSCREEN_DISTANCE)) { + set_state(STATE_ACTIVE); + if (!is_initialized) { + + // if starting direction was set to AUTO, this is our chance to re-orient the badguy + if (start_dir == AUTO) { + Player* player = get_nearest_player(); + if (player && (player->get_bbox().p1.x > get_bbox().p2.x)) { + dir = RIGHT; + } else { + dir = LEFT; + } + } + + initialize(); + is_initialized = true; + } + activate(); + } +} + +/* EOF */