X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fsector.cpp;h=f5609fdae72eba8d5813706051ce9d1a7b79777a;hb=875ef8eb7e93726bc67dfa7f05da946250e588d4;hp=0dd15884b36374f70b9b6688d9f948d5dcc3219e;hpb=22e7accd3e335951d82850ec2e54563e67e1cf97;p=supertux.git diff --git a/src/sector.cpp b/src/sector.cpp index 0dd15884b..f5609fdae 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -46,7 +46,6 @@ #include "object/block.h" #include "object/invisible_block.h" #include "object/platform.h" -#include "trigger/door.h" #include "object/bullet.h" #include "badguy/jumpy.h" #include "badguy/snowball.h" @@ -54,6 +53,10 @@ #include "badguy/flame.h" #include "badguy/mriceblock.h" #include "badguy/mrbomb.h" +#include "badguy/dispenser.h" +#include "badguy/spike.h" +#include "badguy/nolok_01.h" +#include "trigger/door.h" #include "trigger/sequence_trigger.h" #include "trigger/secretarea_trigger.h" @@ -101,7 +104,7 @@ Sector *Sector::create(const std::string& name, size_t width, size_t height) } GameObject* -Sector::parseObject(const std::string& name, LispReader& reader) +Sector::parse_object(const std::string& name, LispReader& reader) { if(name == "background") { background = new Background(reader); @@ -152,6 +155,12 @@ Sector::parseObject(const std::string& name, LispReader& reader) return new MrIceBlock(reader); } else if(name == "mrbomb") { return new MrBomb(reader); + } else if(name == "dispenser") { + return new Dispenser(reader); + } else if(name == "spike") { + return new Spike(reader); + } else if(name == "nolok_01") { + return new Nolok_01(reader); } #if 0 else if(badguykind_from_string(name) != BAD_INVALID) { @@ -192,7 +201,7 @@ Sector::parse(LispReader& lispreader) reader.read_float("y", sp->pos.y); spawnpoints.push_back(sp); } else { - GameObject* object = parseObject(token, reader); + GameObject* object = parse_object(token, reader); if(object) { add_object(object); } @@ -327,7 +336,7 @@ Sector::parse_old_format(LispReader& reader) LispReader reader(lisp_cdr(data)); - GameObject* object = parseObject(object_type, reader); + GameObject* object = parse_object(object_type, reader); if(object) { add_object(object); } else { @@ -356,6 +365,18 @@ Sector::fix_old_tiles() if(tile->id == 112) { add_object(new InvisibleBlock(pos)); solids->change(x, y, 0); + } else if(tile->id == 295) { + add_object(new Spike(pos, Spike::NORTH)); + solids->change(x, y, 0); + } else if(tile->id == 296) { + add_object(new Spike(pos, Spike::EAST)); + solids->change(x, y, 0); + } else if(tile->id == 297) { + add_object(new Spike(pos, Spike::SOUTH)); + solids->change(x, y, 0); + } else if(tile->id == 298) { + add_object(new Spike(pos, Spike::WEST)); + solids->change(x, y, 0); } else if(tile->attributes & Tile::COIN) { add_object(new Coin(pos)); solids->change(x, y, 0); @@ -597,6 +618,8 @@ Sector::draw(DrawingContext& context) context.pop_transform(); } +static const float DELTA = .001; + void Sector::collision_tilemap(MovingObject* object, int depth) { @@ -635,7 +658,7 @@ Sector::collision_tilemap(MovingObject* object, int depth) CollisionHit temphit, hit; Rectangle dest = object->get_bbox(); dest.move(object->movement); - hit.depth = -1; + hit.time = -1; // represents an invalid value for(int x = starttilex; x*32 < max_x; ++x) { for(int y = starttiley; y*32 < max_y; ++y) { const Tile* tile = solids->get_tile(x, y); @@ -670,14 +693,14 @@ Sector::collision_tilemap(MovingObject* object, int depth) if(Collision::rectangle_aatriangle(temphit, dest, object->movement, triangle)) { - if(temphit.depth > hit.depth) + if(temphit.time > hit.time) hit = temphit; } } else { // normal rectangular tile Rectangle rect(x*32, y*32, (x+1)*32, (y+1)*32); if(Collision::rectangle_rectangle(temphit, dest, object->movement, rect)) { - if(temphit.depth > hit.depth) + if(temphit.time > hit.time) hit = temphit; } } @@ -685,7 +708,7 @@ Sector::collision_tilemap(MovingObject* object, int depth) } // did we collide at all? - if(hit.depth < 0) + if(hit.time < 0) return; // call collision function @@ -698,7 +721,7 @@ Sector::collision_tilemap(MovingObject* object, int depth) return; } // move out of collision and try again - object->movement += hit.normal * (hit.depth + .001); + object->movement += hit.normal * (hit.depth + DELTA); collision_tilemap(object, depth+1); } @@ -714,7 +737,6 @@ Sector::collision_object(MovingObject* object1, MovingObject* object2) Vector movement = object1->get_movement() - object2->get_movement(); if(Collision::rectangle_rectangle(hit, dest1, movement, dest2)) { HitResponse response1 = object1->collision(*object2, hit); - Vector hitnormal1 = hit.normal; hit.normal *= -1; HitResponse response2 = object2->collision(*object1, hit); @@ -722,15 +744,15 @@ Sector::collision_object(MovingObject* object1, MovingObject* object2) if(response1 == ABORT_MOVE) object1->movement = Vector(0, 0); if(response2 == CONTINUE) - object2->movement += hit.normal * (hit.depth + .1); + object2->movement += hit.normal * (hit.depth + DELTA); } else if(response2 != CONTINUE) { if(response2 == ABORT_MOVE) object2->movement = Vector(0, 0); if(response1 == CONTINUE) - object1->movement += hitnormal1 * (hit.depth + .1); + object1->movement += -hit.normal * (hit.depth + DELTA); } else { - object1->movement += hitnormal1 * (hit.depth/2 + 1); - object2->movement += hit.normal * (hit.depth/2 + 1); + object1->movement += -hit.normal * (hit.depth/2 + DELTA); + object2->movement += hit.normal * (hit.depth/2 + DELTA); } } } @@ -741,12 +763,16 @@ Sector::collision_handler() for(std::vector::iterator i = gameobjects.begin(); i != gameobjects.end(); ++i) { GameObject* gameobject = *i; - if(!gameobject->is_valid() - || gameobject->get_flags() & GameObject::FLAG_NO_COLLDET) + if(!gameobject->is_valid()) continue; MovingObject* movingobject = dynamic_cast (gameobject); if(!movingobject) continue; + if(movingobject->get_flags() & GameObject::FLAG_NO_COLLDET) { + movingobject->bbox.move(movingobject->movement); + movingobject->movement = Vector(0, 0); + continue; + } // collision with tilemap if(! (movingobject->movement == Vector(0, 0)))