diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index a8d415535..1fba47038 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -319,7 +319,7 @@ bool AchievementCriteriaRequirement::Meets(uint32 criteria_id, Player const* sou case ACHIEVEMENT_CRITERIA_REQUIRE_S_DRUNK: return (uint32)Player::GetDrunkenstateByValue(source->GetDrunkValue()) >= drunk.state; case ACHIEVEMENT_CRITERIA_REQUIRE_HOLIDAY: - return IsHolidayActive(HolidayIds(holiday.id)); + return sGameEventMgr.IsActiveHoliday(HolidayIds(holiday.id)); case ACHIEVEMENT_CRITERIA_REQUIRE_BG_LOSS_TEAM_SCORE: { BattleGround* bg = source->GetBattleGround(); diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index 4936a9596..26122f91e 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -2079,7 +2079,7 @@ BattleGroundTypeId BattleGroundMgr::WeekendHolidayIdToBGType(HolidayIds holiday) bool BattleGroundMgr::IsBGWeekend(BattleGroundTypeId bgTypeId) { - return IsHolidayActive(BGTypeToWeekendHolidayId(bgTypeId)); + return sGameEventMgr.IsActiveHoliday(BGTypeToWeekendHolidayId(bgTypeId)); } void BattleGroundMgr::LoadBattleEventIndexes() diff --git a/src/game/GameEventMgr.cpp b/src/game/GameEventMgr.cpp index e7953db7d..4c97869cf 100644 --- a/src/game/GameEventMgr.cpp +++ b/src/game/GameEventMgr.cpp @@ -130,7 +130,7 @@ void GameEventMgr::LoadFromDB() bar.step(); uint16 event_id = fields[0].GetUInt16(); - if(event_id==0) + if (event_id == 0) { sLog.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id); continue; @@ -206,18 +206,18 @@ void GameEventMgr::LoadFromDB() if (event_id == 0) { - sLog.outErrorDb("`game_event_creature` game event id (%i) not allowed",event_id); + sLog.outErrorDb("`game_event_creature` game event id (%i) not allowed", event_id); continue; } - int32 internal_event_id = mGameEvent.size() + event_id - 1; - - if(internal_event_id < 0 || (size_t)internal_event_id >= mGameEventCreatureGuids.size()) + if (!IsValidEvent(std::abs(event_id))) { - sLog.outErrorDb("`game_event_creature` game event id (%i) is out of range compared to max event id in `game_event`",event_id); + sLog.outErrorDb("`game_event_creature` game event id (%i) not exist in `game_event`", event_id); continue; } + int32 internal_event_id = mGameEvent.size() + event_id - 1; + ++count; // spawn objects at event can be grouped in pools and then affected pools have stricter requirements for this case @@ -284,18 +284,18 @@ void GameEventMgr::LoadFromDB() if (event_id == 0) { - sLog.outErrorDb("`game_event_gameobject` game event id (%i) not allowed",event_id); + sLog.outErrorDb("`game_event_gameobject` game event id (%i) not allowed", event_id); continue; } - int32 internal_event_id = mGameEvent.size() + event_id - 1; - - if(internal_event_id < 0 || (size_t)internal_event_id >= mGameEventGameobjectGuids.size()) + if (!IsValidEvent(std::abs(event_id))) { - sLog.outErrorDb("`game_event_gameobject` game event id (%i) is out of range compared to max event id in `game_event`",event_id); + sLog.outErrorDb("`game_event_gameobject` game event id (%i) not exist in `game_event`", event_id); continue; } + int32 internal_event_id = mGameEvent.size() + event_id - 1; + ++count; // spawn objects at event can be grouped in pools and then affected pools have stricter requirements for this case @@ -372,15 +372,15 @@ void GameEventMgr::LoadFromDB() uint32 guid = fields[0].GetUInt32(); uint16 event_id = fields[1].GetUInt16(); - if(event_id==0) + if (event_id == 0) { - sLog.outErrorDb("`game_event_creature_data` game event id (%i) is reserved and can't be used.",event_id); + sLog.outErrorDb("`game_event_creature_data` game event id (%i) is reserved and can't be used." ,event_id); continue; } - if(event_id >= mGameEventCreatureData.size()) + if (!IsValidEvent(event_id)) { - sLog.outErrorDb("`game_event_creature_data` game event id (%u) is out of range compared to max event id in `game_event`",event_id); + sLog.outErrorDb("`game_event_creature_data` game event id (%u) not exist in `game_event`", event_id); continue; } @@ -452,9 +452,15 @@ void GameEventMgr::LoadFromDB() uint32 quest = fields[0].GetUInt32(); uint16 event_id = fields[1].GetUInt16(); - if(event_id >= mGameEventQuests.size()) + if (event_id == 0) { - sLog.outErrorDb("`game_event_quest` game event id (%u) is out of range compared to max event id in `game_event`",event_id); + sLog.outErrorDb("`game_event_quest` game event id (%i) is reserved and can't be used.", event_id); + continue; + } + + if (!IsValidEvent(event_id)) + { + sLog.outErrorDb("`game_event_quest` game event id (%u) not exist in `game_event`", event_id); continue; } @@ -517,14 +523,14 @@ void GameEventMgr::LoadFromDB() continue; } - int32 internal_event_id = mGameEvent.size() + event_id - 1; - - if (internal_event_id < 0 || (size_t)internal_event_id >= mGameEventMails.size()) + if (!IsValidEvent(event_id)) { - sLog.outErrorDb("`game_event_mail` game event id (%i) is out of range compared to max event id in `game_event`", event_id); + sLog.outErrorDb("`game_event_mail` game event id (%u) not exist in `game_event`", event_id); continue; } + int32 internal_event_id = mGameEvent.size() + event_id - 1; + if (!(mail.raceMask & RACEMASK_ALL_PLAYABLE)) { sLog.outErrorDb("Table `game_event_mail` have raceMask (%u) requirement for game event %i that not include any player races, ignoring.", mail.raceMask, event_id); @@ -1007,17 +1013,19 @@ GameEventMgr::GameEventMgr() m_IsGameEventsInit = false; } -MANGOS_DLL_SPEC bool IsHolidayActive( HolidayIds id ) +bool GameEventMgr::IsActiveHoliday( HolidayIds id ) { if (id == HOLIDAY_NONE) return false; - GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap(); - GameEventMgr::ActiveEvents const& ae = sGameEventMgr.GetActiveEventList(); - - for(GameEventMgr::ActiveEvents::const_iterator itr = ae.begin(); itr != ae.end(); ++itr) - if (events[*itr].holiday_id == id) + for(GameEventMgr::ActiveEvents::const_iterator itr = m_ActiveEvents.begin(); itr != m_ActiveEvents.end(); ++itr) + if (mGameEvent[*itr].holiday_id == id) return true; return false; } + +MANGOS_DLL_SPEC bool IsHolidayActive( HolidayIds id ) +{ + return sGameEventMgr.IsActiveHoliday(id); +} diff --git a/src/game/GameEventMgr.h b/src/game/GameEventMgr.h index 42ee3425f..b24382db1 100644 --- a/src/game/GameEventMgr.h +++ b/src/game/GameEventMgr.h @@ -78,7 +78,9 @@ class GameEventMgr uint32 NextCheck(uint16 entry) const; void LoadFromDB(); uint32 Update(ActiveEvents const* activeAtShutdown = NULL); + bool IsValidEvent(uint16 event_id) const { return event_id < mGameEvent.size() && mGameEvent[event_id].isValid(); } bool IsActiveEvent(uint16 event_id) const { return ( m_ActiveEvents.find(event_id)!=m_ActiveEvents.end()); } + bool IsActiveHoliday(HolidayIds id); uint32 Initialize(); void StartEvent(uint16 event_id, bool overwrite = false, bool resume = false); void StopEvent(uint16 event_id, bool overwrite = false); diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index d04c24aa3..6c6c132f8 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -4114,10 +4114,12 @@ bool ChatHandler::HandleLookupEventCommand(char* args) uint32 counter = 0; GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap(); - GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr.GetActiveEventList(); - for(uint32 id = 0; id < events.size(); ++id) + for(uint32 id = 1; id < events.size(); ++id) { + if (!sGameEventMgr.IsValidEvent(id)) + continue; + GameEventData const& eventData = events[id]; std::string descr = eventData.description; @@ -4126,7 +4128,7 @@ bool ChatHandler::HandleLookupEventCommand(char* args) if (Utf8FitTo(descr, wnamepart)) { - char const* active = activeEvents.find(id) != activeEvents.end() ? GetMangosString(LANG_ACTIVE) : ""; + char const* active = sGameEventMgr.IsActiveEvent(id) ? GetMangosString(LANG_ACTIVE) : ""; if (m_session) PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT, id, id, eventData.description.c_str(), active); @@ -4152,7 +4154,6 @@ bool ChatHandler::HandleEventListCommand(char* args) all = true; GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap(); - GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr.GetActiveEventList(); char const* active = GetMangosString(LANG_ACTIVE); char const* inactive = GetMangosString(LANG_FACTION_INACTIVE); @@ -4160,7 +4161,10 @@ bool ChatHandler::HandleEventListCommand(char* args) for (uint32 event_id = 0; event_id < events.size(); ++event_id) { - if (activeEvents.find(event_id) == activeEvents.end()) + if (!sGameEventMgr.IsValidEvent(event_id)) + continue; + + if (!sGameEventMgr.IsActiveEvent(event_id)) { if (!all) continue; @@ -4197,7 +4201,7 @@ bool ChatHandler::HandleEventInfoCommand(char* args) GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap(); - if (event_id >=events.size()) + if (!sGameEventMgr.IsValidEvent(event_id)) { SendSysMessage(LANG_EVENT_NOT_EXIST); SetSentErrorMessage(true); @@ -4205,16 +4209,8 @@ bool ChatHandler::HandleEventInfoCommand(char* args) } GameEventData const& eventData = events[event_id]; - if (!eventData.isValid()) - { - SendSysMessage(LANG_EVENT_NOT_EXIST); - SetSentErrorMessage(true); - return false; - } - GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr.GetActiveEventList(); - bool active = activeEvents.find(event_id) != activeEvents.end(); - char const* activeStr = active ? GetMangosString(LANG_ACTIVE) : ""; + char const* activeStr = sGameEventMgr.IsActiveEvent(event_id) ? GetMangosString(LANG_ACTIVE) : ""; std::string startTimeStr = TimeToTimestampStr(eventData.start); std::string endTimeStr = TimeToTimestampStr(eventData.end); @@ -4244,7 +4240,7 @@ bool ChatHandler::HandleEventStartCommand(char* args) GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap(); - if (event_id < 1 || event_id >= events.size()) + if (!sGameEventMgr.IsValidEvent(event_id)) { SendSysMessage(LANG_EVENT_NOT_EXIST); SetSentErrorMessage(true); @@ -4259,8 +4255,7 @@ bool ChatHandler::HandleEventStartCommand(char* args) return false; } - GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr.GetActiveEventList(); - if (activeEvents.find(event_id) != activeEvents.end()) + if (sGameEventMgr.IsActiveEvent(event_id)) { PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id); SetSentErrorMessage(true); @@ -4284,7 +4279,7 @@ bool ChatHandler::HandleEventStopCommand(char* args) GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap(); - if (event_id < 1 || event_id >= events.size()) + if (!sGameEventMgr.IsValidEvent(event_id)) { SendSysMessage(LANG_EVENT_NOT_EXIST); SetSentErrorMessage(true); @@ -4299,9 +4294,7 @@ bool ChatHandler::HandleEventStopCommand(char* args) return false; } - GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr.GetActiveEventList(); - - if (activeEvents.find(event_id) == activeEvents.end()) + if (!sGameEventMgr.IsActiveEvent(event_id)) { PSendSysMessage(LANG_EVENT_NOT_ACTIVE,event_id); SetSentErrorMessage(true); diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp index 1d070302b..615262ca7 100644 --- a/src/game/LootMgr.cpp +++ b/src/game/LootMgr.cpp @@ -125,6 +125,12 @@ void LootStore::LoadLootTable() continue; // error already printed to log/console. } + if (mincountOrRef < 0 && condition != CONDITION_NONE) + { + sLog.outErrorDb("Table '%s' entry %u mincountOrRef %i < 0 and not allowed has condition, skipped", + GetName(), entry, mincountOrRef); + continue; + } if(!PlayerCondition::IsValid(condition,cond_value1, cond_value2)) { diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index a09be4531..8cb47f60e 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -7632,7 +7632,7 @@ bool PlayerCondition::Meets(Player const * player) const } case CONDITION_NO_AURA: return !player->HasAura(value1, SpellEffectIndex(value2)); - case CONDITION_ACTIVE_EVENT: + case CONDITION_ACTIVE_GAME_EVENT: return sGameEventMgr.IsActiveEvent(value1); case CONDITION_AREA_FLAG: { @@ -7713,6 +7713,12 @@ bool PlayerCondition::Meets(Player const * player) const return player->HasItemCount(value1, value2, true); case CONDITION_NOITEM_WITH_BANK: return !player->HasItemCount(value1, value2, true); + case CONDITION_NOT_ACTIVE_GAME_EVENT: + return !sGameEventMgr.IsActiveEvent(value1); + case CONDITION_ACTIVE_HOLIDAY: + return sGameEventMgr.IsActiveHoliday(HolidayIds(value1)); + case CONDITION_NOT_ACTIVE_HOLIDAY: + return !sGameEventMgr.IsActiveHoliday(HolidayIds(value1)); default: return false; } @@ -7861,10 +7867,10 @@ bool PlayerCondition::IsValid(ConditionType condition, uint32 value1, uint32 val } break; } - case CONDITION_ACTIVE_EVENT: + case CONDITION_ACTIVE_GAME_EVENT: + case CONDITION_NOT_ACTIVE_GAME_EVENT: { - GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap(); - if (value1 >=events.size() || !events[value1].isValid()) + if (!sGameEventMgr.IsValidEvent(value1)) { sLog.outErrorDb("Active event (%u) condition requires existing event id (%u), skipped", condition, value1); return false; @@ -7961,6 +7967,16 @@ bool PlayerCondition::IsValid(ConditionType condition, uint32 value1, uint32 val break; } + case CONDITION_ACTIVE_HOLIDAY: + case CONDITION_NOT_ACTIVE_HOLIDAY: + { + if (!sHolidaysStore.LookupEntry(value1)) + { + sLog.outErrorDb("Active holiday (%u) condition requires existing holiday id (%u), skipped", condition, value1); + return false; + } + break; + } case CONDITION_NONE: break; } diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index c38ced70d..6efb2fd12 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -339,7 +339,7 @@ enum ConditionType CONDITION_QUESTTAKEN = 9, // quest_id 0, for condition true while quest active. CONDITION_AD_COMMISSION_AURA = 10, // 0 0, for condition true while one from AD commission aura active CONDITION_NO_AURA = 11, // spell_id effindex - CONDITION_ACTIVE_EVENT = 12, // event_id 0 + CONDITION_ACTIVE_GAME_EVENT = 12, // event_id 0 CONDITION_AREA_FLAG = 13, // area_flag area_flag_not CONDITION_RACE_CLASS = 14, // race_mask class_mask CONDITION_LEVEL = 15, // player_level 0, 1 or 2 (0: equal to, 1: equal or higher than, 2: equal or less than) @@ -352,9 +352,12 @@ enum ConditionType CONDITION_QUEST_NONE = 22, // quest_id 0 (quest did not take and not rewarded) CONDITION_ITEM_WITH_BANK = 23, // item_id count check present req. amount items in inventory or bank CONDITION_NOITEM_WITH_BANK = 24, // item_id count check not present req. amount items in inventory or bank + CONDITION_NOT_ACTIVE_GAME_EVENT = 25, // event_id 0 + CONDITION_ACTIVE_HOLIDAY = 26, // holiday_id 0 preferred use instead CONDITION_ACTIVE_GAME_EVENT when possible + CONDITION_NOT_ACTIVE_HOLIDAY = 27, // holiday_id 0 preferred use instead CONDITION_NOT_ACTIVE_GAME_EVENT when possible }; -#define MAX_CONDITION 25 // maximum value in ConditionType enum +#define MAX_CONDITION 28 // maximum value in ConditionType enum struct PlayerCondition { diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 1f58fece6..49625ce7a 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2451,6 +2451,14 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& { if (!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)) { + // General override, we don't want to use max spell range here. + // Note: 0.0 radius is also for index 36. It is possible that 36 must be defined as + // "at the base of", in difference to 0 which appear to be "directly in front of". + // TODO: some summoned will make caster be half inside summoned object. Need to fix + // that in the below code (nearpoint vs closepoint, etc). + if (m_spellInfo->EffectRadiusIndex[effIndex] == 0) + radius = 0.0f; + if (m_spellInfo->Id == 50019) // Hawk Hunting, problematic 50K radius radius = 10.0f; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b2f357b4f..3bd9e1bf5 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 "11075" + #define REVISION_NR "11077" #endif // __REVISION_NR_H__