diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index ff16605..b12f3c9 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -509,9 +509,10 @@ void BattleGround::Update(uint32 diff) if(GetStatus() == STATUS_WAIT_LEAVE) { // remove all players from battleground after 2 minutes - m_EndTime += diff; - if(m_EndTime >= TIME_TO_AUTOREMOVE) // 2 minutes + m_EndTime -= diff; + if( m_EndTime <= 0) { + m_EndTime = 0; BattleGroundPlayerMap::iterator itr, next; for(itr = m_Players.begin(); itr != m_Players.end(); itr = next) { @@ -524,6 +525,8 @@ void BattleGround::Update(uint32 diff) } } + //update start time + m_StartTime += diff; } void BattleGround::SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O) @@ -714,7 +717,8 @@ void BattleGround::EndBattleGround(uint32 winner) } SetStatus(STATUS_WAIT_LEAVE); - m_EndTime = 0; + //we must set it this way, because end time is sent in packet! + m_EndTime = TIME_TO_AUTOREMOVE; // arena rating calculation if(isArena() && isRated()) @@ -803,7 +807,7 @@ void BattleGround::EndBattleGround(uint32 winner) plr->GetSession()->SendPacket(&data); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType()); - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime()); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType()); plr->GetSession()->SendPacket(&data); plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1); } @@ -1037,7 +1041,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac if(SendPacket) { WorldPacket data; - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_NONE, 0, 0); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_NONE, 0, 0, 0); plr->GetSession()->SendPacket(&data); } @@ -1717,7 +1721,7 @@ void BattleGround::EndNow() { RemoveFromBGFreeSlotQueue(); SetStatus(STATUS_WAIT_LEAVE); - SetEndTime(TIME_TO_AUTOREMOVE); + SetEndTime(0); // inform invited players about the removal sBattleGroundMgr.m_BattleGroundQueues[BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this); } @@ -1791,6 +1795,14 @@ void BattleGround::HandleKillPlayer( Player *player, Player *killer ) player->SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE ); } +void BattleGround::SetHoliday(bool is_holiday) +{ + if(is_holiday) + m_HonorMode = BG_HOLIDAY; + else + m_HonorMode = BG_NORMAL; +} + int32 BattleGround::GetObjectType(uint64 guid) { for(uint32 i = 0;i <= m_BgObjects.size(); i++) @@ -1836,7 +1848,7 @@ void BattleGround::PlayerAddedToBGCheckIfBGIsRunning(Player* plr) sBattleGroundMgr.BuildPvpLogDataPacket(&data, this); plr->GetSession()->SendPacket(&data); - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime()); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType()); plr->GetSession()->SendPacket(&data); } diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h index 3c09db2..c1408b4 100644 --- a/src/game/BattleGround.h +++ b/src/game/BattleGround.h @@ -260,6 +260,12 @@ class BattleGroundScore uint32 HealingDone; }; +enum BGHonorMode +{ + BG_NORMAL = 0, + BG_HOLIDAY, + BG_HONOR_MODE_NUM +}; /* This class is used to: 1. Add player to battleground @@ -473,6 +479,7 @@ class BattleGround virtual void OnObjectCreate(GameObject* /*Creature*/) {} void HandleTriggerBuff(uint64 const& go_guid); + void SetHoliday(bool is_holiday); // TODO: make this protected: typedef std::vector BGObjects; @@ -527,6 +534,7 @@ class BattleGround bool m_BuffChange; + BGHonorMode m_HonorMode; private: /* Battleground */ BattleGroundTypeId m_TypeID; @@ -534,7 +542,7 @@ class BattleGround BattleGroundStatus m_Status; uint32 m_ClientInstanceID; //the instance-id which is sent to the client and without any other internal use uint32 m_StartTime; - uint32 m_EndTime; + int32 m_EndTime; // it is set to 120000 when bg is ending and it decreases itself uint32 m_LastResurrectTime; BGQueueIdBasedOnLevel m_QueueId; uint8 m_ArenaType; // 2=2v2, 3=3v3, 5=5v5 diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp index dee75a9..fceb9c0 100644 --- a/src/game/BattleGroundHandler.cpp +++ b/src/game/BattleGroundHandler.cpp @@ -173,7 +173,7 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data ) WorldPacket data; // send status packet (in queue) - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType); member->GetSession()->SendPacket(&data); sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId); member->GetSession()->SendPacket(&data); @@ -191,7 +191,7 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data ) WorldPacket data; // send status packet (in queue) - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType); SendPacket(&data); sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo); @@ -433,7 +433,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data ) //TODO FIX ME this call must be removed! _player->RemoveFromGroup(); - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime()); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType()); _player->GetSession()->SendPacket(&data); // remove battleground queue status from BGmgr sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(_player->GetGUID(), false); @@ -465,7 +465,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data ) } } _player->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, arenaType); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0); sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(_player->GetGUID(), true); // player left queue, we should update it - do not update Arena Queue if( !arenaType ) @@ -510,40 +510,55 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ ) sLog.outDebug( "WORLD: Battleground status" ); WorldPacket data; - uint32 queueSlot = PLAYER_MAX_BATTLEGROUND_QUEUES; - - if(_player->InBattleGround()) - { - BattleGround *bg = _player->GetBattleGround(); - if(!bg) - return; - BattleGroundQueueTypeId bgQueueTypeId_tmp = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType()); - queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId_tmp); - if((bg->GetStatus() <= STATUS_IN_PROGRESS)) - { - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime()); - SendPacket(&data); - } - } - // we should update all queues? .. i'm not sure if this code is correct - for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++) + // we must update all queues here + BattleGround *bg = NULL; + for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++) { BattleGroundQueueTypeId bgQueueTypeId = _player->GetBattleGroundQueueTypeId(i); - if(!bgQueueTypeId || i == queueSlot) //queueslot check in case we already send it in the above code + if( !bgQueueTypeId ) continue; BattleGroundTypeId bgTypeId = BattleGroundMgr::BGTemplateId(bgQueueTypeId); - uint8 arenatype = BattleGroundMgr::BGArenaType(bgQueueTypeId); - BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId); - if(!bg) - continue; + uint8 arenaType = BattleGroundMgr::BGArenaType(bgQueueTypeId); + if( bgTypeId == _player->GetBattleGroundTypeId() ) + { + bg = _player->GetBattleGround(); + //i cannot check any variable from player class because player class doesn't know if player is in 2v2 / 3v3 or 5v5 arena + //so i must use bg pointer to get that information + if( bg && bg->GetArenaType() == arenaType ) + { + // this line is checked, i only don't know if GetStartTime is changing itself after bg end! + // send status in BattleGround + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType); + SendPacket(&data); + continue; + } + } + //we are sending update to player about queue - he can be invited there! + //get GroupQueueInfo for queue status BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers; BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID()); - if(itrPlayerStatus == qpMap.end() || !itrPlayerStatus->second.GroupInfo) + if( itrPlayerStatus == qpMap.end() ) continue; - arenatype = itrPlayerStatus->second.GroupInfo->ArenaType; - uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(itrPlayerStatus->second.GroupInfo, _player->GetBattleGroundQueueIdFromLevel(bgTypeId)); - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTime()-itrPlayerStatus->second.GroupInfo->JoinTime, arenatype); - SendPacket(&data); + if( itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID ) + { + bg = sBattleGroundMgr.GetBattleGround(itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID, bgTypeId); + if( !bg ) + continue; + uint32 remainingTime = getMSTimeDiff(getMSTime(), itrPlayerStatus->second.GroupInfo->RemoveInviteTime); + // send status invited to BattleGround + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, arenaType); + SendPacket(&data); + } + else + { + BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId); + if( !bg ) + continue; + uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(itrPlayerStatus->second.GroupInfo, _player->GetBattleGroundQueueIdFromLevel(bgTypeId)); + // send status in BattleGround Queue + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(itrPlayerStatus->second.GroupInfo->JoinTime, getMSTime()), arenaType); + SendPacket(&data); + } } } diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index d7c56d7..bfe4321 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -159,7 +159,8 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId ginfo->ArenaTeamId = arenateamid; ginfo->IsRated = isRated; ginfo->IsInvitedToBGInstanceGUID = 0; - ginfo->JoinTime = sWorld.GetGameTime() * IN_MILISECONDS; + ginfo->JoinTime = getMSTime(); + ginfo->RemoveInviteTime = 0; ginfo->Team = leader->GetTeam(); ginfo->ArenaTeamRating = arenaRating; ginfo->OpponentsTeamRating = 0; @@ -194,7 +195,7 @@ void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo) void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id) { - uint32 timeInQueue = (sWorld.GetGameTime() * IN_MILISECONDS) - ginfo->JoinTime; + uint32 timeInQueue = getMSTimeDiff(ginfo->JoinTime, getMSTime()); uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas! if( !ginfo->ArenaType ) { @@ -353,7 +354,7 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou plr2->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to // queue->removeplayer, it causes bugs WorldPacket data; - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0); plr2->GetSession()->SendPacket(&data); } // then actually delete, this may delete the group as well! @@ -442,6 +443,7 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b // invite the player PlayerInvitedToBGUpdateAverageWaitTime(ginfo, queue_id); + ginfo->RemoveInviteTime = getMSTime() + INVITE_ACCEPT_WAIT_TIME; sBattleGroundMgr.InvitePlayer(plr, bg->GetInstanceID(), bg->GetTypeID(), ginfo->Team); WorldPacket data; @@ -451,7 +453,7 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b sLog.outDebug("Battleground: invited plr %s (%u) to BG instance %u queueindex %u bgtype %u, I can't help it if they don't press the enter battle button.",plr->GetName(),plr->GetGUIDLow(),bg->GetInstanceID(),queueSlot,bg->GetTypeID()); // send status packet - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0, ginfo->ArenaType); plr->GetSession()->SendPacket(&data); } return true; @@ -508,7 +510,7 @@ void BattleGroundQueue::BGEndedRemoveInvites(BattleGround *bg) // remove player from queue, this might delete the ginfo as well! don't use that pointer after this! RemovePlayer(itr2->first, true); WorldPacket data; - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0); plr->GetSession()->SendPacket(&data); } } @@ -1067,7 +1069,8 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) if (qItr != qpMap.end() && qItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID) { WorldPacket data; - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITATION_REMIND_TIME, 0); + //here must be remaining time + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, 0, qItr->second.GroupInfo->ArenaType); plr->GetSession()->SendPacket(&data); } } @@ -1106,7 +1109,7 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(m_PlayerGuid, true); sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bg->GetTypeID(), bg->GetQueueId()); WorldPacket data; - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0); plr->GetSession()->SendPacket(&data); } } @@ -1226,7 +1229,7 @@ void BattleGroundMgr::Update(uint32 diff) } } -void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint32 arenatype) +void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype) { // we can be in 3 queues in same time... if(StatusID == 0) @@ -1240,11 +1243,11 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro data->Initialize(SMSG_BATTLEFIELD_STATUS, (4+1+1+4+2+4+1+4+4+4)); *data << uint32(QueueSlot); // queue id (0...2) - player can be in 3 queues in time // uint64 in client - *data << uint64( uint64(arenatype ? arenatype : bg->GetArenaType()) | (uint64(0x0D) << 8) | (uint64(bg->GetTypeID()) << 16) | (uint64(0x1F90) << 48) ); + *data << uint64( uint64(arenatype) | (uint64(0x0D) << 8) | (uint64(bg->GetTypeID()) << 16) | (uint64(0x1F90) << 48) ); *data << uint32(bg->GetClientInstanceID()); // alliance/horde for BG and skirmish/rated for Arenas // following displays the minimap-icon 0 = faction icon 1 = arenaicon - *data << uint8(bg->isArena()); + *data << uint8(bg->isRated()); /* *data << uint8(arenatype ? arenatype : bg->GetArenaType()); // team type (0=BG, 2=2x2, 3=3x3, 5=5x5), for arenas // NOT PROPER VALUE IF ARENA ISN'T RUNNING YET!!!! switch(bg->GetTypeID()) // value depends on bg id { @@ -1301,7 +1304,7 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro { case STATUS_WAIT_QUEUE: // status_in_queue *data << uint32(Time1); // average wait time, milliseconds - *data << uint32(Time2); // time in queue, updated every minute? + *data << uint32(Time2); // time in queue, updated every minute!, milliseconds break; case STATUS_WAIT_JOIN: // status_invite *data << uint32(bg->GetMapId()); // map id @@ -1309,7 +1312,7 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro break; case STATUS_IN_PROGRESS: // status_in_progress *data << uint32(bg->GetMapId()); // map id - *data << uint32(Time1); // 0 at bg start, 120000 after bg end, time to bg auto leave, milliseconds + *data << uint32(Time1); // time to bg auto leave, 0 at bg start, 120000 after bg end, milliseconds *data << uint32(Time2); // time from bg start, milliseconds *data << uint8(0x1); // unk sometimes 0x0! break; @@ -2040,6 +2043,17 @@ void BattleGroundMgr::ToggleTesting() sWorld.SendWorldText(LANG_DEBUG_BG_OFF); } +void BattleGroundMgr::SetHolidayWeekends(uint32 mask) +{ + for(uint32 bgtype = 1; bgtype < MAX_BATTLEGROUND_TYPE_ID; ++bgtype) + { + if(BattleGround * bg = GetBattleGroundTemplate(BattleGroundTypeId(bgtype))) + { + bg->SetHoliday(mask & (1 << bgtype)); + } + } +} + void BattleGroundMgr::ToggleArenaTesting() { m_ArenaTesting = !m_ArenaTesting; diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h index 6e6dd31..b3db04d 100644 --- a/src/game/BattleGroundMgr.h +++ b/src/game/BattleGroundMgr.h @@ -48,6 +48,7 @@ struct GroupQueueInfo // stores informatio uint8 ArenaType; // 2v2, 3v3, 5v5 or 0 when BG uint32 ArenaTeamId; // team id if rated match uint32 JoinTime; // time when group was added + uint32 RemoveInviteTime; // time when we will remove invite for players in group uint32 IsInvitedToBGInstanceGUID; // was invited to certain BG uint32 ArenaTeamRating; // if rated match, inited to the rating of the team uint32 OpponentsTeamRating; // for rated arena matches @@ -184,7 +185,7 @@ class BattleGroundMgr void BuildGroupJoinedBattlegroundPacket(WorldPacket *data, BattleGroundTypeId bgTypeId); void BuildUpdateWorldStatePacket(WorldPacket *data, uint32 field, uint32 value); void BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg); - void BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint32 arenatype = 0); + void BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype); void BuildPlaySoundPacket(WorldPacket *data, uint32 soundid); void SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, const uint64& guid); @@ -225,6 +226,7 @@ class BattleGroundMgr void ToggleArenaTesting(); void ToggleTesting(); + void SetHolidayWeekends(uint32 mask); void LoadBattleMastersEntry(); BattleGroundTypeId GetBattleMasterBG(uint32 entry) const { diff --git a/src/game/GameEventMgr.cpp b/src/game/GameEventMgr.cpp index bf8fc41..3efeb18 100644 --- a/src/game/GameEventMgr.cpp +++ b/src/game/GameEventMgr.cpp @@ -27,6 +27,7 @@ #include "Policies/SingletonImp.h" #include "GossipDef.h" #include "Player.h" +#include "BattleGroundMgr.h" INSTANTIATE_SINGLETON_1(GameEventMgr); @@ -211,34 +212,34 @@ void GameEventMgr::LoadFromDB() continue; } + GameEventData& pGameEvent = mGameEvent[event_id]; + uint64 starttime = fields[1].GetUInt64(); + pGameEvent.start = time_t(starttime); + uint64 endtime = fields[2].GetUInt64(); + pGameEvent.end = time_t(endtime); + pGameEvent.occurence = fields[3].GetUInt32(); + pGameEvent.length = fields[4].GetUInt32(); + pGameEvent.holiday_id = fields[5].GetUInt32(); - GameEventData& pGameEvent = mGameEvent[event_id]; - uint64 starttime = fields[1].GetUInt64(); - pGameEvent.start = time_t(starttime); - uint64 endtime = fields[2].GetUInt64(); - pGameEvent.end = time_t(endtime); - pGameEvent.occurence = fields[3].GetUInt32(); - pGameEvent.length = fields[4].GetUInt32(); - pGameEvent.holiday_id = fields[5].GetUInt32(); - pGameEvent.state = (GameEventState)(fields[7].GetUInt8()); - pGameEvent.nextstart = 0; + pGameEvent.state = (GameEventState)(fields[7].GetUInt8()); + pGameEvent.nextstart = 0; - if(pGameEvent.length==0 && !pGameEvent.state) // length>0 and not world_event is validity check - { - sLog.outErrorDb("`game_event` game event id (%i) have length 0 and can't be used.",event_id); - continue; - } + if(pGameEvent.length==0 && pGameEvent.state == GAMEEVENT_NORMAL) // length>0 is validity check + { + sLog.outErrorDb("`game_event` game event id (%i) isn't a world event and has length = 0, thus it can't be used.",event_id); + continue; + } - if(pGameEvent.holiday_id) - { - if(!sHolidaysStore.LookupEntry(pGameEvent.holiday_id)) + if(pGameEvent.holiday_id) { - sLog.outErrorDb("`game_event` game event id (%i) have not existed holiday id %u.",event_id,pGameEvent.holiday_id); - pGameEvent.holiday_id = 0; + if(!sHolidaysStore.LookupEntry(pGameEvent.holiday_id)) + { + sLog.outErrorDb("`game_event` game event id (%i) have not existed holiday id %u.",event_id,pGameEvent.holiday_id); + pGameEvent.holiday_id = 0; + } } - } - - pGameEvent.description = fields[5].GetCppString(); + + pGameEvent.description = fields[6].GetCppString(); } while( result->NextRow() ); delete result; @@ -248,7 +249,7 @@ void GameEventMgr::LoadFromDB() } // load game event saves - // 0 1 2 + // 0 1 2 result = CharacterDatabase.Query("SELECT event_id, state, UNIX_TIMESTAMP(next_start) FROM game_event_save"); count = 0; @@ -278,7 +279,7 @@ void GameEventMgr::LoadFromDB() continue; } - if(mGameEvent[event_id].state != GAMEEVENT_NORMAL) + if(mGameEvent[event_id].state != GAMEEVENT_NORMAL) { mGameEvent[event_id].state = (GameEventState)(fields[1].GetUInt8()); mGameEvent[event_id].nextstart = time_t(fields[2].GetUInt64()); @@ -539,60 +540,9 @@ void GameEventMgr::LoadFromDB() questlist.push_back(QuestRelation(id, quest)); } while( result->NextRow() ); - delete result; - sLog.outString(); sLog.outString( ">> Loaded %u quests additions in game events", count ); - } - mGameEventPoolIds.resize(mGameEvent.size()*2-1); - // 1 2 - result = WorldDatabase.Query("SELECT pool_template.entry, game_event_pool.event " - "FROM pool_template JOIN game_event_pool ON pool_template.entry = game_event_pool.pool_entry"); - - count = 0; - if( !result ) - { - barGoLink bar2(1); - bar2.step(); - - sLog.outString(); - sLog.outString(">> Loaded %u pools in game events", count ); - } - else - { - - barGoLink bar2( result->GetRowCount() ); - do - { - Field *fields = result->Fetch(); - - bar2.step(); - - uint32 entry = fields[0].GetUInt16(); - int16 event_id = fields[1].GetInt16(); - - int32 internal_event_id = mGameEvent.size() + event_id - 1; - - if(internal_event_id < 0 || internal_event_id >= mGameEventPoolIds.size()) - { - sLog.outErrorDb("`game_event_pool` game event id (%i) is out of range compared to max event id in `game_event`",event_id); - continue; - } - - if (!poolhandler.CheckPool(entry)) - { - sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", entry); - continue; - } - - ++count; - IdList& poollist = mGameEventPoolIds[internal_event_id]; - poollist.push_back(entry); - - } while( result->NextRow() ); - sLog.outString(); - sLog.outString( ">> Loaded %u pools in game events", count ); delete result; } @@ -633,10 +583,10 @@ void GameEventMgr::LoadFromDB() questlist.push_back(QuestRelation(id, quest)); } while( result->NextRow() ); + delete result; + sLog.outString(); sLog.outString( ">> Loaded %u quests additions in game events", count ); - - delete result; } // Load quest to (event,condition) mapping @@ -685,7 +635,7 @@ void GameEventMgr::LoadFromDB() } // load conditions of the events - // 0 1 2 3 4 + // 0 1 2 3 4 result = WorldDatabase.Query("SELECT event_id, condition_id, req_num, max_world_state_field, done_world_state_field FROM game_event_condition"); count = 0; @@ -730,7 +680,7 @@ void GameEventMgr::LoadFromDB() } // load condition saves - // 0 1 2 + // 0 1 2 result = CharacterDatabase.Query("SELECT event_id, condition_id, done FROM game_event_condition_save"); count = 0; @@ -824,6 +774,74 @@ void GameEventMgr::LoadFromDB() delete result; } + mGameEventVendors.resize(mGameEvent.size()); + // 0 1 2 3 4 5 + result = WorldDatabase.Query("SELECT event, guid, item, maxcount, incrtime, ExtendedCost FROM game_event_npc_vendor"); + + count = 0; + if( !result ) + { + barGoLink bar3(1); + bar3.step(); + + sLog.outString(); + sLog.outString(">> Loaded %u vendor additions in game events", count ); + } + else + { + + barGoLink bar3( result->GetRowCount() ); + do + { + Field *fields = result->Fetch(); + + bar3.step(); + uint16 event_id = fields[0].GetUInt16(); + + if(event_id >= mGameEventVendors.size()) + { + sLog.outErrorDb("`game_event_npc_vendor` game event id (%u) is out of range compared to max event id in `game_event`",event_id); + continue; + } + + NPCVendorList& vendors = mGameEventVendors[event_id]; + NPCVendorEntry newEntry; + uint32 guid = fields[1].GetUInt32(); + newEntry.item = fields[2].GetUInt32(); + newEntry.maxcount = fields[3].GetUInt32(); + newEntry.incrtime = fields[4].GetUInt32(); + newEntry.ExtendedCost = fields[5].GetUInt32(); + // get the event npc flag for checking if the npc will be vendor during the event or not + uint32 event_npc_flag = 0; + NPCFlagList& flist = mGameEventNPCFlags[event_id]; + for(NPCFlagList::const_iterator itr = flist.begin(); itr != flist.end(); ++itr) + { + if(itr->first == guid) + { + event_npc_flag = itr->second; + break; + } + } + // get creature entry + newEntry.entry = 0; + + if( CreatureData const* data = objmgr.GetCreatureData(guid) ) + newEntry.entry = data->id; + + // check validity with event's npcflag + if(!objmgr.IsVendorItemValid(newEntry.entry, newEntry.item, newEntry.maxcount, newEntry.incrtime, newEntry.ExtendedCost, NULL, NULL, event_npc_flag)) + continue; + + ++count; + vendors.push_back(newEntry); + + } while( result->NextRow() ); + sLog.outString(); + sLog.outString( ">> Loaded %u vendor additions in game events", count ); + + delete result; + } + // load game event npc gossip ids // 0 1 2 result = WorldDatabase.Query("SELECT guid, event_id, textid FROM game_event_npc_gossip"); @@ -866,6 +884,105 @@ void GameEventMgr::LoadFromDB() delete result; } + + // set all flags to 0 + mGameEventBattleGroundHolidays.resize(mGameEvent.size(),0); + // load game event battleground flags + // 0 1 + result = WorldDatabase.Query("SELECT event, bgflag FROM game_event_battleground_holiday"); + + count = 0; + if( !result ) + { + barGoLink bar3(1); + bar3.step(); + + sLog.outString(); + sLog.outString(">> Loaded %u battleground holidays in game events", count ); + } + else + { + + barGoLink bar3( result->GetRowCount() ); + do + { + Field *fields = result->Fetch(); + + bar3.step(); + + uint16 event_id = fields[0].GetUInt16(); + + if(event_id >= mGameEvent.size()) + { + sLog.outErrorDb("`game_event_battleground_holiday` game event id (%u) is out of range compared to max event id in `game_event`",event_id); + continue; + } + + ++count; + + mGameEventBattleGroundHolidays[event_id] = fields[1].GetUInt32(); + + } while( result->NextRow() ); + sLog.outString(); + sLog.outString( ">> Loaded %u battleground holidays in game events", count ); + + delete result; + } + + //////////////////////// + // GameEventPool + //////////////////////// + + mGameEventPoolIds.resize(mGameEvent.size()*2-1); + // 1 2 + result = WorldDatabase.Query("SELECT pool_template.entry, game_event_pool.event " + "FROM pool_template JOIN game_event_pool ON pool_template.entry = game_event_pool.pool_entry"); + + count = 0; + if( !result ) + { + barGoLink bar2(1); + bar2.step(); + + sLog.outString(); + sLog.outString(">> Loaded %u pools in game events", count ); + } + else + { + + barGoLink bar2( result->GetRowCount() ); + do + { + Field *fields = result->Fetch(); + + bar2.step(); + + uint32 entry = fields[0].GetUInt16(); + int16 event_id = fields[1].GetInt16(); + + int32 internal_event_id = mGameEvent.size() + event_id - 1; + + if(internal_event_id < 0 || internal_event_id >= mGameEventPoolIds.size()) + { + sLog.outErrorDb("`game_event_pool` game event id (%i) is out of range compared to max event id in `game_event`",event_id); + continue; + } + + if (!poolhandler.CheckPool(entry)) + { + sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", entry); + continue; + } + + ++count; + IdList& poollist = mGameEventPoolIds[internal_event_id]; + poollist.push_back(entry); + + } while( result->NextRow() ); + sLog.outString(); + sLog.outString( ">> Loaded %u pools in game events", count ); + delete result; + } } uint32 GameEventMgr::GetNPCFlag(Creature * cr) @@ -909,8 +1026,7 @@ uint32 GameEventMgr::Update() // return the next e uint32 nextEventDelay = max_ge_check_delay; // 1 day uint32 calcDelay; std::set activate, deactivate; - - for (uint16 itr = 1; itr < mGameEvent.size(); ++itr) + for (uint16 itr = 1; itr < mGameEvent.size(); ++itr) { // must do the activating first, and after that the deactivating // so first queue it @@ -970,7 +1086,7 @@ uint32 GameEventMgr::Update() // return the next e nextEventDelay = 0; for(std::set::iterator itr = deactivate.begin(); itr != deactivate.end(); ++itr) StopEvent(*itr); - sLog.outBasic("Next game event check in %u seconds.", nextEventDelay + 1); + sLog.outDetail("Next game event check in %u seconds.", nextEventDelay + 1); return (nextEventDelay + 1) * IN_MILISECONDS; // Add 1 second to be sure event has started/stopped at next call } @@ -988,6 +1104,10 @@ void GameEventMgr::UnApplyEvent(uint16 event_id) UpdateEventQuests(event_id, false); // update npcflags in this event UpdateEventNPCFlags(event_id); + // remove vendor items + UpdateEventNPCVendor(event_id, false); + // update bg holiday + UpdateBattleGroundSettings(); } void GameEventMgr::ApplyNewEvent(uint16 event_id) @@ -1002,6 +1122,7 @@ void GameEventMgr::ApplyNewEvent(uint16 event_id) } sLog.outString("GameEvent %u \"%s\" started.", event_id, mGameEvent[event_id].description.c_str()); + // spawn positive event tagget objects GameEventSpawn(event_id); // un-spawn negative event tagged objects @@ -1013,6 +1134,10 @@ void GameEventMgr::ApplyNewEvent(uint16 event_id) UpdateEventQuests(event_id, true); // update npcflags in this event UpdateEventNPCFlags(event_id); + // add vendor items + UpdateEventNPCVendor(event_id, true); + // update bg holiday + UpdateBattleGroundSettings(); } void GameEventMgr::UpdateEventNPCFlags(uint16 event_id) @@ -1041,6 +1166,25 @@ void GameEventMgr::UpdateEventNPCFlags(uint16 event_id) } } +void GameEventMgr::UpdateBattleGroundSettings() +{ + uint32 mask = 0; + for(ActiveEvents::const_iterator itr = m_ActiveEvents.begin(); itr != m_ActiveEvents.end(); ++itr ) + mask |= mGameEventBattleGroundHolidays[*itr]; + sBattleGroundMgr.SetHolidayWeekends(mask); +} + +void GameEventMgr::UpdateEventNPCVendor(uint16 event_id, bool activate) +{ + for(NPCVendorList::iterator itr = mGameEventVendors[event_id].begin(); itr != mGameEventVendors[event_id].end(); ++itr) + { + if(activate) + objmgr.AddVendorItem(itr->entry, itr->item, itr->maxcount, itr->incrtime, itr->ExtendedCost, false); + else + objmgr.RemoveVendorItem(itr->entry, itr->item, false); + } +} + void GameEventMgr::GameEventSpawn(int16 event_id) { int32 internal_event_id = mGameEvent.size() + event_id - 1; @@ -1263,6 +1407,20 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate) } } +bool GameEventMgr::hasCreatureQuestActiveEventExcept(uint32 quest_id, uint16 event_id) +{ + for(ActiveEvents::iterator e_itr = m_ActiveEvents.begin(); e_itr != m_ActiveEvents.end(); ++e_itr) + { + if((*e_itr) != event_id) + for(QuestRelList::iterator itr = mGameEventCreatureQuests[*e_itr].begin(); + itr != mGameEventCreatureQuests[*e_itr].end(); + ++ itr) + if(itr->second == quest_id) + return true; + } + return false; +} + bool GameEventMgr::hasGameObjectQuestActiveEventExcept(uint32 quest_id, uint16 event_id) { for(ActiveEvents::iterator e_itr = m_ActiveEvents.begin(); e_itr != m_ActiveEvents.end(); ++e_itr) @@ -1318,7 +1476,7 @@ void GameEventMgr::UpdateEventQuests(uint16 event_id, bool Activate) if (Activate) // Add the pair(id,quest) to the multimap CreatureQuestMap.insert(QuestRelations::value_type(itr->first, itr->second)); else - { + { if(!hasCreatureQuestActiveEventExcept(itr->second,event_id)) { // Remove the pair(id,quest) from the multimap @@ -1343,7 +1501,7 @@ void GameEventMgr::UpdateEventQuests(uint16 event_id, bool Activate) if (Activate) // Add the pair(id,quest) to the multimap GameObjectQuestMap.insert(QuestRelations::value_type(itr->first, itr->second)); else - { + { if(!hasGameObjectQuestActiveEventExcept(itr->second,event_id)) { // Remove the pair(id,quest) from the multimap @@ -1368,18 +1526,6 @@ GameEventMgr::GameEventMgr() isSystemInit = false; } -MANGOS_DLL_SPEC bool IsHolidayActive( HolidayIds id ) -{ - GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap(); - GameEventMgr::ActiveEvents const& ae = gameeventmgr.GetActiveEventList(); - - for(GameEventMgr::ActiveEvents::const_iterator itr = ae.begin(); itr != ae.end(); ++itr) - if(events[id].holiday_id==id) - return true; - - return false; -} - void GameEventMgr::HandleQuestComplete(uint32 quest_id) { // translate the quest to event and condition @@ -1448,7 +1594,7 @@ void GameEventMgr::SaveWorldEventStateToDB(uint16 event_id) CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("DELETE FROM game_event_save WHERE event_id = '%u'",event_id); if(mGameEvent[event_id].nextstart) - CharacterDatabase.PExecute("INSERT INTO game_event_save (event_id, state, next_start) VALUES ('%u','%u',FROM_UNIXTIME('"I64FMTD"'))",event_id,mGameEvent[event_id].state,mGameEvent[event_id].nextstart); + CharacterDatabase.PExecute("INSERT INTO game_event_save (event_id, state, next_start) VALUES ('%u','%u',FROM_UNIXTIME("I64FMTD"))",event_id,mGameEvent[event_id].state,(uint64)(mGameEvent[event_id].nextstart)); else CharacterDatabase.PExecute("INSERT INTO game_event_save (event_id, state, next_start) VALUES ('%u','%u','0000-00-00 00:00:00')",event_id,mGameEvent[event_id].state); CharacterDatabase.CommitTransaction(); @@ -1472,23 +1618,20 @@ void GameEventMgr::SendWorldStateUpdate(Player * plr, uint16 event_id) for(itr = mGameEvent[event_id].conditions.begin(); itr !=mGameEvent[event_id].conditions.end(); ++itr) { if(itr->second.done_world_state) - plr->SendUpdateWorldState(itr->second.done_world_state, itr->second.done); + plr->SendUpdateWorldState(itr->second.done_world_state, (uint32)(itr->second.done)); if(itr->second.max_world_state) - plr->SendUpdateWorldState(itr->second.max_world_state, itr->second.reqNum); + plr->SendUpdateWorldState(itr->second.max_world_state, (uint32)(itr->second.reqNum)); } } -bool GameEventMgr::hasCreatureQuestActiveEventExcept(uint32 quest_id, uint16 event_id) - { - for(ActiveEvents::iterator e_itr = m_ActiveEvents.begin(); e_itr != m_ActiveEvents.end(); ++e_itr) - { - if((*e_itr) != event_id) - for(QuestRelList::iterator itr = mGameEventCreatureQuests[*e_itr].begin(); - itr != mGameEventCreatureQuests[*e_itr].end(); - ++ itr) - if(itr->second == quest_id) - return true; - } - return false; - } +MANGOS_DLL_SPEC bool IsHolidayActive( HolidayIds id ) +{ + GameEventMgr::GameEventDataMap const& events = gameeventmgr.GetEventMap(); + GameEventMgr::ActiveEvents const& ae = gameeventmgr.GetActiveEventList(); + for(GameEventMgr::ActiveEvents::const_iterator itr = ae.begin(); itr != ae.end(); ++itr) + if(events[id].holiday_id==id) + return true; + + return false; +} diff --git a/src/game/GameEventMgr.h b/src/game/GameEventMgr.h index 4dce224..09ee2e3 100644 --- a/src/game/GameEventMgr.h +++ b/src/game/GameEventMgr.h @@ -25,10 +25,6 @@ #define max_ge_check_delay 86400 // 1 day in seconds -class Creature; -class GameObject; -class Player; - enum GameEventState { GAMEEVENT_NORMAL = 0, // standard game events @@ -55,19 +51,19 @@ struct GameEventQuestToEventConditionNum struct GameEventData { - GameEventData() : start(1),end(0),occurence(0),length(0) {} - time_t start; - time_t end; - time_t nextstart; // after this time the follow-up events count this phase completed - uint32 occurence; - uint32 length; + GameEventData() : start(1),end(0),nextstart(0),occurence(0),length(0),state(GAMEEVENT_NORMAL) {} + time_t start; // occurs after this time + time_t end; // occurs before this time + time_t nextstart; // after this time the follow-up events count this phase completed + uint32 occurence; // time between end and start + uint32 length; // length of the event (minutes) after finishing all conditions uint32 holiday_id; GameEventState state; // state of the game event, these are saved into the game_event table on change! std::map conditions; // conditions to finish std::set prerequisite_events; // events that must be completed before starting this event std::string description; - bool isValid() const { return (length > 0 || state > 0); } + bool isValid() const { return ((length > 0) || (state > GAMEEVENT_NORMAL)); } }; struct ModelEquip @@ -78,6 +74,18 @@ struct ModelEquip uint32 equipement_id_prev; }; +struct NPCVendorEntry +{ + uint32 entry; // creature entry + uint32 item; // item id + uint32 maxcount; // 0 for infinite + uint32 incrtime; // time for restore items amount if maxcount != 0 + uint32 ExtendedCost; +}; + +class Player; +class Creature; + class GameEventMgr { public: @@ -110,6 +118,8 @@ class GameEventMgr void ChangeEquipOrModel(int16 event_id, bool activate); void UpdateEventQuests(uint16 event_id, bool Activate); void UpdateEventNPCFlags(uint16 event_id); + void UpdateEventNPCVendor(uint16 event_id, bool activate); + void UpdateBattleGroundSettings(); bool CheckOneGameEventConditions(uint16 event_id); void SaveWorldEventStateToDB(uint16 event_id); bool hasCreatureQuestActiveEventExcept(uint32 quest_id, uint16 event_id); @@ -127,19 +137,24 @@ class GameEventMgr typedef std::pair QuestRelation; typedef std::list QuestRelList; typedef std::vector GameEventQuestMap; + typedef std::list NPCVendorList; + typedef std::vector GameEventNPCVendorMap; typedef std::map QuestIdToEventConditionMap; typedef std::pair GuidNPCFlagPair; typedef std::list NPCFlagList; typedef std::vector GameEventNPCFlagMap; typedef std::pair EventNPCGossipIdPair; typedef std::map GuidEventNpcGossipIdMap; + typedef std::vector GameEventBitmask; GameEventQuestMap mGameEventCreatureQuests; GameEventQuestMap mGameEventGameObjectQuests; + GameEventNPCVendorMap mGameEventVendors; GameEventModelEquipMap mGameEventModelEquip; GameEventGuidMap mGameEventCreatureGuids; GameEventGuidMap mGameEventGameobjectGuids; GameEventIdMap mGameEventPoolIds; GameEventDataMap mGameEvent; + GameEventBitmask mGameEventBattleGroundHolidays; QuestIdToEventConditionMap mQuestToEventConditions; GameEventNPCFlagMap mGameEventNPCFlags; GuidEventNpcGossipIdMap mNPCGossipIds; @@ -151,4 +166,4 @@ class GameEventMgr MANGOS_DLL_SPEC bool IsHolidayActive(HolidayIds id); -#endif \ No newline at end of file +#endif diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 1bbde3b..aaf1d9f 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -7174,15 +7174,15 @@ void ObjectMgr::LoadNpcOptions() sLog.outString( ">> Loaded %d npc_option entries", count ); } -void ObjectMgr::AddVendorItem( uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedcost ) +void ObjectMgr::AddVendorItem( uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedcost, bool savetodb) { VendorItemData& vList = m_mCacheVendorItemMap[entry]; vList.AddItem(item,maxcount,incrtime,extendedcost); - WorldDatabase.PExecuteLog("INSERT INTO npc_vendor (entry,item,maxcount,incrtime,extendedcost) VALUES('%u','%u','%u','%u','%u')",entry, item, maxcount,incrtime,extendedcost); + if(savetodb) WorldDatabase.PExecuteLog("INSERT INTO npc_vendor (entry,item,maxcount,incrtime,extendedcost) VALUES('%u','%u','%u','%u','%u')",entry, item, maxcount,incrtime,extendedcost); } -bool ObjectMgr::RemoveVendorItem( uint32 entry,uint32 item ) +bool ObjectMgr::RemoveVendorItem( uint32 entry,uint32 item, bool savetodb) { CacheVendorItemMap::iterator iter = m_mCacheVendorItemMap.find(entry); if(iter == m_mCacheVendorItemMap.end()) @@ -7192,11 +7192,11 @@ bool ObjectMgr::RemoveVendorItem( uint32 entry,uint32 item ) return false; iter->second.RemoveItem(item); - WorldDatabase.PExecuteLog("DELETE FROM npc_vendor WHERE entry='%u' AND item='%u'",entry, item); + if(savetodb) WorldDatabase.PExecuteLog("DELETE FROM npc_vendor WHERE entry='%u' AND item='%u'",entry, item); return true; } -bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* pl, std::set* skip_vendors ) const +bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* pl, std::set* skip_vendors, uint32 ORnpcflag ) const { CreatureInfo const* cInfo = GetCreatureTemplate(vendor_entry); if(!cInfo) @@ -7204,18 +7204,18 @@ bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 m if(pl) ChatHandler(pl).SendSysMessage(LANG_COMMAND_VENDORSELECTION); else - sLog.outErrorDb("Table `npc_vendor` have data for not existed creature template (Entry: %u), ignore", vendor_entry); + sLog.outErrorDb("Table `(game_event_)npc_vendor` have data for not existed creature template (Entry: %u), ignore", vendor_entry); return false; } - if(!(cInfo->npcflag & UNIT_NPC_FLAG_VENDOR)) + if(!((cInfo->npcflag | ORnpcflag) & UNIT_NPC_FLAG_VENDOR)) { if(!skip_vendors || skip_vendors->count(vendor_entry)==0) { if(pl) ChatHandler(pl).SendSysMessage(LANG_COMMAND_VENDORSELECTION); else - sLog.outErrorDb("Table `npc_vendor` have data for not creature template (Entry: %u) without vendor flag, ignore", vendor_entry); + sLog.outErrorDb("Table `(game_event_)npc_vendor` have data for not creature template (Entry: %u) without vendor flag, ignore", vendor_entry); if(skip_vendors) skip_vendors->insert(vendor_entry); @@ -7228,7 +7228,7 @@ bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 m if(pl) ChatHandler(pl).PSendSysMessage(LANG_ITEM_NOT_FOUND, item_id); else - sLog.outErrorDb("Table `npc_vendor` for Vendor (Entry: %u) have in item list non-existed item (%u), ignore",vendor_entry,item_id); + sLog.outErrorDb("Table `(game_event_)npc_vendor` for Vendor (Entry: %u) have in item list non-existed item (%u), ignore",vendor_entry,item_id); return false; } @@ -7237,7 +7237,7 @@ bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 m if(pl) ChatHandler(pl).PSendSysMessage(LANG_EXTENDED_COST_NOT_EXIST,ExtendedCost); else - sLog.outErrorDb("Table `npc_vendor` have Item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignore",item_id,ExtendedCost,vendor_entry); + sLog.outErrorDb("Table `(game_event_)npc_vendor` have Item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignore",item_id,ExtendedCost,vendor_entry); return false; } @@ -7246,7 +7246,7 @@ bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 m if(pl) ChatHandler(pl).PSendSysMessage("MaxCount!=0 (%u) but IncrTime==0", maxcount); else - sLog.outErrorDb( "Table `npc_vendor` has `maxcount` (%u) for item %u of vendor (Entry: %u) but `incrtime`=0, ignore", maxcount, item_id, vendor_entry); + sLog.outErrorDb( "Table `(game_event_)npc_vendor` has `maxcount` (%u) for item %u of vendor (Entry: %u) but `incrtime`=0, ignore", maxcount, item_id, vendor_entry); return false; } else if(maxcount==0 && incrtime > 0) @@ -7254,7 +7254,7 @@ bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 m if(pl) ChatHandler(pl).PSendSysMessage("MaxCount==0 but IncrTime<>=0"); else - sLog.outErrorDb( "Table `npc_vendor` has `maxcount`=0 for item %u of vendor (Entry: %u) but `incrtime`<>0, ignore", item_id, vendor_entry); + sLog.outErrorDb( "Table `(game_event_)npc_vendor` has `maxcount`=0 for item %u of vendor (Entry: %u) but `incrtime`<>0, ignore", item_id, vendor_entry); return false; } @@ -7267,7 +7267,7 @@ bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 m if(pl) ChatHandler(pl).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST,item_id); else - sLog.outErrorDb( "Table `npc_vendor` has duplicate items %u for vendor (Entry: %u), ignore", item_id, vendor_entry); + sLog.outErrorDb( "Table `(game_event_)npc_vendor` has duplicate items %u for vendor (Entry: %u), ignore", item_id, vendor_entry); return false; } diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 6f16282..72ee85a 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -754,9 +754,9 @@ class ObjectMgr return &iter->second; } - void AddVendorItem(uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost); - bool RemoveVendorItem(uint32 entry,uint32 item); - bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set* skip_vendors = NULL ) const; + void AddVendorItem(uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, bool savetodb = true); // for event + bool RemoveVendorItem(uint32 entry,uint32 item, bool savetodb = true); // for event + bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set* skip_vendors = NULL, uint32 ORnpcflag = 0 ) const; void LoadScriptNames(); ScriptNameMap &GetScriptNames() { return m_scriptNames; }