dragonriding
This commit is contained in:
@@ -32744,15 +32744,20 @@ void Player::InitAdvFlying()
|
||||
SendAdvFlyingSpeed(SMSG_MOVE_SET_ADV_FLYING_LAUNCH_SPEED_COEFFICIENT, ADV_FLYING_LAUNCH_SPEED_COEFFICIENT);
|
||||
}
|
||||
|
||||
void Player::SendAdvFlyingSpeed(OpcodeServer opcode, AdvFlyingRateTypeSingle speedType, AdvFlyingRateTypeSingle maxSpeedType /*= AdvFlyingRateType(0)*/) //[FIX][2024-07-14] Renamed member to avoid C++ type
|
||||
void Player::SendAdvFlyingSpeed(OpcodeServer opcode, AdvFlyingRateTypeSingle speedType, std::optional<AdvFlyingRateTypeSingle> maxSpeedType)
|
||||
{
|
||||
if (maxSpeedType != AdvFlyingRateTypeSingle(0))
|
||||
SendDirectMessage(WorldPackets::Movement::SetAdvFlyingMinMaxSpeeds(opcode, m_movementCounter++, GetAdvFlyingSpeed(speedType), GetAdvFlyingSpeed(maxSpeedType)).Write());
|
||||
//else
|
||||
// SendDirectMessage(WorldPackets::Movement::SetAdvFlyingSpeed(opcode, m_movementCounter++, GetAdvFlyingSpeed(speedType)).Write());
|
||||
if (maxSpeedType.has_value() && maxSpeedType.value() != AdvFlyingRateTypeSingle(0))
|
||||
SendDirectMessage(WorldPackets::Movement::SetAdvFlyingMinMaxSpeeds(opcode, m_movementCounter++, GetAdvFlyingSpeed(speedType), GetAdvFlyingSpeed(maxSpeedType.value())).Write());
|
||||
else
|
||||
{
|
||||
WorldPackets::Movement::SetAdvFlyingSpeed packet(opcode);
|
||||
packet.MoverGUID = GetGUID();
|
||||
packet.SequenceIndex = m_movementCounter++;
|
||||
packet.Speed = GetAdvFlyingSpeed(speedType);
|
||||
SendDirectMessage(packet.Write());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Player::UpdateDynamicFlight(bool apply)
|
||||
{
|
||||
if (apply)
|
||||
|
||||
@@ -2042,7 +2042,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
|
||||
void AddMoveImpulse(Position direction);
|
||||
//WowCommunity
|
||||
void InitAdvFlying();
|
||||
void SendAdvFlyingSpeed(OpcodeServer opcode, AdvFlyingRateTypeSingle speedType, AdvFlyingRateTypeSingle maxSpeedType = AdvFlyingRateTypeSingle(0)); // [FIX][2024-07-14] Renamed member to avoid C++ type.
|
||||
void SendAdvFlyingSpeed(OpcodeServer opcode, AdvFlyingRateTypeSingle speedType, std::optional<AdvFlyingRateTypeSingle> maxSpeedType = {});
|
||||
void UpdateDynamicFlight(bool apply = false);
|
||||
bool IsInAlliance() const { return m_team == ALLIANCE; }
|
||||
bool IsInHorde() const { return m_team == HORDE; }
|
||||
|
||||
@@ -14648,3 +14648,9 @@ float Unit::GetAdvFlyingVelocity() const
|
||||
|
||||
return std::sqrt(advFlying->forwardVelocity * advFlying->forwardVelocity + advFlying->upVelocity * advFlying->upVelocity);
|
||||
}
|
||||
|
||||
bool Unit::IsInAir() const
|
||||
{
|
||||
float ground = GetFloorZ();
|
||||
return (G3D::fuzzyGt(GetPositionZ(), ground + GetHoverOffset() + GROUND_HEIGHT_TOLERANCE) || G3D::fuzzyLt(GetPositionZ(), ground - GROUND_HEIGHT_TOLERANCE)); // Can be underground too, prevent the falling
|
||||
}
|
||||
|
||||
@@ -1096,6 +1096,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
bool isTargetableForAttack(bool checkFakeDeath = true) const;
|
||||
|
||||
bool IsInWater() const;
|
||||
bool IsInAir() const;
|
||||
bool IsUnderWater() const;
|
||||
bool IsOnOceanFloor() const;
|
||||
bool isInAccessiblePlaceFor(Creature const* c) const;
|
||||
|
||||
@@ -22,19 +22,6 @@ void PerksProgramRequestPurchase::Read()
|
||||
_worldPacket >> VendorItemID;
|
||||
}
|
||||
|
||||
void PerksProgramRequestCartCheckout::Read()
|
||||
{
|
||||
uint32 count = _worldPacket.ReadBits(5);
|
||||
VendorItemIDs.resize(count);
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
_worldPacket >> VendorItemIDs[i];
|
||||
}
|
||||
|
||||
void PerksProgramGetRecentPurchases::Read()
|
||||
{
|
||||
// This packet doesn't contain any data, it's just a request
|
||||
}
|
||||
|
||||
void PerksProgramSetFrozenVendorItem::Read()
|
||||
{
|
||||
_worldPacket >> VendorItemID;
|
||||
|
||||
@@ -2983,13 +2983,19 @@ void AuraEffect::HandleAuraCanTurnWhileFalling(AuraApplication const* aurApp, ui
|
||||
|
||||
void AuraEffect::HandleModAdvFlying(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
{
|
||||
if (!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
|
||||
if (!(mode & AURA_EFFECT_HANDLE_REAL))
|
||||
return;
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
target->SetCanDoubleJump(apply || target->HasAura(SPELL_DH_DOUBLE_JUMP));
|
||||
target->SetCanFly(apply);
|
||||
target->SetCanAdvFly(apply);
|
||||
Player* player = aurApp->GetTarget()->ToPlayer();
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
player->SetCanDoubleJump(apply || player->HasAura(SPELL_DH_DOUBLE_JUMP));
|
||||
player->SetCanFly(apply);
|
||||
player->SetCanAdvFly(apply);
|
||||
|
||||
if (apply)
|
||||
player->InitAdvFlying();
|
||||
}
|
||||
|
||||
void AuraEffect::HandleIgnoreMovementForces(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
@@ -6702,6 +6708,36 @@ void AuraEffect::HandleAuraActAsControlZone(AuraApplication const* aurApp, uint8
|
||||
controlZone->SetSpellId(GetSpellInfo()->Id);
|
||||
}
|
||||
|
||||
void AuraEffect::HandleAdvFlyModSpeed(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
|
||||
{
|
||||
if (!(mode & AURA_EFFECT_HANDLE_REAL))
|
||||
return;
|
||||
|
||||
Player* player = aurApp->GetTarget()->ToPlayer();
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
player->CalculateAdvFlyingSpeeds();
|
||||
|
||||
static std::unordered_map<AuraType, std::tuple<OpcodeServer, AdvFlyingRateTypeSingle, std::optional<AdvFlyingRateTypeSingle>>> advFlyMap;
|
||||
if (advFlyMap.empty())
|
||||
{
|
||||
using TupleType = std::tuple<OpcodeServer, AdvFlyingRateTypeSingle, std::optional<AdvFlyingRateTypeSingle>>;
|
||||
advFlyMap[SPELL_AURA_MOD_ADV_FLYING_LIFT_COEF] = TupleType{ SMSG_MOVE_SET_ADV_FLYING_LIFT_COEFFICIENT, AdvFlyingRateTypeSingle(ADV_FLYING_LIFT_COEFFICIENT), std::optional<AdvFlyingRateTypeSingle>(std::nullopt) };
|
||||
advFlyMap[SPELL_AURA_MOD_ADV_FLYING_MAX_VEL] = TupleType{ SMSG_MOVE_SET_ADV_FLYING_MAX_VEL, AdvFlyingRateTypeSingle(ADV_FLYING_MAX_VEL), std::optional<AdvFlyingRateTypeSingle>(std::nullopt) };
|
||||
advFlyMap[SPELL_AURA_MOD_ADV_FLYING_AIR_FRICTION] = TupleType{ SMSG_MOVE_SET_ADV_FLYING_AIR_FRICTION, AdvFlyingRateTypeSingle(ADV_FLYING_AIR_FRICTION), std::optional<AdvFlyingRateTypeSingle>(std::nullopt) };
|
||||
advFlyMap[SPELL_AURA_MOD_ADV_FLYING_ADD_IMPULSE_MAX_SPEED] = TupleType{ SMSG_MOVE_SET_ADV_FLYING_ADD_IMPULSE_MAX_SPEED, AdvFlyingRateTypeSingle(ADV_FLYING_ADD_IMPULSE_MAX_SPEED), std::optional<AdvFlyingRateTypeSingle>(std::nullopt) };
|
||||
advFlyMap[SPELL_AURA_MOD_ADV_FLYING_BANKING_RATE] = TupleType{ SMSG_MOVE_SET_ADV_FLYING_PITCHING_RATE_DOWN, AdvFlyingRateTypeSingle(ADV_FLYING_BANKING_RATE), std::optional<AdvFlyingRateTypeSingle>(AdvFlyingRateTypeSingle(ADV_FLYING_PITCHING_RATE_DOWN)) };
|
||||
advFlyMap[SPELL_AURA_MOD_ADV_FLYING_PITCHING_RATE_DOWN] = TupleType{ SMSG_MOVE_SET_ADV_FLYING_PITCHING_RATE_UP, AdvFlyingRateTypeSingle(ADV_FLYING_PITCHING_RATE_UP), std::optional<AdvFlyingRateTypeSingle>(AdvFlyingRateTypeSingle(ADV_FLYING_PITCHING_RATE_UP)) };
|
||||
advFlyMap[SPELL_AURA_MOD_ADV_FLYING_PITCHING_RATE_UP] = TupleType{ SMSG_MOVE_SET_ADV_FLYING_OVER_MAX_DECELERATION, AdvFlyingRateTypeSingle(ADV_FLYING_OVER_MAX_DECELERATION), std::optional<AdvFlyingRateTypeSingle>(std::nullopt) };
|
||||
advFlyMap[SPELL_AURA_MOD_ADV_FLYING_OVER_MAX_DECELERATION] = TupleType{ SMSG_MOVE_SET_ADV_FLYING_BANKING_RATE, AdvFlyingRateTypeSingle(ADV_FLYING_BANKING_RATE), std::optional<AdvFlyingRateTypeSingle>(AdvFlyingRateTypeSingle(ADV_FLYING_BANKING_RATE)) };
|
||||
}
|
||||
|
||||
auto [opcode, speedType, speedTypeMax] = advFlyMap[GetSpellEffectInfo().ApplyAuraName];
|
||||
|
||||
player->SendAdvFlyingSpeed(opcode, speedType, speedTypeMax);
|
||||
}
|
||||
|
||||
template TC_GAME_API void AuraEffect::GetTargetList(std::list<Unit*>&) const;
|
||||
template TC_GAME_API void AuraEffect::GetTargetList(std::deque<Unit*>&) const;
|
||||
template TC_GAME_API void AuraEffect::GetTargetList(std::vector<Unit*>&) const;
|
||||
|
||||
@@ -371,6 +371,7 @@ class TC_GAME_API AuraEffect
|
||||
void HandleAuraPvpTalents(AuraApplication const* auraApp, uint8 mode, bool apply) const;
|
||||
|
||||
void HandleAuraActAsControlZone(AuraApplication const* aurApp, uint8 mode, bool apply) const;
|
||||
void HandleAdvFlyModSpeed(AuraApplication const* aurApp, uint8 mode, bool) const;
|
||||
};
|
||||
|
||||
namespace Trinity
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "SpellScript.h"
|
||||
#include "Unit.h"
|
||||
|
||||
const float THRILL_OF_THE_SKIES_MIN_VELOCITY = 40.f;
|
||||
|
||||
enum DragonridingSpells
|
||||
{
|
||||
SPELL_DRAGONRIDING_SURGE_FORWARD = 372608,
|
||||
@@ -40,6 +42,12 @@ enum DragonridingSpells
|
||||
SPELL_SWITCH_FLIGHT_STYLE = 436854,
|
||||
SPELL_VIGOR = 372773,
|
||||
SPELL_LIFT_OFF_3 = 386451,
|
||||
SPELL_THRILL_OF_THE_SKIES = 377234,
|
||||
SPELL_THRILL_OF_THE_SKIES_2 = 383366,
|
||||
SPELL_EVOKER_SOAR_RACIAL = 369536,
|
||||
SPELL_ENERGY_WIDGET = 423624,
|
||||
SPELL_VIGOR_CACHE = 433547,
|
||||
SPELL_DRAGONRIDER_ENERGIZE = 372606,
|
||||
};
|
||||
|
||||
// Spell 436854 - Switch Flight Style
|
||||
@@ -250,6 +258,177 @@ class spell_dragonriding_launch_boost_aura : public AuraScript
|
||||
}
|
||||
};
|
||||
|
||||
// 406095 - Dynamic Flight
|
||||
class spell_dragonriding : public AuraScript
|
||||
{
|
||||
void OnPeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
float advFlyingVelocity = GetTarget()->GetAdvFlyingVelocity();
|
||||
bool advFylingEnabled = GetTarget()->HasAuraType(SPELL_AURA_ADV_FLYING);
|
||||
|
||||
float ground = GetTarget()->GetFloorZ();
|
||||
bool isInAir = (G3D::fuzzyGt(GetTarget()->GetPositionZ(), ground + GROUND_HEIGHT_TOLERANCE) || G3D::fuzzyLt(GetTarget()->GetPositionZ(), ground - GROUND_HEIGHT_TOLERANCE));
|
||||
|
||||
if (isInAir && advFlyingVelocity && advFylingEnabled)
|
||||
{
|
||||
if (advFlyingVelocity > THRILL_OF_THE_SKIES_MIN_VELOCITY)
|
||||
{
|
||||
if (!GetTarget()->HasAura(SPELL_THRILL_OF_THE_SKIES))
|
||||
GetTarget()->CastSpell(GetTarget(), SPELL_THRILL_OF_THE_SKIES, TRIGGERED_FULL_MASK);
|
||||
GetTarget()->CastSpell(GetTarget(), SPELL_THRILL_OF_THE_SKIES_2, TRIGGERED_FULL_MASK);
|
||||
}
|
||||
else
|
||||
GetTarget()->RemoveAurasDueToSpell(SPELL_THRILL_OF_THE_SKIES);
|
||||
GetTarget()->RemoveAurasDueToSpell(SPELL_THRILL_OF_THE_SKIES_2);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetTarget()->RemoveAurasDueToSpell(SPELL_THRILL_OF_THE_SKIES);
|
||||
GetTarget()->RemoveAurasDueToSpell(SPELL_THRILL_OF_THE_SKIES_2);
|
||||
}
|
||||
|
||||
if (advFlyingVelocity <= 8.5f)
|
||||
{
|
||||
// TODO ORNIXX
|
||||
}
|
||||
|
||||
// Soar Evoker
|
||||
if (!isInAir && GetCaster()->HasAura(SPELL_EVOKER_SOAR_RACIAL))
|
||||
GetCaster()->RemoveAura(SPELL_EVOKER_SOAR_RACIAL);
|
||||
}
|
||||
|
||||
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
caster->AddAura(SPELL_DRAGONRIDER_ENERGY, caster);
|
||||
GetTarget()->CastSpell(GetTarget(), SPELL_ENERGY_WIDGET, true);
|
||||
GetTarget()->SetPower(POWER_ALTERNATE_MOUNT, GetTarget()->GetPower(POWER_ALTERNATE_MOUNT), true);
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
caster->RemoveAura(SPELL_DRAGONRIDER_ENERGY);
|
||||
caster->RemoveAura(SPELL_VIGOR_CACHE);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_dragonriding::OnPeriodic, EFFECT_2, SPELL_AURA_PERIODIC_DUMMY);
|
||||
OnEffectApply += AuraEffectApplyFn(spell_dragonriding::OnApply, EFFECT_2, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_dragonriding::OnRemove, EFFECT_2, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
// 372771 - Dragonrider Energy
|
||||
class spell_dragonrider_energy : public AuraScript
|
||||
{
|
||||
void OnPeriodic(AuraEffect* /*aurEff*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
if (!caster)
|
||||
return;
|
||||
|
||||
caster->ToPlayer()->AddAura(433547, caster);
|
||||
|
||||
int newMaxPower = 3;
|
||||
|
||||
if (caster->HasAura(377920) && !caster->HasAura(377921) && !caster->HasAura(377922))
|
||||
{
|
||||
newMaxPower = 4;
|
||||
}
|
||||
else if (caster->HasAura(377921) && caster->HasAura(377920) && !caster->HasAura(377922))
|
||||
{
|
||||
newMaxPower = 5;
|
||||
}
|
||||
else if (caster->HasAura(377922) && caster->HasAura(377921) && caster->HasAura(377920))
|
||||
{
|
||||
newMaxPower = 6;
|
||||
}
|
||||
|
||||
caster->SetMaxPower(POWER_ALTERNATE_MOUNT, newMaxPower);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_dragonrider_energy::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
// 372773 - Dragonrider Energy
|
||||
class spell_af_energy : public AuraScript
|
||||
{
|
||||
void OnPeriodic(AuraEffect* /*aurEff*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
if (ShouldRegenEnergy(caster))
|
||||
{
|
||||
if (AuraEffect* subAmountAurEff = caster->GetAuraEffect(SPELL_VIGOR_CACHE, EFFECT_1))
|
||||
{
|
||||
int32 baseRegen = 20; // Todo : Calculate this based on talents & if we are thrilled/grounded
|
||||
|
||||
int32 newAmount = subAmountAurEff->GetAmount() + baseRegen;
|
||||
|
||||
if (newAmount >= 100)
|
||||
{
|
||||
newAmount -= 100;
|
||||
|
||||
caster->CastSpell(caster, SPELL_DRAGONRIDER_ENERGIZE, TRIGGERED_FULL_MASK);
|
||||
|
||||
if (AuraEffect* amountAurEff = caster->GetAuraEffect(SPELL_VIGOR_CACHE, EFFECT_0))
|
||||
amountAurEff->SetAmount(caster->GetPower(POWER_ALTERNATE_MOUNT));
|
||||
}
|
||||
|
||||
subAmountAurEff->SetAmount(newAmount);
|
||||
subAmountAurEff->GetBase()->SetNeedClientUpdateForTargets();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ShouldRegenEnergy(Unit const* caster) const
|
||||
{
|
||||
if (caster->GetPower(POWER_ALTERNATE_MOUNT) == caster->GetMaxPower(POWER_ALTERNATE_MOUNT))
|
||||
return false;
|
||||
|
||||
FlightCapabilityEntry const* flightCapabilityEntry = sFlightCapabilityStore.LookupEntry(caster->GetFlightCapabilityID());
|
||||
if (!flightCapabilityEntry)
|
||||
return false;
|
||||
|
||||
float velocityRegenThreshold = flightCapabilityEntry->MaxVel * flightCapabilityEntry->VigorRegenMaxVelCoefficient;
|
||||
if (caster->GetAdvFlyingVelocity() >= velocityRegenThreshold)
|
||||
return true;
|
||||
|
||||
return !caster->IsInAir() || caster->IsInWater();
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
GetTarget()->RemoveAurasDueToSpell(SPELL_VIGOR_CACHE);
|
||||
}
|
||||
|
||||
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target->HasAura(SPELL_VIGOR_CACHE))
|
||||
{
|
||||
CastSpellExtraArgs extraArgs(TRIGGERED_FULL_MASK);
|
||||
extraArgs.AddSpellMod(SPELLVALUE_BASE_POINT0, target->GetPower(POWER_ALTERNATE_MOUNT));
|
||||
target->CastSpell(target, SPELL_VIGOR_CACHE, extraArgs);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectApply += AuraEffectApplyFn(spell_af_energy::OnApply, EFFECT_0, SPELL_AURA_ENABLE_ALT_POWER, AURA_EFFECT_HANDLE_REAL);
|
||||
OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_af_energy::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY);
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_af_energy::OnRemove, EFFECT_0, SPELL_AURA_ENABLE_ALT_POWER, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_dragonriding_spell_scripts()
|
||||
{
|
||||
RegisterSpellScript(spell_switch_flight);
|
||||
@@ -257,4 +436,7 @@ void AddSC_dragonriding_spell_scripts()
|
||||
RegisterSpellAndAuraScriptPair(spell_dragonriding_launch_boost, spell_dragonriding_launch_boost_aura);
|
||||
RegisterSpellScript(spell_dragonriding_surge_forward);
|
||||
RegisterSpellScript(spell_dragonriding_skyward_ascent);
|
||||
RegisterSpellScript(spell_dragonriding);
|
||||
RegisterSpellScript(spell_dragonrider_energy);
|
||||
RegisterSpellScript(spell_af_energy);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user