From 4e5fb276d639c0624761f74166b98a39827fe0b9 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Tue, 10 Nov 2026 16:57:15 -0600 Subject: [PATCH] feat(scripts): L_FIRE_TRANS_ROCKS and its manager, the rocks of the NJ fire transition L_FIRE_TRANS_ROCKS_MANAGER waits until the rocks of its RockGroup are all there (NumberOfRocks, 3), sends them to waypoint 1 five seconds later, and each time all of them have told it they are back down sends them up again after a second. L_FIRE_TRANS_ROCKS holds a rock that arrived at waypoint 1 for 3.5 s and sends it back to waypoint 0, where it tells the manager (PlatformDown). Both act on ArrivedAtDesiredWaypoint and GoToWaypoint, which the mover has. Co-Authored-By: Claude Fable 5.2 --- dScripts/02_server/Map/njhub/CMakeLists.txt | 2 + .../02_server/Map/njhub/FireTransRocks.cpp | 24 +++++++++ dScripts/02_server/Map/njhub/FireTransRocks.h | 11 ++++ .../Map/njhub/FireTransRocksManager.cpp | 53 +++++++++++++++++++ .../Map/njhub/FireTransRocksManager.h | 15 ++++++ dScripts/CppScripts.cpp | 4 ++ .../MovingPlatformComponentTests.cpp | 39 ++++++++++++++ 7 files changed, 148 insertions(+) create mode 100644 dScripts/02_server/Map/njhub/FireTransRocks.cpp create mode 100644 dScripts/02_server/Map/njhub/FireTransRocks.h create mode 100644 dScripts/02_server/Map/njhub/FireTransRocksManager.cpp create mode 100644 dScripts/02_server/Map/njhub/FireTransRocksManager.h diff --git a/dScripts/02_server/Map/njhub/CMakeLists.txt b/dScripts/02_server/Map/njhub/CMakeLists.txt index b2d0ba7f8..4c13fcb82 100644 --- a/dScripts/02_server/Map/njhub/CMakeLists.txt +++ b/dScripts/02_server/Map/njhub/CMakeLists.txt @@ -5,6 +5,8 @@ set(DSCRIPTS_SOURCES_02_SERVER_MAP_NJHUB "CavePrisonCage.cpp" "EnemySkeletonSpawner.cpp" "FallingTile.cpp" + "FireTransRocks.cpp" + "FireTransRocksManager.cpp" "FlameJetServer.cpp" "LightningOrbServer.cpp" "ImaginationShrineServer.cpp" diff --git a/dScripts/02_server/Map/njhub/FireTransRocks.cpp b/dScripts/02_server/Map/njhub/FireTransRocks.cpp new file mode 100644 index 000000000..ad9147e52 --- /dev/null +++ b/dScripts/02_server/Map/njhub/FireTransRocks.cpp @@ -0,0 +1,24 @@ +#include "FireTransRocks.h" + +#include "Entity.h" +#include "EntityManager.h" +#include "MovingPlatformComponent.h" + +void FireTransRocks::OnStartup(Entity* self) { + if (!self->HasVar(u"RockManagerGroup")) self->SetVar(u"RockManagerGroup", u"FireTransRocksManager"); +} + +void FireTransRocks::OnArrivedAtDesiredWaypoint(Entity* self, const uint32_t waypointIndex) { + if (waypointIndex == 1) { + self->AddTimer("PlatHold", 3.5f); + return; + } + // The first manager there is hears that the rock is down + const auto managers = Game::entityManager->GetEntitiesInGroup(self->GetVarAsString(u"RockManagerGroup")); + if (!managers.empty()) managers.front()->GetScript()->OnNotifyObject(managers.front(), self, "PlatformDown"); +} + +void FireTransRocks::OnTimerDone(Entity* self, std::string timerName) { + if (timerName != "PlatHold") return; + if (auto* const platform = self->GetComponent()) platform->GotoWaypoint(0); +} diff --git a/dScripts/02_server/Map/njhub/FireTransRocks.h b/dScripts/02_server/Map/njhub/FireTransRocks.h new file mode 100644 index 000000000..ffcc0107d --- /dev/null +++ b/dScripts/02_server/Map/njhub/FireTransRocks.h @@ -0,0 +1,11 @@ +#pragma once +#include "CppScripts.h" + +// L_FIRE_TRANS_ROCKS.lua: a rock in the NJ monastery's fire transition, a mover between its bottom (waypoint 0) and its +// top (waypoint 1). At the top it holds 3.5 s and goes back down; at the bottom it tells the rocks' manager. +class FireTransRocks : public CppScripts::Script { +public: + void OnStartup(Entity* self) override; + void OnArrivedAtDesiredWaypoint(Entity* self, uint32_t waypointIndex) override; + void OnTimerDone(Entity* self, std::string timerName) override; +}; diff --git a/dScripts/02_server/Map/njhub/FireTransRocksManager.cpp b/dScripts/02_server/Map/njhub/FireTransRocksManager.cpp new file mode 100644 index 000000000..97407e9ff --- /dev/null +++ b/dScripts/02_server/Map/njhub/FireTransRocksManager.cpp @@ -0,0 +1,53 @@ +#include "FireTransRocksManager.h" + +#include + +#include "Entity.h" +#include "EntityManager.h" +#include "MovingPlatformComponent.h" + +void FireTransRocksManager::OnStartup(Entity* self) { + self->AddTimer("check", 5.0f); + if (!self->HasVar(u"RockGroup")) self->SetVar(u"RockGroup", u"FireTransRocks"); + if (!self->HasVar(u"NumberOfRocks")) self->SetVar(u"NumberOfRocks", 3); +} + +void FireTransRocksManager::CheckForRocks(Entity* self) { + const auto rocks = Game::entityManager->GetEntitiesInGroup(self->GetVarAsString(u"RockGroup")); + // Not all there yet: look again in a second + if (static_cast(rocks.size()) < self->GetVarAs(u"NumberOfRocks")) { + self->AddTimer("check", 1.0f); + return; + } + self->AddTimer("StartPlatforms", 5.0f); +} + +void FireTransRocksManager::OnNotifyObject(Entity* self, Entity* sender, const std::string& name, int32_t param1, int32_t param2) { + if (name != "PlatformDown" || !sender) return; + auto down = self->GetVar>(u"PlatTable"); + if (std::ranges::find(down, sender->GetObjectID()) != down.end()) return; + down.push_back(sender->GetObjectID()); + if (static_cast(down.size()) < self->GetVarAs(u"NumberOfRocks")) { + self->SetVar>(u"PlatTable", down); + return; + } + // All of them are down + self->AddTimer("restartPlatforms", 1.0f); +} + +void FireTransRocksManager::SendRocksUp(Entity* self) { + for (auto* const rock : Game::entityManager->GetEntitiesInGroup(self->GetVarAsString(u"RockGroup"))) { + if (auto* const platform = rock->GetComponent()) platform->GotoWaypoint(1); + } +} + +void FireTransRocksManager::OnTimerDone(Entity* self, std::string timerName) { + if (timerName == "check") { + CheckForRocks(self); + } else if (timerName == "StartPlatforms") { + SendRocksUp(self); + } else if (timerName == "restartPlatforms") { + self->SetVar>(u"PlatTable", {}); + SendRocksUp(self); + } +} diff --git a/dScripts/02_server/Map/njhub/FireTransRocksManager.h b/dScripts/02_server/Map/njhub/FireTransRocksManager.h new file mode 100644 index 000000000..4d942f551 --- /dev/null +++ b/dScripts/02_server/Map/njhub/FireTransRocksManager.h @@ -0,0 +1,15 @@ +#pragma once +#include "CppScripts.h" + +// L_FIRE_TRANS_ROCKS_MANAGER.lua: the manager of the rocks in the NJ monastery's fire transition. Once all the rocks of +// its RockGroup are there (NumberOfRocks, 3) it sends them up 5 s later, and each time all of them are back down it +// sends them up again after 1 s. +class FireTransRocksManager : public CppScripts::Script { +public: + void OnStartup(Entity* self) override; + void OnNotifyObject(Entity* self, Entity* sender, const std::string& name, int32_t param1 = 0, int32_t param2 = 0) override; + void OnTimerDone(Entity* self, std::string timerName) override; +private: + void CheckForRocks(Entity* self); + void SendRocksUp(Entity* self); +}; diff --git a/dScripts/CppScripts.cpp b/dScripts/CppScripts.cpp index b927ab6df..0c2a30b4e 100644 --- a/dScripts/CppScripts.cpp +++ b/dScripts/CppScripts.cpp @@ -272,6 +272,8 @@ #include "NjNPCMissionSpinjitzuServer.h" #include "NjJayMissionItems.h" #include "FallingTile.h" +#include "FireTransRocks.h" +#include "FireTransRocksManager.h" #include "SimpleMoverSwitch.h" #include "SimpleOnceOnlyMoverSpinnerEvent.h" #include "ImaginationShrineServer.h" @@ -681,6 +683,8 @@ namespace { {"scripts\\02_server\\Map\\General\\Ninjago\\L_RAIL_POST_SERVER.lua", []() {return new NjRailPostServer();}}, {"scripts\\02_server\\Map\\General\\Ninjago\\L_ICE_RAIL_ACTIVATOR_SERVER.lua", []() {return new NjIceRailActivator();}}, {"scripts\\02_server\\Map\\njhub\\L_FALLING_TILE.lua", []() {return new FallingTile();}}, + {"scripts\\02_server\\Map\\njhub\\L_FIRE_TRANS_ROCKS.lua", []() {return new FireTransRocks();}}, + {"scripts\\02_server\\Map\\njhub\\L_FIRE_TRANS_ROCKS_MANAGER.lua", []() {return new FireTransRocksManager();}}, {"scripts\\02_server\\Map\\General\\L_SIMPLE_MOVER_SWITCH.lua", []() {return new SimpleMoverSwitch();}}, {"scripts\\02_server\\Map\\firetemple\\L_SIMPLE_ONCE_ONLY_MOVER_SPINNER_EVENT.lua", []() {return new SimpleOnceOnlyMoverSpinnerEvent();}}, {"scripts\\02_server\\Enemy\\General\\L_ENEMY_NJ_BUFF_STUN_IMMUNITY.lua", []() {return new EnemyNjBuff();}}, diff --git a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp index 61d37ae36..00b92846d 100644 --- a/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp +++ b/tests/dGameTests/dComponentsTests/MovingPlatformComponentTests.cpp @@ -9,6 +9,7 @@ #include "CDClientDatabase.h" #include "Entity.h" #include "GameMessages.h" +#include "02_server/Map/njhub/FireTransRocks.h" #include "LDFFormat.h" #include "MovementMessages.h" #include "MovingPlatformComponent.h" @@ -643,3 +644,41 @@ TEST_F(MovingPlatformComponentTest, OnceOnlyMoverGoesOnItsSpinnersEvent) { EXPECT_EQ(mover->mState, 2u); EXPECT_EQ(mover->mCurrentWaypointIndex, 0u); } + +// L_FIRE_TRANS_ROCKS: a rock that arrived at its top (waypoint 1) holds there (the PlatHold timer) and is then sent +// back down to waypoint 0 +TEST_F(MovingPlatformComponentTest, FireTransRockGoesBackDownAfterItsHold) { + Path path; + path.pathType = PathType::MovingPlatform; + path.pathName = "TestRockPath"; + path.pathBehavior = PathBehavior::Once; + PathWaypoint first; + first.position = NiPoint3(0.0f, 0.0f, 0.0f); + first.speed = 5.0f; + PathWaypoint second = first; + second.position = NiPoint3(0.0f, 10.0f, 0.0f); + path.pathWaypoints = { first, second }; + const_cast(Game::zoneManager->GetZone())->AddPath(path); + + info.settings.Insert(u"startPathingOnLoad", false); + Entity entity(288300744895900119, info); + info.settings.values.clear(); + auto* const platform = entity.AddComponent(-1, "TestRockPath"); + auto* const mover = platform->GetMoverSubComponent(); + FireTransRocks script; + script.OnStartup(&entity); + EXPECT_EQ(entity.GetVarAsString(u"RockManagerGroup"), "FireTransRocksManager"); + + platform->GotoWaypoint(1); + platform->Run(0.11f); + platform->Run(2.1f); + EXPECT_EQ(mover->mState, 28u); + EXPECT_EQ(mover->mCurrentWaypointIndex, 1u); + + script.OnTimerDone(&entity, "PlatHold"); + EXPECT_EQ(mover->mDesiredWaypointIndex, 0); + platform->Run(0.11f); + platform->Run(2.1f); + EXPECT_EQ(mover->mState, 28u); + EXPECT_EQ(mover->mCurrentWaypointIndex, 0u); +}