diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cppindex 20ac51d..58e9b3d 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
@@ -779,6 +782,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder *holder)
if(!pCurrChar->IsStandState() && !pCurrChar->hasUnitState(UNIT_STAT_STUNNED))
pCurrChar->SetStandState(UNIT_STAND_STATE_STAND);
+ if (sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1)
+ pCurrChar->CombatStop(); //wtf ???
+
m_playerLoading = false;
delete holder;
}
diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp
index 857bddc..6383a81 100644
--- a/src/game/MiscHandler.cpp
+++ b/src/game/MiscHandler.cpp
@@ -1507,8 +1507,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->HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED))
+ return;
+ 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 88541ba..5a508f7 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -10124,6 +10124,123 @@ 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)
+ {
+ Unit* player = ((Unit*)this);
+ if (sEntry->EffectApplyAuraName[0] == SPELL_AURA_MOUNTED &&
+ sEntry->EffectApplyAuraName[1] == SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED &&
+ sEntry->EffectApplyAuraName[2] == SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED )
+ {
+ if (!(player->HasAuraType(SPELL_AURA_MOUNTED) &&
+ player->HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) &&
+ player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED)))
+ {
+ uint32 v_map = GetVirtualMapForMapAndZone(player->GetMapId(), player->GetZoneId());
+ MapEntry const* mapEntry = sMapStore.LookupEntry(v_map);
+ if(player && !player->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 EQUIP_ERR_OK;
+ }
+ if(!mapEntry)
+ {
+ 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 EQUIP_ERR_OK;
+ }
+ /*
+ else if(mapEntry->Instanceable())
+ {
+ 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 EQUIP_ERR_OK;
+ }
+ */
+ else if(mapEntry->IsDungeon())
+ {
+ 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 EQUIP_ERR_OK;
+ }
+ else if(mapEntry->IsRaid())
+ {
+ 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 EQUIP_ERR_OK;
+ }
+ else if(mapEntry->IsBattleArena())
+ {
+ 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 EQUIP_ERR_OK;
+ }
+ else if(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 EQUIP_ERR_OK;
+ }
+ else
+ {
+ for (int j = 0; j < 3; ++j)
+ {
+ Aura* aur = CreateAura(sEntry, j, NULL, player, player, NULL);
+ player->AddAura(aur);
+ }
+ }
+ }
+ else
+ {
+ player->Unmount();
+ player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+ player->RemoveSpellsCausingAura(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED);
+ player->RemoveSpellsCausingAura(SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED);
+ }
+ return EQUIP_ERR_OK;
+ }
+ else if (sEntry->EffectApplyAuraName[0] == SPELL_AURA_MOUNTED &&
+ sEntry->EffectApplyAuraName[1] == SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED &&
+ player->HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED))
+ {
+ player->Unmount();
+ player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+ player->RemoveSpellsCausingAura(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED);
+ player->RemoveSpellsCausingAura(SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED);
+ }
+ }
+ }
+ }
+ }
sLog.outDebug( "STORAGE: CanUseItem item = %u", pItem->GetEntry());
if (!isAlive() && not_loading)
@@ -11006,6 +11123,29 @@ void Player::DestroyItemCount( Item* pItem, uint32 &count, bool update )
if(!pItem)
return;
+ if (sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1)
+ {
+ ItemPrototype const *pProto = objmgr.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(sEntry->EffectApplyAuraName[0] == SPELL_AURA_MOUNTED &&
+ sEntry->EffectApplyAuraName[1] == SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED &&
+ sEntry->EffectApplyAuraName[2] == SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED )
+ {
+ 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 )
@@ -19825,6 +19965,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
@@ -20755,3 +20896,117 @@ void Player::SendDuelCountdown(uint32 counter)
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(!(sEntry->EffectApplyAuraName[0] == SPELL_AURA_MOUNTED &&
+ sEntry->EffectApplyAuraName[1] == SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED &&
+ sEntry->EffectApplyAuraName[2] == SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED )
+ ) continue; //This spell is a flying mount maybe another better check exists...
+
+ uint32 itemId = 0;
+ for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
+ {
+ ItemPrototype const *pProto = objmgr.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 = objmgr.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(!(sEntry->EffectApplyAuraName[0] == SPELL_AURA_MOUNTED &&
+ sEntry->EffectApplyAuraName[1] == SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED &&
+ sEntry->EffectApplyAuraName[2] == SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED )
+ ) continue; //This spell is a flying mount maybe another better check exists...
+
+ if(HasSpell(pProto->Spells[i].SpellId))
+ {
+ removeSpell(pProto->Spells[i].SpellId, false, false);
+ 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 = objmgr.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(!(sEntry->EffectApplyAuraName[0] == SPELL_AURA_MOUNTED &&
+ sEntry->EffectApplyAuraName[1] == SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED &&
+ sEntry->EffectApplyAuraName[2] == SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED )
+ ) continue; //This spell is a flying mount maybe another better check exists...
+
+ if(HasSpell(pProto->Spells[i].SpellId))
+ {
+ removeSpell(pProto->Spells[i].SpellId, false, false);
+ break;
+ }
+
+ }
+ }
+ }
+ }
+}
diff --git a/src/game/Player.h b/src/game/Player.h
index 5d0a4fb..77b54df 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -1200,6 +1200,8 @@ 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); }
+ void FlyingMountsSpellsToItems();
+
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;
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 435f7d2..46a30d8 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -4146,6 +4146,8 @@ SpellCastResult Spell::CheckCast(bool strict)
{
if (m_caster->isInFlight())
return SPELL_FAILED_NOT_FLYING;
+ else if ((sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1) && (m_spellInfo->Id==55884))
+ return SPELL_CAST_OK;
else
return SPELL_FAILED_NOT_MOUNTED;
}
@@ -5374,6 +5376,8 @@ SpellCastResult Spell::CheckItems()
continue;
}
}
+ else if ((sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1) && (m_spellInfo->Id==55884))
+ return SPELL_CAST_OK;
else
TotemCategory -= 1;
}
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index bf9852b..630007e 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -3414,6 +3414,24 @@ 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];
+
+ if ((sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1) && (m_spellInfo->Id==55884))
+ {
+ SpellEntry const *sEntry = sSpellStore.LookupEntry(spellToLearn);
+ if(sEntry)
+ {
+ if( sEntry->EffectApplyAuraName[0]==SPELL_AURA_MOUNTED &&
+ sEntry->EffectApplyAuraName[1]==SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED &&
+ sEntry->EffectApplyAuraName[2]==SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED )
+ {
+ 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 85d600e..695efc2 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,16 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
return;
}
+ if (sWorld.getConfig(CONFIG_ALLOW_FLYING_MOUNTS_EVERYWHERE) == 1)
+ {
+ if (spellInfo->EffectApplyAuraName[0] == SPELL_AURA_MOUNTED &&
+ spellInfo->EffectApplyAuraName[1] == SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED )
+ {
+ _player->Unmount();
+ _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+ }
+ }
+
if(mover->GetTypeId()==TYPEID_PLAYER)
{
// not have spell in spellbook or spell passive and not casted by client
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index fa0cff1..2aeee4a 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -2753,6 +2753,30 @@ 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 (spellInfo->EffectApplyAuraName[0] == SPELL_AURA_MOUNTED &&
+ spellInfo->EffectApplyAuraName[1] == SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED &&
+ spellInfo->EffectApplyAuraName[2] == SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED )
+ {
+ 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 fb5fb2c..48fb71b 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -995,6 +995,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_VisibleUnitGreyDistance = sConfig.GetFloatDefault("Visibility.Distance.Grey.Unit", 1);
if(m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE)
diff --git a/src/game/World.h b/src/game/World.h
index 73883c4..7ee7832 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -217,6 +217,7 @@ enum WorldConfigs
CONFIG_CLIENTCACHE_VERSION,
CONFIG_GUILD_EVENT_LOG_COUNT,
CONFIG_GUILD_BANK_EVENT_LOG_COUNT,
+ 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 e559642..4a3cbc3 100644
--- a/src/mangosd/mangosd.conf.dist.in
+++ b/src/mangosd/mangosd.conf.dist.in
@@ -1339,3 +1339,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
|