Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quest moved to lua (Part 2) #4388

Merged
merged 7 commits into from
Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions data/XML/quests.xml

This file was deleted.

1 change: 1 addition & 0 deletions data/events/events.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<event class="Player" method="onWrapItem" enabled="1" />
<event class="Player" method="onInventoryUpdate" enabled="1" />
<event class="Player" method="onNetworkMessage" enabled="1" />
<event class="Player" method="onUpdateStorage" enabled="1" />

<!-- Monster methods -->
<event class="Monster" method="onDropLoot" enabled="1" />
Expand Down
7 changes: 7 additions & 0 deletions data/events/scripts/player.lua
Original file line number Diff line number Diff line change
Expand Up @@ -357,3 +357,10 @@ function Player:onNetworkMessage(recvByte, msg)

handler(self, msg)
end

function Player:onUpdateStorage(key, value, oldValue, isLogin)
local onUpdateStorage = EventCallback.onUpdateStorage
if onUpdateStorage then
onUpdateStorage(self, key, value, oldValue, isLogin)
end
end
1 change: 1 addition & 0 deletions data/lib/core/core.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ dofile('data/lib/core/position.lua')
dofile('data/lib/core/teleport.lua')
dofile('data/lib/core/tile.lua')
dofile('data/lib/core/vocation.lua')
dofile('data/lib/core/quests.lua')
66 changes: 66 additions & 0 deletions data/lib/core/game.lua
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,69 @@ end
function Game.setStorageValue(key, value)
globalStorageTable[key] = value
end

do
local quests = {}
local missions = {}
local trackedQuests = {}

function Game.getQuests() return quests end
function Game.getMissions() return missions end
function Game.getTrackedQuests() return trackedQuests end

function Game.getQuestById(id) return quests[id] end
function Game.getMissionById(id) return missions[id] end

function Game.clearQuests()
quests = {}
missions = {}
for playerId, _ in pairs(trackedQuests) do
local player = Player(playerId)
if player then
player:sendQuestTracker({})
end
end
trackedQuests = {}
return true
end

function Game.createQuest(name, quest)
if not isScriptsInterface() then
return
end

if type(quest) == "table" then
setmetatable(quest, Quest)
quest.id = -1
quest.name = name
if type(quest.missions) ~= "table" then
quest.missions = {}
end

return quest
end

quest = setmetatable({}, Quest)
quest.id = -1
quest.name = name
quest.storageId = 0
quest.storageValue = 0
quest.missions = {}
return quest
end

function Game.isQuestStorage(key, value, oldValue)
for _, quest in pairs(quests) do
if quest.storageId == key and quest.storageValue == value then
return true
end
end

for _, mission in pairs(missions) do
if mission.storageId == key and value >= mission.startValue and value <= mission.endValue then
return not mission.description or oldValue < mission.startValue or oldValue > mission.endValue
end
end
return false
end
end
105 changes: 105 additions & 0 deletions data/lib/core/player.lua
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,111 @@ function Player.isPromoted(self)
return vocation:getId() ~= fromVocId
end

function Player.getMaxTrackedQuests(self)
return configManager.getNumber(self:isPremium() and configKeys.QUEST_TRACKER_PREMIUM_LIMIT or configKeys.QUEST_TRACKER_FREE_LIMIT)
end

