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

Added a framework to know how a talent got activated (by action, forceuse,...

Added a framework to know how a talent got activated (by action, forceuse, callback, ...) along with passing this into to the damage projectors

Merged Quicken Spells and Spellcraft sustains
Added a new Energy Alteration spell as Meta third talent, it can convert all damage types to that of a cast spell
parent d1054101
No related branches found
No related tags found
No related merge requests found
Pipeline #
Showing
with 71 additions and 6 deletions
......@@ -32,7 +32,7 @@ local entities_load_functions = {}
_M.__mo_final_repo = {}
--- Fields we shouldn't save
_M._no_save_fields = { _shader = true }
_M._no_save_fields = { _shader = true, _temp_data = true }
--- Subclasses can change it to know where they are on the map
_M.__position_aware = false
......
......@@ -165,7 +165,9 @@ function _M:useTalent(id, who, force_level, ignore_cd, force_target, silent, no_
msg, line = game.logNewest()
if not silent then self:logTalentMessage(ab) end
self:setCurrentTalentMode("active")
local ok, ret, special = xpcall(function() return ab.action(who, ab) end, debug.traceback)
self:setCurrentTalentMode(nil)
self.__talent_running = nil
if not ok then self:onTalentLuaError(ab, ret) error(ret) end
......@@ -199,7 +201,9 @@ function _M:useTalent(id, who, force_level, ignore_cd, force_target, silent, no_
local ok, ret, special
if not self.sustain_talents[id] then -- activating
if self.deactivating_sustain_talent == ab.id then return end
self:setCurrentTalentMode("active")
ok, ret, special = xpcall(function() return ab.activate(who, ab) end, debug.traceback)
self:setCurrentTalentMode(nil)
if not ok then self:onTalentLuaError(ab, ret) error(ret) end
if ret == true then ret = {} end -- fix for badly coded talents
if ret then ret.name = ret.name or ab.name end
......@@ -242,7 +246,9 @@ function _M:useTalent(id, who, force_level, ignore_cd, force_target, silent, no_
end
end
p.__tmpparticles = nil
self:setCurrentTalentMode("active")
ok, ret, special = xpcall(function() return ab.deactivate(who, ab, p) end, debug.traceback)
self:setCurrentTalentMode(nil)
if not ok then self:onTalentLuaError(ab, ret) error(ret) end
if not ret and self._silent_talent_failure then -- remove messages generated by failed talent
......@@ -421,7 +427,9 @@ function _M:forceUseTalent(t, def)
if def.ignore_energy then self.energy.value = 10000 end
if def.ignore_ressources then self:attr("force_talent_ignore_ressources", 1) end
self:setCurrentTalentMode("forced")
local ret = {self:useTalent(t, def.force_who, def.force_level, def.ignore_cd or def.ignore_cooldown, def.force_target, def.silent, true)}
self:setCurrentTalentMode(nil)
if def.ignore_ressources then self:attr("force_talent_ignore_ressources", -1) end
if def.ignore_energy then
......@@ -1044,7 +1052,12 @@ end
--- Returns the target table for a talent
function _M:getTalentTarget(t)
if type(t.target) == "function" then return t.target(self, t) end
if type(t.target) == "function" then
typ = t.target(self, t)
typ.talent_mode = self:getCurrentTalentMode()
return typ
end
if t.target then t.target.talent_mode = self:getCurrentTalentMode() end -- Yes t is a global, not linked to actor, but this shouldnt matter as this will be set every time anyway
return t.target
end
......@@ -1149,6 +1162,20 @@ function _M:talentParticles(p, ...)
return unpack(ret)
end
function _M:getCurrentTalentMode()
return self._temp_data and self._temp_data.current_talent_mode and self._temp_data.current_talent_mode[1] or "none"
end
function _M:setCurrentTalentMode(mode)
if not self._temp_data then self._temp_data = {} end
if not self._temp_data.current_talent_mode then self._temp_data.current_talent_mode = {} end
if mode then
table.insert(self._temp_data.current_talent_mode, mode)
else
table.remove(self._temp_data.current_talent_mode)
end
end
--- Trigger a talent method
function _M:triggerTalent(tid, name, ...)
if self:isTalentCoolingDown(tid) then return end
......@@ -1157,7 +1184,9 @@ function _M:triggerTalent(tid, name, ...)
name = name or "trigger"
if t[name] then
self.__talent_running = t
self:setCurrentTalentMode("trigger")
local ret = {t[name](self, t, ...)}
self:setCurrentTalentMode(nil)
self.__talent_running = nil
return unpack(ret, 1, table.maxn(ret))
end
......@@ -1169,7 +1198,9 @@ function _M:callTalent(tid, name, ...)
name = name or "trigger"
if t[name] then
self.__talent_running = t
self:setCurrentTalentMode("call")
local ret = {t[name](self, t, ...)}
self:setCurrentTalentMode(nil)
self.__talent_running = nil
return unpack(ret, 1, table.maxn(ret))
end
......
......@@ -6174,7 +6174,9 @@ function _M:iterCallbacks(event)
return function(...)
local old_ps = self.__project_source
self.__project_source = self.sustain_talents[tid]
self:setCurrentTalentMode("callback")
local ret = self:callTalent(tid, event, ...)
self:setCurrentTalentMode(nil)
self.__project_source = old_ps
return ret
end, priority, kind
......@@ -7522,6 +7524,8 @@ end
--- Called when we are initiating a projection
function _M:on_project_init(t, x, y, damtype, dam, particles)
t.talent_mode = self:getCurrentTalentMode()
if self:attr("nullify_all_friendlyfire") and not t.ignore_nullify_all_friendlyfire then
local dt = DamageType:exists(damtype)
if not dt or not dt.ignore_nullify_all_friendlyfire then
......
......@@ -1164,7 +1164,7 @@ function _M:handleEffect(player, eff_id, e, p, x, y, hs, bx, by, is_first, scale
txt.fw, txt.fh = font:size(dur)
end
if e.charges then
local font = e.decrease > 0 and self.buff_font_smallmed or self.buff_font
local font = e.decrease > 0 or e.charges_smallfont and self.buff_font_smallmed or self.buff_font
txt2 = font:draw(charges, 40, colors.WHITE.r, colors.WHITE.g, colors.WHITE.b, true)[1]
txt2.fw, txt2.fh = font:size(charges)
......
......@@ -112,6 +112,8 @@ setDefaultProjector(function(src, x, y, type, dam, state)
end
local source_talent = src.__projecting_for and src.__projecting_for.project_type and (src.__projecting_for.project_type.talent_id or src.__projecting_for.project_type.talent) and src.getTalentFromId and src:getTalentFromId(src.__projecting_for.project_type.talent or src.__projecting_for.project_type.talent_id)
local source_talent_mode = src.__projecting_for and src.__projecting_for.project_type and src.__projecting_for.project_type.talent_mode
if not source_talent_mode and src.getCurrentTalentMode then source_talent_mode = src:getCurrentTalentMode() end
local terrain = game.level.map(x, y, Map.TERRAIN)
if terrain then terrain:check("damage_project", src, x, y, type, dam, source_talent) end
......@@ -517,7 +519,7 @@ setDefaultProjector(function(src, x, y, type, dam, state)
print("[PROJECTOR] final dam after static checks", dam)
local hd = {"DamageProjector:final", src=src, target=target, x=x, y=y, type=type, dam=dam, state=state, source_talent=source_talent}
local hd = {"DamageProjector:final", src=src, target=target, x=x, y=y, type=type, dam=dam, state=state, source_talent=source_talent, source_talent_mode=source_talent_mode}
if src:triggerHook(hd) then dam = hd.dam if hd.stopped then return hd.stopped end end
if target.iterCallbacks then
for cb in target:iterCallbacks("callbackOnTakeDamage") do
......@@ -537,7 +539,7 @@ setDefaultProjector(function(src, x, y, type, dam, state)
print("[PROJECTOR] final dam after hooks and callbacks", dam)
local dead
dead, dam = target:takeHit(dam, src, {damtype=type, damstate=state, source_talent=source_talent, initial_dam=initial_dam})
dead, dam = target:takeHit(dam, src, {damtype=type, damstate=state, source_talent=source_talent, source_talent_mode=source_talent_mode, initial_dam=initial_dam})
-- Log damage for later
if not DamageType:get(type).hideMessage then
......
......@@ -96,7 +96,7 @@ newEntity{ base = "BASE_NPC_WILD_DRAKE",
[Talents.T_MANATHRUST]={base=4, every=5, max = 10},
[Talents.T_MANAFLOW]={base=5, every=5, max = 10},
[Talents.T_DISPERSE_MAGIC]={base=4, every=5, max = 8},
[Talents.T_QUICKEN_SPELLS]={base=4, every=5, max = 10},
[Talents.T_SPELLCRAFT]={base=4, every=5, max = 10},
[Talents.T_METAFLOW]={base=5, every=5, max = 10},
[Talents.T_ESSENCE_OF_SPEED]={base=4, every=5, max = 10},
[Talents.T_MINDLASH]={base=5, every=5, max = 10},
......
game/modules/tome/data/gfx/effects/energy_alteration_acid.png

8.24 KiB

game/modules/tome/data/gfx/effects/energy_alteration_arcane.png

9.08 KiB

game/modules/tome/data/gfx/effects/energy_alteration_blight.png

8.4 KiB

game/modules/tome/data/gfx/effects/energy_alteration_cold.png

8.29 KiB

game/modules/tome/data/gfx/effects/energy_alteration_darkness.png

7.92 KiB

game/modules/tome/data/gfx/effects/energy_alteration_fire.png

8.37 KiB

game/modules/tome/data/gfx/effects/energy_alteration_light.png

8.97 KiB

game/modules/tome/data/gfx/effects/energy_alteration_lightning.png

8.96 KiB

game/modules/tome/data/gfx/effects/energy_alteration_mind.png

8.46 KiB

game/modules/tome/data/gfx/effects/energy_alteration_nature.png

8.6 KiB

game/modules/tome/data/gfx/effects/energy_alteration_physical.png

8.15 KiB

game/modules/tome/data/gfx/effects/energy_alteration_temporal.png

8.86 KiB

......@@ -3969,3 +3969,29 @@ newTalent{
Damage improves with your Spellpower.]]):tformat(darkCount, radius, damDesc(self, DamageType.COLD, damage))
end,
}
newTalent{
name = "Quicken Spells",
type = {"spell/other",1},
points = 5,
mode = "sustained",
sustain_mana = 80,
cooldown = 30,
tactical = { BUFF = 2 },
getCooldownReduction = function(self, t) return util.bound(self:getTalentLevelRaw(t) / 15, 0.05, 0.3) end,
activate = function(self, t)
game:playSoundNear(self, "talents/spell_generic")
return {
cd = self:addTemporaryValue("spell_cooldown_reduction", t.getCooldownReduction(self, t)),
}
end,
deactivate = function(self, t, p)
self:removeTemporaryValue("spell_cooldown_reduction", p.cd)
return true
end,
info = function(self, t)
local cooldownred = t.getCooldownReduction(self, t)
return ([[Reduces the cooldown of all spells by %d%%.]]):
tformat(cooldownred * 100)
end,
}
......@@ -130,6 +130,7 @@ newTalent{
game.level:addEntity(t)
game.zone:addEntity(game.level, t, "trap", x, y)
game.level.map:particleEmitter(x, y, 1, "summon")
self:callTalent(self.T_ENERGY_ALTERATION, "forceActivate", DamageType.ARCANE)
return true
end,
......@@ -173,6 +174,7 @@ newTalent{
local list = {}
self:project(tg, x, y, function(px, py) list[#list+1] = {x=px, y=py} end)
self:callTalent(self.T_ENERGY_ALTERATION, "forceActivate", DamageType.ARCANE)
self:setEffect(self.EFF_AETHER_BREACH, t.getNb(self, t), {src=self, x=x, y=y, radius=tg.radius, list=list, level=game.zone.short_name.."-"..game.level.level, dam=self:spellCrit(t.getDamage(self, t))})
game:playSoundNear(self, "talents/arcane")
......
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