[12660] Implement mount capabilities by Shauren.

Also  update AreaFlags enum, implement mount capabilities check at teleport.

----------------------------
commit is partially based on ec5eabdc69
This commit is contained in:
sanctum32 2013-08-05 23:43:55 +03:00 committed by Antz
parent a253344a02
commit 46d4f07052
8 changed files with 105 additions and 36 deletions

View file

@ -280,7 +280,7 @@ enum AchievementCriteriaMoreReqType
enum AreaFlags
{
AREA_FLAG_SNOW = 0x00000001, // snow (only Dun Morogh, Naxxramas, Razorfen Downs and Winterspring)
AREA_FLAG_SNOW = 0x00000001, // wrong - snow (only Dun Morogh, Naxxramas, Razorfen Downs and Winterspring)
AREA_FLAG_UNK1 = 0x00000002, // may be necropolis?
AREA_FLAG_UNK2 = 0x00000004, // Only used for areas on map 571 (development before)
AREA_FLAG_SLAVE_CAPITAL = 0x00000008, // city and city subsones
@ -290,25 +290,27 @@ enum AreaFlags
AREA_FLAG_ARENA = 0x00000080, // arena, both instanced and world arenas
AREA_FLAG_CAPITAL = 0x00000100, // main capital city flag
AREA_FLAG_CITY = 0x00000200, // only for one zone named "City" (where it located?)
AREA_FLAG_OUTLAND = 0x00000400, // expansion zones? (only Eye of the Storm not have this flag, but have 0x00004000 flag)
AREA_FLAG_OUTLAND = 0x00000400, // Dragonshrines, The Verne, Pincer X2, Entryway of Time
AREA_FLAG_SANCTUARY = 0x00000800, // sanctuary area (PvP disabled)
AREA_FLAG_NEED_FLY = 0x00001000, // only Netherwing Ledge, Socrethar's Seat, Tempest Keep, The Arcatraz, The Botanica, The Mechanar, Sorrow Wing Point, Dragonspine Ridge, Netherwing Mines, Dragonmaw Base Camp, Dragonmaw Skyway
AREA_FLAG_NEED_FLY = 0x00001000, // only Netherwing Ledge, Socrethar's Seat, Tempest Keep, The Arcatraz, The Botanica, The Mechanar, Sorrow Wing Point, Dragonspine Ridge, Netherwing Mines, Dragonmaw Base Camp, Dragonmaw Skyway, Naxxramas, Maelstrom zones
AREA_FLAG_UNUSED1 = 0x00002000, // not used now (no area/zones with this flag set in 3.0.3)
AREA_FLAG_OUTLAND2 = 0x00004000, // expansion zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag)
AREA_FLAG_PVP = 0x00008000, // pvp objective area? (Death's Door also has this flag although it's no pvp object area)
AREA_FLAG_ARENA_INSTANCE = 0x00010000, // used by instanced arenas only
AREA_FLAG_ARENA_INSTANCE = 0x00010000, // used by instanced arenas, Twin Peaks indoor areas, THe Lost Isles
AREA_FLAG_UNUSED2 = 0x00020000, // not used now (no area/zones with this flag set in 3.0.3)
AREA_FLAG_UNK5 = 0x00040000, // only used for Amani Pass, Hatchet Hills
AREA_FLAG_UNK6 = 0x00080000, // Valgarde and Acherus: The Ebon Hold
AREA_FLAG_UNK6 = 0x00080000, // Valgarde, Acherus: The Ebon Hold, Gilneas, Kezhan, The Maelstrom, Duskmist Shore, The Lost Isles
AREA_FLAG_LOWLEVEL = 0x00100000, // used for some starting areas with area_level <=15
AREA_FLAG_TOWN = 0x00200000, // small towns with Inn
AREA_FLAG_UNK7 = 0x00400000, // Warsong Hold, Acherus: The Ebon Hold, New Agamand Inn, Vengeance Landing Inn
AREA_FLAG_UNK8 = 0x00800000, // Westguard Inn, Acherus: The Ebon Hold, Valgarde
AREA_FLAG_OUTDOOR_PVP = 0x01000000, // Wintergrasp and it's subzones
AREA_FLAG_OUTDOOR_PVP = 0x01000000, // Wintergrasp, Twin peaks and it's subzones, Ironclad Garrison (Tol Barad)
AREA_FLAG_INSIDE = 0x02000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors
AREA_FLAG_OUTSIDE = 0x04000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors
AREA_FLAG_CAN_HEARTH_AND_RES = 0x08000000, // Wintergrasp and it's subzones
AREA_FLAG_CANNOT_FLY = 0x20000000 // not allowed to fly, only used in Dalaran areas (zone 4395)
AREA_FLAG_CAN_HEARTH_AND_RES = 0x08000000, // Wintergrasp, Tol Barad and their subzones
AREA_FLAG_TP = 0x20000000, // Twin Peaks areas
AREA_FLAG_UNK9 = 0x40000000, // many world zones
AREA_FLAG_BFG = 0x80000000, // Battle for Gilneas areas and one Twin Peaks area
};
enum Difficulty

