summaryrefslogtreecommitdiff
path: root/src/koopatlas/pathmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/koopatlas/pathmanager.cpp')
-rw-r--r--src/koopatlas/pathmanager.cpp114
1 files changed, 101 insertions, 13 deletions
diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp
index 4eb6c2d..ee7b596 100644
--- a/src/koopatlas/pathmanager.cpp
+++ b/src/koopatlas/pathmanager.cpp
@@ -68,21 +68,40 @@ void dWMPathManager_c::setup() {
}
static u8 *PathAvailabilityData = 0;
+static u8 *NodeAvailabilityData = 0;
dWMPathManager_c::~dWMPathManager_c() {
if (PathAvailabilityData && !isEnteringLevel) {
delete[] PathAvailabilityData;
PathAvailabilityData = 0;
+
+ delete[] NodeAvailabilityData;
+ NodeAvailabilityData = 0;
}
}
void dWMPathManager_c::unlockPaths() {
- u8 *oldAvData = PathAvailabilityData;
+ u8 *oldPathAvData = PathAvailabilityData;
PathAvailabilityData = new u8[pathLayer->pathCount];
+ u8 *oldNodeAvData = NodeAvailabilityData;
+ NodeAvailabilityData = new u8[pathLayer->nodeCount];
+
+ OSReport("Unlocking paths\n");
+
// unlock all needed paths
- for (int i = 0; i < pathLayer->pathCount; i++)
- PathAvailabilityData[i] = dKPPath_s::NOT_AVAILABLE;
+ for (int i = 0; i < pathLayer->pathCount; i++) {
+ dKPPath_s *path = pathLayer->paths[i];
+
+ PathAvailabilityData[i] = path->isAvailable;
+
+ //OSReport("Path %d: %d\n", i, path->isAvailable);
+ // if this path is not "always available", then nuke its alpha
+ path->setLayerAlpha((path->isAvailable == dKPPath_s::ALWAYS_AVAILABLE) ? 255 : 0);
+ }
+
+ for (int i = 0; i < pathLayer->nodeCount; i++)
+ NodeAvailabilityData[i] = pathLayer->nodes[i]->isUnlocked();
SaveBlock *save = GetSaveFile()->GetBlock(-1);
@@ -91,6 +110,7 @@ void dWMPathManager_c::unlockPaths() {
while (*in != 0) {
// begin processing a block
bool value = evaluateUnlockCondition(in, save);
+ //OSReport("Unlock condition: %d\n", value);
// get what it's supposed to affect
// for now we'll assume that it affects one or more paths
@@ -102,27 +122,55 @@ void dWMPathManager_c::unlockPaths() {
u16 pathID = (one << 8) | two;
dKPPath_s *path = pathLayer->paths[pathID];
- path->isAvailable = dKPPath_s::AVAILABLE;
- PathAvailabilityData[pathID] = dKPPath_s::AVAILABLE;
+ path->isAvailable = value ? dKPPath_s::AVAILABLE : dKPPath_s::NOT_AVAILABLE;
+ PathAvailabilityData[pathID] = value ? dKPPath_s::AVAILABLE : dKPPath_s::NOT_AVAILABLE;
+ //OSReport("Applied to path %p[%d]\n", path, pathID);
// NEWLY_AVAILABLE is set later, when that stuff is figured out
+
+ path->setLayerAlpha(value ? 255 : 0);
}
}
// did anything become newly available?!
- int whatsNew = 0;
+ newlyAvailablePaths = 0;
+ newlyAvailableNodes = 0;
- if (oldAvData) {
+ if (oldPathAvData) {
for (int i = 0; i < pathLayer->pathCount; i++) {
- if ((PathAvailabilityData[i] > 0) && (oldAvData[i] == 0)) {
+ if ((PathAvailabilityData[i] > 0) && (oldPathAvData[i] == 0)) {
dKPPath_s *path = pathLayer->paths[i];
path->isAvailable = dKPPath_s::NEWLY_AVAILABLE;
- whatsNew++;
+ newlyAvailablePaths++;
+
+ // set this path's alpha to 0, we'll fade it in later
+ path->setLayerAlpha(0);
}
}
- delete[] oldAvData;
+ delete[] oldPathAvData;
+
+ // check nodes too
+ for (int i = 0; i < pathLayer->nodeCount; i++) {
+ if ((NodeAvailabilityData[i] > 0) && (oldNodeAvData[i] == 0)) {
+ dKPNode_s *node = pathLayer->nodes[i];
+ node->isNew = true;
+ newlyAvailableNodes++;
+ }
+ }
+ delete[] oldNodeAvData;
+ }
+
+ // now set all node alphas
+ for (int i = 0; i < pathLayer->nodeCount; i++) {
+ dKPNode_s *node = pathLayer->nodes[i];
+
+ node->setLayerAlpha((node->isUnlocked() & !node->isNew) ? 255 : 0);
}
- // todo: set a flag on Map to do the path fade/sound, with whatsNew
+ // if anything was new, set it as such
+ if (newlyAvailablePaths || newlyAvailableNodes) {
+ countdownToFadeIn = 30;
+ }
+ unlockingAlpha = -1;
}
bool dWMPathManager_c::evaluateUnlockCondition(u8 *&in, SaveBlock *save) {
@@ -186,6 +234,36 @@ void dWMPathManager_c::execute() {
else if (nowPressed & WPAD_TWO)
activatePoint();
}
+
+ // handle path fading
+ if (countdownToFadeIn > 0) {
+ countdownToFadeIn--;
+ if (countdownToFadeIn <= 0)
+ unlockingAlpha = 0;
+ }
+
+ if (unlockingAlpha != -1) {
+ unlockingAlpha += 3;
+
+ for (int i = 0; i < pathLayer->pathCount; i++) {
+ dKPPath_s *path = pathLayer->paths[i];
+
+ if (path->isAvailable == dKPPath_s::NEWLY_AVAILABLE)
+ path->setLayerAlpha(unlockingAlpha);
+ }
+
+ for (int i = 0; i < pathLayer->nodeCount; i++) {
+ dKPNode_s *node = pathLayer->nodes[i];
+
+ if (node->isNew)
+ node->setLayerAlpha(unlockingAlpha);
+ }
+
+ if (unlockingAlpha == 255) {
+ // we've reached the end
+ unlockingAlpha = -1;
+ }
+ }
}
@@ -404,6 +482,16 @@ void dWMPathManager_c::moveThroughPath() {
SpammyReport("reached path end (%p)\n", to);
+ // Quick check: do we *actually* need to stop on this node?
+ // If it's a junction with more than two exits, but only two are open,
+ // take the opposite open one
+ bool stopOverride = false;
+
+ if (to->type == dKPNode_s::STOP) {
+ if (to->getExitCount() > 2 && to->getAvailableExitCount() == 2)
+ stopOverride = true;
+ }
+
if (to->type == dKPNode_s::CHANGE) {
// Go to another map
isMoving = false;
@@ -415,7 +503,7 @@ void dWMPathManager_c::moveThroughPath() {
DoSceneChange(WORLD_MAP, 0x10000000 | to->foreignID, 0);
- } else if (to->type != dKPNode_s::PASS_THROUGH) {
+ } else if (to->type != dKPNode_s::PASS_THROUGH && !stopOverride) {
// Stop here
player->startAnimation(0, 1.2, 10.0, 0.0);
player->hasEffect = false;
@@ -431,7 +519,7 @@ void dWMPathManager_c::moveThroughPath() {
dWMHud_c::instance->showPointBar();
SpammyReport("Point bar shown\n");
} else {
- startMovementTo(to->getOppositeExitTo(currentPath));
+ startMovementTo(to->getOppositeAvailableExitTo(currentPath));
SpammyReport("passthrough node, continuing to next path\n");
}
}