dragon riding and perks
This commit is contained in:
@@ -62,15 +62,6 @@ constexpr uint32 SPELL_THRILL_OF_THE_SKIES = 383366; // High-speed vigor regener
|
||||
constexpr uint32 SPELL_FLIGHT_STYLE_SKYRIDING = 404464; // "Skyriding is currently enabled" - ENABLES ABILITIES
|
||||
constexpr uint32 SPELL_FLIGHT_STYLE_STEADY = 404468; // "Steady Flight is currently enabled" - MUST REMOVE for Soar
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// CRITICAL: DRAGONRIDER ENERGY (372773)
|
||||
// This aura is REQUIRED by Surge Forward (372608) and Skyward Ascent (372610)
|
||||
// Both abilities have CasterAuraSpell = 372773 in their SpellInfo
|
||||
// Without this aura, abilities show "You can't do that yet"
|
||||
// This aura also enables the Alt Power bar (vigor UI display)
|
||||
// -----------------------------------------------------------------------------
|
||||
constexpr uint32 SPELL_DRAGONRIDER_ENERGY = 372773; // "Dragonrider Energy" - enables vigor UI + ability casting
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// CUSTOM INTERNAL SPELLS (900000+ range)
|
||||
// These are server-side only tracking spells that don't need client display
|
||||
|
||||
@@ -25969,6 +25969,17 @@ void Player::SendInitialPacketsAfterAddToMap()
|
||||
}
|
||||
|
||||
GetSceneMgr().TriggerDelayedScenes();
|
||||
|
||||
// WowCommunity
|
||||
// Dragonriding
|
||||
if (HasAura(SPELL_DYNAMIC_FLIGHT))
|
||||
{
|
||||
if (GetPower(POWER_ALTERNATE_MOUNT) < 3)
|
||||
SetPower(POWER_ALTERNATE_MOUNT, 3);
|
||||
|
||||
AddAura(SPELL_DRAGONRIDER_ENERGY, this);
|
||||
// WowCommunity
|
||||
}
|
||||
}
|
||||
|
||||
void Player::SendUpdateToOutOfRangeGroupMembers()
|
||||
@@ -32740,4 +32751,20 @@ void Player::SendAdvFlyingSpeed(OpcodeServer opcode, AdvFlyingRateTypeSingle sp
|
||||
//else
|
||||
// SendDirectMessage(WorldPackets::Movement::SetAdvFlyingSpeed(opcode, m_movementCounter++, GetAdvFlyingSpeed(speedType)).Write());
|
||||
}
|
||||
|
||||
|
||||
void Player::UpdateDynamicFlight(bool apply)
|
||||
{
|
||||
if (apply)
|
||||
{
|
||||
if (!HasAuraType(SPELL_AURA_ADV_FLYING));
|
||||
AddAura(SPELL_DYNAMIC_FLIGHT, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (HasAuraType(SPELL_AURA_ADV_FLYING));
|
||||
RemoveAura(SPELL_DYNAMIC_FLIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
//WowCommunity
|
||||
|
||||
@@ -371,6 +371,13 @@ enum ReputationSource
|
||||
#define ACTION_BUTTON_TYPE(X) ((uint64(X) & 0xFF00000000000000) >> 56)
|
||||
#define MAX_ACTION_BUTTON_ACTION_VALUE UI64LIT(0xFFFFFFFFFFFFFF)
|
||||
|
||||
//WowCommunity
|
||||
enum DragonRidingSpells
|
||||
{
|
||||
SPELL_DYNAMIC_FLIGHT = 406095,
|
||||
SPELL_DRAGONRIDER_ENERGY = 372771
|
||||
};
|
||||
//WowCommunity
|
||||
struct ActionButton
|
||||
{
|
||||
ActionButton() : packedData(0), uState(ACTIONBUTTON_NEW) { }
|
||||
@@ -2034,9 +2041,9 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
|
||||
void DeleteTraitConfig(int32 deletedConfigId);
|
||||
void AddMoveImpulse(Position direction);
|
||||
//WowCommunity
|
||||
void InitAdvancedFly();
|
||||
void InitAdvFlying();
|
||||
void SendAdvFlyingSpeed(OpcodeServer opcode, AdvFlyingRateTypeSingle speedType, AdvFlyingRateTypeSingle maxSpeedType = AdvFlyingRateTypeSingle(0)); // [FIX][2024-07-14] Renamed member to avoid C++ type.
|
||||
void UpdateDynamicFlight(bool apply = false);
|
||||
//WowCommunity
|
||||
void ApplyTraitConfig(int32 configId, bool apply);
|
||||
void ApplyTraitEntry(int32 traitNodeEntryId, int32 rank, int32 grantedRanks, bool apply);
|
||||
|
||||
@@ -8359,6 +8359,11 @@ void Unit::Dismount()
|
||||
player->ResummonPetTemporaryUnSummonedIfAny();
|
||||
player->ResummonBattlePetTemporaryUnSummonedIfAny();
|
||||
}
|
||||
|
||||
// Dragonriding - Reset power if dismount
|
||||
if (Player* player = ToPlayer())
|
||||
if (player->HasAuraType(SPELL_AURA_ADV_FLYING))
|
||||
player->UpdateDynamicFlight(false);
|
||||
}
|
||||
|
||||
void Unit::CancelMountAura(bool force)
|
||||
@@ -10260,6 +10265,8 @@ void Unit::AddToWorld()
|
||||
i_motionMaster->AddToWorld();
|
||||
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::EnterWorld);
|
||||
|
||||
CalculateAdvFlyingSpeeds();
|
||||
}
|
||||
|
||||
void Unit::RemoveFromWorld()
|
||||
@@ -14605,3 +14612,30 @@ void Unit::SendAddImpulse(Position const& direction)
|
||||
playerMover->SendDirectMessage(addImpulse.Write());
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::CalculateAdvFlyingSpeeds()
|
||||
{
|
||||
FlightCapabilityEntry const* flightCapabilityEntry = sFlightCapabilityStore.LookupEntry(GetFlightCapabilityID());
|
||||
if (!flightCapabilityEntry)
|
||||
flightCapabilityEntry = sFlightCapabilityStore.LookupEntry(1);
|
||||
|
||||
ASSERT(flightCapabilityEntry, "Wrong default value for flightCapabilityID");
|
||||
|
||||
// m_advFlyingSpeed[ADV_FLYING_ADD_IMPULSE_MAX_SPEED] = flightCapabilityEntry->AddImpulseMaxSpeed * GetTotalAuraPercent(SPELL_AURA_ADV_FLY_MOD_ADD_IMPULSE_MAX_SPEED);
|
||||
// m_advFlyingSpeed[ADV_FLYING_AIR_FRICTION] = flightCapabilityEntry->AirFriction * GetTotalAuraPercent(SPELL_AURA_ADV_FLY_MOD_AIR_FRICTION);
|
||||
// m_advFlyingSpeed[ADV_FLYING_BANKING_RATE_MIN] = flightCapabilityEntry->BankingRateMin * GetTotalAuraPercent(SPELL_AURA_ADV_FLY_MOD_BANKING_RATE);
|
||||
// m_advFlyingSpeed[ADV_FLYING_BANKING_RATE_MAX] = flightCapabilityEntry->BankingRateMax * GetTotalAuraPercent(SPELL_AURA_ADV_FLY_MOD_BANKING_RATE);
|
||||
m_advFlyingSpeed[ADV_FLYING_DOUBLE_JUMP_VEL_MOD] = flightCapabilityEntry->DoubleJumpVelMod;
|
||||
m_advFlyingSpeed[ADV_FLYING_GLIDE_START_MIN_HEIGHT] = flightCapabilityEntry->GlideStartMinHeight;
|
||||
m_advFlyingSpeed[ADV_FLYING_LAUNCH_SPEED_COEFFICIENT] = flightCapabilityEntry->LaunchSpeedCoefficient;
|
||||
// m_advFlyingSpeed[SPELL_AURA_ADV_FLY_MOD_LIFT_COEF ] = flightCapabilityEntry->LiftCoefficient * GetTotalAuraPercent(SPELL_AURA_ADV_FLY_MOD_LIFT_COEF);
|
||||
// m_advFlyingSpeed[ADV_FLYING_MAX_VEL] = flightCapabilityEntry->MaxVel * GetTotalAuraPercent(SPELL_AURA_ADV_FLY_MOD_MAX_VEL);
|
||||
// m_advFlyingSpeed[ADV_FLYING_OVER_MAX_DECELERATION] = flightCapabilityEntry->OverMaxDeceleration * GetTotalAuraPercent(SPELL_AURA_ADV_FLY_MOD_OVER_MAX_DECELERATION);
|
||||
// m_advFlyingSpeed[ADV_FLYING_PITCHING_RATE_DOWN_MIN] = flightCapabilityEntry->PitchingRateDownMin * GetTotalAuraPercent(SPELL_AURA_ADV_FLY_MOD_PITCHING_RATE_DOWN);
|
||||
// m_advFlyingSpeed[ADV_FLYING_PITCHING_RATE_DOWN_MAX] = flightCapabilityEntry->PitchingRateDownMax * GetTotalAuraPercent(SPELL_AURA_ADV_FLY_MOD_PITCHING_RATE_DOWN);
|
||||
// m_advFlyingSpeed[ADV_FLYING_PITCHING_RATE_UP_MIN] = flightCapabilityEntry->PitchingRateUpMin * GetTotalAuraPercent(SPELL_AURA_ADV_FLY_MOD_PITCHING_RATE_UP);
|
||||
// m_advFlyingSpeed[ADV_FLYING_PITCHING_RATE_UP_MAX] = flightCapabilityEntry->PitchingRateUpMax * GetTotalAuraPercent(SPELL_AURA_ADV_FLY_MOD_PITCHING_RATE_UP);
|
||||
m_advFlyingSpeed[ADV_FLYING_SURFACE_FRICTION] = flightCapabilityEntry->SurfaceFriction;
|
||||
// m_advFlyingSpeed[ADV_FLYING_TURN_VELOCITY_THRESHOLD_MIN] = flightCapabilityEntry->TurnVelocityThresholdMin;
|
||||
// m_advFlyingSpeed[ADV_FLYING_TURN_VELOCITY_THRESHOLD_MAX] = flightCapabilityEntry->TurnVelocityThresholdMax;
|
||||
}
|
||||
|
||||
@@ -1714,6 +1714,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
float GetAdvFlyingSpeedMax(AdvFlyingRateTypeRange speedType) const { return m_advFlyingSpeed[speedType + 1]; }
|
||||
void UpdateAdvFlyingSpeed(AdvFlyingRateTypeSingle speedType, bool clientUpdate);
|
||||
void UpdateAdvFlyingSpeed(AdvFlyingRateTypeRange speedType, bool clientUpdate);
|
||||
void CalculateAdvFlyingSpeeds();
|
||||
|
||||
void FollowerAdded(AbstractFollower* f);
|
||||
void FollowerRemoved(AbstractFollower* f);
|
||||
|
||||
@@ -55,6 +55,15 @@ void WorldSession::HandlePerkProgramRequestCartCheckout(WorldPackets::PerksProgr
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandlePerkProgramGetRecentPurchases(WorldPackets::PerksProgram::PerksProgramGetRecentPurchases& /*packet*/)
|
||||
{
|
||||
if (!_player)
|
||||
return;
|
||||
|
||||
// Send recent purchases response
|
||||
GetPerkProgramMgr()->SendRecentPurchases();
|
||||
}
|
||||
|
||||
void WorldSession::HandlePerkProgramSetFrozenVendorItem(WorldPackets::PerksProgram::PerksProgramSetFrozenVendorItem& packet)
|
||||
{
|
||||
if (!_player)
|
||||
|
||||
@@ -144,8 +144,8 @@ bool PerkProgramManager::IsItemAlreadyOwned(PerkProgramData::PerkVendorItem cons
|
||||
{
|
||||
case PerkPrograms::PERKS_VENDOR_CATEGORY_TOYS:
|
||||
return m_player->GetSession()->GetCollectionMgr()->HasToy(vendorItem->ToyItem);
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_MOUNTS:
|
||||
// return m_player->GetMountCollection()->Has(vendorItem->MountSpellID);
|
||||
case PerkPrograms::PERKS_VENDOR_CATEGORY_MOUNTS:
|
||||
return m_player->HasSpell(vendorItem->MountSpellID);
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG_SETS:
|
||||
// return m_player->GetSession()->GetCollectionMgr()->HasTransmogSet(vendorItem->TransmogSet);
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG:
|
||||
@@ -380,7 +380,28 @@ void PerkProgramManager::SendRefundSuccess(int32 itemId)
|
||||
|
||||
WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
perks.Type = PerkPrograms::RESULT_REFUND_SUCCESS;
|
||||
perks.Params.BuyItem.VendorItemID = itemId;
|
||||
perks.Params.BuyItem.VendorItemID = itemId; // Use BuyItem struct since RefundItem doesn't exist
|
||||
|
||||
_session->SendPacket(perks.Write());
|
||||
}
|
||||
|
||||
void PerkProgramManager::SendRecentPurchases()
|
||||
{
|
||||
if (!_session)
|
||||
return;
|
||||
|
||||
WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
perks.Type = PerkPrograms::RESULT_BUY_ITEM; // Use BuyItem result type for recent purchases
|
||||
|
||||
// Send recent purchases
|
||||
for (auto const& [itemId, purchaseTime] : m_recentPurchases)
|
||||
{
|
||||
WorldPackets::PerksProgram::JamTimePair time;
|
||||
time.BuyTime = purchaseTime;
|
||||
time.VendorItemID = itemId;
|
||||
perks.Params.BuyItem.TimePair.emplace_back(time);
|
||||
}
|
||||
|
||||
_session->SendPacket(perks.Write());
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ public:
|
||||
void SendPerksProgramActivities();
|
||||
void SendPerksProgramStatus();
|
||||
void SendPendingRewards();
|
||||
void SendRecentPurchases();
|
||||
void SetFrozenItem(int32 itemId, bool clear);
|
||||
void RefundItem(int32 itemId);
|
||||
void CartCheckout(std::vector<uint32> const& itemIds);
|
||||
|
||||
@@ -30,6 +30,11 @@ void PerksProgramRequestCartCheckout::Read()
|
||||
_worldPacket >> VendorItemIDs[i];
|
||||
}
|
||||
|
||||
void PerksProgramGetRecentPurchases::Read()
|
||||
{
|
||||
// This packet doesn't contain any data, it's just a request
|
||||
}
|
||||
|
||||
void PerksProgramSetFrozenVendorItem::Read()
|
||||
{
|
||||
_worldPacket >> VendorItemID;
|
||||
|
||||
@@ -52,6 +52,13 @@ public:
|
||||
std::vector<int32> VendorItemIDs;
|
||||
};
|
||||
|
||||
class PerksProgramGetRecentPurchases final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
explicit PerksProgramGetRecentPurchases(WorldPacket&& packet) : ClientPacket(CMSG_PERKS_PROGRAM_GET_RECENT_PURCHASES, std::move(packet)) { }
|
||||
void Read() override;
|
||||
};
|
||||
|
||||
class PerksProgramSetFrozenVendorItem final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -876,7 +876,7 @@ void OpcodeTable::InitializeClientOpcodes()
|
||||
DEFINE_HANDLER(CMSG_PARTY_INVITE_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePartyInviteResponseOpcode);
|
||||
DEFINE_HANDLER(CMSG_PARTY_UNINVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePartyUninviteOpcode);
|
||||
DEFINE_HANDLER(CMSG_PERFORM_ITEM_INTERACTION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_PERKS_PROGRAM_GET_RECENT_PURCHASES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_PERKS_PROGRAM_GET_RECENT_PURCHASES, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandlePerkProgramGetRecentPurchases);
|
||||
DEFINE_HANDLER(CMSG_PERKS_PROGRAM_ITEMS_REFRESHED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_PERKS_PROGRAM_REQUEST_CART_CHECKOUT, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandlePerkProgramRequestCartCheckout);
|
||||
DEFINE_HANDLER(CMSG_PERKS_PROGRAM_REQUEST_PENDING_REWARDS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandlePerkProgramPendingReward);
|
||||
|
||||
@@ -756,6 +756,7 @@ namespace WorldPackets
|
||||
class PerksProgramSetFrozenVendorItem;
|
||||
class PerksProgramPendingReward;
|
||||
class PerksProgramRequestCartCheckout;
|
||||
class PerksProgramGetRecentPurchases;
|
||||
}
|
||||
|
||||
//WowCommunity
|
||||
@@ -1555,6 +1556,7 @@ class TC_GAME_API WorldSession
|
||||
void HandleGetPerkProgramRequest(WorldPackets::PerksProgram::PerksProgramStatusRequest& packet);
|
||||
void HandlePerkProgramRequestPurchase(WorldPackets::PerksProgram::PerksProgramRequestPurchase& packet);
|
||||
void HandlePerkProgramRequestCartCheckout(WorldPackets::PerksProgram::PerksProgramRequestCartCheckout& packet);
|
||||
void HandlePerkProgramGetRecentPurchases(WorldPackets::PerksProgram::PerksProgramGetRecentPurchases& packet);
|
||||
void HandlePerkProgramSetFrozenVendorItem(WorldPackets::PerksProgram::PerksProgramSetFrozenVendorItem& packet);
|
||||
void HandlePerkProgramPendingReward(WorldPackets::PerksProgram::PerksProgramPendingReward& packet);
|
||||
|
||||
|
||||
@@ -597,7 +597,7 @@ enum AuraType : uint32
|
||||
SPELL_AURA_MODIFIED_RAID_INSTANCE = 510, // NYI; Related to "Fated" raid affixes
|
||||
SPELL_AURA_APPLY_PROFESSION_EFFECT = 511, // NYI; MiscValue[0] = ProfessionEffectID
|
||||
SPELL_AURA_512 = 512,
|
||||
SPELL_AURA_MOD_ADV_FLYING_AIR_FRICTION = 513,
|
||||
SPELL_AURA_MOD_ADV_FLYING_AIR_FRICTION = 513,
|
||||
SPELL_AURA_MOD_ADV_FLYING_MAX_VEL = 514,
|
||||
SPELL_AURA_MOD_ADV_FLYING_LIFT_COEF = 515,
|
||||
SPELL_AURA_516 = 516,
|
||||
|
||||
@@ -2878,6 +2878,11 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo
|
||||
// Remove Vigor aura on dismount
|
||||
target->RemoveAura(372773);
|
||||
}
|
||||
|
||||
// Dragonriding updates
|
||||
if (target->GetTypeId() == TYPEID_PLAYER && (mode & AURA_EFFECT_HANDLE_REAL))
|
||||
if (GetMiscValue() == 32158 && GetMiscValueB() == 229) // Dragon mounts
|
||||
target->ToPlayer()->UpdateDynamicFlight(apply);
|
||||
}
|
||||
|
||||
void AuraEffect::HandleAuraAllowFlight(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
|
||||
@@ -60,18 +60,17 @@ class spell_switch_flight : public SpellScript
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
// Check if player can fly
|
||||
if (!player->CanFly())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool hadSkyriding = caster->HasAura(SPELL_SKYRIDING);
|
||||
// Debug current state
|
||||
bool hasSkyriding = caster->HasAura(SPELL_SKYRIDING);
|
||||
bool hasSteadyFlight = caster->HasAura(SPELL_STEADY_FLIGHT);
|
||||
|
||||
TC_LOG_INFO("spells", "Switch Flight Style - Skyriding: {}, Steady Flight: {}", hasSkyriding, hasSteadyFlight);
|
||||
|
||||
// Clean up both auras first
|
||||
caster->RemoveAura(SPELL_SKYRIDING);
|
||||
caster->RemoveAura(SPELL_STEADY_FLIGHT);
|
||||
|
||||
if (hadSkyriding)
|
||||
if (hasSkyriding)
|
||||
{
|
||||
// Switch to steady flight (normal flight)
|
||||
caster->CastSpell(caster, SPELL_STEADY_FLIGHT, true);
|
||||
@@ -81,10 +80,11 @@ class spell_switch_flight : public SpellScript
|
||||
caster->SetCanAdvFly(false);
|
||||
caster->SetCanDoubleJump(false);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Switch to skyriding (dragonriding)
|
||||
// Switch to skyriding (dragonriding) - default behavior
|
||||
caster->CastSpell(caster, SPELL_SKYRIDING, true);
|
||||
if (!caster->HasAura(SPELL_VIGOR))
|
||||
caster->CastSpell(caster, SPELL_VIGOR, true);
|
||||
@@ -93,7 +93,10 @@ class spell_switch_flight : public SpellScript
|
||||
caster->SetCanAdvFly(true);
|
||||
caster->SetCanDoubleJump(true);
|
||||
caster->SetFlightCapabilityID(1, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Send message to player
|
||||
TC_LOG_INFO("spells", "Switched to Skyriding");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user