(y 1967)
)
(platform
- (name "elev1")
(running #f)
(sprite "images/objects/platforms/big.sprite")
(path
(node
(x 1984)
(y 1152)
- )
- (node
- (x 1984)
- (y 1152)
(time 3)
)
)
)
(platform
- (name "elev2")
(running #f)
(sprite "images/objects/platforms/big.sprite")
(path
(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
(node
(x 896)
(y 288)
- )
- (node
- (x 896)
- (y 288)
(time 2)
)
)
)
(platform
- (name "elev6")
(running #f)
(sprite "images/objects/platforms/big.sprite")
(path
)
)
(platform
- (name "elev7")
(running #f)
(sprite "images/objects/flying_platform/flying_platform.sprite")
(path
(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)
(y 1408)
)
(platform
- (name "plat1")
(running #f)
(sprite "images/objects/flying_platform/flying_platform.sprite")
(path
(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();
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<Node>::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<Node>::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;
+}
+
std::vector<Node> 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;
/** stop advancing automatically */
void stop_moving();
+ /** returns true if PathWalker is currently moving */
+ bool is_moving() {
+ return running;
+ }
+
const Path* path;
private:
#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");
}
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));
}
HitResponse
-Platform::collision(GameObject& , const CollisionHit& )
+Platform::collision(GameObject& other, const CollisionHit& )
{
+ if (dynamic_cast<Player*>(&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<Player*> players = Sector::current()->get_players();
+ for (std::vector<Player*>::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;
}
virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
virtual void update(float elapsed_time);
+
const Vector& get_speed() const
{
return speed;
private:
std::auto_ptr<Path> path;
std::auto_ptr<PathWalker> 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