View file

@ -187,7 +187,58 @@ void WorldSession::HandleMoveWorldportAckOpcode()
// mount allow check
if (!mEntry->IsMountAllowed())
{
_player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
_player->RemoveSpellsCausingAura(SPELL_AURA_FLY);
}
else
{
// recheck mount capabilities at far teleport
Unit::AuraList const& mMountAuras = _player->GetAurasByType(SPELL_AURA_MOUNTED);
for (Unit::AuraList::const_iterator itr = mMountAuras.begin(); itr != mMountAuras.end(); )
{
Aura const* aura = *itr;
// mount is no longer suitable
MountCapabilityEntry const* entry = _player->GetMountCapability(aura->GetSpellEffect()->EffectMiscValueB);
if (!entry)
{
_player->RemoveAurasDueToSpell(aura->GetId());
itr = mMountAuras.begin();
continue;
}
// mount capability changed
if (entry->Id != aura->GetModifier()->m_amount)
{
if (MountCapabilityEntry const* oldEntry = sMountCapabilityStore.LookupEntry(aura->GetModifier()->m_amount))
_player->RemoveAurasDueToSpell(oldEntry->SpeedModSpell);
_player->CastSpell(_player, entry->SpeedModSpell, true);
const_cast<Aura*>(aura)->ChangeAmount(entry->Id);
}
++itr;
}
uint32 zone, area;
_player->GetZoneAndAreaId(zone, area);
// recheck fly auras
Unit::AuraList const& mFlyAuras = _player->GetAurasByType(SPELL_AURA_FLY);
for (Unit::AuraList::const_iterator itr = mFlyAuras.begin(); itr != mFlyAuras.end(); )
{
Aura const* aura = *itr;
if (!_player->CanStartFlyInArea(_player->GetMapId(), zone, area))
{
_player->RemoveAurasDueToSpell(aura->GetId());
itr = mFlyAuras.begin();
continue;
}
++itr;
}
}
// honorless target
if (GetPlayer()->pvpInfo.inHostileArea)

View file

@ -6851,17 +6851,6 @@ void Player::UpdateArea(uint32 newArea)
SetFFAPvP(false);
}
if (area)
{
// Dalaran restricted flight zone
if ((area->flags & AREA_FLAG_CANNOT_FLY) && IsFreeFlying() && !isGameMaster() && !HasAura(58600))
CastSpell(this, 58600, true); // Restricted Flight Area
// TODO: implement wintergrasp parachute when battle in progress
/* if ((area->flags & AREA_FLAG_OUTDOOR_PVP) && IsFreeFlying() && <WINTERGRASP_BATTLE_IN_PROGRESS> && !isGameMaster())
CastSpell(this, 58730, true); */
}
UpdateAreaDependentAuras();
}
@ -22044,20 +22033,26 @@ bool Player::CanStartFlyInArea(uint32 mapid, uint32 zone, uint32 area) const
{
if (isGameMaster())
return true;
// continent checked in SpellMgr::GetSpellAllowedInLocationError at cast and area update
uint32 v_map = GetVirtualMapForMapAndZone(mapid, zone);
if (v_map == 571 && !HasSpell(54197)) // Cold Weather Flying
return false;
// switch all known flying maps
switch (v_map)
{
case 0: // Eastern Kingdoms
case 1: // Kalimdor
case 646: // Deepholm
return HasSpell(90267);
case 530: // Outland
return true;
case 571: // Northrend
// Check Cold Weather Flying
// Disallow mounting in wintergrasp when battle is in progress
return HasSpell(54197); /* && (!inWintergrasp || wg->GetState() != BF_IN_PROGRESS);*/
}
// don't allow flying in Dalaran restricted areas
// (no other zones currently has areas with AREA_FLAG_CANNOT_FLY)
if (AreaTableEntry const* atEntry = GetAreaEntryByAreaID(area))
return (!(atEntry->flags & AREA_FLAG_CANNOT_FLY));
// TODO: disallow mounting in wintergrasp too when battle is in progress
// forced dismount part in Player::UpdateArea()
return true;
return false;
}
struct DoPlayerLearnSpell

