[11077] Game event fixes and condition improvments.

* At game events table loading checked not only allowed event ids range but also event existance.
* Renamed CONDITION_ACTIVE_EVENT -> CONDITION_ACTIVE_GAME_EVENT
* Implemented new conditions:
   - CONDITION_NOT_ACTIVE_GAME_EVENT
   - CONDITION_ACTIVE_HOLIDAY
   - CONDITION_NOT_ACTIVE_HOLIDAY

Recomended use holiday version where possible as more portable.
This commit is contained in:
VladimirMangos 2011-01-28 23:29:04 +03:00
parent 84dd2e4393
commit 2fd536fe43
9 changed files with 90 additions and 62 deletions

View file

@ -319,7 +319,7 @@ bool AchievementCriteriaRequirement::Meets(uint32 criteria_id, Player const* sou
case ACHIEVEMENT_CRITERIA_REQUIRE_S_DRUNK: case ACHIEVEMENT_CRITERIA_REQUIRE_S_DRUNK:
return (uint32)Player::GetDrunkenstateByValue(source->GetDrunkValue()) >= drunk.state; return (uint32)Player::GetDrunkenstateByValue(source->GetDrunkValue()) >= drunk.state;
case ACHIEVEMENT_CRITERIA_REQUIRE_HOLIDAY: case ACHIEVEMENT_CRITERIA_REQUIRE_HOLIDAY:
return IsHolidayActive(HolidayIds(holiday.id)); return sGameEventMgr.IsActiveHoliday(HolidayIds(holiday.id));
case ACHIEVEMENT_CRITERIA_REQUIRE_BG_LOSS_TEAM_SCORE: case ACHIEVEMENT_CRITERIA_REQUIRE_BG_LOSS_TEAM_SCORE:
{ {
BattleGround* bg = source->GetBattleGround(); BattleGround* bg = source->GetBattleGround();

View file

@ -2079,7 +2079,7 @@ BattleGroundTypeId BattleGroundMgr::WeekendHolidayIdToBGType(HolidayIds holiday)
bool BattleGroundMgr::IsBGWeekend(BattleGroundTypeId bgTypeId) bool BattleGroundMgr::IsBGWeekend(BattleGroundTypeId bgTypeId)
{ {
return IsHolidayActive(BGTypeToWeekendHolidayId(bgTypeId)); return sGameEventMgr.IsActiveHoliday(BGTypeToWeekendHolidayId(bgTypeId));
} }
void BattleGroundMgr::LoadBattleEventIndexes() void BattleGroundMgr::LoadBattleEventIndexes()

View file

@ -130,7 +130,7 @@ void GameEventMgr::LoadFromDB()
bar.step(); bar.step();
uint16 event_id = fields[0].GetUInt16(); 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); sLog.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id);
continue; continue;
@ -206,18 +206,18 @@ void GameEventMgr::LoadFromDB()
if (event_id == 0) 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;
}
if (!IsValidEvent(std::abs(event_id)))
{
sLog.outErrorDb("`game_event_creature` game event id (%i) not exist in `game_event`", event_id);
continue; continue;
} }
int32 internal_event_id = mGameEvent.size() + event_id - 1; int32 internal_event_id = mGameEvent.size() + event_id - 1;
if(internal_event_id < 0 || (size_t)internal_event_id >= mGameEventCreatureGuids.size())
{
sLog.outErrorDb("`game_event_creature` game event id (%i) is out of range compared to max event id in `game_event`",event_id);
continue;
}
++count; ++count;
// spawn objects at event can be grouped in pools and then affected pools have stricter requirements for this case // 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) 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;
}
if (!IsValidEvent(std::abs(event_id)))
{
sLog.outErrorDb("`game_event_gameobject` game event id (%i) not exist in `game_event`", event_id);
continue; continue;
} }
int32 internal_event_id = mGameEvent.size() + event_id - 1; int32 internal_event_id = mGameEvent.size() + event_id - 1;
if(internal_event_id < 0 || (size_t)internal_event_id >= mGameEventGameobjectGuids.size())
{
sLog.outErrorDb("`game_event_gameobject` game event id (%i) is out of range compared to max event id in `game_event`",event_id);
continue;
}
++count; ++count;
// spawn objects at event can be grouped in pools and then affected pools have stricter requirements for this case // 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(); uint32 guid = fields[0].GetUInt32();
uint16 event_id = fields[1].GetUInt16(); 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; 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; continue;
} }
@ -452,9 +452,15 @@ void GameEventMgr::LoadFromDB()
uint32 quest = fields[0].GetUInt32(); uint32 quest = fields[0].GetUInt32();
uint16 event_id = fields[1].GetUInt16(); 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; continue;
} }
@ -517,14 +523,14 @@ void GameEventMgr::LoadFromDB()
continue; continue;
} }
int32 internal_event_id = mGameEvent.size() + event_id - 1; if (!IsValidEvent(event_id))
if (internal_event_id < 0 || (size_t)internal_event_id >= mGameEventMails.size())
{ {
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; continue;
} }
int32 internal_event_id = mGameEvent.size() + event_id - 1;
if (!(mail.raceMask & RACEMASK_ALL_PLAYABLE)) 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); 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; m_IsGameEventsInit = false;
} }
MANGOS_DLL_SPEC bool IsHolidayActive( HolidayIds id ) bool GameEventMgr::IsActiveHoliday( HolidayIds id )
{ {
if (id == HOLIDAY_NONE) if (id == HOLIDAY_NONE)
return false; return false;
GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap(); for(GameEventMgr::ActiveEvents::const_iterator itr = m_ActiveEvents.begin(); itr != m_ActiveEvents.end(); ++itr)
GameEventMgr::ActiveEvents const& ae = sGameEventMgr.GetActiveEventList(); if (mGameEvent[*itr].holiday_id == id)
for(GameEventMgr::ActiveEvents::const_iterator itr = ae.begin(); itr != ae.end(); ++itr)
if (events[*itr].holiday_id == id)
return true; return true;
return false; return false;
} }
MANGOS_DLL_SPEC bool IsHolidayActive( HolidayIds id )
{
return sGameEventMgr.IsActiveHoliday(id);
}

