mirror of
https://github.com/ErikasKontenis/SabrehavenServer.git
synced 2025-04-29 17:19:20 +02:00
first implementation of quest log need to review everything
This commit is contained in:
parent
abed251a30
commit
871013018e
@ -37,7 +37,7 @@ replaceKickOnLogin = true
|
||||
maxPacketsPerSecond = -1
|
||||
autoStackCumulatives = false
|
||||
moneyRate = 1
|
||||
clientVersion = 780
|
||||
clientVersion = 792
|
||||
|
||||
-- Deaths
|
||||
-- NOTE: Leave deathLosePercent as -1 if you want to use the default
|
||||
|
1167
data/XML/quests.xml
Normal file
1167
data/XML/quests.xml
Normal file
File diff suppressed because it is too large
Load Diff
@ -33,6 +33,9 @@ local reloadTypes = {
|
||||
["npc"] = { targetType = RELOAD_TYPE_NPCS, name = "npcs" },
|
||||
["npcs"] = { targetType = RELOAD_TYPE_NPCS, name = "npcs" },
|
||||
|
||||
["quest"] = { targetType = RELOAD_TYPE_QUESTS, name = "quests" },
|
||||
["quests"] = { targetType = RELOAD_TYPE_QUESTS, name = "quests" },
|
||||
|
||||
["raid"] = { targetType = RELOAD_TYPE_RAIDS, name = "raids" },
|
||||
["raids"] = { targetType = RELOAD_TYPE_RAIDS, name = "raids" },
|
||||
|
||||
|
30
src/game.cpp
30
src/game.cpp
@ -104,6 +104,8 @@ void Game::setGameState(GameState_t newState)
|
||||
raids.loadFromXml();
|
||||
raids.startup();
|
||||
|
||||
quests.loadFromXml();
|
||||
|
||||
loadMotdNum();
|
||||
loadPlayersRecord();
|
||||
|
||||
@ -2914,6 +2916,31 @@ void Game::playerChangeOutfit(uint32_t playerId, Outfit_t outfit)
|
||||
}
|
||||
}
|
||||
|
||||
void Game::playerShowQuestLog(uint32_t playerId)
|
||||
{
|
||||
Player* player = getPlayerByID(playerId);
|
||||
if (!player) {
|
||||
return;
|
||||
}
|
||||
|
||||
player->sendQuestLog();
|
||||
}
|
||||
|
||||
void Game::playerShowQuestLine(uint32_t playerId, uint16_t questId)
|
||||
{
|
||||
Player* player = getPlayerByID(playerId);
|
||||
if (!player) {
|
||||
return;
|
||||
}
|
||||
|
||||
Quest* quest = quests.getQuestByID(questId);
|
||||
if (!quest) {
|
||||
return;
|
||||
}
|
||||
|
||||
player->sendQuestLine(quest);
|
||||
}
|
||||
|
||||
void Game::playerSay(uint32_t playerId, uint16_t channelId, SpeakClasses type,
|
||||
const std::string& receiver, const std::string& text)
|
||||
{
|
||||
@ -4599,6 +4626,8 @@ bool Game::reload(ReloadTypes_t reloadType)
|
||||
Npcs::reload();
|
||||
return true;
|
||||
}
|
||||
|
||||
case RELOAD_TYPE_QUESTS: return quests.reload();
|
||||
case RELOAD_TYPE_RAIDS: return raids.reload() && raids.startup();
|
||||
|
||||
case RELOAD_TYPE_SPELLS: {
|
||||
@ -4636,6 +4665,7 @@ bool Game::reload(ReloadTypes_t reloadType)
|
||||
raids.reload() && raids.startup();
|
||||
g_talkActions->reload();
|
||||
Item::items.reload();
|
||||
quests.reload();
|
||||
g_globalEvents->reload();
|
||||
g_events->load();
|
||||
g_chat->load();
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "raids.h"
|
||||
#include "npc.h"
|
||||
#include "wildcardtree.h"
|
||||
#include "quests.h"
|
||||
|
||||
class ServiceManager;
|
||||
class Creature;
|
||||
@ -387,6 +388,8 @@ class Game
|
||||
void playerRequestRemoveVip(uint32_t playerId, uint32_t guid);
|
||||
void playerTurn(uint32_t playerId, Direction dir);
|
||||
void playerRequestOutfit(uint32_t playerId);
|
||||
void playerShowQuestLog(uint32_t playerId);
|
||||
void playerShowQuestLine(uint32_t playerId, uint16_t questId);
|
||||
void playerSay(uint32_t playerId, uint16_t channelId, SpeakClasses type,
|
||||
const std::string& receiver, const std::string& text);
|
||||
void playerChangeOutfit(uint32_t playerId, Outfit_t outfit);
|
||||
@ -493,6 +496,7 @@ class Game
|
||||
Groups groups;
|
||||
Map map;
|
||||
Raids raids;
|
||||
Quests quests;
|
||||
|
||||
protected:
|
||||
bool playerSaySpell(Player* player, SpeakClasses type, const std::string& text);
|
||||
|
@ -495,7 +495,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result)
|
||||
query << "SELECT `key`, `value` FROM `player_storage` WHERE `player_id` = " << player->getGUID();
|
||||
if ((result = db->storeQuery(query.str()))) {
|
||||
do {
|
||||
player->addStorageValue(result->getNumber<uint32_t>("key"), result->getNumber<int32_t>("value"));
|
||||
player->addStorageValue(result->getNumber<uint32_t>("key"), result->getNumber<int32_t>("value"), true);
|
||||
} while (result->next());
|
||||
}
|
||||
|
||||
|
@ -507,7 +507,7 @@ uint16_t Player::getLookCorpse() const
|
||||
}
|
||||
}
|
||||
|
||||
void Player::addStorageValue(const uint32_t key, const int32_t value)
|
||||
void Player::addStorageValue(const uint32_t key, const int32_t value, const bool isLogin/* = false*/)
|
||||
{
|
||||
if (IS_IN_KEYRANGE(key, RESERVED_RANGE)) {
|
||||
if (IS_IN_KEYRANGE(key, OUTFITS_RANGE)) {
|
||||
@ -524,8 +524,20 @@ void Player::addStorageValue(const uint32_t key, const int32_t value)
|
||||
}
|
||||
|
||||
if (value != -1) {
|
||||
int32_t oldValue;
|
||||
getStorageValue(key, oldValue);
|
||||
|
||||
storageMap[key] = value;
|
||||
} else {
|
||||
|
||||
if (!isLogin && g_game.getClientVersion() >= CLIENT_VERSION_790) {
|
||||
auto currentFrameTime = g_dispatcher.getDispatcherCycle();
|
||||
if (lastQuestlogUpdate != currentFrameTime && g_game.quests.isQuestStorage(key, value, oldValue)) {
|
||||
lastQuestlogUpdate = currentFrameTime;
|
||||
sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your questlog has been updated.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
storageMap.erase(key);
|
||||
}
|
||||
}
|
||||
|
13
src/player.h
13
src/player.h
@ -273,7 +273,7 @@ class Player final : public Creature, public Cylinder
|
||||
|
||||
bool canOpenCorpse(uint32_t ownerId) const;
|
||||
|
||||
void addStorageValue(const uint32_t key, const int32_t value);
|
||||
void addStorageValue(const uint32_t key, const int32_t value, const bool isLogin = false);
|
||||
bool getStorageValue(const uint32_t key, int32_t& value) const;
|
||||
void genReservedStorageRange();
|
||||
|
||||
@ -854,6 +854,16 @@ class Player final : public Creature, public Cylinder
|
||||
client->sendOpenPrivateChannel(receiver);
|
||||
}
|
||||
}
|
||||
void sendQuestLog() {
|
||||
if (client) {
|
||||
client->sendQuestLog();
|
||||
}
|
||||
}
|
||||
void sendQuestLine(const Quest* quest) {
|
||||
if (client) {
|
||||
client->sendQuestLine(quest);
|
||||
}
|
||||
}
|
||||
void sendOutfitWindow() {
|
||||
if (client) {
|
||||
client->sendOutfitWindow();
|
||||
@ -1012,6 +1022,7 @@ class Player final : public Creature, public Cylinder
|
||||
uint64_t experience = 0;
|
||||
uint64_t manaSpent = 0;
|
||||
uint64_t bankBalance = 0;
|
||||
uint64_t lastQuestlogUpdate = 0;
|
||||
int64_t lastAttack = 0;
|
||||
int64_t lastFailedFollow = 0;
|
||||
int64_t lastPing;
|
||||
|
@ -429,6 +429,8 @@ void ProtocolGame::parsePacket(NetworkMessage& msg)
|
||||
case 0xE6: parseBugReport(msg); break;
|
||||
case 0xE7: /* violation window */ break;
|
||||
case 0xE8: parseDebugAssert(msg); break;
|
||||
case 0xF0: addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerShowQuestLog, player->getID()); break;
|
||||
case 0xF1: parseQuestLine(msg); break;
|
||||
default:
|
||||
std::cout << "Player: " << player->getName() << " sent an unknown packet header: 0x" << std::hex << static_cast<uint16_t>(recvbyte) << std::dec << "!" << std::endl;
|
||||
break;
|
||||
@ -963,6 +965,12 @@ void ProtocolGame::parsePassPartyLeadership(NetworkMessage& msg)
|
||||
addGameTask(&Game::playerPassPartyLeadership, player->getID(), targetId);
|
||||
}
|
||||
|
||||
void ProtocolGame::parseQuestLine(NetworkMessage& msg)
|
||||
{
|
||||
uint16_t questId = msg.get<uint16_t>();
|
||||
addGameTask(&Game::playerShowQuestLine, player->getID(), questId);
|
||||
}
|
||||
|
||||
void ProtocolGame::parseSeekInContainer(NetworkMessage& msg)
|
||||
{
|
||||
uint8_t containerId = msg.getByte();
|
||||
@ -1205,7 +1213,39 @@ void ProtocolGame::sendContainer(uint8_t cid, const Container* container, bool h
|
||||
writeToOutputBuffer(msg);
|
||||
}
|
||||
|
||||
void ProtocolGame::sendQuestLog()
|
||||
{
|
||||
NetworkMessage msg;
|
||||
msg.addByte(0xF0);
|
||||
msg.add<uint16_t>(g_game.quests.getQuestsCount(player));
|
||||
|
||||
for (const Quest& quest : g_game.quests.getQuests()) {
|
||||
if (quest.isStarted(player)) {
|
||||
msg.add<uint16_t>(quest.getID());
|
||||
msg.addString(quest.getName());
|
||||
msg.addByte(quest.isCompleted(player));
|
||||
}
|
||||
}
|
||||
|
||||
writeToOutputBuffer(msg);
|
||||
}
|
||||
|
||||
void ProtocolGame::sendQuestLine(const Quest* quest)
|
||||
{
|
||||
NetworkMessage msg;
|
||||
msg.addByte(0xF1);
|
||||
msg.add<uint16_t>(quest->getID());
|
||||
msg.addByte(quest->getMissionsCount(player));
|
||||
|
||||
for (const Mission& mission : quest->getMissions()) {
|
||||
if (mission.isStarted(player)) {
|
||||
msg.addString(mission.getName(player));
|
||||
msg.addString(mission.getDescription(player));
|
||||
}
|
||||
}
|
||||
|
||||
writeToOutputBuffer(msg);
|
||||
}
|
||||
|
||||
void ProtocolGame::sendTradeItemRequest(const std::string& traderName, const Item* item, bool ack)
|
||||
{
|
||||
|
@ -113,6 +113,8 @@ class ProtocolGame final : public Protocol
|
||||
void parseTextWindow(NetworkMessage& msg);
|
||||
void parseHouseWindow(NetworkMessage& msg);
|
||||
|
||||
void parseQuestLine(NetworkMessage& msg);
|
||||
|
||||
void parseInviteToParty(NetworkMessage& msg);
|
||||
void parseJoinParty(NetworkMessage& msg);
|
||||
void parseRevokePartyInvite(NetworkMessage& msg);
|
||||
@ -156,6 +158,9 @@ class ProtocolGame final : public Protocol
|
||||
void sendCreatureTurn(const Creature* creature, uint32_t stackpos);
|
||||
void sendCreatureSay(const Creature* creature, SpeakClasses type, const std::string& text, const Position* pos = nullptr);
|
||||
|
||||
void sendQuestLog();
|
||||
void sendQuestLine(const Quest* quest);
|
||||
|
||||
void sendCancelWalk();
|
||||
void sendChangeSpeed(const Creature* creature, uint32_t speed);
|
||||
void sendCancelTarget();
|
||||
|
230
src/quests.cpp
Normal file
230
src/quests.cpp
Normal file
@ -0,0 +1,230 @@
|
||||
/**
|
||||
* The Forgotten Server - a free and open-source MMORPG server emulator
|
||||
* Copyright (C) 2019 Mark Samman <mark.samman@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "otpch.h"
|
||||
|
||||
#include "quests.h"
|
||||
|
||||
#include "pugicast.h"
|
||||
|
||||
std::string Mission::getDescription(Player* player) const
|
||||
{
|
||||
int32_t value;
|
||||
player->getStorageValue(storageID, value);
|
||||
|
||||
if (!mainDescription.empty()) {
|
||||
std::string desc = mainDescription;
|
||||
replaceString(desc, "|STATE|", std::to_string(value));
|
||||
replaceString(desc, "\\n", "\n");
|
||||
return desc;
|
||||
}
|
||||
|
||||
if (ignoreEndValue) {
|
||||
for (int32_t current = endValue; current >= startValue; current--) {
|
||||
if (value >= current) {
|
||||
auto sit = descriptions.find(current);
|
||||
if (sit != descriptions.end()) {
|
||||
return sit->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int32_t current = endValue; current >= startValue; current--) {
|
||||
if (value == current) {
|
||||
auto sit = descriptions.find(current);
|
||||
if (sit != descriptions.end()) {
|
||||
return sit->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "An error has occurred, please contact a gamemaster.";
|
||||
}
|
||||
|
||||
bool Mission::isStarted(Player* player) const
|
||||
{
|
||||
if (!player) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t value;
|
||||
if (!player->getStorageValue(storageID, value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value < startValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ignoreEndValue && value > endValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mission::isCompleted(Player* player) const
|
||||
{
|
||||
if (!player) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t value;
|
||||
if (!player->getStorageValue(storageID, value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ignoreEndValue) {
|
||||
return value >= endValue;
|
||||
}
|
||||
|
||||
return value == endValue;
|
||||
}
|
||||
|
||||
std::string Mission::getName(Player* player) const
|
||||
{
|
||||
if (isCompleted(player)) {
|
||||
return name + " (completed)";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
uint16_t Quest::getMissionsCount(Player* player) const
|
||||
{
|
||||
uint16_t count = 0;
|
||||
for (const Mission& mission : missions) {
|
||||
if (mission.isStarted(player)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bool Quest::isCompleted(Player* player) const
|
||||
{
|
||||
for (const Mission& mission : missions) {
|
||||
if (!mission.isCompleted(player)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Quest::isStarted(Player* player) const
|
||||
{
|
||||
if (!player) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t value;
|
||||
if (!player->getStorageValue(startStorageID, value) || value < startStorageValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Quests::reload()
|
||||
{
|
||||
quests.clear();
|
||||
return loadFromXml();
|
||||
}
|
||||
|
||||
bool Quests::loadFromXml()
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result = doc.load_file("data/XML/quests.xml");
|
||||
if (!result) {
|
||||
printXMLError("Error - Quests::loadFromXml", "data/XML/quests.xml", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t id = 0;
|
||||
for (auto questNode : doc.child("quests").children()) {
|
||||
quests.emplace_back(
|
||||
questNode.attribute("name").as_string(),
|
||||
++id,
|
||||
pugi::cast<int32_t>(questNode.attribute("startstorageid").value()),
|
||||
pugi::cast<int32_t>(questNode.attribute("startstoragevalue").value())
|
||||
);
|
||||
Quest& quest = quests.back();
|
||||
|
||||
for (auto missionNode : questNode.children()) {
|
||||
std::string mainDescription = missionNode.attribute("description").as_string();
|
||||
|
||||
quest.missions.emplace_back(
|
||||
missionNode.attribute("name").as_string(),
|
||||
pugi::cast<int32_t>(missionNode.attribute("storageid").value()),
|
||||
pugi::cast<int32_t>(missionNode.attribute("startvalue").value()),
|
||||
pugi::cast<int32_t>(missionNode.attribute("endvalue").value()),
|
||||
missionNode.attribute("ignoreendvalue").as_bool()
|
||||
);
|
||||
Mission& mission = quest.missions.back();
|
||||
|
||||
if (mainDescription.empty()) {
|
||||
for (auto missionStateNode : missionNode.children()) {
|
||||
int32_t missionId = pugi::cast<int32_t>(missionStateNode.attribute("id").value());
|
||||
mission.descriptions.emplace(missionId, missionStateNode.attribute("description").as_string());
|
||||
}
|
||||
}
|
||||
else {
|
||||
mission.mainDescription = mainDescription;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Quest* Quests::getQuestByID(uint16_t id)
|
||||
{
|
||||
for (Quest& quest : quests) {
|
||||
if (quest.id == id) {
|
||||
return ?
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint16_t Quests::getQuestsCount(Player* player) const
|
||||
{
|
||||
uint16_t count = 0;
|
||||
for (const Quest& quest : quests) {
|
||||
if (quest.isStarted(player)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bool Quests::isQuestStorage(const uint32_t key, const int32_t value, const int32_t oldValue) const
|
||||
{
|
||||
for (const Quest& quest : quests) {
|
||||
if (quest.getStartStorageId() == key && quest.getStartStorageValue() == value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const Mission& mission : quest.getMissions()) {
|
||||
if (mission.getStorageId() == key && value >= mission.getStartStorageValue() && value <= mission.getEndStorageValue()) {
|
||||
return mission.mainDescription.empty() || oldValue < mission.getStartStorageValue() || oldValue > mission.getEndStorageValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
119
src/quests.h
Normal file
119
src/quests.h
Normal file
@ -0,0 +1,119 @@
|
||||
/**
|
||||
* The Forgotten Server - a free and open-source MMORPG server emulator
|
||||
* Copyright (C) 2019 Mark Samman <mark.samman@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef FS_QUESTS_H_16E44051F23547BE8097F8EA9FCAACA0
|
||||
#define FS_QUESTS_H_16E44051F23547BE8097F8EA9FCAACA0
|
||||
|
||||
#include "player.h"
|
||||
#include "networkmessage.h"
|
||||
|
||||
class Mission;
|
||||
class Quest;
|
||||
|
||||
using MissionsList = std::list<Mission>;
|
||||
using QuestsList = std::list<Quest>;
|
||||
|
||||
class Mission
|
||||
{
|
||||
public:
|
||||
Mission(std::string name, int32_t storageID, int32_t startValue, int32_t endValue, bool ignoreEndValue) :
|
||||
name(std::move(name)), storageID(storageID), startValue(startValue), endValue(endValue), ignoreEndValue(ignoreEndValue) {}
|
||||
|
||||
bool isCompleted(Player* player) const;
|
||||
bool isStarted(Player* player) const;
|
||||
std::string getName(Player* player) const;
|
||||
std::string getDescription(Player* player) const;
|
||||
|
||||
uint32_t getStorageId() const {
|
||||
return storageID;
|
||||
}
|
||||
int32_t getStartStorageValue() const {
|
||||
return startValue;
|
||||
}
|
||||
int32_t getEndStorageValue() const {
|
||||
return endValue;
|
||||
}
|
||||
|
||||
std::map<int32_t, std::string> descriptions;
|
||||
std::string mainDescription;
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
uint32_t storageID;
|
||||
int32_t startValue, endValue;
|
||||
bool ignoreEndValue;
|
||||
};
|
||||
|
||||
class Quest
|
||||
{
|
||||
public:
|
||||
Quest(std::string name, uint16_t id, int32_t startStorageID, int32_t startStorageValue) :
|
||||
name(std::move(name)), startStorageID(startStorageID), startStorageValue(startStorageValue), id(id) {}
|
||||
|
||||
bool isCompleted(Player* player) const;
|
||||
bool isStarted(Player* player) const;
|
||||
uint16_t getID() const {
|
||||
return id;
|
||||
}
|
||||
std::string getName() const {
|
||||
return name;
|
||||
}
|
||||
uint16_t getMissionsCount(Player* player) const;
|
||||
|
||||
uint32_t getStartStorageId() const {
|
||||
return startStorageID;
|
||||
}
|
||||
int32_t getStartStorageValue() const {
|
||||
return startStorageValue;
|
||||
}
|
||||
|
||||
const MissionsList& getMissions() const {
|
||||
return missions;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
|
||||
uint32_t startStorageID;
|
||||
int32_t startStorageValue;
|
||||
uint16_t id;
|
||||
|
||||
MissionsList missions;
|
||||
|
||||
friend class Quests;
|
||||
};
|
||||
|
||||
class Quests
|
||||
{
|
||||
public:
|
||||
const QuestsList& getQuests() const {
|
||||
return quests;
|
||||
}
|
||||
|
||||
bool loadFromXml();
|
||||
Quest* getQuestByID(uint16_t id);
|
||||
bool isQuestStorage(const uint32_t key, const int32_t value, const int32_t oldValue) const;
|
||||
uint16_t getQuestsCount(Player* player) const;
|
||||
bool reload();
|
||||
|
||||
private:
|
||||
QuestsList quests;
|
||||
};
|
||||
|
||||
#endif
|
@ -217,6 +217,7 @@
|
||||
<ClCompile Include="..\src\waitlist.cpp" />
|
||||
<ClCompile Include="..\src\wildcardtree.cpp" />
|
||||
<ClCompile Include="..\src\xtea.cpp" />
|
||||
<ClCompile Include="..\src\quests.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\account.h" />
|
||||
@ -295,6 +296,7 @@
|
||||
<ClInclude Include="..\src\waitlist.h" />
|
||||
<ClInclude Include="..\src\wildcardtree.h" />
|
||||
<ClInclude Include="..\src\xtea.h" />
|
||||
<ClInclude Include="..\src\quests.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
Loading…
x
Reference in New Issue
Block a user