Code: Select all
-- ToME - Tales of Maj'Eyal
-- Copyright (C) 2009 - 2015 Nicolas Casalini
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- Nicolas Casalini "DarkGod"
-- darkgod@te4.org
local Stats = require "engine.interface.ActorStats"
local ActorTalents = require "engine.interface.ActorTalents"
local Object = require "engine.Object"
--load("/data/general/npcs/rat_lich_minions.lua")
undeads_req1 = {
level = function(level) return 0 + (level-1) end,
}
undeads_req2 = {
level = function(level) return 4 + (level-1) end,
}
undeads_req3 = {
level = function(level) return 8 + (level-1) end,
}
undeads_req4 = {
level = function(level) return 12 + (level-1) end,
}
newTalentType{ type="undead/ratlich", name = "Rat Lich", generic = true, description = "Rat Lich's innate abilities."}
newTalentType{ type="undead/ratlich-misc", name = "ratlich-misc-skills", generic = true, description = "Misc talents that the Rat Lich can use" }
function applyEmpathy_Call_of_the_Rat_Lich(self, m)
if self:knowTalent(self.T_CALL_OF_THE_RAT_LICH) then
local t = self:getTalentFromId(self.T_CALL_OF_THE_RAT_LICH)
local perc = t.getPerc(self, t)
for k, e in pairs(self.resists) do
m.resists[k] = (m.resists[k] or 0) + e * perc / 100
end
-- for k, e in pairs(self.resists_cap) do
-- m.resists_cap[k] = e
-- end
m.combat_physresist = m.combat_physresist + self:combatPhysicalResist() * perc / 100
m.combat_spellresist = m.combat_spellresist + self:combatSpellResist() * perc / 100
m.combat_mentalresist = m.combat_mentalresist + self:combatMentalResist() * perc / 100
m.poison_immune = (m.poison_immune or 0) + (self:attr("poison_immune") or 0) * perc / 100
m.disease_immune = (m.disease_immune or 0) + (self:attr("disease_immune") or 0) * perc / 100
m.cut_immune = (m.cut_immune or 0) + (self:attr("cut_immune") or 0) * perc / 100
m.confusion_immune = (m.confusion_immune or 0) + (self:attr("confusion_immune") or 0) * perc / 100
m.blind_immune = (m.blind_immune or 0) + (self:attr("blind_immune") or 0) * perc / 100
m.silence_immune = (m.silence_immune or 0) + (self:attr("silence_immune") or 0) * perc / 100
m.disarm_immune = (m.disarm_immune or 0) + (self:attr("disarm_immune") or 0) * perc / 100
m.pin_immune = (m.pin_immune or 0) + (self:attr("pin_immune") or 0) * perc / 100
m.stun_immune = (m.stun_immune or 0) + (self:attr("stun_immune") or 0) * perc / 100
m.fear_immune = (m.fear_immune or 0) + (self:attr("fear_immune") or 0) * perc / 100
m.knockback_immune = (m.knockback_immune or 0) + (self:attr("knockback_immune") or 0) * perc / 100
m.stone_immune = (m.stone_immune or 0) + (self:attr("stone_immune") or 0) * perc / 100
m.teleport_immune = (m.teleport_immune or 0) + (self:attr("teleport_immune") or 0) * perc / 100
m.necrotic_minion_be_nice = 1
end
end
local rat_lich_minions_list = {
ratlich_skeletal_rat = {
base = "BASE_NPC_UNDEAD_RAT_RATLICH_MOD",
name = "skeletal rat", color=colors.WHITE, image="npc/undead_rodent_skeletal_rat.png",
desc = [[A skeletal rat, teeth and claws ground to a sharp point. It glares at you menacingly.]],
level_range = {5, nil}, exp_worth = 0,
rarity = 1,
max_life = resolvers.rngavg(25,45),
combat_armor = 12, combat_def = 0,
cut_immune = 1,
blind_immune = 1,
fear_immune = 1,
poison_immune = 1,
combat = { dam=resolvers.levelup(resolvers.rngavg(20,30), 1, 0.6), atk=resolvers.rngavg(25,50), apr=20, dammod={str=1.1} },
resolvers.tmasteries{ ["undead/skeleton"]=-0.5},
resolvers.talents{
[Talents.T_SKELETON_REASSEMBLE]={base=1, every=5, max=4},
},
emote_random = {chance=1, "*squeak*", "Squeak!", "Squeak??", "SQUEAK!!!!!"},
},
ratlich_ghoulish_rat = {
base = "BASE_NPC_UNDEAD_RAT_RATLICH_MOD",
name = "ghoulish rat", color=colors.TAN, image="npc/undead_rodent_ghoulish_rat.png",
desc = [[Layers of rotting skin are peeling off of this rat. One of the eye sockets appears empty.]],
level_range = {6, nil}, exp_worth = 0,
rarity = 1,
max_life = resolvers.rngavg(34,56),
combat_armor = 4, combat_def = 10,
life_rating = 10,
autolevel="ghoul",
combat = { dam=resolvers.levelup(resolvers.rngavg(16,24), 1, 0.6), atk=resolvers.rngavg(25,50), apr=25, dammod={str=1} },
poison_immune = 0.5,
disease_immune = 0.5,
resists = {[DamageType.BLIGHT] = 15},
resolvers.talents{
[Talents.T_ROTTING_DISEASE]={base=1, every=7, max=4},
[Talents.T_GHOULISH_LEAP]={base=2, every=8, max=4},
},
emote_random = {chance=1, "*s.q.u.e.a.k*", "Squeeeeeeak!", "Squeakkkkkkk??"},
},
ratlich_spectral_rat = {
base = "BASE_NPC_UNDEAD_RAT_RATLICH_MOD",
name = "spectral rat", color=colors.GREY, image="npc/undead_rodent_spectral_rat.png",
desc = [[An eerie haze surrounds this translucent rat.]],
level_range = {9, nil}, exp_worth = 0,
rarity = 3,
rank = 2,
max_life = resolvers.rngavg(18,25),
combat_armor = 0, combat_def = 15,
combat = { dam=resolvers.levelup(resolvers.rngavg(25,40), 1, 0.6), atk=resolvers.rngavg(25,50), apr=25, dammod={str=1} },
can_pass = {pass_wall=70},
resists = {all = 20, [DamageType.LIGHT] = -40, [DamageType.DARKNESS] = 45},
no_breath = 1,
stone_immune = 1,
confusion_immune = 1,
fear_immune = 1,
teleport_immune = 0.5,
disease_immune = 1,
poison_immune = 1,
stun_immune = 1,
blind_immune = 1,
cut_immune = 1,
see_invisible = 80,
resolvers.talents{
[Talents.T_PHASE_DOOR]={base=1, every=6, max=4},
[Talents.T_BLUR_SIGHT]={base=3, every=6, max=6},
},
resolvers.sustains_at_birth(),
emote_random = {chance=1, "Eerie Squeak!", "Frightening Squeak??", "SQUEAK!!!!!"},
},
-- these will later require rat liches skull equipped to appear
ratlich_vampire_rat = {
base = "BASE_NPC_UNDEAD_RAT_RATLICH_MOD",
name = "vampire rat", color=colors.WHITE, image="npc/undead_rodent_vampire_rat.png",
desc = [[Looks much like a normal rat. That is, other than the very large fangs.]],
level_range = {8, nil}, exp_worth = 0,
rarity = 2,
max_life = resolvers.rngavg(45,60),
life_rating=11,
combat_armor = 8, combat_def = 18,
autolevel = "random_boss",
fear_immune = 1,
combat = { dam=resolvers.levelup(resolvers.rngavg(25,35), 1, 0.6), atk=resolvers.rngavg(25,50), apr=22, dammod={str=1.1} },
resolvers.talents{
[Talents.T_VAMPIRIC_GIFT]={base=1, every=5, max=4},
[Talents.T_INVOKE_DARKNESS]={base=1, every=8, max=5},
[Talents.T_COLD_FLAMES]={base=1, every=9, max=5},
},
emote_random = {chance=1, "Squeak! Blood!", "Squeak??", "SQUEAK!!!!!"},
},
ratlich_gigantic_bone_rat = {
base = "BASE_NPC_UNDEAD_RAT_RATLICH_MOD", -- only if have ratlich skull equipped/later on swap bone giant for version of this if your a necromancer and rat lich :P
name = "gigantic bone rat", color=colors.LIGHTGREY,
desc = [[This massive beast appears to be a rat composed of countless bones fused together.]],
resolvers.nice_tile{image="invis.png", add_mos = {{image="npc/undead_rodent_gigantic_bone_rat.png", display_h=2, display_y=-1}}},
level_range = {14, nil}, exp_worth = 0,
rarity = 6,
max_life = resolvers.rngavg(60,80),
life_rating=14,
combat_armor = 25, combat_def = 10,
rank = 3,
size_category = 3,
cut_immune = 1,
blind_immune = 1,
fear_immune = 1,
poison_immune = 1,
stats = { str=20, dex=15, mag=10, con=8 },
combat = { dam=resolvers.levelup(resolvers.rngavg(48,56), 1, 0.6), atk=resolvers.rngavg(32,60), apr=24, dammod={str=1.2} },
resolvers.tmasteries{ ["undead/skeleton"]=-0.2},
resolvers.talents{
[Talents.T_SKELETON_REASSEMBLE]={base=2, every=7, max=4},
[Talents.T_BONE_ARMOUR]={base=1, every=10, max=4},
[Talents.T_STUN]={base=1, every=9, max=6},
[Talents.T_KNOCKBACK]={base=1, every=7, max=4},
},
emote_random = {chance=1, "*SQUEAK*", "SQUEAK!!!!!"},
},
}
local rat_lich_minion_order = {"ratlich_skeletal_rat", "ratlich_ghoulish_rat", "ratlich_spectral_rat", "ratlich_vampire_rat", "ratlich_gigantic_bone_rat"} -- Sets listing order
-- Parameters are b, n, m, p where weight = b + n*tl + m*tl^p
local rat_lich_minionWeightParams = {
ratlich_skeletal_rat={7.000, 0.200, 3.000, 1.200},
ratlich_ghoulish_rat={2.000, 0.500, 3.000, 1.500},
ratlich_spectral_rat={1.471, 0.500, 3.529, 1.000},
}
local Adv_rat_lich_minionWeightParams = {
ratlich_vampire_rat={2.690, 3.139, -0.448, 2.000},
ratlich_gigantic_bone_rat={-1.076, 0.100, 1.076, 1.000},
}
-- tl = talent level, or {createrat_lich_minionsTL, rat_lich_minionmasteryTL}
-- wtable = weight table or table of weight tables
local function rat_lich_minionWeights(tl,wtable)
local tl = tl
if type(tl) == "number" then tl = {tl} end
local tables = #wtable > 0 and #wtable or 1
local chances, sum = {}, 0
for i = 1, tables do
for utype, params in pairs(tables > 1 and wtable[i] or wtable) do
chances[utype] = math.max(0,params[1] + params[2]*tl[i] + params[3]*tl[i]^params[4])
sum = sum + chances[utype]
end
end
return chances, sum
end
local function rat_lich_getMinionChances(self)
local chances, sum
local tlcm, tlmm = self:getTalentLevel(self.T_CALL_OF_THE_RAT_LICH)
if tlmm > 0 then
chances, sum = rat_lich_minionWeight({math.max(tlcm,tlmm), tlmm},{rat_lich_minionWeightParams, Adv_rat_lich_minionWeightParams}) -- Balance talent levels to avoid too many powerful rat_lich_minions
else
chances, sum = rat_lich_minionWeight(tlcm,rat_lich_minionWeightParams)
end
for i,k in pairs(chances) do
chances[i] = k*100/sum
end
return chances
end
local function rat_lich_makeMinion(self, lev)
local rat_lich_chances = rat_lich_getMinionChances(self)
local pick = rng.float(0,100)
local tot, m = 0
for k, e in pairs(chances) do
tot = tot + e
if tot > pick then m = k break end
end
m = require("mod.class.NPC").new(rat_lich_minions_list[m])
m.necrotic_minion = true
return m
end
function rat_lich_SetupSummon(self, m, x, y, level, no_control, no_decay)
m.faction = self.faction
m.summoner = self
m.summoner_gain_exp = true
m.necrotic_minion = true
m.exp_worth = 0
m.life_regen = m.life_regen + 0.2
-- m.move_others= true,
-- m.never_anger = true,
-- remove_from_party_on_death = true,
-- m.unused_stats = 0
-- m.unused_talents = 0
-- m.unused_generics = 0
-- m.unused_talents_types = 0
m.silent_levelup = true
-- m.no_points_on_levelup = true
m.save_hotkeys = true
m.ai_state = m.ai_state or {}
m.ai_state.tactic_leash = 13
local main_weapon = self:getInven("TAIL_WEAPON") and self:getInven("TAIL_WEAPON")[1]
-- Try to use stored AI talents to preserve tweaking over multiple summons
m.ai_talents = self.stored_ai_talents and self.stored_ai_talents[m.name] or {}
m.inc_damage = table.clone(self.inc_damage, true)
m.resists_pen = table.clone(self.resists_pen, true)
m.no_breath = 1
m.no_drops = true
local t = self:getTalentFromId(self.T_CALL_OF_THE_RAT_LICH)
CallofRatLichLevel=self:getTalentLevel(t)
summon_time = t.getSummonTime(self, t),
-- max_summon_time = math.ceil(self:t*10),
applyEmpathy_Call_of_the_Rat_Lich(self, m)
if game.party:hasMember(self) then
local can_control = not no_control
m.remove_from_party_on_death = true
game.party:addMember(m, {
control=can_control and "full" or "no",
type="minion",
title="Necrotic Minion",
orders = {target=true, leash=true, anchor=true, talents=true},
on_control = function(self)
local summoner = self.summoner
self:setEffect(self.EFF_SUMMON_CONTROL, 1000, {incdur=summoner:callTalent(summoner.T_SUMMON_CONTROL, "lifetime"), res=summoner:callTalent(summoner.T_SUMMON_CONTROL, "DamReduc")})
self:hotkeyAutoTalents()
end,
on_uncontrol = function(self)
self:removeEffect(self.EFF_SUMMON_CONTROL)
end,
})
end
m:resolve() m:resolve(nil, true)
m.max_level = self.level + (level or 0)
m:forceLevelup(math.max(1, self.level + (level or 0)))
game.zone:addEntity(game.level, m, "actor", x, y)
game.level.map:particleEmitter(x, y, 1, "summon")
-- Summons never flee
m.ai_tactic = m.ai_tactic or {}
m.ai_tactic.escape = 0
if self:knowTalent(self.T_BLIGHTED_SUMMONING) then m:incIncStat("mag", self:getMag()) m:incVim(m:getMaxVim()) end
self:attr("summoned_times", 1)
end
newTalent{
short_name = "ratlich_race_equip_tail_weapon",
name = "Equip Tail Weapon",
type = {"undead/ratlich-misc", 1},
points = 1,
cooldown = 1,
type_no_req = true,
no_unlearn_last = true,
no_npc_use = true,
action = function(self, t)
local inven = self:getInven("INVEN")
local d d = self:showInventory("Hold which weapon (does not work with all types)?", inven,
function(o) --weapon types to allow
return (o.subtype == "trident") or (o.subtype == "mace") or (o.subtype == "shield") or (o.subtype == "staff") or (o.subtype == "mindstar") or (o.subtype == "whip") or (o.subtype == "dagger") or (o.subtype == "longsword") or (o.subtype == "short staff") or (o.subtype == "steamsaw") or (o.subtype == "steamgun")
end,
function(o, item)
local slot = self:getInven("TAIL_WEAPON")
if not slot then return end
-- Put back the old one in inventory
local old = self:removeObject(slot, 1, true)
if old then
self:addObject(inven, old)
end
-- Fix the slot_forbid bug
if o.slot_forbid then
-- Store any original on_takeoff function
if o.on_takeoff then
o._old_on_takeoff = o.on_takeoff
end
-- Save the original slot_forbid
o._slot_forbid = o.slot_forbid
o.slot_forbid = nil
-- And prepare the resoration of everything
o.on_takeoff = function(self)
-- Remove the slot forbid fix
self.slot_forbid = self._slot_forbid
self._slot_forbid = nil
-- Run the original on_takeoff
if self._old_on_takeoff then
self.on_takeoff = self._old_on_takeoff
self._old_on_takeoff = nil
self:on_takeoff()
-- Or remove on_takeoff entirely
else
self.on_takeoff = nil
end
end
end
self.shader = nil
o = self:removeObject(inven, item)
-- Force "wield"
self:addObject(slot, o)
game.logSeen(self, "%s uses its innate magics to bind a weapon to its tail: %s.", self.name:capitalize(), o:getName{do_color=true})
self:sortInven()
d.used_talent = true
end)
local co = coroutine.running()
d.unload = function(self) coroutine.resume(co, self.used_talent) end
if not coroutine.yield() then return nil end
return true
end,
info = function(self, t)
return ([[Carry a weapon on your tail]])
end,
}
newTalent{
short_name = 'ratlich_cunning',
name = "Rat Lich's Cunning",
type = {"undead/ratlich", 1},
mode = "sustained",
require = undeads_req1,
points = 5,
cooldown = 6,
tactical = { BUFF = 4 },
statBonus = function(self, t) return math.ceil(self:combatTalentScale(t, 2, 10, 0.75)) end,
getStealth = function(self, t) return self:combatTalentScale(t, 2, 14, 0.75) end,
-- passives = function(self, t, p) end,
on_learn = function(self, t)
self:talentTemporaryValue(p, "inc_stats", {[self.STAT_STR]=t.statBonus(self, t)})
self:talentTemporaryValue(p, "inc_stats", {[self.STAT_DEX]=t.statBonus(self, t)})
-- self:attr("unharmed_attack_on_hit", 1) --have its own form of this that scale different and only has 30% chance to do as a additional attack on hit (passive hand to hand chance to does damage calculation based on spell power dex and mag? melee attack with claws with bonus damage based on spellpower)
-- self:attr("show_gloves_combat", 1) --give this after i have new attr for ratlich
end,
on_unlearn = function(self, t)
self:talentTemporaryValue(p, "inc_stats", {[self.STAT_STR]=t.statBonus(self, t)})
self:talentTemporaryValue(p, "inc_stats", {[self.STAT_DEX]=t.statBonus(self, t)})
-- self:attr("unharmed_attack_on_hit", 1) --have its own form of this that scale different and only has 30% chance to do as a additional attack on hit (passive hand to hand chance to does damage calculation based on spell power dex and mag? melee attack with claws with bonus damage based on spellpower)
-- self:attr("show_gloves_combat", 1) --give this after i have new attr for ratlich
end,
activate = function(self, t)
local ret = {}
self:talentTemporaryValue(ret, "inc_stealth", t.getStealth(self, t))
return ret
end,
deactivate = function(self, t, p)
return true
end,
info = function(self, t)
return ([[Your cunning and magic increases with the mastery of %d.
Talent can be sustained to grant some stealth
]]):
--- Having 1 point in this skill grants a chance to do a unarmed attack with your claws. Still need a way to do hand to hand combat while using weapon and scaling it with spellpower or mindpower instead
format(t.statBonus(self, t), t.getStealth(self, t))
end
}
newTalent{
short_name = 'ratlich_dark_feed',
name = "Rat Lich's Dark Feed", --uses nul's Searing Ire as a template for this skill
type = {"undead/ratlich", 2},
speed = "spell",
random_ego = "attack",
require = undeads_req2,
tactical = { ATTACK = 2, HEAL = 1, CLOSEIN = 3},
points = 5,
requires_target = true,
cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 19, 25, 23)) end, --Limit to >19
range = function(self, t) return math.min(10, self:combatTalentScale(t, 7, 9)) end,
target = function(self, t) return {type="bolt", range=self:getTalentRange(t), nolock=true, nowarning=true, requires_knowledge=false, stop__block=true} end,
getClawDamage = function(self, t)
return self:combatTalentWeaponDamage(t, 0.4, 1.2) --change this to use you gloves attack and damage later
end,
getDarkFeedBite = function(self, t)
return self:combatTalentSpellDamage(t, 20, 120) --maybe add stat mods to this later ---add mindpower scaling later if its higher
end,
action = function(self, t)
if self:attr("never_move") and core.fov.distance(self.x, self.y, tx, ty) > 0 then return nil end
local tg = {type="hit", range=self:getTalentRange(t)}
local x, y, target = self:getTarget(tg)
if not x or not y or not target then return nil end
if core.fov.distance(self.x, self.y, x, y) > self:getTalentRange(t) then return nil end
local block_actor = function(_, bx, by) return game.level.map:checkEntity(bx, by, Map.TERRAIN, "block_move", self) end
local l = self:lineFOV(x, y, block_actor)
local tx, ty = lx, ly
while lx and ly do
if game.level.map:checkAllEntities(lx, ly, "block_move", self) then break end
tx, ty = lx, ly
end
if not (x and y and tx and ty) then return nil end
if core.fov.distance(x, y, tx, ty) > 2 then return nil end
local ox, oy = self.x, self.y
self:move(tx, ty, true)
if config.settings.tome.smooth_move > 0 then
self:resetMoveAnim()
self:setMoveAnim(ox, oy, 8, 5)
end
-- Attack ?
if core.fov.distance(self.x, self.y, x, y) == 1 then
-- self:attackTarget(target, nil, t.getClawDamage(self,t)) ---change to forced hand to hand attack later weapon damage unneeded
local dam = self:spellCrit( t.getDarkFeedBite(self, t) )
local tg2 = {type="bolt", range=1, selffire=false, radius=0, talent=t}
local grids = self:project(tg2, x, y,
function(tx, ty)
local target = game.level.map(tx, ty, Map.ACTOR)
if (not target) then return end -- removed friendly fire avoid so you can turn on your allies if not careful or need a heal bad enough
DamageType:get(DamageType.HELLCOM_RATLICHDARKFEED).projector(self, tx, ty, DamageType.HELLCOM_RATLICHDARKFEED, dam)
target = game.level.map(tx, ty, Map.ACTOR)
end)
-- game.level.map:particleEmitter(x, y, tg2.radius, "dark_torrent", {radius=tg2.0, grids=grids, tx=x, ty=y, max_alpha=80})
game:playSoundNear(self, "creatures/rats/rat_attack")
end
return true
end,
info = function(self, t)
local range = self:getTalentRange(t)
local wdam = t.getDamage(self, t) * 100
local adam = t.getDarkFeedBite(self, t)
return ([[Channel your dark magics that power you form to hurl yourself %d spaces to an enemy, then attack for %d%% unarmed damage. Hit or miss you will attack with a bite infused with you dark magic (90% darkness, 10% physical) for %d%% that will heal you for the amount of damage dealt.
The damage will increase with your Spellpower.]]
):format(range, wdam, rad, damDesc(self, DamageType.HELLCOM_RATLICHDARKFEED, adam))
end,
}
newTalent{
short_name = 'rat_lich_tactical_retreat',
name = "Rat Lich's Tactical Retreat", --uses a tweaked lightning speed effect atm --might make it have a small cover of darkness as you move later to make it harder to see your real position
type = {"undead/ratlich", 3},
require = undeads_req3,
points = 5,
cooldown = 40,
range = 10,
tactical = { ESCAPE = 3, CLOSEIN = 1 },
requires_target = true,
no_energy = true,
getPassiveSpeed = function(self, t) return self:combatTalentScale(t, 0.08, 0.4, 0.5) end,
getSpeed = function(self, t) return self:combatTalentScale(t, 500, 800, 0.75) end,--reduce the bonus but allow it to scale?
getDuration = function(self, t) return math.ceil(self:combatTalentScale(t, 1, 2)) end,
passives = function(self, t, p)
self:talentTemporaryValue(p, "movement_speed", t.getPassiveSpeed(self, t))
end,
on_pre_use = function(self, t) return not self:attr("never_move") end,
action = function(self, t)
self:setEffect(self.EFF_RATLICH_SPEED, self:spellCrit(t.getDuration(self, t)), {power=t.getSpeed(self, t)})
return true
end,
info = function(self, t)
return ([[For a %d%% turns you focus your innate dark magics to improve your movement speed by %d%% to close the gap or flee from danger.
Each point in this skill will raise your Movement Speed by %d%%, passively
While this effect you a granted 100% darkness resistance.
Any any action other then moving will remove the effect).]]):format(t.getSpeed(self, t), t.getDuration(self, t), t.getPassiveSpeed(self, t)*100)
end,
}
newTalent{
short_name = 'call_of_the_rat_lich',
name = "Call of the Rat Lich",
type = {"undead/ratlich", 4},
tactical = { DEFEND = 3 },
require = undeads_req4,
requires_target = true,
range = 0,
radius = 5,
no_energy = true,
points = 5,
cooldown = 50,
summonTime = function(self, t) return math.floor(self:combatScale(self:getTalentLevel(t), 30, 0, 45, 5)) end,
-- local nb = t.getMax(self, t)
-- local lev = t.getLevel(self, t)
target = function(self, t)
return {type="cone", range=self:getTalentRange(t), radius=self:getTalentRadius(t), selffire=false, talent=t}
end,
getRatLichMax = function(self, t)
local max = math.max(1, math.floor(self:combatTalentScale(t, 2, 6, "log")))
if necroEssenceDead(self, true) then max = max + 2 end
return max - necroGetNbSummon(self)
end, -- talent level 1-5 gives 1-5
getLevel = function(self, t) return math.floor(self:combatScale(self:getTalentLevel(t), -2, 0.9, 1, 2)) end,
rat_lich_minionChancesDesc = function(self)
local c = rat_lich_getMinionChances(self)
local rat_lich_chancelist = tstring({})
for i, k in ipairs(rat_lich_minion_order) do
if c[k] then rat_lich_chancelist:add(true,rat_lich_minions_list[k].name:capitalize(),(": %d%%"):format(c[k])) end
end
return rat_lich_chancelist:toString()
end,
action = function(self, t)
local nb = t.getMax(self, t)
local lev = t.getLevel(self, t)
-- Summon minions in a cone
local tg = self:getTalentTarget(t)
local x, y = self:getTarget(tg)
if not x or not y then return nil end
local possible_spots = {}
self:project(tg, x, y, function(px, py)
if not game.level.map:checkAllEntities(px, py, "block_move") then
possible_spots[#possible_spots+1] = {x=px, y=py}
end
end)
for i = 1, nb do
local rat_lich_minion = rat_lich_makeMinion(self, self:getTalentLevel(t))
local pos = rng.tableRemove(possible_spots)
if rat_lich_minion and pos then
rat_lich_necroSetupSummon(self, rat_lich_minion, pos.x, pos.y, lev, true)
end
end
local empower = necroEssenceDead(self)
if empower then empower() end
game:playSoundNear(self, "talents/spell_generic2")
--game.logSeen(who, "%s raises %s %s, and a red light flashes from it's eye sockets!", who.name:capitalize(), who:his_her(), self:getName({do_color=true, no_add_name=true})),
return true
end,
info = function(self, t)
-- return ([[You use your innate dark magics to call (up to %d rat_lich_minions) undead rats (The rat_lich_minions level is your level %+d.) that live for %D% turns. Chance for each minion type changes with talent level. (if you possess skull of the rat lich it has a chance to spawn special undead rodent types (not restricted yet).]]:format --(t.summonTime(self, t)) --nb, lev, --t.rat_lich_minionChancesDesc(self, t))
end,
}
---ideas for new rat lich themed undead
---undead plague rat
---undead gloom rat
---undead mage ratman?
--undead steam ratman?