mirror of
https://github.com/projectPiki/pikmin2.git
synced 2024-11-23 05:20:06 +00:00
Cleanup pathfinding chicanery
This commit is contained in:
parent
79d53e7a5e
commit
a12750be55
@ -17,13 +17,14 @@ enum PathFindState {
|
||||
};
|
||||
|
||||
enum PathFindFlags {
|
||||
PATHFLAG_Unk1 = 0x1,
|
||||
PATHFLAG_PathThroughWater = 0x2,
|
||||
PATHFLAG_Unk3 = 0x4,
|
||||
PATHFLAG_Unk4 = 0x8,
|
||||
PATHFLAG_VsRed = 0x10,
|
||||
PATHFLAG_VsBlue = 0x20,
|
||||
PATHFLAG_InVersusMode = 0x40,
|
||||
PATHFLAG_RequireOpen = 0x1,
|
||||
PATHFLAG_PathThroughWater = 0x2,
|
||||
PATHFLAG_DisallowUnfinishedBridges = 0x4,
|
||||
PATHFLAG_Unk4 = 0x8,
|
||||
PATHFLAG_DisallowVsRed = 0x10,
|
||||
PATHFLAG_DisallowVsBlue = 0x20,
|
||||
PATHFLAG_AllowUnvisited = 0x40,
|
||||
PATHFLAG_TwoWayPathing = 0x80 // used for Panmodoki and BlackMan
|
||||
};
|
||||
|
||||
namespace PathfindContext {
|
||||
|
@ -44,15 +44,15 @@ struct WayPointLinks {
|
||||
|
||||
namespace Game {
|
||||
enum WayPointFlags {
|
||||
WPF_Unset = 0x00,
|
||||
WPF_Closed = 0x01,
|
||||
WPF_Water = 0x02,
|
||||
WPF_Bridge = 0x04,
|
||||
WPF_Unknown4 = 0x08,
|
||||
WPF_Unknown5 = 0x10,
|
||||
WPF_Unknown6 = 0x20,
|
||||
WPF_Unknown7 = 0x40,
|
||||
WPF_Unknown8 = 0x80
|
||||
WPF_Unset = 0x00,
|
||||
WPF_Closed = 0x01,
|
||||
WPF_Water = 0x02,
|
||||
WPF_Bridge = 0x04,
|
||||
WPF_Unknown4 = 0x08,
|
||||
WPF_VersusBlue = 0x10, // unused
|
||||
WPF_VersusRed = 0x20, // unused
|
||||
WPF_Unknown7 = 0x40,
|
||||
WPF_Unvisited = 0x80
|
||||
// There is an additional value for "visited", and probably values for vs
|
||||
// color
|
||||
};
|
||||
@ -170,7 +170,7 @@ struct WPEdgeSearchArg {
|
||||
inline bool isLinkedTo(s16 idx) { return mLinks ? mLinks->isLinkedTo(idx) : false; }
|
||||
|
||||
Vector3f mStartPosition; // _00
|
||||
bool mInWater; // _0C
|
||||
u8 mInWater; // _0C
|
||||
WayPointLinks* mLinks; // _10
|
||||
s16 mRoomID; // _14
|
||||
WayPoint* mWp1; // _18
|
||||
|
@ -1737,17 +1737,17 @@ void ActPathMove::initPathfinding(bool resetLinkCount)
|
||||
}
|
||||
mState = PATHMOVE_Pathfinding;
|
||||
|
||||
u8 flag = Game::PATHFLAG_Unk1;
|
||||
u8 flag = Game::PATHFLAG_RequireOpen;
|
||||
if (isAllBlue()) {
|
||||
flag |= Game::PATHFLAG_PathThroughWater;
|
||||
}
|
||||
|
||||
flag |= Game::PATHFLAG_Unk3;
|
||||
flag |= Game::PATHFLAG_DisallowUnfinishedBridges;
|
||||
if (Game::gameSystem && Game::gameSystem->isVersusMode()) {
|
||||
if (mOnyon->mOnyonType == ONYON_TYPE_BLUE) {
|
||||
flag |= (Game::PATHFLAG_VsBlue | Game::PATHFLAG_InVersusMode);
|
||||
flag |= (Game::PATHFLAG_DisallowVsRed | Game::PATHFLAG_AllowUnvisited);
|
||||
} else {
|
||||
flag |= (Game::PATHFLAG_VsRed | Game::PATHFLAG_InVersusMode);
|
||||
flag |= (Game::PATHFLAG_DisallowVsBlue | Game::PATHFLAG_AllowUnvisited);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1875,14 +1875,14 @@ int ActPathMove::execPathfinding()
|
||||
Game::testPathfinder->release(mContextHandle);
|
||||
}
|
||||
|
||||
u8 flag = (Game::PATHFLAG_PathThroughWater | Game::PATHFLAG_Unk3);
|
||||
u8 flag = (Game::PATHFLAG_PathThroughWater | Game::PATHFLAG_DisallowUnfinishedBridges);
|
||||
mStartPathFindCounter++;
|
||||
mState = PATHMOVE_Pathfinding;
|
||||
if (Game::gameSystem && Game::gameSystem->isVersusMode()) {
|
||||
flag |= Game::PATHFLAG_InVersusMode;
|
||||
flag |= Game::PATHFLAG_AllowUnvisited;
|
||||
}
|
||||
if (mStartPathFindCounter >= 2) {
|
||||
flag |= Game::PATHFLAG_InVersusMode; // hm
|
||||
flag |= Game::PATHFLAG_AllowUnvisited; // hm
|
||||
if (mStartPathFindCounter >= 3) {
|
||||
mStartPathFindCounter = 3;
|
||||
}
|
||||
@ -3098,7 +3098,7 @@ bool ActPathMove::contextCheck(int idx)
|
||||
Game::WayPoint* wp = getWayPoint(nextIdx);
|
||||
|
||||
if (mOnyon->mOnyonType == ONYON_TYPE_BLUE) {
|
||||
if (wp->isFlag(Game::WPF_Unknown6)) {
|
||||
if (wp->isFlag(Game::PATHFLAG_DisallowVsBlue)) {
|
||||
mVsWayPointCounter++;
|
||||
if (mVsWayPointCounter < 2) {
|
||||
return false;
|
||||
@ -3106,7 +3106,7 @@ bool ActPathMove::contextCheck(int idx)
|
||||
} else {
|
||||
mVsWayPointCounter = 0;
|
||||
}
|
||||
} else if (wp->isFlag(Game::WPF_Unknown5)) {
|
||||
} else if (wp->isFlag(Game::PATHFLAG_DisallowVsRed)) {
|
||||
mVsWayPointCounter++;
|
||||
if (mVsWayPointCounter < 2) {
|
||||
return false;
|
||||
|
@ -494,118 +494,124 @@ int AStarPathfinder::search(Game::AStarContext* context, int maxIterations, Game
|
||||
}
|
||||
}
|
||||
|
||||
if (targetNode) {
|
||||
PathNode* child = targetNode->mParent;
|
||||
if (child) {
|
||||
PathNode* node = child->mRootNode;
|
||||
PathNode* prevNode = nullptr;
|
||||
while (node) {
|
||||
if (node == targetNode) {
|
||||
if (prevNode) {
|
||||
prevNode->mSibling = node->mSibling;
|
||||
if (node->mSibling) {
|
||||
node->mSibling->mPrevious = prevNode;
|
||||
}
|
||||
if (!targetNode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
targetNode->mPrevious = nullptr;
|
||||
targetNode->mSibling = nullptr;
|
||||
targetNode->mParent = nullptr;
|
||||
} else {
|
||||
child->mRootNode = node->mSibling;
|
||||
if (node->mSibling) {
|
||||
node->mSibling->mPrevious = nullptr;
|
||||
}
|
||||
|
||||
targetNode->mPrevious = nullptr;
|
||||
targetNode->mSibling = nullptr;
|
||||
targetNode->mParent = nullptr;
|
||||
}
|
||||
break;
|
||||
PathNode* child = targetNode->mParent;
|
||||
if (!child) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PathNode* node = child->mRootNode;
|
||||
PathNode* prevNode = nullptr;
|
||||
while (node) {
|
||||
if (node == targetNode) {
|
||||
if (prevNode) {
|
||||
prevNode->mSibling = node->mSibling;
|
||||
if (node->mSibling) {
|
||||
node->mSibling->mPrevious = prevNode;
|
||||
}
|
||||
|
||||
prevNode = node;
|
||||
node = node->mSibling;
|
||||
targetNode->mPrevious = nullptr;
|
||||
targetNode->mSibling = nullptr;
|
||||
targetNode->mParent = nullptr;
|
||||
} else {
|
||||
child->mRootNode = node->mSibling;
|
||||
if (node->mSibling) {
|
||||
node->mSibling->mPrevious = nullptr;
|
||||
}
|
||||
|
||||
targetNode->mPrevious = nullptr;
|
||||
targetNode->mSibling = nullptr;
|
||||
targetNode->mParent = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (targetNode->mWpIndex == endIdx) {
|
||||
path[0] = targetNode;
|
||||
return 0;
|
||||
}
|
||||
prevNode = node;
|
||||
node = node->mSibling;
|
||||
}
|
||||
|
||||
WayPoint* wp = PathfindContext::routeMgr->getWayPoint(targetNode->mWpIndex);
|
||||
if (targetNode->mWpIndex == endIdx) {
|
||||
path[0] = targetNode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
WayPointIterator iter(wp, mContext->mRequestFlag & 0x80);
|
||||
WayPoint* wp = PathfindContext::routeMgr->getWayPoint(targetNode->mWpIndex);
|
||||
|
||||
CI_LOOP(iter) { s16 idx = *iter; }
|
||||
WayPointIterator iter(wp, mContext->mRequestFlag & PATHFLAG_TwoWayPathing);
|
||||
|
||||
CI_LOOP(iter)
|
||||
{
|
||||
s16 idx = *iter;
|
||||
WayPoint* cWP = PathfindContext::routeMgr->getWayPoint(idx);
|
||||
CI_LOOP(iter) { s16 idx = *iter; }
|
||||
|
||||
PathNode* node = mContext->getNode(idx);
|
||||
if ((!(mContext->mRequestFlag & 1) || !(cWP->mFlags & 1)) && ((mContext->mRequestFlag & 2) || !(cWP->mFlags & 2))
|
||||
&& ((mContext->mRequestFlag & 0x40) || !(cWP->mFlags & 0x80))
|
||||
&& (!(cWP->mFlags & 2) || !(mContext->mRequestFlag & 4) || !(wp->mFlags & 4))
|
||||
&& (!(mContext->mRequestFlag & 0x20) || !(wp->mFlags & 0x20))
|
||||
&& (!(mContext->mRequestFlag & 0x10) || !(wp->mFlags & 0x10))) {
|
||||
f32 test = estimate(targetNode->mWpIndex, node->mWpIndex);
|
||||
test += node->_00;
|
||||
if (node->_22 == 2 || test <= node->_00) {
|
||||
node->mChild = targetNode;
|
||||
node->_00 = test;
|
||||
node->mDistanceToEnd = estimate(node->mWpIndex, endIdx);
|
||||
if (node->_22 == 1) {
|
||||
PathNode* parent = node->mParent;
|
||||
if (parent) {
|
||||
PathNode* out = nullptr;
|
||||
for (PathNode* child = parent->mRootNode; child->mSibling != nullptr;) {
|
||||
if (child == node) {
|
||||
if (out) {
|
||||
out->mSibling = child->mSibling;
|
||||
if (child->mSibling) {
|
||||
child->mSibling->mPrevious = out;
|
||||
}
|
||||
node->mPrevious = nullptr;
|
||||
node->mSibling = nullptr;
|
||||
node->mParent = nullptr;
|
||||
} else {
|
||||
parent->mSibling = child->mSibling;
|
||||
if (child->mSibling) {
|
||||
child->mSibling->mPrevious = nullptr;
|
||||
}
|
||||
node->mPrevious = nullptr;
|
||||
node->mSibling = nullptr;
|
||||
node->mParent = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
CI_LOOP(iter)
|
||||
{
|
||||
s16 idx = *iter;
|
||||
WayPoint* cWP = PathfindContext::routeMgr->getWayPoint(idx);
|
||||
|
||||
PathNode* node = mContext->getNode(idx);
|
||||
if ((((mContext->mRequestFlag & PATHFLAG_RequireOpen) && (cWP->mFlags & WPF_Closed))
|
||||
|| (!(mContext->mRequestFlag & PATHFLAG_PathThroughWater) && (cWP->mFlags & WPF_Water))
|
||||
|| (!(mContext->mRequestFlag & PATHFLAG_AllowUnvisited) && (cWP->mFlags & WPF_Unvisited))
|
||||
|| ((cWP->mFlags & WPF_Water) && (mContext->mRequestFlag & PATHFLAG_DisallowUnfinishedBridges) && (wp->mFlags & WPF_Bridge))
|
||||
|| ((mContext->mRequestFlag & PATHFLAG_DisallowVsRed) && (wp->mFlags & WPF_VersusRed))
|
||||
|| ((mContext->mRequestFlag & PATHFLAG_DisallowVsBlue) && (wp->mFlags & WPF_VersusBlue)))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
f32 test = estimate(targetNode->mWpIndex, node->mWpIndex);
|
||||
test += node->_00;
|
||||
if (node->_22 == 2 || test <= node->_00) {
|
||||
node->mChild = targetNode;
|
||||
node->_00 = test;
|
||||
node->mDistanceToEnd = estimate(node->mWpIndex, endIdx);
|
||||
if (node->_22 == 1) {
|
||||
PathNode* parent = node->mParent;
|
||||
if (parent) {
|
||||
PathNode* out = nullptr;
|
||||
for (PathNode* child = parent->mRootNode; child->mSibling != nullptr;) {
|
||||
if (child == node) {
|
||||
if (out) {
|
||||
out->mSibling = child->mSibling;
|
||||
if (child->mSibling) {
|
||||
child->mSibling->mPrevious = out;
|
||||
}
|
||||
}
|
||||
node->_22 = 2;
|
||||
}
|
||||
if (node->_22) {
|
||||
node->_22 = 0;
|
||||
AStarContext* context = mContext;
|
||||
PathNode* newnode = context->mNodeLists[0].mRootNode;
|
||||
if (newnode) {
|
||||
while (newnode->mSibling) {
|
||||
newnode = newnode->mSibling;
|
||||
}
|
||||
newnode->mSibling = node;
|
||||
node->mPrevious = newnode;
|
||||
node->mPrevious = nullptr;
|
||||
node->mSibling = nullptr;
|
||||
node->mParent = nullptr;
|
||||
} else {
|
||||
context->mNodeLists[0].mRootNode = node;
|
||||
parent->mSibling = child->mSibling;
|
||||
if (child->mSibling) {
|
||||
child->mSibling->mPrevious = nullptr;
|
||||
}
|
||||
node->mPrevious = nullptr;
|
||||
node->mSibling = nullptr;
|
||||
node->mParent = nullptr;
|
||||
}
|
||||
node->mParent = &context->mNodeLists[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
node->_22 = 2;
|
||||
}
|
||||
if (node->_22) {
|
||||
node->_22 = 0;
|
||||
AStarContext* context = mContext;
|
||||
PathNode* newnode = context->mNodeLists[0].mRootNode;
|
||||
if (newnode) {
|
||||
while (newnode->mSibling) {
|
||||
newnode = newnode->mSibling;
|
||||
}
|
||||
newnode->mSibling = node;
|
||||
node->mPrevious = newnode;
|
||||
} else {
|
||||
context->mNodeLists[0].mRootNode = node;
|
||||
}
|
||||
node->mParent = &context->mNodeLists[0];
|
||||
}
|
||||
|
||||
targetNode->_22 = 1;
|
||||
}
|
||||
}
|
||||
targetNode->_22 = 1;
|
||||
}
|
||||
|
||||
if (!mContext->mNodeLists[0].mRootNode) {
|
||||
|
@ -227,18 +227,32 @@ void WayPoint::setBridge(bool bridge)
|
||||
* @note Address: N/A
|
||||
* @note Size: 0x28
|
||||
*/
|
||||
void WayPoint::setVisit(bool)
|
||||
void WayPoint::setVisit(bool visit)
|
||||
{
|
||||
// UNUSED FUNCTION
|
||||
if (visit) {
|
||||
resetFlag(WPF_Unvisited);
|
||||
}
|
||||
else {
|
||||
setFlag(WPF_Unvisited);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @note Address: N/A
|
||||
* @note Size: 0x48
|
||||
* @note Assumed code but size matches. Function is unused
|
||||
*/
|
||||
void WayPoint::setVsColor(int)
|
||||
void WayPoint::setVsColor(int color)
|
||||
{
|
||||
// UNUSED FUNCTION
|
||||
resetFlag(WPF_VersusBlue);
|
||||
resetFlag(WPF_VersusRed);
|
||||
|
||||
if (color == Blue) {
|
||||
setFlag(WPF_VersusBlue);
|
||||
}
|
||||
else if (color == Red) {
|
||||
setFlag(WPF_VersusRed);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -247,17 +261,26 @@ void WayPoint::setVsColor(int)
|
||||
*/
|
||||
bool WayPoint::hasLinkTo(s16 idx)
|
||||
{
|
||||
// UNUSED FUNCTION
|
||||
for (s16 i = 0; i < mNumToLinks; i++) {
|
||||
if (mToLinks[i] == idx) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @note Address: N/A
|
||||
* @note Size: 0xB4
|
||||
*/
|
||||
void WayPoint::addLink(s16)
|
||||
void WayPoint::addLink(s16 idx)
|
||||
{
|
||||
P2ASSERTLINE(300, false);
|
||||
// UNUSED FUNCTION
|
||||
// currently this is 0x4 larger than the given size
|
||||
if (!hasLinkTo(idx)) {
|
||||
P2ASSERTLINE(300, mNumToLinks < ARRAY_SIZE(mToLinks));
|
||||
|
||||
mToLinks[mNumToLinks++] = idx;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1280,7 +1303,7 @@ void RouteMgr::setCloseAll()
|
||||
CI_LOOP(iter)
|
||||
{
|
||||
WayPoint* wp = (*iter);
|
||||
wp->setFlag(WPF_Unknown8);
|
||||
wp->setVisit(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1297,7 +1320,7 @@ void RouteMgr::openRoom(s16 roomIdx)
|
||||
FOREACH_NODE(WayPoint::RoomList, wp->mRoomList.mChild, node)
|
||||
{
|
||||
if (node->mRoomIdx == roomIdx) {
|
||||
wp->resetFlag(WPF_Unknown8);
|
||||
wp->setVisit(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3798,7 +3798,9 @@ bool BlackMan::Obj::setPathFinder(bool check)
|
||||
mPreviousWaypointIndex = mCurrentWaypointIndex;
|
||||
mCurrentWaypointIndex = idx1;
|
||||
|
||||
u32 flag = (check > 0) + 0xC3;
|
||||
int flag = (check) ? (PATHFLAG_PathThroughWater | PATHFLAG_AllowUnvisited | PATHFLAG_TwoWayPathing)
|
||||
: (PATHFLAG_RequireOpen | PATHFLAG_PathThroughWater | PATHFLAG_AllowUnvisited | PATHFLAG_TwoWayPathing);
|
||||
|
||||
if (mPathFindingHandle) {
|
||||
testPathfinder->release(mPathFindingHandle);
|
||||
}
|
||||
|
@ -1568,7 +1568,8 @@ bool Obj::setPathFinder(bool cond)
|
||||
mWpIndex3 = mWpIndex2;
|
||||
mWpIndex2 = nearIdx;
|
||||
|
||||
int flag = cond != 0 ? 0xC2 : 0xC3;
|
||||
int flag = cond != 0 ? (PATHFLAG_PathThroughWater | PATHFLAG_AllowUnvisited | PATHFLAG_TwoWayPathing)
|
||||
: (PATHFLAG_RequireOpen | PATHFLAG_PathThroughWater | PATHFLAG_AllowUnvisited | PATHFLAG_TwoWayPathing);
|
||||
|
||||
if (mPathID) {
|
||||
testPathfinder->release(mPathID);
|
||||
|
Loading…
Reference in New Issue
Block a user