#include "AmDarklingDragon.h" #include "BaseCombatAIComponent.h" #include "DestroyableComponent.h" #include "EntityManager.h" #include "GameMessages.h" #include "SkillComponent.h" #include "BaseCombatAIComponent.h" #include "EntityInfo.h" #include "eAnimationFlags.h" #include "RenderComponent.h" void AmDarklingDragon::OnStartup(Entity* self) { self->SetVar(u"weakspot", 0); auto* baseCombatAIComponent = self->GetComponent(); if (baseCombatAIComponent != nullptr) { baseCombatAIComponent->SetStunImmune(true); } } void AmDarklingDragon::OnDie(Entity* self, Entity* killer) { if (self->GetVar(u"bDied")) { return; } self->SetVar(u"bDied", true); auto golemId = self->GetVar(u"Golem"); auto* golem = Game::entityManager->GetEntity(golemId); if (golem != nullptr) { golem->Smash(self->GetObjectID()); } } void AmDarklingDragon::OnHitOrHealResult(Entity* self, Entity* attacker, int32_t damage) { GameMessages::SendPlayFXEffect(self, -1, u"gothit", "", LWOOBJID_EMPTY, 1, 1, true); if (true) { auto weakpoint = self->GetVar(u"weakspot"); if (weakpoint == 1) { self->Smash(attacker->GetObjectID()); } } auto* destroyableComponent = self->GetComponent(); if (destroyableComponent != nullptr) { if (destroyableComponent->GetArmor() > 0) return; auto weakpoint = self->GetVar(u"weakpoint"); if (weakpoint == 0) { self->AddTimer("ReviveTimer", 12); auto* baseCombatAIComponent = self->GetComponent(); auto* skillComponent = self->GetComponent(); if (baseCombatAIComponent != nullptr) { baseCombatAIComponent->SetDisabled(true); baseCombatAIComponent->SetStunned(true); } if (skillComponent != nullptr) { skillComponent->Interrupt(); skillComponent->Reset(); } self->SetVar(u"weakpoint", 2); GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_NONE, eAnimationFlags::IDLE_COMBAT, UNASSIGNED_SYSTEM_ADDRESS); float animationTime = RenderComponent::PlayAnimation(self, u"stunstart", 1.7f); self->AddTimer("timeToStunLoop", 1.0f); auto position = self->GetPosition(); auto forward = self->GetRotation().GetForwardVector(); auto backwards = forward * -1; forward.x *= 10; forward.z *= 10; auto rotation = self->GetRotation(); auto objectPosition = NiPoint3(); objectPosition.y = position.y; objectPosition.x = position.x - (backwards.x * 8); objectPosition.z = position.z - (backwards.z * 8); auto golem = self->GetVar(u"DragonSmashingGolem"); EntityInfo info{}; info.lot = golem != 0 ? golem : 8340; info.pos = objectPosition; info.rot = rotation; info.spawnerID = self->GetObjectID(); info.settings = { new LDFData(u"rebuild_activators", std::to_string(objectPosition.x + forward.x) + "\x1f" + std::to_string(objectPosition.y) + "\x1f" + std::to_string(objectPosition.z + forward.z) ), new LDFData(u"respawn", 100000), new LDFData(u"rebuild_reset_time", 15), new LDFData(u"no_timed_spawn", true), new LDFData(u"Dragon", self->GetObjectID()) }; auto* golemObject = Game::entityManager->CreateEntity(info); Game::entityManager->ConstructEntity(golemObject); } } } void AmDarklingDragon::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "ReviveHeldTimer") { self->AddTimer("backToAttack", 2.5); } else if (timerName == "ExposeWeakSpotTimer") { self->SetVar(u"weakspot", 1); } else if (timerName == "timeToStunLoop") { RenderComponent::PlayAnimation(self, u"stunloop", 1.8f); } else if (timerName == "ReviveTimer") { RenderComponent::PlayAnimation(self, u"stunend", 2.0f); self->AddTimer("backToAttack", 1); } else if (timerName == "backToAttack") { auto* baseCombatAIComponent = self->GetComponent(); auto* skillComponent = self->GetComponent(); if (baseCombatAIComponent != nullptr) { baseCombatAIComponent->SetDisabled(false); baseCombatAIComponent->SetStunned(false); } if (skillComponent != nullptr) { skillComponent->Interrupt(); skillComponent->Reset(); } GameMessages::SendChangeIdleFlags(self->GetObjectID(), eAnimationFlags::IDLE_COMBAT, eAnimationFlags::IDLE_NONE, UNASSIGNED_SYSTEM_ADDRESS); self->SetVar(u"weakspot", -1); GameMessages::SendNotifyObject(self->GetObjectID(), self->GetObjectID(), u"DragonRevive", UNASSIGNED_SYSTEM_ADDRESS); } } void AmDarklingDragon::OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) { if (args != "rebuildDone") return; self->AddTimer("ExposeWeakSpotTimer", 3.8f); self->CancelTimer("ReviveTimer"); self->AddTimer("ReviveHeldTimer", 10.5f); self->SetVar(u"Golem", sender->GetObjectID()); RenderComponent::PlayAnimation(self, u"quickbuildhold", 1.9f); }