mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
Every hit started both the rapid fire shooter and the rain of fire timers, from stage 1 on, so the two specials ran in every stage and on top of each other, each turning the boss's AI off and on again under the other's animations. They also wrote the "stoppedFlag" that the no-players-around attack stop uses, which could leave her stopped for good. As the live script: after she comes back down, a skill manager fires the rapid fire shooter in stage 2 and the rain of fire in stage 3 only, again 10 to 15 s after each ends; for 3.1 s after her melee smash (skill 322) a due special waits and fires when the smash ends. The rain of fire keeps her from attacking until its last impact. Check in game: Spider Queen fight: no specials before the first spiderling wave; stage 2 only rapid fire, stage 3 only rain of fire; she never freezes in the smash animation and keeps attacking after each special. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
145 lines
6.4 KiB
C++
145 lines
6.4 KiB
C++
#pragma once
|
|
#include "CppScripts.h"
|
|
|
|
/*
|
|
--------------------------------------------------------------
|
|
|
|
--L_BOSS_SPIDER_QUEEN_ENEMY_SERVER.lua
|
|
|
|
-- Server side Spider Queen Boss fight behavior script
|
|
-- created abeechler ... 5 / 12 / 11
|
|
|
|
-- ported by Wincent01 & Max, July 2020
|
|
|
|
--------------------------------------------------------------
|
|
*/
|
|
class DestroyableComponent;
|
|
class ControllablePhysicsComponent;
|
|
class BaseCombatAIComponent;
|
|
class BossSpiderQueenEnemyServer final : public CppScripts::Script {
|
|
public:
|
|
void OnStartup(Entity* self) override;
|
|
|
|
void OnDie(Entity* self, Entity* killer) override;
|
|
|
|
void OnHitOrHealResult(Entity* self, Entity* attacker, int32_t damage) override;
|
|
|
|
void OnUpdate(Entity* self) override;
|
|
|
|
void WithdrawSpider(Entity* self, bool withdraw);
|
|
|
|
void SpawnSpiderWave(Entity* self, int spiderCount);
|
|
|
|
void SpiderWaveManager(Entity* self);
|
|
|
|
void ToggleForSpecial(Entity* self, bool state);
|
|
|
|
void SetRainOfFireStun(Entity* self, bool state);
|
|
|
|
// Runs the special attack of the current stage (live SpiderSkillManager); false stops polling
|
|
void SpiderSkillManager(Entity* self, bool active);
|
|
|
|
void OnSkillCast(Entity* self, uint32_t skillID) override;
|
|
|
|
void RunRainOfFire(Entity* self);
|
|
|
|
void RainOfFireManager(Entity* self);
|
|
|
|
void RapidFireShooterManager(Entity* self);
|
|
|
|
void RunRapidFireShooter(Entity* self);
|
|
|
|
float PlayAnimAndReturnTime(Entity* self, const std::u16string& animId);
|
|
|
|
void OnTimerDone(Entity* self, std::string timerName) override;
|
|
|
|
void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status);
|
|
|
|
// The boss's client script asks for the zone data ("QueryZoneScript") once the boss renders
|
|
void OnFireEventServerSide(Entity* self, Entity* sender, std::string args, int32_t param1, int32_t param2, int32_t param3) override;
|
|
|
|
// "SpiderlingDied" from the spiderlings the eggs hatch (live: notifyDie on the spiderling)
|
|
void OnNotifyObject(Entity* self, Entity* sender, const std::string& name, int32_t param1, int32_t param2) override;
|
|
|
|
private:
|
|
void ToggleAttacking(Entity& self, bool on);
|
|
void UpdateSpecialStun(Entity* self);
|
|
//Regular variables:
|
|
DestroyableComponent* destroyable = nullptr;
|
|
ControllablePhysicsComponent* controllable = nullptr;
|
|
BaseCombatAIComponent* combat = nullptr;
|
|
|
|
NiQuaternion originRotation = QuatUtils::IDENTITY;
|
|
|
|
int m_CurrentBossStage = 0;
|
|
int m_DeathCounter = 0;
|
|
std::vector<int> ThresholdTable;
|
|
bool waitForIdle = false;
|
|
|
|
//Const variables:
|
|
|
|
const std::vector<int> spiderWaveCntTable = { 2, 3 }; //The number of Dark Spiderling enemies to spawn per indexed wave number
|
|
|
|
const int ROFImpactCnt = 2; //The number of ROF impacts in each quadrant of the arena selected at random
|
|
|
|
const LOT SpiderlingID = 16197; //Reference obj ID for hatched Spiderlings
|
|
|
|
const int maxSpiderEggCnt = 3;
|
|
int hatchCounter = 0; //Global counter mainting visibility over how many eggs we have prepped to hatch per wave
|
|
std::vector<LWOOBJID> hatchList = {}; //Global list maintaining a record of all the eggs we have prepped to hatch for a wave
|
|
|
|
const std::string defaultFacingZone = "Zone3Vol"; //Maintains a default facing to ensure appropriate Spider Boss positioning for teleported players
|
|
std::vector<int> inZoneTable = {}; //Keeps track through player ID index what quadrant of the zone the player is in now
|
|
std::vector<int> fromZoneTable = {}; //Keeps track through player ID index what quadrant of the zone the player was last in
|
|
|
|
const float defaultAnimPause = 2.5f; //Default period of time to pause between missing animation actions
|
|
const std::u16string spiderJeerAnim = u"taunt"; //Animation Spider Boss plays to antagonize the player
|
|
const std::u16string spiderROFAnim = u"attack-fire"; //Animation Spider Boss plays to telegraph the ROF attack
|
|
const std::u16string spiderWithdrawAnim = u"withdraw"; //Animation Spider Boss plays to withdraw to the top of the mountain
|
|
const std::u16string spiderAdvanceAnim = u"advance"; //Animation Spider Boss plays to come back down from the mountain
|
|
const std::u16string spiderWithdrawIdle = u"idle-withdrawn"; //Animation Spider Boss plays to idle on the mountain
|
|
const std::u16string spiderShootLeft = u"attack-shoot-left"; //Animation Spider Boss plays to RFS shoot CCW
|
|
const std::u16string spiderShootRght = u"attack-shoot-right"; //Animation Spider Boss plays to RFS shoot CW
|
|
const std::u16string spiderSingleShot = u"attack-fire-single"; //Animation Spider Boss plays for a single shot
|
|
|
|
const uint32_t bossBulletSkill = 303; //Generic Spider Boss long range attack
|
|
const uint32_t bossSmashSkill = 322; //Generic Spider Boss short range attack
|
|
const uint32_t bossQueueSkill = 1568; //Empty skill to queue for special attack timing
|
|
const uint32_t bossLandingSkill = 1539; //Generic Spider Boss landing attack
|
|
const uint32_t bossSwipeSkill = 1573; //Generic Spider Boss landing attack
|
|
|
|
const float smashSkillLength = 3.1f; //Time (in seconds) the boss smash skill lasts
|
|
|
|
// Whole seconds, as live's math.random(min, max)
|
|
const int32_t s1DelayMin = 10; //Minimum time until calling for another Rapid Fire Shot
|
|
const int32_t s1DelayMax = 15; //Maximum time until calling for another Rapid Fire Shot
|
|
const int32_t s2DelayMin = 10; //Minimum time until calling for another Rain Of Fire
|
|
const int32_t s2DelayMax = 15; //Maximum time until calling for another Rain Of Fire
|
|
|
|
const unsigned int instanceZoneID = 1102; //Zone ID for the Spider Queen fight instance
|
|
const unsigned int instanceMissionID = 1941; //Achievement to update for beating the instanced Boss
|
|
|
|
//Establishes a link for the Spider to identify rapid fire targets based on zone reference
|
|
const std::map<std::string, std::vector<std::string>> rapidFireTargetTable = {
|
|
{"Zone1Vol", {"Zone8Targets", "Zone1Targets", "Zone2Targets"}},
|
|
{"Zone2Vol", {"Zone1Targets", "Zone2Targets", "Zone3Targets"}},
|
|
{"Zone3Vol", {"Zone2Targets", "Zone3Targets", "Zone4Targets"}},
|
|
{"Zone4Vol", {"Zone3Targets", "Zone4Targets", "Zone5Targets"}},
|
|
{"Zone5Vol", {"Zone4Targets", "Zone5Targets", "Zone6Targets"}},
|
|
{"Zone6Vol", {"Zone5Targets", "Zone6Targets", "Zone7Targets"}},
|
|
{"Zone7Vol", {"Zone6Targets", "Zone7Targets", "Zone8Targets"}},
|
|
{"Zone8Vol", {"Zone7Targets", "Zone8Targets", "Zone1Targets"}}
|
|
};
|
|
|
|
const std::vector<std::string> ROFTargetGroupIDTable = {
|
|
"ROF_Targets_00",
|
|
"ROF_Targets_01",
|
|
"ROF_Targets_02",
|
|
"ROF_Targets_03",
|
|
"ROF_Targets_04"
|
|
};
|
|
|
|
std::vector<LWOOBJID> attackTargetTable;
|
|
std::vector<LWOOBJID> impactList;
|
|
};
|