diff --git a/sql/updates/world/2014_02_04_00_world_access_requirement.sql b/sql/updates/world/2014_02_04_00_world_access_requirement.sql new file mode 100644 index 0000000000000..5d2a89370f06b --- /dev/null +++ b/sql/updates/world/2014_02_04_00_world_access_requirement.sql @@ -0,0 +1,9 @@ +-- Add new collum in the access_requirement table. +ALTER TABLE `access_requirement` ADD COLUMN `item_level` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' AFTER `level_max`; + +-- All WotLK Heroics require at least an average item level of 180. +UPDATE `access_requirement` SET `item_level`=180 WHERE `mapId` IN (574, 575, 576, 578, 595, 599, 600, 601, 602, 604, 608, 619) AND `difficulty`=1; +-- Trial of the Champion, Pit of Saron, and the Forge of Souls require an average item level of 200. +UPDATE `access_requirement` SET `item_level`=200 WHERE `mapId` IN (632, 650, 658); +-- Halls of Reflection requires an average item level of 219. +UPDATE `access_requirement` SET `item_level`=219 WHERE `mapId`=668; diff --git a/sql/updates/world/2014_02_04_01_world_sai.sql b/sql/updates/world/2014_02_04_01_world_sai.sql new file mode 100644 index 0000000000000..c29a64cf347e7 --- /dev/null +++ b/sql/updates/world/2014_02_04_01_world_sai.sql @@ -0,0 +1,8 @@ +-- +UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI' WHERE `entry` IN (179507,179508,179510,179513); +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (179507,179508,179510,179513) AND `source_type` =1; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(179507, 1, 0, 0, 70, 0, 100, 0, 2, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 14, 49943, 177188, 0, 0, 0, 0, 0, 'Door Lever - On Gameobject State Changed - Activate Gameobject (No Repeat)'), +(179508, 1, 0, 0, 70, 0, 100, 0, 2, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 14, 49945, 177189, 0, 0, 0, 0, 0, 'Door Lever - On Gameobject State Changed - Activate Gameobject (No Repeat)'), +(179510, 1, 0, 0, 70, 0, 100, 0, 2, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 14, 49948, 177192, 0, 0, 0, 0, 0, 'Door Lever - On Gameobject State Changed - Activate Gameobject (No Repeat)'), +(179513, 1, 0, 0, 70, 0, 100, 0, 2, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 14, 49956, 177198, 0, 0, 0, 0, 0, 'Door Lever - On Gameobject State Changed - Activate Gameobject (No Repeat)'); diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 61fb619171029..624a5657cfd52 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -404,7 +404,9 @@ void LFGMgr::InitializeLockedDungeons(Player* player, uint8 level /* = 0 */) lockData = LFG_LOCKSTATUS_NOT_IN_SEASON; else if (AccessRequirement const* ar = sObjectMgr->GetAccessRequirement(dungeon->map, Difficulty(dungeon->difficulty))) { - if (ar->achievement && !player->HasAchieved(ar->achievement)) + if (player->GetAverageItemLevel() < ar->item_level) + lockData = LFG_LOCKSTATUS_TOO_LOW_GEAR_SCORE; + else if (ar->achievement && !player->HasAchieved(ar->achievement)) lockData = LFG_LOCKSTATUS_MISSING_ACHIEVEMENT; else if (player->GetTeam() == ALLIANCE && ar->quest_A && !player->GetQuestRewardStatus(ar->quest_A)) lockData = LFG_LOCKSTATUS_QUEST_NOT_COMPLETED; @@ -421,7 +423,6 @@ void LFGMgr::InitializeLockedDungeons(Player* player, uint8 level /* = 0 */) } /* @todo VoA closed if WG is not under team control (LFG_LOCKSTATUS_RAID_LOCKED) - lockData = LFG_LOCKSTATUS_TOO_LOW_GEAR_SCORE; lockData = LFG_LOCKSTATUS_TOO_HIGH_GEAR_SCORE; lockData = LFG_LOCKSTATUS_ATTUNEMENT_TOO_LOW_LEVEL; lockData = LFG_LOCKSTATUS_ATTUNEMENT_TOO_HIGH_LEVEL; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 84d3b4de2fbd9..79f7c35637650 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -18719,6 +18719,9 @@ void Player::_LoadGroup(PreparedQueryResult result) { if (Group* group = sGroupMgr->GetGroupByDbStoreId((*result)[0].GetUInt32())) { + if (group->IsLeader(GetGUID())) + SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER); + uint8 subgroup = group->GetMemberGroup(GetGUID()); SetGroup(group, subgroup); if (getLevel() >= LEVELREQUIREMENT_HEROIC) @@ -18729,6 +18732,9 @@ void Player::_LoadGroup(PreparedQueryResult result) } } } + + if (!GetGroup() || !GetGroup()->IsLeader(GetGUID())) + RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER); } void Player::_LoadBoundInstances(PreparedQueryResult result) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 5e159ef16d3ae..9a77a999a4681 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -918,6 +918,7 @@ struct AccessRequirement { uint8 levelMin; uint8 levelMax; + uint16 item_level; uint32 item; uint32 item2; uint32 quest_A; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 49b7543da85fe..7ff01c84ff951 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -7276,13 +7276,28 @@ ReputationRank Unit::GetReactionTo(Unit const* target) const if (GetCharmerOrOwnerOrSelf() == target->GetCharmerOrOwnerOrSelf()) return REP_FRIENDLY; + Player const* selfPlayerOwner = GetAffectingPlayer(); + Player const* targetPlayerOwner = target->GetAffectingPlayer(); + + // check forced reputation to support SPELL_AURA_FORCE_REACTION + if (selfPlayerOwner) + { + if (FactionTemplateEntry const* targetFactionTemplateEntry = target->GetFactionTemplateEntry()) + if (ReputationRank const* repRank = selfPlayerOwner->GetReputationMgr().GetForcedRankIfAny(targetFactionTemplateEntry)) + return *repRank; + } + else if (targetPlayerOwner) + { + if (FactionTemplateEntry const* selfFactionTemplateEntry = GetFactionTemplateEntry()) + if (ReputationRank const* repRank = targetPlayerOwner->GetReputationMgr().GetForcedRankIfAny(selfFactionTemplateEntry)) + return *repRank; + } + + if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)) { if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)) { - Player const* selfPlayerOwner = GetAffectingPlayer(); - Player const* targetPlayerOwner = target->GetAffectingPlayer(); - if (selfPlayerOwner && targetPlayerOwner) { // always friendly to other unit controlled by player, or to the player himself diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 3f15ec87392b4..2936c31e1ae71 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -725,12 +725,6 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo) cInfo->Entry, cInfo->type, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->type); } - if (cInfo->type_flags != difficultyInfo->type_flags) - { - TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, type_flags %u) has different `type_flags` in difficulty %u mode (Entry: %u, type_flags %u).", - cInfo->Entry, cInfo->type_flags, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->type_flags); - } - if (!cInfo->VehicleId && difficultyInfo->VehicleId) { TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, VehicleId %u) has different `VehicleId` in difficulty %u mode (Entry: %u, VehicleId %u).", @@ -5995,8 +5989,9 @@ void ObjectMgr::LoadAccessRequirements() _accessRequirementStore.clear(); // need for reload case } - // 0 1 2 3 4 5 6 7 8 9 - QueryResult result = WorldDatabase.Query("SELECT mapid, difficulty, level_min, level_max, item, item2, quest_done_A, quest_done_H, completed_achievement, quest_failed_text FROM access_requirement"); + // 0 1 2 3 4 5 6 7 8 9 10 + QueryResult result = WorldDatabase.Query("SELECT mapid, difficulty, level_min, level_max, item_level, item, item2, quest_done_A, quest_done_H, completed_achievement, quest_failed_text FROM access_requirement"); + if (!result) { TC_LOG_INFO("server.loading", ">> Loaded 0 access requirement definitions. DB table `access_requirement` is empty."); @@ -6019,12 +6014,13 @@ void ObjectMgr::LoadAccessRequirements() ar->levelMin = fields[2].GetUInt8(); ar->levelMax = fields[3].GetUInt8(); - ar->item = fields[4].GetUInt32(); - ar->item2 = fields[5].GetUInt32(); - ar->quest_A = fields[6].GetUInt32(); - ar->quest_H = fields[7].GetUInt32(); - ar->achievement = fields[8].GetUInt32(); - ar->questFailedText = fields[9].GetString(); + ar->item_level = fields[4].GetUInt16(); + ar->item = fields[5].GetUInt32(); + ar->item2 = fields[6].GetUInt32(); + ar->quest_A = fields[7].GetUInt32(); + ar->quest_H = fields[8].GetUInt32(); + ar->achievement = fields[9].GetUInt32(); + ar->questFailedText = fields[10].GetString(); if (ar->item) { diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 2198086c9002a..be18852ce8e0d 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -99,6 +99,7 @@ bool Group::Create(Player* leader) m_guid = MAKE_NEW_GUID(lowguid, 0, HIGHGUID_GROUP); m_leaderGuid = leaderGuid; m_leaderName = leader->GetName(); + leader->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER); if (isBGGroup() || isBFGroup()) m_groupType = GROUPTYPE_BGRAID; @@ -697,6 +698,10 @@ void Group::ChangeLeader(uint64 newLeaderGuid) CharacterDatabase.CommitTransaction(trans); } + if (Player* oldLeader = ObjectAccessor::FindPlayer(m_leaderGuid)) + oldLeader->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER); + + newLeader->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER); m_leaderGuid = newLeader->GetGUID(); m_leaderName = newLeader->GetName(); ToggleGroupMemberFlag(slot, MEMBER_FLAG_ASSISTANT, false); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index c3baf493156d5..abd4a5c1d1e73 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -5792,6 +5792,13 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const else damage = uint32(target->CountPctFromMaxHealth(damage)); + if (m_spellInfo->Effects[m_effIndex].IsTargetingArea() || m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA)) + { + damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask)); + if (caster->GetTypeId() != TYPEID_PLAYER) + damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask)); + } + bool crit = IsPeriodicTickCrit(target, caster); if (crit) damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index f5396daef5127..edf9271df1ade 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -6679,10 +6679,10 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier) if (m_damage > 0) { - if (m_spellInfo->Effects[i].IsTargetingArea()) + if (m_spellInfo->Effects[i].IsTargetingArea() || m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA)) { m_damage = int32(float(m_damage) * unit->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask)); - if (m_caster->GetTypeId() == TYPEID_UNIT) + if (m_caster->GetTypeId() != TYPEID_PLAYER) m_damage = int32(float(m_damage) * unit->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask)); if (m_caster->GetTypeId() == TYPEID_PLAYER)