Jump to content

Flying mounts everywhere


Guest Hive

Recommended Posts

  • Replies 62
  • Created
  • Last Reply

Top Posters In This Topic

This patch works by changing mounts into trinkets or a non-armor clothing item. To do this, it must make a custom item that is linked to the "Summon Mount" spell for a particular mount.

The trouble is that custom items no longer work by the method used. After client version 3.2.2a, items are hard-linked to the DBC entries. This means that you must find unused item IDs in the DBC files of the same type as the custom item with which you wish to replace it. So, a custom trinket would need an unused trinket from the DBC, just as using a custom shirt or tabard for the flying mount would also require an unused shirt or tabard in the DBC file.

However, since these DBC files can change with every new patch or expansion, unused item IDs can suddenly come into use for official items. As such, you would need to revise the item IDs for the custom items to keep them working... but only if there are any remaining unused IDs for trinkets, shirts, or tabards.

That's one reason why this patch declined into disuse.

Perhaps someone might have a better method for dealing with custom items. If so, it would be deeply appreciated for details to be posted.

Link to comment
Share on other sites

no if this patch would go in the core with no errors then no need for custom items flying mounts same items can fly everywere just click on mount items and fly

my custom items solution:

i explain what i did

made totaly custom weapon with custom id but with it you cant use skills but you see model what ya added to it now i got unused weapon id list choosed correct unused id all was oke until i were ingame and saw the wep model what werent same what i added when i made it , so i edited server side item.dbc searched the unused id what i used for my wep and there was a model field so i changed it to what i wanted in begginning when i made the custom wep...i hope you guys understand my english sux a bit

Link to comment
Share on other sites

Do you realy can't change this in code manualy???

It should work...

diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index d8aa6be..ab31c99 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -2971,7 +2971,7 @@ SpellCastResult SpellMgr::GetSpellAllowedInLocationError(SpellEntry const *spell
    {
        uint32 v_map = GetVirtualMapForMapAndZone(map_id, zone_id);
        MapEntry const* mapEntry = sMapStore.LookupEntry(v_map);
-        if (!mapEntry || mapEntry->addon < 1 || !mapEntry->IsContinent())
+        if (!mapEntry || !mapEntry->IsContinent())
            return SPELL_FAILED_INCORRECT_AREA;
    }

Link to comment
Share on other sites

yad has kept his Github repository current with MaNGOS master. Unfortunately, all of his old branches are now merged into a single code tree. This means you'll have to pick through the commits to find all the changes you'll need to have flying mounts everywhere working correctly.

...unless yad can be persuaded to return and post an updated patch.

Link to comment
Share on other sites

  • 1 month later...
  • 2 weeks later...

From a89b4285d9bb252a8cfff70e7a28faded4b23463 Mon Sep 17 00:00:00 2001
From: yad <[email protected]>
Date: Wed, 11 Nov 2009 18:56:35 +0100
Subject: [PATCH 0121/1588] Add flying mounts everywhere patch (hack)
It's my first commit on github !

---
sql/druid_flying_item.sql        |   22 ++++
src/game/CharacterHandler.cpp    |    3 +
src/game/MiscHandler.cpp         |   10 ++-
src/game/Player.cpp              |  222 ++++++++++++++++++++++++++++++++++++++
src/game/Player.h                |   92 ++++++++++++++++
src/game/Spell.cpp               |   28 +++++-
src/game/SpellEffects.cpp        |   18 +++-
src/game/SpellHandler.cpp        |   16 +++
src/game/SpellMgr.cpp            |   22 ++++
src/game/World.cpp               |    2 +
src/game/World.h                 |    1 +
src/mangosd/mangosd.conf.dist.in |   11 ++
12 files changed, 443 insertions(+), 4 deletions(-)
create mode 100644 sql/druid_flying_item.sql

diff --git a/sql/druid_flying_item.sql b/sql/druid_flying_item.sql
new file mode 100644
index 0000000..30c8f4b
--- /dev/null
+++ b/sql/druid_flying_item.sql
@@ -0,0 +1,22 @@
+-- DELETE FROM `item_template` WHERE `entry` IN (4451, 33179);
+-- DELETE FROM `locales_item` WHERE `entry` IN (4451, 33179);
+
+INSERT INTO `item_template`
+    (`entry`, `class`, `subclass`, `unk0`, `name`, `displayid`, `Quality`, `Flags`, `Faction`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `stat_type1`, `stat_value1`, `stat_type2`, `stat_value2`, `stat_type3`, `stat_value3`, `stat_type4`, `stat_value4`, `stat_type5`, `stat_value5`, `stat_type6`, `stat_value6`, `stat_type7`, `stat_value7`, `stat_type8`, `stat_value8`, `stat_type9`, `stat_value9`, `stat_type10`, `stat_value10`, `ScalingStatDistribution`, `ScalingStatValue`, `dmg_min1`, `dmg_max1`, `dmg_type1`, `dmg_min2`, `dmg_max2`, `dmg_type2`, `armor`, `holy_res`, `fire_res`, `nature_res`, `frost_res`, `shadow_res`, `arcane_res`, `delay`, `ammo_type`, `RangedModRange`, `spellid_1`, `spelltrigger_1`, `spellcharges_1`, `spellppmRate_1`, `spellcooldown_1`, `spellcategory_1`, `spellcategorycooldown_1`, `spellid_2`, `spelltrigger_2`, `spellcharges_2`, `spellppmRate_2`, `spellcooldown_2`, `spellcategory_2`, `spellcategorycooldown_2`, `spellid_3`, `spelltrigger_3`, `spellcharges_3`, `spellppmRate_3`, `spellcooldown_3`, `spellcategory_3`, `spellcategorycooldown_3`, `spellid_4`, `spelltrigger_4`, `spellcharges_4`, `spellppmRate_4`, `spellcooldown_4`, `spellcategory_4`, `spellcategorycooldown_4`, `spellid_5`, `spelltrigger_5`, `spellcharges_5`, `spellppmRate_5`, `spellcooldown_5`, `spellcategory_5`, `spellcategorycooldown_5`, `bonding`, `description`, `PageText`, `LanguageID`, `PageMaterial`, `startquest`, `lockid`, `Material`, `sheath`, `RandomProperty`, `RandomSuffix`, `block`, `itemset`, `MaxDurability`, `area`, `Map`, `BagFamily`, `TotemCategory`, `socketColor_1`, `socketContent_1`, `socketColor_2`, `socketContent_2`, `socketColor_3`, `socketContent_3`, `socketBonus`, `GemProperties`, `RequiredDisenchantSkill`, `ArmorDamageModifier`, `Duration`, `ItemLimitCategory`, `HolidayId`, `ScriptName`, `DisenchantID`, `FoodType`, `minMoneyLoot`, `maxMoneyLoot`)
+VALUES
+    (33179, 15, 5, -1, 'Flight Form', 46325, 3, 0, 0, 1, 0, 0, 0, -1, -1, 60, 60, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55884, 0, -1, 0, -1, 330, 3000, 33943, 6, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 1, 'Teaches you how to fly. Can only be casted in Outland or Northrend.', 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, '', 0, 0, 0, 0);
+
+INSERT INTO `item_template`
+    (`entry`, `class`, `subclass`, `unk0`, `name`, `displayid`, `Quality`, `Flags`, `Faction`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `stat_type1`, `stat_value1`, `stat_type2`, `stat_value2`, `stat_type3`, `stat_value3`, `stat_type4`, `stat_value4`, `stat_type5`, `stat_value5`, `stat_type6`, `stat_value6`, `stat_type7`, `stat_value7`, `stat_type8`, `stat_value8`, `stat_type9`, `stat_value9`, `stat_type10`, `stat_value10`, `ScalingStatDistribution`, `ScalingStatValue`, `dmg_min1`, `dmg_max1`, `dmg_type1`, `dmg_min2`, `dmg_max2`, `dmg_type2`, `armor`, `holy_res`, `fire_res`, `nature_res`, `frost_res`, `shadow_res`, `arcane_res`, `delay`, `ammo_type`, `RangedModRange`, `spellid_1`, `spelltrigger_1`, `spellcharges_1`, `spellppmRate_1`, `spellcooldown_1`, `spellcategory_1`, `spellcategorycooldown_1`, `spellid_2`, `spelltrigger_2`, `spellcharges_2`, `spellppmRate_2`, `spellcooldown_2`, `spellcategory_2`, `spellcategorycooldown_2`, `spellid_3`, `spelltrigger_3`, `spellcharges_3`, `spellppmRate_3`, `spellcooldown_3`, `spellcategory_3`, `spellcategorycooldown_3`, `spellid_4`, `spelltrigger_4`, `spellcharges_4`, `spellppmRate_4`, `spellcooldown_4`, `spellcategory_4`, `spellcategorycooldown_4`, `spellid_5`, `spelltrigger_5`, `spellcharges_5`, `spellppmRate_5`, `spellcooldown_5`, `spellcategory_5`, `spellcategorycooldown_5`, `bonding`, `description`, `PageText`, `LanguageID`, `PageMaterial`, `startquest`, `lockid`, `Material`, `sheath`, `RandomProperty`, `RandomSuffix`, `block`, `itemset`, `MaxDurability`, `area`, `Map`, `BagFamily`, `TotemCategory`, `socketColor_1`, `socketContent_1`, `socketColor_2`, `socketContent_2`, `socketColor_3`, `socketContent_3`, `socketBonus`, `GemProperties`, `RequiredDisenchantSkill`, `ArmorDamageModifier`, `Duration`, `ItemLimitCategory`, `HolidayId`, `ScriptName`, `DisenchantID`, `FoodType`, `minMoneyLoot`, `maxMoneyLoot`)
+VALUES
+    (4451, 15, 5, -1, 'Swift Flight Form', 7298, 4, 0, 0, 1, 0, 0, 0, -1, -1, 70, 70, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55884, 0, -1, 0, -1, 330, 3000, 40120, 6, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 1, 'Teaches you how to fly. Can only be casted in Outland or Northrend.', 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, '', 0, 0, 0, 0);
+
+INSERT INTO `locales_item`
+    (`entry`, `name_loc1`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc5`, `name_loc6`, `name_loc7`, `name_loc8`, `description_loc1`, `description_loc2`, `description_loc3`, `description_loc4`, `description_loc5`, `description_loc6`, `description_loc7`, `description_loc8`)
+VALUES
+    (33179, '', 'Forme de vol', '', '', '', '', '', '', 'NULL', 'Vous apprend ?voler. Ne peut 阾re utilis?qu\\'en Outreterre et en Norfendre.', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL');
+    
+INSERT INTO `locales_item`
+    (`entry`, `name_loc1`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc5`, `name_loc6`, `name_loc7`, `name_loc8`, `description_loc1`, `description_loc2`, `description_loc3`, `description_loc4`, `description_loc5`, `description_loc6`, `description_loc7`, `description_loc8`)
+VALUES
+    (4451, '', 'Forme de vol rapide', '', '', '', '', '', '', 'NULL', 'Vous apprend ?voler. Ne peut 阾re utilis?qu\\'en Outreterre et en Norfendre.', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL');
\\ No newline at end of file
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
index 815a48c..cf50d0f 100644
--- a/src/game/CharacterHandler.cpp
+++ b/src/game/CharacterHandler.cpp
@@ -674,6 +674,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder *holder)
    if(!pCurrChar->isAlive())
        pCurrChar->SendCorpseReclaimDelay(true);

