diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/game/CharacterHandler.cpp | 1 | ||||
| -rw-r--r-- | src/game/GossipDef.cpp | 77 | ||||
| -rw-r--r-- | src/game/ObjectMgr.cpp | 30 | ||||
| -rw-r--r-- | src/game/Player.cpp | 89 | ||||
| -rw-r--r-- | src/game/Player.h | 13 | ||||
| -rw-r--r-- | src/game/QuestDef.h | 2 | ||||
| -rw-r--r-- | src/game/QuestHandler.cpp | 2 | ||||
| -rw-r--r-- | src/game/World.cpp | 40 | ||||
| -rw-r--r-- | src/game/World.h | 4 | ||||
| -rw-r--r-- | src/shared/Common.h | 1 | 
10 files changed, 212 insertions, 47 deletions
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 2ccbce54e10..a823cd5c0e4 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -76,6 +76,7 @@ bool LoginQueryHolder::Initialize()      res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS,          "SELECT spell,active,disabled FROM character_spell WHERE guid = '%u'", GUID_LOPART(m_guid));      res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS,     "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4 FROM character_queststatus WHERE guid = '%u'", GUID_LOPART(m_guid));      res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS,"SELECT quest,time FROM character_queststatus_daily WHERE guid = '%u'", GUID_LOPART(m_guid)); +    res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADWEKLYQUESTSTATUS,"SELECT quest FROM character_queststatus_weekly WHERE guid = '%u'", GUID_LOPART(m_guid));      res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADREPUTATION,      "SELECT faction,standing,flags FROM character_reputation WHERE guid = '%u'", GUID_LOPART(m_guid));      res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADINVENTORY,       "SELECT data,text,bag,slot,item,item_template FROM character_inventory JOIN item_instance ON character_inventory.item = item_instance.guid WHERE character_inventory.guid = '%u' ORDER BY bag,slot", GUID_LOPART(m_guid));      res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACTIONS,         "SELECT a.button,a.action,a.type FROM character_action as a, characters as c WHERE a.guid = c.guid AND a.spec = c.activespec AND a.guid = '%u' ORDER BY button", GUID_LOPART(m_guid)); diff --git a/src/game/GossipDef.cpp b/src/game/GossipDef.cpp index bfb81dfa724..f72ae563622 100644 --- a/src/game/GossipDef.cpp +++ b/src/game/GossipDef.cpp @@ -166,8 +166,8 @@ void PlayerMenu::SendGossipMenu(uint32 TitleTextId, uint64 objectGUID)          data << uint32(questID);          data << uint32(qItem.m_qIcon); -        data << uint32(pSession->GetPlayer()->GetQuestLevel(pQuest)); -        data << uint32(pQuest->GetClientFlags());           // 3.3.3 quest flags +        data << int32(pQuest->GetQuestLevel()); +        data << uint32(pQuest->GetFlags());                 // 3.3.3 quest flags          data << uint8(0);                                   // 3.3.3 changes icon: blue question or yellow exclamation          std::string Title = pQuest->GetTitle(); @@ -387,34 +387,40 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote eEmote, const std::string& Title      data << Title;      data << uint32(eEmote._Delay);                         // player emote      data << uint32(eEmote._Emote);                         // NPC emote -    data << uint8 (mQuestMenu.MenuItemCount()); -    for (uint32 iI = 0; iI < mQuestMenu.MenuItemCount(); ++iI) +    size_t count_pos = data.wpos(); +    data << uint8 ( mQuestMenu.MenuItemCount()); +    uint32 count = 0; +    for (; count < mQuestMenu.MenuItemCount(); ++count)      { -        QuestMenuItem const& qmi = mQuestMenu.GetItem(iI); +        QuestMenuItem const& qmi = mQuestMenu.GetItem(count);          uint32 questID = qmi.m_qId; -        Quest const *pQuest = objmgr.GetQuestTemplate(questID); - -        std::string title = pQuest ? pQuest->GetTitle() : ""; -        int loc_idx = pSession->GetSessionDbLocaleIndex(); -        if (loc_idx >= 0) +        if (Quest const *pQuest = objmgr.GetQuestTemplate(questID))          { -            if (QuestLocale const *ql = objmgr.GetQuestLocale(questID)) +            std::string title = pQuest->GetTitle(); + +            int loc_idx = pSession->GetSessionDbLocaleIndex(); +            if (loc_idx >= 0)              { -                if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty()) -                    title=ql->Title[loc_idx]; +                if (QuestLocale const *ql = objmgr.GetQuestLocale(questID)) +                { +                    if (ql->Title.size() > (size_t)loc_idx && !ql->Title[loc_idx].empty()) +                        title = ql->Title[loc_idx]; +                }              } -        } -        data << uint32(questID); -        data << uint32(qmi.m_qIcon); -        data << uint32(pSession->GetPlayer()->GetQuestLevel(pQuest)); -        data << uint32(pQuest->GetClientFlags());       // 3.3.3 quest flags -        data << uint8(0);                               // 3.3.3 changes icon: blue question or yellow exclamation -        data << title; +            data << uint32(questID); +            data << uint32(qmi.m_qIcon); +            data << int32(pQuest->GetQuestLevel()); +            data << uint32(pQuest->GetFlags());             // 3.3.3 quest flags +            data << uint8(0);                               // 3.3.3 changes icon: blue question or yellow exclamation +            data << title; +        }      } + +    data.put<uint8>(count_pos, count);      pSession->SendPacket(&data);      sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_LIST NPC Guid=%u", GUID_LOPART(npcGUID));  } @@ -461,15 +467,16 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const *pQuest, uint64 npcGUID,      data << Details;      data << Objectives;      data << uint8(ActivateAccept ? 1 : 0);                  // auto finish -    data << uint32(pQuest->GetClientFlags());               // 3.3.3 questFlags +    data << uint32(pQuest->GetFlags());                     // 3.3.3 questFlags      data << uint32(pQuest->GetSuggestedPlayers()); -    data << uint8(0);                                       // IsFinished, value is sent back to server in quest accept packet +    data << uint8(0);                                       // IsFinished? value is sent back to server in quest accept packet      if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))      {          data << uint32(0);                                  // Rewarded chosen items hidden          data << uint32(0);                                  // Rewarded items hidden          data << uint32(0);                                  // Rewarded money hidden +        data << uint32(0);                                  // Rewarded XP hidden      }      else      { @@ -478,10 +485,14 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const *pQuest, uint64 npcGUID,          data << uint32(pQuest->GetRewChoiceItemsCount());          for (uint32 i=0; i < QUEST_REWARD_CHOICES_COUNT; ++i)          { -            if (!pQuest->RewChoiceItemId[i]) continue; +            if (!pQuest->RewChoiceItemId[i]) +                continue; +              data << uint32(pQuest->RewChoiceItemId[i]);              data << uint32(pQuest->RewChoiceItemCount[i]); +              IProto = objmgr.GetItemPrototype(pQuest->RewChoiceItemId[i]); +              if (IProto)                  data << uint32(IProto->DisplayInfoID);              else @@ -489,12 +500,17 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const *pQuest, uint64 npcGUID,          }          data << uint32(pQuest->GetRewItemsCount()); +          for (uint32 i=0; i < QUEST_REWARDS_COUNT; ++i)          { -            if (!pQuest->RewItemId[i]) continue; +            if (!pQuest->RewItemId[i]) +                continue; +              data << uint32(pQuest->RewItemId[i]);              data << uint32(pQuest->RewItemCount[i]); +              IProto = objmgr.GetItemPrototype(pQuest->RewItemId[i]); +              if (IProto)                  data << uint32(IProto->DisplayInfoID);              else @@ -603,12 +619,12 @@ void PlayerMenu::SendQuestQueryResponse(Quest const *pQuest)      data << uint32(Trinity::Honor::hk_honor_at_level(pSession->GetPlayer()->getLevel(), pQuest->GetRewHonorableKills()));      data << float(0);                                       // new reward honor (multipled by ~62 at client side)      data << uint32(pQuest->GetSrcItemId());                 // source item id -    data << uint32(pQuest->GetClientFlags());               // quest flags +    data << uint32(pQuest->GetFlags() & 0xFFFF);            // quest flags      data << uint32(pQuest->GetCharTitleId());               // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)      data << uint32(pQuest->GetPlayersSlain());              // players slain      data << uint32(pQuest->GetBonusTalents());              // bonus talents      data << uint32(pQuest->GetRewArenaPoints());            // bonus arena points -    data << uint32(0);                                      // unknown +    data << uint32(0);                                      // review rep show mask      int iI; @@ -708,7 +724,7 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* pQuest, uint64 npcGUID,      data << OfferRewardText;      data << uint8(EnableNext ? 1 : 0);                      // Auto Finish -    data << uint32(pQuest->GetClientFlags());               // 3.3.3 questFlags +    data << uint32(pQuest->GetFlags());                     // 3.3.3 questFlags      data << uint32(pQuest->GetSuggestedPlayers());          // SuggestedGroupNum      uint32 EmoteCount = 0; @@ -828,7 +844,7 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const *pQuest, uint64 npcGUID,      else          data << uint32(0x00); -    data << uint32(pQuest->GetClientFlags());               // 3.3.3 questFlags +    data << uint32(pQuest->GetFlags());                     // 3.3.3 questFlags      data << uint32(pQuest->GetSuggestedPlayers());          // SuggestedGroupNum      // Required Money @@ -838,8 +854,11 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const *pQuest, uint64 npcGUID,      ItemPrototype const *pItem;      for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)      { -        if (!pQuest->ReqItemId[i]) continue; +        if (!pQuest->ReqItemId[i]) +            continue; +          pItem = objmgr.GetItemPrototype(pQuest->ReqItemId[i]); +          data << uint32(pQuest->ReqItemId[i]);          data << uint32(pQuest->ReqItemCount[i]); diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index beb4ca2839e..d1b2b1c525b 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -3653,26 +3653,41 @@ void ObjectMgr::LoadQuests()              sLog.outErrorDb("Quest %u has `Method` = %u, expected values are 0, 1 or 2.",qinfo->GetQuestId(),qinfo->GetQuestMethod());          } -        if (qinfo->GetFlags() & ~QUEST_TRINITY_FLAGS_DB_ALLOWED) +        if (qinfo->QuestFlags & ~QUEST_TRINITY_FLAGS_DB_ALLOWED)          {              sLog.outErrorDb("Quest %u has `SpecialFlags` = %u > max allowed value. Correct `SpecialFlags` to value <= %u", -                qinfo->GetQuestId(),qinfo->GetFlags(),QUEST_TRINITY_FLAGS_DB_ALLOWED >> 20); +                qinfo->GetQuestId(),qinfo->QuestFlags  >> 20, QUEST_TRINITY_FLAGS_DB_ALLOWED >> 20);              qinfo->QuestFlags &= QUEST_TRINITY_FLAGS_DB_ALLOWED;          } -        if (qinfo->GetFlags() & (QUEST_FLAGS_DAILY | QUEST_FLAGS_WEEKLY)) +        if (qinfo->QuestFlags & QUEST_FLAGS_DAILY && qinfo->QuestFlags & QUEST_FLAGS_WEEKLY)          { -            if (!(qinfo->GetFlags() & QUEST_TRINITY_FLAGS_REPEATABLE)) +            sLog.outErrorDb("Weekly Quest %u is marked as daily quest in `QuestFlags`, removed daily flag.",qinfo->GetQuestId()); +            qinfo->QuestFlags &= ~QUEST_FLAGS_DAILY; +        } + +        if (qinfo->QuestFlags & QUEST_FLAGS_DAILY) +        { +            if (!(qinfo->QuestFlags & QUEST_TRINITY_FLAGS_REPEATABLE))              {                  sLog.outErrorDb("Daily Quest %u not marked as repeatable in `SpecialFlags`, added.",qinfo->GetQuestId()); -                qinfo->SetFlag(QUEST_TRINITY_FLAGS_REPEATABLE); +                qinfo->QuestFlags |= QUEST_TRINITY_FLAGS_REPEATABLE; +            } +        } + +        if (qinfo->QuestFlags & QUEST_FLAGS_WEEKLY) +        { +            if (!(qinfo->QuestFlags & QUEST_TRINITY_FLAGS_REPEATABLE)) +            { +                sLog.outErrorDb("Weekly Quest %u not marked as repeatable in `SpecialFlags`, added.",qinfo->GetQuestId()); +                qinfo->QuestFlags |= QUEST_TRINITY_FLAGS_REPEATABLE;              }          } -        if (qinfo->GetFlags() & QUEST_FLAGS_AUTO_REWARDED) +        if (qinfo->QuestFlags & QUEST_FLAGS_AUTO_REWARDED)          {              // at auto-reward can be rewarded only RewChoiceItemId[0] -            for (uint8 j = 1; j < QUEST_REWARD_CHOICES_COUNT; ++j) +            for(int j = 1; j < QUEST_REWARD_CHOICES_COUNT; ++j )              {                  if (uint32 id = qinfo->RewChoiceItemId[j])                  { @@ -4450,7 +4465,6 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename)                      continue;                  } -                // if (!objmgr.GetMangosStringLocale(tmp.dataint)) will checked after db_script_string loading                  break;              } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 10aac3aa60b..405e144c75a 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1198,7 +1198,7 @@ void Player::Update(uint32 p_time)      if (!m_timedquests.empty())      { -        std::set<uint32>::iterator iter = m_timedquests.begin(); +        QuestSet::iterator iter = m_timedquests.begin();          while (iter != m_timedquests.end())          {              QuestStatusData& q_status = mQuestStatus[*iter]; @@ -13578,7 +13578,7 @@ void Player::SendPreparedQuest(uint64 guid)                  PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, CanRewardQuest(pQuest, false), true);              // Send completable on repeatable and autoCompletable quest if player don't have quest              // TODO: verify if check for !pQuest->IsDaily() is really correct (possibly not) -            else if (pQuest->IsAutoComplete() && pQuest->IsRepeatable() && !pQuest->IsDaily()) +            else if (pQuest->IsAutoComplete() && pQuest->IsRepeatable() && !pQuest->IsDailyOrWeekly())                  PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, CanCompleteRepeatableQuest(pQuest), true);              else                  PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, guid, true); @@ -13696,7 +13696,7 @@ bool Player::CanSeeStartQuest(Quest const *pQuest)      if (SatisfyQuestRace(pQuest, false) && SatisfyQuestSkillOrClass(pQuest, false) &&          SatisfyQuestExclusiveGroup(pQuest, false) && SatisfyQuestReputation(pQuest, false) &&          SatisfyQuestPreviousQuest(pQuest, false) && SatisfyQuestNextChain(pQuest, false) && -        SatisfyQuestPrevChain(pQuest, false) && SatisfyQuestDay(pQuest, false)) +        SatisfyQuestPrevChain(pQuest, false) && SatisfyQuestDay(pQuest, false) && SatisfyQuestWeek(pQuest, false))      {          return getLevel() + sWorld.getConfig(CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF) >= pQuest->GetMinLevel();      } @@ -13711,7 +13711,7 @@ bool Player::CanTakeQuest(Quest const *pQuest, bool msg)          && SatisfyQuestSkillOrClass(pQuest, msg) && SatisfyQuestReputation(pQuest, msg)          && SatisfyQuestPreviousQuest(pQuest, msg) && SatisfyQuestTimed(pQuest, msg)          && SatisfyQuestNextChain(pQuest, msg) && SatisfyQuestPrevChain(pQuest, msg) -        && SatisfyQuestDay(pQuest, msg); +        && SatisfyQuestDay(pQuest, msg) && SatisfyQuestWeek(pQuest, msg);  }  bool Player::CanAddQuest(Quest const *pQuest, bool msg) @@ -13831,7 +13831,7 @@ bool Player::CanRewardQuest(Quest const *pQuest, bool msg)          return false;      // daily quest can't be rewarded (25 daily quest already completed) -    if (!SatisfyQuestDay(pQuest,true)) +    if (!SatisfyQuestDay(pQuest,true) || !SatisfyQuestWeek(pQuest,true))          return false;      // rewarded and not repeatable quest (only cheating case, then ignore without message) @@ -14126,6 +14126,9 @@ void Player::RewardQuest(Quest const *pQuest, uint32 reward, Object* questGiver,          GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, 1);      } +    if (pQuest->IsWeekly()) +        SetWeeklyQuestStatus(quest_id);	 +      if (!pQuest->IsRepeatable())          SetQuestStatus(quest_id, QUEST_STATUS_COMPLETE);      else @@ -14472,10 +14475,11 @@ bool Player::SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg)          // not allow have daily quest if daily quest from exclusive group already recently completed          Quest const* Nquest = objmgr.GetQuestTemplate(exclude_Id); -        if (!SatisfyQuestDay(Nquest, false)) +        if (!SatisfyQuestDay(Nquest, false) || !SatisfyQuestWeek(Nquest, false))          {              if (msg)                  SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ); +              return false;          } @@ -14574,6 +14578,15 @@ bool Player::SatisfyQuestDay(Quest const* qInfo, bool msg)      return true;  } +bool Player::SatisfyQuestWeek( Quest const* qInfo, bool msg ) +{ +    if (!qInfo->IsWeekly() || m_weeklyquests.empty()) +        return true; + +    // if not found in cooldown list +    return m_weeklyquests.find(qInfo->GetQuestId()) == m_weeklyquests.end(); +} +  bool Player::GiveQuestSourceItem(Quest const *pQuest)  {      uint32 srcitem = pQuest->GetSrcItemId(); @@ -16047,6 +16060,7 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder)      // after spell load, learn rewarded spell if need also      _LoadQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS));      _LoadDailyQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS)); +    _LoadWeeklyQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADWEKLYQUESTSTATUS));      // after spell and quest load      InitTalentForLevel(); @@ -16820,6 +16834,33 @@ void Player::_LoadDailyQuestStatus(QueryResult_AutoPtr result)      m_DailyQuestChanged = false;  } +void Player::_LoadWeeklyQuestStatus(QueryResult_AutoPtr result)	 +{ +    m_weeklyquests.clear(); + +    if (result)	 +    { +        do +        { +            Field *fields = result->Fetch(); + +            uint32 quest_id = fields[0].GetUInt32(); + +            Quest const* pQuest = objmgr.GetQuestTemplate(quest_id); + +            if (!pQuest)	 +                continue;	 +	 +            m_weeklyquests.insert(quest_id); + +            sLog.outDebug("Weekly quest {%u} cooldown for player (GUID: %u)", quest_id, GetGUIDLow()); +        } +        while(result->NextRow()); +    } + +    m_WeeklyQuestChanged = false; +} +  void Player::_LoadSpells(QueryResult_AutoPtr result)  {      //QueryResult *result = CharacterDatabase.PQuery("SELECT spell,active,disabled FROM character_spell WHERE guid = '%u'",GetGUIDLow()); @@ -17434,6 +17475,7 @@ void Player::SaveToDB()      _SaveInventory();      _SaveQuestStatus();      _SaveDailyQuestStatus(); +    _SaveWeeklyQuestStatus();      _SaveTalents();      _SaveSpells();      _SaveSpellCooldowns(); @@ -17730,6 +17772,24 @@ void Player::_SaveDailyQuestStatus()                  GetGUIDLow(), GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx),uint64(m_lastDailyQuestTime));  } +void Player::_SaveWeeklyQuestStatus() +{ +    if (!m_WeeklyQuestChanged || m_weeklyquests.empty()) +        return; + +    // we don't need transactions here. +    CharacterDatabase.PExecute("DELETE FROM character_queststatus_weekly WHERE guid = '%u'",GetGUIDLow()); + +    for (QuestSet::const_iterator iter = m_weeklyquests.begin(); iter != m_weeklyquests.end(); ++iter) +    { +        uint32 quest_id  = *iter; + +        CharacterDatabase.PExecute("INSERT INTO character_queststatus_weekly (guid,quest) VALUES ('%u', '%u')", GetGUIDLow(), quest_id); +    } + +    m_WeeklyQuestChanged = false; +} +  void Player::_SaveSkills()  {      // we don't need transactions here. @@ -20905,6 +20965,13 @@ void Player::SetDailyQuestStatus(uint32 quest_id)      }  } + +void Player::SetWeeklyQuestStatus(uint32 quest_id)	 +{ +    m_weeklyquests.insert(quest_id); +    m_WeeklyQuestChanged = true; +} +  void Player::ResetDailyQuestStatus()  {      for (uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx) @@ -20915,6 +20982,16 @@ void Player::ResetDailyQuestStatus()      m_lastDailyQuestTime = 0;  } +void Player::ResetWeeklyQuestStatus() +{ +    if (m_weeklyquests.empty()) +        return; + +    m_weeklyquests.clear();	 +    // DB data deleted in caller +    m_WeeklyQuestChanged = false; +} +  BattleGround* Player::GetBattleGround() const  {      if (GetBattleGroundId() == 0) diff --git a/src/game/Player.h b/src/game/Player.h index bccf9030fe1..119c70ffe5a 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -851,7 +851,8 @@ enum PlayerLoginQueryIndex      PLAYER_LOGIN_QUERY_LOADTALENTS              = 23,      PLAYER_LOGIN_QUERY_LOADACCOUNTDATA          = 24,      PLAYER_LOGIN_QUERY_LOADSKILLS               = 25, -    MAX_PLAYER_LOGIN_QUERY                      = 26 +    PLAYER_LOGIN_QUERY_LOADWEKLYQUESTSTATUS     = 26, +    MAX_PLAYER_LOGIN_QUERY                      = 27  };  enum PlayerDelayedOperations @@ -1328,6 +1329,7 @@ class Player : public Unit, public GridObject<Player>          bool SatisfyQuestNextChain(Quest const* qInfo, bool msg);          bool SatisfyQuestPrevChain(Quest const* qInfo, bool msg);          bool SatisfyQuestDay(Quest const* qInfo, bool msg); +        bool SatisfyQuestWeek(Quest const* qInfo, bool msg);          bool GiveQuestSourceItem(Quest const *pQuest);          bool TakeQuestSourceItem(uint32 quest_id, bool msg);          bool GetQuestRewardStatus(uint32 quest_id) const; @@ -1335,7 +1337,9 @@ class Player : public Unit, public GridObject<Player>          void SetQuestStatus(uint32 quest_id, QuestStatus status);          void SetDailyQuestStatus(uint32 quest_id); +        void SetWeeklyQuestStatus(uint32 quest_id);          void ResetDailyQuestStatus(); +        void ResetWeeklyQuestStatus();          uint16 FindQuestSlot(uint32 quest_id) const;          uint32 GetQuestSlotQuestId(uint16 slot) const { return GetUInt32Value(PLAYER_QUEST_LOG_1_1 + slot * MAX_QUEST_OFFSET + QUEST_ID_OFFSET); } @@ -2363,7 +2367,9 @@ class Player : public Unit, public GridObject<Player>          /*********************************************************/          //We allow only one timed quest active at the same time. Below can then be simple value instead of set. -        std::set<uint32> m_timedquests; +        typedef std::set<uint32> QuestSet; +        QuestSet m_timedquests; +        QuestSet m_weeklyquests;          uint64 m_divider;          uint32 m_ingametime; @@ -2382,6 +2388,7 @@ class Player : public Unit, public GridObject<Player>          void _LoadMailedItems(Mail *mail);          void _LoadQuestStatus(QueryResult_AutoPtr result);          void _LoadDailyQuestStatus(QueryResult_AutoPtr result); +        void _LoadWeeklyQuestStatus(QueryResult_AutoPtr result);          void _LoadGroup(QueryResult_AutoPtr result);          void _LoadSkills(QueryResult_AutoPtr result);          void _LoadSpells(QueryResult_AutoPtr result); @@ -2405,6 +2412,7 @@ class Player : public Unit, public GridObject<Player>          void _SaveMail();          void _SaveQuestStatus();          void _SaveDailyQuestStatus(); +        void _SaveWeeklyQuestStatus();          void _SaveSkills();          void _SaveSpells();          void _SaveEquipmentSets(); @@ -2508,6 +2516,7 @@ class Player : public Unit, public GridObject<Player>          uint32 tradeGold;          bool   m_DailyQuestChanged; +        bool   m_WeeklyQuestChanged;          time_t m_lastDailyQuestTime;          uint32 m_drunkTimer; diff --git a/src/game/QuestDef.h b/src/game/QuestDef.h index c8537c8eff3..c694c65abb9 100644 --- a/src/game/QuestDef.h +++ b/src/game/QuestDef.h @@ -239,9 +239,9 @@ class Quest          bool   IsRepeatable() const { return QuestFlags & QUEST_TRINITY_FLAGS_REPEATABLE; }          bool   IsAutoComplete() const { return QuestMethod ? false : true; }          uint32 GetFlags() const { return QuestFlags; } -        uint32 GetClientFlags() const { return QuestFlags & 0xFFFFF; }          bool   IsDaily() const { return QuestFlags & QUEST_FLAGS_DAILY; }          bool   IsWeekly() const { return QuestFlags & QUEST_FLAGS_WEEKLY; } +        bool   IsDailyOrWeekly() const { return QuestFlags & (QUEST_FLAGS_DAILY | QUEST_FLAGS_WEEKLY); }          bool   IsAutoAccept() const { return QuestFlags & QUEST_FLAGS_AUTO_ACCEPT; }          // multiple values diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp index 53bb4335169..c7632cf10f0 100644 --- a/src/game/QuestHandler.cpp +++ b/src/game/QuestHandler.cpp @@ -619,7 +619,7 @@ uint32 WorldSession::getDialogStatus(Player *pPlayer, Object* questgiver, uint32                          result2 = DIALOG_STATUS_REWARD_REP;                      else if (pPlayer->getLevel() <= ((pPlayer->GetQuestLevel(pQuest) == -1) ? pPlayer->getLevel() : pPlayer->GetQuestLevel(pQuest) + sWorld.getConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF)))                      { -                        if (pQuest->IsDaily()) +                        if (pQuest->HasFlag(QUEST_FLAGS_DAILY) || pQuest->HasFlag(QUEST_FLAGS_WEEKLY))                              result2 = DIALOG_STATUS_AVAILABLE_REP;                          else                              result2 = DIALOG_STATUS_AVAILABLE; diff --git a/src/game/World.cpp b/src/game/World.cpp index 057e3489216..7419e65772d 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -105,6 +105,7 @@ World::World()      m_MaxPlayerCount = 0;      m_resultQueue = NULL;      m_NextDailyQuestReset = 0; +    m_NextWeeklyQuestReset = 0;      m_scheduledScripts = 0;      m_defaultDbcLocale = LOCALE_enUS; @@ -1680,6 +1681,9 @@ void World::SetInitialWorldSettings()      sLog.outString("Calculate next daily quest reset time...");      InitDailyQuestResetTime(); +    sLog.outString("Calculate next weekly quest reset time..." ); +    InitWeeklyQuestResetTime(); +      sLog.outString("Starting objects Pooling system...");      poolhandler.Initialize(); @@ -1844,6 +1848,12 @@ void World::Update(uint32 diff)          m_NextDailyQuestReset += DAY;      } +    if (m_gameTime > m_NextWeeklyQuestReset) +    { +        ResetWeeklyQuests();	 +        m_NextWeeklyQuestReset += WEEK; +    }	 +      /// <ul><li> Handle auctions when the timer has passed      if (m_timers[WUPDATE_AUCTIONS].Passed())      { @@ -2486,6 +2496,25 @@ void World::_UpdateRealmCharCount(QueryResult_AutoPtr resultCharCount, uint32 ac      }  } +void World::InitWeeklyQuestResetTime()	 +{	 +    QueryResult_AutoPtr result = CharacterDatabase.Query("SELECT NextWeeklyQuestResetTime FROM worldstates"); +    if (!result) +    {	 +        m_NextWeeklyQuestReset = time_t(m_gameTime + WEEK); +        CharacterDatabase.PExecute("INSERT INTO worldstates (NextWeeklyQuestResetTime) VALUES ('"UI64FMTD"')", uint64(m_NextWeeklyQuestReset));	 +    } +    else	 +    {	 +        m_NextWeeklyQuestReset = time_t((*result)[0].GetUInt64());	 +	 +        // move to just before if need	 +        time_t cur = time(NULL);	 +        if (m_NextWeeklyQuestReset < cur) +            m_NextWeeklyQuestReset += WEEK * ((cur - m_NextWeeklyQuestReset) / WEEK);	 +    }	 +}	 +  void World::InitDailyQuestResetTime()  {      time_t mostRecentQuestTime; @@ -2543,6 +2572,17 @@ void World::UpdateAllowedSecurity()      }  } +void World::ResetWeeklyQuests()	 +{	 +    CharacterDatabase.Execute("DELETE FROM character_queststatus_weekly"); +    for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)	 +        if (itr->second->GetPlayer())	 +            itr->second->GetPlayer()->ResetWeeklyQuestStatus(); + +    m_NextWeeklyQuestReset = time_t(m_NextWeeklyQuestReset + WEEK); +    CharacterDatabase.PExecute("UPDATE worldstates SET NextWeeklyQuestResetTime = '"UI64FMTD"'", uint64(m_NextWeeklyQuestReset));	 +}	 +  void World::SetPlayerLimit(int32 limit, bool needUpdate)  {      m_playerLimit = limit; diff --git a/src/game/World.h b/src/game/World.h index 0a336395921..7477c317617 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -550,6 +550,7 @@ class World          void SetRecordDiffInterval(int32 t) { if (t >= 0) m_configs[CONFIG_INTERVAL_LOG_UPDATE] = (uint32)t; }          /// Next daily quests reset time          time_t GetNextDailyQuestsResetTime() const { return m_NextDailyQuestReset; } +        time_t GetNextWeeklyQuestsResetTime() const { return m_NextWeeklyQuestReset; }          /// Get the maximum skill level a player can reach          uint16 GetConfigMaxSkillValue() const @@ -670,7 +671,9 @@ class World          void _UpdateRealmCharCount(QueryResult_AutoPtr resultCharCount, uint32 accountId);          void InitDailyQuestResetTime(); +        void InitWeeklyQuestResetTime();          void ResetDailyQuests(); +        void ResetWeeklyQuests();      private:          static volatile bool m_stopEvent;          static uint8 m_ExitCode; @@ -738,6 +741,7 @@ class World          // next daily quests reset time          time_t m_NextDailyQuestReset; +        time_t m_NextWeeklyQuestReset;          //Player Queue          Queue m_QueuedPlayer; diff --git a/src/shared/Common.h b/src/shared/Common.h index 4310c426883..be61019cef0 100644 --- a/src/shared/Common.h +++ b/src/shared/Common.h @@ -165,6 +165,7 @@ enum TimeConstants      MINUTE = 60,      HOUR   = MINUTE*60,      DAY    = HOUR*24, +    WEEK   = DAY*7,      MONTH  = DAY*30,      YEAR   = MONTH*12,      IN_MILISECONDS = 1000  | 
