mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-04 17:54:01 +00:00
.github
cmake
dAuthServer
dChatFilter
dChatServer
dCommon
dDatabase
dGame
dMasterServer
dNavigation
dNet
dPhysics
dScripts
02_server
EquipmentScripts
EquipmentTriggers
ai
ACT
AG
FV
GENERAL
GF
MINIGAME
NP
NS
NS_PP_01
WH
CMakeLists.txt
ClRing.cpp
ClRing.h
NsConcertChoiceBuild.cpp
NsConcertChoiceBuild.h
NsConcertInstrument.cpp
NsConcertInstrument.h
NsConcertQuickBuild.cpp
NsConcertQuickBuild.h
NsGetFactionMissionServer.cpp
NsGetFactionMissionServer.h
NsJohnnyMissionServer.cpp
NsJohnnyMissionServer.h
NsModularBuild.cpp
NsModularBuild.h
NsQbImaginationStatue.cpp
NsQbImaginationStatue.h
WhFans.cpp
WhFans.h
PETS
PROPERTY
RACING
SPEC
WILD
CMakeLists.txt
client
zone
ActivityManager.cpp
ActivityManager.h
BaseConsoleTeleportServer.cpp
BaseConsoleTeleportServer.h
BasePropertyServer.cpp
BasePropertyServer.h
BaseRandomServer.cpp
BaseRandomServer.h
BaseSurvivalServer.cpp
BaseSurvivalServer.h
BaseWavesGenericEnemy.cpp
BaseWavesGenericEnemy.h
BaseWavesServer.cpp
BaseWavesServer.h
CMakeLists.txt
ChooseYourDestinationNsToNt.cpp
ChooseYourDestinationNsToNt.h
CppScripts.cpp
CppScripts.h
Darkitect.cpp
Darkitect.h
InvalidScript.cpp
InvalidScript.h
NPCAddRemoveItem.cpp
NPCAddRemoveItem.h
NtFactionSpyServer.cpp
NtFactionSpyServer.h
ScriptComponent.cpp
ScriptComponent.h
ScriptedPowerupSpawner.cpp
ScriptedPowerupSpawner.h
SpawnPetBaseServer.cpp
SpawnPetBaseServer.h
dServer
dWorldServer
dZoneManager
docs
migrations
resources
tests
thirdparty
vanity
.dockerignore
.editorconfig
.env.example
.git-blame-ignore-revs
.gitattributes
.gitignore
.gitmodules
CMakeLists.txt
CMakePresets.json
CMakeVariables.txt
CONTRIBUTING.md
Dockerfile
LICENSE
README.md
SECURITY.md
build.sh
docker-compose.yml
entrypoint.sh
logo.png
systemd.example
versions.txt
225 lines
7.9 KiB
C++
225 lines
7.9 KiB
C++
#include "NsConcertQuickBuild.h"
|
|
#include "EntityManager.h"
|
|
#include "NsConcertChoiceBuildManager.h"
|
|
#include "DestroyableComponent.h"
|
|
#include "GameMessages.h"
|
|
#include "MovingPlatformComponent.h"
|
|
#include "MissionComponent.h"
|
|
|
|
const float NsConcertQuickBuild::resetTime = 40.0f;
|
|
const float NsConcertQuickBuild::resetBlinkTime = 6.0f;
|
|
const float NsConcertQuickBuild::resetStageTime = 66.5f;
|
|
const float NsConcertQuickBuild::resetActivatorTime = 30.0f;
|
|
const std::map<LOT, QuickBuildSet> NsConcertQuickBuild::quickBuildSets{
|
|
{5846, QuickBuildSet {"laser", {"discoball", "discofloor", "stagelights", "spotlight"}}},
|
|
{5847, QuickBuildSet {"spotlight", {"spotlight", "stagelights"}}},
|
|
{5848, QuickBuildSet {"rocket", {"flamethrower"}}},
|
|
{5845, QuickBuildSet {"speaker", {"speaker", "speakerHill", "stagelights", "spotlight"}}}
|
|
};
|
|
|
|
const std::map<std::string, std::string> NsConcertQuickBuild::quickBuildFX{
|
|
{"discoball", "effectsDiscoball"},
|
|
{"speaker", "effectsShell"},
|
|
{"speakerHill", "effectsHill"},
|
|
{"spotlight", "effectsHill"},
|
|
{"discofloor", "effectsShell"},
|
|
{"flamethrower", "effectsShell"},
|
|
{"stagelights", "effectsShell"}
|
|
};
|
|
|
|
std::vector<LWOOBJID> NsConcertQuickBuild::finishedQuickBuilds = {};
|
|
|
|
void NsConcertQuickBuild::OnStartup(Entity* self) {
|
|
const auto groups = self->GetGroups();
|
|
if (groups.empty())
|
|
return;
|
|
|
|
// Groups are of the form Concert_Laser_QB_1, Concert_Laser_QB_2, etc.
|
|
auto group = groups.at(0);
|
|
const auto splitGroup = GeneralUtils::SplitString(group, '_');
|
|
if (splitGroup.size() < 4)
|
|
return;
|
|
|
|
// Get the manager of the crate of this quick build
|
|
const auto groupNumber = std::stoi(splitGroup.at(3));
|
|
const auto managerObjects = Game::entityManager->GetEntitiesInGroup("CB_" + std::to_string(groupNumber));
|
|
if (managerObjects.empty())
|
|
return;
|
|
|
|
auto* managerObject = managerObjects.at(0);
|
|
self->SetVar<LWOOBJID>(u"managerObject", managerObject->GetObjectID());
|
|
self->SetVar<int32_t>(u"groupNumber", groupNumber);
|
|
|
|
// Makes the quick build blink after a certain amount of time
|
|
self->AddCallbackTimer(GetBlinkTime(resetActivatorTime), [self]() {
|
|
self->SetNetworkVar<float>(u"startEffect", NsConcertQuickBuild::GetBlinkTime(resetActivatorTime));
|
|
});
|
|
|
|
// Destroys the quick build after a while if it wasn't built
|
|
self->AddCallbackTimer(resetActivatorTime, [self]() {
|
|
self->SetNetworkVar<float>(u"startEffect", -1.0f);
|
|
self->Smash(self->GetObjectID(), eKillType::SILENT);
|
|
});
|
|
}
|
|
|
|
float NsConcertQuickBuild::GetBlinkTime(float time) {
|
|
return time <= NsConcertQuickBuild::resetBlinkTime ? 1.0f : time - NsConcertQuickBuild::resetBlinkTime;
|
|
}
|
|
|
|
void NsConcertQuickBuild::OnDie(Entity* self, Entity* killer) {
|
|
auto* managerObject = Game::entityManager->GetEntity(self->GetVar<LWOOBJID>(u"managerObject"));
|
|
if (managerObject) {
|
|
managerObject->CancelAllTimers();
|
|
managerObject->AddCallbackTimer(1.0f, [managerObject]() {
|
|
NsConcertChoiceBuildManager::SpawnCrate(managerObject);
|
|
});
|
|
}
|
|
|
|
auto position = std::find(finishedQuickBuilds.begin(), finishedQuickBuilds.end(), self->GetObjectID());
|
|
if (position != finishedQuickBuilds.end())
|
|
finishedQuickBuilds.erase(position);
|
|
}
|
|
|
|
void NsConcertQuickBuild::OnQuickBuildComplete(Entity* self, Entity* target) {
|
|
const auto groupNumber = self->GetVar<int32_t>(u"groupNumber");
|
|
finishedQuickBuilds.push_back(self->GetObjectID());
|
|
self->SetNetworkVar<float>(u"startEffect", -1.0f);
|
|
|
|
ProgressStageCraft(self, target);
|
|
|
|
// Find all the quick build objects of the same lot
|
|
auto finishedQuickBuildObjects = std::vector<Entity*>();
|
|
for (auto quickBuildID : finishedQuickBuilds) {
|
|
const auto quickBuildObject = Game::entityManager->GetEntity(quickBuildID);
|
|
if (quickBuildObject && quickBuildObject->GetLOT() == self->GetLOT()) {
|
|
quickBuildObject->SetVar<LWOOBJID>(u"Player_" + (GeneralUtils::to_u16string(groupNumber)), target->GetObjectID());
|
|
finishedQuickBuildObjects.push_back(quickBuildObject);
|
|
}
|
|
}
|
|
|
|
// If all 4 sets were built, do cool stuff
|
|
if (finishedQuickBuildObjects.size() >= 4) {
|
|
|
|
// Move all the platforms so the user can collect the imagination brick
|
|
const auto movingPlatforms = Game::entityManager->GetEntitiesInGroup("ConcertPlatforms");
|
|
for (auto* movingPlatform : movingPlatforms) {
|
|
auto* component = movingPlatform->GetComponent<MovingPlatformComponent>();
|
|
if (component) {
|
|
component->WarpToWaypoint(component->GetLastWaypointIndex());
|
|
|
|
movingPlatform->AddCallbackTimer(resetStageTime, [movingPlatform, component]() {
|
|
component->WarpToWaypoint(0);
|
|
});
|
|
}
|
|
}
|
|
|
|
ProgressLicensedTechnician(self);
|
|
|
|
// Reset all timers for the quickbuilds and make them indestructible
|
|
for (auto quickBuild : finishedQuickBuildObjects) {
|
|
quickBuild->SetNetworkVar<float>(u"startEffect", -1.0f);
|
|
quickBuild->CancelAllTimers();
|
|
|
|
// Indicate that the stage will reset
|
|
quickBuild->AddCallbackTimer(GetBlinkTime(resetStageTime), [quickBuild]() {
|
|
quickBuild->SetNetworkVar<float>(u"startEffect", GetBlinkTime(resetTime));
|
|
});
|
|
|
|
// Reset the stage
|
|
quickBuild->AddCallbackTimer(resetStageTime, [quickBuild]() {
|
|
CancelEffects(quickBuild);
|
|
quickBuild->SetNetworkVar<float>(u"startEffect", -1);
|
|
quickBuild->Smash();
|
|
});
|
|
|
|
auto* destroyableComponent = quickBuild->GetComponent<DestroyableComponent>();
|
|
if (destroyableComponent)
|
|
destroyableComponent->SetFaction(-1);
|
|
}
|
|
|
|
UpdateEffects(self);
|
|
return;
|
|
}
|
|
|
|
// If not all 4 sets were built, reset the timers that were set on spawn
|
|
self->CancelAllTimers();
|
|
|
|
// Makes the quick build blink after a certain amount of time
|
|
self->AddCallbackTimer(GetBlinkTime(resetTime), [self]() {
|
|
self->SetNetworkVar<float>(u"startEffect", NsConcertQuickBuild::GetBlinkTime(resetActivatorTime));
|
|
});
|
|
|
|
// Destroys the quick build after a while if it wasn't built
|
|
self->AddCallbackTimer(resetTime, [self]() {
|
|
self->SetNetworkVar<float>(u"startEffect", -1.0f);
|
|
self->Smash(self->GetObjectID());
|
|
});
|
|
}
|
|
|
|
void NsConcertQuickBuild::ProgressStageCraft(Entity* self, Entity* player) {
|
|
auto* missionComponent = player->GetComponent<MissionComponent>();
|
|
if (missionComponent) {
|
|
|
|
// Has to be forced as to not accidentally trigger the licensed technician achievement
|
|
switch (self->GetLOT()) {
|
|
case 5845:
|
|
missionComponent->ForceProgress(283, 432, 5845);
|
|
break;
|
|
case 5846:
|
|
missionComponent->ForceProgress(283, 433, 5846);
|
|
break;
|
|
case 5847:
|
|
missionComponent->ForceProgress(283, 434, 5847);
|
|
break;
|
|
case 5848:
|
|
missionComponent->ForceProgress(283, 435, 5848);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void NsConcertQuickBuild::ProgressLicensedTechnician(Entity* self) {
|
|
for (auto i = 1; i < 5; i++) {
|
|
const auto playerID = self->GetVar<LWOOBJID>(u"Player_" + (GeneralUtils::to_u16string(i)));
|
|
if (playerID != LWOOBJID_EMPTY) {
|
|
const auto player = Game::entityManager->GetEntity(playerID);
|
|
if (player) {
|
|
auto playerMissionComponent = player->GetComponent<MissionComponent>();
|
|
if (playerMissionComponent)
|
|
playerMissionComponent->ForceProgress(598, 903, self->GetLOT());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void NsConcertQuickBuild::UpdateEffects(Entity* self) {
|
|
CancelEffects(self);
|
|
|
|
auto setIterator = quickBuildSets.find(self->GetLOT());
|
|
if (setIterator == quickBuildSets.end())
|
|
return;
|
|
|
|
for (const auto& effectName : setIterator->second.effects) {
|
|
const auto effectObjects = Game::entityManager->GetEntitiesInGroup(quickBuildFX.at(effectName));
|
|
for (auto* effectObject : effectObjects) {
|
|
GameMessages::SendPlayFXEffect(effectObject, 0, GeneralUtils::ASCIIToUTF16(effectName),
|
|
effectName + "Effect", LWOOBJID_EMPTY, 1, 1, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
void NsConcertQuickBuild::CancelEffects(Entity* self) {
|
|
auto setIterator = quickBuildSets.find(self->GetLOT());
|
|
if (setIterator == quickBuildSets.end())
|
|
return;
|
|
|
|
for (const auto& effectName : setIterator->second.effects) {
|
|
const auto effectObjects = Game::entityManager->GetEntitiesInGroup(quickBuildFX.at(effectName));
|
|
for (auto* effectObject : effectObjects) {
|
|
GameMessages::SendStopFXEffect(effectObject, true, effectName + "Effect");
|
|
}
|
|
}
|
|
}
|