Merge branch 'araxia-main' of github.com:araxiaonline/TrinityCore into araxia-main

This commit is contained in:
2025-12-13 19:03:19 -05:00
7 changed files with 312 additions and 2 deletions

View File

@@ -14,6 +14,13 @@
#include "GitRevision.h"
#include "GameTime.h"
#include "LuaEngine/ElunaSharedData.h"
#include "Cell.h"
#include "CellImpl.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "Creature.h"
#include "SpellMgr.h"
#include "SpellInfo.h"
#include <sstream>
namespace Araxia
@@ -301,13 +308,151 @@ void RegisterServerTools()
{"player", player->GetName()}
};
}
// Handle: aura <spellId> - Add aura to player
else if (cmd == "aura")
{
uint32 spellId;
if (!(iss >> spellId))
return {{"success", false}, {"error", "Usage: aura <spellId>"}};
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE);
if (!spellInfo)
return {{"success", false}, {"error", "Invalid spell ID"}, {"spellId", spellId}};
player->AddAura(spellId, player);
return {
{"success", true},
{"command", "aura"},
{"player", player->GetName()},
{"spellId", spellId},
{"spellName", spellInfo->SpellName->Str[LOCALE_enUS]}
};
}
// Handle: unaura <spellId> - Remove aura from player
else if (cmd == "unaura")
{
uint32 spellId;
if (!(iss >> spellId))
return {{"success", false}, {"error", "Usage: unaura <spellId>"}};
if (!player->HasAura(spellId))
return {{"success", false}, {"error", "Player does not have this aura"}, {"spellId", spellId}};
player->RemoveAurasDueToSpell(spellId);
return {
{"success", true},
{"command", "unaura"},
{"player", player->GetName()},
{"spellId", spellId}
};
}
// Handle: learn <spellId> - Teach spell to player
else if (cmd == "learn")
{
uint32 spellId;
if (!(iss >> spellId))
return {{"success", false}, {"error", "Usage: learn <spellId>"}};
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE);
if (!spellInfo)
return {{"success", false}, {"error", "Invalid spell ID"}, {"spellId", spellId}};
player->LearnSpell(spellId, false);
return {
{"success", true},
{"command", "learn"},
{"player", player->GetName()},
{"spellId", spellId},
{"spellName", spellInfo->SpellName->Str[LOCALE_enUS]}
};
}
// Handle: unlearn <spellId> - Remove spell from player
else if (cmd == "unlearn")
{
uint32 spellId;
if (!(iss >> spellId))
return {{"success", false}, {"error", "Usage: unlearn <spellId>"}};
if (!player->HasSpell(spellId))
return {{"success", false}, {"error", "Player does not have this spell"}, {"spellId", spellId}};
player->RemoveSpell(spellId, false, false);
return {
{"success", true},
{"command", "unlearn"},
{"player", player->GetName()},
{"spellId", spellId}
};
}
// Handle: respawn - Respawn creatures around player or targeted creature
else if (cmd == "respawn")
{
Map* map = player->GetMap();
if (!map)
return {{"success", false}, {"error", "Player not on valid map"}};
// Check if player has a creature selected
Unit* target = player->GetSelectedUnit();
Creature* targetCreature = target ? target->ToCreature() : nullptr;
if (targetCreature)
{
// Respawn the specific targeted creature
if (targetCreature->isDead())
{
targetCreature->Respawn();
return {
{"success", true},
{"command", "respawn"},
{"mode", "targeted"},
{"creature", targetCreature->GetName()},
{"entry", targetCreature->GetEntry()}
};
}
else
{
// Force despawn and respawn for living creature
targetCreature->DespawnOrUnsummon(0ms, 1s);
return {
{"success", true},
{"command", "respawn"},
{"mode", "force_respawn"},
{"creature", targetCreature->GetName()},
{"entry", targetCreature->GetEntry()},
{"message", "Creature will despawn and respawn in 1 second"}
};
}
}
else
{
// No target - respawn all creatures in area (like .respawn command)
CellCoord p(Trinity::ComputeCellCoord(player->GetPositionX(), player->GetPositionY()));
Cell cell(p);
cell.SetNoCreate();
Trinity::RespawnDo u;
Trinity::WorldObjectWorker<Trinity::RespawnDo> worker(player, u);
Cell::VisitGridObjects(player, worker, player->GetGridActivationRange());
return {
{"success", true},
{"command", "respawn"},
{"mode", "area"},
{"message", "Respawned all creatures in area"}
};
}
}
// Unknown command
return {
{"success", false},
{"error", "Unknown or unimplemented command"},
{"command", cmd},
{"supported", {"go xyz", "tele", "gps", "additem", "die", "revive"}}
{"supported", {"go xyz", "tele", "gps", "additem", "die", "revive", "aura", "unaura", "learn", "unlearn", "respawn"}}
};
}
);