View file

@ -6105,12 +6105,13 @@ SpellCastResult Spell::CheckCast(bool strict)
}
case SPELL_AURA_MOUNTED:
{
if (m_caster->IsInWater())
return SPELL_FAILED_ONLY_ABOVEWATER;
if (m_caster->GetTypeId() == TYPEID_PLAYER && ((Player*)m_caster)->GetTransport())
return SPELL_FAILED_NO_MOUNTS_ALLOWED;
if (spellEffect->EffectMiscValueB && !m_caster->GetMountCapability(spellEffect->EffectMiscValueB))
return SPELL_FAILED_NOT_HERE;
// Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
if (m_caster->GetTypeId() == TYPEID_PLAYER && !sMapStore.LookupEntry(m_caster->GetMapId())->IsMountAllowed() && !m_IsTriggeredSpell && !m_spellInfo->GetAreaGroupId())
return SPELL_FAILED_NO_MOUNTS_ALLOWED;

View file

@ -2900,14 +2900,14 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
}
case 58600: // Restricted Flight Area
{
AreaTableEntry const* area = GetAreaEntryByAreaID(target->GetAreaId());
/*AreaTableEntry const* area = GetAreaEntryByAreaID(target->GetAreaId());
// Dalaran restricted flight zone (recheck before apply unmount)
if (area && target->GetTypeId() == TYPEID_PLAYER && (area->flags & AREA_FLAG_CANNOT_FLY) &&
((Player*)target)->IsFreeFlying() && !((Player*)target)->isGameMaster())
{
target->CastSpell(target, 58601, true); // Remove Flight Auras (also triggered Parachute (45472))
}
}*/
return;
}
case 61900: // Electrical Charge
@ -3407,6 +3407,10 @@ void Aura::HandleAuraMounted(bool apply, bool Real)
if (apply)
{
// Running Wild
if (GetId() == 87840)
target->Mount(target->getGender() == GENDER_MALE ? 29422 : 29423, GetId());
CreatureInfo const* ci = ObjectMgr::GetCreatureTemplate(m_modifier.m_miscvalue);
if (!ci)
{
@ -3436,8 +3440,8 @@ void Aura::HandleAuraMounted(bool apply, bool Real)
target->Unmount(true);
// remove speed aura
if (MountCapabilityEntry const* mountCapability = target->GetMountCapability(uint32(GetMiscBValue())))
target->RemoveAurasDueToSpell(mountCapability->SpeedModSpell);
if (MountCapabilityEntry const* mountCapability = target->GetMountCapability(m_modifier.m_amount))
target->RemoveAurasByCasterSpell(mountCapability->SpeedModSpell, target->GetObjectGuid());
CreatureInfo const* ci = ObjectMgr::GetCreatureTemplate(m_modifier.m_miscvalue);
if (ci && target->IsVehicle() && ci->vehicleId == target->GetVehicleInfo()->GetVehicleEntry()->m_ID)

View file

@ -465,6 +465,12 @@ class MANGOS_DLL_SPEC Aura
}
}
void ApplyModifier(bool apply, bool Real = false);
void ChangeAmount(int32 amount, bool update = true)
{
m_modifier.m_amount = amount;
if (update)
GetHolder()->SendAuraUpdate(false);
}
void UpdateAura(uint32 diff) { SetInUse(true); Update(diff); SetInUse(false); }

View file

@ -9428,6 +9428,16 @@ int32 Unit::CalculateSpellDamage(Unit const* target, SpellEntry const* spellProt
if(!spellEffect)
return 0;
switch (spellEffect->EffectApplyAuraName)
{
case SPELL_AURA_MOUNTED:
if (MountCapabilityEntry const* mountCapability = GetMountCapability(uint32(spellEffect->EffectMiscValueB)))
return int32(mountCapability->Id);
break;
default:
break;
}
Player* unitPlayer = (GetTypeId() == TYPEID_PLAYER) ? (Player*)this : NULL;
uint32 level = getLevel();

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "12659"
#define REVISION_NR "12660"
#endif // __REVISION_NR_H__