initial commit
This commit is contained in:
@@ -0,0 +1,753 @@
|
||||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local __TS__ArrayForEach = ____lualib.__TS__ArrayForEach
|
||||
local Map = ____lualib.Map
|
||||
local __TS__New = ____lualib.__TS__New
|
||||
local Set = ____lualib.Set
|
||||
local __TS__ArrayIncludes = ____lualib.__TS__ArrayIncludes
|
||||
local __TS__ArrayIsArray = ____lualib.__TS__ArrayIsArray
|
||||
local __TS__ObjectEntries = ____lualib.__TS__ObjectEntries
|
||||
local __TS__ObjectValues = ____lualib.__TS__ObjectValues
|
||||
local __TS__ArrayEvery = ____lualib.__TS__ArrayEvery
|
||||
local __TS__ArrayPushArray = ____lualib.__TS__ArrayPushArray
|
||||
local __TS__Iterator = ____lualib.__TS__Iterator
|
||||
local __TS__ArrayFrom = ____lualib.__TS__ArrayFrom
|
||||
local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
|
||||
local __TS__ArrayMap = ____lualib.__TS__ArrayMap
|
||||
local ____exports = {}
|
||||
local ____crystal_currency = require("crystal_currency")
|
||||
local CrystalCurrency = ____crystal_currency.CrystalCurrency
|
||||
local ____entity_radius = require("utils.entity_radius")
|
||||
local findNearestByClassname = ____entity_radius.findNearestByClassname
|
||||
local ____real_lobby_player = require("utils.real_lobby_player")
|
||||
local collectStatsEligiblePlayerIds = ____real_lobby_player.collectStatsEligiblePlayerIds
|
||||
local ____quest_reward_scaling = require("quests.quest_reward_scaling")
|
||||
local getQuestRewardSplitCount = ____quest_reward_scaling.getQuestRewardSplitCount
|
||||
local splitQuestTeamReward = ____quest_reward_scaling.splitQuestTeamReward
|
||||
____exports.QuestType = QuestType or ({})
|
||||
____exports.QuestType.KILL_UNIT = "KILL_UNIT"
|
||||
____exports.QuestType.COLLECT_ITEM = "COLLECT_ITEM"
|
||||
____exports.QuestType.REACH_LOCATION = "REACH_LOCATION"
|
||||
____exports.QuestType.CUSTOM = "CUSTOM"
|
||||
____exports.QuestState = QuestState or ({})
|
||||
____exports.QuestState.AVAILABLE = 0
|
||||
____exports.QuestState[____exports.QuestState.AVAILABLE] = "AVAILABLE"
|
||||
____exports.QuestState.IN_PROGRESS = 1
|
||||
____exports.QuestState[____exports.QuestState.IN_PROGRESS] = "IN_PROGRESS"
|
||||
____exports.QuestState.COMPLETED = 2
|
||||
____exports.QuestState[____exports.QuestState.COMPLETED] = "COMPLETED"
|
||||
____exports.QuestState.LOCKED = 3
|
||||
____exports.QuestState[____exports.QuestState.LOCKED] = "LOCKED"
|
||||
____exports.QuestState.FAILED = 4
|
||||
____exports.QuestState[____exports.QuestState.FAILED] = "FAILED"
|
||||
____exports.QuestEvents = __TS__Class()
|
||||
local QuestEvents = ____exports.QuestEvents
|
||||
QuestEvents.name = "QuestEvents"
|
||||
QuestEvents.____file_path = "scripts/vscripts/quests/QuestSystem.lua"
|
||||
function QuestEvents.prototype.____constructor(self)
|
||||
end
|
||||
function QuestEvents.OnQuestAccepted(self, callback)
|
||||
local ____self_onQuestAcceptedCallbacks_0 = self.onQuestAcceptedCallbacks
|
||||
____self_onQuestAcceptedCallbacks_0[#____self_onQuestAcceptedCallbacks_0 + 1] = callback
|
||||
end
|
||||
function QuestEvents.OnQuestCompleted(self, callback)
|
||||
local ____self_onQuestCompletedCallbacks_1 = self.onQuestCompletedCallbacks
|
||||
____self_onQuestCompletedCallbacks_1[#____self_onQuestCompletedCallbacks_1 + 1] = callback
|
||||
end
|
||||
function QuestEvents.FireQuestAccepted(self, data)
|
||||
__TS__ArrayForEach(
|
||||
self.onQuestAcceptedCallbacks,
|
||||
function(____, callback) return callback(nil, data) end
|
||||
)
|
||||
end
|
||||
function QuestEvents.FireQuestCompleted(self, data)
|
||||
__TS__ArrayForEach(
|
||||
self.onQuestCompletedCallbacks,
|
||||
function(____, callback) return callback(nil, data) end
|
||||
)
|
||||
end
|
||||
QuestEvents.onQuestAcceptedCallbacks = {}
|
||||
QuestEvents.onQuestCompletedCallbacks = {}
|
||||
local DOTA_ModifyGold_Unspecified = 0
|
||||
local DOTA_ModifyXP_Unspecified = 0
|
||||
____exports.QuestSystem = __TS__Class()
|
||||
local QuestSystem = ____exports.QuestSystem
|
||||
QuestSystem.name = "QuestSystem"
|
||||
QuestSystem.____file_path = "scripts/vscripts/quests/QuestSystem.lua"
|
||||
function QuestSystem.prototype.____constructor(self)
|
||||
self.quests = __TS__New(Map)
|
||||
self.npcQuests = __TS__New(Map)
|
||||
self.processedItems = __TS__New(Set)
|
||||
self.questItems = __TS__New(Map)
|
||||
self.initialized = false
|
||||
self.questMenuOpenNpcByPlayer = __TS__New(Map)
|
||||
self:initializeEventListeners()
|
||||
end
|
||||
function QuestSystem.getInstance(self)
|
||||
if not ____exports.QuestSystem.instance then
|
||||
____exports.QuestSystem.instance = __TS__New(____exports.QuestSystem)
|
||||
end
|
||||
return ____exports.QuestSystem.instance
|
||||
end
|
||||
function QuestSystem.prototype.registerQuest(self, quest)
|
||||
self.quests:set(quest.id, quest)
|
||||
self.initialized = true
|
||||
end
|
||||
function QuestSystem.prototype.linkQuestChains(self)
|
||||
self.quests:forEach(function(____, quest)
|
||||
if not quest.previousQuestId then
|
||||
return
|
||||
end
|
||||
local previousQuest = self.quests:get(quest.previousQuestId)
|
||||
if not previousQuest then
|
||||
return
|
||||
end
|
||||
local questNpc = self:getNpcForQuest(quest.id)
|
||||
local previousNpc = self:getNpcForQuest(previousQuest.id)
|
||||
if questNpc and questNpc == previousNpc then
|
||||
previousQuest.nextQuestId = quest.id
|
||||
end
|
||||
end)
|
||||
end
|
||||
function QuestSystem.prototype.initializeEventListeners(self)
|
||||
CustomGameEventManager:RegisterListener(
|
||||
"request_quests_data",
|
||||
function(source, event)
|
||||
local npcName = event.npcName
|
||||
local player = PlayerResource:GetPlayer(event.PlayerID)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
if npcName then
|
||||
local questsData = self:getQuestsForUI(npcName)
|
||||
CustomGameEventManager:Send_ServerToPlayer(player, "quests_update", {quests = questsData, npcName = npcName, playerId = event.PlayerID})
|
||||
return
|
||||
end
|
||||
local acceptedQuestsData = self:getAcceptedQuestsForUI()
|
||||
CustomGameEventManager:Send_ServerToPlayer(player, "quests_update", {quests = acceptedQuestsData, playerId = event.PlayerID})
|
||||
end
|
||||
)
|
||||
CustomGameEventManager:RegisterListener(
|
||||
"quest_action",
|
||||
function(source, event)
|
||||
if event and event.questId and event.action == "accept" then
|
||||
local playerId = event.PlayerID or source
|
||||
if not PlayerResource:IsValidPlayerID(playerId) then
|
||||
return
|
||||
end
|
||||
self:startQuest(playerId, event.questId)
|
||||
local npcName = self:getNpcForQuest(event.questId)
|
||||
if npcName then
|
||||
local player = PlayerResource:GetPlayer(playerId)
|
||||
if player then
|
||||
local questsData = self:getQuestsForUI(npcName)
|
||||
CustomGameEventManager:Send_ServerToPlayer(player, "quests_update", {quests = questsData, npcName = npcName, playerId = playerId})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
CustomGameEventManager:RegisterListener(
|
||||
"quests_client_ui_state",
|
||||
function(_source, event)
|
||||
local playerId = event.PlayerID
|
||||
if playerId == nil or playerId < 0 then
|
||||
return
|
||||
end
|
||||
local open = event.open == 1 or event.open == true
|
||||
local rawNpc = event.npcName or ""
|
||||
if open then
|
||||
self.questMenuOpenNpcByPlayer:set(playerId, rawNpc ~= "" and rawNpc or "*")
|
||||
else
|
||||
self.questMenuOpenNpcByPlayer:delete(playerId)
|
||||
end
|
||||
end
|
||||
)
|
||||
ListenToGameEvent(
|
||||
"entity_killed",
|
||||
function(event)
|
||||
local unit = EntIndexToHScript(event.entindex_killed)
|
||||
if unit and unit:IsBaseNPC() then
|
||||
self:OnNpcKilled(unit)
|
||||
end
|
||||
end,
|
||||
nil
|
||||
)
|
||||
ListenToGameEvent(
|
||||
"dota_item_picked_up",
|
||||
function(event)
|
||||
self:OnItemPickedUp(event)
|
||||
end,
|
||||
nil
|
||||
)
|
||||
end
|
||||
function QuestSystem.prototype.startQuest(self, playerId, questId)
|
||||
local quest = self.quests:get(questId)
|
||||
if not quest then
|
||||
return
|
||||
end
|
||||
if not self:isQuestAvailable(questId) then
|
||||
return
|
||||
end
|
||||
quest.state = ____exports.QuestState.IN_PROGRESS
|
||||
____exports.QuestEvents:FireQuestAccepted({questId = questId, playerId = playerId})
|
||||
local ____opt_4 = quest.events
|
||||
local ____opt_2 = ____opt_4 and ____opt_4.onAccept
|
||||
if ____opt_2 ~= nil then
|
||||
____opt_2(____opt_4)
|
||||
end
|
||||
local npcName = self:getNpcForQuest(questId)
|
||||
if npcName then
|
||||
self:updateUI(npcName, playerId)
|
||||
end
|
||||
end
|
||||
function QuestSystem.prototype.isPreviousQuestRequirementMet(self, quest)
|
||||
if not quest.previousQuestId then
|
||||
return true
|
||||
end
|
||||
local previousQuest = self.quests:get(quest.previousQuestId)
|
||||
if not previousQuest then
|
||||
return false
|
||||
end
|
||||
if previousQuest.state == ____exports.QuestState.COMPLETED then
|
||||
return true
|
||||
end
|
||||
local ____temp_8 = previousQuest.state == ____exports.QuestState.AVAILABLE
|
||||
if ____temp_8 then
|
||||
local ____opt_6 = previousQuest.unlocksQuestIds
|
||||
____temp_8 = ____opt_6 and __TS__ArrayIncludes(previousQuest.unlocksQuestIds, quest.id)
|
||||
end
|
||||
if ____temp_8 then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
function QuestSystem.prototype.isQuestAvailable(self, questId)
|
||||
local quest = self.quests:get(questId)
|
||||
if not quest or quest.state ~= ____exports.QuestState.AVAILABLE then
|
||||
return false
|
||||
end
|
||||
return self:isPreviousQuestRequirementMet(quest)
|
||||
end
|
||||
function QuestSystem.prototype.updateQuestProgress(self, ____type, target, playerID, data)
|
||||
self.quests:forEach(function(____, quest, questId)
|
||||
if quest.state ~= ____exports.QuestState.IN_PROGRESS then
|
||||
return
|
||||
end
|
||||
local questDirty = false
|
||||
__TS__ArrayForEach(
|
||||
__TS__ObjectEntries(quest.objectives),
|
||||
function(____, ____bindingPattern0)
|
||||
local objective
|
||||
local objectiveId = ____bindingPattern0[1]
|
||||
objective = ____bindingPattern0[2]
|
||||
local objectiveChanged = false
|
||||
if objective.type == ____exports.QuestType.CUSTOM and objective.customHandler then
|
||||
objective.customHandler:onProgress(data)
|
||||
objectiveChanged = true
|
||||
elseif objective.type == ____type then
|
||||
local ____Array_isArray_result_9
|
||||
if __TS__ArrayIsArray(objective.target) then
|
||||
____Array_isArray_result_9 = __TS__ArrayIncludes(objective.target, target)
|
||||
else
|
||||
____Array_isArray_result_9 = objective.target == target
|
||||
end
|
||||
local isTargetMatch = ____Array_isArray_result_9
|
||||
if isTargetMatch and objective.current < objective.required then
|
||||
objective.current = objective.current + 1
|
||||
objectiveChanged = true
|
||||
end
|
||||
end
|
||||
if objectiveChanged then
|
||||
questDirty = true
|
||||
self:checkQuestCompletion(quest)
|
||||
end
|
||||
end
|
||||
)
|
||||
if questDirty then
|
||||
local npcName = self:getNpcForQuest(quest.id) or ""
|
||||
if npcName ~= nil then
|
||||
self:updateUI(npcName, playerID)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
function QuestSystem.prototype.checkQuestCompletion(self, quest)
|
||||
local allCompleted = __TS__ArrayEvery(
|
||||
__TS__ObjectValues(quest.objectives),
|
||||
function(____, objective) return objective.current >= objective.required end
|
||||
)
|
||||
if allCompleted and quest.state == ____exports.QuestState.IN_PROGRESS then
|
||||
quest.state = ____exports.QuestState.COMPLETED
|
||||
print("[QuestSystem] FireQuestCompleted: questId=" .. quest.id)
|
||||
____exports.QuestEvents:FireQuestCompleted({questId = quest.id, playerId = 0})
|
||||
local ____opt_12 = quest.events
|
||||
local ____opt_10 = ____opt_12 and ____opt_12.onComplete
|
||||
if ____opt_10 ~= nil then
|
||||
____opt_10(____opt_12)
|
||||
end
|
||||
self:giveRewards(quest)
|
||||
self:clearCollectedItems(quest)
|
||||
self:unlockLinkedQuests(quest)
|
||||
end
|
||||
end
|
||||
function QuestSystem.prototype.unlockLinkedQuests(self, quest)
|
||||
local npcsToUpdate = __TS__New(Set)
|
||||
local questIdsToUnlock = {}
|
||||
if quest.nextQuestId then
|
||||
questIdsToUnlock[#questIdsToUnlock + 1] = quest.nextQuestId
|
||||
end
|
||||
if quest.unlocksQuestIds then
|
||||
__TS__ArrayPushArray(questIdsToUnlock, quest.unlocksQuestIds)
|
||||
end
|
||||
for ____, questId in ipairs(questIdsToUnlock) do
|
||||
local linkedQuest = self.quests:get(questId)
|
||||
if linkedQuest and linkedQuest.state == ____exports.QuestState.LOCKED then
|
||||
linkedQuest.state = ____exports.QuestState.AVAILABLE
|
||||
local npcName = self:getNpcForQuest(questId)
|
||||
if npcName then
|
||||
npcsToUpdate:add(npcName)
|
||||
end
|
||||
end
|
||||
end
|
||||
for ____, npcName in __TS__Iterator(npcsToUpdate) do
|
||||
self:updateUI(npcName, 0)
|
||||
end
|
||||
end
|
||||
function QuestSystem.prototype.repairStuckQuestUnlocks(self)
|
||||
self.quests:forEach(function(____, quest)
|
||||
if quest.state ~= ____exports.QuestState.LOCKED or not quest.previousQuestId then
|
||||
return
|
||||
end
|
||||
local previousQuest = self.quests:get(quest.previousQuestId)
|
||||
if (previousQuest and previousQuest.state) == ____exports.QuestState.COMPLETED then
|
||||
quest.state = ____exports.QuestState.AVAILABLE
|
||||
end
|
||||
end)
|
||||
end
|
||||
function QuestSystem.prototype.shouldShowQuestInNpcUI(self, quest)
|
||||
repeat
|
||||
local ____switch72 = quest.state
|
||||
local previousQuest
|
||||
local ____cond72 = ____switch72 == ____exports.QuestState.AVAILABLE
|
||||
if ____cond72 then
|
||||
return self:isPreviousQuestRequirementMet(quest)
|
||||
end
|
||||
____cond72 = ____cond72 or (____switch72 == ____exports.QuestState.IN_PROGRESS or ____switch72 == ____exports.QuestState.COMPLETED or ____switch72 == ____exports.QuestState.FAILED)
|
||||
if ____cond72 then
|
||||
return true
|
||||
end
|
||||
____cond72 = ____cond72 or ____switch72 == ____exports.QuestState.LOCKED
|
||||
if ____cond72 then
|
||||
if not quest.previousQuestId then
|
||||
return false
|
||||
end
|
||||
previousQuest = self.quests:get(quest.previousQuestId)
|
||||
return (previousQuest and previousQuest.state) == ____exports.QuestState.COMPLETED
|
||||
end
|
||||
do
|
||||
return false
|
||||
end
|
||||
until true
|
||||
end
|
||||
function QuestSystem.prototype.resetQuest(self, questId)
|
||||
local quest = self.quests:get(questId)
|
||||
if not quest then
|
||||
return
|
||||
end
|
||||
__TS__ArrayForEach(
|
||||
__TS__ObjectValues(quest.objectives),
|
||||
function(____, objective)
|
||||
objective.current = 0
|
||||
end
|
||||
)
|
||||
quest.state = ____exports.QuestState.AVAILABLE
|
||||
local npcName = self:getNpcForQuest(questId) or ""
|
||||
self:updateUI(npcName, 0)
|
||||
end
|
||||
function QuestSystem.prototype.getRewardPlayerIds(self)
|
||||
local ids = collectStatsEligiblePlayerIds(nil)
|
||||
if #ids > 0 then
|
||||
return ids
|
||||
end
|
||||
do
|
||||
local playerID = 0
|
||||
while playerID < DOTA_MAX_TEAM_PLAYERS do
|
||||
do
|
||||
local pid = playerID
|
||||
if not PlayerResource:IsValidPlayerID(pid) then
|
||||
goto __continue79
|
||||
end
|
||||
if PlayerResource:GetTeam(pid) ~= DOTA_TEAM_GOODGUYS then
|
||||
goto __continue79
|
||||
end
|
||||
return {pid}
|
||||
end
|
||||
::__continue79::
|
||||
playerID = playerID + 1
|
||||
end
|
||||
end
|
||||
return {}
|
||||
end
|
||||
function QuestSystem.prototype.giveRewards(self, quest)
|
||||
local playerIds = self:getRewardPlayerIds()
|
||||
local playerCount = math.max(1, #playerIds)
|
||||
local goldSplitCount = getQuestRewardSplitCount(nil, playerCount)
|
||||
local goldParts = splitQuestTeamReward(nil, quest.rewards.gold or 0, goldSplitCount)
|
||||
local xpParts = splitQuestTeamReward(nil, quest.rewards.experience or 0, playerCount)
|
||||
local crystalParts = splitQuestTeamReward(nil, quest.rewards.crystals or 0, playerCount)
|
||||
local crystalCurrency = CrystalCurrency:getInstance()
|
||||
do
|
||||
local i = 0
|
||||
while i < #playerIds do
|
||||
local playerID = playerIds[i + 1]
|
||||
local hero = PlayerResource:GetSelectedHeroEntity(playerID)
|
||||
local gold = goldParts[i + 1] or 0
|
||||
if gold > 0 and hero then
|
||||
hero:ModifyGold(gold, true, DOTA_ModifyGold_Unspecified)
|
||||
end
|
||||
local xp = xpParts[i + 1] or 0
|
||||
if xp > 0 and hero then
|
||||
hero:AddExperience(xp, DOTA_ModifyXP_Unspecified, false, true)
|
||||
end
|
||||
local crystals = crystalParts[i + 1] or 0
|
||||
if crystals > 0 then
|
||||
crystalCurrency:addCrystals(playerID, crystals)
|
||||
end
|
||||
if hero then
|
||||
local madstone = CreateItem("item_madstone_bundle", nil, hero)
|
||||
if madstone then
|
||||
hero:AddItem(madstone)
|
||||
end
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
function QuestSystem.prototype.getVisibleQuests(self)
|
||||
local visibleQuests = {}
|
||||
local startingQuests = __TS__ArrayFilter(
|
||||
__TS__ArrayFrom(self.quests:values()),
|
||||
function(____, quest) return not quest.previousQuestId end
|
||||
)
|
||||
for ____, startQuest in ipairs(startingQuests) do
|
||||
local currentQuest = startQuest
|
||||
while currentQuest do
|
||||
visibleQuests[#visibleQuests + 1] = currentQuest
|
||||
if currentQuest.state ~= ____exports.QuestState.COMPLETED then
|
||||
break
|
||||
end
|
||||
if currentQuest.nextQuestId then
|
||||
currentQuest = self.quests:get(currentQuest.nextQuestId)
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return visibleQuests
|
||||
end
|
||||
function QuestSystem.prototype.registerNpcQuests(self, npcName, questIds)
|
||||
self.npcQuests:set(npcName, questIds)
|
||||
end
|
||||
function QuestSystem.prototype.getQuestsForNpc(self, npcName)
|
||||
local questIds = self.npcQuests:get(npcName) or ({})
|
||||
local quests = __TS__ArrayFilter(
|
||||
__TS__ArrayMap(
|
||||
questIds,
|
||||
function(____, id)
|
||||
local quest = self.quests:get(id)
|
||||
return quest
|
||||
end
|
||||
),
|
||||
function(____, quest)
|
||||
return quest ~= nil and (quest.state == ____exports.QuestState.AVAILABLE or quest.state == ____exports.QuestState.LOCKED or quest.state == ____exports.QuestState.IN_PROGRESS or quest.state == ____exports.QuestState.COMPLETED)
|
||||
end
|
||||
)
|
||||
return quests
|
||||
end
|
||||
function QuestSystem.prototype.getQuestsForUI(self, npcName)
|
||||
local questsData = {}
|
||||
if not self.initialized or not npcName then
|
||||
return questsData
|
||||
end
|
||||
self:repairStuckQuestUnlocks()
|
||||
local npcQuestIds = self.npcQuests:get(npcName) or ({})
|
||||
for ____, questId in ipairs(npcQuestIds) do
|
||||
local quest = self.quests:get(questId)
|
||||
if quest and self:shouldShowQuestInNpcUI(quest) then
|
||||
questsData[questId] = quest
|
||||
end
|
||||
end
|
||||
return questsData
|
||||
end
|
||||
function QuestSystem.prototype.getAcceptedQuestsForUI(self)
|
||||
local questsData = {}
|
||||
if not self.initialized then
|
||||
return questsData
|
||||
end
|
||||
self.quests:forEach(function(____, quest, id)
|
||||
if quest.state == ____exports.QuestState.IN_PROGRESS or quest.state == ____exports.QuestState.COMPLETED then
|
||||
questsData[id] = quest
|
||||
end
|
||||
end)
|
||||
return questsData
|
||||
end
|
||||
function QuestSystem.prototype.getNpcForQuest(self, questId)
|
||||
for ____, ____value in __TS__Iterator(self.npcQuests:entries()) do
|
||||
local npcName = ____value[1]
|
||||
local questIds = ____value[2]
|
||||
if __TS__ArrayIncludes(questIds, questId) then
|
||||
return npcName
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
function QuestSystem.prototype.updateUI(self, npcName, playerId)
|
||||
if not npcName then
|
||||
return
|
||||
end
|
||||
local questsData = self:getQuestsForUI(npcName)
|
||||
do
|
||||
local i = 0
|
||||
while i < DOTA_MAX_TEAM_PLAYERS do
|
||||
do
|
||||
if not PlayerResource:IsValidPlayerID(i) or PlayerResource:IsFakeClient(i) then
|
||||
goto __continue116
|
||||
end
|
||||
local openFor = self.questMenuOpenNpcByPlayer:get(i)
|
||||
if openFor == nil then
|
||||
goto __continue116
|
||||
end
|
||||
if openFor ~= "*" and openFor ~= npcName then
|
||||
goto __continue116
|
||||
end
|
||||
local player = PlayerResource:GetPlayer(i)
|
||||
if player then
|
||||
CustomGameEventManager:Send_ServerToPlayer(player, "quests_update", {quests = questsData, npcName = npcName, playerId = i})
|
||||
end
|
||||
end
|
||||
::__continue116::
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
function QuestSystem.prototype.OnNpcKilled(self, unit)
|
||||
local unitName = unit:GetUnitName()
|
||||
self:updateQuestProgress(____exports.QuestType.KILL_UNIT, unitName, 0)
|
||||
end
|
||||
function QuestSystem.prototype.OnItemPickedUp(self, event)
|
||||
local itemEntity = EntIndexToHScript(event.ItemEntityIndex)
|
||||
if not itemEntity then
|
||||
return
|
||||
end
|
||||
local itemName = itemEntity:GetAbilityName()
|
||||
local itemHandle = itemEntity:GetEntityHandle()
|
||||
if self.processedItems:has(itemHandle) then
|
||||
return
|
||||
end
|
||||
local targetQuestId
|
||||
self.quests:forEach(function(____, quest, questId)
|
||||
if quest.state == ____exports.QuestState.IN_PROGRESS then
|
||||
__TS__ArrayForEach(
|
||||
__TS__ObjectValues(quest.objectives),
|
||||
function(____, objective)
|
||||
if objective.type == ____exports.QuestType.COLLECT_ITEM and objective.target == itemName then
|
||||
targetQuestId = questId
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
end)
|
||||
if targetQuestId then
|
||||
if not self.questItems:has(targetQuestId) then
|
||||
self.questItems:set(
|
||||
targetQuestId,
|
||||
__TS__New(Set)
|
||||
)
|
||||
end
|
||||
self.questItems:get(targetQuestId):add(itemEntity)
|
||||
end
|
||||
self:updateQuestProgress(____exports.QuestType.COLLECT_ITEM, itemName, 0)
|
||||
self.processedItems:add(itemHandle)
|
||||
end
|
||||
function QuestSystem.prototype.clearCollectedItems(self, quest)
|
||||
local items = self.questItems:get(quest.id)
|
||||
if items then
|
||||
items:forEach(function(____, item)
|
||||
do
|
||||
local ____try, ____hasReturned, ____returnValue = pcall(function()
|
||||
if not item or item:IsNull() then
|
||||
return true
|
||||
end
|
||||
local itemName
|
||||
do
|
||||
local function ____catch(e)
|
||||
return true
|
||||
end
|
||||
local ____try, ____hasReturned, ____returnValue = pcall(function()
|
||||
itemName = item:GetAbilityName()
|
||||
end)
|
||||
if not ____try then
|
||||
____hasReturned, ____returnValue = ____catch(____hasReturned)
|
||||
end
|
||||
if ____hasReturned then
|
||||
return true, ____returnValue
|
||||
end
|
||||
end
|
||||
do
|
||||
pcall(function()
|
||||
local container = item:GetContainer()
|
||||
if container and not container:IsNull() then
|
||||
local hero = container:GetOwner()
|
||||
if hero and not hero:IsNull() then
|
||||
hero:RemoveItem(item)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
do
|
||||
pcall(function()
|
||||
if not item:IsNull() then
|
||||
local itemPos = item:GetAbsOrigin()
|
||||
if itemPos ~= nil then
|
||||
local itemPhysical = findNearestByClassname("dota_item_drop", itemPos, 100)
|
||||
if itemPhysical and not itemPhysical:IsNull() then
|
||||
local containedItem = itemPhysical:GetContainedItem()
|
||||
if containedItem and not containedItem:IsNull() and containedItem:GetEntityHandle() == item:GetEntityHandle() then
|
||||
itemPhysical:RemoveSelf()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
do
|
||||
pcall(function()
|
||||
if not item:IsNull() then
|
||||
item:RemoveSelf()
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
if ____try and ____hasReturned then
|
||||
return ____returnValue
|
||||
end
|
||||
end
|
||||
end)
|
||||
self.questItems:delete(quest.id)
|
||||
end
|
||||
self.processedItems:clear()
|
||||
end
|
||||
function QuestSystem.prototype.triggerCustomProgress(self, questId, data)
|
||||
local quest = self.quests:get(questId)
|
||||
if not quest or quest.state ~= ____exports.QuestState.IN_PROGRESS then
|
||||
return
|
||||
end
|
||||
self:updateQuestProgress(____exports.QuestType.CUSTOM, "", 0, data)
|
||||
end
|
||||
function QuestSystem.prototype.addQuestProgress(self, questId, objectiveId, amount)
|
||||
if amount == nil then
|
||||
amount = 1
|
||||
end
|
||||
local quest = self.quests:get(questId)
|
||||
if not quest or quest.state ~= ____exports.QuestState.IN_PROGRESS then
|
||||
return
|
||||
end
|
||||
local objective = quest.objectives[objectiveId]
|
||||
if not objective then
|
||||
return
|
||||
end
|
||||
local nextCurrent = math.min(objective.current + amount, objective.required)
|
||||
if nextCurrent == objective.current then
|
||||
return
|
||||
end
|
||||
objective.current = nextCurrent
|
||||
self:checkQuestCompletion(quest)
|
||||
self:updateUI(
|
||||
self:getNpcForQuest(questId) or "",
|
||||
0
|
||||
)
|
||||
end
|
||||
function QuestSystem.prototype.setQuestProgress(self, questId, objectiveId, value, updateUI)
|
||||
if updateUI == nil then
|
||||
updateUI = true
|
||||
end
|
||||
local quest = self.quests:get(questId)
|
||||
if not quest or quest.state ~= ____exports.QuestState.IN_PROGRESS then
|
||||
return
|
||||
end
|
||||
local objective = quest.objectives[objectiveId]
|
||||
if not objective then
|
||||
return
|
||||
end
|
||||
local nextCurrent = math.min(
|
||||
math.max(0, value),
|
||||
objective.required
|
||||
)
|
||||
if nextCurrent == objective.current then
|
||||
return
|
||||
end
|
||||
objective.current = nextCurrent
|
||||
self:checkQuestCompletion(quest)
|
||||
if updateUI then
|
||||
self:updateUI(
|
||||
self:getNpcForQuest(questId) or "",
|
||||
0
|
||||
)
|
||||
end
|
||||
end
|
||||
function QuestSystem.prototype.setObjectiveRequired(self, questId, objectiveId, required, updateUI)
|
||||
if updateUI == nil then
|
||||
updateUI = true
|
||||
end
|
||||
local quest = self.quests:get(questId)
|
||||
if not quest then
|
||||
return
|
||||
end
|
||||
local objective = quest.objectives[objectiveId]
|
||||
if not objective then
|
||||
return
|
||||
end
|
||||
local nextRequired = math.max(
|
||||
1,
|
||||
math.floor(required)
|
||||
)
|
||||
objective.required = nextRequired
|
||||
if objective.current > nextRequired then
|
||||
objective.current = nextRequired
|
||||
end
|
||||
if updateUI then
|
||||
self:updateUI(
|
||||
self:getNpcForQuest(questId) or "",
|
||||
0
|
||||
)
|
||||
end
|
||||
end
|
||||
function QuestSystem.prototype.failQuest(self, questId)
|
||||
local quest = self.quests:get(questId)
|
||||
if not quest or quest.state == ____exports.QuestState.COMPLETED then
|
||||
return
|
||||
end
|
||||
quest.state = ____exports.QuestState.FAILED
|
||||
local ____opt_18 = quest.events
|
||||
if ____opt_18 and ____opt_18.onFail then
|
||||
quest.events:onFail()
|
||||
end
|
||||
CustomGameEventManager:Send_ServerToAllClients("quest_failed", {questId = quest.id})
|
||||
self:updateUI(
|
||||
self:getNpcForQuest(questId) or "",
|
||||
0
|
||||
)
|
||||
end
|
||||
function QuestSystem.prototype.getQuestProgress(self, questId, objectiveId)
|
||||
local quest = self.quests:get(questId)
|
||||
if not quest then
|
||||
return 0
|
||||
end
|
||||
local objective = quest.objectives[objectiveId]
|
||||
if not objective then
|
||||
return 0
|
||||
end
|
||||
return objective.current
|
||||
end
|
||||
return ____exports
|
||||
Reference in New Issue
Block a user