mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-12-23 14:03:34 +00:00
389 lines
9.5 KiB
C++
389 lines
9.5 KiB
C++
|
#include "AmSkullkinDrill.h"
|
||
|
#include "GameMessages.h"
|
||
|
#include "MovingPlatformComponent.h"
|
||
|
#include "DestroyableComponent.h"
|
||
|
#include "ProximityMonitorComponent.h"
|
||
|
#include "MissionComponent.h"
|
||
|
|
||
|
void AmSkullkinDrill::OnStartup(Entity* self)
|
||
|
{
|
||
|
self->SetNetworkVar(u"bIsInUse", false);
|
||
|
self->SetVar(u"bActive", true);
|
||
|
|
||
|
GameMessages::SendPlayFXEffect(self->GetObjectID(), -1, u"spin", "active");
|
||
|
|
||
|
auto* movingPlatformComponent = self->GetComponent<MovingPlatformComponent>();
|
||
|
|
||
|
if (movingPlatformComponent == nullptr)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
movingPlatformComponent->SetSerialized(true);
|
||
|
|
||
|
movingPlatformComponent->GotoWaypoint(0);
|
||
|
|
||
|
auto* standObj = GetStandObj(self);
|
||
|
|
||
|
if (standObj != nullptr)
|
||
|
{
|
||
|
standObj->SetVar(u"bActive", true);
|
||
|
}
|
||
|
|
||
|
self->SetProximityRadius(5, "spin_distance");
|
||
|
}
|
||
|
|
||
|
Entity* AmSkullkinDrill::GetStandObj(Entity* self)
|
||
|
{
|
||
|
const auto& myGroup = self->GetGroups();
|
||
|
|
||
|
if (myGroup.empty())
|
||
|
{
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
std::string groupName = "Drill_Stand_";
|
||
|
|
||
|
groupName.push_back(myGroup[0][myGroup[0].size() - 1]);
|
||
|
|
||
|
const auto standObjs = EntityManager::Instance()->GetEntitiesInGroup(groupName);
|
||
|
|
||
|
if (standObjs.empty())
|
||
|
{
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
return standObjs[0];
|
||
|
}
|
||
|
|
||
|
void AmSkullkinDrill::OnSkillEventFired(Entity* self, Entity* caster, const std::string& message)
|
||
|
{
|
||
|
if (message != "NinjagoSpinEvent" || self->GetNetworkVar<bool>(u"bIsInUse"))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
auto* proximityMonitorComponent = self->GetComponent<ProximityMonitorComponent>();
|
||
|
|
||
|
if (proximityMonitorComponent == nullptr || !proximityMonitorComponent->IsInProximity("spin_distance", caster->GetObjectID()))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
self->SetVar(u"activaterID", caster->GetObjectID());
|
||
|
|
||
|
self->SetNetworkVar(u"bIsInUse", true);
|
||
|
|
||
|
TriggerDrill(self);
|
||
|
}
|
||
|
|
||
|
void AmSkullkinDrill::TriggerDrill(Entity* self)
|
||
|
{
|
||
|
GameMessages::SendPlayAnimation(self, u"slowdown");
|
||
|
|
||
|
self->AddTimer("killDrill", 10.0f);
|
||
|
|
||
|
auto* standObj = GetStandObj(self);
|
||
|
|
||
|
if (standObj != nullptr)
|
||
|
{
|
||
|
Game::logger->Log("AmSkullkinDrill", "Disabling knockback\n");
|
||
|
|
||
|
standObj->SetVar(u"bActive", false);
|
||
|
}
|
||
|
|
||
|
auto* movingPlatformComponent = self->GetComponent<MovingPlatformComponent>();
|
||
|
|
||
|
if (movingPlatformComponent == nullptr)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
movingPlatformComponent->GotoWaypoint(1);
|
||
|
}
|
||
|
|
||
|
void AmSkullkinDrill::OnWaypointReached(Entity* self, uint32_t waypointIndex)
|
||
|
{
|
||
|
if (waypointIndex == 1)
|
||
|
{
|
||
|
auto myPos = self->GetPosition();
|
||
|
auto myRot = self->GetRotation();
|
||
|
|
||
|
myPos.y -= 21;
|
||
|
|
||
|
EntityInfo info = {};
|
||
|
info.lot = 12346;
|
||
|
info.pos = myPos;
|
||
|
info.rot = myRot;
|
||
|
info.scale = 3; // Needs the scale, otherwise attacks fail
|
||
|
info.spawnerID = self->GetObjectID();
|
||
|
|
||
|
auto* child = EntityManager::Instance()->CreateEntity(info);
|
||
|
|
||
|
EntityManager::Instance()->ConstructEntity(child);
|
||
|
|
||
|
self->SetVar(u"ChildSmash", child->GetObjectID());
|
||
|
|
||
|
child->AddDieCallback([this, self] () {
|
||
|
const auto& userID = self->GetVar<LWOOBJID>(u"activaterID");
|
||
|
|
||
|
auto* player = EntityManager::Instance()->GetEntity(userID);
|
||
|
|
||
|
if (player == nullptr)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
OnHitOrHealResult(self, player, 1);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
OnArrived(self, waypointIndex);
|
||
|
}
|
||
|
|
||
|
void AmSkullkinDrill::OnUse(Entity* self, Entity* user)
|
||
|
{
|
||
|
if (self->GetNetworkVar<bool>(u"bIsInUse"))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
self->SetNetworkVar(u"bIsInUse", true);
|
||
|
|
||
|
GameMessages::SendPlayFXEffect(user->GetObjectID(), 5499, u"on-anim", "tornado");
|
||
|
GameMessages::SendPlayFXEffect(user->GetObjectID(), 5502, u"on-anim", "staff");
|
||
|
|
||
|
const auto userID = user->GetObjectID();
|
||
|
|
||
|
self->SetVar(u"userID", userID);
|
||
|
self->SetVar(u"activaterID", userID);
|
||
|
|
||
|
PlayAnim(self, user, "spinjitzu-staff-windup");
|
||
|
PlayCinematic(self);
|
||
|
|
||
|
FreezePlayer(self, user, true);
|
||
|
}
|
||
|
|
||
|
void AmSkullkinDrill::FreezePlayer(Entity* self, Entity* player, bool bFreeze)
|
||
|
{
|
||
|
eStunState eChangeType = POP;
|
||
|
|
||
|
if (bFreeze)
|
||
|
{
|
||
|
if (player->GetIsDead())
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
eChangeType = PUSH;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (player->GetIsDead())
|
||
|
{
|
||
|
//
|
||
|
}
|
||
|
}
|
||
|
|
||
|
GameMessages::SendSetStunned(player->GetObjectID(), eChangeType, player->GetSystemAddress(), self->GetObjectID(),
|
||
|
true, false, true, false, true, false, true
|
||
|
);
|
||
|
}
|
||
|
|
||
|
void AmSkullkinDrill::OnArrived(Entity* self, uint32_t waypointIndex)
|
||
|
{
|
||
|
auto* standObj = GetStandObj(self);
|
||
|
|
||
|
if (waypointIndex == 1)
|
||
|
{
|
||
|
GameMessages::SendPlayAnimation(self, u"no-spin");
|
||
|
GameMessages::SendStopFXEffect(self, true, "active");
|
||
|
GameMessages::SendPlayFXEffect(self->GetObjectID(), -1, u"indicator", "indicator");
|
||
|
|
||
|
self->SetVar(u"bActive", false);
|
||
|
|
||
|
const auto playerID = self->GetVar<LWOOBJID>(u"userID");
|
||
|
|
||
|
auto* player = EntityManager::Instance()->GetEntity(playerID);
|
||
|
|
||
|
if (player != nullptr)
|
||
|
{
|
||
|
PlayAnim(self, player, "spinjitzu-staff-end");
|
||
|
}
|
||
|
|
||
|
if (standObj != nullptr)
|
||
|
{
|
||
|
Game::logger->Log("AmSkullkinDrill", "Disabling knockback\n");
|
||
|
|
||
|
standObj->SetVar(u"bActive", false);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
GameMessages::SendPlayAnimation(self, u"idle");
|
||
|
GameMessages::SendPlayFXEffect(self->GetObjectID(), -1, u"spin", "active");
|
||
|
GameMessages::SendStopFXEffect(self, true, "indicator");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void AmSkullkinDrill::PlayCinematic(Entity* self)
|
||
|
{
|
||
|
auto* player = EntityManager::Instance()->GetEntity(self->GetVar<LWOOBJID>(u"userID"));
|
||
|
|
||
|
if (player == nullptr)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const auto& cine = self->GetVar<std::u16string>(u"cinematic");
|
||
|
|
||
|
if (cine.empty())
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
GameMessages::SendPlayCinematic(player->GetObjectID(), cine, player->GetSystemAddress());
|
||
|
}
|
||
|
|
||
|
void AmSkullkinDrill::PlayAnim(Entity* self, Entity* player, const std::string& animName)
|
||
|
{
|
||
|
const auto animTime = animName == "spinjitzu-staff-end" ? 0.5f : 1.0f;
|
||
|
|
||
|
GameMessages::SendPlayAnimation(player, GeneralUtils::ASCIIToUTF16(animName));
|
||
|
|
||
|
self->AddTimer("AnimDone_" + animName, animTime);
|
||
|
}
|
||
|
|
||
|
void AmSkullkinDrill::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t damage)
|
||
|
{
|
||
|
auto* destroyableComponent = self->GetComponent<DestroyableComponent>();
|
||
|
|
||
|
if (destroyableComponent == nullptr || !attacker->IsPlayer())
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (self->GetVar<bool>(u"bActive"))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const auto activaterID = self->GetVar<LWOOBJID>(u"activaterID");
|
||
|
|
||
|
auto* activator = EntityManager::Instance()->GetEntity(activaterID);
|
||
|
|
||
|
// TODO: Missions
|
||
|
if (activator != nullptr)
|
||
|
{
|
||
|
auto* missionComponent = activator->GetComponent<MissionComponent>();
|
||
|
|
||
|
if (missionComponent != nullptr)
|
||
|
{
|
||
|
for (const auto missionID : m_MissionsToUpdate)
|
||
|
{
|
||
|
missionComponent->ForceProgressValue(missionID, 1, self->GetLOT());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
self->Smash(attacker->GetObjectID(), SILENT);
|
||
|
|
||
|
self->CancelAllTimers();
|
||
|
|
||
|
auto* standObj = GetStandObj(self);
|
||
|
|
||
|
if (standObj != nullptr)
|
||
|
{
|
||
|
GameMessages::SendPlayFXEffect(standObj->GetObjectID(), 4946, u"explode", "explode");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void AmSkullkinDrill::OnTimerDone(Entity* self, std::string timerName)
|
||
|
{
|
||
|
Game::logger->Log("AmSkullkinDrill", "Timer: %s\n", timerName.c_str());
|
||
|
|
||
|
if (timerName == "killDrill")
|
||
|
{
|
||
|
const auto childID = self->GetVar<LWOOBJID>(u"ChildSmash");
|
||
|
|
||
|
auto* child = EntityManager::Instance()->GetEntity(childID);
|
||
|
|
||
|
if (child != nullptr)
|
||
|
{
|
||
|
child->Smash(self->GetObjectID(), SILENT);
|
||
|
}
|
||
|
|
||
|
self->SetNetworkVar(u"bIsInUse", false);
|
||
|
self->SetVar(u"bActive", true);
|
||
|
self->SetVar(u"activaterID", LWOOBJID_EMPTY);
|
||
|
|
||
|
auto* standObj = GetStandObj(self);
|
||
|
|
||
|
if (standObj != nullptr)
|
||
|
{
|
||
|
Game::logger->Log("AmSkullkinDrill", "Enabling knockback\n");
|
||
|
|
||
|
standObj->SetVar(u"bActive", true);
|
||
|
}
|
||
|
|
||
|
auto* movingPlatformComponent = self->GetComponent<MovingPlatformComponent>();
|
||
|
|
||
|
if (movingPlatformComponent == nullptr)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
movingPlatformComponent->GotoWaypoint(0);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const auto& data = GeneralUtils::SplitString(timerName, '_');
|
||
|
|
||
|
if (data.empty())
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (data[0] == "AnimDone")
|
||
|
{
|
||
|
const auto& animName = data[1];
|
||
|
|
||
|
Game::logger->Log("AmSkullkinDrill", "Anim done: %s\n", animName.c_str());
|
||
|
|
||
|
const auto playerID = self->GetVar<LWOOBJID>(u"userID");
|
||
|
|
||
|
auto* player = EntityManager::Instance()->GetEntity(playerID);
|
||
|
|
||
|
if (player == nullptr)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (animName == "spinjitzu-staff-windup")
|
||
|
{
|
||
|
Game::logger->Log("AmSkullkinDrill", "Triggering drill\n");
|
||
|
|
||
|
TriggerDrill(self);
|
||
|
|
||
|
GameMessages::SendPlayAnimation(player, u"spinjitzu-staff-loop");
|
||
|
}
|
||
|
else if (animName == "spinjitzu-staff-end")
|
||
|
{
|
||
|
FreezePlayer(self, player, false);
|
||
|
|
||
|
self->SetVar(u"userID", LWOOBJID_EMPTY);
|
||
|
|
||
|
GameMessages::SendStopFXEffect(player, true, "tornado");
|
||
|
GameMessages::SendStopFXEffect(player, true, "staff");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else if (data[0] == "TryUnFreezeAgain")
|
||
|
{
|
||
|
|
||
|
}
|
||
|
}
|