diff options
Diffstat (limited to 'src/koopatlas/pathmanager.cpp')
-rw-r--r-- | src/koopatlas/pathmanager.cpp | 130 |
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); + } +} + + |