summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/sql/updates/db_world/2025_09_29_00.sql19
-rw-r--r--data/sql/updates/db_world/2025_09_30_00.sql6
-rw-r--r--data/sql/updates/db_world/2025_09_30_01.sql4
-rw-r--r--data/sql/updates/db_world/2025_09_30_02.sql3
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp56
-rw-r--r--src/server/game/Server/WorldSession.h1
-rw-r--r--src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp13
-rw-r--r--src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp15
-rw-r--r--src/server/shared/SharedDefines.h17
9 files changed, 84 insertions, 50 deletions
diff --git a/data/sql/updates/db_world/2025_09_29_00.sql b/data/sql/updates/db_world/2025_09_29_00.sql
new file mode 100644
index 0000000000..4fb84247d1
--- /dev/null
+++ b/data/sql/updates/db_world/2025_09_29_00.sql
@@ -0,0 +1,19 @@
+-- DB update 2025_09_28_01 -> 2025_09_29_00
+
+-- Update SmartAI (Bleeding Hollow Necrolyte and Tunneler)
+UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE (`entry` IN (16968, 19422));
+
+DELETE FROM `smart_scripts` WHERE (`source_type` = 0) AND (`entryorguid` IN (16968, 19422));
+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
+(19422, 0, 0, 0, 0, 0, 100, 0, 0, 0, 2400, 3800, 0, 0, 11, 9053, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Bleeding Hollow Necrolyte - In Combat - Cast \'Fireball\''),
+(19422, 0, 1, 0, 0, 0, 100, 0, 8000, 12000, 30000, 45000, 0, 0, 11, 34073, 33, 0, 0, 0, 0, 5, 0, 0, 0, 34073, 0, 0, 0, 0, 'Bleeding Hollow Necrolyte - In Combat - Cast \'Curse of the Bleeding Hollow\''),
+(19422, 0, 2, 0, 2, 0, 100, 512, 0, 15, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Bleeding Hollow Necrolyte - Between 0-15% Health - Flee For Assist'),
+(19422, 0, 3, 0, 5, 0, 100, 1, 0, 0, 0, 0, 0, 0, 11, 34019, 1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Bleeding Hollow Necrolyte - On Killed Unit - Cast \'Raise Dead\' (No Repeat)'),
+(16968, 0, 0, 1, 25, 0, 100, 512, 0, 0, 0, 0, 0, 0, 18, 33554432, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Tunneler - On Reset - Set Flags Not Selectable'),
+(16968, 0, 1, 2, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 11, 29147, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Tunneler - On Reset - Cast \'Tunnel Bore Passive\''),
+(16968, 0, 2, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 90, 9, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Tunneler - On Reset - Set Flag Standstate Submerged'),
+(16968, 0, 3, 4, 4, 0, 100, 512, 0, 0, 0, 0, 0, 0, 19, 33554432, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Tunneler - On Aggro - Remove Flags Not Selectable'),
+(16968, 0, 4, 5, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 28, 29147, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Tunneler - On Aggro - Remove Aura \'Tunnel Bore Passive\''),
+(16968, 0, 5, 0, 61, 0, 100, 513, 0, 0, 0, 0, 0, 0, 91, 9, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Tunneler - On Aggro - Remove FlagStandstate Submerged'),
+(16968, 0, 6, 0, 0, 0, 100, 0, 1000, 6000, 8000, 11000, 0, 0, 11, 32738, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Tunneler - In Combat - Cast \'Bore\''),
+(16968, 0, 7, 0, 9, 0, 100, 0, 0, 0, 2000, 3500, 4, 50, 11, 31747, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Tunneler - Within 4-50 Range - Cast \'Poison\'');
diff --git a/data/sql/updates/db_world/2025_09_30_00.sql b/data/sql/updates/db_world/2025_09_30_00.sql
new file mode 100644
index 0000000000..c4fbf8264a
--- /dev/null
+++ b/data/sql/updates/db_world/2025_09_30_00.sql
@@ -0,0 +1,6 @@
+-- DB update 2025_09_29_00 -> 2025_09_30_00
+DELETE FROM `creature_formations` WHERE (`leaderGUID` = 127046);
+INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES
+(127046, 127046, 0, 0, 1, 0, 0),
+(127046, 127080, 0, 0, 1, 0, 0),
+(127046, 127081, 0, 0, 1, 0, 0);
diff --git a/data/sql/updates/db_world/2025_09_30_01.sql b/data/sql/updates/db_world/2025_09_30_01.sql
new file mode 100644
index 0000000000..1d4899fe1e
--- /dev/null
+++ b/data/sql/updates/db_world/2025_09_30_01.sql
@@ -0,0 +1,4 @@
+-- DB update 2025_09_30_00 -> 2025_09_30_01
+-- Drakkari Colossus - Mortal Strike spell difficulty
+DELETE FROM `spelldifficulty_dbc` WHERE `ID` = 54715;
+INSERT INTO `spelldifficulty_dbc` (`ID`, `DifficultySpellID_1`, `DifficultySpellID_2`, `DifficultySpellID_3`, `DifficultySpellID_4`) VALUES (54715, 54715, 59454, 0, 0);
diff --git a/data/sql/updates/db_world/2025_09_30_02.sql b/data/sql/updates/db_world/2025_09_30_02.sql
new file mode 100644
index 0000000000..15ed01d1af
--- /dev/null
+++ b/data/sql/updates/db_world/2025_09_30_02.sql
@@ -0,0 +1,3 @@
+-- DB update 2025_09_30_01 -> 2025_09_30_02
+--
+UPDATE `creature_template` SET `type` = 8 WHERE `entry` = 8881;
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 259bf34158..1bb8ac6ed2 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -668,51 +668,46 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData)
void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData)
{
- m_playerLoading = true;
- ObjectGuid playerGuid;
- recvData >> playerGuid;
+ if (!sWorld->getBoolConfig(CONFIG_REALM_LOGIN_ENABLED))
+ {
+ SendCharLoginFailed(LoginFailureReason::NoWorld);
+ return;
+ }
- if (PlayerLoading() || GetPlayer() != nullptr || !playerGuid.IsPlayer())
+ if (PlayerLoading() || GetPlayer() != nullptr)
{
- // limit player interaction with the world
- if (!sWorld->getBoolConfig(CONFIG_REALM_LOGIN_ENABLED))
- {
- WorldPacket data(SMSG_CHARACTER_LOGIN_FAILED, 1);
- // see LoginFailureReason enum for more reasons
- data << uint8(LoginFailureReason::NoWorld);
- SendPacket(&data);
- return;
- }
+ LOG_ERROR("network", "Player tried to login again, AccountId = {}", GetAccountId());
+ KickPlayer("WorldSession::HandlePlayerLoginOpcode Another client logging in");
+ return;
}
- if (!playerGuid.IsPlayer() || !IsLegitCharacterForAccount(playerGuid))
+ ObjectGuid playerGuid;
+ recvData >> playerGuid;
+
+ if (!IsLegitCharacterForAccount(playerGuid))
{
LOG_ERROR("network", "Account ({}) can't login with that character ({}).", GetAccountId(), playerGuid.ToString());
KickPlayer("Account can't login with this character");
return;
}
- auto SendCharLogin = [&](ResponseCodes result)
- {
- WorldPacket data(SMSG_CHARACTER_LOGIN_FAILED, 1);
- data << uint8(result);
- SendPacket(&data);
- };
-
// pussywizard:
if (WorldSession* sess = sWorldSessionMgr->FindOfflineSessionForCharacterGUID(playerGuid.GetCounter()))
+ {
if (sess->GetAccountId() != GetAccountId())
{
- SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER);
+ SendCharLoginFailed(LoginFailureReason::DuplicateCharacter);
return;
}
+ }
+
// pussywizard:
if (WorldSession* sess = sWorldSessionMgr->FindOfflineSession(GetAccountId()))
{
Player* p = sess->GetPlayer();
if (!p || sess->IsKicked())
{
- SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER);
+ SendCharLoginFailed(LoginFailureReason::DuplicateCharacter);
return;
}
@@ -723,7 +718,7 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData)
// pussywizard: players stay ingame no matter what (prevent abuse), but allow to turn it off to stop crashing
if (!sWorld->getBoolConfig(CONFIG_ENABLE_LOGIN_AFTER_DC))
{
- SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER);
+ SendCharLoginFailed(LoginFailureReason::DuplicateCharacter);
return;
}
@@ -765,7 +760,7 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData)
}
if (!p->FindMap() || !p->IsInWorld() || sess->IsKicked())
{
- SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER);
+ SendCharLoginFailed(LoginFailureReason::DuplicateCharacter);
return;
}
@@ -781,11 +776,9 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData)
std::shared_ptr<LoginQueryHolder> holder = std::make_shared<LoginQueryHolder>(GetAccountId(), playerGuid);
if (!holder->Initialize())
- {
- m_playerLoading = false;
return;
- }
+ m_playerLoading = true;
AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder)
{
HandlePlayerLoginFromDB(static_cast<LoginQueryHolder const&>(holder));
@@ -2575,6 +2568,13 @@ void WorldSession::SendCharDelete(ResponseCodes result)
SendPacket(&data);
}
+void WorldSession::SendCharLoginFailed(LoginFailureReason reason)
+{
+ WorldPacket data(SMSG_CHARACTER_LOGIN_FAILED, 1);
+ data << uint8(reason);
+ SendPacket(&data);
+};
+
void WorldSession::SendCharRename(ResponseCodes result, CharacterRenameInfo const* renameInfo)
{
WorldPacket data(SMSG_CHAR_RENAME, 1 + 8 + renameInfo->Name.size() + 1);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 15c0a73685..c5fa3c8aee 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -601,6 +601,7 @@ public: // opcodes handlers
void SendCharCreate(ResponseCodes result);
void SendCharDelete(ResponseCodes result);
+ void SendCharLoginFailed(LoginFailureReason reason);
void SendCharRename(ResponseCodes result, CharacterRenameInfo const* renameInfo);
void SendCharCustomize(ResponseCodes result, CharacterCustomizeInfo const* customizeInfo);
void SendCharFactionChange(ResponseCodes result, CharacterFactionChangeInfo const* factionChangeInfo);
diff --git a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
index 8a9463b514..18a30b7dbc 100644
--- a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
+++ b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
@@ -27,6 +27,7 @@ enum Spells
SPELL_MOJO_WAVE = 55626,
SPELL_FREEZE_ANIM = 52656,
SPELL_MIGHTY_BLOW = 54719,
+ SPELL_MORTAL_STRIKE = 54715,
SPELL_ELEMENTAL_SPAWN_EFFECT = 54888,
SPELL_EMERGE = 54850,
@@ -54,9 +55,10 @@ enum Misc
EMOTE_ALTAR = 1,
EVENT_COLOSSUS_MIGHTY_BLOW = 1,
- EVENT_COLOSSUS_HEALTH_1 = 2,
- EVENT_COLOSSUS_HEALTH_2 = 3,
- EVENT_COLOSSUS_START_FIGHT = 4,
+ EVENT_COLOSSUS_MORTAL_STRIKE = 2,
+ EVENT_COLOSSUS_HEALTH_1 = 3,
+ EVENT_COLOSSUS_HEALTH_2 = 4,
+ EVENT_COLOSSUS_START_FIGHT = 5,
EVENT_ELEMENTAL_HEALTH = 10,
EVENT_ELEMENTAL_SURGE = 11,
@@ -146,6 +148,7 @@ public:
{
BossAI::JustEngagedWith(who);
events.ScheduleEvent(EVENT_COLOSSUS_MIGHTY_BLOW, 10s);
+ events.ScheduleEvent(EVENT_COLOSSUS_MORTAL_STRIKE, 7s);
events.ScheduleEvent(EVENT_COLOSSUS_HEALTH_1, 1s);
events.ScheduleEvent(EVENT_COLOSSUS_HEALTH_2, 1s);
}
@@ -212,6 +215,10 @@ public:
me->CastSpell(me->GetVictim(), SPELL_MIGHTY_BLOW, false);
events.ScheduleEvent(EVENT_COLOSSUS_MIGHTY_BLOW, 10s);
break;
+ case EVENT_COLOSSUS_MORTAL_STRIKE:
+ DoCastVictim(SPELL_MORTAL_STRIKE);
+ events.ScheduleEvent(EVENT_COLOSSUS_MORTAL_STRIKE, 7s);
+ break;
case EVENT_COLOSSUS_HEALTH_1:
if (me->HealthBelowPct(51))
{
diff --git a/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp b/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp
index 68a22e9640..5bf51b7c91 100644
--- a/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp
+++ b/src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp
@@ -51,14 +51,7 @@ enum Misc
MAX_CONSTRICTOR = 3,
MAX_SUMMONS = 5,
- EVENT_POISON_NOVA = 1,
- EVENT_POWERFULL_BITE = 2,
- EVENT_VENOM_BOLT = 3,
- EVENT_CHECK_HEALTH1 = 4,
- EVENT_CHECK_HEALTH2 = 5,
- EVENT_SUMMON1 = 6,
- EVENT_SUMMON2 = 7,
- EVENT_KILL_TALK = 8
+ EVENT_KILL_TALK = 1
};
const Position SpawnLoc[] =
@@ -121,17 +114,17 @@ public:
Talk(SAY_AGGRO);
BossAI::JustEngagedWith(who);
- ScheduleTimedEvent(10s, [&]{
+ ScheduleTimedEvent(16s, 53s, [&]{
Talk(EMOTE_NOVA);
DoCastAOE(SPELL_POISON_NOVA);
- }, 15s);
+ }, 16s, 53s);
ScheduleTimedEvent(3s, [&] {
DoCastVictim(SPELL_POWERFULL_BITE);
}, 10s);
ScheduleTimedEvent(15s, [&] {
- DoCastVictim(SPELL_VENOM_BOLT);
+ DoCastRandomTarget(SPELL_VENOM_BOLT, 0, 45.0f, false);
}, 10s);
}
diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h
index fb95d6cea5..aa278a3d63 100644
--- a/src/server/shared/SharedDefines.h
+++ b/src/server/shared/SharedDefines.h
@@ -4010,14 +4010,15 @@ enum ServerProcessTypes
// Login Failure Reasons
enum class LoginFailureReason : uint8
{
- Failed = 0,
- NoWorld = 1,
- DuplicateCharacter = 2,
- NoInstances = 3,
- Disabled = 4,
- NoCharacter = 5,
- LockedForTransfer = 6,
- LockedByBilling = 7
+ Failed = 0, // Login failed
+ NoWorld = 1, // World server down
+ DuplicateCharacter = 2, // A character with that name already exists
+ NoInstances = 3, // No instance servers are available
+ Disabled = 4, // Login for that race, class or character is currently disabled.
+ NoCharacter = 5, // Character not found
+ LockedForTransfer = 6, // You cannot log in until the character update process you recently initiated is complete.
+ LockedByBilling = 7, // Character locked. Contact billing for more information
+ UsingRemote = 8, // You cannot log in while using World of Warcraft Remote.
};
namespace Acore::Impl