[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:
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();

View file

@ -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()

View file

@ -210,14 +210,14 @@ void GameEventMgr::LoadFromDB()
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
@ -288,14 +288,14 @@ void GameEventMgr::LoadFromDB()
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
@ -378,9 +378,9 @@ void GameEventMgr::LoadFromDB()
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);
}

View file

@ -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);

View file

@ -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);

View file

@ -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))
{

View file

@ -7562,7 +7562,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:
{
@ -7643,6 +7643,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;
}
@ -7791,10 +7797,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;
@ -7891,6 +7897,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;
}

View file

@ -338,7 +338,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)
@ -351,9 +351,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
{

View file

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