From 57577aa4c163b01572b21914defe34e7ee24104b Mon Sep 17 00:00:00 2001 From: Treeki Date: Tue, 24 Jul 2012 15:55:13 +0200 Subject: parts of the new unlock system, still got to wrap up some stuff --- src/koopatlas/mapdata.cpp | 10 ++-- src/koopatlas/mapdata.h | 10 +++- src/koopatlas/pathmanager.cpp | 108 +++++++++++++++++++++++++++++++++++++++++- src/koopatlas/pathmanager.h | 7 +++ 4 files changed, 128 insertions(+), 7 deletions(-) (limited to 'src/koopatlas') diff --git a/src/koopatlas/mapdata.cpp b/src/koopatlas/mapdata.cpp index 9c84c4a..dd4646b 100644 --- a/src/koopatlas/mapdata.cpp +++ b/src/koopatlas/mapdata.cpp @@ -173,6 +173,7 @@ void dKPMapData_c::fixup() { fixRef(data->layers); fixRef(data->tilesets); + fixRef(data->unlockData); for (int iLayer = 0; iLayer < data->layerCount; iLayer++) { dKPLayer_s *layer = fixRef(data->layers[iLayer]); @@ -225,10 +226,7 @@ void dKPMapData_c::fixup() { } - // before we finish here, create the Node Extra classes - - // before the first off, do the unlocking. - SaveBlock *save = GetSaveFile()->GetBlock(-1); + /*SaveBlock *save = GetSaveFile()->GetBlock(-1); for (int i = 0; i < pathLayer->pathCount; i++) { dKPPath_s *path = pathLayer->paths[i]; @@ -242,8 +240,10 @@ void dKPMapData_c::fixup() { else path->isAvailable = false; } - } + }*/ + + // before we finish here, create the Node Extra classes // first off, count how many we need... int count = 0; diff --git a/src/koopatlas/mapdata.h b/src/koopatlas/mapdata.h index 18dd9ee..b9a32f3 100644 --- a/src/koopatlas/mapdata.h +++ b/src/koopatlas/mapdata.h @@ -95,12 +95,18 @@ struct dKPNode_s { }; struct dKPPath_s { + enum Availability { + NOT_AVAILABLE = 0, + AVAILABLE = 1, + NEWLY_AVAILABLE = 2 + }; + dKPNode_s *start, *end; dKPLayer_s *tileLayer, *doodadLayer; u8 unlockType; // 0 = always, 1 = normal, 2 = secret u8 unlockLevelNumber[2]; - bool isAvailable; // computed on-the-fly - default from Koopatlas is true + u8 isAvailable; // computed on-the-fly - default from Koopatlas is 1 float speed; int animation; }; @@ -164,6 +170,8 @@ struct dKPMapFile_s { int tilesetCount; GXTexObj *tilesets; + u8 *unlockData; + dKPLayer_s::sector_s sectors[1]; // variable size }; diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp index 41515a6..444684c 100644 --- a/src/koopatlas/pathmanager.cpp +++ b/src/koopatlas/pathmanager.cpp @@ -61,11 +61,115 @@ void dWMPathManager_c::setup() { } } - // unlock all needed paths SpammyReport("Unlocking paths\n"); + isEnteringLevel = false; + unlockPaths(); SpammyReport("done\n"); } +static u8 *PathAvailabilityData = 0; + +dWMPathManager_c::~dWMPathManager_c() { + if (PathAvailabilityData && !isEnteringLevel) { + delete[] PathAvailabilityData; + PathAvailabilityData = 0; + } +} + +void dWMPathManager_c::unlockPaths() { + u8 *oldAvData = PathAvailabilityData; + PathAvailabilityData = new u8[pathLayer->pathCount]; + + // unlock all needed paths + for (int i = 0; i < pathLayer->pathCount; i++) + PathAvailabilityData[i] = dKPPath_s::NOT_AVAILABLE; + + SaveBlock *save = GetSaveFile()->GetBlock(-1); + + u8 *in = (u8*)dScKoopatlas_c::instance->mapData.data->unlockData; + + while (*in != 0) { + // begin processing a block + bool value = evaluateUnlockCondition(in, save); + + // , get what it's supposed to affect + // for now we'll assume that it affects one or more paths + u8 affectedCount = *(in++); + + for (int i = 0; i < affectedCount; i++) { + u8 one = *(in++); + u8 two = *(in++); + u16 pathID = (one << 8) | two; + + dKPPath_s *path = pathLayer->paths[pathID]; + path->isAvailable = dKPPath_s::AVAILABLE; + PathAvailabilityData[pathID] = dKPPath_s::AVAILABLE; + // NEWLY_AVAILABLE is set later, when that stuff is figured out + } + + // now evaluate a condition. simple! + } + + // did anything become newly available?! + int whatsNew = 0; + + if (oldAvData) { + for (int i = 0; i < pathLayer->pathCount; i++) { + if ((PathAvailabilityData[i] > 0) && (oldAvData[i] == 0)) { + dKPPath_s *path = pathLayer->paths[i]; + path->isAvailable = dKPPath_s::NEWLY_AVAILABLE; + whatsNew++; + } + } + delete[] oldAvData; + } + + // todo: set a flag on Map to do the path fade/sound, with whatsNew +} + +bool dWMPathManager_c::evaluateUnlockCondition(u8 *&in, SaveBlock *save) { + u8 controlByte = *(in++); + + u8 conditionType = (controlByte >> 6); + + if (conditionType == 0) + return true; + + if (conditionType == 1) { + // Simple level + + bool isSecret = (controlByte & 0x10); + u8 worldNumber = controlByte & 0xF; + u8 levelNumber = *(in++); + + u32 conds = save->GetLevelCondition(worldNumber, levelNumber); + + if (isSecret) + return (conds & COND_SECRET) != 0; + else + return (conds & COND_NORMAL) != 0; + } + + // Type: 2 = AND, 3 = OR + bool isAnd = (conditionType == 2); + bool isOr = (conditionType == 3); + + bool value = isOr ? false : true; + + u8 termCount = (controlByte & 0x3F) + 1; + + for (int i = 0; i < termCount; i++) { + bool what = evaluateUnlockCondition(in, save); + + if (isOr) + value |= what; + else + value &= what; + } + + return value; +} + void dWMPathManager_c::execute() { int nowPressed = Remocon_GetPressed(GetActiveRemocon()); @@ -354,6 +458,8 @@ void dWMPathManager_c::activatePoint() { MapSoundPlayer(SoundRelatedClass, SE_SYS_GAME_START, 1); daWMPlayer_c::instance->startAnimation(170, 1.2, 10.0, 0.0); + isEnteringLevel = true; + dLevelInfo_c::entry_s *level = dScKoopatlas_c::instance->levelInfo.search(w, l); dScKoopatlas_c::instance->startLevel(level); } diff --git a/src/koopatlas/pathmanager.h b/src/koopatlas/pathmanager.h index 969bdb2..5d35f4c 100644 --- a/src/koopatlas/pathmanager.h +++ b/src/koopatlas/pathmanager.h @@ -10,6 +10,7 @@ extern "C" bool SpawnEffect(const char*, int, Vec*, S16Vec*, Vec*); class dWMPathManager_c { public: void setup(); + ~dWMPathManager_c(); void execute(); bool canUseExit(dKPPath_s *path) { @@ -36,6 +37,12 @@ class dWMPathManager_c { bool reverseThroughPath; // direction we are going through the path bool mustComplainToMapCreator; + + private: + void unlockPaths(); + bool evaluateUnlockCondition(u8 *&in, SaveBlock *save); + + bool isEnteringLevel; }; #endif -- cgit v1.2.3 From 0d20c172706178e5df2d426fcf5cb1b7ae85c225 Mon Sep 17 00:00:00 2001 From: Treeki Date: Wed, 25 Jul 2012 00:36:07 +0200 Subject: moving to desktop --- src/koopatlas/mapdata.cpp | 17 ----------------- src/koopatlas/mapdata.h | 6 ++---- src/koopatlas/pathmanager.cpp | 4 +--- 3 files changed, 3 insertions(+), 24 deletions(-) (limited to 'src/koopatlas') diff --git a/src/koopatlas/mapdata.cpp b/src/koopatlas/mapdata.cpp index dd4646b..650f1e3 100644 --- a/src/koopatlas/mapdata.cpp +++ b/src/koopatlas/mapdata.cpp @@ -226,23 +226,6 @@ void dKPMapData_c::fixup() { } - /*SaveBlock *save = GetSaveFile()->GetBlock(-1); - 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; - else - path->isAvailable = false; - } - }*/ - - // before we finish here, create the Node Extra classes // first off, count how many we need... diff --git a/src/koopatlas/mapdata.h b/src/koopatlas/mapdata.h index b9a32f3..48a1720 100644 --- a/src/koopatlas/mapdata.h +++ b/src/koopatlas/mapdata.h @@ -75,8 +75,6 @@ struct dKPNode_s { // The union is placed at the very end so we can leave out padding in the // kpbin union { - // struct { u8 levelNumber[2]; }; - // FORWARDS COMPATIBILITY: struct { u8 levelNumber[2]; bool hasSecret; }; struct { const char *destMap; u8 thisID, foreignID, transition, _; }; }; @@ -104,9 +102,9 @@ struct dKPPath_s { dKPNode_s *start, *end; dKPLayer_s *tileLayer, *doodadLayer; - u8 unlockType; // 0 = always, 1 = normal, 2 = secret - u8 unlockLevelNumber[2]; u8 isAvailable; // computed on-the-fly - default from Koopatlas is 1 + u8 hasSecret; + u8 _padding[2]; float speed; int animation; }; diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp index 444684c..4eb6c2d 100644 --- a/src/koopatlas/pathmanager.cpp +++ b/src/koopatlas/pathmanager.cpp @@ -92,7 +92,7 @@ void dWMPathManager_c::unlockPaths() { // begin processing a block bool value = evaluateUnlockCondition(in, save); - // , get what it's supposed to affect + // get what it's supposed to affect // for now we'll assume that it affects one or more paths u8 affectedCount = *(in++); @@ -106,8 +106,6 @@ void dWMPathManager_c::unlockPaths() { PathAvailabilityData[pathID] = dKPPath_s::AVAILABLE; // NEWLY_AVAILABLE is set later, when that stuff is figured out } - - // now evaluate a condition. simple! } // did anything become newly available?! -- cgit v1.2.3 From 6895c831ad320c14b01ccabe1c8adcec354e3f9f Mon Sep 17 00:00:00 2001 From: Treeki Date: Wed, 25 Jul 2012 14:10:39 +0200 Subject: lots more work completed, basic unlocks working --- src/koopatlas/core.cpp | 5 ++ src/koopatlas/map.cpp | 35 ++++--------- src/koopatlas/map.h | 5 +- src/koopatlas/mapdata.cpp | 32 +++++++++++- src/koopatlas/mapdata.h | 29 ++++++++--- src/koopatlas/pathmanager.cpp | 114 +++++++++++++++++++++++++++++++++++++----- src/koopatlas/pathmanager.h | 8 +++ 7 files changed, 178 insertions(+), 50 deletions(-) (limited to 'src/koopatlas') diff --git a/src/koopatlas/core.cpp b/src/koopatlas/core.cpp index 42bf7c1..2317d00 100644 --- a/src/koopatlas/core.cpp +++ b/src/koopatlas/core.cpp @@ -973,6 +973,11 @@ void NewerMapDrawFunc() { DrawOpa(); DrawXlu(); UnlinkScene(1); + SetCurrentCameraID(0); + for (int i = 0; i < 4; i++) + RenderEffects(0, 0xB+i); + for (int i = 0; i < 4; i++) + RenderEffects(0, 7+i); GXDrawDone(); // Leaving out some stuff here DrawAllLayoutsAfterX(0x80); diff --git a/src/koopatlas/map.cpp b/src/koopatlas/map.cpp index 4d2bc1d..2486d34 100644 --- a/src/koopatlas/map.cpp +++ b/src/koopatlas/map.cpp @@ -45,7 +45,6 @@ int dWMMap_c::onCreate() { renderer.allocator.setup(GameHeaps[0], 0x20); bool result = renderer.setup(&renderer.allocator); - bgMatrix.identity(); bgMatrix.translation(0.0f, 0.0f, -500.0f); allocator.link(-1, GameHeaps[0], 0, 0x20); @@ -112,34 +111,21 @@ void dWMMap_c::renderer_c::drawLayers() { beginRendering(); - bool cont = false; for (int iLayer = data->layerCount - 1; iLayer >= 0; iLayer--) { dKPLayer_s *layer = data->layers[iLayer]; renderMtx[2][3] += 2.0f; - cont = false; - for (int iNodes = dataCls->pathLayer->nodeCount - 1; iNodes >= 0; iNodes--) { - dKPNode_s *node = dataCls->pathLayer->nodes[iNodes]; - bool unlock = node->isUnlocked(); - if (!unlock) { - if (node->tileLayer == layer) { cont = true; break; } - if (node->doodadLayer == layer) { cont = true; break; } - } - } - for (int iPaths = dataCls->pathLayer->pathCount - 1; iPaths >= 0; iPaths--) { - dKPPath_s *path = dataCls->pathLayer->paths[iPaths]; - if (!path->isAvailable) { - if (path->tileLayer == layer) { cont = true; break; } - if (path->doodadLayer == layer) { cont = true; break; } - } - } + if (layer->alpha == 0) + continue; // invisible - if (cont) { continue; } TileReport("Checking layer %d with type %d\n", iLayer, layer->type); + + GXSetTevColor(GX_TEVREG0, (GXColor){255,255,255,layer->alpha}); + if (layer->type == dKPLayer_s::OBJECTS) - renderTileLayer(layer, data->sectors, 255); + renderTileLayer(layer, data->sectors); else if (layer->type == dKPLayer_s::DOODADS) - renderDoodadLayer(layer, 255); + renderDoodadLayer(layer); } endRendering(); @@ -209,7 +195,7 @@ void dWMMap_c::renderer_c::beginRendering() { GXSetTevColor(GX_TEVREG1, (GXColor){0,0,0,255}); } -void dWMMap_c::renderer_c::renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector_s *sectors, int alpha) { +void dWMMap_c::renderer_c::renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector_s *sectors) { //TileReport("Rendering layer %p\n", layer); // don't render it if we don't need to @@ -288,8 +274,6 @@ void dWMMap_c::renderer_c::renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector float coordY2 = yMult * (tileY + 26.0f); - GXSetTevColor(GX_TEVREG0, (GXColor){255,255,255,alpha}); - GXBegin(GX_QUADS, GX_VTXFMT0, 4); GXPosition2s16(worldX + 24, worldY - 24); GXTexCoord2f32(coordX2, coordY2); @@ -310,7 +294,7 @@ void dWMMap_c::renderer_c::renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector //TileReport("Layer complete\n"); } -void dWMMap_c::renderer_c::renderDoodadLayer(dKPLayer_s *layer, int alpha) { +void dWMMap_c::renderer_c::renderDoodadLayer(dKPLayer_s *layer) { for (int i = 0; i < layer->doodadCount; i++) { dKPDoodad_s *doodad = layer->doodads[i]; DoodadReport("Doodad @ %f,%f sized %f,%f with angle %f\n", doodad->x, doodad->y, doodad->width, doodad->height, doodad->angle); @@ -430,7 +414,6 @@ void dWMMap_c::renderer_c::renderDoodadLayer(dKPLayer_s *layer, int alpha) { loadCamera(doodadMtx); loadTexture(doodad->texObj); - GXSetTevColor(GX_TEVREG0, (GXColor){255,255,255,alpha}); GXBegin(GX_QUADS, GX_VTXFMT1, 4); GXPosition2f32(halfW, -halfH); GXTexCoord2u8(255, 255); diff --git a/src/koopatlas/map.h b/src/koopatlas/map.h index 14c2b87..8d3e2ae 100644 --- a/src/koopatlas/map.h +++ b/src/koopatlas/map.h @@ -42,8 +42,8 @@ class dWMMap_c : public dBase_c { void beginRendering(); void endRendering(); - void renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector_s *sector, int alpha); - void renderDoodadLayer(dKPLayer_s *layer, int alpha); + void renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector_s *sector); + void renderDoodadLayer(dKPLayer_s *layer); void loadTexture(GXTexObj *obj); @@ -55,7 +55,6 @@ class dWMMap_c : public dBase_c { float baseZ; int minX, minY, maxX, maxY; - int unlockingAlpha; }; renderer_c renderer; diff --git a/src/koopatlas/mapdata.cpp b/src/koopatlas/mapdata.cpp index 650f1e3..63fd0b7 100644 --- a/src/koopatlas/mapdata.cpp +++ b/src/koopatlas/mapdata.cpp @@ -2,17 +2,31 @@ // HELPER FUNCTIONS -dKPPath_s *dKPNode_s::getOppositeExitTo(dKPPath_s *path) { +dKPPath_s *dKPNode_s::getOppositeExitTo(dKPPath_s *path, bool mustBeAvailable) { for (int i = 0; i < 4; i++) { dKPPath_s *check = exits[i]; - if (check != 0 && check != path) + if (check != 0 && check != path) { + if (mustBeAvailable && !check->isAvailable) + continue; + return check; + } } return 0; } +int dKPNode_s::getExitCount(bool mustBeAvailable) { + int ct = 0; + + for (int i = 0; i < 4; i++) + if (exits[i] && (mustBeAvailable ? exits[i]->isAvailable : true)) + ct++; + + return ct; +} + bool dKPNode_s::isUnlocked() { for (int i = 0; i < 4; i++) if (exits[i]) @@ -89,6 +103,20 @@ void dKPNode_s::setupNodeExtra() { this->extra->mallocator.unlink(); } +void dKPNode_s::setLayerAlpha(u8 alpha) { + if (tileLayer) + tileLayer->alpha = alpha; + if (doodadLayer) + doodadLayer->alpha = alpha; +} + +void dKPPath_s::setLayerAlpha(u8 alpha) { + if (tileLayer) + tileLayer->alpha = alpha; + if (doodadLayer) + doodadLayer->alpha = alpha; +} + int dKPLayer_s::findNodeID(dKPNode_s *node) { for (int i = 0; i < nodeCount; i++) if (nodes[i] == node) diff --git a/src/koopatlas/mapdata.h b/src/koopatlas/mapdata.h index 48a1720..40e1a43 100644 --- a/src/koopatlas/mapdata.h +++ b/src/koopatlas/mapdata.h @@ -70,6 +70,8 @@ struct dKPNode_s { NodeTypes type; + bool isNew; + dKPNodeExtra_c *extra; // The union is placed at the very end so we can leave out padding in the @@ -89,24 +91,37 @@ struct dKPNode_s { bool isUnlocked(); void setupNodeExtra(); - dKPPath_s *getOppositeExitTo(dKPPath_s *path); + dKPPath_s *getOppositeExitTo(dKPPath_s *path, bool mustBeAvailable=false); + dKPPath_s *getOppositeAvailableExitTo(dKPPath_s *path) { + return getOppositeExitTo(path, true); + } + + int getExitCount(bool mustBeAvailable=false); + int getAvailableExitCount() { + return getExitCount(true); + } + + void setLayerAlpha(u8 alpha); }; struct dKPPath_s { enum Availability { NOT_AVAILABLE = 0, AVAILABLE = 1, - NEWLY_AVAILABLE = 2 + NEWLY_AVAILABLE = 2, + ALWAYS_AVAILABLE = 3 }; dKPNode_s *start, *end; dKPLayer_s *tileLayer, *doodadLayer; - u8 isAvailable; // computed on-the-fly - default from Koopatlas is 1 - u8 hasSecret; + u8 isAvailable; // computed on-the-fly - default from Koopatlas is NOT or ALWAYS + u8 isSecret; u8 _padding[2]; float speed; int animation; + + void setLayerAlpha(u8 alpha); }; /****************************************************************************** @@ -118,6 +133,8 @@ struct dKPLayer_s { }; LayerTypes type; + u8 alpha; + u8 _padding[3]; typedef u16 sector_s[16][16]; @@ -180,7 +197,7 @@ class dKPMapData_c { template inline T* fixRef(T*& indexAsPtr) { unsigned int index = (unsigned int)indexAsPtr; - if (index == 0xFFFFFFFF) + if (index == 0xFFFFFFFF || index == 0) indexAsPtr = 0; else indexAsPtr = (T*)(((char*)data) + index); @@ -190,7 +207,7 @@ class dKPMapData_c { template inline T* fixRefSafe(T*& indexAsPtr) { unsigned int index = (unsigned int)indexAsPtr; - if (index == 0xFFFFFFFF) + if (index == 0xFFFFFFFF || index == 0) indexAsPtr = 0; else if (index < 0x80000000) indexAsPtr = (T*)(((char*)data) + index); 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"); } } diff --git a/src/koopatlas/pathmanager.h b/src/koopatlas/pathmanager.h index 5d35f4c..2ce0e9c 100644 --- a/src/koopatlas/pathmanager.h +++ b/src/koopatlas/pathmanager.h @@ -14,6 +14,8 @@ class dWMPathManager_c { void execute(); bool canUseExit(dKPPath_s *path) { + OSReport("Checking usability of path %p\n", path); + if (path) OSReport("Availability: %d\n", path->isAvailable); return (path != 0) && (path->isAvailable); } @@ -38,6 +40,12 @@ class dWMPathManager_c { bool mustComplainToMapCreator; + int newlyAvailablePaths; + int newlyAvailableNodes; + + int unlockingAlpha; // -1 if not used + int countdownToFadeIn; + private: void unlockPaths(); bool evaluateUnlockCondition(u8 *&in, SaveBlock *save); -- cgit v1.2.3