+    if (sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1)
+        pCurrChar->FlyingMountsSpellsToItems();
+
    pCurrChar->SendInitialPacketsBeforeAddToMap();

    //Show cinematic at the first time that player login
diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp
index a605fc5..878d3b7 100644
--- a/src/game/MiscHandler.cpp
+++ b/src/game/MiscHandler.cpp
@@ -1508,8 +1508,14 @@ void WorldSession::HandleCancelMountAuraOpcode( WorldPacket & /*recv_data*/ )
        return;
    }

-    _player->Unmount();
-    _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+    if ((sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1)
+        && _player->HasAuraTypeFlyingSpell())
+        _player->SetFlyingMountTimer();
+    else
+    {
+        _player->Unmount();
+        _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+    }
}

void WorldSession::HandleMoveSetCanFlyAckOpcode( WorldPacket & recv_data )
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 128d01c..6b1edb0 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -471,6 +471,8 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa

    m_lastFallTime = 0;
    m_lastFallZ = 0;
+
+    m_flytimer = time(NULL);
}

Player::~Player ()
@@ -10131,6 +10133,64 @@ uint8 Player::CanUseItem( Item *pItem, bool not_loading ) const
{
    if (pItem)
    {
+        if (sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1)
+        {
+            ItemPrototype const *iProto = pItem->GetProto();
+            if (iProto)
+            {
+                for(int i = 0; i < 5; i++)
+                {
+                    SpellEntry const *sEntry = sSpellStore.LookupEntry(iProto->Spells[i].SpellId);
+                    if (sEntry)
+                    {
+                        Player* player = ((Player*)this);
+                        if(isFlyingSpell(sEntry))
+                        {
+                            if(player->HasAuraTypeFlyingSpell())
+                                player->RemoveFlyingSpells();
+                            else if(player->HasAuraTypeFlyingFormSpell())
+                                player->RemoveFlyingFormSpells();
+                            else if(player->HasAuraTypeRunningFormSpell())
+                                player->RemoveRunningFormSpells();
+
+                            if(player->CanUseFlyingMounts(sEntry))
+                            {
+                                for (int j = 0; j < 3; ++j)
+                                {
+                                    Aura* aur = CreateAura(sEntry, j, NULL, player, player, NULL);
+                                    player->AddAura(aur);
+                                }
+                            }
+                            return EQUIP_ERR_OK;
+                        }
+                        else if(isFlyingFormSpell(sEntry))
+                        {
+                            if(player->HasAuraTypeFlyingSpell())
+                                player->RemoveFlyingSpells();
+                            else if(player->HasAuraTypeFlyingFormSpell())
+                                player->RemoveFlyingFormSpells();
+                            /*else if(player->HasAuraTypeRunningFormSpell())
+                                player->RemoveRunningFormSpells();*/
+
+                            if(player->CanUseFlyingMounts(sEntry))
+                            {
+                                for (int j = 0; j < 3; ++j)
+                                {
+                                    Aura* aur = CreateAura(sEntry, j, NULL, player, player, NULL);
+                                    player->AddAura(aur);
+                                }
+                            }
+                            return EQUIP_ERR_OK;
+                        }
+                        else if (isRunningSpell(sEntry) || isRunningFormSpell(sEntry))
+                        {
+                            player->RemoveAllFlyingSpells();
+                            return EQUIP_ERR_OK;
+                        }
+                    }
+                }
+            }
+        }
        sLog.outDebug( "STORAGE: CanUseItem item = %u", pItem->GetEntry());

        if (!isAlive() && not_loading)
@@ -11013,6 +11073,27 @@ void Player::DestroyItemCount( Item* pItem, uint32 &count, bool update )
    if(!pItem)
        return;

+    if (sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1)
+    {
+        ItemPrototype const *pProto = sObjectMgr.GetItemPrototype(pItem->GetEntry());
+        if(pProto)
+        {
+            for(int i = 0; i < 5; i++)
+            {
+                SpellEntry const *sEntry = sSpellStore.LookupEntry(pProto->Spells[i].SpellId);
+                if(!sEntry)
+                    continue;
+
+                if(isFlyingSpell(sEntry) || isFlyingFormSpell(sEntry))
+                {
+                    pItem->SetSpellCharges(0, 1);
+                    pItem->SetState(ITEM_CHANGED, this);
+                    return;
+                }
+            }
+        }
+    }
+
    sLog.outDebug( "STORAGE: DestroyItemCount item (GUID: %u, Entry: %u) count = %u", pItem->GetGUIDLow(),pItem->GetEntry(), count);

    if( pItem->GetCount() <= count )
@@ -19814,6 +19895,7 @@ uint32 Player::CalculateTalentsPoints() const

bool Player::IsKnowHowFlyIn(uint32 mapid, uint32 zone) const
{
+    if(sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1) return true;
    // continent checked in SpellMgr::GetSpellAllowedInLocationError at cast and area update
    uint32 v_map = GetVirtualMapForMapAndZone(mapid, zone);
    return v_map != 571 || HasSpell(54197);                 // Cold Weather Flying
@@ -20743,4 +20825,144 @@ void Player::SendDuelCountdown(uint32 counter)
    WorldPacket data(SMSG_DUEL_COUNTDOWN, 4);
    data << uint32(counter);                                // seconds
    GetSession()->SendPacket(&data);
+}
+
+void Player::FlyingMountsSpellsToItems()
+{
+    for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
+    {
+        SpellEntry const *sEntry = sSpellStore.LookupEntry(itr->first);
+        if(!sEntry)
+            continue;
+
+        if(! (isFlyingSpell(sEntry) || isFlyingFormSpell(sEntry)) )
+            continue;
+
+        uint32 itemId = 0;
+        for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
+        {
+            ItemPrototype const *pProto = sObjectMgr.GetItemPrototype(id);
+            if(!pProto)
+                continue;
+
+            for(int i = 0; i < 5; i++)
+            {
+                if(pProto->Spells[i].SpellId == itr->first)
+                {
+                    itemId = id;
+                    break;
+                }
+            }
+        }
+        if(!HasItemCount(itemId, 1, false))
+        {
+            //Adding items
+            uint32 noSpaceForCount = 0;
+
+            // check space and find places
+            ItemPosCountVec dest;
+            uint8 msg = CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, 1, &noSpaceForCount );
+
+            if(!dest.empty())                         // can't add any
+            {
+                Item* item = StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
+                SendNewItem(item, 1,false,false);
+            }
+        }
+
+    }
+
+    for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i)
+    {
+        Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
+        if(!pItem)
+            continue;
+
+        ItemPrototype const *pProto = sObjectMgr.GetItemPrototype(pItem->GetEntry());
+        if(!pProto)
+            continue;
+
+        for(int i = 0; i < 5; i++)
+        {
+            SpellEntry const *sEntry = sSpellStore.LookupEntry(pProto->Spells[i].SpellId);
+            if(!sEntry)
+                continue;
+
+            if(! (isFlyingSpell(sEntry) || isFlyingFormSpell(sEntry)) )
+                continue;
+
+            if(HasSpell(pProto->Spells[i].SpellId))
+            {
+                uint16 RindingSkill = GetSkillValue(SKILL_RIDING);
+                removeSpell(pProto->Spells[i].SpellId, false, false);
+                SetSkill(SKILL_RIDING, RindingSkill, 300);
+                break;
+            }
+
+        }        
+    }
+
+    for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
+    {
+        if(Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
+        {
+            for(uint32 j = 0; j < pBag->GetBagSize(); ++j)
+            {
+                Item* pItem = GetItemByPos( i, j );
+                if(!pItem)
+                    continue;
+
+                ItemPrototype const *pProto = sObjectMgr.GetItemPrototype(pItem->GetEntry());
+                if(!pProto)
+                    continue;
+
+                for(int i = 0; i < 5; i++)
+                {
+                    SpellEntry const *sEntry = sSpellStore.LookupEntry(pProto->Spells[i].SpellId);
+                    if(!sEntry)
+                        continue;
+
+                    if(! (isFlyingSpell(sEntry) || isFlyingFormSpell(sEntry)) )
+                        continue;
+
+                    if(HasSpell(pProto->Spells[i].SpellId))
+                    {
+                        uint16 RindingSkill = GetSkillValue(SKILL_RIDING);
+                        removeSpell(pProto->Spells[i].SpellId, false, false);
+                        SetSkill(SKILL_RIDING, RindingSkill, 300);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+}
+
+bool Player::CanUseFlyingMounts(SpellEntry const* sEntry)
+{
+    if(!GetFlyingMountTimer())
+        return false;
+
+    uint32 v_map = GetVirtualMapForMapAndZone(GetMapId(), GetZoneId());
+    MapEntry const* mapEntry = sMapStore.LookupEntry(v_map);
+    if(!getAttackers().empty())
+    {
+        WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
+        data << uint8(0);
+        data << uint32(sEntry->Id);
+        data << uint8(SPELL_FAILED_TARGET_IN_COMBAT); 
+        GetSession()->SendPacket(&data);
+        return false;
+    }
+    if( (!mapEntry)/* || (mapEntry->Instanceable())*/ || (mapEntry->IsDungeon()) ||
+        (mapEntry->IsRaid()) || (mapEntry->IsBattleArena()) || (mapEntry->IsBattleGround()) )
+    {
+        WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
+        data << uint8(0);
+        data << uint32(sEntry->Id);
+        data << uint8(SPELL_FAILED_NOT_HERE); 
+        GetSession()->SendPacket(&data);
+        return false;
+    }
+    return true;
}
\\ No newline at end of file
diff --git a/src/game/Player.h b/src/game/Player.h
index 79014e9..8ae0d1f 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -1199,6 +1199,97 @@ class MANGOS_DLL_SPEC Player : public Unit
        void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store, bool broadcast = false);
        void AutoStoreLoot(uint32 loot_id, LootStore const& store, bool broadcast = false) { AutoStoreLoot(NULL_BAG,NULL_SLOT,loot_id,store,broadcast); }

+        /// Flying mounts everywhere mode
+        void FlyingMountsSpellsToItems();
+        bool CanUseFlyingMounts(SpellEntry const* spellInfo);
+        //helpers
+        bool isFlyingSpell(SpellEntry const* spellInfo) const
+        {
+            return spellInfo->EffectApplyAuraName[0]==SPELL_AURA_MOUNTED && 
+            spellInfo->EffectApplyAuraName[1]==SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED && 
+            spellInfo->EffectApplyAuraName[2]==SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED;
+        }
+
+        bool isRunningSpell(SpellEntry const* spellInfo) const
+        {
+            return spellInfo->EffectApplyAuraName[0]==SPELL_AURA_MOUNTED &&
+            spellInfo->EffectApplyAuraName[1]==SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED; 
+        }
+
+        bool isFlyingFormSpell(SpellEntry const* spellInfo) const
+        { 
+            return spellInfo->EffectApplyAuraName[0]==SPELL_AURA_MOD_SHAPESHIFT && 
+            spellInfo->EffectApplyAuraName[1]==SPELL_AURA_MECHANIC_IMMUNITY &&
+            spellInfo->EffectApplyAuraName[2]==SPELL_AURA_FLY;
+        }
+
+        bool isRunningFormSpell(SpellEntry const* spellInfo) const
+        { 
+            return spellInfo->EffectApplyAuraName[0]==SPELL_AURA_MOD_SHAPESHIFT &&
+            spellInfo->EffectApplyAuraName[1]==SPELL_AURA_MECHANIC_IMMUNITY &&
+            spellInfo->EffectApplyAuraName[2]!=SPELL_AURA_FLY;
+        }
+
+        void RemoveFlyingSpells()
+        { 
+            Unmount(); 
+            RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); 
+            RemoveSpellsCausingAura(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED);
+            RemoveSpellsCausingAura(SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED);
+        }
+
+        void RemoveFlyingFormSpells()
+        { 
+            RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT);
+            RemoveSpellsCausingAura(SPELL_AURA_MECHANIC_IMMUNITY);
+            RemoveSpellsCausingAura(SPELL_AURA_FLY);
+        }
+
+        void RemoveRunningFormSpells()
+        { 
+            RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT);
+            RemoveSpellsCausingAura(SPELL_AURA_MECHANIC_IMMUNITY);
+        }
+
+        void RemoveAllFlyingSpells()
+        {
+            RemoveFlyingSpells();
+            RemoveFlyingFormSpells();
+        }
+
+        bool HasAuraTypeFlyingSpell()
+        {
+            return HasAuraType(SPELL_AURA_MOUNTED) &&
+            HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) &&
+            HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED);
+        }
+
+        bool HasAuraTypeFlyingFormSpell()
+        {
+            return HasAuraType(SPELL_AURA_MOD_SHAPESHIFT) &&
+            HasAuraType(SPELL_AURA_MECHANIC_IMMUNITY) &&
+            HasAuraType(SPELL_AURA_FLY);
+        }
+
+        bool HasAuraTypeRunningFormSpell()
+        {
+            return HasAuraType(SPELL_AURA_MOD_SHAPESHIFT) &&
+            HasAuraType(SPELL_AURA_MECHANIC_IMMUNITY) &&
+            !HasAuraType(SPELL_AURA_FLY);
+        }
+
+        bool GetFlyingMountTimer()
+        {
+            return m_flytimer < time(NULL);
+        }
+
+        void SetFlyingMountTimer()
+        {
+            m_flytimer = time(NULL) + 0.5;
+        }
+        //end of helpers.
+        ///end of Flying mounts everywhere mode
+
        uint8 _CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL) const;
        uint8 _CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item *pItem = NULL, bool swap = false, uint32* no_space_count = NULL ) const;

