Skip to content
Snippets Groups Projects
Commit 219b4d77 authored by dg's avatar dg
Browse files

Temporal Devourers renamed Devourer and subtype changed to eldritch

Temporal Dredge renmed Dredge (subtype still temporal)
Worm that Walks and Devourers now have unique talents
Devourer hit points and damage improved (beware the land sharks!!)
Carrion Worms multiply less but have better resists
Epidemic now checks for disease immunity when spreading diseases
Dredge Frenzy improved a bit


git-svn-id: http://svn.net-core.org/repos/t-engine4@4271 51575b47-30f0-44d4-a5cc-537603b46e54
parent c1037087
No related branches found
No related tags found
No related merge requests found
......@@ -143,6 +143,9 @@ function _M:init(t, no_default)
t.resists = t.resists or {}
t.resists_cap = t.resists_cap or { all = 100 }
t.resists_pen = t.resists_pen or {}
-- Absorbs a percentage of damage
t.damage_affinity = t.damage_affinity or {}
-- % Increase damage
t.inc_damage = t.inc_damage or {}
......
......@@ -133,7 +133,14 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr)
target:setEffect(target.EFF_SMEARED, 6, {src=src, power=smear/6})
dam = 0
end
-- affinity healing, we store it to apply it after damage is resolved
local affinity_heal = 0
if target.damage_affinity then
local aff = (target.damage_affinity[type] or 0) / 100
affinity_heal = (dam * aff)
end
-- Reduce damage with resistance
if target.resists then
local pen = 0
......@@ -198,6 +205,12 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr)
target:setEffect(target.EFF_ELEMENTAL_HARMONY, 5 + math.ceil(target:attr("elemental_harmony")), {power=target:attr("elemental_harmony"), type=type})
end
end
-- damage affinity healing
if not target.dead and affinity_heal > 0 then
target:heal(affinity_heal)
game.logSeen(target, "%s is healed by the %s%s#LAST# damage!", target.name:capitalize(), DamageType:get(type).text_color or "#aaaaaa#", DamageType:get(type).name)
end
if dam > 0 and 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 not src.__projecting_for.talent_on_hit_done then
local t = src:getTalentFromId(src.__projecting_for.project_type.talent or src.__projecting_for.project_type.talent_id)
......@@ -1546,17 +1559,6 @@ newDamageType{
end,
}
-- Dredge Haste
newDamageType{
name = "dredge frenzy", type = "DREDGE_FRENZY",
projector = function(src, x, y, type, dam)
local target = game.level.map(x, y, Map.ACTOR)
if target and target.dredge then
target:setEffect(target.EFF_SPEED, 3, {power=0.6})
end
end,
}
newDamageType{
name = "devour life", type = "DEVOUR_LIFE",
projector = function(src, x, y, type, dam)
......
......@@ -44,7 +44,8 @@ newEntity{
newEntity{ base = "BASE_NPC_HORROR",
name = "worm that walks", color=colors.SANDY_BROWN,
desc = [[A maggot-filled robe with a vaguely humanoid shape.]],
desc = [[A bulging rotten robe seems to tear at the seams, with masses of bloated worms spilling from out and around the moving form. Two arm-like appendages, each made up of overlapping mucous-drenched maggots, grasp tightly around the handles of bile-coated waraxes.
Each swing drips pestulant fluid before it, and each droplet writhes and wriggles in the air before splashing against the ground.]],
level_range = {25, nil}, exp_worth = 1,
rarity = 5,
max_life = resolvers.rngavg(150,170),
......@@ -52,8 +53,9 @@ newEntity{ base = "BASE_NPC_HORROR",
rank = 3,
hate_regen = 1,
vim_regen = 1,
ai = "tactical", ai_state = { ai_move="move_dmap", talent_in=1, },
autolevel = "warriormage",
ai = "tactical", ai_state = { ai_move="move_dmap", talent_in=1, ally_compassion=0 },
ai_tactic = resolvers.tactic "melee",
see_invisible = 100,
......@@ -61,10 +63,11 @@ newEntity{ base = "BASE_NPC_HORROR",
stun_immune = 1,
blind_immune = 1,
disease_immune = 1,
move_others=true,
resists = { [DamageType.PHYSICAL] = 50, [DamageType.BLIGHT] = 100, [DamageType.FIRE] = -50},
resists = { [DamageType.PHYSICAL] = 50, [DamageType.ACID] = 100, [DamageType.BLIGHT] = 100, [DamageType.FIRE] = -50},
damage_affinity = { [DamageType.BLIGHT] = 50 },
no_auto_resists = true,
body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 },
resolvers.drops{chance=20, nb=1, {} },
resolvers.equip{
......@@ -78,15 +81,15 @@ newEntity{ base = "BASE_NPC_HORROR",
resolvers.inscriptions(1, {"regeneration infusion"}),
resolvers.talents{
--[Talents.T_BONE_GRAB]={base=4, every=10},
[Talents.T_BLINDSIDE]={base=5, every=12},
[Talents.T_WORM_ROT]={base=4, every=8},
[Talents.T_EPIDEMIC]={base=4, every=8},
[Talents.T_REND]={base=4, every=8},
[Talents.T_ACID_STRIKE]={base=4, every=8},
[Talents.T_BLOODLUST]={base=4, every=8},
[Talents.T_RUIN]={base=4, every=8},
[Talents.T_CORRUPTED_STRENGTH]={base=3, every=15},
[Talents.T_SLASH]={base=4, every=12},
[Talents.T_FRENZY]={base=4, every=15},
[Talents.T_REND]={base=4, every=12},
[Talents.T_BLOODLUST]={base=3, every=12},
[Talents.T_RUIN]={base=2, every=12},
[Talents.T_SUMMON]=1,
[Talents.T_BLINDSIDE]={base=3, every=12},
[Talents.T_WEAPON_COMBAT]={base=5, every=10, max=10},
[Talents.T_WEAPONS_MASTERY]={base=3, every=10, max=10},
......@@ -96,14 +99,12 @@ newEntity{ base = "BASE_NPC_HORROR",
on_takehit = function(self, value, src)
if value >= (self.max_life * 0.1) then
self:forceUseTalent(self.T_SUMMON, {ignore_energy=true, ignore_cd=true})
local t = self:getTalentFromId(self.T_WORM_ROT)
t.spawn_carrion_worm(self, self, t)
game.logSeen(self, "#LIGHT_RED#A carrion worm mass has spawned from %s' wounds!", self.name)
end
return value
end,
summon = {
{type="vermin", subtype="worms", name="carrion worm mass", number=1, hasxp=false},
},
}
newEntity{ base = "BASE_NPC_HORROR",
......@@ -474,11 +475,9 @@ newEntity{ base = "BASE_NPC_HORROR",
},
}
-- Temporal Horrors
newEntity{ base = "BASE_NPC_HORROR",
subtype = "temporal",
name = "temporal devourer", color=colors.CRIMSON,
subtype = "eldritch",
name = "devourer", color=colors.CRIMSON,
desc = "A headless, round creature with stubby legs and arms. Its body seems to be all teeth.",
level_range = {10, nil}, exp_worth = 1,
rarity = 2,
......@@ -486,17 +485,27 @@ newEntity{ base = "BASE_NPC_HORROR",
movement_speed = 0.8,
size_category = 2,
autolevel = "warrior",
max_life = resolvers.rngavg(50, 80),
combat_armor = 1, combat_def = 10,
combat = { dam=resolvers.levelup(resolvers.rngavg(20,30), 1, 1.2), atk=resolvers.rngavg(10,20), apr=5, dammod={str=1} },
max_life = resolvers.rngavg(80, 100),
life_rating = 14,
life_regen = 4,
combat_armor = 16, combat_def = 1,
combat = { dam=resolvers.levelup(resolvers.rngavg(25,40), 1, 0.6), atk=resolvers.rngavg(25,50), apr=25, dammod={str=1.1}, physcrit = 10 },
ai_state = { talent_in=2, },
resists = { [DamageType.TEMPORAL] = 5},
resolvers.talents{
[Talents.T_BLOODBATH]={base=1, every=5, max=7},
[Talents.T_GNASHING_TEETH]={base=1, every=5, max=7},
-- talents only usable while frenzied
[Talents.T_FRENZIED_LEAP]={base=1, every=5, max=7},
[Talents.T_FRENZIED_BITE]={base=1, every=5, max=7},
},
make_escort = {
{type="horror", subtype="temporal", name="temporal devourer", number=2, no_subescort=true},
{type="horror", subtype="eldritch", name="devourer", number=2, no_subescort=true},
},
}
-- temporal horrors
newEntity{ base = "BASE_NPC_HORROR",
subtype = "temporal",
dredge = 1,
......@@ -511,7 +520,7 @@ newEntity{ base = "BASE_NPC_HORROR",
combat_armor = 1, combat_def = 10,
combat = { dam=resolvers.levelup(resolvers.rngavg(15,20), 1, 1.1), atk=resolvers.rngavg(5,15), apr=5, dammod={str=1} },
resists = { [DamageType.TEMPORAL] = 5},
resists = { [DamageType.TEMPORAL] = 25},
resolvers.talents{
[Talents.T_DUST_TO_DUST]={base=1, every=7, max=5},
......@@ -523,7 +532,7 @@ newEntity{ base = "BASE_NPC_HORROR",
newEntity{ base = "BASE_NPC_HORROR",
subtype = "temporal",
dredge = 1,
name = "temporal dredge", color=colors.PINK,
name = "dredge", color=colors.PINK,
desc = "A hulking pink-skinned creature with long arms as thick as tree trunks. It drags its knuckles on the ground as it lumbers toward you.",
level_range = {15, nil}, exp_worth = 1,
rarity = 2,
......@@ -536,7 +545,7 @@ newEntity{ base = "BASE_NPC_HORROR",
combat_armor = 1, combat_def = 0,
combat = { dam=resolvers.levelup(resolvers.rngavg(25,150), 1, 1.2), atk=resolvers.rngavg(25,130), apr=1, dammod={str=1.1} },
resists = {all = 10, [DamageType.TEMPORAL] = 50, [DamageType.PHYSICAL] = 25},
resists = {all = 10, [DamageType.TEMPORAL] = 25, [DamageType.PHYSICAL] = 25},
resolvers.talents{
[Talents.T_STUN]={base=3, every=7, max=7},
......@@ -565,7 +574,7 @@ newEntity{ base = "BASE_NPC_HORROR",
resists = {all = 10, [DamageType.TEMPORAL] = 50},
make_escort = {
{type="horror", subtype="temporal", name="temporal dredge", number=3, no_subescort=true},
{type="horror", subtype="temporal", name="dredge", number=3, no_subescort=true},
},
resolvers.inscriptions(1, {"shielding rune"}),
......
......@@ -66,15 +66,18 @@ newEntity{ base = "BASE_NPC_WORM",
newEntity{ base = "BASE_NPC_WORM",
name = "carrion worm mass", color=colors.SANDY_BROWN,
can_multiply = 2,
level_range = {20, nil}, exp_worth = 1,
rarity = 4,
max_life = resolvers.rngavg(5,9),
combat = { dam=1, atk=15, apr=100 },
resists = {[DamageType.BLIGHT] = 100},
disease_immune = 1,
resists = { [DamageType.PHYSICAL] = 50, [DamageType.ACID] = 100, [DamageType.BLIGHT] = 100, [DamageType.FIRE] = -50},
no_auto_resists = true,
autolevel = "warriormage",
resolvers.talents{ [Talents.T_CRAWL_POISON]=2, [Talents.T_ROTTING_DISEASE]=4, [Talents.T_MULTIPLY]=1 },
resolvers.talents{ [Talents.T_CRAWL_ACID]=2, [Talents.T_ROTTING_DISEASE]=4, [Talents.T_MULTIPLY]=1 },
on_die = function(self, src)
game.level.map:addEffect(self,
......@@ -82,7 +85,7 @@ newEntity{ base = "BASE_NPC_WORM",
engine.DamageType.BLIGHT, self:getStr(90, true),
2,
5, nil,
engine.Entity.new{alpha=100, display='', color_br=30, color_bg=180, color_bb=60}
engine.Entity.new{alpha=50, display='', color_br=30, color_bg=180, color_bb=60}
)
game.logSeen(self, "%s exudes a corrupted gas as it dies.", self.name:capitalize())
end,
......
......@@ -212,7 +212,11 @@ newTalent{
local disease = rng.table(diseases)
local params = disease.params
params.src = self
target:setEffect(disease.id, 6, {src=self, dam=disease.params.dam, str=disease.params.str, dex=disease.params.dex, con=disease.params.con, heal_factor=disease.params.heal_factor})
if target:checkHit(self:combatSpellpower(), target:combatSpellResist(), 0, 95, 12 - self:getTalentLevel(t)) and target:canBe("disease") then
target:setEffect(disease.id, 6, {src=self, dam=disease.params.dam, str=disease.params.str, dex=disease.params.dex, con=disease.params.con, heal_factor=disease.params.heal_factor, burst=disease.params.burst})
else
game.logSeen(target, "%s resists the disease!", target.name:capitalize())
end
game.level.map:particleEmitter(px, py, 1, "slime")
end)
end,
......
......@@ -19,11 +19,139 @@
newTalentType{ type="technique/horror", name = "horror techniques", hide = true, description = "Physical talents of the various horrors of the world." }
newTalentType{ no_silence=true, is_spell=true, type="spell/horror", name = "horror spells", hide = true, description = "Spell talents of the various horrors of the world." }
newTalentType{ no_silence=true, is_spell=true, type="corruption/horror", name = "horror spells", hide = true, description = "Spell talents of the various horrors of the world." }
newTalentType{ type="other/horror", name = "horror powers", hide = true, description = "Unclassified talents of the various horrors of the world." }
local oldTalent = newTalent
local newTalent = function(t) if type(t.hide) == "nil" then t.hide = true end return oldTalent(t) end
-- Bloated Horror Powers
-- Ideas; Mind Shriek (confusion, plus mental damge each turn), Hallucination (Clones that die on hit if the target makes a mental save)
-- Devourer Powers
newTalent{
name = "Frenzied Bite",
type = {"technique/horror", 3},
points = 5,
cooldown = 12,
stamina = 24,
tactical = { ATTACK = 1, DISABLE = 2 },
message = "In a frenzy @Source@ bites at @Target@!",
on_pre_use = function(self, t, silent) if not self:hasEffect(self.EFF_FRENZY) then return false end return true end,
action = function(self, t)
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 math.floor(core.fov.distance(self.x, self.y, x, y)) > 1 then return nil end
local hit = self:attackTarget(target, nil, self:combatTalentWeaponDamage(t, 1, 1.7), true)
if hit then
if target:checkHit(self:combatAttackStr(), target:combatPhysicalResist(), 0, 95, 5) and target:canBe("cut") then
target:setEffect(target.EFF_DEEP_WOUND, 5, {src=self, heal_factor=self:getTalentLevel(t) * 10, power=self:combatTalentWeaponDamage(t, 1.5, 3)/5})
end
end
return true
end,
info = function(self, t)
return ([[A nasty bite that causes a deep wound, only usable in a frenzy.]])
end,
}
newTalent{
name = "Frenzied Leap", -- modified ghoulish leap, only usable while in a frenzy
type = {"technique/horror", 1},
points = 5,
cooldown = 5,
tactical = { CLOSEIN = 3 },
direct_hit = true,
message = "@Source@ leaps forward in a frenzy!",
range = function(self, t) return math.floor(2 + self:getTalentLevel(t)) end,
requires_target = true,
on_pre_use = function(self, t, silent) if not self:hasEffect(self.EFF_FRENZY) or self:attr("encased_in_ice") or self:attr("never_move") then return false end return true end,
action = function(self, t)
local tg = {type="hit", range=self:getTalentRange(t)}
local x, y, target = self:getTarget(tg)
if not x or not y then return nil end
if math.floor(core.fov.distance(self.x, self.y, x, y)) > self:getTalentRange(t) then return nil end
local l = line.new(self.x, self.y, x, y)
local lx, ly = l()
local tx, ty = lx, ly
lx, ly = l()
while lx and ly do
if game.level.map:checkEntity(lx, ly, Map.TERRAIN, "block_move", self) then break end
tx, ty = lx, ly
lx, ly = l()
end
-- Find space
if game.level.map:checkEntity(tx, ty, Map.TERRAIN, "block_move", self) then return nil end
local fx, fy = util.findFreeGrid(tx, ty, 5, true, {[Map.ACTOR]=true})
if not fx then
return
end
self:move(fx, fy, true)
return true
end,
info = function(self, t)
return ([[Leap toward your target.]])
end,
}
newTalent{
name = "Gnashing Teeth",
type = {"technique/horror", 1},
points = 5,
cooldown = 3,
stamina = 8,
message = "@Source@ tries to bite @Target@ with razor sharp teeth!",
requires_target = true,
tactical = { ATTACK = 2 },
do_devourer_frenzy = function(self, target, t)
game.logSeen(self, "The scent of blood sends the %ss into a frenzy!", self.name:capitalize())
-- frenzy devourerers
local tg = {type="ball", range=0, radius=3, selffire=true, talent=t}
self:project(tg, target.x, target.y, function(px, py)
local target = game.level.map(px, py, engine.Map.ACTOR)
local reapplied = false
if target then
local actor_frenzy = false
if target.name == "devourer" then
actor_frenzy = true
end
if actor_frenzy then
-- silence the apply message if the target already has the effect
for eff_id, p in pairs(target.tmp) do
local e = target.tempeffect_def[eff_id]
if e.name == "Frenzy" then
reapplied = true
end
end
target:setEffect(target.EFF_FRENZY, math.floor(2 + self:getTalentLevel(t)), {crit = self:getTalentLevel(t) * 3, power=self:getTalentLevel(t) * 0.2, dieat=self:getTalentLevel(t) * 0.2}, reapplied)
end
end
end)
end,
action = function(self, t)
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 math.floor(core.fov.distance(self.x, self.y, x, y)) > 1 then return nil end
local hit = self:attackTarget(target, nil, self:combatTalentWeaponDamage(t, 0.5, 1), true)
if target:checkHit(self:combatAttackStr(), target:combatPhysicalResist(), 0, 95, 8 - self:getTalentLevel(t) / 2) and target:canBe("cut") then
target:setEffect(target.EFF_CUT, 5, {power=self:combatTalentWeaponDamage(t, 0.8, 1.5), src=self})
t.do_devourer_frenzy(self, target, t)
else
game.logSeen(target, "%s resists the cut!", target.name:capitalize())
end
return true
end,
info = function(self, t)
return ([[Bites the target, potentially causing it to bleed. The blood will send the devourer into a frenzy (which in turn will frenzy nearby devourers).]])
end,
}
-- Nightmare Horror Powers
newTalent{
......@@ -45,7 +173,7 @@ newTalent{
if not x then
return
end
local m = target:clone{
shader = "shadow_simulacrum",
no_drops = true,
......@@ -63,7 +191,7 @@ newTalent{
mod.class.NPC.castAs(m)
engine.interface.ActorAI.init(m, m)
m.energy.value = 0
m.player = nil
m.max_life = m.max_life / 2
......@@ -75,7 +203,7 @@ newTalent{
m.seen_by = nil
m.can_talk = nil
m.clone_on_hit = nil
-- Remove some talents
local tids = {}
for tid, _ in pairs(m.talents) do
......@@ -86,10 +214,10 @@ newTalent{
if t.mode == "sustained" and m:isTalentActive(t.id) then m:forceUseTalent(t.id, {ignore_energy=true}) end
m.talents[t.id] = nil
end
-- nil the Inner Demons effect to squelch combat log spam
m.tmp[m.EFF_INNER_DEMONS] = nil
-- remove detrimental timed effects
local effs = {}
for eff_id, p in pairs(m.tmp) do
......@@ -98,7 +226,7 @@ newTalent{
effs[#effs+1] = {"effect", eff_id}
end
end
while #effs > 0 do
local eff = rng.tableRemove(effs)
if eff[1] == "effect" then
......@@ -106,12 +234,12 @@ newTalent{
end
end
game.zone:addEntity(game.level, m, "actor", x, y)
game.level.map:particleEmitter(x, y, 1, "shadow")
game.logSeen(target, "%s's Inner Demon manifests!", target.name:capitalize())
end,
action = function(self, t)
local tg = {type="hit", range=self:getTalentRange(t), talent=t}
......@@ -121,13 +249,13 @@ newTalent{
if not x or not y then return nil end
local target = game.level.map(x, y, Map.ACTOR)
if not target then return nil end
if target:checkHit(self:combatSpellpower(), target:combatSpellResist(), 0, 95, 15) and target:canBe("fear") then
target:setEffect(target.EFF_INNER_DEMONS, t.getDuration(self, t), {src = self, chance=t.getChance(self, t), dam=t.getDamage(self, t)})
else
game.logSeen(target, "%s resists the demons!", target.name:capitalize())
end
return true
end,
info = function(self, t)
......@@ -156,13 +284,13 @@ newTalent{
if not x or not y then return nil end
local target = game.level.map(x, y, Map.ACTOR)
if not target then return nil end
if target:checkHit(self:combatSpellpower(), target:combatSpellResist(), 0, 95, 15) and target:canBe("fear") then
target:setEffect(target.EFF_WAKING_NIGHTMARE, t.getDuration(self, t), {src = self, chance=t.getChance(self, t), dam=t.getDamage(self, t)})
else
game.logSeen(target, "%s resists the nightmare!", target.name:capitalize())
end
return true
end,
info = function(self, t)
......@@ -211,7 +339,8 @@ newTalent{
return ([[An area of effect that causes darkness damage and reduces the lite radius and darkness resistance of those within.]])
end,
}
-- Temporal Stalker Powers
-- Ideas; Damage Shift >:) Give more temporal effects, especially Warden effects, raise AP and add Temporal Damage on hit to mimic weapon folding, give invis rune
-- Void Horror Powers
newTalent{
name = "Echoes From The Void",
......@@ -233,13 +362,13 @@ newTalent{
if not x or not y then return nil end
local target = game.level.map(x, y, Map.ACTOR)
if not target then return nil end
if target:checkHit(self:combatMindpower(), target:combatMentalResist(), 0, 95, 15) and target:canBe("fear") then
target:setEffect(target.EFF_VOID_ECHOES, 6, {src=self, power=t.getDamage(self, t)})
if target:checkHit(src:combatMindpower(), target:combatMentalResist(), 0, 95, 15) and target:canBe("fear") then
target:setEffect(target.EFF_VOID_ECHOES, 6, {src= self, power=t.getDamage(self, t)})
else
game.logSeen(target, "%s resists the void!", target.name:capitalize())
end
game:playSoundNear(self, "talents/arcane")
return true
end,
......@@ -269,9 +398,9 @@ newTalent{
local _ _, tx, ty = self:canProject(tg, tx, ty)
target = game.level.map(tx, ty, Map.ACTOR)
if target == self then target = nil end
if self:getTalentLevel(t) < 5 then self:setEffect(self.EFF_SUMMON_DESTABILIZATION, 500, {power=5}) end
for i = 1, self:getTalentLevelRaw(t) do
-- Find space
local x, y = util.findFreeGrid(tx, ty, 5, true, {[Map.ACTOR]=true})
......@@ -287,41 +416,41 @@ newTalent{
name = "void shard", faction = self.faction,
desc = [[It looks like a small hole in the fabric of spacetime.]],
stats = { str=22, dex=20, wil=15, con=15 },
--level_range = {self.level, self.level},
--level_range = {self.level, self.level},
exp_worth = 0,
max_life = resolvers.rngavg(5,10),
life_rating = 2,
rank = 2,
size_category = 1,
autolevel = "summoner",
ai = "summoned", ai_real = "dumb_talented_simple", ai_state = { talent_in=2, ai_move="move_snake" },
ai = "summoned", ai_real = "dumb_talented_simple", ai_state = { talent_in=2, ai_move="move_snake" },
combat_armor = 1, combat_def = 1,
combat = { dam=resolvers.levelup(resolvers.mbonus(40, 15), 1, 1.2), atk=15, apr=15, dammod={wil=0.8}, damtype=DamageType.TEMPORAL },
on_melee_hit = { [DamageType.TEMPORAL] = resolvers.mbonus(20, 10), },
infravision = 10,
no_breath = 1,
fear_immune = 1,
stun_immune = 1,
confusion_immune = 1,
silence_immune = 1,
ai_target = {actor=target}
}
m.faction = self.faction
m.summoner = self
m.summoner = self
m.summoner_gain_exp=true
m.summon_time = t.getSummonTime(self, t)
m:resolve() m:resolve(nil, true)
m:forceLevelup(self.level)
game.zone:addEntity(game.level, m, "actor", x, y)
game.level.map:particleEmitter(x, y, 1, "summon")
m:setEffect(m.EFF_TEMPORAL_DESTABILIZATION, 5, {src=self, dam=t.getDamage(self, t), explosion=self:spellCrit(t.getExplosion(self, t))})
end
game:playSoundNear(self, "talents/spell_generic")
return true
......@@ -329,4 +458,56 @@ newTalent{
info = function(self, t)
return ([[Summons shards of explosive doom!]])
end,
}
\ No newline at end of file
}
-- Worm that Walks Powers
newTalent{
name = "Worm Rot",
type = {"corruption/horror", 1},
points = 5,
cooldown = 8,
vim = 10,
range = 6,
requires_target = true,
tactical = { ATTACK = 2, DISABLE = 4 },
getBurstDamage = function(self, t) return self:combatTalentSpellDamage(t, 30, 300) end,
getDamage = function(self, t) return self:combatTalentSpellDamage(t, 5, 50) end,
getHealReduction = function(self, t) return self:combatTalentSpellDamage(t, 20, 70) end,
getDuration = function(self, t) return 4 + math.ceil(self:getTalentLevel(t)) end,
proj_speed = 6,
spawn_carrion_worm = function (self, target, t)
local x, y = util.findFreeGrid(target.x, target.y, 10, true, {[Map.ACTOR]=true})
if not x then
return
end
local worm = {type="vermin", subtype="worms", name="carrion worm mass", number=1, hasxp=false}
local m = game.zone:makeEntity(game.level, "actor", worm, nil, true)
m:resolve()
m.faction = self.faction
game.zone:addEntity(game.level, m, "actor", x, y)
end,
action = function(self, t)
local tg = {type="bolt", range=self:getTalentRange(t), talent=t, display={particle="bolt_slime"}}
local x, y = self:getTarget(tg)
if not x or not y then return nil end
self:project(tg, x, y, function(px, py)
local target = game.level.map(px, py, engine.Map.ACTOR)
if not target then return end
if target:checkHit(self:combatSpellpower(), target:combatSpellResist(), 0, 95, 12 - self:getTalentLevel(t)) and target:canBe("disease") then
target:setEffect(target.EFF_WORM_ROT, 5, {src=self, dam=t.getDamage(self, t), burst=t.getBurstDamage(self, t)})
else
game.logSeen(target, "%s resists the worm rot!", target.name:capitalize())
end
game.level.map:particleEmitter(px, py, 1, "slime")
end)
game:playSoundNear(self, "talents/slime")
return true
end,
info = function(self, t)
return ([[A terrible rotting disease that removes a beneficial physical effect and deals acid and blight damage each turn. If not cleared after a full five turn duration it will inflict extra damage and spawn a carrion worm mass.]])
end,
}
......@@ -1119,7 +1119,7 @@ newTalent{
target = function(self, t)
return {type="beam", range=self:getTalentRange(t), talent=t}
end,
tactical = { ATTACK = 3 },
tactical = { ATTACK = 2, ESCAPE = 2 },
action = function(self, t)
local tg = self:getTalentTarget(t)
local x, y = self:getTarget(tg)
......@@ -1418,7 +1418,7 @@ newTalent{
points = 5,
cooldown = 6,
tactical = {
BUFF = 10,
BUFF = 4,
},
direct_hit = true,
range = 0,
......@@ -1428,9 +1428,30 @@ newTalent{
end,
action = function(self, t)
local tg = self:getTalentTarget(t)
local grids = self:project(tg, self.x, self.y, DamageType.DREDGE_FRENZY)
self:project(tg, self.x, self.y, function(px, py)
local target = game.level.map(px, py, engine.Map.ACTOR)
local reapplied = false
if target then
local actor_frenzy = false
if target.dredge then
actor_frenzy = true
end
if actor_frenzy then
-- silence the apply message if the target already has the effect
for eff_id, p in pairs(target.tmp) do
local e = target.tempeffect_def[eff_id]
if e.name == "Frenzy" then
reapplied = true
end
end
target:setEffect(target.EFF_FRENZY, self:getTalentLevel(t), {crit = self:getTalentLevel(t), power=self:getTalentLevel(t) * 0.1, dieat=self:getTalentLevel(t) * 0.1}, reapplied)
end
end
end)
game.level.map:particleEmitter(self.x, self.y, tg.radius, "ball_light", {radius=tg.radius})
game:playSoundNear(self, "talents/arcane")
return true
end,
info = function(self, t)
......
......@@ -1506,7 +1506,7 @@ newEffect{
newEffect{
name = "EPIDEMIC",
desc = "Epidemic",
long_desc = function(self, eff) return ("The target is infected by a disease, doing %0.2f blight damage per turn.\nEach non-disease blight damage done to it will spread the disease."):format(eff.dam) end,
long_desc = function(self, eff) return ("The target is infected by a disease, doing %0.2f blight damage per turn and reducig healing received by %d%%.\nEach non-disease blight damage done to it will spread the disease."):format(eff.dam, eff.heal_factor) end,
type = "disease",
status = "detrimental",
parameters = {},
......@@ -2744,13 +2744,10 @@ newEffect{
end
end
for i = 1, 1 do
if #effs == 0 then break end
if #effs > 0 then
local eff = rng.tableRemove(effs)
if eff[1] == "effect" then
self:removeEffect(eff[2])
known = true
end
end
end,
......@@ -4531,4 +4528,94 @@ newEffect{
end
end
end,
}
newEffect{
name = "WORM_ROT",
desc = "Worm Rot",
long_desc = function(self, eff) return ("The target is infected with carrion worm larvae. Each turn it will lose one beneficial physical effect and %0.2f blight and acid damage will be inflicted.\nAfter five turns the disease will inflict %0.2f blight damage and spawn a carrion worm mass."):format(eff.dam, eff.burst) end,
type = "disease",
status = "detrimental",
parameters = {},
on_gain = function(self, err) return "#Target# is afflicted by a terrible worm rot!" end,
on_lose = function(self, err) return "#Target# is free from the worm rot." end,
-- Damage each turn
on_timeout = function(self, eff)
self.worm_rot_timer = self.worm_rot_timer - 1
-- disease damage
if self:attr("purify_disease") then
self:heal(eff.dam)
else
DamageType:get(DamageType.BLIGHT).projector(eff.src, self.x, self.y, DamageType.BLIGHT, eff.dam, {from_disease=true})
end
-- acid damage from the larvae
DamageType:get(DamageType.ACID).projector(eff.src, self.x, self.y, DamageType.ACID, eff.dam)
local effs = {}
-- Go through all physical effects
for eff_id, p in pairs(self.tmp) do
local e = self.tempeffect_def[eff_id]
if e.status == "beneficial" and e.type == "physical" then
effs[#effs+1] = {"effect", eff_id}
end
end
-- remove a random physical effect
if #effs > 0 then
local eff = rng.tableRemove(effs)
if eff[1] == "effect" then
self:removeEffect(eff[2])
end
end
-- burst and spawn a worm mass
if self.worm_rot_timer == 0 then
DamageType:get(DamageType.BLIGHT).projector(eff.src, self.x, self.y, DamageType.BLIGHT, eff.burst, {from_disease=true})
local t = eff.src:getTalentFromId(eff.src.T_WORM_ROT)
t.spawn_carrion_worm(eff.src, self, t)
game.logSeen(self, "#LIGHT_RED#A carrion worm mass bursts out of %s!", self.name:capitalize())
self:removeEffect(self.EFF_WORM_ROT)
end
end,
activate = function(self, eff)
self.worm_rot_timer = 5
end,
deactivate = function(self, eff)
self.worm_rot_timer = nil
end,
}
newEffect{
name = "FRENZY",
desc = "Frenzy",
long_desc = function(self, eff) return ("Increases global action speed by %d%% and physical crit by %d%%.\nAdditionally the target will continue to fight until it's hit points reach -%d%%."):format(eff.power * 100, eff.crit, eff.dieat * 100) end,
type = "physical",
status = "beneficial",
parameters = { power=0.1 },
on_gain = function(self, err) return "#Target# goes into a killing frenzy.", "+Frenzy" end,
on_lose = function(self, err) return "#Target# calms down.", "-Frenzy" end,
on_merge = function(self, old_eff, new_eff)
-- use on merge so reapplied frenzy doesn't kill off creatures with negative life
old_eff.dur = new_eff.dur
old_eff.power = new_eff.power
old_eff.crit = new_eff.crit
return old_eff
end,
activate = function(self, eff)
eff.tmpid = self:addTemporaryValue("global_speed", eff.power)
eff.critid = self:addTemporaryValue("combat_physcrit", eff.crit)
eff.dieatid = self:addTemporaryValue("die_at", -self.max_life * eff.dieat)
end,
deactivate = function(self, eff)
-- check negative life first incase the creature has healing
if self.life <= 0 then
local sx, sy = game.level.map:getTileToScreen(self.x, self.y)
game.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, rng.float(-2.5, -1.5), "Falls dead!", {255,0,255})
game.logSeen(self, "%s dies when it's frenzy ends!", self.name:capitalize())
self:die(self)
end
self:removeTemporaryValue("global_speed", eff.tmpid)
self:removeTemporaryValue("combat_physcrit", eff.critid)
self:removeTemporaryValue("die_at", eff.dieatid)
end,
}
\ No newline at end of file
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