mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-04 09:44:10 +00:00
Organize dScripts (#814)
* Organize dScripts whitespace Remove parent scope Remove parent scope from initial setter Remove debug Remove helper programs * Fix NtImagimeterVisibility script Co-authored-by: aronwk-aaron <aronwk.aaron@gmail.com>
This commit is contained in:
14
dScripts/02_server/Map/njhub/BurningTile.cpp
Normal file
14
dScripts/02_server/Map/njhub/BurningTile.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "BurningTile.h"
|
||||
#include "SkillComponent.h"
|
||||
|
||||
void BurningTile::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) {
|
||||
if (args == "PlayerEntered") {
|
||||
auto* skillComponent = sender->GetComponent<SkillComponent>();
|
||||
|
||||
if (skillComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
skillComponent->CalculateBehavior(726, 11723, sender->GetObjectID(), true);
|
||||
}
|
||||
}
|
8
dScripts/02_server/Map/njhub/BurningTile.h
Normal file
8
dScripts/02_server/Map/njhub/BurningTile.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class BurningTile : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) override;
|
||||
};
|
31
dScripts/02_server/Map/njhub/CMakeLists.txt
Normal file
31
dScripts/02_server/Map/njhub/CMakeLists.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
set(DSCRIPTS_SOURCES_02_SERVER_MAP_NJHUB
|
||||
"BurningTile.cpp"
|
||||
"CatapultBaseServer.cpp"
|
||||
"CatapultBouncerServer.cpp"
|
||||
"CavePrisonCage.cpp"
|
||||
"EnemySkeletonSpawner.cpp"
|
||||
"FallingTile.cpp"
|
||||
"FlameJetServer.cpp"
|
||||
"ImaginationShrineServer.cpp"
|
||||
"Lieutenant.cpp"
|
||||
"MonCoreNookDoors.cpp"
|
||||
"MonCoreSmashableDoors.cpp"
|
||||
"NjColeNPC.cpp"
|
||||
"NjDragonEmblemChestServer.cpp"
|
||||
"NjEarthDragonPetServer.cpp"
|
||||
"NjEarthPetServer.cpp"
|
||||
"NjGarmadonCelebration.cpp"
|
||||
"NjJayMissionItems.cpp"
|
||||
"NjNPCMissionSpinjitzuServer.cpp"
|
||||
"NjNyaMissionitems.cpp"
|
||||
"NjScrollChestServer.cpp"
|
||||
"NjWuNPC.cpp"
|
||||
"RainOfArrows.cpp")
|
||||
|
||||
add_subdirectory(boss_instance)
|
||||
|
||||
foreach(file ${DSCRIPTS_SOURCES_02_SERVER_MAP_NJHUB_BOSS_INSTANCE})
|
||||
set(DSCRIPTS_SOURCES_02_SERVER_MAP_NJHUB ${DSCRIPTS_SOURCES_02_SERVER_MAP_NJHUB} "boss_instance/${file}")
|
||||
endforeach()
|
||||
|
||||
set(DSCRIPTS_SOURCES_02_SERVER_MAP_NJHUB ${DSCRIPTS_SOURCES_02_SERVER_MAP_NJHUB} PARENT_SCOPE)
|
64
dScripts/02_server/Map/njhub/CatapultBaseServer.cpp
Normal file
64
dScripts/02_server/Map/njhub/CatapultBaseServer.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "CatapultBaseServer.h"
|
||||
#include "GameMessages.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
void CatapultBaseServer::OnNotifyObject(Entity* self, Entity* sender, const std::string& name, int32_t param1, int32_t param2) {
|
||||
if (name == "BouncerBuilt") {
|
||||
// start a timer for the arm to player the with bouncer animation
|
||||
self->AddTimer("PlatAnim", .75);
|
||||
|
||||
// set the bouncer so we can use it later
|
||||
self->SetVar(u"Bouncer", sender->GetObjectID());
|
||||
|
||||
GameMessages::SendBouncerActiveStatus(sender->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
}
|
||||
}
|
||||
|
||||
void CatapultBaseServer::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "PlatAnim") {
|
||||
// get the arm asset
|
||||
const auto arm = EntityManager::Instance()->GetEntitiesInGroup(self->GetVarAsString(u"ArmGroup"));
|
||||
|
||||
// tell the arm to the play the platform animation, which is just the arm laying there but with bouncer
|
||||
for (auto* obj : arm) {
|
||||
GameMessages::SendPlayAnimation(obj, u"idle-platform");
|
||||
GameMessages::SendPlayNDAudioEmitter(obj, UNASSIGNED_SYSTEM_ADDRESS, "{8cccf912-69e3-4041-a20b-63e4afafc993}");
|
||||
// set the art so we can use it again
|
||||
self->SetVar(u"Arm", obj->GetObjectID());
|
||||
break;
|
||||
}
|
||||
|
||||
// start a timer till the bouncer actually bounces
|
||||
self->AddTimer("bounce", 3);
|
||||
} else if (timerName == "launchAnim") {
|
||||
// get the arm asset
|
||||
auto* arm = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"Arm"));
|
||||
if (arm == nullptr) return;
|
||||
|
||||
// tell the arm to player the launcher animation
|
||||
auto animTime = 1;
|
||||
self->AddTimer("resetArm", animTime);
|
||||
GameMessages::SendPlayAnimation(arm, u"launch");
|
||||
} else if (timerName == "bounce") {
|
||||
auto* bouncer = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"Bouncer"));
|
||||
if (bouncer == nullptr) return;
|
||||
|
||||
// bounce all players
|
||||
bouncer->NotifyObject(bouncer, "bounceAllInProximity"); // Likely to trigger server side bounce, bodging this
|
||||
// add a delay to play the animation
|
||||
self->AddTimer("launchAnim", .3);
|
||||
} else if (timerName == "resetArm") {
|
||||
auto* arm = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"Arm"));
|
||||
if (arm == nullptr) return;
|
||||
|
||||
// set the arm back to natural state
|
||||
GameMessages::SendPlayAnimation(arm, u"idle");
|
||||
|
||||
auto* bouncer = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"Bouncer"));
|
||||
if (bouncer == nullptr) return;
|
||||
|
||||
// kill the bouncer
|
||||
GameMessages::SendNotifyClientObject(bouncer->GetObjectID(), u"TimeToDie");
|
||||
bouncer->Smash(self->GetObjectID(), VIOLENT);
|
||||
}
|
||||
}
|
9
dScripts/02_server/Map/njhub/CatapultBaseServer.h
Normal file
9
dScripts/02_server/Map/njhub/CatapultBaseServer.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class CatapultBaseServer : public CppScripts::Script {
|
||||
public:
|
||||
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;
|
||||
};
|
15
dScripts/02_server/Map/njhub/CatapultBouncerServer.cpp
Normal file
15
dScripts/02_server/Map/njhub/CatapultBouncerServer.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "CatapultBouncerServer.h"
|
||||
#include "GameMessages.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
void CatapultBouncerServer::OnRebuildComplete(Entity* self, Entity* target) {
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"Built", 0, 0, LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
self->SetNetworkVar<bool>(u"Built", true);
|
||||
|
||||
const auto base = EntityManager::Instance()->GetEntitiesInGroup(self->GetVarAsString(u"BaseGroup"));
|
||||
|
||||
for (auto* obj : base) {
|
||||
obj->NotifyObject(self, "BouncerBuilt");
|
||||
}
|
||||
}
|
7
dScripts/02_server/Map/njhub/CatapultBouncerServer.h
Normal file
7
dScripts/02_server/Map/njhub/CatapultBouncerServer.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class CatapultBouncerServer : public CppScripts::Script {
|
||||
public:
|
||||
void OnRebuildComplete(Entity* self, Entity* target) override;
|
||||
};
|
215
dScripts/02_server/Map/njhub/CavePrisonCage.cpp
Normal file
215
dScripts/02_server/Map/njhub/CavePrisonCage.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
#include "CavePrisonCage.h"
|
||||
#include "EntityManager.h"
|
||||
#include "RebuildComponent.h"
|
||||
#include "GameMessages.h"
|
||||
#include "Character.h"
|
||||
#include "dZoneManager.h"
|
||||
|
||||
void CavePrisonCage::OnStartup(Entity* self) {
|
||||
const auto& myNum = self->GetVar<std::u16string>(u"myNumber");
|
||||
|
||||
if (myNum.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* spawner = dZoneManager::Instance()->GetSpawnersByName("PrisonCounterweight_0" + GeneralUtils::UTF16ToWTF8(myNum))[0];
|
||||
|
||||
self->SetVar<Spawner*>(u"CWSpawner", spawner);
|
||||
|
||||
Setup(self, spawner);
|
||||
}
|
||||
|
||||
void CavePrisonCage::Setup(Entity* self, Spawner* spawner) {
|
||||
SpawnCounterweight(self, spawner);
|
||||
|
||||
NiPoint3 mypos = self->GetPosition();
|
||||
NiQuaternion myrot = self->GetRotation();
|
||||
|
||||
mypos.y += 1.5;
|
||||
mypos.z -= 0.5;
|
||||
|
||||
EntityInfo info{};
|
||||
info.lot = m_Villagers[self->GetVarAs<int32_t>(u"myNumber") - 1];
|
||||
info.pos = mypos;
|
||||
info.rot = myrot;
|
||||
info.spawnerID = self->GetObjectID();
|
||||
|
||||
// Spawn the villager inside the jail
|
||||
auto* entity = EntityManager::Instance()->CreateEntity(info);
|
||||
|
||||
// Save the villeger ID
|
||||
self->SetVar<LWOOBJID>(u"villager", entity->GetObjectID());
|
||||
|
||||
// Construct the entity
|
||||
EntityManager::Instance()->ConstructEntity(entity);
|
||||
}
|
||||
|
||||
void CavePrisonCage::OnRebuildNotifyState(Entity* self, eRebuildState state) {
|
||||
if (state != eRebuildState::REBUILD_RESETTING) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* spawner = self->GetVar<Spawner*>(u"CWSpawner");
|
||||
|
||||
if (spawner == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
spawner->Reset();
|
||||
|
||||
SpawnCounterweight(self, spawner);
|
||||
}
|
||||
|
||||
void CavePrisonCage::SpawnCounterweight(Entity* self, Spawner* spawner) {
|
||||
spawner->Reset();
|
||||
|
||||
auto* counterweight = spawner->Spawn();
|
||||
|
||||
self->SetVar<LWOOBJID>(u"Counterweight", counterweight->GetObjectID());
|
||||
|
||||
auto* rebuildComponent = counterweight->GetComponent<RebuildComponent>();
|
||||
|
||||
if (rebuildComponent != nullptr) {
|
||||
rebuildComponent->AddRebuildStateCallback([this, self](eRebuildState state) {
|
||||
OnRebuildNotifyState(self, state);
|
||||
});
|
||||
|
||||
rebuildComponent->AddRebuildCompleteCallback([this, self](Entity* user) {
|
||||
// The counterweight is a simple mover, which is not implemented, so we'll just set it's position
|
||||
auto* counterweight = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"Counterweight"));
|
||||
|
||||
if (counterweight == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Move the counterweight down 2 units
|
||||
counterweight->SetPosition(counterweight->GetPosition() + NiPoint3(0, -2, 0));
|
||||
|
||||
// Serialize the counterweight
|
||||
EntityManager::Instance()->SerializeEntity(counterweight);
|
||||
|
||||
// notifyPlatformAtLastWaypoint
|
||||
|
||||
// Save the userID as Builder
|
||||
self->SetVar<LWOOBJID>(u"Builder", user->GetObjectID());
|
||||
|
||||
// Get the button and make sure it still exists
|
||||
auto* button = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"Button"));
|
||||
|
||||
if (button == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Play the 'down' animation on the button
|
||||
GameMessages::SendPlayAnimation(button, u"down");
|
||||
|
||||
// Setup a timer named 'buttonGoingDown' to be triggered in 5 seconds
|
||||
self->AddTimer("buttonGoingDown", 5.0f);
|
||||
});
|
||||
}
|
||||
|
||||
if (self->GetVar<LWOOBJID>(u"Button")) {
|
||||
return;
|
||||
}
|
||||
|
||||
GetButton(self);
|
||||
}
|
||||
|
||||
void CavePrisonCage::GetButton(Entity* self) {
|
||||
const auto buttons = EntityManager::Instance()->GetEntitiesInGroup("PrisonButton_0" + std::to_string(self->GetVarAs<int32_t>(u"myNumber")));
|
||||
|
||||
if (buttons.size() == 0) {
|
||||
// Try again in 0.5 seconds
|
||||
self->AddCallbackTimer(0.5, [this, self]() {
|
||||
GetButton(self);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto* button = buttons[0];
|
||||
|
||||
self->SetVar<LWOOBJID>(u"Button", button->GetObjectID());
|
||||
}
|
||||
|
||||
void CavePrisonCage::OnTimerDone(Entity* self, std::string timerName) {
|
||||
// the anim of the button down is over
|
||||
if (timerName == "buttonGoingDown") {
|
||||
// Play the 'up' animation
|
||||
GameMessages::SendPlayAnimation(self, u"up");
|
||||
|
||||
// Setup a timer named 'CageOpen' to be triggered in 1 second
|
||||
self->AddTimer("CageOpen", 1.0f);
|
||||
} else if (timerName == "CageOpen") {
|
||||
// play the idle open anim
|
||||
GameMessages::SendPlayAnimation(self, u"idle-up");
|
||||
|
||||
// Get the villeger
|
||||
auto* villager = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"villager"));
|
||||
|
||||
if (villager == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
GameMessages::SendNotifyClientObject(villager->GetObjectID(), u"TimeToChat", 0, 0, LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
// Get the builder and make sure it still exists
|
||||
auto* builder = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"Builder"));
|
||||
|
||||
if (builder == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto flagNum = 2020 + self->GetVarAs<int32_t>(u"myNumber");
|
||||
|
||||
// Set the flag on the builder character
|
||||
builder->GetCharacter()->SetPlayerFlag(flagNum, true);
|
||||
|
||||
// Setup a timer named 'VillagerEscape' to be triggered in 5 seconds
|
||||
self->AddTimer("VillagerEscape", 5.0f);
|
||||
} else if (timerName == "VillagerEscape") {
|
||||
// Get the villeger and make sure it still exists
|
||||
auto* villager = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"villager"));
|
||||
|
||||
if (villager == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Kill the villager
|
||||
villager->Kill();
|
||||
|
||||
// Setup a timer named 'SmashCounterweight' to be triggered in 2 seconds
|
||||
self->AddTimer("SmashCounterweight", 2.0f);
|
||||
} else if (timerName == "SmashCounterweight") {
|
||||
// Get the counterweight and make sure it still exists
|
||||
auto* counterweight = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"Counterweight"));
|
||||
|
||||
if (counterweight == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Smash the counterweight
|
||||
counterweight->Smash();
|
||||
|
||||
// Get the button and make sure it still exists
|
||||
auto* button = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"Button"));
|
||||
|
||||
if (button == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Play the 'up' animation on the button
|
||||
GameMessages::SendPlayAnimation(button, u"up");
|
||||
|
||||
// Setup a timer named 'CageClosed' to be triggered in 1 second
|
||||
self->AddTimer("CageClosed", 1.0f);
|
||||
} else if (timerName == "CageClosed") {
|
||||
// play the idle closed anim
|
||||
GameMessages::SendPlayAnimation(self, u"idle");
|
||||
|
||||
// Setup a timer named 'ResetPrison' to be triggered in 10 seconds
|
||||
self->AddTimer("ResetPrison", 10.0f);
|
||||
} else if (timerName == "ResetPrison") {
|
||||
Setup(self, self->GetVar<Spawner*>(u"CWSpawner"));
|
||||
}
|
||||
}
|
16
dScripts/02_server/Map/njhub/CavePrisonCage.h
Normal file
16
dScripts/02_server/Map/njhub/CavePrisonCage.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class CavePrisonCage : public CppScripts::Script {
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void Setup(Entity* self, Spawner* spawner);
|
||||
void OnRebuildNotifyState(Entity* self, eRebuildState state) override;
|
||||
void SpawnCounterweight(Entity* self, Spawner* spawner);
|
||||
void GetButton(Entity* self);
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
|
||||
private:
|
||||
std::vector<LOT> m_Villagers = { 15851, 15866, 15922, 15924, 15927, 15929 };
|
||||
std::vector<int32_t> m_Missions = { 1801, 2039 };
|
||||
};
|
75
dScripts/02_server/Map/njhub/EnemySkeletonSpawner.cpp
Normal file
75
dScripts/02_server/Map/njhub/EnemySkeletonSpawner.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include "EnemySkeletonSpawner.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "RenderComponent.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
void EnemySkeletonSpawner::OnStartup(Entity* self) {
|
||||
self->SetProximityRadius(15, "ronin");
|
||||
|
||||
auto* skillComponent = self->GetComponent<SkillComponent>();
|
||||
|
||||
if (skillComponent != nullptr) {
|
||||
skillComponent->CalculateBehavior(1127, 24812, LWOOBJID_EMPTY, true);
|
||||
}
|
||||
}
|
||||
|
||||
void EnemySkeletonSpawner::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "hatchTime") {
|
||||
auto* renderComponent = self->GetComponent<RenderComponent>();
|
||||
|
||||
if (renderComponent != nullptr) {
|
||||
renderComponent->PlayEffect(644, u"create", "BurstFX1");
|
||||
}
|
||||
|
||||
EntityInfo info{};
|
||||
info.lot = 14024;
|
||||
info.pos = self->GetPosition();
|
||||
info.rot = self->GetRotation();
|
||||
info.spawnerID = self->GetObjectID();
|
||||
|
||||
auto* spawnedEntity = EntityManager::Instance()->CreateEntity(info);
|
||||
|
||||
if (spawnedEntity == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
EntityManager::Instance()->ConstructEntity(spawnedEntity);
|
||||
|
||||
spawnedEntity->AddCallbackTimer(60, [spawnedEntity]() {
|
||||
spawnedEntity->Smash(spawnedEntity->GetObjectID());
|
||||
});
|
||||
|
||||
self->Smash(self->GetObjectID());
|
||||
}
|
||||
}
|
||||
|
||||
void EnemySkeletonSpawner::OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) {
|
||||
if (entering->IsPlayer() && name == "ronin" && status == "ENTER" && !self->GetVar<bool>(u"hatching")) {
|
||||
StartHatching(self);
|
||||
|
||||
auto* skillComponent = self->GetComponent<SkillComponent>();
|
||||
|
||||
if (skillComponent != nullptr) {
|
||||
skillComponent->CalculateBehavior(305, 3568, LWOOBJID_EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnemySkeletonSpawner::OnHit(Entity* self, Entity* attacker) {
|
||||
if (!self->GetVar<bool>(u"hatching")) {
|
||||
StartHatching(self);
|
||||
}
|
||||
}
|
||||
|
||||
void EnemySkeletonSpawner::StartHatching(Entity* self) {
|
||||
self->SetVar(u"hatching", true);
|
||||
|
||||
auto* renderComponent = self->GetComponent<RenderComponent>();
|
||||
|
||||
if (renderComponent != nullptr) {
|
||||
renderComponent->PlayEffect(9017, u"cast", "WakeUpFX1");
|
||||
renderComponent->PlayEffect(9018, u"burst", "WakeUpFX1");
|
||||
}
|
||||
|
||||
self->AddTimer("hatchTime", 2);
|
||||
}
|
12
dScripts/02_server/Map/njhub/EnemySkeletonSpawner.h
Normal file
12
dScripts/02_server/Map/njhub/EnemySkeletonSpawner.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class EnemySkeletonSpawner final : public CppScripts::Script {
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) override;
|
||||
void OnHit(Entity* self, Entity* attacker) override;
|
||||
void StartHatching(Entity* self);
|
||||
};
|
||||
|
55
dScripts/02_server/Map/njhub/FallingTile.cpp
Normal file
55
dScripts/02_server/Map/njhub/FallingTile.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#include "FallingTile.h"
|
||||
#include "MovingPlatformComponent.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void FallingTile::OnStartup(Entity* self) {
|
||||
auto* movingPlatfromComponent = self->GetComponent<MovingPlatformComponent>();
|
||||
|
||||
if (movingPlatfromComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
movingPlatfromComponent->SetSerialized(true);
|
||||
}
|
||||
|
||||
void FallingTile::OnCollisionPhantom(Entity* self, Entity* target) {
|
||||
if (self->GetVar<bool>(u"AboutToFall")) {
|
||||
return;
|
||||
}
|
||||
|
||||
self->AddTimer("flipTime", 0.75f);
|
||||
|
||||
self->SetVar<bool>(u"AboutToFall", true);
|
||||
|
||||
self->SetNetworkVar<float>(u"startEffect", 2);
|
||||
}
|
||||
|
||||
void FallingTile::OnWaypointReached(Entity* self, uint32_t waypointIndex) {
|
||||
if (waypointIndex == 1) {
|
||||
} else if (waypointIndex == 0) {
|
||||
}
|
||||
}
|
||||
|
||||
void FallingTile::OnTimerDone(Entity* self, std::string timerName) {
|
||||
auto* movingPlatfromComponent = self->GetComponent<MovingPlatformComponent>();
|
||||
|
||||
if (movingPlatfromComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (timerName == "flipTime") {
|
||||
self->AddTimer("flipBack", 2.0f);
|
||||
|
||||
self->SetNetworkVar<float>(u"stopEffect", 3);
|
||||
|
||||
movingPlatfromComponent->GotoWaypoint(1);
|
||||
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), -1, u"down", "down");
|
||||
} else if (timerName == "flipBack") {
|
||||
self->SetVar<bool>(u"AboutToFall", false);
|
||||
|
||||
movingPlatfromComponent->GotoWaypoint(0);
|
||||
|
||||
GameMessages::SendPlayFXEffect(self->GetObjectID(), -1, u"up", "up");
|
||||
}
|
||||
}
|
11
dScripts/02_server/Map/njhub/FallingTile.h
Normal file
11
dScripts/02_server/Map/njhub/FallingTile.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FallingTile : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnCollisionPhantom(Entity* self, Entity* target) override;
|
||||
void OnWaypointReached(Entity* self, uint32_t waypointIndex) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
};
|
47
dScripts/02_server/Map/njhub/FlameJetServer.cpp
Normal file
47
dScripts/02_server/Map/njhub/FlameJetServer.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#include "FlameJetServer.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void FlameJetServer::OnStartup(Entity* self) {
|
||||
if (self->GetVar<bool>(u"NotActive")) {
|
||||
return;
|
||||
}
|
||||
|
||||
self->SetNetworkVar<bool>(u"FlameOn", true);
|
||||
}
|
||||
|
||||
void FlameJetServer::OnCollisionPhantom(Entity* self, Entity* target) {
|
||||
if (!target->IsPlayer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self->GetNetworkVar<bool>(u"FlameOn")) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* skillComponent = target->GetComponent<SkillComponent>();
|
||||
|
||||
if (skillComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
skillComponent->CalculateBehavior(726, 11723, target->GetObjectID(), true);
|
||||
|
||||
auto dir = target->GetRotation().GetForwardVector();
|
||||
|
||||
dir.y = 25;
|
||||
dir.x = -dir.x * 15;
|
||||
dir.z = -dir.z * 15;
|
||||
|
||||
GameMessages::SendKnockback(target->GetObjectID(), self->GetObjectID(), self->GetObjectID(), 1000, dir);
|
||||
}
|
||||
|
||||
void FlameJetServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) {
|
||||
Game::logger->Log("FlameJetServer::OnFireEventServerSide", "Event: %s", args.c_str());
|
||||
|
||||
if (args == "OnActivated") {
|
||||
self->SetNetworkVar<bool>(u"FlameOn", false);
|
||||
} else if (args == "OnDectivated") {
|
||||
self->SetNetworkVar<bool>(u"FlameOn", true);
|
||||
}
|
||||
}
|
10
dScripts/02_server/Map/njhub/FlameJetServer.h
Normal file
10
dScripts/02_server/Map/njhub/FlameJetServer.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class FlameJetServer : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnCollisionPhantom(Entity* self, Entity* target) override;
|
||||
void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) override;
|
||||
};
|
16
dScripts/02_server/Map/njhub/ImaginationShrineServer.cpp
Normal file
16
dScripts/02_server/Map/njhub/ImaginationShrineServer.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "ImaginationShrineServer.h"
|
||||
#include "RebuildComponent.h"
|
||||
|
||||
void ImaginationShrineServer::OnUse(Entity* self, Entity* user) {
|
||||
// If the rebuild component is complete, use the shrine
|
||||
auto* rebuildComponent = self->GetComponent<RebuildComponent>();
|
||||
|
||||
if (rebuildComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rebuildComponent->GetState() == REBUILD_COMPLETED) {
|
||||
// Use the shrine
|
||||
BaseUse(self, user);
|
||||
}
|
||||
}
|
10
dScripts/02_server/Map/njhub/ImaginationShrineServer.h
Normal file
10
dScripts/02_server/Map/njhub/ImaginationShrineServer.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
#include "BaseInteractDropLootServer.h"
|
||||
|
||||
class ImaginationShrineServer : public BaseInteractDropLootServer
|
||||
{
|
||||
public:
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
};
|
||||
|
44
dScripts/02_server/Map/njhub/Lieutenant.cpp
Normal file
44
dScripts/02_server/Map/njhub/Lieutenant.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "Lieutenant.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "dZoneManager.h"
|
||||
|
||||
void Lieutenant::OnStartup(Entity* self) {
|
||||
auto* skillComponent = self->GetComponent<SkillComponent>();
|
||||
|
||||
if (skillComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
skillComponent->CalculateBehavior(1127, 24812, self->GetObjectID(), true);
|
||||
}
|
||||
|
||||
void Lieutenant::OnDie(Entity* self, Entity* killer) {
|
||||
const auto myLOT = self->GetLOT();
|
||||
|
||||
std::string spawnerName;
|
||||
|
||||
switch (myLOT) {
|
||||
case 16047:
|
||||
spawnerName = "EarthShrine_ERail";
|
||||
break;
|
||||
case 16050:
|
||||
spawnerName = "IceShrine_QBBouncer";
|
||||
break;
|
||||
case 16049:
|
||||
spawnerName = "LightningShrine_LRail";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
const auto spawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName);
|
||||
|
||||
if (spawners.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto* spawner : spawners) {
|
||||
spawner->Reset();
|
||||
spawner->Activate();
|
||||
}
|
||||
}
|
11
dScripts/02_server/Map/njhub/Lieutenant.h
Normal file
11
dScripts/02_server/Map/njhub/Lieutenant.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class Lieutenant : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
|
||||
void OnDie(Entity* self, Entity* killer) override;
|
||||
};
|
||||
|
37
dScripts/02_server/Map/njhub/MonCoreNookDoors.cpp
Normal file
37
dScripts/02_server/Map/njhub/MonCoreNookDoors.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "MonCoreNookDoors.h"
|
||||
#include "dZoneManager.h"
|
||||
|
||||
void MonCoreNookDoors::OnStartup(Entity* self) {
|
||||
SpawnDoor(self);
|
||||
}
|
||||
|
||||
void MonCoreNookDoors::SpawnDoor(Entity* self) {
|
||||
const auto doorNum = self->GetVarAsString(u"number");
|
||||
|
||||
if (doorNum.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto spawners = dZoneManager::Instance()->GetSpawnersByName("MonCoreNookDoor0" + doorNum);
|
||||
|
||||
if (spawners.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* spawner = spawners[0];
|
||||
|
||||
spawner->Reset();
|
||||
spawner->Activate();
|
||||
}
|
||||
|
||||
void MonCoreNookDoors::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) {
|
||||
if (args == "DoorSmashed") {
|
||||
self->AddTimer("RespawnDoor", 30);
|
||||
}
|
||||
}
|
||||
|
||||
void MonCoreNookDoors::OnTimerDone(Entity* self, std::string timerName) {
|
||||
if (timerName == "RespawnDoor") {
|
||||
SpawnDoor(self);
|
||||
}
|
||||
}
|
14
dScripts/02_server/Map/njhub/MonCoreNookDoors.h
Normal file
14
dScripts/02_server/Map/njhub/MonCoreNookDoors.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class MonCoreNookDoors : public CppScripts::Script {
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
|
||||
void SpawnDoor(Entity* self);
|
||||
|
||||
void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) override;
|
||||
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
};
|
||||
|
21
dScripts/02_server/Map/njhub/MonCoreSmashableDoors.cpp
Normal file
21
dScripts/02_server/Map/njhub/MonCoreSmashableDoors.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "MonCoreSmashableDoors.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
void MonCoreSmashableDoors::OnDie(Entity* self, Entity* killer) {
|
||||
auto myNum = self->GetVarAsString(u"spawner_name");
|
||||
|
||||
myNum = myNum.substr(myNum.length() - 1, 1);
|
||||
|
||||
auto triggerGroup = "CoreNookTrig0" + myNum;
|
||||
|
||||
// Get the trigger
|
||||
auto triggers = EntityManager::Instance()->GetEntitiesInGroup(triggerGroup);
|
||||
|
||||
if (triggers.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto trigger : triggers) {
|
||||
trigger->OnFireEventServerSide(self, "DoorSmashed");
|
||||
}
|
||||
}
|
8
dScripts/02_server/Map/njhub/MonCoreSmashableDoors.h
Normal file
8
dScripts/02_server/Map/njhub/MonCoreSmashableDoors.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class MonCoreSmashableDoors : public CppScripts::Script {
|
||||
public:
|
||||
void OnDie(Entity* self, Entity* killer) override;
|
||||
};
|
||||
|
48
dScripts/02_server/Map/njhub/NjColeNPC.cpp
Normal file
48
dScripts/02_server/Map/njhub/NjColeNPC.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "NjColeNPC.h"
|
||||
#include "MissionComponent.h"
|
||||
#include "InventoryComponent.h"
|
||||
|
||||
void NjColeNPC::OnEmoteReceived(Entity* self, int32_t emote, Entity* target) {
|
||||
if (emote != 393) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* inventoryComponent = target->GetComponent<InventoryComponent>();
|
||||
|
||||
if (inventoryComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inventoryComponent->IsEquipped(14499) && !inventoryComponent->IsEquipped(16644)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* missionComponent = target->GetComponent<MissionComponent>();
|
||||
|
||||
if (missionComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
missionComponent->ForceProgressTaskType(1818, 1, 1);
|
||||
}
|
||||
|
||||
void NjColeNPC::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) {
|
||||
NjNPCMissionSpinjitzuServer::OnMissionDialogueOK(self, target, missionID, missionState);
|
||||
|
||||
if (missionID == 1818 && missionState >= MissionState::MISSION_STATE_READY_TO_COMPLETE) {
|
||||
auto* missionComponent = target->GetComponent<MissionComponent>();
|
||||
auto* inventoryComponent = target->GetComponent<InventoryComponent>();
|
||||
|
||||
if (missionComponent == nullptr || inventoryComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (inventoryComponent->GetLotCount(14499) > 0) {
|
||||
inventoryComponent->RemoveItem(14499, 1);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
inventoryComponent->AddItem(16644, 1, eLootSourceType::LOOT_SOURCE_NONE);
|
||||
}
|
||||
}
|
7
dScripts/02_server/Map/njhub/NjColeNPC.h
Normal file
7
dScripts/02_server/Map/njhub/NjColeNPC.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "NjNPCMissionSpinjitzuServer.h"
|
||||
|
||||
class NjColeNPC : public NjNPCMissionSpinjitzuServer {
|
||||
void OnEmoteReceived(Entity* self, int32_t emote, Entity* target) override;
|
||||
|
||||
void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override;
|
||||
};
|
15
dScripts/02_server/Map/njhub/NjDragonEmblemChestServer.cpp
Normal file
15
dScripts/02_server/Map/njhub/NjDragonEmblemChestServer.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "NjDragonEmblemChestServer.h"
|
||||
#include "Character.h"
|
||||
#include "DestroyableComponent.h"
|
||||
|
||||
void NjDragonEmblemChestServer::OnUse(Entity* self, Entity* user) {
|
||||
auto* character = user->GetCharacter();
|
||||
if (character != nullptr) {
|
||||
character->SetPlayerFlag(NJ_WU_SHOW_DAILY_CHEST, false);
|
||||
}
|
||||
|
||||
auto* destroyable = self->GetComponent<DestroyableComponent>();
|
||||
if (destroyable != nullptr) {
|
||||
LootGenerator::Instance().DropLoot(user, self, destroyable->GetLootMatrixID(), 0, 0);
|
||||
}
|
||||
}
|
6
dScripts/02_server/Map/njhub/NjDragonEmblemChestServer.h
Normal file
6
dScripts/02_server/Map/njhub/NjDragonEmblemChestServer.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class NjDragonEmblemChestServer : public CppScripts::Script {
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
};
|
10
dScripts/02_server/Map/njhub/NjEarthDragonPetServer.cpp
Normal file
10
dScripts/02_server/Map/njhub/NjEarthDragonPetServer.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "NjEarthDragonPetServer.h"
|
||||
#include "Entity.h"
|
||||
|
||||
void NjEarthDragonPetServer::SetVariables(Entity* self) {
|
||||
self->SetVar<LOT>(u"petLOT", 16210);
|
||||
self->SetVar<std::string>(u"petType", "earthpet");
|
||||
self->SetVar<uint32_t>(u"maxPets", 3);
|
||||
self->SetVar<std::u16string>(u"spawnAnim", u"spawn");
|
||||
self->SetVar<std::u16string>(u"spawnCinematic", u"EarthPetSpawn");
|
||||
}
|
6
dScripts/02_server/Map/njhub/NjEarthDragonPetServer.h
Normal file
6
dScripts/02_server/Map/njhub/NjEarthDragonPetServer.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "SpawnPetBaseServer.h"
|
||||
|
||||
class NjEarthDragonPetServer : public SpawnPetBaseServer {
|
||||
void SetVariables(Entity* self) override;
|
||||
};
|
12
dScripts/02_server/Map/njhub/NjEarthPetServer.cpp
Normal file
12
dScripts/02_server/Map/njhub/NjEarthPetServer.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "NjEarthPetServer.h"
|
||||
#include "PetComponent.h"
|
||||
|
||||
void NjEarthPetServer::OnStartup(Entity* self) {
|
||||
auto* petComponent = self->GetComponent<PetComponent>();
|
||||
if (petComponent == nullptr || petComponent->GetOwnerId() != LWOOBJID_EMPTY)
|
||||
return;
|
||||
|
||||
// Removes the chocolate bars
|
||||
petComponent->SetPreconditions(const_cast<std::string&>(m_Precondition));
|
||||
PetFromObjectServer::OnStartup(self);
|
||||
}
|
7
dScripts/02_server/Map/njhub/NjEarthPetServer.h
Normal file
7
dScripts/02_server/Map/njhub/NjEarthPetServer.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include "PetFromObjectServer.h"
|
||||
|
||||
class NjEarthPetServer : public PetFromObjectServer {
|
||||
void OnStartup(Entity* self) override;
|
||||
const std::string m_Precondition = "279";
|
||||
};
|
17
dScripts/02_server/Map/njhub/NjGarmadonCelebration.cpp
Normal file
17
dScripts/02_server/Map/njhub/NjGarmadonCelebration.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "NjGarmadonCelebration.h"
|
||||
#include "Character.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void NjGarmadonCelebration::OnCollisionPhantom(Entity* self, Entity* target) {
|
||||
auto* character = target->GetCharacter();
|
||||
|
||||
if (character == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!character->GetPlayerFlag(ePlayerFlags::NJ_GARMADON_CINEMATIC_SEEN)) {
|
||||
character->SetPlayerFlag(ePlayerFlags::NJ_GARMADON_CINEMATIC_SEEN, true);
|
||||
|
||||
GameMessages::SendStartCelebrationEffect(target, target->GetSystemAddress(), GarmadonCelebrationID);
|
||||
}
|
||||
}
|
8
dScripts/02_server/Map/njhub/NjGarmadonCelebration.h
Normal file
8
dScripts/02_server/Map/njhub/NjGarmadonCelebration.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class NjGarmadonCelebration : public CppScripts::Script {
|
||||
void OnCollisionPhantom(Entity* self, Entity* target) override;
|
||||
private:
|
||||
const int32_t GarmadonCelebrationID = 23;
|
||||
};
|
13
dScripts/02_server/Map/njhub/NjJayMissionItems.cpp
Normal file
13
dScripts/02_server/Map/njhub/NjJayMissionItems.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "NjJayMissionItems.h"
|
||||
|
||||
void NjJayMissionItems::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) {
|
||||
NjNPCMissionSpinjitzuServer::OnMissionDialogueOK(self, target, missionID, missionState);
|
||||
NPCAddRemoveItem::OnMissionDialogueOK(self, target, missionID, missionState);
|
||||
}
|
||||
|
||||
std::map<uint32_t, std::vector<ItemSetting>> NjJayMissionItems::GetSettings() {
|
||||
return {
|
||||
{1789, {{{14474},false, true}}},
|
||||
{1927, {{{14493},false, true}}}
|
||||
};
|
||||
}
|
10
dScripts/02_server/Map/njhub/NjJayMissionItems.h
Normal file
10
dScripts/02_server/Map/njhub/NjJayMissionItems.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "NjNPCMissionSpinjitzuServer.h"
|
||||
#include "NPCAddRemoveItem.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class NjJayMissionItems : public NjNPCMissionSpinjitzuServer, NPCAddRemoveItem {
|
||||
void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override;
|
||||
std::map<uint32_t, std::vector<ItemSetting>> GetSettings() override;
|
||||
};
|
24
dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp
Normal file
24
dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "NjNPCMissionSpinjitzuServer.h"
|
||||
#include "Character.h"
|
||||
#include "EntityManager.h"
|
||||
|
||||
void NjNPCMissionSpinjitzuServer::OnMissionDialogueOK(Entity* self, Entity* target, int missionID,
|
||||
MissionState missionState) {
|
||||
|
||||
const auto& element = self->GetVar<std::u16string>(ElementVariable);
|
||||
if (missionID == ElementMissions.at(element) && missionState >= MissionState::MISSION_STATE_READY_TO_COMPLETE) {
|
||||
|
||||
const auto targetID = target->GetObjectID();
|
||||
|
||||
// Wait for an animation to complete and flag that the player has learned spinjitzu
|
||||
self->AddCallbackTimer(5.0f, [targetID, element]() {
|
||||
auto* target = EntityManager::Instance()->GetEntity(targetID);
|
||||
if (target != nullptr) {
|
||||
auto* character = target->GetCharacter();
|
||||
if (character != nullptr) {
|
||||
character->SetPlayerFlag(ElementFlags.at(element), true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
24
dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.h
Normal file
24
dScripts/02_server/Map/njhub/NjNPCMissionSpinjitzuServer.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
#include <map>
|
||||
|
||||
static std::map<std::u16string, uint32_t> ElementFlags = {
|
||||
{u"earth", ePlayerFlags::NJ_EARTH_SPINJITZU},
|
||||
{u"lightning", ePlayerFlags::NJ_LIGHTNING_SPINJITZU},
|
||||
{u"ice", ePlayerFlags::NJ_ICE_SPINJITZU},
|
||||
{u"fire", ePlayerFlags::NJ_FIRE_SPINJITZU}
|
||||
};
|
||||
|
||||
static std::map<std::u16string, uint32_t> ElementMissions = {
|
||||
{u"earth", 1796},
|
||||
{u"lightning", 1952},
|
||||
{u"ice", 1959},
|
||||
{u"fire", 1962},
|
||||
};
|
||||
|
||||
class NjNPCMissionSpinjitzuServer : public CppScripts::Script {
|
||||
public:
|
||||
void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override;
|
||||
private:
|
||||
const std::u16string ElementVariable = u"element";
|
||||
};
|
8
dScripts/02_server/Map/njhub/NjNyaMissionitems.cpp
Normal file
8
dScripts/02_server/Map/njhub/NjNyaMissionitems.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "NjNyaMissionitems.h"
|
||||
|
||||
std::map<uint32_t, std::vector<ItemSetting>> NjNyaMissionitems::GetSettings() {
|
||||
return {
|
||||
{1809, {{{14472}, true, false}}},
|
||||
{1821, {{{14500}, false, true}}}
|
||||
};
|
||||
}
|
8
dScripts/02_server/Map/njhub/NjNyaMissionitems.h
Normal file
8
dScripts/02_server/Map/njhub/NjNyaMissionitems.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "NPCAddRemoveItem.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class NjNyaMissionitems : public NPCAddRemoveItem {
|
||||
std::map<uint32_t, std::vector<ItemSetting>> GetSettings() override;
|
||||
};
|
17
dScripts/02_server/Map/njhub/NjScrollChestServer.cpp
Normal file
17
dScripts/02_server/Map/njhub/NjScrollChestServer.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "NjScrollChestServer.h"
|
||||
#include "InventoryComponent.h"
|
||||
|
||||
void NjScrollChestServer::OnUse(Entity* self, Entity* user) {
|
||||
const auto keyLOT = self->GetVar<LOT>(u"KeyNum");
|
||||
const auto rewardItemLOT = self->GetVar<LOT>(u"openItemID");
|
||||
|
||||
auto* playerInventory = user->GetComponent<InventoryComponent>();
|
||||
if (playerInventory != nullptr && playerInventory->GetLotCount(keyLOT) == 1) {
|
||||
|
||||
// Check for the key and remove
|
||||
playerInventory->RemoveItem(keyLOT, 1);
|
||||
|
||||
// Reward the player with the item set
|
||||
playerInventory->AddItem(rewardItemLOT, 1, eLootSourceType::LOOT_SOURCE_NONE);
|
||||
}
|
||||
}
|
6
dScripts/02_server/Map/njhub/NjScrollChestServer.h
Normal file
6
dScripts/02_server/Map/njhub/NjScrollChestServer.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class NjScrollChestServer : public CppScripts::Script {
|
||||
void OnUse(Entity* self, Entity* user) override;
|
||||
};
|
63
dScripts/02_server/Map/njhub/NjWuNPC.cpp
Normal file
63
dScripts/02_server/Map/njhub/NjWuNPC.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "NjWuNPC.h"
|
||||
#include "MissionComponent.h"
|
||||
#include "Character.h"
|
||||
#include "EntityManager.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void NjWuNPC::OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) {
|
||||
|
||||
// The Dragon statue daily mission
|
||||
if (missionID == m_MainDragonMissionID) {
|
||||
auto* character = target->GetCharacter();
|
||||
auto* missionComponent = target->GetComponent<MissionComponent>();
|
||||
if (character == nullptr || missionComponent == nullptr)
|
||||
return;
|
||||
|
||||
switch (missionState) {
|
||||
case MissionState::MISSION_STATE_AVAILABLE:
|
||||
case MissionState::MISSION_STATE_COMPLETE_AVAILABLE:
|
||||
{
|
||||
// Reset the sub missions
|
||||
for (const auto& subMissionID : m_SubDragonMissionIDs) {
|
||||
missionComponent->RemoveMission(subMissionID);
|
||||
missionComponent->AcceptMission(subMissionID);
|
||||
}
|
||||
|
||||
character->SetPlayerFlag(ePlayerFlags::NJ_WU_SHOW_DAILY_CHEST, false);
|
||||
|
||||
// Hide the chest
|
||||
for (auto* chest : EntityManager::Instance()->GetEntitiesInGroup(m_DragonChestGroup)) {
|
||||
GameMessages::SendNotifyClientObject(chest->GetObjectID(), m_ShowChestNotification, 0, -1,
|
||||
target->GetObjectID(), "", target->GetSystemAddress());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
case MissionState::MISSION_STATE_READY_TO_COMPLETE:
|
||||
case MissionState::MISSION_STATE_COMPLETE_READY_TO_COMPLETE:
|
||||
{
|
||||
character->SetPlayerFlag(NJ_WU_SHOW_DAILY_CHEST, true);
|
||||
|
||||
// Show the chest
|
||||
for (auto* chest : EntityManager::Instance()->GetEntitiesInGroup(m_DragonChestGroup)) {
|
||||
GameMessages::SendNotifyClientObject(chest->GetObjectID(), m_ShowChestNotification, 1, -1,
|
||||
target->GetObjectID(), "", target->GetSystemAddress());
|
||||
}
|
||||
|
||||
auto playerID = target->GetObjectID();
|
||||
self->AddCallbackTimer(5.0f, [this, playerID]() {
|
||||
auto* player = EntityManager::Instance()->GetEntity(playerID);
|
||||
if (player == nullptr)
|
||||
return;
|
||||
|
||||
// Stop the dragon effects
|
||||
for (auto* dragon : EntityManager::Instance()->GetEntitiesInGroup(m_DragonStatueGroup)) {
|
||||
GameMessages::SendStopFXEffect(dragon, true, "on");
|
||||
}
|
||||
});
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
13
dScripts/02_server/Map/njhub/NjWuNPC.h
Normal file
13
dScripts/02_server/Map/njhub/NjWuNPC.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "AmTemplateSkillVolume.h"
|
||||
|
||||
class NjWuNPC : public AmTemplateSkillVolume {
|
||||
void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override;
|
||||
const uint32_t m_MainDragonMissionID = 2040;
|
||||
const std::vector<uint32_t> m_SubDragonMissionIDs = { 2064, 2065, 2066, 2067 };
|
||||
|
||||
// Groups and variables
|
||||
const std::string m_DragonChestGroup = "DragonEmblemChest";
|
||||
const std::string m_DragonStatueGroup = "Minidragons";
|
||||
const std::u16string m_ShowChestNotification = u"showChest";
|
||||
};
|
70
dScripts/02_server/Map/njhub/RainOfArrows.cpp
Normal file
70
dScripts/02_server/Map/njhub/RainOfArrows.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "RainOfArrows.h"
|
||||
#include "EntityManager.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
void RainOfArrows::OnStartup(Entity* self) {
|
||||
|
||||
}
|
||||
|
||||
void RainOfArrows::OnRebuildComplete(Entity* self, Entity* target) {
|
||||
auto myPos = self->GetPosition();
|
||||
auto myRot = self->GetRotation();
|
||||
|
||||
EntityInfo info;
|
||||
info.lot = m_ArrowFXObject;
|
||||
info.pos = myPos;
|
||||
info.rot = myRot;
|
||||
info.spawnerID = self->GetObjectID();
|
||||
|
||||
auto* entity = EntityManager::Instance()->CreateEntity(info);
|
||||
|
||||
EntityManager::Instance()->ConstructEntity(entity);
|
||||
|
||||
self->SetVar<LWOOBJID>(u"ChildFX", entity->GetObjectID());
|
||||
self->SetVar<LWOOBJID>(u"playerID", target->GetObjectID());
|
||||
|
||||
self->AddTimer("ArrowsIncoming", m_ArrowDelay);
|
||||
self->AddTimer("PlayArrowSound", m_ArrowDelay - 4);
|
||||
}
|
||||
|
||||
void RainOfArrows::OnTimerDone(Entity* self, std::string timerName) {
|
||||
auto* child = EntityManager::Instance()->GetEntity(
|
||||
self->GetVar<LWOOBJID>(u"ChildFX")
|
||||
);
|
||||
|
||||
auto* player = EntityManager::Instance()->GetEntity(
|
||||
self->GetVar<LWOOBJID>(u"playerID")
|
||||
);
|
||||
|
||||
if (timerName == "ArrowsIncoming") {
|
||||
if (child == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* skillComponent = child->GetComponent<SkillComponent>();
|
||||
|
||||
if (skillComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
skillComponent->CalculateBehavior(
|
||||
m_ArrowSkill,
|
||||
m_ArrowBehavior,
|
||||
LWOOBJID_EMPTY,
|
||||
true,
|
||||
false,
|
||||
player != nullptr ? player->GetObjectID() : LWOOBJID_EMPTY
|
||||
);
|
||||
|
||||
self->AddTimer("FireSkill", 0.7f);
|
||||
} else if (timerName == "PlayArrowSound") {
|
||||
GameMessages::SendPlayNDAudioEmitter(self, UNASSIGNED_SYSTEM_ADDRESS, m_ArrowsGUID);
|
||||
} else if (timerName == "FireSkill") {
|
||||
if (child != nullptr) {
|
||||
child->Smash();
|
||||
}
|
||||
|
||||
self->Smash(player != nullptr ? player->GetObjectID() : LWOOBJID_EMPTY);
|
||||
}
|
||||
}
|
17
dScripts/02_server/Map/njhub/RainOfArrows.h
Normal file
17
dScripts/02_server/Map/njhub/RainOfArrows.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "CppScripts.h"
|
||||
|
||||
class RainOfArrows : public CppScripts::Script
|
||||
{
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnRebuildComplete(Entity* self, Entity* target) override;
|
||||
void OnTimerDone(Entity* self, std::string timerName) override;
|
||||
|
||||
private:
|
||||
LOT m_ArrowFXObject = 15850;
|
||||
int32_t m_ArrowSkill = 1482;
|
||||
int32_t m_ArrowBehavior = 36680;
|
||||
int32_t m_ArrowDelay = 6;
|
||||
std::string m_ArrowsGUID = "{532cba3c-54da-446c-986b-128af9647bdb}";
|
||||
};
|
@@ -0,0 +1,3 @@
|
||||
set(DSCRIPTS_SOURCES_02_SERVER_MAP_NJHUB_BOSS_INSTANCE
|
||||
"NjMonastryBossInstance.cpp"
|
||||
PARENT_SCOPE)
|
@@ -0,0 +1,523 @@
|
||||
#include "NjMonastryBossInstance.h"
|
||||
#include "RebuildComponent.h"
|
||||
#include "DestroyableComponent.h"
|
||||
#include "EntityManager.h"
|
||||
#include "dZoneManager.h"
|
||||
#include "GameMessages.h"
|
||||
#include "BaseCombatAIComponent.h"
|
||||
#include "BuffComponent.h"
|
||||
#include "SkillComponent.h"
|
||||
#include "TeamManager.h"
|
||||
#include <algorithm>
|
||||
|
||||
// // // // // // //
|
||||
// Event handling //
|
||||
// // // // // // //
|
||||
|
||||
void NjMonastryBossInstance::OnStartup(Entity* self) {
|
||||
auto spawnerNames = std::vector<std::string>{ LedgeFrakjawSpawner, LowerFrakjawSpawner, BaseEnemiesSpawner + std::to_string(1),
|
||||
BaseEnemiesSpawner + std::to_string(2), BaseEnemiesSpawner + std::to_string(3),
|
||||
BaseEnemiesSpawner + std::to_string(4), CounterweightSpawner };
|
||||
|
||||
// Add a notification request for all the spawned entities, corresponds to notifySpawnedObjectLoaded
|
||||
for (const auto& spawnerName : spawnerNames) {
|
||||
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(spawnerName)) {
|
||||
spawner->AddEntitySpawnedCallback([self, this](Entity* entity) {
|
||||
const auto lot = entity->GetLOT();
|
||||
switch (lot) {
|
||||
case LedgedFrakjawLOT:
|
||||
NjMonastryBossInstance::HandleLedgedFrakjawSpawned(self, entity);
|
||||
return;
|
||||
case CounterWeightLOT:
|
||||
NjMonastryBossInstance::HandleCounterWeightSpawned(self, entity);
|
||||
return;
|
||||
case LowerFrakjawLOT:
|
||||
NjMonastryBossInstance::HandleLowerFrakjawSpawned(self, entity);
|
||||
return;
|
||||
default:
|
||||
NjMonastryBossInstance::HandleWaveEnemySpawned(self, entity);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::OnPlayerLoaded(Entity* self, Entity* player) {
|
||||
ActivityTimerStop(self, WaitingForPlayersTimer);
|
||||
|
||||
// Join the player in the activity
|
||||
UpdatePlayer(self, player->GetObjectID());
|
||||
|
||||
// Buff the player
|
||||
auto* destroyableComponent = player->GetComponent<DestroyableComponent>();
|
||||
if (destroyableComponent != nullptr) {
|
||||
destroyableComponent->SetHealth((int32_t)destroyableComponent->GetMaxHealth());
|
||||
destroyableComponent->SetArmor((int32_t)destroyableComponent->GetMaxArmor());
|
||||
destroyableComponent->SetImagination((int32_t)destroyableComponent->GetMaxImagination());
|
||||
}
|
||||
|
||||
// Add player ID to instance
|
||||
auto totalPlayersLoaded = self->GetVar<std::vector<LWOOBJID>>(TotalPlayersLoadedVariable);
|
||||
totalPlayersLoaded.push_back(player->GetObjectID());
|
||||
|
||||
// Properly position the player
|
||||
self->SetVar<std::vector<LWOOBJID>>(TotalPlayersLoadedVariable, totalPlayersLoaded);
|
||||
// This was always spawning all players at position one before and other values cause players to be invisible.
|
||||
TeleportPlayer(player, 1);
|
||||
|
||||
// Large teams face a tougher challenge
|
||||
if (totalPlayersLoaded.size() >= 3)
|
||||
self->SetVar<bool>(LargeTeamVariable, true);
|
||||
|
||||
// Start the game if all players in the team have loaded
|
||||
auto* team = TeamManager::Instance()->GetTeam(player->GetObjectID());
|
||||
if (team == nullptr || totalPlayersLoaded.size() == team->members.size()) {
|
||||
StartFight(self);
|
||||
return;
|
||||
}
|
||||
|
||||
self->AddCallbackTimer(0.0f, [self, player]() {
|
||||
if (player != nullptr) {
|
||||
// If we don't have enough players yet, wait for the others to load and notify the client to play a cool cinematic
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"PlayerLoaded", 0, 0,
|
||||
player->GetObjectID(), "", player->GetSystemAddress());
|
||||
}
|
||||
});
|
||||
|
||||
ActivityTimerStart(self, WaitingForPlayersTimer, 45.0f, 45.0f);
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::OnPlayerExit(Entity* self, Entity* player) {
|
||||
UpdatePlayer(self, player->GetObjectID(), true);
|
||||
// Fetch the total players loaded from the vars
|
||||
auto totalPlayersLoaded = self->GetVar<std::vector<LWOOBJID> >(TotalPlayersLoadedVariable);
|
||||
|
||||
// Find the player to remove
|
||||
auto playerToRemove = std::find(totalPlayersLoaded.begin(), totalPlayersLoaded.end(), player->GetObjectID());
|
||||
|
||||
// If we found the player remove them from out list of players
|
||||
if (playerToRemove != totalPlayersLoaded.end()) {
|
||||
totalPlayersLoaded.erase(playerToRemove);
|
||||
} else {
|
||||
Game::logger->Log("NjMonastryBossInstance", "Failed to remove player at exit.");
|
||||
}
|
||||
|
||||
// Set the players loaded var back
|
||||
self->SetVar<std::vector<LWOOBJID>>(TotalPlayersLoadedVariable, totalPlayersLoaded);
|
||||
|
||||
// Since this is an exit method, check if enough players have left. If enough have left
|
||||
// resize the instance to account for such.
|
||||
if (totalPlayersLoaded.size() <= 2) self->SetVar<bool>(LargeTeamVariable, false);
|
||||
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"PlayerLeft", 0, 0, player->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS);
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::OnActivityTimerDone(Entity* self, const std::string& name) {
|
||||
auto split = GeneralUtils::SplitString(name, TimerSplitChar);
|
||||
auto timerName = split[0];
|
||||
auto objectID = split.size() > 1 ? (LWOOBJID)std::stoull(split[1]) : LWOOBJID_EMPTY;
|
||||
|
||||
if (timerName == WaitingForPlayersTimer) {
|
||||
StartFight(self);
|
||||
} else if (timerName == SpawnNextWaveTimer) {
|
||||
auto* frakjaw = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(LedgeFrakjawVariable));
|
||||
if (frakjaw != nullptr) {
|
||||
SummonWave(self, frakjaw);
|
||||
}
|
||||
} else if (timerName == SpawnWaveTimer) {
|
||||
auto wave = self->GetVar<uint32_t>(WaveNumberVariable);
|
||||
self->SetVar<uint32_t>(WaveNumberVariable, wave + 1);
|
||||
self->SetVar<uint32_t>(TotalAliveInWaveVariable, 0);
|
||||
|
||||
if (wave < m_Waves.size()) {
|
||||
auto waves = m_Waves.at(wave);
|
||||
auto counter = 0;
|
||||
|
||||
for (const auto& waveEnemy : waves) {
|
||||
const auto numberToSpawn = self->GetVar<bool>(LargeTeamVariable)
|
||||
? waveEnemy.largeNumber : waveEnemy.smallNumber;
|
||||
|
||||
auto spawnIndex = counter % 4 + 1;
|
||||
SpawnOnNetwork(self, waveEnemy.lot, numberToSpawn, BaseEnemiesSpawner + std::to_string(spawnIndex));
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
} else if (timerName + TimerSplitChar == UnstunTimer) {
|
||||
auto* entity = EntityManager::Instance()->GetEntity(objectID);
|
||||
if (entity != nullptr) {
|
||||
auto* combatAI = entity->GetComponent<BaseCombatAIComponent>();
|
||||
if (combatAI != nullptr) {
|
||||
combatAI->SetDisabled(false);
|
||||
}
|
||||
}
|
||||
} else if (timerName == SpawnCounterWeightTimer) {
|
||||
auto spawners = dZoneManager::Instance()->GetSpawnersByName(CounterweightSpawner);
|
||||
if (!spawners.empty()) {
|
||||
// Spawn the counter weight at a specific waypoint, there's one for each round
|
||||
auto* spawner = spawners.front();
|
||||
|
||||
spawner->Spawn({
|
||||
spawner->m_Info.nodes.at((self->GetVar<uint32_t>(WaveNumberVariable) - 1) % 3)
|
||||
}, true);
|
||||
}
|
||||
} else if (timerName == LowerFrakjawCamTimer) {
|
||||
// Destroy the frakjaw on the ledge
|
||||
auto* ledgeFrakjaw = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(LedgeFrakjawVariable));
|
||||
if (ledgeFrakjaw != nullptr) {
|
||||
ledgeFrakjaw->Kill();
|
||||
}
|
||||
|
||||
ActivityTimerStart(self, SpawnLowerFrakjawTimer, 1.0f, 1.0f);
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0,
|
||||
LWOOBJID_EMPTY, BottomFrakSpawn, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
} else if (timerName == SpawnLowerFrakjawTimer) {
|
||||
auto spawners = dZoneManager::Instance()->GetSpawnersByName(LowerFrakjawSpawner);
|
||||
if (!spawners.empty()) {
|
||||
auto* spawner = spawners.front();
|
||||
spawner->Activate();
|
||||
}
|
||||
} else if (timerName == SpawnRailTimer) {
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0,
|
||||
LWOOBJID_EMPTY, FireRailSpawn, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
auto spawners = dZoneManager::Instance()->GetSpawnersByName(FireRailSpawner);
|
||||
if (!spawners.empty()) {
|
||||
auto* spawner = spawners.front();
|
||||
spawner->Activate();
|
||||
}
|
||||
} else if (timerName + TimerSplitChar == FrakjawSpawnInTimer) {
|
||||
auto* lowerFrakjaw = EntityManager::Instance()->GetEntity(objectID);
|
||||
if (lowerFrakjaw != nullptr) {
|
||||
LowerFrakjawSummon(self, lowerFrakjaw);
|
||||
}
|
||||
} else if (timerName == WaveOverTimer) {
|
||||
WaveOver(self);
|
||||
} else if (timerName == FightOverTimer) {
|
||||
FightOver(self);
|
||||
}
|
||||
}
|
||||
|
||||
// // // // // // // //
|
||||
// Custom functions //
|
||||
// // // // // // // //
|
||||
|
||||
void NjMonastryBossInstance::StartFight(Entity* self) {
|
||||
if (self->GetVar<bool>(FightStartedVariable))
|
||||
return;
|
||||
|
||||
self->SetVar<bool>(FightStartedVariable, true);
|
||||
|
||||
// Activate the frakjaw spawner
|
||||
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(LedgeFrakjawSpawner)) {
|
||||
spawner->Activate();
|
||||
}
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::HandleLedgedFrakjawSpawned(Entity* self, Entity* ledgedFrakjaw) {
|
||||
self->SetVar<LWOOBJID>(LedgeFrakjawVariable, ledgedFrakjaw->GetObjectID());
|
||||
SummonWave(self, ledgedFrakjaw);
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::HandleCounterWeightSpawned(Entity* self, Entity* counterWeight) {
|
||||
auto* rebuildComponent = counterWeight->GetComponent<RebuildComponent>();
|
||||
if (rebuildComponent != nullptr) {
|
||||
rebuildComponent->AddRebuildStateCallback([this, self, counterWeight](eRebuildState state) {
|
||||
|
||||
switch (state) {
|
||||
case REBUILD_BUILDING:
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification,
|
||||
0, 0, counterWeight->GetObjectID(),
|
||||
BaseCounterweightQB + std::to_string(self->GetVar<uint32_t>(WaveNumberVariable)),
|
||||
UNASSIGNED_SYSTEM_ADDRESS);
|
||||
return;
|
||||
case REBUILD_INCOMPLETE:
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), EndCinematicNotification,
|
||||
0, 0, LWOOBJID_EMPTY, "",
|
||||
UNASSIGNED_SYSTEM_ADDRESS);
|
||||
return;
|
||||
case REBUILD_RESETTING:
|
||||
ActivityTimerStart(self, SpawnCounterWeightTimer, 0.0f, 0.0f);
|
||||
return;
|
||||
case REBUILD_COMPLETED: {
|
||||
// TODO: Move the platform?
|
||||
|
||||
// The counterweight is actually a moving platform and we should listen to the last waypoint event here
|
||||
// 0.5f is a rough estimate of that path, though, and results in less needed logic
|
||||
self->AddCallbackTimer(0.5f, [this, self, counterWeight]() {
|
||||
if (counterWeight != nullptr) {
|
||||
counterWeight->Kill();
|
||||
}
|
||||
|
||||
auto* frakjaw = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(LedgeFrakjawVariable));
|
||||
if (frakjaw == nullptr) {
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"LedgeFrakjawDead", 0,
|
||||
0, LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS);
|
||||
return;
|
||||
}
|
||||
|
||||
auto* skillComponent = frakjaw->GetComponent<SkillComponent>();
|
||||
if (skillComponent != nullptr) {
|
||||
skillComponent->CalculateBehavior(1635, 39097, frakjaw->GetObjectID(), true, false);
|
||||
}
|
||||
|
||||
GameMessages::SendPlayAnimation(frakjaw, StunnedAnimation);
|
||||
GameMessages::SendPlayNDAudioEmitter(frakjaw, UNASSIGNED_SYSTEM_ADDRESS, CounterSmashAudio);
|
||||
|
||||
// Before wave 4 we should lower frakjaw from the ledge
|
||||
if (self->GetVar<uint32_t>(WaveNumberVariable) == 3) {
|
||||
LowerFrakjaw(self, frakjaw);
|
||||
return;
|
||||
}
|
||||
|
||||
ActivityTimerStart(self, SpawnNextWaveTimer, 2.0f, 2.0f);
|
||||
});
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::HandleLowerFrakjawSpawned(Entity* self, Entity* lowerFrakjaw) {
|
||||
GameMessages::SendPlayAnimation(lowerFrakjaw, TeleportInAnimation);
|
||||
self->SetVar<LWOOBJID>(LowerFrakjawVariable, lowerFrakjaw->GetObjectID());
|
||||
|
||||
auto* combatAI = lowerFrakjaw->GetComponent<BaseCombatAIComponent>();
|
||||
if (combatAI != nullptr) {
|
||||
combatAI->SetDisabled(true);
|
||||
}
|
||||
|
||||
auto* destroyableComponent = lowerFrakjaw->GetComponent<DestroyableComponent>();
|
||||
if (destroyableComponent != nullptr) {
|
||||
destroyableComponent->AddOnHitCallback([this, self, lowerFrakjaw](Entity* attacker) {
|
||||
NjMonastryBossInstance::HandleLowerFrakjawHit(self, lowerFrakjaw, attacker);
|
||||
});
|
||||
}
|
||||
|
||||
lowerFrakjaw->AddDieCallback([this, self, lowerFrakjaw]() {
|
||||
NjMonastryBossInstance::HandleLowerFrakjawDied(self, lowerFrakjaw);
|
||||
});
|
||||
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"LedgeFrakjawDead", 0, 0,
|
||||
LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
if (self->GetVar<bool>(LargeTeamVariable)) {
|
||||
// Double frakjaws health for large teams
|
||||
if (destroyableComponent != nullptr) {
|
||||
const auto doubleHealth = destroyableComponent->GetHealth() * 2;
|
||||
destroyableComponent->SetHealth(doubleHealth);
|
||||
destroyableComponent->SetMaxHealth((float_t)doubleHealth);
|
||||
}
|
||||
|
||||
ActivityTimerStart(self, FrakjawSpawnInTimer + std::to_string(lowerFrakjaw->GetObjectID()),
|
||||
2.0f, 2.0f);
|
||||
ActivityTimerStart(self, UnstunTimer + std::to_string(lowerFrakjaw->GetObjectID()),
|
||||
7.0f, 7.0f);
|
||||
} else {
|
||||
ActivityTimerStart(self, UnstunTimer + std::to_string(lowerFrakjaw->GetObjectID()),
|
||||
5.0f, 5.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::HandleLowerFrakjawHit(Entity* self, Entity* lowerFrakjaw, Entity* attacker) {
|
||||
auto* destroyableComponent = lowerFrakjaw->GetComponent<DestroyableComponent>();
|
||||
if (destroyableComponent == nullptr)
|
||||
return;
|
||||
|
||||
// Progress the fight to the last wave if frakjaw has less than 50% of his health left
|
||||
if (destroyableComponent->GetHealth() <= (uint32_t)destroyableComponent->GetMaxHealth() / 2 && !self->GetVar<bool>(OnLastWaveVarbiale)) {
|
||||
self->SetVar<bool>(OnLastWaveVarbiale, true);
|
||||
|
||||
// Stun frakjaw during the cinematic
|
||||
auto* combatAI = lowerFrakjaw->GetComponent<BaseCombatAIComponent>();
|
||||
if (combatAI != nullptr) {
|
||||
combatAI->SetDisabled(true);
|
||||
}
|
||||
ActivityTimerStart(self, UnstunTimer + std::to_string(lowerFrakjaw->GetObjectID()), 5.0f, 5.0f);
|
||||
|
||||
const auto trashMobsAlive = self->GetVar<std::vector<LWOOBJID>>(TrashMobsAliveVariable);
|
||||
std::vector<LWOOBJID> newTrashMobs = {};
|
||||
|
||||
for (const auto& trashMobID : trashMobsAlive) {
|
||||
auto* trashMob = EntityManager::Instance()->GetEntity(trashMobID);
|
||||
if (trashMob != nullptr) {
|
||||
newTrashMobs.push_back(trashMobID);
|
||||
|
||||
// Stun all the enemies until the cinematic is over
|
||||
auto* trashMobCombatAI = trashMob->GetComponent<BaseCombatAIComponent>();
|
||||
if (trashMobCombatAI != nullptr) {
|
||||
trashMobCombatAI->SetDisabled(true);
|
||||
}
|
||||
ActivityTimerStart(self, UnstunTimer + std::to_string(trashMobID), 5.0f, 5.0f);
|
||||
}
|
||||
}
|
||||
|
||||
self->SetVar<std::vector<LWOOBJID>>(TrashMobsAliveVariable, newTrashMobs);
|
||||
|
||||
LowerFrakjawSummon(self, lowerFrakjaw);
|
||||
RemovePoison(self);
|
||||
}
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::HandleLowerFrakjawDied(Entity* self, Entity* lowerFrakjaw) {
|
||||
ActivityTimerStart(self, FightOverTimer, 2.0f, 2.0f);
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::HandleWaveEnemySpawned(Entity* self, Entity* waveEnemy) {
|
||||
waveEnemy->AddDieCallback([this, self, waveEnemy]() {
|
||||
NjMonastryBossInstance::HandleWaveEnemyDied(self, waveEnemy);
|
||||
});
|
||||
|
||||
auto waveEnemies = self->GetVar<std::vector<LWOOBJID>>(TrashMobsAliveVariable);
|
||||
waveEnemies.push_back(waveEnemy->GetObjectID());
|
||||
self->SetVar<std::vector<LWOOBJID>>(TrashMobsAliveVariable, waveEnemies);
|
||||
|
||||
auto* combatAI = waveEnemy->GetComponent<BaseCombatAIComponent>();
|
||||
if (combatAI != nullptr) {
|
||||
combatAI->SetDisabled(true);
|
||||
ActivityTimerStart(self, UnstunTimer + std::to_string(waveEnemy->GetObjectID()), 3.0f, 3.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::HandleWaveEnemyDied(Entity* self, Entity* waveEnemy) {
|
||||
auto waveEnemies = self->GetVar<std::vector<LWOOBJID>>(TrashMobsAliveVariable);
|
||||
waveEnemies.erase(std::remove(waveEnemies.begin(), waveEnemies.end(), waveEnemy->GetObjectID()), waveEnemies.end());
|
||||
self->SetVar<std::vector<LWOOBJID>>(TrashMobsAliveVariable, waveEnemies);
|
||||
|
||||
if (waveEnemies.empty()) {
|
||||
ActivityTimerStart(self, WaveOverTimer, 2.0f, 2.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::TeleportPlayer(Entity* player, uint32_t position) {
|
||||
for (const auto* spawnPoint : EntityManager::Instance()->GetEntitiesInGroup("SpawnPoint" + std::to_string(position))) {
|
||||
GameMessages::SendTeleport(player->GetObjectID(), spawnPoint->GetPosition(), spawnPoint->GetRotation(),
|
||||
player->GetSystemAddress(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::SummonWave(Entity* self, Entity* frakjaw) {
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0, LWOOBJID_EMPTY,
|
||||
LedgeFrakSummon, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
GameMessages::SendPlayAnimation(frakjaw, SummonAnimation);
|
||||
|
||||
// Stop the music for the first, fourth and fifth wave
|
||||
const auto wave = self->GetVar<uint32_t>(WaveNumberVariable);
|
||||
if (wave >= 1 || wave < (m_Waves.size() - 1)) {
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), StopMusicNotification, 0, 0,
|
||||
LWOOBJID_EMPTY, AudioWaveAudio + std::to_string(wave - 1),
|
||||
UNASSIGNED_SYSTEM_ADDRESS);
|
||||
}
|
||||
|
||||
// After frakjaw moves down the music stays the same
|
||||
if (wave < (m_Waves.size() - 1)) {
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), StartMusicNotification, 0, 0,
|
||||
LWOOBJID_EMPTY, AudioWaveAudio + std::to_string(wave),
|
||||
UNASSIGNED_SYSTEM_ADDRESS);
|
||||
}
|
||||
|
||||
ActivityTimerStart(self, SpawnWaveTimer, 4.0f, 4.0f);
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::LowerFrakjawSummon(Entity* self, Entity* frakjaw) {
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0,
|
||||
LWOOBJID_EMPTY, BottomFrakSummon, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
ActivityTimerStart(self, SpawnWaveTimer, 2.0f, 2.0f);
|
||||
GameMessages::SendPlayAnimation(frakjaw, SummonAnimation);
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::RemovePoison(Entity* self) {
|
||||
const auto& totalPlayer = self->GetVar<std::vector<LWOOBJID>>(TotalPlayersLoadedVariable);
|
||||
for (const auto& playerID : totalPlayer) {
|
||||
|
||||
auto* player = EntityManager::Instance()->GetEntity(playerID);
|
||||
if (player != nullptr) {
|
||||
|
||||
auto* buffComponent = player->GetComponent<BuffComponent>();
|
||||
if (buffComponent != nullptr) {
|
||||
buffComponent->RemoveBuff(PoisonBuff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::LowerFrakjaw(Entity* self, Entity* frakjaw) {
|
||||
GameMessages::SendPlayAnimation(frakjaw, TeleportOutAnimation);
|
||||
ActivityTimerStart(self, LowerFrakjawCamTimer, 2.0f, 2.0f);
|
||||
|
||||
GameMessages::SendNotifyClientObject(frakjaw->GetObjectID(), StopMusicNotification, 0, 0,
|
||||
LWOOBJID_EMPTY, AudioWaveAudio + std::to_string(m_Waves.size() - 3), UNASSIGNED_SYSTEM_ADDRESS);
|
||||
GameMessages::SendNotifyClientObject(frakjaw->GetObjectID(), StartMusicNotification, 0, 0,
|
||||
LWOOBJID_EMPTY, AudioWaveAudio + std::to_string(m_Waves.size() - 2), UNASSIGNED_SYSTEM_ADDRESS);
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::SpawnOnNetwork(Entity* self, const LOT& toSpawn, const uint32_t& numberToSpawn, const std::string& spawnerName) {
|
||||
auto spawners = dZoneManager::Instance()->GetSpawnersByName(spawnerName);
|
||||
if (spawners.empty() || numberToSpawn <= 0)
|
||||
return;
|
||||
|
||||
auto* spawner = spawners.front();
|
||||
|
||||
// Spawn the lot N times
|
||||
spawner->SetSpawnLot(toSpawn);
|
||||
for (auto i = 0; i < numberToSpawn; i++)
|
||||
spawner->Spawn({ spawner->m_Info.nodes.at(i % spawner->m_Info.nodes.size()) }, true);
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::WaveOver(Entity* self) {
|
||||
auto wave = self->GetVar<uint32_t>(WaveNumberVariable);
|
||||
if (wave >= m_Waves.size() - 1)
|
||||
return;
|
||||
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0,
|
||||
LWOOBJID_EMPTY, BaseCounterweightSpawn + std::to_string(wave),
|
||||
UNASSIGNED_SYSTEM_ADDRESS);
|
||||
ActivityTimerStart(self, SpawnCounterWeightTimer, 1.5f, 1.5f);
|
||||
RemovePoison(self);
|
||||
}
|
||||
|
||||
void NjMonastryBossInstance::FightOver(Entity* self) {
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"GroundFrakjawDead", 0, 0,
|
||||
LWOOBJID_EMPTY, "", UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
// Remove all the enemies from the battlefield
|
||||
for (auto i = 1; i < 5; i++) {
|
||||
auto spawners = dZoneManager::Instance()->GetSpawnersByName(BaseEnemiesSpawner + std::to_string(i));
|
||||
if (!spawners.empty()) {
|
||||
auto* spawner = spawners.front();
|
||||
spawner->Deactivate();
|
||||
spawner->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
RemovePoison(self);
|
||||
ActivityTimerStart(self, SpawnRailTimer, 1.5f, 1.5f);
|
||||
|
||||
// Set the music to play the victory music
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), StopMusicNotification, 0, 0,
|
||||
LWOOBJID_EMPTY, AudioWaveAudio + std::to_string(m_Waves.size() - 2),
|
||||
UNASSIGNED_SYSTEM_ADDRESS);
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), FlashMusicNotification, 0, 0,
|
||||
LWOOBJID_EMPTY, "Monastery_Frakjaw_Battle_Win", UNASSIGNED_SYSTEM_ADDRESS);
|
||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), PlayCinematicNotification, 0, 0,
|
||||
LWOOBJID_EMPTY, TreasureChestSpawning, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
auto treasureChests = EntityManager::Instance()->GetEntitiesInGroup(ChestSpawnpointGroup);
|
||||
for (auto* treasureChest : treasureChests) {
|
||||
auto info = EntityInfo{};
|
||||
|
||||
info.lot = ChestLOT;
|
||||
info.pos = treasureChest->GetPosition();
|
||||
info.rot = treasureChest->GetRotation();
|
||||
info.spawnerID = self->GetObjectID();
|
||||
info.settings = {
|
||||
new LDFData<LWOOBJID>(u"parent_tag", self->GetObjectID())
|
||||
};
|
||||
|
||||
// Finally spawn a treasure chest at the correct spawn point
|
||||
auto* chestObject = EntityManager::Instance()->CreateEntity(info);
|
||||
EntityManager::Instance()->ConstructEntity(chestObject);
|
||||
}
|
||||
}
|
@@ -0,0 +1,157 @@
|
||||
#pragma once
|
||||
#include "ActivityManager.h"
|
||||
|
||||
enum FrakjawEnemies {
|
||||
BoneWolf = 16191,
|
||||
BlackSmith = 14007,
|
||||
Marksman = 14008,
|
||||
Commando = 14009,
|
||||
MadScientist = 16511
|
||||
};
|
||||
|
||||
enum FrakjawLots : LOT {
|
||||
ChestLOT = 16486,
|
||||
LedgedFrakjawLOT = 16289,
|
||||
LowerFrakjawLOT = 16048,
|
||||
CounterWeightLOT = 16141
|
||||
};
|
||||
|
||||
struct FrakjawWaveEnemy {
|
||||
LOT lot;
|
||||
uint32_t largeNumber;
|
||||
uint32_t smallNumber;
|
||||
};
|
||||
|
||||
class NjMonastryBossInstance : public ActivityManager {
|
||||
public:
|
||||
void OnStartup(Entity* self) override;
|
||||
void OnPlayerLoaded(Entity* self, Entity* player) override;
|
||||
void OnPlayerExit(Entity* self, Entity* player) override;
|
||||
void OnActivityTimerDone(Entity* self, const std::string& name) override;
|
||||
private:
|
||||
void StartFight(Entity* self);
|
||||
void WaveOver(Entity* self);
|
||||
void FightOver(Entity* self);
|
||||
void SummonWave(Entity* self, Entity* frakjaw);
|
||||
void LowerFrakjaw(Entity* self, Entity* frakjaw);
|
||||
void LowerFrakjawSummon(Entity* self, Entity* frakjaw);
|
||||
void RemovePoison(Entity* self);
|
||||
static void SpawnOnNetwork(Entity* self, const LOT& toSpawn, const uint32_t& numberToSpawn, const std::string& spawnerName);
|
||||
static void TeleportPlayer(Entity* player, uint32_t position);
|
||||
|
||||
// Event handlers for anything spawned by the main spawner
|
||||
void HandleLedgedFrakjawSpawned(Entity* self, Entity* ledgedFrakjaw);
|
||||
void HandleCounterWeightSpawned(Entity* self, Entity* counterWeight);
|
||||
void HandleLowerFrakjawSpawned(Entity* self, Entity* lowerFrakjaw);
|
||||
void HandleWaveEnemySpawned(Entity* self, Entity* waveEnemy);
|
||||
void HandleWaveEnemyDied(Entity* self, Entity* waveEnemy);
|
||||
void HandleLowerFrakjawHit(Entity* self, Entity* lowerFrakjaw, Entity* attacker);
|
||||
void HandleLowerFrakjawDied(Entity* self, Entity* lowerFrakjaw);
|
||||
|
||||
const std::vector<std::vector<FrakjawWaveEnemy>> m_Waves = {
|
||||
// Wave 1
|
||||
{
|
||||
{ FrakjawEnemies::Marksman, 2, 1},
|
||||
{ FrakjawEnemies::BlackSmith, 4, 3},
|
||||
{ FrakjawEnemies::Commando, 2, 1},
|
||||
{ FrakjawEnemies::MadScientist, 1, 0},
|
||||
},
|
||||
|
||||
// Wave 2
|
||||
{
|
||||
{ FrakjawEnemies::BoneWolf, 1, 0},
|
||||
{ FrakjawEnemies::BlackSmith, 2, 2},
|
||||
{ FrakjawEnemies::Marksman, 2, 1},
|
||||
{ FrakjawEnemies::MadScientist, 1, 1},
|
||||
},
|
||||
|
||||
// Wave 3
|
||||
{
|
||||
{ FrakjawEnemies::BoneWolf, 2, 1},
|
||||
{ FrakjawEnemies::Marksman, 2, 1},
|
||||
{ FrakjawEnemies::Commando, 2, 2},
|
||||
{ FrakjawEnemies::MadScientist, 1, 0},
|
||||
},
|
||||
|
||||
// Wave 4
|
||||
{
|
||||
{ FrakjawEnemies::BlackSmith, 2, 2},
|
||||
{ FrakjawEnemies::BoneWolf, 1, 1},
|
||||
{ FrakjawEnemies::Commando, 3, 1},
|
||||
{ FrakjawEnemies::Marksman, 2, 0},
|
||||
},
|
||||
|
||||
// Wave 5
|
||||
{
|
||||
{ FrakjawEnemies::MadScientist, 1, 0},
|
||||
{ FrakjawEnemies::BoneWolf, 2, 0},
|
||||
{ FrakjawEnemies::Commando, 3, 0},
|
||||
{ FrakjawEnemies::Marksman, 2, 0},
|
||||
}
|
||||
};
|
||||
|
||||
const int32_t PoisonBuff = 60;
|
||||
|
||||
// Variables
|
||||
const std::u16string TotalPlayersLoadedVariable = u"TotalPlayersLoaded";
|
||||
const std::u16string LargeTeamVariable = u"LargeTeam";
|
||||
const std::u16string FightStartedVariable = u"FightStarted";
|
||||
const std::u16string LedgeFrakjawVariable = u"LedgeFrakjaw";
|
||||
const std::u16string LowerFrakjawVariable = u"LowerFrakjaw";
|
||||
const std::u16string WaveNumberVariable = u"WaveNumber";
|
||||
const std::u16string OnLastWaveVarbiale = u"OnLastWave";
|
||||
const std::u16string TrashMobsAliveVariable = u"TrashMobsAlive";
|
||||
const std::u16string TotalAliveInWaveVariable = u"TotalAliveInWave";
|
||||
|
||||
// Timers
|
||||
const char TimerSplitChar = '+';
|
||||
const std::string WaitingForPlayersTimer = "WaitingForPlayers";
|
||||
const std::string SpawnWaveTimer = "SpawnWave";
|
||||
const std::string SpawnNextWaveTimer = "SpawnNextWave";
|
||||
const std::string UnstunTimer = "Unstun+";
|
||||
const std::string FrakjawSpawnInTimer = "LowerFrakjawSpawnIn+";
|
||||
const std::string WaveOverTimer = "WaveOverTimer";
|
||||
const std::string FightOverTimer = "FightOver";
|
||||
const std::string LowerFrakjawCamTimer = "StartLowerFrakjawCam";
|
||||
const std::string SpawnCounterWeightTimer = "SpawnQB";
|
||||
const std::string SpawnRailTimer = "SpawnRailQB";
|
||||
const std::string SpawnLowerFrakjawTimer = "SpawnLowerFrakjaw";
|
||||
|
||||
// Groups
|
||||
const std::string ChestSpawnpointGroup = "ChestSpawnPoint";
|
||||
|
||||
// Spawner network names
|
||||
const std::string LedgeFrakjawSpawner = "LedgeFrakjaw";
|
||||
const std::string LowerFrakjawSpawner = "LowerFrakjaw";
|
||||
const std::string BaseEnemiesSpawner = "EnemySpawnPoints_";
|
||||
const std::string CounterweightSpawner = "Counterweights";
|
||||
const std::string FireRailSpawner = "FireRailActivatorQB";
|
||||
const std::string ExtraRocks = "ExtraRocks";
|
||||
|
||||
// Cinematics
|
||||
const std::string LedgeFrakSummon = "FrakjawSummoning";
|
||||
const std::string BaseCounterweightQB = "CounterweightQB";
|
||||
const std::string BaseCounterweightSpawn = "CWQBSpawn";
|
||||
const std::string BottomFrakSummon = "BottomFrakjawSummoning";
|
||||
const std::string BottomFrakSpawn = "BottomFrakjawSpawning";
|
||||
const std::string TreasureChestSpawning = "TreasureChestSpawning";
|
||||
const std::string FireRailSpawn = "RailQBSpawn";
|
||||
|
||||
// Notifications
|
||||
const std::u16string StopMusicNotification = u"StopMusic";
|
||||
const std::u16string StartMusicNotification = u"StartMusic";
|
||||
const std::u16string FlashMusicNotification = u"FlashMusic";
|
||||
const std::u16string PlayCinematicNotification = u"PlayCinematic";
|
||||
const std::u16string EndCinematicNotification = u"EndCinematic";
|
||||
|
||||
// Animations
|
||||
const std::u16string SummonAnimation = u"summon";
|
||||
const std::u16string TeleportOutAnimation = u"teleport-out";
|
||||
const std::u16string TeleportInAnimation = u"teleport-in";
|
||||
const std::u16string StunnedAnimation = u"stunned";
|
||||
|
||||
// Audio cues
|
||||
const std::string AudioWaveAudio = "Monastery_Frakjaw_Battle_";
|
||||
const std::string BattleOverAudio = "Monastery_Frakjaw_Battle_Win";
|
||||
const std::string CounterSmashAudio = "{d76d7b9d-9dc2-4e52-a315-69b25ef521ca}";
|
||||
};
|
Reference in New Issue
Block a user