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.cpp130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp
new file mode 100644
index 0000000..30f4920
--- /dev/null
+++ b/src/koopatlas/pathmanager.cpp
@@ -0,0 +1,130 @@
+#include "koopatlas/pathmanager.h"
+#include "koopatlas/core.h"
+#include "koopatlas/hud.h"
+#include "koopatlas/player.h"
+
+void dWMPathManager_c::setup() {
+ isMoving = false;
+ currentPath = 0;
+ reverseThroughPath = false;
+
+ pathLayer = dScKoopatlas_c::instance->mapData.pathLayer;
+
+ SaveBlock *save = GetSaveFile()->GetBlock(-1);
+ if (save->current_path_node >= pathLayer->nodeCount) {
+ currentNode = pathLayer->nodes[0];
+ } else {
+ currentNode = pathLayer->nodes[save->current_path_node];
+ }
+
+ // unlock all needed paths
+ for (int i = 0; i < pathLayer->pathCount; i++) {
+ dKPPath_s *path = pathLayer->paths[i];
+
+ if (path->unlockType > 0) {
+ u32 conds = save->GetLevelCondition(path->unlockLevelNumber[0] - 1, path->unlockLevelNumber[1] - 1);
+
+ if (path->unlockType == 1 && (conds & COND_NORMAL))
+ path->isAvailable = true;
+ else if (path->unlockType == 2 && (conds & COND_SECRET))
+ path->isAvailable = true;
+ }
+ }
+}
+
+
+void dWMPathManager_c::execute() {
+ int nowPressed = Remocon_GetPressed(GetActiveRemocon());
+
+ if (isMoving) {
+ moveThroughPath();
+ } else {
+ if (nowPressed & WPAD_LEFT && canUseExit(currentNode->leftExit))
+ startMovementTo(currentNode->leftExit);
+ else if (nowPressed & WPAD_RIGHT && canUseExit(currentNode->rightExit))
+ startMovementTo(currentNode->rightExit);
+ else if (nowPressed & WPAD_UP && canUseExit(currentNode->upExit))
+ startMovementTo(currentNode->upExit);
+ else if (nowPressed & WPAD_DOWN && canUseExit(currentNode->downExit))
+ startMovementTo(currentNode->downExit);
+ else if (nowPressed & WPAD_TWO)
+ activatePoint();
+ }
+}
+
+
+void dWMPathManager_c::startMovementTo(dKPPath_s *path) {
+ dWMHud_c::instance->hidePointBar();
+
+ isMoving = true;
+ reverseThroughPath = (path->end == currentNode);
+
+ currentPath = path;
+
+ // calculate direction of the path
+ short deltaX = path->end->x - path->start->x;
+ short deltaY = path->end->y - path->start->y;
+ u16 direction = (u16)(atan2(deltaX, deltaY) / ((M_PI * 2) / 65536.0));
+
+ if (reverseThroughPath) {
+ direction += 0x8000;
+ }
+
+ daWMPlayer_c *player = daWMPlayer_c::instance;
+ player->startAnimation(2, 2.0, 10.0, 0.0);
+ player->rot.y = direction;
+}
+
+void dWMPathManager_c::moveThroughPath() {
+ dKPNode_s *from, *to;
+
+ from = reverseThroughPath ? currentPath->end : currentPath->start;
+ to = reverseThroughPath ? currentPath->start : currentPath->end;
+
+ Vec move = (Vec){to->x - from->x, to->y - from->y, 0};
+ VECNormalize(&move, &move);
+ VECScale(&move, &move, 1.5);
+
+ daWMPlayer_c *player = daWMPlayer_c::instance;
+
+ player->pos.x += move.x;
+ player->pos.y -= move.y;
+
+ // Check if we've reached the end yet
+ if (
+ ((move.x > 0) ? (player->pos.x >= to->x) : (player->pos.x <= to->x)) &&
+ ((move.y > 0) ? (-player->pos.y >= to->y) : (-player->pos.y <= to->y))
+ ) {
+
+ currentNode = to;
+ player->pos.x = to->x;
+ player->pos.y = -to->y;
+
+ if (to->type != dKPNode_s::PASS_THROUGH) {
+ // Stop here
+ player->startAnimation(0, 1.2, 10.0, 0.0);
+
+ isMoving = false;
+
+ SaveBlock *save = GetSaveFile()->GetBlock(-1);
+ save->current_path_node = pathLayer->findNodeID(to);
+
+ dWMHud_c::instance->showPointBar();
+ } else {
+ startMovementTo(to->getOppositeExitTo(currentPath));
+ }
+ }
+}
+
+void dWMPathManager_c::activatePoint() {
+ if (currentNode->type == dKPNode_s::LEVEL) {
+ daWMPlayer_c::instance->startAnimation(170, 1.2, 10.0, 0.0);
+
+ int w = currentNode->levelNumber[0] - 1;
+ int l = currentNode->levelNumber[1] - 1;
+ dLevelInfo_c::entry_s *level = dScKoopatlas_c::instance->levelInfo.search(w, l);
+ dScKoopatlas_c::instance->startLevel(level);
+ }
+}
+
+