Once it's installed, you can reload talent definitions multiple times (it's idempotent) and only need to include updated data in the new definition for existing talents. For example, to update the Fireflash talent radius and tooltip, and move it from spell/fire to spell/wildfire, the new definition is simplified to:
Code: Select all
newTalent{
name = "Fireflash",
type = {"spell/wildfire",3}, -- Moving to the "spell/wildfire" talent group
-- type = {"spell/fire",3},
radius = function(self, t) return math.floor(0.45 + 2.5*self:getTalentLevelRaw(t)^.5) end, -- New function definition overwrites the old one
info = function(self, t)
local damage = t.getDamage(self, t) -- This refers to the original function since it's not redefined here
local radius = t.radius(self, t) -- This refers to the new definition in this data block (above)
return ([[Conjures up a bolt of fire moving toward the target that bursts into a TOTALLY MASSIVE EXPLOSION of WILDFIRE doing %0.2f fire damage in a radius of %d.
The damage will increase with your Spellpower.]]):
format(damage, radius)
end,
}
Code: Select all
-- Old definition for reference:
--newTalent{
-- name = "Fireflash",
-- type = {"spell/fire",3},
-- require = spells_req3,
-- points = 5,
-- random_ego = "attack",
-- mana = 40,
-- cooldown = 8,
-- tactical = { ATTACKAREA = { FIRE = 2 } },
-- range = 7,
-- radius = function(self, t)
-- return 1 + self:getTalentLevelRaw(t)
-- end,
-- proj_speed = 4,
-- direct_hit = true,
-- requires_target = true,
-- target = function(self, t)
-- return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=self:spellFriendlyFire(), talent=t, display={particle="bolt_fire", trail="firetrail"}, sound_stop="talents/fireflash"}
-- end,
-- getDamage = function(self, t) return self:combatTalentSpellDamage(t, 28, 280) end,
-- action = function(self, t)
-- local tg = self:getTalentTarget(t)
-- local x, y = self:getTarget(tg)
-- if not x or not y then return nil end
-- self:projectile(tg, x, y, DamageType.FIRE, self:spellCrit(t.getDamage(self, t)), function(self, tg, x, y, grids)
-- game.level.map:particleEmitter(x, y, tg.radius, "fireflash", {radius=tg.radius, tx=x, ty=y})
-- if self:attr("burning_wake") then
-- game.level.map:addEffect(self,
-- x, y, 4,
-- engine.DamageType.INFERNO, self:attr("burning_wake"),
-- tg.radius,
-- 5, nil,
-- {type="inferno"},
-- nil, tg.selffire
-- )
-- end
-- end)
-- game:playSoundNear(self, "talents/fire")
-- return true
-- end,
-- info = function(self, t)
-- local damage = t.getDamage(self, t)
-- local radius = self:getTalentRadius(t)
-- return ([[Conjures up a bolt of fire moving toward the target that explodes into a flash of fire doing %0.2f fire damage in a radius of %d.
-- The damage will increase with your Spellpower.]]):
-- format(damDesc(self, DamageType.FIRE, damage), radius)
-- end,
--}
Code: Select all
-- Updated to allow for partial talent redefinitions (merge)
-- Can be used to define new talents or to change existing ones.
-- t.name (Talent name) and t.type (Talent type) are the only required fields in a redefinition
-- An existing talent can be moved to a new talent group by changing it's type
--- Defines one talent
-- Static!
function _M:newTalent(t)
assert(t.name, "no talent name")
assert(t.type, "no or unknown talent type")
if type(t.type) == "string" then t.type = {t.type, 1} end
if not t.type[2] then t.type[2] = 1 end
t.short_name = t.short_name or t.name
t.short_name = t.short_name:upper():gsub("[ ']", "_")
-- Can pass a string, make it into a function
if type(t.info) == "string" then
local infostr = t.info
t.info = function() return infostr end
end
-- Remove line stat with tabs to be cleaner ..
if t.info then
local info = t.info
t.info = function(self, t) return info(self, t):gsub("\n\t+", "\n") end
end
t.id = "T_"..t.short_name
if self[t.id] then -- If the talent already exists, merge new data with old by overwriting previous values with new ones
print("[TALENT] Talent "..t.short_name.." already exists. Updating with new definition information.")
-- Update talent type tables if type has changed
if self.talents_def[t.id].type[1] ~= t.type[1] then
print("[TALENT] Updating type tables for "..t.id)
table.removeFromList(self.talents_types_def[self:getTalentFromId(t.id).type[1]].talents,self.talents_def[t.id]) --Unregister from old type table
table.insert(self.talents_types_def[t.type[1]].talents, t) --Register with new type table
end
-- Merge the talent data
table.merge(self.talents_def[t.id],t)
else -- load as a new talent
self.talents_def[t.id] = t
self[t.id] = t.id
-- Register in the type table
table.insert(self.talents_types_def[t.type[1]].talents, t)
end
print("[TALENT]", t.name, t.short_name, t.id)
t.mode = t.mode or "activated" -- default to activated mode
-- Reject if mode or info are not properly specified
assert(t.mode == "activated" or t.mode == "sustained" or t.mode == "passive", "wrong talent mode, requires either 'activated' or 'sustained'")
t.points = t.points or 1
assert(self.talents_def[t.id].info, "no talent info")
end