View File

@@ -18869,6 +18869,7 @@ void Player::_LoadAuras(PreparedQueryResult auraResult, PreparedQueryResult effe
}
// TODO: finish dragonriding - this forces old flight mode
// Araxia: Players can use .flight toggle to enable Skyriding
AddAura(404468, this);
}

View File

@@ -8864,6 +8864,20 @@ void Unit::SetFlightCapabilityID(int32 flightCapabilityId, bool clientUpdate)
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::FlightCapabilityID), flightCapabilityId);
// Araxia: Apply the FlightCapability's associated spell (may enable Vigor UI)
if (flightCapabilityId > 0)
{
if (FlightCapabilityEntry const* flightCapability = sFlightCapabilityStore.LookupEntry(flightCapabilityId))
{
TC_LOG_INFO("entities.unit", "SetFlightCapabilityID: FlightCapability %d has SpellID %d",
flightCapabilityId, flightCapability->SpellID);
if (flightCapability->SpellID > 0)
{
CastSpell(this, flightCapability->SpellID, true);
}
}
}
UpdateAdvFlyingSpeed(ADV_FLYING_AIR_FRICTION, clientUpdate);
UpdateAdvFlyingSpeed(ADV_FLYING_MAX_VEL, clientUpdate);
UpdateAdvFlyingSpeed(ADV_FLYING_LIFT_COEFFICIENT, clientUpdate);

View File

