DarkflameServer/dScripts/AmSkullkinDrill.cpp

390 lines
9.5 KiB
C++
Raw Normal View History

#include "AmSkullkinDrill.h"
#include "GameMessages.h"
#include "MovingPlatformComponent.h"
#include "DestroyableComponent.h"
#include "ProximityMonitorComponent.h"
2022-06-22 08:22:59 +00:00
#include "dLogger.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")
{
}
}