From 62b51e460d44157cc3d0ef63312a437398d8a64d Mon Sep 17 00:00:00 2001 From: fuzzie Date: Mon, 28 Apr 2008 19:44:17 +0000 Subject: [PATCH] add wraparound support to C2 physics git-svn-id: svn://openc2e.ccdevnet.org/openc2e/trunk@1837 5a3b5b51-85f2-0310-b56e-886e3cf1dda3 --- Agent.cpp | 39 ++++++++++++++++++++++++++++++--------- Agent.h | 4 ++-- SkeletalCreature.cpp | 12 ++++++++---- caosVM_motion.cpp | 5 ++++- 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/Agent.cpp b/Agent.cpp index d4ea8cd..6e2eb72 100644 --- a/Agent.cpp +++ b/Agent.cpp @@ -465,6 +465,8 @@ bool Agent::validInRoomSystem() { bool const Agent::validInRoomSystem(Point p, unsigned int w, unsigned int h, int testperm) { // Return true if this agent is inside the world room system at the specified point, or false if it isn't. + MetaRoom *m = world.map.metaRoomAt(x, y); + if (!m) return false; for (unsigned int i = 0; i < 4; i++) { Point src, dest; @@ -488,14 +490,14 @@ bool const Agent::validInRoomSystem(Point p, unsigned int w, unsigned int h, int // TODO: check suffercollisions? // TODO: muh, provided direction here is kinda a hack - findCollisionInDirection((i < 2) ? 3 : 2, src, dx, dy, deltapt, delta, collided, true); + findCollisionInDirection((i < 2) ? 3 : 2, m, src, dx, dy, deltapt, delta, collided, true); if (collided) return false; } else { // Creatures 3 physics float srcx = src.x, srcy = src.y; - shared_ptr ourRoom = world.map.roomAt(srcx, srcy); + shared_ptr ourRoom = m->roomAt(srcx, srcy); if (!ourRoom) return false; unsigned int dir; Line wall; @@ -672,8 +674,8 @@ void Agent::physicsTick() { } } -shared_ptr const Agent::bestRoomAt(unsigned int tryx, unsigned int tryy, unsigned int direction, shared_ptr exclude) { - std::vector > rooms = world.map.roomsAt(tryx, tryy); +shared_ptr const Agent::bestRoomAt(unsigned int tryx, unsigned int tryy, unsigned int direction, MetaRoom *m, shared_ptr exclude) { + std::vector > rooms = m->roomsAt(tryx, tryy); shared_ptr r; @@ -703,11 +705,16 @@ shared_ptr const Agent::bestRoomAt(unsigned int tryx, unsigned int tryy, u } // Creatures 2 collision finding -void const Agent::findCollisionInDirection(unsigned int i, Point src, int &dx, int &dy, Point &deltapt, double &delta, bool &collided, bool followrooms) { +void const Agent::findCollisionInDirection(unsigned int i, class MetaRoom *m, Point src, int &dx, int &dy, Point &deltapt, double &delta, bool &collided, bool followrooms) { src.x = (int)src.x; src.y = (int)src.y; - - shared_ptr room = bestRoomAt(src.x, src.y, i, shared_ptr()); + + if (m->wraparound()) { + if (src.x > m->x() + m->width() || (dx > 0 && src.x == m->x() + m->width())) src.x -= m->width(); + else if (src.x < m->x() || (dx < 0 && src.x == m->x())) src.x += m->width(); + } + + shared_ptr room = bestRoomAt(src.x, src.y, i, m, shared_ptr()); if (!room) { // out of room system if (!displaycore) @@ -756,7 +763,12 @@ void const Agent::findCollisionInDirection(unsigned int i, Point src, int &dx, i // find the next room, if necessary, and work out whether we should move into it or break out if (endofroom) { - shared_ptr newroom = bestRoomAt(src.x + p.x, src.y + p.y, i, room); + if (m->wraparound()) { + if (dx > 0 && src.x + p.x >= m->x() + m->width()) src.x -= m->width(); + else if (dx < 0 && src.x + p.x <= m->x()) src.x += m->width(); + } + + shared_ptr newroom = bestRoomAt(src.x + p.x, src.y + p.y, i, m, room); bool collision = false; @@ -834,9 +846,18 @@ void Agent::physicsTickC2() { bool collided = false; if (suffercollisions()) { + MetaRoom *m = world.map.metaRoomAt(x, y); + if (!m) { + if (!displaycore) + unhandledException(boost::str(boost::format("out of room system at (%f, %f)") % x % y), false); + grav.setInt(0); + displaycore = true; + return; + } + for (unsigned int i = 0; i < 4; i++) { Point src = boundingBoxPoint(i); - findCollisionInDirection(i, src, dx, dy, deltapt, delta, collided, true); + findCollisionInDirection(i, m, src, dx, dy, deltapt, delta, collided, true); } } else { deltapt.x = dx; diff --git a/Agent.h b/Agent.h index 87f9758..c7dab39 100644 --- a/Agent.h +++ b/Agent.h @@ -223,8 +223,8 @@ public: unsigned int getHeight() { return part(0)->getHeight(); } Point const boundingBoxPoint(unsigned int n); Point const boundingBoxPoint(unsigned int n, Point p, unsigned int w, unsigned int h); - shared_ptr const bestRoomAt(unsigned int x, unsigned int y, unsigned int direction, shared_ptr exclude); - void const findCollisionInDirection(unsigned int i, Point src, int &dx, int &dy, Point &deltapt, double &delta, bool &collided, bool followrooms); + shared_ptr const bestRoomAt(unsigned int x, unsigned int y, unsigned int direction, class MetaRoom *m, shared_ptr exclude); + void const findCollisionInDirection(unsigned int i, class MetaRoom *m, Point src, int &dx, int &dy, Point &deltapt, double &delta, bool &collided, bool followrooms); bool validInRoomSystem(); bool const validInRoomSystem(Point p, unsigned int w, unsigned int h, int testperm); diff --git a/SkeletalCreature.cpp b/SkeletalCreature.cpp index 4b407dd..30eea53 100644 --- a/SkeletalCreature.cpp +++ b/SkeletalCreature.cpp @@ -31,6 +31,7 @@ #include "World.h" #include "Engine.h" #include "Backend.h" +#include "MetaRoom.h" #include "Room.h" #include "creaturesImage.h" @@ -384,6 +385,9 @@ void SkeletalCreature::snapDownFoot() { float footx = x + attachmentX(orig_footpart, 1); float footy = y + attachmentY(orig_footpart, 1); + MetaRoom *m = world.map.metaRoomAt(x, y); + if (!m) return; // TODO: exceptiony death + shared_ptr newroom; if (downfootroom) { @@ -408,12 +412,12 @@ void SkeletalCreature::snapDownFoot() { } } } else { - newroom = bestRoomAt(footx, footy, 3, shared_ptr()); + newroom = bestRoomAt(footx, footy, 3, m, shared_ptr()); // insane emergency handling float newfooty = footy; while (!newroom && newfooty > (footy - 500.0f)) { - newroom = world.map.roomAt(footx, newfooty); + newroom = m->roomAt(footx, newfooty); newfooty--; } @@ -429,7 +433,7 @@ void SkeletalCreature::snapDownFoot() { if (!downfootroom /*|| !falling */) { // TODO: hackery to cope with scripts moving us, this needs handling correctly somewhere if (fabs(lastgoodfootx - attachmentX(orig_footpart, 1) - x) > 50.0f || fabs(lastgoodfooty - attachmentY(orig_footpart, 1) - y) > 50.0f) { - downfootroom = bestRoomAt(footx, footy, 3, shared_ptr()); + downfootroom = bestRoomAt(footx, footy, 3, m, shared_ptr()); if (downfootroom) { snapDownFoot(); return; @@ -447,7 +451,7 @@ void SkeletalCreature::snapDownFoot() { x = lastgoodfootx - attachmentX(orig_footpart, 1); footx = lastgoodfootx; footy = lastgoodfooty; - downfootroom = world.map.roomAt(footx, footy); + downfootroom = m->roomAt(footx, footy); queueScript(6); if (!downfootroom) { diff --git a/caosVM_motion.cpp b/caosVM_motion.cpp index b4482c1..3657309 100644 --- a/caosVM_motion.cpp +++ b/caosVM_motion.cpp @@ -207,7 +207,10 @@ void caosVM::v_OBST_c2() { double delta = 1000000000; bool collided = false; - targ->findCollisionInDirection(direction, src, dx, dy, deltapt, delta, collided, false); + MetaRoom *m = world.map.metaRoomAt(targ->x, targ->y); + caos_assert(m); + + targ->findCollisionInDirection(direction, m, src, dx, dy, deltapt, delta, collided, false); if (!collided) result.setInt(INT_MAX); -- 2.11.4.GIT