diff options
-rw-r--r-- | src/game/Player.cpp | 51 | ||||
-rw-r--r-- | src/game/Player.h | 3 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 73 |
3 files changed, 127 insertions, 0 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 0b31ec67b1f..5a99c66d8ee 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -3333,6 +3333,12 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen if (!pSkill) continue; + if (!Has310Flyer(false) && pSkill->id == SKILL_MOUNTS) + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED && + spellInfo->CalculateSimpleValue(i) == 310) + SetHas310Flyer(true); + if (HasSkill(pSkill->id)) continue; @@ -3355,6 +3361,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen break; } } + } } @@ -3596,6 +3603,16 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank) SetSkill(pSkill->id, GetSkillStep(pSkill->id), 0, 0); } + + // most likely will never be used, haven't heard of cases where players unlearn a mount + if (Has310Flyer(false) && _spell_idx->second->skillId == SKILL_MOUNTS) + { + SpellEntry const *pSpellInfo = sSpellStore.LookupEntry(spell_id); + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (pSpellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED && + pSpellInfo->CalculateSimpleValue(i) == 310) + Has310Flyer(true, spell_id); // with true as first argument its also used to set/remove the flag + } } } @@ -3665,6 +3682,40 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank) } } +bool Player::Has310Flyer(bool checkAllSpells, uint32 excludeSpellId) +{ + if (!checkAllSpells) + return m_ExtraFlags & PLAYER_EXTRA_HAS_310_FLYER; + else + { + SetHas310Flyer(false); + SpellEntry const *pSpellInfo; + for (PlayerSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) + { + if (itr->first == excludeSpellId) + continue; + + SkillLineAbilityMapBounds bounds = spellmgr.GetSkillLineAbilityMapBounds(itr->first); + for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx) + { + if (_spell_idx->second->skillId != SKILL_MOUNTS) + break; // We can break because mount spells belong only to one skillline (at least 310 flyers do) + + pSpellInfo = sSpellStore.LookupEntry(itr->first); + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (pSpellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED && + pSpellInfo->CalculateSimpleValue(i) == 310) + { + SetHas310Flyer(true); + return true; + } + } + } + } + + return false; +} + void Player::RemoveSpellCooldown(uint32 spell_id, bool update /* = false */) { m_spellCooldowns.erase(spell_id); diff --git a/src/game/Player.h b/src/game/Player.h index 5ea6e22154f..9bc658aade2 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -485,6 +485,7 @@ enum PlayerExtraFlags PLAYER_EXTRA_TAXICHEAT = 0x0008, PLAYER_EXTRA_GM_INVISIBLE = 0x0010, PLAYER_EXTRA_GM_CHAT = 0x0020, // Show GM badge in chat messages + PLAYER_EXTRA_HAS_310_FLYER = 0x0040, // Marks if player already has 310% speed flying mount // other states PLAYER_EXTRA_PVP_DEATH = 0x0100 // store PvP death status until corpse creating. @@ -1005,6 +1006,8 @@ class Player : public Unit, public GridObject<Player> void SetTaxiCheater(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_TAXICHEAT; else m_ExtraFlags &= ~PLAYER_EXTRA_TAXICHEAT; } bool isGMVisible() const { return !(m_ExtraFlags & PLAYER_EXTRA_GM_INVISIBLE); } void SetGMVisible(bool on); + bool Has310Flyer(bool checkAllSpells, uint32 excludeSpellId = 0); + void SetHas310Flyer(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_HAS_310_FLYER; else m_ExtraFlags &= ~PLAYER_EXTRA_HAS_310_FLYER; } void SetPvPDeath(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_PVP_DEATH; else m_ExtraFlags &= ~PLAYER_EXTRA_PVP_DEATH; } void GiveXP(uint32 xp, Unit* victim); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 08dd692fa1d..acd610d20fb 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -5729,6 +5729,79 @@ void Spell::EffectScriptEffect(uint32 effIndex) } return; } + case 75614: // Celestial Steed + { + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + // Prevent stacking of mounts and client crashes upon dismounting + unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); + + // Triggered spell id dependent on riding skill and zone + bool canFly = true; + uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId()); + if (v_map != 530 && v_map != 571) + canFly = false; + + if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197)) + canFly = false; + + float x, y, z; + unitTarget->GetPosition(x, y, z); + uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z); + AreaTableEntry const *pArea = sAreaStore.LookupEntry(areaFlag); + if (canFly && pArea->flags & AREA_FLAG_NO_FLY_ZONE) + canFly = false; + + switch(unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING)) + { + case 75: unitTarget->CastSpell(unitTarget, 75619, true); break; + case 150: unitTarget->CastSpell(unitTarget, 75620, true); break; + case 225: + { + if (canFly) + unitTarget->CastSpell(unitTarget, 75617, true); + else + unitTarget->CastSpell(unitTarget, 75620, true); + }break; + case 300: + { + if (canFly) + { + if (unitTarget->ToPlayer()->Has310Flyer(false)) + unitTarget->CastSpell(unitTarget, 76153, true); + else + unitTarget->CastSpell(unitTarget, 75618, true); + } + else + unitTarget->CastSpell(unitTarget, 75620, true); + }break; + } + return; + } + case 75973: // X-53 Touring Rocket + { + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + // Prevent stacking of mounts + unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); + + // Triggered spell id dependent on riding skill + if (uint16 skillval = unitTarget->ToPlayer()->GetSkillValue(SKILL_RIDING)) + { + if (skillval >= 300) + { + if (unitTarget->ToPlayer()->Has310Flyer(false)) + unitTarget->CastSpell(unitTarget, 76154, true); + else + unitTarget->CastSpell(unitTarget, 75972, true); + } + else + unitTarget->CastSpell(unitTarget, 75957, true); + } + return; + } case 59317: // Teleporting if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; |