function Player.getQuests(self)
local quests = {}
for _, quest in pairs(Game.getQuests()) do
if quest:isStarted(self) then
quests[#quests + 1] = quest
end
end
return quests
end

function Player.sendQuestLog(self)
local msg = NetworkMessage()
msg:addByte(0xF0)
local quests = self:getQuests()
msg:addU16(#quests)

for _, quest in pairs(quests) do
msg:addU16(quest.id)
msg:addString(quest.name)
msg:addByte(quest:isCompleted(self))
end

msg:sendToPlayer(self)
msg:delete()
return true
end

function Player.sendQuestLine(self, quest)
local msg = NetworkMessage()
msg:addByte(0xF1)
msg:addU16(quest.id)
local missions = quest:getMissions(self)
msg:addByte(#missions)

for _, mission in pairs(missions) do
msg:addU16(mission.id)
msg:addString(mission:getName(self))
msg:addString(mission:getDescription(self))
end

msg:sendToPlayer(self)
msg:delete()
return true
end

function Player.getTrackedQuests(self, missionsId)
local playerId = self:getId()
local maxTrackedQuests = self:getMaxTrackedQuests()
local trackedQuests = {}
Game.getTrackedQuests()[playerId] = trackedQuests
local quests = Game.getQuests()
local missions = Game.getMissions()
local trackeds = 0
for _, missionId in pairs(missionsId) do
local mission = missions[missionId]
if mission and mission:isStarted(self) then
trackedQuests[mission] = quests[mission.questId]
MillhioreBT marked this conversation as resolved.
Show resolved Hide resolved
trackeds = trackeds + 1
if trackeds >= maxTrackedQuests then
break
end
end
end
return trackedQuests, trackeds
end

function Player.sendQuestTracker(self, missionsId)
local msg = NetworkMessage()
msg:addByte(0xD0)
msg:addByte(1)

local trackedQuests, trackeds = self:getTrackedQuests(missionsId)
msg:addByte(self:getMaxTrackedQuests() - trackeds)
msg:addByte(trackeds)

for mission, quest in pairs(trackedQuests or {}) do
msg:addU16(mission.id)
msg:addString(quest.name)
msg:addString(mission:getName(self))
msg:addString(mission:getDescription(self))
end

msg:sendToPlayer(self)
msg:delete()
return true
end

function Player.sendUpdateQuestTracker(self, mission)
local msg = NetworkMessage()
msg:addByte(0xD0)
msg:addByte(0)

msg:addU16(mission.id)
msg:addString(mission:getName(self))
msg:addString(mission:getDescription(self))

msg:sendToPlayer(self)
msg:delete()
return true
end

function Player.getBestiaryKills(self, raceId)
return math.max(0, self:getStorageValue(PlayerStorageKeys.bestiaryKillsBase + raceId))
end
Expand Down
116 changes: 116 additions & 0 deletions data/lib/core/quests.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
Quest = {}
Quest.__index = Quest

function Quest:register()
local quests = Game.getQuests()
local missions = Game.getMissions()

self.id = #quests + 1

for _, mission in pairs(self.missions) do
mission.id = #missions + 1
mission.questId = self.id
missions[mission.id] = setmetatable(mission, Mission)
end

quests[self.id] = self
return true
end

function Quest:isStarted(player)
return player:getStorageValue(self.storageId) >= self.storageValue
end

function Quest:isCompleted(player)
for _, mission in pairs(self.missions) do
if not mission:isCompleted(player) then
return false
end
end
return true
end

function Quest:getMissions(player)
local missions = {}
for _, mission in pairs(self.missions) do
if mission:isStarted(player) then
missions[#missions + 1] = mission
end
end
return missions
end

function Quest:isTracking(key, value)
if self.storageId == key and value == self.storageValue then
return true
end

for _, mission in pairs(self.missions) do
if mission.storageId == key and value >= mission.startValue and value <= mission.endValue then
return true
end
end
return false
end

Mission = {}
Mission.__index = Mission

function Mission:isStarted(player)
local value = player:getStorageValue(self.storageId)
if value < self.startValue then
return false
end

if not self.ignoreEndValue and value > self.endValue then
return false
end

return true
end

function Mission:isCompleted(player)
if self.ignoreEndValue then
return player:getStorageValue(self.storageId) >= self.endValue
end
return player:getStorageValue(self.storageId) == self.endValue
end

function Mission:getName(player)
if self:isCompleted(player) then
return string.format("%s (Completed)", self.name)
end
return self.name
end

function Mission:getDescription(player)
local descriptionType = type(self.description)
if descriptionType == "function" then
return self.description(player)
end

local value = player:getStorageValue(self.storageId)
if descriptionType == "string" then
local description = self.description:gsub("|STATE|", value)
description = self.description:gsub("\\n", "\n")
return description
end

if descriptionType == "table" then
if self.ignoreEndValue then
for current = self.endValue, self.startValue, -1 do
if value >= current then
return self.description[current]
end
end
else
for current = self.endValue, self.startValue, -1 do
if value == current then
return self.description[current]
end
end
end
end

return "An error has occurred, please contact a gamemaster."
end
8 changes: 8 additions & 0 deletions data/scripts/creaturescripts/clean_tracked_quests.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
local cleanTrackedQuests = CreatureEvent("cleanTrackedQuests")

function cleanTrackedQuests.onLogout(player)
Game.getTrackedQuests()[player:getId()] = nil
return true
end

cleanTrackedQuests:register()
29 changes: 29 additions & 0 deletions data/scripts/eventcallbacks/player/default_onUpdateStorage.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
local lastQuestUpdate = {}

local ec = EventCallback

ec.onUpdateStorage = function(player, key, value, oldValue, isLogin)
if isLogin then
return
end

local playerId = player:getId()
local now = os.mtime()
if not lastQuestUpdate[playerId] then
lastQuestUpdate[playerId] = now
end

if lastQuestUpdate[playerId] - now <= 0 and Game.isQuestStorage(key, value, oldValue) then
lastQuestUpdate[playerId] = os.mtime() + 100
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your questlog has been updated.")
end

local trackedQuests = Game.getTrackedQuests()[playerId] or {}
for mission, quest in pairs(trackedQuests) do
if quest:isTracking(key, value) then
player:sendUpdateQuestTracker(mission)
end
end
end

ec:register()
1 change: 1 addition & 0 deletions data/scripts/lib/event_callbacks.lua
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ ec.onLoseExperience = {[2] = 1}
ec.onGainSkillTries = {[3] = 1}
ec.onWrapItem = {}
ec.onInventoryUpdate = {}
ec.onUpdateStorage = {}
MillhioreBT marked this conversation as resolved.
Show resolved Hide resolved
-- Monster
ec.onDropLoot = {}
ec.onSpawn = {}
Expand Down
Loading
Loading