diff --git a/sql/mangos.sql b/sql/mangos.sql index b9cfff2b2..1d7ffdc90 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_10203_01_mangos_item_template` bit(1) default NULL + `required_10205_01_mangos_spell_area` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- diff --git a/sql/updates/10205_01_mangos_spell_area.sql b/sql/updates/10205_01_mangos_spell_area.sql new file mode 100644 index 000000000..a711b71a9 --- /dev/null +++ b/sql/updates/10205_01_mangos_spell_area.sql @@ -0,0 +1,3 @@ +ALTER TABLE db_version CHANGE COLUMN required_10203_01_mangos_item_template required_10205_01_mangos_spell_area bit; + +DELETE FROM spell_area WHERE spell = 58600; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index f0148fc5e..49766b898 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -108,6 +108,7 @@ pkgdata_DATA = \ 10171_01_mangos_mangos_string.sql \ 10197_01_mangos_playercreateinfo.sql \ 10203_01_mangos_item_template.sql \ + 10205_01_mangos_spell_area.sql \ README ## Additional files to include when running 'make dist' @@ -196,4 +197,5 @@ EXTRA_DIST = \ 10171_01_mangos_mangos_string.sql \ 10197_01_mangos_playercreateinfo.sql \ 10203_01_mangos_item_template.sql \ + 10205_01_mangos_spell_area.sql \ README diff --git a/src/game/DBCEnums.h b/src/game/DBCEnums.h index 93d15174b..dcd66504f 100644 --- a/src/game/DBCEnums.h +++ b/src/game/DBCEnums.h @@ -244,8 +244,8 @@ enum AreaFlags AREA_FLAG_OUTDOOR_PVP = 0x01000000, // Wintergrasp and it's subzones 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 - // 0x20000000 not flyable? + 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) }; enum Difficulty diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 2127d8542..1b968ec41 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -6621,15 +6621,15 @@ uint32 Player::GetLevelFromDB(uint64 guid) void Player::UpdateArea(uint32 newArea) { - // FFA_PVP flags are area and not zone id dependent - // so apply them accordingly m_areaUpdateId = newArea; AreaTableEntry const* area = GetAreaEntryByAreaID(newArea); - if(area && (area->flags & AREA_FLAG_ARENA)) + // FFA_PVP flags are area and not zone id dependent + // so apply them accordingly + if (area && (area->flags & AREA_FLAG_ARENA)) { - if(!isGameMaster()) + if (!isGameMaster()) SetFFAPvP(true); } else @@ -6640,6 +6640,17 @@ void Player::UpdateArea(uint32 newArea) SetFFAPvP(false); } + if (area) + { + // Dalaran restricted flight zone + if ((area->flags & AREA_FLAG_CANNOT_FLY) && IsFreeFlying() && !isGameMaster()) + CastSpell(this, 58600, true); + + // TODO: implement wintergrasp parachute when battle in progress + /* if ((area->flags & AREA_FLAG_OUTDOOR_PVP) && IsFreeFlying() && && !isGameMaster()) + CastSpell(this, 58730, true); */ + } + UpdateAreaDependentAuras(newArea); } @@ -13965,7 +13976,7 @@ bool Player::SatisfyQuestExclusiveGroup( Quest const* qInfo, bool msg ) const if (i_exstatus != mQuestStatus.end() && (i_exstatus->second.m_status == QUEST_STATUS_COMPLETE || i_exstatus->second.m_status == QUEST_STATUS_INCOMPLETE)) { - if (msg) + if (msg) SendCanTakeQuestResponse( INVALIDREASON_DONT_HAVE_REQ ); return false; } @@ -15673,7 +15684,7 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff) aura->SetLoadedState(damage[i], maxduration[i], remaintime[i]); holder->AddAura(aura, SpellEffectIndex(i)); } - + if (!holder->IsEmptyHolder()) { // reset stolen single target auras @@ -15692,7 +15703,7 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff) } if(getClass() == CLASS_WARRIOR && !HasAuraType(SPELL_AURA_MOD_SHAPESHIFT)) - CastSpell(this,SPELL_ID_PASSIVE_BATTLE_STANCE,true); + CastSpell(this,SPELL_ID_PASSIVE_BATTLE_STANCE,true); } void Player::_LoadGlyphs(QueryResult *result) @@ -16895,7 +16906,7 @@ void Player::_SaveAuras() for(SpellAuraHolderMap::const_iterator itr = auraHolders.begin(); itr != auraHolders.end(); ++itr) { - SpellAuraHolder *holder = itr->second; + SpellAuraHolder *holder = itr->second; //skip all holders from spells that are passive //do not save single target holders (unless they were cast by the player) if (!holder->IsPassive() && (holder->GetCasterGUID() == GetGUID() || !holder->IsSingleTarget())) @@ -16923,7 +16934,7 @@ void Player::_SaveAuras() effIndexMask |= (1 << i); } } - + if (!effIndexMask) continue; @@ -21002,13 +21013,24 @@ uint32 Player::CalculateTalentsPoints() const return uint32(talentPointsForLevel * sWorld.getConfig(CONFIG_FLOAT_RATE_TALENT)); } -bool Player::IsKnowHowFlyIn(uint32 mapid, uint32 zone, uint32 area) const +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); - // don't allow flying in Dalaran except Krasus' Landing - return (v_map != 571 || HasSpell(54197)) && (zone != 4395 || area == 4564); // Cold Weather Flying + if (v_map == 571 && !HasSpell(54197)) // Cold Weather Flying + return false; + + // 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; } struct DoPlayerLearnSpell diff --git a/src/game/Player.h b/src/game/Player.h index 1bae1bdd7..e9b0a02e2 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2209,7 +2209,7 @@ class MANGOS_DLL_SPEC Player : public Unit bool CanFly() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_CAN_FLY); } bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_FLYING); } bool IsFreeFlying() const { return HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED) || HasAuraType(SPELL_AURA_FLY); } - bool IsKnowHowFlyIn(uint32 mapid, uint32 zone, uint32 area) const; + bool CanStartFlyInArea(uint32 mapid, uint32 zone, uint32 area) const; void SetClientControl(Unit* target, uint8 allowMove); void SetMover(Unit* target) { m_mover = target ? target : this; } diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index ee928c84e..08b7012ec 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2676,7 +2676,7 @@ void Spell::cancel() if(m_spellState == SPELL_STATE_FINISHED) return; - // channeled spells don't display interrupted message even if they are interrupted, possible other cases with no "Interrupted" message + // channeled spells don't display interrupted message even if they are interrupted, possible other cases with no "Interrupted" message bool sendInterrupt = IsChanneledSpell(m_spellInfo) ? false : true; m_autoRepeat = false; @@ -2705,7 +2705,7 @@ void Spell::cancel() SendChannelUpdate(0); SendInterrupted(0); - + if (sendInterrupt) SendCastResult(SPELL_FAILED_INTERRUPTED); } break; @@ -5219,7 +5219,7 @@ SpellCastResult Spell::CheckCast(bool strict) // allow always ghost flight spells if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->isAlive()) { - if (!((Player*)m_caster)->IsKnowHowFlyIn(m_caster->GetMapId(), zone, area)) + if (!((Player*)m_caster)->CanStartFlyInArea(m_caster->GetMapId(), zone, area)) return m_IsTriggeredSpell ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_NOT_HERE; } break; @@ -6685,7 +6685,7 @@ void Spell::SelectMountByAreaAndSkill(Unit* target, uint32 spellId75, uint32 spe target->GetZoneAndAreaId(zone, area); SpellCastResult locRes= sSpellMgr.GetSpellAllowedInLocationError(pSpell, target->GetMapId(), zone, area, target->GetCharmerOrOwnerPlayerOrPlayerItself()); - if (locRes != SPELL_CAST_OK || !((Player*)target)->IsKnowHowFlyIn(target->GetMapId(), zone, area)) + if (locRes != SPELL_CAST_OK || !((Player*)target)->CanStartFlyInArea(target->GetMapId(), zone, area)) target->CastSpell(target, spellId150, true); else if (spellIdSpecial > 0) { @@ -6729,4 +6729,4 @@ void Spell::ClearCastItem() m_targets.setItemTarget(NULL); m_CastItem = NULL; -} \ No newline at end of file +} diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 02852c874..b53fdcf48 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10204" + #define REVISION_NR "10205" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index ffe07fb0c..5a64934c2 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_10160_02_characters_pet_aura" - #define REVISION_DB_MANGOS "required_10203_01_mangos_item_template" + #define REVISION_DB_MANGOS "required_10205_01_mangos_spell_area" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version" #endif // __REVISION_SQL_H__