Skip to content
Snippets Groups Projects
Commit ab708acf authored by DarkGod's avatar DarkGod
Browse files

Merge branch '0player/t-engine4-talent_proper_cleanup'

parents 1e9033a7 e9a244aa
No related branches found
No related tags found
No related merge requests found
......@@ -129,28 +129,21 @@ function _M:useTalent(id, who, force_level, ignore_cd, force_target, silent, no_
assert(ab, "trying to cast talent "..tostring(id).." but it is not defined")
local cancel = false
local co, success, err
if ab.mode == "activated" and ab.action then
if self:isTalentCoolingDown(ab) and not ignore_cd then
game.logPlayer(who, "%s is still on cooldown for %d turns.", ab.name:capitalize(), self.talents_cd[ab.id])
return
end
local co = coroutine.create(function()
co = coroutine.create(function()
if cancel then
success = false
return false
end
if not self:preUseTalent(ab, silent) then return end
local old_level
local old_target, old_target_set = nil, false
if force_level then old_level = who.talents[id]; who.talents[id] = force_level end
if ab.onAIGetTarget and not who.player then old_target_set = true; old_target = rawget(who, "getTarget"); who.getTarget = function() return ab.onAIGetTarget(self, ab) end end
if force_target and not old_target then old_target_set = true; old_target = rawget(who, "getTarget"); who.getTarget = function(a) return force_target.x, force_target.y, not force_target.__no_self and force_target end end
self.__talent_running = ab
local ok, ret, special = xpcall(function() return ab.action(who, ab) end, debug.traceback)
self.__talent_running = nil
if old_target_set then who.getTarget = old_target end
if force_level then who.talents[id] = old_level end
if not ok then error(ret) end
......@@ -159,44 +152,21 @@ function _M:useTalent(id, who, force_level, ignore_cd, force_target, silent, no_
-- Everything went ok? then start cooldown if any
if not ignore_cd and (not special or not special.ignore_cd) then self:startTalentCooldown(ab) end
end)
local success, err
if not no_confirm and self:isTalentConfirmable(ab) then
local abname = game:getGenericTextTiles(ab)..ab.name
require "engine.ui.Dialog":yesnoPopup("Talent Use Confirmation", ("Use %s?"):format(abname),
function(quit)
if quit ~= false then
cancel = true
end
success, err = coroutine.resume(co)
end,
"Cancel","Continue")
else
-- cancel checked in coroutine
success, err = coroutine.resume(co)
end
if not success and err then
print(debug.traceback(co))
self:onTalentLuaError(err)
error(err)
end
elseif ab.mode == "sustained" and ab.activate and ab.deactivate then
if self:isTalentCoolingDown(ab) and not ignore_cd then
game.logPlayer(who, "%s is still on cooldown for %d turns.", ab.name:capitalize(), self.talents_cd[ab.id])
return
end
local co = coroutine.create(function()
co = coroutine.create(function()
if cancel then
success = false
return false
end
if not self:preUseTalent(ab, silent) then return end
if not self.sustain_talents[id] then
local old_level
if force_level then old_level = who.talents[id]; who.talents[id] = force_level end
local ret = ab.activate(who, ab)
if ret == true then ret = {} end -- fix for badly coded talents
if ret then ret.name = ret.name or ab.name end
if force_level then who.talents[id] = old_level end
if not self:postUseTalent(ab, ret) then return end
......@@ -215,8 +185,6 @@ function _M:useTalent(id, who, force_level, ignore_cd, force_target, silent, no_
end
end
else
local old_level
if force_level then old_level = who.talents[id]; who.talents[id] = force_level end
local p = self.sustain_talents[id]
if p and type(p) == "table" and p.__tmpvals then
for i = 1, #p.__tmpvals do
......@@ -229,7 +197,6 @@ function _M:useTalent(id, who, force_level, ignore_cd, force_target, silent, no_
end
end
local ret = ab.deactivate(who, ab, p)
if force_level then who.talents[id] = old_level end
if not self:postUseTalent(ab, ret, silent) then return end
......@@ -251,25 +218,58 @@ function _M:useTalent(id, who, force_level, ignore_cd, force_target, silent, no_
end
end
end)
local success, err
else
print("Activating non activable or sustainable talent: "..id.." :: "..ab.name.." :: "..ab.mode)
end
if co then
-- Stub some stuff
local old_level, old_target, new_target = nil, nil, nil
if force_level then old_level = who.talents[id] end
if ab.mode == "activated" then
if ab.onAIGetTarget and not who.player then old_target = rawget(who, "getTarget"); new_target = function() return ab.onAIGetTarget(self, ab) end end
if force_target and not old_target then old_target = rawget(who, "getTarget"); new_target = function(a) return force_target.x, force_target.y, not force_target.__no_self and force_target end end
end
local co_wrapper = coroutine.create(function()
success = true
local ok
while success do
if new_target then who.getTarget = new_target end
if force_level then who.talents[id] = force_level end
self.__talent_running = ab
ok, err = coroutine.resume(co)
success = success and ok
if new_target then who.getTarget = old_target end
if force_level then who.talents[id] = old_level end
self.__talent_running = nil
if ok and coroutine.status(co) == "dead" then
-- terminated
return
end
coroutine.yield()
end
if err then error(err) end --propagate
end)
if not no_confirm and self:isTalentConfirmable(ab) then
local abname = game:getGenericTextTiles(ab)..ab.name
require "engine.ui.Dialog":yesnoPopup("Talent Use Confirmation", ("%s %s?"):
format(self:isTalentActive(ab.id) and "Deactivate" or "Activate",abname),
require "engine.ui.Dialog":yesnoPopup("Talent Use Confirmation", ("Use %s?"):format(abname),
function(quit)
if quit ~= false then
cancel = true
end
success, err = coroutine.resume(co)
success, err = coroutine.resume(co_wrapper)
end,
"Cancel","Continue")
else
-- cancel checked in coroutine
success, err = coroutine.resume(co)
success, err = coroutine.resume(co_wrapper)
end
-- Cleanup in case we coroutine'd out
self.__talent_running = nil
if not success and err then
print(debug.traceback(co_wrapper))
self:onTalentLuaError(err)
error(err)
end
if not success and err then print(debug.traceback(co)) error(err) end
else
print("Activating non activable or sustainable talent: "..id.." :: "..ab.name.." :: "..ab.mode)
end
self.changed = true
return true
......
......@@ -441,6 +441,7 @@ newTalent{
points = 1,
hard_cap = 1,
no_npc_use = true,
on_pre_use = function(self, t) return not self.resting end,
action = function(self, t)
local best = t.findBest(self, t)
if not best then game.logPlayer(self, "You require a digger to dig.") return end
......
......@@ -195,6 +195,7 @@ newTalent{
mana = 10,
no_npc_use = true,
no_unlearn_last = true,
on_pre_use = function(self, t) return not self.resting end,
getHeal = function(self, t)
if not self.alchemy_golem then return 0 end
local ammo = self:hasAlchemistWeapon()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment