From a564bdaf72edefea95ad768330131a009f1be37d Mon Sep 17 00:00:00 2001 From: Christoph Sommer Date: Sun, 27 May 2007 21:51:46 +0000 Subject: [PATCH] Platforms without a name that start with "running" set to false will now pick destinations automatically SVN-Revision: 5064 --- data/levels/world2/christoph2.stl | 152 -------------------------------------- data/levels/world2/christophA.stl | 49 ------------ src/object/path.cpp | 33 +++++++++ src/object/path.hpp | 10 +++ src/object/path_walker.hpp | 5 ++ src/object/platform.cpp | 49 +++++++++++- src/object/platform.hpp | 6 ++ 7 files changed, 100 insertions(+), 204 deletions(-) diff --git a/data/levels/world2/christoph2.stl b/data/levels/world2/christoph2.stl index 332999c4b..f92dede57 100644 --- a/data/levels/world2/christoph2.stl +++ b/data/levels/world2/christoph2.stl @@ -34,7 +34,6 @@ (y 1967) ) (platform - (name "elev1") (running #f) (sprite "images/objects/platforms/big.sprite") (path @@ -46,16 +45,11 @@ (node (x 1984) (y 1152) - ) - (node - (x 1984) - (y 1152) (time 3) ) ) ) (platform - (name "elev2") (running #f) (sprite "images/objects/platforms/big.sprite") (path @@ -67,16 +61,11 @@ (node (x 1856) (y 1152) - ) - (node - (x 1856) - (y 1152) (time 3) ) ) ) (platform - (name "elev3") (running #f) (sprite "images/objects/flying_platform/flying_platform.sprite") (path @@ -88,16 +77,11 @@ (node (x 896) (y 288) - ) - (node - (x 896) - (y 288) (time 2) ) ) ) (platform - (name "elev6") (running #f) (sprite "images/objects/platforms/big.sprite") (path @@ -114,7 +98,6 @@ ) ) (platform - (name "elev7") (running #f) (sprite "images/objects/flying_platform/flying_platform.sprite") (path @@ -242,141 +225,6 @@ (x 5991.881) (y 1384.084) ) - (scripttrigger - (script "elev1.goto_node(2); -elev2.goto_node(2); -elev1.goto_node(0); -elev2.goto_node(0); -") - (button #f) - (width 64) - (height 32) - (x 2016) - (y 1536) - ) - (scripttrigger - (script "elev1.goto_node(2); -elev2.goto_node(2); -elev1.goto_node(0); -elev2.goto_node(0); -") - (button #f) - (width 376) - (height 152) - (x 1812) - (y 1012) - ) - (scripttrigger - (script "elev3.goto_node(1); -elev3.goto_node(0); -") - (button #f) - (width 64) - (height 32) - (x 928) - (y 704) - ) - (scripttrigger - (script "elev6.goto_node(1);") - (button #f) - (width 128) - (height 32) - (x 5920) - (y 2112) - ) - (scripttrigger - (script "elev6.goto_node(0); -") - (button #f) - (width 256) - (height 64) - (x 5760) - (y 2080) - ) - (scripttrigger - (script "elev6.goto_node(0); -") - (button #f) - (width 128) - (height 32) - (x 6720) - (y 2112) - ) - (scripttrigger - (script "elev6.goto_node(1); -") - (button #f) - (width 256) - (height 64) - (x 6752) - (y 2080) - ) - (scripttrigger - (script "elev7.goto_node(1); -") - (button #f) - (width 128) - (height 32) - (x 4480) - (y 480) - ) - (scripttrigger - (script "elev7.goto_node(0); -") - (button #f) - (width 256) - (height 64) - (x 4320) - (y 448) - ) - (scripttrigger - (script "elev7.goto_node(0); -") - (button #f) - (width 128) - (height 32) - (x 6464) - (y 480) - ) - (scripttrigger - (script "elev7.goto_node(1); -") - (button #f) - (width 256) - (height 64) - (x 6496) - (y 448) - ) - (scripttrigger - (script "elev7.goto_node(1); -") - (button #f) - (width 1092.66) - (height 32) - (x 5762.074) - (y 877.9238) - ) - (scripttrigger - (script "elev7.goto_node(0); -") - (button #f) - (width 1316) - (height 32) - (x 4192) - (y 864) - ) - (scripttrigger - (script "elev1.goto_node(2); -elev2.goto_node(2); -elev1.goto_node(0); -elev2.goto_node(0); -") - (button #f) - (width 64) - (height 32) - (x 1888) - (y 704) - ) (secretarea (width 111.196) (height 167.7644) diff --git a/data/levels/world2/christophA.stl b/data/levels/world2/christophA.stl index dd42e06d3..37f09f2f8 100644 --- a/data/levels/world2/christophA.stl +++ b/data/levels/world2/christophA.stl @@ -53,7 +53,6 @@ (y 1408) ) (platform - (name "plat1") (running #f) (sprite "images/objects/flying_platform/flying_platform.sprite") (path @@ -127,54 +126,6 @@ wind1h.start(); (y 1714) ) (scripttrigger - (script "plat1.goto_node(0);") - (button #f) - (width 256) - (height 32) - (x 2720) - (y 1312) - ) - (scripttrigger - (script "plat1.goto_node(0);") - (button #f) - (width 32) - (height 348) - (x 2048) - (y 1088) - ) - (scripttrigger - (script "plat1.goto_node(1);") - (button #f) - (width 256) - (height 32) - (x 2336) - (y 1312) - ) - (scripttrigger - (script "plat1.goto_node(0);") - (button #f) - (width 256) - (height 64) - (x 2208) - (y 1280) - ) - (scripttrigger - (script "plat1.goto_node(1);") - (button #f) - (width 256) - (height 64) - (x 2848) - (y 1280) - ) - (scripttrigger - (script "plat1.goto_node(1);") - (button #f) - (width 32) - (height 348) - (x 3392) - (y 1216) - ) - (scripttrigger (script "wind1a.start(); wind1b.start(); wind1c.start(); diff --git a/src/object/path.cpp b/src/object/path.cpp index b7a34af8e..5d7e88a7d 100644 --- a/src/object/path.cpp +++ b/src/object/path.cpp @@ -134,3 +134,36 @@ Path::get_base() const return nodes[0].position; } + +int +Path::get_nearest_node_no(Vector reference_point) const +{ + int nearest_node_id = -1; + float nearest_node_dist = 0; + int id = 0; + for (std::vector::const_iterator i = nodes.begin(); i != nodes.end(); i++, id++) { + float dist = (i->position - reference_point).norm(); + if ((nearest_node_id == -1) || (dist < nearest_node_dist)) { + nearest_node_id = id; + nearest_node_dist = dist; + } + } + return nearest_node_id; +} + +int +Path::get_farthest_node_no(Vector reference_point) const +{ + int farthest_node_id = -1; + float farthest_node_dist = 0; + int id = 0; + for (std::vector::const_iterator i = nodes.begin(); i != nodes.end(); i++, id++) { + float dist = (i->position - reference_point).norm(); + if ((farthest_node_id == -1) || (dist > farthest_node_dist)) { + farthest_node_id = id; + farthest_node_dist = dist; + } + } + return farthest_node_id; +} + diff --git a/src/object/path.hpp b/src/object/path.hpp index f599c760f..ff17c4e4f 100644 --- a/src/object/path.hpp +++ b/src/object/path.hpp @@ -50,6 +50,16 @@ public: std::vector nodes; + /** + * returns Node index nearest to reference_point or -1 if not applicable + */ + int get_nearest_node_no(Vector reference_point) const; + + /** + * returns Node index farthest from reference_point or -1 if not applicable + */ + int get_farthest_node_no(Vector reference_point) const; + private: friend class PathWalker; diff --git a/src/object/path_walker.hpp b/src/object/path_walker.hpp index f3bdf9e6e..829eca175 100644 --- a/src/object/path_walker.hpp +++ b/src/object/path_walker.hpp @@ -50,6 +50,11 @@ public: /** stop advancing automatically */ void stop_moving(); + /** returns true if PathWalker is currently moving */ + bool is_moving() { + return running; + } + const Path* path; private: diff --git a/src/object/platform.cpp b/src/object/platform.cpp index b017ca447..c6a2da656 100644 --- a/src/object/platform.cpp +++ b/src/object/platform.cpp @@ -33,13 +33,17 @@ #include "object_factory.hpp" #include "scripting/platform.hpp" #include "scripting/squirrel_util.hpp" +#include "sector.hpp" Platform::Platform(const lisp::Lisp& reader) - : MovingSprite(reader, Vector(0,0), LAYER_OBJECTS, COLGROUP_STATIC), speed(Vector(0,0)) + : MovingSprite(reader, Vector(0,0), LAYER_OBJECTS, COLGROUP_STATIC), + speed(Vector(0,0)), + automatic(false), player_contact(false), last_player_contact(false) { bool running = true; reader.get("name", name); reader.get("running", running); + if ((name == "") && (!running)) automatic=true; const lisp::Lisp* pathLisp = reader.get_lisp("path"); if(pathLisp == NULL) throw std::runtime_error("No path specified for platform"); @@ -50,7 +54,9 @@ Platform::Platform(const lisp::Lisp& reader) } Platform::Platform(const Platform& other) - : MovingSprite(other), ScriptInterface(other), speed(other.speed) + : MovingSprite(other), ScriptInterface(other), + speed(other.speed), + automatic(other.automatic), player_contact(false), last_player_contact(false) { name = other.name; path.reset(new Path(*other.path)); @@ -59,14 +65,51 @@ Platform::Platform(const Platform& other) } HitResponse -Platform::collision(GameObject& , const CollisionHit& ) +Platform::collision(GameObject& other, const CollisionHit& ) { + if (dynamic_cast(&other)) player_contact = true; return FORCE_MOVE; } void Platform::update(float elapsed_time) { + // check if Platform should automatically pick a destination + if (automatic) { + + if (!player_contact && !walker->is_moving()) { + // Player doesn't touch platform and Platform is not moving + + // Travel to node nearest to nearest player + // FIXME: does not really use nearest player + Player* player = 0; + std::vector players = Sector::current()->get_players(); + for (std::vector::iterator playerIter = players.begin(); playerIter != players.end(); ++playerIter) { + player = *playerIter; + } + if (player) { + int nearest_node_id = path->get_nearest_node_no(player->get_bbox().p2); + if (nearest_node_id != -1) { + goto_node(nearest_node_id); + } + } + } + + if (player_contact && !last_player_contact && !walker->is_moving()) { + // Player touched platform, didn't touch last frame and Platform is not moving + + // Travel to node farthest from current position + int farthest_node_id = path->get_farthest_node_no(get_pos()); + if (farthest_node_id != -1) { + goto_node(farthest_node_id); + } + } + + // Clear player_contact flag set by collision() method + last_player_contact = player_contact; + player_contact = false; + } + movement = walker->advance(elapsed_time) - get_pos(); speed = movement / elapsed_time; } diff --git a/src/object/platform.hpp b/src/object/platform.hpp index a9567ed08..06456a7b5 100644 --- a/src/object/platform.hpp +++ b/src/object/platform.hpp @@ -39,6 +39,7 @@ public: virtual HitResponse collision(GameObject& other, const CollisionHit& hit); virtual void update(float elapsed_time); + const Vector& get_speed() const { return speed; @@ -72,8 +73,13 @@ public: private: std::auto_ptr path; std::auto_ptr walker; + Vector speed; + bool automatic; /**< true if Platform will automatically pick a destination based on collisions and current Player position */ + bool player_contact; /**< true if a Player touched the Platform during the last round of collision detections */ + bool last_player_contact; /**< true if a Player touched the Platform during the round before the last round of collision detections */ + }; #endif -- 2.11.0