@@ -2418,6 +2509,7 @@ class MANGOS_DLL_SPEC Player : public Unit

        uint32 m_deathTimer;
        time_t m_deathExpireTime;
+        time_t m_flytimer;

        uint32 m_restTime;

diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index be4e65a..314d9d9 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -4107,6 +4107,19 @@ SpellCastResult Spell::CheckCast(bool strict)
    {
        if (m_caster->isInFlight())
            return SPELL_FAILED_NOT_ON_TAXI;
+        else if ((sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1) && (m_spellInfo->Id==55884))
+        {
+            Player* player = (Player*)m_caster;
+            uint32 spellToLearn = ((m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN_PET)) ? damage : m_spellInfo->EffectTriggerSpell[0];
+            SpellEntry const *sEntry = sSpellStore.LookupEntry(spellToLearn);
+            if(sEntry)
+            {
+                if(player->isFlyingSpell(sEntry) || player->isFlyingFormSpell(sEntry))
+                {
+                    return SPELL_CAST_OK;
+                }
+            }
+        }
        else
            return SPELL_FAILED_NOT_MOUNTED;
    }
@@ -5196,9 +5209,22 @@ SpellCastResult Spell::CheckItems()
{
    if (m_caster->GetTypeId() != TYPEID_PLAYER)
        return SPELL_CAST_OK;
-
+        
    Player* p_caster = (Player*)m_caster;

+    if ((sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1) && (m_spellInfo->Id==55884))
+    {
+        uint32 spellToLearn = ((m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN_PET)) ? damage : m_spellInfo->EffectTriggerSpell[0];
+        SpellEntry const *sEntry = sSpellStore.LookupEntry(spellToLearn);
+        if(sEntry)
+        {
+            if(p_caster->isFlyingSpell(sEntry) || p_caster->isFlyingFormSpell(sEntry))
+            {
+                return SPELL_CAST_OK;
+            }
+        }
+    }
+
    // cast item checks
    if(m_CastItem)
    {
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 6dd37ae..9266536 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -3500,7 +3500,23 @@ void Spell::EffectLearnSpell(uint32 i)

    Player *player = (Player*)unitTarget;

-    uint32 spellToLearn = ((m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN_PET)) ? damage : m_spellInfo->EffectTriggerSpell[i];
+    uint32 spellToLearn = ((m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN_PET)) ? damage : m_spellInfo->EffectTriggerSpell[0];
+
+    if ((sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1) && (m_spellInfo->Id==55884))
+    {
+        SpellEntry const *sEntry = sSpellStore.LookupEntry(spellToLearn);
+        if(sEntry)
+        {
+            if(player->isFlyingSpell(sEntry) || player->isFlyingFormSpell(sEntry))
+            {
+                player->RemoveSpellCooldown(55884, true);
+                return;
+            }
+        }
+        else
+            return;
+    }
+
    player->learnSpell(spellToLearn,false);

    sLog.outDebug( "Spell: Player %u has learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow() );
diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp
index da998c7..ddda7e5 100644
--- a/src/game/SpellHandler.cpp
+++ b/src/game/SpellHandler.cpp
@@ -23,6 +23,7 @@
#include "ObjectMgr.h"
#include "SpellMgr.h"
#include "Log.h"
+#include "World.h"
#include "Opcodes.h"
#include "Spell.h"
#include "ScriptCalls.h"
@@ -306,6 +307,19 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
        return;
    }

+    if (sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1)
+    {
+        if (_player->isRunningSpell(spellInfo))
+        {
+            _player->Unmount();
+            _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+        }
+        else if (_player->isRunningFormSpell(spellInfo))
+        {
+            _player->RemoveFlyingSpells();
+        }
+    }
+
    if(mover->GetTypeId()==TYPEID_PLAYER)
    {
        // not have spell in spellbook or spell passive and not casted by client
@@ -437,6 +451,8 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)

    // non channeled case
    _player->RemoveAurasDueToSpellByCancel(spellId);
+    if(_player->isFlyingSpell(spellInfo) || _player->isFlyingFormSpell(spellInfo))
+        _player->SetFlyingMountTimer();
}

void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 2d4d559..16cb9b5 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -2811,6 +2811,28 @@ void SpellMgr::LoadSpellAreas()

SpellCastResult SpellMgr::GetSpellAllowedInLocationError(SpellEntry const *spellInfo, uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player)
{
+    if (sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1)
+    {
+        if(player && (player->isFlyingSpell(spellInfo) || player->isFlyingFormSpell(spellInfo)))
+        {
+            uint32 v_map = GetVirtualMapForMapAndZone(map_id, zone_id);
+            MapEntry const* mapEntry = sMapStore.LookupEntry(v_map);
+            if(!mapEntry)
+                return SPELL_FAILED_NOT_HERE;
+            /*else if(mapEntry->Instanceable())
+                return SPELL_FAILED_NOT_HERE;*/
+            else if(mapEntry->IsDungeon())
+                return SPELL_FAILED_NOT_HERE;
+            else if(mapEntry->IsRaid())
+                return SPELL_FAILED_NOT_HERE;
+            else if(mapEntry->IsBattleArena())
+                return SPELL_FAILED_NOT_HERE;
+            else if(mapEntry->IsBattleGround())
+                return SPELL_FAILED_NOT_HERE;
+            else
+                return SPELL_CAST_OK;
+        }
+    }
    // normal case
    if (spellInfo->AreaGroupId > 0)
    {
diff --git a/src/game/World.cpp b/src/game/World.cpp
index 4491e4c..aa77287 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -993,6 +993,8 @@ void World::LoadConfigSettings(bool reload)
    m_configs[CONFIG_GUILD_BANK_EVENT_LOG_COUNT] = sConfig.GetIntDefault("Guild.BankEventLogRecordsCount", GUILD_BANK_MAX_LOGS);
    if (m_configs[CONFIG_GUILD_BANK_EVENT_LOG_COUNT] < GUILD_BANK_MAX_LOGS)
        m_configs[CONFIG_GUILD_BANK_EVENT_LOG_COUNT] = GUILD_BANK_MAX_LOGS;
+        
+    m_configs[CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE] = sConfig.GetIntDefault("Custom.AllowFlyingMountsEverywhere", 0);

    m_configs[CONFIG_TIMERBAR_FATIGUE_GMLEVEL] = sConfig.GetIntDefault("TimerBar.Fatigue.GMLevel", SEC_CONSOLE);
    m_configs[CONFIG_TIMERBAR_FATIGUE_MAX]     = sConfig.GetIntDefault("TimerBar.Fatigue.Max", 60);
diff --git a/src/game/World.h b/src/game/World.h
index 74c897a..ebb45d9 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -222,6 +222,7 @@ enum WorldConfigs
    CONFIG_TIMERBAR_BREATH_MAX,
    CONFIG_TIMERBAR_FIRE_GMLEVEL,
    CONFIG_TIMERBAR_FIRE_MAX,
+    CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE,
    CONFIG_VALUE_COUNT
};

diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in
index d925a15..cd440d5 100644
--- a/src/mangosd/mangosd.conf.dist.in
+++ b/src/mangosd/mangosd.conf.dist.in
@@ -1373,3 +1373,14 @@ Ra.IP = 0.0.0.0
Ra.Port = 3443
Ra.MinLevel = 3
Ra.Secure = 1
+
+###################################################################################################################
+#
+#     Custom.AllowFlyingMountsEverywhere
+#         Set it to 1 to enable flying mounts everywhere
+#         If you do it, mounts are now used as item...
+#     Default : 0
+#
+###################################################################################################################
+
+Custom.AllowFlyingMountsEverywhere = 0
-- 
1.7.0.2.msysgit.0

From yad's repo(easy-mangos)

Link to comment
Share on other sites

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use