View file

@ -78,7 +78,9 @@ class GameEventMgr
uint32 NextCheck(uint16 entry) const; uint32 NextCheck(uint16 entry) const;
void LoadFromDB(); void LoadFromDB();
uint32 Update(ActiveEvents const* activeAtShutdown = NULL); 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 IsActiveEvent(uint16 event_id) const { return ( m_ActiveEvents.find(event_id)!=m_ActiveEvents.end()); }
bool IsActiveHoliday(HolidayIds id);
uint32 Initialize(); uint32 Initialize();
void StartEvent(uint16 event_id, bool overwrite = false, bool resume = false); void StartEvent(uint16 event_id, bool overwrite = false, bool resume = false);
void StopEvent(uint16 event_id, bool overwrite = false); void StopEvent(uint16 event_id, bool overwrite = false);

View file

@ -4114,10 +4114,12 @@ bool ChatHandler::HandleLookupEventCommand(char* args)
uint32 counter = 0; uint32 counter = 0;
GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap(); 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]; GameEventData const& eventData = events[id];
std::string descr = eventData.description; std::string descr = eventData.description;
@ -4126,7 +4128,7 @@ bool ChatHandler::HandleLookupEventCommand(char* args)
if (Utf8FitTo(descr, wnamepart)) 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) if (m_session)
PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT, id, id, eventData.description.c_str(), active); PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT, id, id, eventData.description.c_str(), active);
@ -4152,7 +4154,6 @@ bool ChatHandler::HandleEventListCommand(char* args)
all = true; all = true;
GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap(); GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap();
GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr.GetActiveEventList();
char const* active = GetMangosString(LANG_ACTIVE); char const* active = GetMangosString(LANG_ACTIVE);
char const* inactive = GetMangosString(LANG_FACTION_INACTIVE); 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) 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) if (!all)
continue; continue;
@ -4197,7 +4201,7 @@ bool ChatHandler::HandleEventInfoCommand(char* args)
GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap(); GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap();
if (event_id >=events.size()) if (!sGameEventMgr.IsValidEvent(event_id))
{ {
SendSysMessage(LANG_EVENT_NOT_EXIST); SendSysMessage(LANG_EVENT_NOT_EXIST);
SetSentErrorMessage(true); SetSentErrorMessage(true);
@ -4205,16 +4209,8 @@ bool ChatHandler::HandleEventInfoCommand(char* args)
} }
GameEventData const& eventData = events[event_id]; GameEventData const& eventData = events[event_id];
if (!eventData.isValid())
{
SendSysMessage(LANG_EVENT_NOT_EXIST);
SetSentErrorMessage(true);
return false;
}
GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr.GetActiveEventList(); char const* activeStr = sGameEventMgr.IsActiveEvent(event_id) ? GetMangosString(LANG_ACTIVE) : "";
bool active = activeEvents.find(event_id) != activeEvents.end();
char const* activeStr = active ? GetMangosString(LANG_ACTIVE) : "";
std::string startTimeStr = TimeToTimestampStr(eventData.start); std::string startTimeStr = TimeToTimestampStr(eventData.start);
std::string endTimeStr = TimeToTimestampStr(eventData.end); std::string endTimeStr = TimeToTimestampStr(eventData.end);
@ -4244,7 +4240,7 @@ bool ChatHandler::HandleEventStartCommand(char* args)
GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap(); GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap();
if (event_id < 1 || event_id >= events.size()) if (!sGameEventMgr.IsValidEvent(event_id))
{ {
SendSysMessage(LANG_EVENT_NOT_EXIST); SendSysMessage(LANG_EVENT_NOT_EXIST);
SetSentErrorMessage(true); SetSentErrorMessage(true);
@ -4259,8 +4255,7 @@ bool ChatHandler::HandleEventStartCommand(char* args)
return false; return false;
} }
GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr.GetActiveEventList(); if (sGameEventMgr.IsActiveEvent(event_id))
if (activeEvents.find(event_id) != activeEvents.end())
{ {
PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id); PSendSysMessage(LANG_EVENT_ALREADY_ACTIVE,event_id);
SetSentErrorMessage(true); SetSentErrorMessage(true);
@ -4284,7 +4279,7 @@ bool ChatHandler::HandleEventStopCommand(char* args)
GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap(); GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap();
if (event_id < 1 || event_id >= events.size()) if (!sGameEventMgr.IsValidEvent(event_id))
{ {
SendSysMessage(LANG_EVENT_NOT_EXIST); SendSysMessage(LANG_EVENT_NOT_EXIST);
SetSentErrorMessage(true); SetSentErrorMessage(true);
@ -4299,9 +4294,7 @@ bool ChatHandler::HandleEventStopCommand(char* args)
return false; return false;
} }
GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr.GetActiveEventList(); if (!sGameEventMgr.IsActiveEvent(event_id))
if (activeEvents.find(event_id) == activeEvents.end())
{ {
PSendSysMessage(LANG_EVENT_NOT_ACTIVE,event_id); PSendSysMessage(LANG_EVENT_NOT_ACTIVE,event_id);
SetSentErrorMessage(true); SetSentErrorMessage(true);

View file

@ -125,6 +125,12 @@ void LootStore::LoadLootTable()
continue; // error already printed to log/console. 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)) if(!PlayerCondition::IsValid(condition,cond_value1, cond_value2))
{ {

View file

@ -7562,7 +7562,7 @@ bool PlayerCondition::Meets(Player const * player) const
} }
case CONDITION_NO_AURA: case CONDITION_NO_AURA:
return !player->HasAura(value1, SpellEffectIndex(value2)); return !player->HasAura(value1, SpellEffectIndex(value2));
case CONDITION_ACTIVE_EVENT: case CONDITION_ACTIVE_GAME_EVENT:
return sGameEventMgr.IsActiveEvent(value1); return sGameEventMgr.IsActiveEvent(value1);
case CONDITION_AREA_FLAG: case CONDITION_AREA_FLAG:
{ {
@ -7643,6 +7643,12 @@ bool PlayerCondition::Meets(Player const * player) const
return player->HasItemCount(value1, value2, true); return player->HasItemCount(value1, value2, true);
case CONDITION_NOITEM_WITH_BANK: case CONDITION_NOITEM_WITH_BANK:
return !player->HasItemCount(value1, value2, true); 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: default:
return false; return false;
} }
@ -7791,10 +7797,10 @@ bool PlayerCondition::IsValid(ConditionType condition, uint32 value1, uint32 val
} }
break; break;
} }
case CONDITION_ACTIVE_EVENT: case CONDITION_ACTIVE_GAME_EVENT:
case CONDITION_NOT_ACTIVE_GAME_EVENT:
{ {
GameEventMgr::GameEventDataMap const& events = sGameEventMgr.GetEventMap(); if (!sGameEventMgr.IsValidEvent(value1))
if (value1 >=events.size() || !events[value1].isValid())
{ {
sLog.outErrorDb("Active event (%u) condition requires existing event id (%u), skipped", condition, value1); sLog.outErrorDb("Active event (%u) condition requires existing event id (%u), skipped", condition, value1);
return false; return false;
@ -7891,6 +7897,16 @@ bool PlayerCondition::IsValid(ConditionType condition, uint32 value1, uint32 val
break; 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: case CONDITION_NONE:
break; break;
} }

View file

@ -338,7 +338,7 @@ enum ConditionType
CONDITION_QUESTTAKEN = 9, // quest_id 0, for condition true while quest active. 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_AD_COMMISSION_AURA = 10, // 0 0, for condition true while one from AD commission aura active
CONDITION_NO_AURA = 11, // spell_id effindex 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_AREA_FLAG = 13, // area_flag area_flag_not
CONDITION_RACE_CLASS = 14, // race_mask class_mask 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) CONDITION_LEVEL = 15, // player_level 0, 1 or 2 (0: equal to, 1: equal or higher than, 2: equal or less than)
@ -351,9 +351,12 @@ enum ConditionType
CONDITION_QUEST_NONE = 22, // quest_id 0 (quest did not take and not rewarded) 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_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_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 struct PlayerCondition
{ {

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "11076" #define REVISION_NR "11077"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__