@@ -5163,7 +5163,8 @@ void SpellMgr::LoadSpellInfoCorrections()
});
// TODO: temporary, remove with dragonriding
ApplySpellFix({ 404468 }, [](SpellInfo* spellInfo)
// Araxia: Also prevent Skyriding aura from saving (applied via .flight command)
ApplySpellFix({ 404464, 404468 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesCu |= SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED;
});

View File

@@ -0,0 +1,117 @@
/*
* Araxia Online - Flight Style Toggle Command
*
* Allows players to toggle between Skyriding and Steady flight modes.
*/
#include "ScriptMgr.h"
#include "Chat.h"
#include "ChatCommand.h"
#include "Player.h"
#include "SpellAuras.h"
#include "WorldSession.h"
using namespace Trinity::ChatCommands;
// Flight style spell IDs
constexpr uint32 SPELL_FLIGHT_STYLE_SKYRIDING = 404464;
constexpr uint32 SPELL_FLIGHT_STYLE_STEADY = 404468;
// Dragonriding spells
constexpr uint32 SPELL_SKYRIDING_BASICS = 376777;
constexpr uint32 SPELL_SURGE_FORWARD = 372608;
constexpr uint32 SPELL_TAKE_TO_THE_SKIES = 377920;
// Helper function to grant dragonriding spells
static void GrantDragonridingSpells(Player* player)
{
if (!player->HasSpell(SPELL_SKYRIDING_BASICS))
player->LearnSpell(SPELL_SKYRIDING_BASICS, false);
if (!player->HasSpell(SPELL_SURGE_FORWARD))
player->LearnSpell(SPELL_SURGE_FORWARD, false);
if (!player->HasSpell(SPELL_TAKE_TO_THE_SKIES))
player->LearnSpell(SPELL_TAKE_TO_THE_SKIES, false);
}
class flight_commandscript : public CommandScript
{
public:
flight_commandscript() : CommandScript("flight_commandscript") { }
ChatCommandTable GetCommands() const override
{
static ChatCommandTable flightCommandTable =
{
{ "toggle", HandleFlightToggleCommand, rbac::RBAC_PERM_COMMAND_HELP, Console::No },
{ "sky", HandleFlightSkyCommand, rbac::RBAC_PERM_COMMAND_HELP, Console::No },
{ "steady", HandleFlightSteadyCommand, rbac::RBAC_PERM_COMMAND_HELP, Console::No },
};
static ChatCommandTable commandTable =
{
{ "flight", flightCommandTable },
};
return commandTable;
}
// Toggle between Skyriding and Steady flight
static bool HandleFlightToggleCommand(ChatHandler* handler)
{
Player* player = handler->GetSession()->GetPlayer();
if (!player)
return false;
if (player->HasAura(SPELL_FLIGHT_STYLE_SKYRIDING))
{
// Switch to Steady
player->RemoveAura(SPELL_FLIGHT_STYLE_SKYRIDING);
player->AddAura(SPELL_FLIGHT_STYLE_STEADY, player);
handler->SendSysMessage("Flight style changed to |cff00ff00Steady Flight|r.");
}
else
{
// Switch to Skyriding - grant dragonriding spells
player->RemoveAura(SPELL_FLIGHT_STYLE_STEADY);
player->AddAura(SPELL_FLIGHT_STYLE_SKYRIDING, player);
GrantDragonridingSpells(player);
handler->SendSysMessage("Flight style changed to |cff00ffffSkyriding|r (Dragonriding). Dragonriding spells learned!");
}
return true;
}
// Force Skyriding mode
static bool HandleFlightSkyCommand(ChatHandler* handler)
{
Player* player = handler->GetSession()->GetPlayer();
if (!player)
return false;
player->RemoveAura(SPELL_FLIGHT_STYLE_STEADY);
player->AddAura(SPELL_FLIGHT_STYLE_SKYRIDING, player);
GrantDragonridingSpells(player);
handler->SendSysMessage("Flight style set to |cff00ffffSkyriding|r (Dragonriding). Dragonriding spells learned!");
return true;
}
// Force Steady flight mode
static bool HandleFlightSteadyCommand(ChatHandler* handler)
{
Player* player = handler->GetSession()->GetPlayer();
if (!player)
return false;
player->RemoveAura(SPELL_FLIGHT_STYLE_SKYRIDING);
player->AddAura(SPELL_FLIGHT_STYLE_STEADY, player);
handler->SendSysMessage("Flight style set to |cff00ff00Steady Flight|r.");
return true;
}
};
void AddSC_flight_commandscript()
{
new flight_commandscript();
}

View File

@@ -47,6 +47,7 @@ public:
{
{ "chat", HandleGMChatCommand, rbac::RBAC_PERM_COMMAND_GM_CHAT, Console::No },
{ "fly", HandleGMFlyCommand, rbac::RBAC_PERM_COMMAND_GM_FLY, Console::No },
{ "advfly", HandleGMAdvFlyCommand, rbac::RBAC_PERM_COMMAND_GM_FLY, Console::No },
{ "ingame", HandleGMListIngameCommand, rbac::RBAC_PERM_COMMAND_GM_INGAME, Console::Yes },
{ "list", HandleGMListFullCommand, rbac::RBAC_PERM_COMMAND_GM_LIST, Console::Yes },
{ "visible", HandleGMVisibleCommand, rbac::RBAC_PERM_COMMAND_GM_VISIBLE, Console::No },
@@ -114,6 +115,35 @@ public:
return true;
}
// Araxia: Enable dragonriding/skyriding (advanced flight)
static bool HandleGMAdvFlyCommand(ChatHandler* handler, bool enable)
{
Player* target = handler->getSelectedPlayer();
if (!target)
target = handler->GetSession()->GetPlayer();
if (enable)
{
target->SetCanFly(true);
target->SetCanAdvFly(true);
target->SetFlightCapabilityID(1, true); // ID 1 = default FlightCapability
target->SetCanTransitionBetweenSwimAndFly(true);
handler->PSendSysMessage("Advanced flight (dragonriding) enabled for %s. FlightCapabilityID=1",
handler->GetNameLink(target).c_str());
}
else
{
target->SetCanAdvFly(false);
target->SetFlightCapabilityID(0, true);
target->SetCanFly(false);
target->SetCanTransitionBetweenSwimAndFly(false);
handler->PSendSysMessage("Advanced flight (dragonriding) disabled for %s",
handler->GetNameLink(target).c_str());
}
return true;
}
static bool HandleGMListIngameCommand(ChatHandler* handler)
{
bool first = true;

View File

@@ -30,6 +30,7 @@ void AddSC_debug_commandscript();
void AddSC_deserter_commandscript();
void AddSC_disable_commandscript();
void AddSC_event_commandscript();
void AddSC_flight_commandscript();
void AddSC_gm_commandscript();
void AddSC_go_commandscript();
void AddSC_gobject_commandscript();
@@ -78,6 +79,7 @@ void AddCommandsScripts()
AddSC_deserter_commandscript();
AddSC_disable_commandscript();
AddSC_event_commandscript();
AddSC_flight_commandscript();
AddSC_gm_commandscript();
AddSC_go_commandscript();
AddSC_gobject_commandscript();