Merge branch 'master' into ScheduleCreatureRespawn

This commit is contained in:
天鹭 2025-10-08 23:21:19 +08:00 committed by GitHub
commit 1ee1d6cd6b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 132 additions and 100 deletions

View File

@ -0,0 +1,12 @@
-- DB update 2025_10_04_04 -> 2025_10_04_05
-- Update SmartAI (Horde Siege Tank and Barrels).
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE (`entry` IN (25334, 27064));
DELETE FROM `smart_scripts` WHERE (`source_type` = 0) AND (`entryorguid` IN (25334, 27064));
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
(27064, 0, 0, 1, 103, 0, 100, 512, 0, 25334, 1, 2, 0, 0, 11, 47916, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Abandoned Fuel Tank - On 1 or More Units in Range - Cast \'Fuel\''),
(27064, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 4000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Abandoned Fuel Tank - On 1 or More Units in Range - Despawn In 4000 ms'),
(27064, 0, 2, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Abandoned Fuel Tank - On Respawn - Stop Attacking'),
(25334, 0, 0, 0, 8, 0, 100, 512, 47916, 0, 2000, 2000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Horde Siege Tank - On Spellhit \'Fuel\' - Say Line 0'),
(25334, 0, 1, 0, 28, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 1000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Horde Siege Tank - On Passenger Removed - Despawn In 1000 ms');

View File

@ -0,0 +1,13 @@
-- DB update 2025_10_04_05 -> 2025_10_04_06
-- Update gameobject 'Doodad_Nox_portal_top01' with sniffed values
-- updated spawns
DELETE FROM `gameobject` WHERE (`id` IN (191542)) AND (`guid` IN (57145, 57146));
INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES
(57145, 191542, 571, 0, 0, 1, 1, 6175.19140625, -2017.2734375, 241.0088348388671875, 2.312558174133300781, 0, 0, 0.915310859680175781, 0.402748137712478637, 120, 255, 1, "", 48019, NULL),
(57146, 191542, 571, 0, 0, 1, 1, 5171.69140625, -1666.64453125, 242.7811279296875, 2.888511419296264648, 0, 0, 0.99200439453125, 0.126203224062919616, 120, 255, 1, "", 46368, NULL);
-- new spawns
DELETE FROM `gameobject` WHERE (`id` IN (191542, 192613)) AND (`guid` IN (149, 150));
INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES
(149, 191542, 571, 0, 0, 1, 1, 2418.4443359375, 6456.0224609375, 50.21396255493164062, 1.608663797378540039, 0, 0, 0.720367431640625, 0.693592667579650878, 120, 255, 1, "", 45772, NULL),
(150, 192613, 571, 0, 0, 1, 1, 3669.799072265625, -1269.822021484375, 251.2554931640625, 2.404482841491699218, 0, 0, 0.932848930358886718, 0.360267788171768188, 120, 255, 1, "", 45854, NULL);

View File

@ -0,0 +1,9 @@
-- DB update 2025_10_04_06 -> 2025_10_06_00
--
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = -127203);
DELETE FROM `creature_formations` WHERE `leaderGUID` = 127203;
INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES
(127203, 127203, 0, 0, 3, 0, 0),
(127203, 127201, 0, 0, 3, 0, 0),
(127203, 127202, 0, 0, 3, 0, 0);

View File

@ -0,0 +1,4 @@
-- DB update 2025_10_06_00 -> 2025_10_07_00
-- Remove Disarm Immunity
UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask` &~ 4 WHERE (`entry` IN (31368, 29306));

View File

@ -0,0 +1,17 @@
-- DB update 2025_10_07_00 -> 2025_10_07_01
--
UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = 25084;
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 25084);
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
(25084, 0, 0, 1, 8, 0, 100, 1, 45109, 0, 0, 0, 0, 0, 11, 45110, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Greengill Slave - On Spellhit \'Orb of Murloc Control\' - Cast \'Greengill Slave Freed\' (No Repeat)'),
(25084, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 45111, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Greengill Slave - On Spellhit \'Orb of Murloc Control\' - Cast \'Enrage\' (No Repeat)'),
(25084, 0, 2, 3, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 36, 25085, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Greengill Slave - On Spellhit \'Orb of Murloc Control\' - Update Template To \'Freed Greengill Slave\' (No Repeat)'),
(25084, 0, 3, 4, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 9, 25073, 0, 100, 0, 0, 0, 0, 0, 'Greengill Slave - On Spellhit \'Orb of Murloc Control\' - Start Attacking (No Repeat)'),
(25084, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 19, 25060, 100, 0, 0, 0, 0, 0, 0, 'Greengill Slave - On Spellhit \'Orb of Murloc Control\' - Start Attacking (No Repeat)'),
(25084, 0, 5, 6, 7, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 5000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Greengill Slave - On Evade - Despawn In 5000 ms'),
(25084, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 89, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Greengill Slave - On Evade - Start Random Movement');
DELETE FROM `spell_custom_attr` WHERE `spell_id` = 45111;
INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES
(45111, 0x00000800);

View File

@ -1644,6 +1644,7 @@ public:
[[nodiscard]] virtual bool CanFly() const = 0;
[[nodiscard]] bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_DISABLE_GRAVITY); }
[[nodiscard]] bool IsFalling() const;
[[nodiscard]] bool IsRooted() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_ROOT); }
[[nodiscard]] float GetHoverHeight() const { return IsHovering() ? GetFloatValue(UNIT_FIELD_HOVERHEIGHT) : 0.0f; }

View File

@ -575,6 +575,12 @@ bool WorldSession::VerifyMovementInfo(MovementInfo const& movementInfo, Player*
return false;
}
}
// rooted mover sent packet without root or moving AND root - ignore, due to client crash possibility
if (opcode != CMSG_FORCE_MOVE_UNROOT_ACK)
if (mover->IsRooted() && (!movementInfo.HasMovementFlag(MOVEMENTFLAG_ROOT) || movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_MOVING)))
return false;
return true;
}

View File

@ -23,6 +23,7 @@
#include "Unit.h"
#include "Vehicle.h"
#include "WorldPacket.h"
#include "Log.h"
namespace Movement
{
@ -103,7 +104,13 @@ namespace Movement
bool isOrientationOnly = args.path.size() == 2 && args.path[0] == args.path[1];
if ((moveFlags & MOVEMENTFLAG_ROOT) || isOrientationOnly)
if (moveFlags & MOVEMENTFLAG_ROOT) // This case should essentially never occur - hence the trace logging - hints to issues elsewhere
{
LOG_TRACE("movement", "Invalid movement during root. Entry: {} IsImmobilized {}, moveflags {}", unit->GetEntry(), unit->IsImmobilizedState() ? "true" : "false", moveFlags);
moveFlags &= ~MOVEMENTFLAG_MASK_MOVING;
}
if (isOrientationOnly)
moveFlags &= ~MOVEMENTFLAG_MASK_MOVING;
if (!args.HasVelocity)

View File

@ -5151,6 +5151,12 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->AttributesEx3 |= SPELL_ATTR3_ALWAYS_HIT;
});
// Earth Shield
ApplySpellFix({ 55599, 58981 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx5 |= SPELL_ATTR5_LIMIT_N;
});
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
{
SpellInfo* spellInfo = mSpellInfoMap[i];

View File

@ -92,24 +92,18 @@ public:
if (!target)
target = handler->GetSession()->GetPlayer();
WorldPacket data(12);
bool canFly = false;
if (enable.has_value())
{
data.SetOpcode(*enable ? SMSG_MOVE_SET_CAN_FLY : SMSG_MOVE_UNSET_CAN_FLY);
canFly = *enable;
target->SetCanFly(canFly);
}
else
{
canFly = handler->GetSession()->GetPlayer()->CanFly();
data.SetOpcode(canFly ? SMSG_MOVE_UNSET_CAN_FLY : SMSG_MOVE_SET_CAN_FLY);
canFly = !canFly;
target->SetCanFly(!canFly);
}
data << target->GetPackGUID();
data << uint32(0); // unknown
target->SendMessageToSet(&data, true);
handler->PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, handler->GetNameLink(target), canFly ? "on" : "off");
return true;
}

View File

@ -178,7 +178,12 @@ struct npc_kiljaeden_controller : public NullCreatureAI
{
summons.Summon(summon);
if (summon->GetEntry() == NPC_SINISTER_REFLECTION)
summon->SetInCombatWithZone();
{
summon->m_Events.AddEventAtOffset([summon] {
if (summon && summon->IsAlive() && !summon->IsInCombat())
summon->SetInCombatWithZone();
}, 5s);
}
else if (summon->GetEntry() == NPC_KALECGOS_KJ)
summon->setActive(true);
}

View File

@ -610,61 +610,6 @@ public:
};
};
/*###### THEIR: ######*/
/*######
## npc_greengill_slave
######*/
#define ENRAGE 45111
#define ORB 45109
#define QUESTG 11541
#define DM 25060
class npc_greengill_slave : public CreatureScript
{
public:
npc_greengill_slave() : CreatureScript("npc_greengill_slave") { }
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_greengill_slaveAI(creature);
}
struct npc_greengill_slaveAI : public ScriptedAI
{
npc_greengill_slaveAI(Creature* creature) : ScriptedAI(creature) { }
void JustEngagedWith(Unit* /*who*/) override { }
void SpellHit(Unit* caster, SpellInfo const* spellInfo) override
{
Player* player = caster->ToPlayer();
if (!player)
return;
if (spellInfo->Id == ORB && !me->HasAura(ENRAGE))
{
if (player->GetQuestStatus(QUESTG) == QUEST_STATUS_INCOMPLETE)
DoCast(player, 45110, true);
DoCast(me, ENRAGE);
if (Creature* Myrmidon = me->FindNearestCreature(DM, 70))
{
me->AddThreat(Myrmidon, 100000.0f);
AttackStart(Myrmidon);
}
}
}
void UpdateAI(uint32 /*diff*/) override
{
DoMeleeAttackIfReady();
}
};
};
// 45396, 45398 - Weapon Coating Enchant
class spell_gen_weapon_coating_enchant : public AuraScript
{
@ -690,6 +635,5 @@ void AddSC_isle_of_queldanas()
new npc_bh_thalorien_dawnseeker();
RegisterSpellScript(spell_bh_cleanse_quel_delar);
new npc_grand_magister_rommath();
new npc_greengill_slave();
RegisterSpellScript(spell_gen_weapon_coating_enchant);
}

View File

@ -1154,16 +1154,7 @@ public:
if (GameObject* go = pInstance->instance->GetGameObject(pInstance->GetGuidData(DATA_EXIT_GATE)))
go->SetGoState(GO_STATE_ACTIVE);
if (!me->GetMap()->GetPlayers().IsEmpty())
{
if (Player* player = me->GetMap()->GetPlayers().getFirst()->GetSource())
{
if (GameObject* chest = player->SummonGameObject(DUNGEON_MODE(GO_MALGANIS_CHEST_N, GO_MALGANIS_CHEST_H), 2288.35f, 1498.73f, 128.414f, -0.994837f, 0, 0, 0, 0, 0))
{
chest->SetLootRecipient(me->GetMap());
}
}
}
pInstance->instance->SummonGameObject(DUNGEON_MODE(GO_MALGANIS_CHEST_N, GO_MALGANIS_CHEST_H), 2288.35f, 1498.73f, 128.414f, -0.994837f, 0, 0, 0, 0, 7 * DAY * IN_MILLISECONDS);
}
ScheduleNextEvent(currentEvent, 10000);
break;

View File

@ -17,6 +17,7 @@
#include "CreatureScript.h"
#include "ScriptedCreature.h"
#include "SpellInfo.h"
#include "gundrak.h"
enum Spells
@ -71,6 +72,15 @@ public:
}
}
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
{
if (spell->Id == SPELL_ECK_SPRING)
{
me->GetThreatMgr().ResetAllThreat();
me->AddThreat(target, 1.0f);
}
}
void Reset() override
{
BossAI::Reset();
@ -81,8 +91,8 @@ public:
BossAI::JustEngagedWith(who);
events.ScheduleEvent(EVENT_ECK_BERSERK, 60s, 90s);
events.ScheduleEvent(EVENT_ECK_BITE, 5s);
events.ScheduleEvent(EVENT_ECK_SPIT, 10s);
events.ScheduleEvent(EVENT_ECK_SPRING, 8s);
events.ScheduleEvent(EVENT_ECK_SPIT, 10s, 37s);
events.ScheduleEvent(EVENT_ECK_SPRING, 10s, 24s);
}
void JustDied(Unit* killer) override
@ -120,17 +130,14 @@ public:
break;
case EVENT_ECK_SPIT:
me->CastSpell(me->GetVictim(), SPELL_ECK_SPIT, false);
events.ScheduleEvent(EVENT_ECK_SPIT, 10s);
events.ScheduleEvent(EVENT_ECK_SPIT, 11s, 24s);
break;
case EVENT_ECK_SPRING:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f, true, false))
{
me->GetThreatMgr().ResetAllThreat();
me->AddThreat(target, 500.0f);
me->CastSpell(target, SPELL_ECK_SPRING, false);
}
events.ScheduleEvent(EVENT_ECK_SPRING, 5s, 10s);
events.ScheduleEvent(EVENT_ECK_SPRING, 10s, 24s);
break;
}

View File

@ -30,16 +30,21 @@ enum Data
DATA_MOORABI = 1,
DATA_DRAKKARI_COLOSSUS = 2,
DATA_GAL_DARAH = 3,
DATA_ECK_THE_FEROCIOUS_INIT = 4,
DATA_ECK_THE_FEROCIOUS = 5,
MAX_ENCOUNTERS = 6
DATA_ECK_THE_FEROCIOUS = 4,
MAX_ENCOUNTERS = 5
};
enum Creatures
{
NPC_RUINS_DWELLER = 29920,
NPC_ECK_THE_FEROCIOUS = 29932
};
enum GDTexts
{
EMOTE_SUMMON_ECK = 0
};
enum GameObjects
{
GO_ALTAR_OF_SLAD_RAN = 192518,

View File

@ -15,6 +15,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CreatureGroups.h"
#include "InstanceMapScript.h"
#include "ScriptedCreature.h"
#include "gundrak.h"
@ -137,13 +138,6 @@ public:
{
switch (type)
{
case NPC_ECK_THE_FEROCIOUS:
if (GetBossState(DATA_ECK_THE_FEROCIOUS_INIT) != DONE)
{
SetBossState(DATA_ECK_THE_FEROCIOUS_INIT, NOT_STARTED);
SetBossState(DATA_ECK_THE_FEROCIOUS_INIT, DONE);
}
break;
case GO_ALTAR_OF_SLAD_RAN:
if (GameObject* statue = instance->GetGameObject(_bridgeGUIDs[0]))
statue->SetGoState(GO_STATE_READY);
@ -194,19 +188,36 @@ public:
if (GameObject* altar = instance->GetGameObject(_drakkariAltarGUID))
altar->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
break;
case DATA_ECK_THE_FEROCIOUS_INIT:
{
Position pos = {1624.70f, 891.43f, 95.08f, 1.2f};
if (instance->IsHeroic())
instance->SummonCreature(NPC_ECK_THE_FEROCIOUS, pos);
break;
}
}
return true;
}
void OnUnitDeath(Unit* unit) override
{
if (!instance->IsHeroic() || !unit->EntryEquals(NPC_RUINS_DWELLER) || IsBossDone(DATA_ECK_THE_FEROCIOUS))
return;
if (Creature* dweller = unit->ToCreature())
if (CreatureGroup* formation = dweller->GetFormation())
{
scheduler.CancelAll();
scheduler.Schedule(1s, [this, dweller, formation](TaskContext /*context*/)
{
if (!formation->IsAnyMemberAlive())
{
if (dweller)
dweller->AI()->Talk(EMOTE_SUMMON_ECK);
instance->SummonCreature(NPC_ECK_THE_FEROCIOUS, { 1624.70f, 891.43f, 95.08f, 1.2f });
}
});
}
}
void Update(uint32 diff) override
{
scheduler.Update(diff);
if (!_activateTimer)
return;