summaryrefslogtreecommitdiff
path: root/src/koopatlas/pathmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/koopatlas/pathmanager.cpp335
1 files changed, 172 insertions, 163 deletions
diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp
index 9525732..e42246e 100644
--- a/src/koopatlas/pathmanager.cpp
+++ b/src/koopatlas/pathmanager.cpp
@@ -7,6 +7,7 @@
void dWMPathManager_c::setup() {
isMoving = false;
isJumping = false;
+ scaleAnimProgress = -1;
timer = 0.0;
currentPath = 0;
reverseThroughPath = false;
@@ -20,6 +21,7 @@ void dWMPathManager_c::setup() {
SpammyReport("Unlocking paths\n");
isEnteringLevel = false;
+ levelStartWait = -1;
unlockPaths();
SpammyReport("done\n");
@@ -61,7 +63,7 @@ void dWMPathManager_c::setup() {
//OSReport("Path: %p nodes %p to %p\n", path, srcNode, destNode);
int ct = destNode->getAvailableExitCount();
//OSReport("Dest Node available exits: %d; type: %d\n", ct, destNode->type);
- if (destNode == node || ct > 2 || destNode->type == dKPNode_s::LEVEL) {
+ if (destNode == node || ct > 2 || destNode->type == dKPNode_s::LEVEL || destNode->type == dKPNode_s::CHANGE) {
exitTo = candidateExit;
//OSReport("Accepting this node\n");
break;
@@ -151,36 +153,36 @@ void dWMPathManager_c::unlockPaths() {
int cmdID = 0;
while (*in != 0) {
- SpammyReport("[%p] Cmd %d: Evaluating condition\n", in, cmdID);
+ UnlockCmdReport("[%p] Cmd %d: Evaluating condition\n", in, cmdID);
// begin processing a block
bool value = evaluateUnlockCondition(in, save, 0);
- SpammyReport("[%p] Cmd %d: Condition evaluated, result: %d\n", in, cmdID, value);
- //SpammyReport("Unlock condition: %d\n", value);
+ UnlockCmdReport("[%p] Cmd %d: Condition evaluated, result: %d\n", in, cmdID, value);
+ //UnlockCmdReport("Unlock condition: %d\n", value);
// get what it's supposed to affect
// for now we'll assume that it affects one or more paths
u8 affectedCount = *(in++);
- SpammyReport("[%p] Cmd %d: Affects %d path(s)\n", in, cmdID, affectedCount);
+ UnlockCmdReport("[%p] Cmd %d: Affects %d path(s)\n", in, cmdID, affectedCount);
for (int i = 0; i < affectedCount; i++) {
u8 one = *(in++);
u8 two = *(in++);
u16 pathID = (one << 8) | two;
- SpammyReport("[%p] Cmd %d: Affected %d: PathID: %d\n", in, cmdID, i, pathID);
+ UnlockCmdReport("[%p] Cmd %d: Affected %d: PathID: %d\n", in, cmdID, i, pathID);
dKPPath_s *path = pathLayer->paths[pathID];
- SpammyReport("[%p] Cmd %d: Affected %d: Path: %p\n", in, cmdID, i, path);
+ UnlockCmdReport("[%p] Cmd %d: Affected %d: Path: %p\n", in, cmdID, i, path);
path->isAvailable = value ? dKPPath_s::AVAILABLE : dKPPath_s::NOT_AVAILABLE;
- SpammyReport("[%p] Cmd %d: Affected %d: IsAvailable written\n", in, cmdID, i);
+ UnlockCmdReport("[%p] Cmd %d: Affected %d: IsAvailable written\n", in, cmdID, i);
PathAvailabilityData[pathID] = value ? dKPPath_s::AVAILABLE : dKPPath_s::NOT_AVAILABLE;
- SpammyReport("[%p] Cmd %d: Affected %d: AvailabilityData written\n", in, cmdID, i);
+ UnlockCmdReport("[%p] Cmd %d: Affected %d: AvailabilityData written\n", in, cmdID, i);
// NEWLY_AVAILABLE is set later, when that stuff is figured out
path->setLayerAlpha(value ? 255 : 0);
- SpammyReport("[%p] Cmd %d: Affected %d: Layer alpha applied\n", in, cmdID, i);
+ UnlockCmdReport("[%p] Cmd %d: Affected %d: Layer alpha applied\n", in, cmdID, i);
}
- SpammyReport("[%p] Cmd %d: %d affected path(s) processed\n", in, cmdID, affectedCount);
+ UnlockCmdReport("[%p] Cmd %d: %d affected path(s) processed\n", in, cmdID, affectedCount);
cmdID++;
}
@@ -230,14 +232,14 @@ void dWMPathManager_c::unlockPaths() {
}
bool dWMPathManager_c::evaluateUnlockCondition(u8 *&in, SaveBlock *save, int stack) {
- SpammyReport("[%p] CondStk:%d begin\n", in, stack);
+ UnlockCmdReport("[%p] CondStk:%d begin\n", in, stack);
u8 controlByte = *(in++);
u8 conditionType = (controlByte >> 6);
- SpammyReport("[%p] CondStk:%d control byte: %d; condition type: %d\n", in, stack, controlByte, conditionType);
+ UnlockCmdReport("[%p] CondStk:%d control byte: %d; condition type: %d\n", in, stack, controlByte, conditionType);
if (conditionType == 0) {
- SpammyReport("[%p] CondStk:%d end, returning CONSTANT 1\n", in, stack);
+ UnlockCmdReport("[%p] CondStk:%d end, returning CONSTANT 1\n", in, stack);
return true;
}
@@ -247,10 +249,10 @@ bool dWMPathManager_c::evaluateUnlockCondition(u8 *&in, SaveBlock *save, int sta
bool isSecret = (controlByte & 0x10);
u8 worldNumber = controlByte & 0xF;
u8 levelNumber = *(in++);
- SpammyReport("[%p] CondStk:%d level, w:%d l:%d secret:%d\n", in, stack, worldNumber, levelNumber, isSecret);
+ UnlockCmdReport("[%p] CondStk:%d level, w:%d l:%d secret:%d\n", in, stack, worldNumber, levelNumber, isSecret);
u32 conds = save->GetLevelCondition(worldNumber, levelNumber);
- SpammyReport("[%p] CondStk:%d returning for level conditions: %d / %x\n", in, stack, conds, conds);
+ UnlockCmdReport("[%p] CondStk:%d returning for level conditions: %d / %x\n", in, stack, conds, conds);
if (isSecret)
return (conds & COND_SECRET) != 0;
@@ -265,7 +267,7 @@ bool dWMPathManager_c::evaluateUnlockCondition(u8 *&in, SaveBlock *save, int sta
bool value = isOr ? false : true;
u8 termCount = (controlByte & 0x3F) + 1;
- SpammyReport("[%p] CondStk:%d and:%d or:%d startValue:%d termCount:%d\n", in, stack, isAnd, isOr, value, termCount);
+ UnlockCmdReport("[%p] CondStk:%d and:%d or:%d startValue:%d termCount:%d\n", in, stack, isAnd, isOr, value, termCount);
for (int i = 0; i < termCount; i++) {
bool what = evaluateUnlockCondition(in, save, stack+1);
@@ -276,27 +278,20 @@ bool dWMPathManager_c::evaluateUnlockCondition(u8 *&in, SaveBlock *save, int sta
value &= what;
}
- SpammyReport("[%p] CondStk:%d end, returning %d\n", in, stack, value);
+ UnlockCmdReport("[%p] CondStk:%d end, returning %d\n", in, stack, value);
return value;
}
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();
+ if (isEnteringLevel) {
+ if (levelStartWait > 0) {
+ levelStartWait--;
+ if (levelStartWait == 0) {
+ dScKoopatlas_c::instance->startLevel(enteredLevel);
+ }
+ }
+ return;
}
// handle path fading
@@ -305,6 +300,8 @@ void dWMPathManager_c::execute() {
if (countdownToFadeIn <= 0) {
unlockingAlpha = 0;
MapSoundPlayer(SoundRelatedClass, SE_SYS_NEW_POINT, 1);
+ } else {
+ return;
}
}
@@ -329,13 +326,46 @@ void dWMPathManager_c::execute() {
// we've reached the end
unlockingAlpha = -1;
MapSoundPlayer(SoundRelatedClass, SE_SYS_NEW_POINT_END, 1);
+ waitAfterUnlock = 15;
+ }
+
+ return;
+ }
+
+ if (waitAfterUnlock > 0) {
+ waitAfterUnlock--;
+ return;
+ }
+
+ int nowPressed = Remocon_GetPressed(GetActiveRemocon());
+
+ if (isMoving) {
+ moveThroughPath();
+ } else {
+ // Left, right, up, down
+ int pressedDir = -1;
+ if (nowPressed & WPAD_LEFT) pressedDir = 0;
+ else if (nowPressed & WPAD_RIGHT) pressedDir = 1;
+ else if (nowPressed & WPAD_UP) pressedDir = 2;
+ else if (nowPressed & WPAD_DOWN) pressedDir = 3;
+ else if (nowPressed & WPAD_TWO)
+ activatePoint();
+
+ if (pressedDir >= 0) {
+ if (canUseExit(currentNode->exits[pressedDir])) {
+ startMovementTo(currentNode->exits[pressedDir]);
+ } else {
+ // TODO: maybe remove this? got to see how it looks
+ static u16 directions[] = {-0x4000,0x4000,-0x7FFF,0};
+ daWMPlayer_c::instance->rot.y = directions[pressedDir];
+ }
}
}
}
void dWMPathManager_c::startMovementTo(dKPPath_s *path) {
- SpammyReport("moving to path %p\n", path);
+ SpammyReport("moving to path %p [%d,%d to %d,%d]\n", path, path->start->x, path->start->y, path->end->x, path->end->y);
if (!path->isAvailable) { return; }
if (currentNode)
@@ -375,131 +405,94 @@ void dWMPathManager_c::startMovementTo(dKPPath_s *path) {
// hang_walk_l = 65,
// hang_walk_r = 66,
- SpammyReport("h\n");
- player->rot.y = direction;
- player->hasSound = false;
- player->hasEffect = false;
- moveSpeed = 3.0f;
-
- switch (path->animation) {
-
- // Running
- case 0:
- player->startAnimation(run, 2.0, 10.0, 0.0);
- player->hasSound = true;
- player->soundName = SE_PLY_FOOTNOTE_DIRT;
- break;
- case 1:
- player->startAnimation(run, 2.0, 10.0, 0.0);
- player->hasSound = true;
- player->hasEffect = true;
- player->soundName = SE_PLY_FOOTNOTE_CS_SAND;
- player->effectName = "Wm_mr_foot_sand";
- break;
- case 2:
- player->startAnimation(run, 2.0, 10.0, 0.0);
- player->hasSound = true;
- player->hasEffect = true;
- player->soundName = SE_PLY_FOOTNOTE_CS_SNOW;
- player->effectName = "Wm_mr_foot_snow";
- break;
- case 3:
- player->startAnimation(run, 2.0, 10.0, 0.0);
- player->hasSound = true;
- player->hasEffect = true;
- player->soundName = SE_PLY_FOOTNOTE_CS_WATER;
- player->effectName = "Wm_mr_foot_water";
- break;
+ static const struct {
+ PlayerAnim anim;
+ float animParam1, animParam2;
+ s16 forceRotation;
+ float forceSpeed;
+ SFX repeatSound, initialSound;
+ const char *repeatEffect, *initialEffect;
+ } Animations[] = {
+ // Walking
+ {run,2.0f,10.0f, -1,-1.0f, SE_PLY_FOOTNOTE_DIRT,SE_NULL, 0,0},
+ {run,2.0f,10.0f, -1,-1.0f, SE_PLY_FOOTNOTE_CS_SAND,SE_NULL, "Wm_mr_foot_sand",0},
+ {run,2.0f,10.0f, -1,-1.0f, SE_PLY_FOOTNOTE_CS_SNOW,SE_NULL, "Wm_mr_foot_snow",0},
+ {run,2.0f,10.0f, -1,-1.0f, SE_PLY_FOOTNOTE_CS_WATER,SE_NULL, "Wm_mr_foot_water",0},
// Jumping
- case 4:
- player->startAnimation(jump, 1.0, 1.0, 0.0);
- MapSoundPlayer(SoundRelatedClass, SE_PLY_JUMP, 1);
- isJumping = true;
- moveSpeed = 2.5f;
- break;
- case 5:
- player->startAnimation(jump, 1.0, 10.0, 0.0);
- MapSoundPlayer(SoundRelatedClass, SE_PLY_JUMP, 1);
- isJumping = true;
- moveSpeed = 2.5f;
- break;
- case 6:
- player->startAnimation(jump, 1.0, 10.0, 0.0);
- MapSoundPlayer(SoundRelatedClass, SE_PLY_JUMP, 1);
- isJumping = true;
- moveSpeed = 2.5f;
- break;
- case 7:
- player->startAnimation(jump, 1.0, 10.0, 0.0);
- MapSoundPlayer(SoundRelatedClass, SE_PLY_JUMP, 1);
- isJumping = true;
- SpawnEffect("Wm_mr_waterwave_out", 0, &player->pos, 0, &player->scale);
- moveSpeed = 2.0f;
- break;
-
- // Climbing
- case 8:
- player->startAnimation(pea_plant, 1.2, 10.0, 0.0);
- player->rot.y = 0x8000;
- player->hasSound = true;
- player->soundName = SE_PLY_FOOTNOTE_CS_ROCK_CLIMB;
- moveSpeed = 1.5f;
- break;
- case 9:
- player->startAnimation(tree_climb, 1.2, 10.0, 0.0);
- player->rot.y = 0xC000;
- player->hasSound = true;
- player->soundName = SE_PLY_FOOTNOTE_CS_ROCK_CLIMB;
- moveSpeed = 1.5f;
- break;
- case 10:
- player->startAnimation(tree_climb, 1.2, 10.0, 0.0);
- player->rot.y = 0x4000;
- player->hasSound = true;
- player->soundName = SE_PLY_FOOTNOTE_CS_ROCK_CLIMB;
- moveSpeed = 1.5f;
- break;
-
- // Others
- case 12:
- player->startAnimation(swim_wait, 1.2, 10.0, 0.0);
- player->hasSound = true;
- player->hasEffect = true;
- player->soundName = SE_PLY_SWIM;
- player->effectName = "Wm_mr_waterswim";
- moveSpeed = 2.0f;
- break;
- case 13:
- player->startAnimation(b_dash2, 3.0, 10.0, 0.0);
- player->hasSound = true;
- player->soundName = SE_PLY_FOOTNOTE_DIRT;
- moveSpeed = 5.0f;
- break;
- case 14:
- player->startAnimation(wait, 2.0, 10.0, 0.0);
- player->rot.y = 0x0000;
- MapSoundPlayer(SoundRelatedClass, SE_PLY_DOKAN_IN_OUT, 1);
- moveSpeed = 1.0f;
- break;
- case 15:
- player->startAnimation(wait, 2.0, 10.0, 0.0);
- player->rot.y = 0x8000;
- MapSoundPlayer(SoundRelatedClass, SE_OBJ_DOOR_OPEN, 1);
- moveSpeed = 0.2f;
- break;
- case 16:
- player->startAnimation(Tjumped, 2.0, 0.0, 0.0);
- break;
- default:
- SpammyReport("No animtaion?!");
- player->startAnimation(run, 2.0, 10.0, 0.0);
- player->hasSound = true;
- player->soundName = SE_PLY_FOOTNOTE_DIRT;
- break;
+ {jump,1.0f,1.0f, -1,2.5f, SE_NULL,SE_PLY_JUMP, 0,0},
+ {jump,1.0f,10.0f, -1,2.5f, SE_NULL,SE_PLY_JUMP, 0,0},
+ {jump,1.0f,10.0f, -1,2.5f, SE_NULL,SE_PLY_JUMP, 0,0},
+ {jump,1.0f,10.0f, -1,2.5f, SE_NULL,SE_PLY_JUMP, 0,"Wm_mr_waterwave_out"},
+
+ // Ladder up, left, right
+ {pea_plant,1.2f,10.0f, -0x7FFF,1.5f, SE_PLY_FOOTNOTE_CS_ROCK_CLIMB,SE_NULL, 0,0},
+ {tree_climb,1.2f,10.0f, -0x4000,1.5f, SE_PLY_FOOTNOTE_CS_ROCK_CLIMB,SE_NULL, 0,0},
+ {tree_climb,1.2f,10.0f, 0x4000,1.5f, SE_PLY_FOOTNOTE_CS_ROCK_CLIMB,SE_NULL, 0,0},
+ // Fall (default?)
+ {run,2.0f,10.0f, -1,-1.0f, SE_PLY_FOOTNOTE_DIRT,SE_NULL, 0,0},
+
+ // Swim
+ {swim_wait,1.2f,10.0f, -1,2.0f, SE_PLY_SWIM,SE_NULL, "Wm_mr_waterswim",0},
+ // Run
+ {b_dash2,3.0f,10.0f, -1,5.0f, SE_PLY_FOOTNOTE_DIRT,SE_NULL, 0,0},
+ // Pipe
+ {wait,2.0f,10.0f, 0,1.0f, SE_NULL,SE_PLY_DOKAN_IN_OUT, 0,0},
+ // Door
+ {wait,2.0f,10.0f, -0x7FFF,0.2f, SE_NULL,SE_OBJ_DOOR_OPEN, 0,0},
+
+ // TJumped
+ {Tjumped,2.0f,0.0f, -1,-1.0f, SE_NULL,SE_NULL, 0,0},
+
+ // Enter cave, this is handled specially
+ {run,1.0f,10.0f, -1,1.0f, SE_NULL,SE_NULL, 0,0},
+ {run,1.0f,10.0f, -1,1.0f, SE_NULL,SE_NULL, 0,0},
+
+ // Invisible, this is handled specially
+ {wait,2.0f,10.0f, -1,1.0f, SE_NULL,SE_NULL, 0,0},
+ };
+
+ isJumping = (path->animation >= dKPPath_s::JUMP && path->animation <= dKPPath_s::JUMP_WATER);
+
+ float playerScale = 1.6f;
+
+ if (path->animation == dKPPath_s::ENTER_CAVE_UP) {
+ scaleAnimProgress = 60;
+ // what direction does this path go in?
+ isScalingUp = (deltaY < 0) ^ reverseThroughPath;
+
+ if (!isScalingUp)
+ playerScale = 0.0f;
}
-
- SpammyReport("i\n");
+
+ player->visible = (path->animation != dKPPath_s::INVISIBLE);
+ player->scale.x = player->scale.y = player->scale.z = playerScale;
+
+ int id = (path->animation >= dKPPath_s::MAX_ANIM) ? 0 : (int)path->animation;
+
+ player->startAnimation(Animations[id].anim, Animations[id].animParam1, Animations[id].animParam2, 0.0f);
+
+ player->rot.y = (Animations[id].forceRotation != -1) ? Animations[id].forceRotation : direction;
+ moveSpeed = (Animations[id].forceSpeed >= 0.0f) ? Animations[id].forceSpeed : 3.0f;
+
+ if (Animations[id].repeatEffect) {
+ player->hasEffect = true;
+ player->effectName = Animations[id].repeatEffect;
+ } else {
+ player->hasEffect = false;
+ }
+
+ if (Animations[id].repeatSound != SE_NULL) {
+ player->hasSound = true;
+ player->soundName = Animations[id].repeatSound;
+ } else {
+ player->hasSound = false;
+ }
+
+ if (Animations[id].initialEffect)
+ SpawnEffect(Animations[id].initialEffect, 0, &player->pos, 0, &player->scale);
+ if (Animations[id].initialSound != SE_NULL)
+ MapSoundPlayer(SoundRelatedClass, Animations[id].initialSound, 1);
}
void dWMPathManager_c::moveThroughPath() {
@@ -508,12 +501,22 @@ void dWMPathManager_c::moveThroughPath() {
from = reverseThroughPath ? currentPath->end : currentPath->start;
to = reverseThroughPath ? currentPath->start : currentPath->end;
+ daWMPlayer_c *player = daWMPlayer_c::instance;
+
+
+ if (scaleAnimProgress >= 0) {
+ float soFar = scaleAnimProgress * (1.6f / 60.0f);
+ float sc = isScalingUp ? soFar : (1.6f - soFar);
+ player->scale.x = player->scale.y = player->scale.z = sc;
+
+ scaleAnimProgress--;
+ }
+
+
Vec move = (Vec){to->x - from->x, to->y - from->y, 0};
VECNormalize(&move, &move);
VECScale(&move, &move, moveSpeed);
- daWMPlayer_c *player = daWMPlayer_c::instance;
-
if (isJumping) {
float ys = (float)from->y;
float ye = (float)to->y;
@@ -550,8 +553,10 @@ void dWMPathManager_c::moveThroughPath() {
// 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))
+ (((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)))
+ ||
+ (from->x == to->x && from->y == to->y)
) {
currentNode = to;
@@ -603,6 +608,7 @@ void dWMPathManager_c::moveThroughPath() {
SpammyReport("Change to map ID %d (%s), entrance ID %d\n", save->current_world, to->destMap, to->foreignID);
+ ActivateWipe(to->transition);
DoSceneChange(WORLD_MAP, 0x10000000 | (to->foreignID << 20), 0);
} else if (reallyStop) {
@@ -634,6 +640,9 @@ void dWMPathManager_c::moveThroughPath() {
}
void dWMPathManager_c::activatePoint() {
+ if (levelStartWait >= 0)
+ return;
+
if (currentNode->type == dKPNode_s::LEVEL) {
int w = currentNode->levelNumber[0] - 1;
int l = currentNode->levelNumber[1] - 1;
@@ -657,11 +666,11 @@ void dWMPathManager_c::activatePoint() {
MapSoundPlayer(SoundRelatedClass, SE_SYS_GAME_START, 1);
daWMPlayer_c::instance->startAnimation(170, 1.2, 10.0, 0.0);
+ daWMPlayer_c::instance->rot.y = 0;
isEnteringLevel = true;
-
- dLevelInfo_c::entry_s *level = dScKoopatlas_c::instance->levelInfo.search(w, l);
- dScKoopatlas_c::instance->startLevel(level);
+ levelStartWait = 40;
+ enteredLevel = dScKoopatlas_c::instance->levelInfo.search(w, l);
}
}