diff --git a/dScripts/CppScripts.cpp b/dScripts/CppScripts.cpp index 93f138cc1..ce0ae133f 100644 --- a/dScripts/CppScripts.cpp +++ b/dScripts/CppScripts.cpp @@ -295,6 +295,7 @@ #include "CauldronOfLife.h" #include "FountainOfImagination.h" #include "Sunflower.h" +#include "Turret.h" #include "BootyDigServer.h" #include "PersonalFortress.h" #include "PropertyDevice.h" @@ -661,6 +662,7 @@ namespace { //Scripted Equipment {"scripts\\EquipmentScripts\\Sunflower.lua", []() {return new Sunflower();}}, + {"scripts\\EquipmentScripts\\TURRET.lua", []() {return new Turret();}}, {"scripts/EquipmentScripts/AnvilOfArmor.lua", []() {return new AnvilOfArmor();}}, {"scripts/EquipmentScripts/FountainOfImagination.lua", []() {return new FountainOfImagination();}}, {"scripts/EquipmentScripts/CauldronOfLife.lua", []() {return new CauldronOfLife();}}, diff --git a/dScripts/EquipmentScripts/CMakeLists.txt b/dScripts/EquipmentScripts/CMakeLists.txt index 60f315035..09c3cce84 100644 --- a/dScripts/EquipmentScripts/CMakeLists.txt +++ b/dScripts/EquipmentScripts/CMakeLists.txt @@ -1,5 +1,6 @@ set(DSCRIPTS_SOURCES_EQUIPMENTSCRIPTS "Sunflower.cpp" + "Turret.cpp" "AnvilOfArmor.cpp" "FountainOfImagination.cpp" "CauldronOfLife.cpp" diff --git a/dScripts/EquipmentScripts/Turret.cpp b/dScripts/EquipmentScripts/Turret.cpp new file mode 100644 index 000000000..39938fcb2 --- /dev/null +++ b/dScripts/EquipmentScripts/Turret.cpp @@ -0,0 +1,52 @@ +#include "Turret.h" + +#include "BaseCombatAIComponent.h" +#include "ControllablePhysicsComponent.h" +#include "DestroyableComponent.h" +#include "Entity.h" +#include "eQuickBuildState.h" +#include "eStateChangeType.h" + +void Turret::SetCombatAI(Entity* self, bool enabled) { + if (auto* combatAI = self->GetComponent()) combatAI->SetDisabled(!enabled); +} + +void Turret::OnStartup(Entity* self) { + SetCombatAI(self, false); + self->SetVar(u"currentTime", 1); + self->SetVar(u"building", false); + self->AddTimer("TickTime", 1.0f); + + // SetStunImmunity (attack, interrupt) and SetStatusImmunity (pull to point, knockback); DLU keeps interrupt with the status ones + if (auto* controllablePhysics = self->GetComponent()) { + controllablePhysics->SetStunImmunity(eStateChangeType::PUSH, self->GetObjectID(), true, false, false, false, false, false, false); + } + if (auto* destroyable = self->GetComponent()) { + destroyable->SetStatusImmunity(eStateChangeType::PUSH, false, false, true, true, false, false, false, false, true); + } +} + +void Turret::OnQuickBuildStart(Entity* self, Entity* target) { + self->SetVar(u"building", true); +} + +void Turret::OnQuickBuildNotifyState(Entity* self, eQuickBuildState state) { + if (state != eQuickBuildState::COMPLETED) return; + SetCombatAI(self, true); + self->SetVar(u"building", false); + self->CancelAllTimers(); + self->AddTimer("TickTime", 1.0f); +} + +void Turret::OnTimerDone(Entity* self, std::string timerName) { + if (timerName != "TickTime") return; + const auto currentTime = self->GetVar(u"currentTime") + 1; + self->SetVar(u"currentTime", currentTime); + if (currentTime >= KILL_TIME && !self->GetVar(u"building")) { + SetCombatAI(self, false); + self->SetVar(u"currentTime", 0); + self->Smash(self->GetObjectID()); + return; + } + self->AddTimer("TickTime", 1.0f); +} diff --git a/dScripts/EquipmentScripts/Turret.h b/dScripts/EquipmentScripts/Turret.h new file mode 100644 index 000000000..6c0a8dee1 --- /dev/null +++ b/dScripts/EquipmentScripts/Turret.h @@ -0,0 +1,15 @@ +#pragma once +#include "CppScripts.h" + +// TURRET.lua: the Assembly Engineer turret. Its combat AI is off until it is built; it can't be stunned, interrupted, +// knocked back or pulled; it dies 30 seconds after it was placed, once nobody is building it. +class Turret : public CppScripts::Script { +public: + void OnStartup(Entity* self) override; + void OnQuickBuildStart(Entity* self, Entity* target) override; + void OnQuickBuildNotifyState(Entity* self, eQuickBuildState state) override; + void OnTimerDone(Entity* self, std::string timerName) override; +private: + static void SetCombatAI(Entity* self, bool enabled); + static constexpr int32_t KILL_TIME = 30; +};