diff --git a/source/WorldServer/LuaFunctions.cpp b/source/WorldServer/LuaFunctions.cpp index e2a76a7..4fec750 100644 --- a/source/WorldServer/LuaFunctions.cpp +++ b/source/WorldServer/LuaFunctions.cpp @@ -4088,9 +4088,15 @@ int EQ2Emu_lua_SetQuestRewardStatus(lua_State* state) { return 0; Quest* quest = lua_interface->GetQuest(state); int32 status = lua_interface->GetInt32Value(state, 2); + int32 min_status_earned = lua_interface->GetInt32Value(state, 3); + int32 max_status_earned = lua_interface->GetInt32Value(state, 4); lua_interface->ResetFunctionStack(state); if (quest) { quest->SetRewardStatus(status); + if(min_status_earned) + quest->SetStatusToEarnMin(min_status_earned); + if(max_status_earned) + quest->SetStatusToEarnMin(max_status_earned); } return 0; } diff --git a/source/WorldServer/Quests.cpp b/source/WorldServer/Quests.cpp index 81fd2ed..83e0565 100644 --- a/source/WorldServer/Quests.cpp +++ b/source/WorldServer/Quests.cpp @@ -317,6 +317,9 @@ Quest::Quest(int32 in_id){ quest_temporary_description = string(""); quest_shareable_flag = 0; can_delete_quest = false; + m_status = 0; + status_to_earn_min = 0; + status_to_earn_max = 0; } Quest::Quest(Quest* old_quest){ @@ -348,6 +351,7 @@ Quest::Quest(Quest* old_quest){ has_sent_last_update = old_quest->has_sent_last_update; yellow_name = old_quest->yellow_name; m_questFlags = old_quest->m_questFlags; + m_status = old_quest->m_status; id = old_quest->id; vector quest_steps; @@ -393,6 +397,8 @@ Quest::Quest(Quest* old_quest){ quest_temporary_description = string(""); quest_shareable_flag = old_quest->GetQuestShareableFlag(); can_delete_quest = old_quest->CanDeleteQuest(); + status_to_earn_min = old_quest->GetStatusToEarnMin(); + status_to_earn_max = old_quest->GetStatusToEarnMax(); } Quest::~Quest(){ @@ -905,7 +911,7 @@ EQ2Packet* Quest::OfferQuest(int16 version, Player* player){ if (reward_coins_max) packet->setDataByName("max_coin", reward_coins_max); } - packet->setDataByName("status_points", reward_status); + packet->setDataByName("status_points", GetStatusEarned() > 0 ? GetStatusEarned() : reward_status); if(reward_comment.length() > 0) packet->setDataByName("text", reward_comment.c_str()); if(reward_items.size() > 0){ @@ -1263,7 +1269,7 @@ EQ2Packet* Quest::QuestJournalReply(int16 version, int32 player_crc, Player* pla packet->setDataByName(tmp.c_str(), reward_coins_max); } tmp = reward_str + "status_points"; - packet->setDataByName(tmp.c_str(), reward_status); + packet->setDataByName(tmp.c_str(), GetStatusEarned() > 0 ? GetStatusEarned() : reward_status); if (reward_comment.length() > 0) { tmp = reward_str + "text"; packet->setDataByName(tmp.c_str(), reward_comment.c_str()); diff --git a/source/WorldServer/Quests.h b/source/WorldServer/Quests.h index a70942f..7adc044 100644 --- a/source/WorldServer/Quests.h +++ b/source/WorldServer/Quests.h @@ -283,6 +283,13 @@ public: ///Sets the quest hidden flag ///Value to set the hidden flag to void SetHidden(bool val) { m_hidden = val; SetSaveNeeded(true); } + + ///Sets the quest status earned + ///Value to set the quest status earned + void SetStatusEarned(int32 status_) { m_status = status_; SetSaveNeeded(true); } + + ///Gets the quest status earned + int32 GetStatusEarned() { return m_status; } ///Gets the step timer ///Unix timestamp (int32) @@ -325,6 +332,13 @@ public: void SetQuestShareableFlag(int32 flag) { quest_shareable_flag = flag; } void SetCanDeleteQuest(bool newval) { can_delete_quest = newval; } + + void SetStatusToEarnMin(int32 value_) { status_to_earn_min = value_; } + void SetStatusToEarnMax(int32 value_) { status_to_earn_max = value_; } + + int32 GetStatusToEarnMin() { return status_to_earn_min; } + int32 GetStatusToEarnMax() { return status_to_earn_max; } + int32 GetQuestShareableFlag() { return quest_shareable_flag; } bool CanDeleteQuest() { return can_delete_quest; } @@ -401,6 +415,7 @@ protected: bool yellow_name; int32 m_questFlags; bool m_hidden; + int32 m_status; int32 m_timestamp; // timer for a quest step int32 m_timerStep; // used for the fail action when timer expires @@ -411,6 +426,8 @@ protected: std::string quest_temporary_description; int32 quest_shareable_flag; bool can_delete_quest; + int32 status_to_earn_min; + int32 status_to_earn_max; }; class MasterQuestList{ diff --git a/source/WorldServer/WorldDatabase.cpp b/source/WorldServer/WorldDatabase.cpp index 12b6378..a058ec3 100644 --- a/source/WorldServer/WorldDatabase.cpp +++ b/source/WorldServer/WorldDatabase.cpp @@ -2795,7 +2795,7 @@ void WorldDatabase::SaveCharacterQuests(Client* client){ } if(itr->second && itr->second->GetSaveNeeded()){ query.AddQueryAsync(client->GetCharacterID(), this,Q_INSERT, "insert ignore into character_quests (char_id, quest_id, given_date, quest_giver) values(%u, %u, now(), %u)", client->GetCharacterID(), itr->first, itr->second->GetQuestGiver()); - query.AddQueryAsync(client->GetCharacterID(), this,Q_UPDATE, "update character_quests set tracked = %i, quest_flags = %u, hidden = %i, complete_count = %u where char_id = %u and quest_id = %u", itr->second->IsTracked() ? 1 : 0, itr->second->GetQuestFlags(), itr->second->IsHidden() ? 1 : 0, itr->second->GetCompleteCount(), client->GetCharacterID(), itr->first); + query.AddQueryAsync(client->GetCharacterID(), this,Q_UPDATE, "update character_quests set tracked = %i, quest_flags = %u, hidden = %i, complete_count = %u, status_to_earn = %u where char_id = %u and quest_id = %u", itr->second->IsTracked() ? 1 : 0, itr->second->GetQuestFlags(), itr->second->IsHidden() ? 1 : 0, itr->second->GetCompleteCount(), itr->second->GetStatusEarned(), client->GetCharacterID(), itr->first); SaveCharacterQuestProgress(client, itr->second); itr->second->SetSaveNeeded(false); } @@ -2809,7 +2809,7 @@ void WorldDatabase::SaveCharacterQuests(Client* client){ /* incase the quest is completed before the quest could be inserted in the PlayerQuests loop, we first try to insert it. If it already exists then we can just update * the completed_date */ - query.AddQueryAsync(client->GetCharacterID(), this,Q_INSERT, "INSERT INTO character_quests (char_id, quest_id, quest_giver, current_quest, given_date, completed_date, complete_count) values (%u,%u,%u,0, now(),now(), %u) ON DUPLICATE KEY UPDATE completed_date = now(), complete_count = %u, current_quest = 0", client->GetCharacterID(), itr->first, itr->second->GetQuestGiver(), itr->second->GetCompleteCount(), itr->second->GetCompleteCount()); + query.AddQueryAsync(client->GetCharacterID(), this,Q_INSERT, "INSERT INTO character_quests (char_id, quest_id, quest_giver, current_quest, given_date, completed_date, complete_count, status_to_earn) values (%u,%u,%u,0, now(),now(), %u, %u) ON DUPLICATE KEY UPDATE completed_date = now(), complete_count = %u, status_to_earn = %u, current_quest = 0", client->GetCharacterID(), itr->first, itr->second->GetQuestGiver(), itr->second->GetCompleteCount(), itr->second->GetStatusEarned(), itr->second->GetCompleteCount(), itr->second->GetStatusEarned()); itr->second->SetSaveNeeded(false); } } @@ -2877,7 +2877,7 @@ void WorldDatabase::LoadCharacterQuestProgress(Client* client){ void WorldDatabase::LoadCharacterQuests(Client* client){ LogWrite(PLAYER__DEBUG, 0, "Player", "Loading Character Quests..."); Query query; - MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT quest_id, DAY(given_date), MONTH(given_date), YEAR(given_date), DAY(completed_date), MONTH(completed_date), YEAR(completed_date), quest_giver, tracked, quest_flags, hidden, UNIX_TIMESTAMP(given_date), UNIX_TIMESTAMP(completed_date), complete_count FROM character_quests WHERE char_id=%u ORDER BY current_quest", client->GetCharacterID()); + MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT quest_id, DAY(given_date), MONTH(given_date), YEAR(given_date), DAY(completed_date), MONTH(completed_date), YEAR(completed_date), quest_giver, tracked, quest_flags, hidden, UNIX_TIMESTAMP(given_date), UNIX_TIMESTAMP(completed_date), complete_count, status_to_earn FROM character_quests WHERE char_id=%u ORDER BY current_quest", client->GetCharacterID()); if(result && mysql_num_rows(result) > 0) { MYSQL_ROW row; Quest* quest = 0; @@ -2914,6 +2914,7 @@ void WorldDatabase::LoadCharacterQuests(Client* client){ addQuest = false; quest->SetCompleteCount(atoi(row[13])); + quest->SetStatusEarned(atoul(row[14])); } if (addQuest) { @@ -5348,7 +5349,7 @@ void WorldDatabase::FixBugReport(){ int32 WorldDatabase::LoadQuests(){ Query query; MYSQL_ROW row; - std::string querystr = std::string("SELECT `quest_id`, `name`, `type`, `zone`, `level`, `enc_level`, `description`, `lua_script`, `completed_text`, `spawn_id`, `shareable_flag`, `deleteable` FROM `quests`"); + std::string querystr = std::string("SELECT `quest_id`, `name`, `type`, `zone`, `level`, `enc_level`, `description`, `lua_script`, `completed_text`, `spawn_id`, `shareable_flag`, `deleteable`, `status_to_earn_min`, `status_to_earn_max` FROM `quests`"); MYSQL_RES* result = query.RunQuery2(Q_SELECT, querystr.c_str()); Quest* quest = 0; char* name = 0; @@ -5396,6 +5397,8 @@ int32 WorldDatabase::LoadQuests(){ quest->SetEncounterLevel(enc_level); quest->SetQuestShareableFlag(atoul(row[10])); quest->SetCanDeleteQuest(atoul(row[11])); + quest->SetStatusToEarnMin(atoul(row[12])); + quest->SetStatusToEarnMax(atoul(row[13])); total++; master_quest_list.AddQuest(id, quest); } diff --git a/source/WorldServer/client.cpp b/source/WorldServer/client.cpp index 06fa747..ac43c22 100644 --- a/source/WorldServer/client.cpp +++ b/source/WorldServer/client.cpp @@ -6937,6 +6937,24 @@ void Client::CheckPlayerQuestsSpellUpdate(Spell* spell) { } void Client::AddPendingQuest(Quest* quest, bool forced) { + if(!quest->GetStatusEarned() && (quest->GetStatusToEarnMin() || quest->GetStatusToEarnMax())) { + int32 min = 0; + int32 max = 0; + if(quest->GetStatusToEarnMin() > 0 && quest->GetStatusToEarnMin() > quest->GetStatusToEarnMax()) { + min = quest->GetStatusToEarnMax(); + max = quest->GetStatusToEarnMin(); + } + else if(quest->GetStatusToEarnMin() < quest->GetStatusToEarnMax()) { + min = quest->GetStatusToEarnMin(); + max = quest->GetStatusToEarnMax(); + } + else { + quest->SetStatusEarned(min); + } + if(min && max) { + quest->SetStatusEarned(MakeRandomInt(min, max)); + } + } if (version <= 372 || forced) { //this client doesn't ask if you want the quest, so auto accept MPendingQuestAccept.lock(); player->pending_quests[quest->GetQuestID()] = quest; @@ -7309,7 +7327,7 @@ void Client::AcceptQuestReward(Quest* quest, int32 item_id) { player->GetInfoStruct()->add_status_points(quest->GetStatusTmpReward()); } else { - player->GetInfoStruct()->add_status_points(quest->GetStatusPoints()); + player->GetInfoStruct()->add_status_points(quest->GetStatusEarned() ? quest->GetStatusEarned() : quest->GetStatusPoints()); } quest->SetQuestTemporaryState(false); @@ -7493,7 +7511,7 @@ void Client::DisplayQuestComplete(Quest* quest, bool tempReward, std::string cus return; if (GetVersion() <= 561) { - DisplayQuestRewards(quest, 0, quest->GetRewardItems(), quest->GetSelectableRewardItems(), quest->GetRewardFactions(), "Quest Complete!", quest->GetStatusPoints(), tempReward ? customDescription.c_str() : quest->GetCompletedDescription(), was_displayed); + DisplayQuestRewards(quest, 0, quest->GetRewardItems(), quest->GetSelectableRewardItems(), quest->GetRewardFactions(), "Quest Complete!", quest->GetStatusEarned() ? quest->GetStatusEarned() : quest->GetStatusPoints(), tempReward ? customDescription.c_str() : quest->GetCompletedDescription(), was_displayed); return; } PacketStruct* packet = configReader.getStruct("WS_QuestComplete", GetVersion()); @@ -7520,7 +7538,7 @@ void Client::DisplayQuestComplete(Quest* quest, bool tempReward, std::string cus { packet->setDataByName("max_coin", quest->GetCoinTmpReward()); packet->setDataByName("min_coin", quest->GetCoinTmpReward()); - packet->setDataByName("status_points", quest->GetStatusPoints()); + packet->setDataByName("status_points", quest->GetStatusEarned() ? quest->GetStatusEarned() : quest->GetStatusPoints()); } else { @@ -7534,7 +7552,7 @@ void Client::DisplayQuestComplete(Quest* quest, bool tempReward, std::string cus quest->SetGeneratedCoin(rewarded_coin); packet->setDataByName("max_coin", rewarded_coin); packet->setDataByName("min_coin", rewarded_coin); - packet->setDataByName("status_points", quest->GetStatusPoints()); + packet->setDataByName("status_points", quest->GetStatusEarned() ? quest->GetStatusEarned() : quest->GetStatusPoints()); } if (tempReward) {