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

New graphical effects for some corruption spells

parent ea281794
No related branches found
No related tags found
No related merge requests found
Showing
with 260 additions and 12 deletions
......@@ -433,7 +433,7 @@ function _M:addedToLevel(level, x, y)
elseif game.difficulty == game.DIFFICULTY_INSANE and not game.party:hasMember(self) then
-- Increase talent level
for tid, lev in pairs(self.talents) do
self:learnTalent(tid, true, math.floor(lev / 3))
self:learnTalent(tid, true, math.floor(lev / 2))
end
-- Give unrand bosses extra classes
if not self.randboss and self.rank >= 3.5 then
......
......@@ -213,7 +213,7 @@ newBirthDescriptor{
"#GOLD##{bold}#Insane mode#WHITE##{normal}#",
"Similar rules to Nightmare, but with more random bosses!",
"All zone levels increased by 50% + 6",
"All creature talent levels increased by 30%",
"All creature talent levels increased by 50%",
"Rare creatures are far more frequent and random bosses start to appear",
"Nonrandom bosses will have randomly selected talents",
"All enemies have 20% more life",
......
......@@ -23,21 +23,38 @@ local speed = speed or 0.023
local a = (a or 60) / 255
local basesize = 2 * radius * (engine.Map.tile_w + engine.Map.tile_h) / 2 + engine.Map.tile_w * 1.8 * (oversize or 1)
local appear = appear or 0
local appear_size = appear_size or 3
local r = (r or 255) / 255
local g = (g or 255) / 255
local b = (b or 255) / 255
local nb = 0
local nb = empty_start and -1 or 0
return {
-- blend_mode=core.particles.BLEND_ADDITIVE,
system_rotation = 0, system_rotationv = speed,
system_rotation = rng.range(0, 360), system_rotationv = speed,
generator = function()
if nb == 0 and appear > 0 then
if nb == -1 then
return {
trail = 0,
life = empty_start,
size = 1, sizev = 0, sizea = 0,
x = 0, xv = 0, xa = 0,
y = 0, yv = 0, ya = 0,
dir = 0, dirv = dirv, dira = 0,
vel = 0, velv = 0, vela = 0,
r = 0, rv = 0, ra = 0,
g = 0, gv = 0, ga = 0,
b = 0, bv = 0, ba = 0,
a = 0, av = 0, aa = 0,
}
elseif nb == 0 and appear > 0 then
return {
trail = 0,
life = appear,
size = basesize * 3, sizev = -basesize * 2 / appear, sizea = 0,
size = basesize * appear_size, sizev = -basesize * (appear_size - 1) / appear, sizea = 0,
x = 0, xv = 0, xa = 0,
y = 0, yv = 0, ya = 0,
......
game/modules/tome/data/gfx/particles_images/demon_circle.png

263 KiB

game/modules/tome/data/gfx/particles_images/demon_fire_circle.png

348 KiB

game/modules/tome/data/gfx/particles_images/demon_flames_circle.png

477 KiB

game/modules/tome/data/gfx/particles_images/green_demon_fire_circle.png

401 KiB

game/modules/tome/data/gfx/particles_images/necromantic_circle.png

289 KiB | W: | H:

game/modules/tome/data/gfx/particles_images/necromantic_circle.png

406 KiB | W: | H:

game/modules/tome/data/gfx/particles_images/necromantic_circle.png
game/modules/tome/data/gfx/particles_images/necromantic_circle.png
game/modules/tome/data/gfx/particles_images/necromantic_circle.png
game/modules/tome/data/gfx/particles_images/necromantic_circle.png
  • 2-up
  • Swipe
  • Onion skin
game/modules/tome/data/gfx/shockbolt/object/artifact/corrupted_queen_heart.png

9.08 KiB

......@@ -38,9 +38,9 @@ checkConnectivity({55,24}, "entrance", "boss-area", "boss-area")
-- defineTile section
defineTile("#", "BURNT_TREE")
defineTile("~", "LAVA")
defineTile("+", "ALTAR")
defineTile("+", "ALTAR_CORRUPT")
defineTile(".", "BURNT_GROUND")
defineTile("@", "ALTAR", nil, "GRAND_CORRUPTOR")
defineTile("@", "ALTAR_CORRUPT", nil, "GRAND_CORRUPTOR")
-- addSpot section
......
......@@ -101,7 +101,9 @@ newTalent{
end
end
end
end, nil, {type="slime"})
end)
local _ _, x, y = self:canProject(tg, x, y)
game.level.map:particleEmitter(x, y, tg.radius, "circle", {zdepth=6, oversize=1, a=130, appear=8, limit_life=8, speed=5, img="green_demon_fire_circle", radius=tg.radius})
game:playSoundNear(self, "talents/slime")
return true
end,
......
......@@ -24,6 +24,7 @@ newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corrupti
newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/bone", name = "bone", description = "Harness the power of bones." }
newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/hexes", name = "hexes", generic = true, description = "Hex your foes, hindering and crippling them." }
newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/curses", name = "curses", generic = true, description = "Curse your foes, hindering and crippling them." }
newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/vile-life", name = "vile life", generic = true, description = "Manipulate life for your vile needs." }
newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/plague", name = "plague", description = "Spread diseases to your foes." }
newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/scourge", name = "scourge", description = "Bring pain and destruction to the world." }
newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="corruption/reaving-combat", name = "reaving combat", description = "Enhanced melee combat through the dark arts." }
......@@ -106,3 +107,4 @@ load("/data/talents/corruptions/blight.lua")
load("/data/talents/corruptions/shadowflame.lua")
load("/data/talents/corruptions/vim.lua")
load("/data/talents/corruptions/torment.lua")
load("/data/talents/corruptions/vile-life.lua")
......@@ -63,6 +63,7 @@ newTalent{
self:projectile(tg, x, y, DamageType.SHADOWFLAME, self:spellCrit(self:combatTalentSpellDamage(t, 28, 220)), function(self, tg, x, y, grids)
game.level.map:particleEmitter(x, y, tg.radius, "fireflash", {radius=tg.radius, grids=grids, tx=x, ty=y})
game.level.map:particleEmitter(x, y, tg.radius, "shadow_flash", {radius=tg.radius, grids=grids, tx=x, ty=y})
game.level.map:particleEmitter(x, y, tg.radius, "circle", {zdepth=6, oversize=1, a=130, appear=8, limit_life=12, speed=5, img="demon_flames_circle", radius=tg.radius})
end)
game:playSoundNear(self, "talents/fireflash")
return true
......
-- ToME - Tales of Maj'Eyal
-- Copyright (C) 2009 - 2014 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
newTalent{
name = "Blood Splash",
type = {"corruption/vile-life", 1},
require = corrs_req1,
points = 5,
mode = "passive",
heal = function(self, t) return self:combatTalentScale(t, 10, 50) end,
callbackOnCrit = function(self, t)
if self.turn_procs.blood_splash_on_crit then return end
self.turn_procs.blood_splash_on_crit = true
self:heal(t.heal(self, t), self)
if core.shader.active(4) then
self:addParticles(Particles.new("shader_shield_temp", 1, {toback=true , size_factor=1.5, y=-0.3, img="healgreen", life=25}, {type="healing", time_factor=2000, beamsCount=20, noup=2.0, circleDescendSpeed=3.5}))
self:addParticles(Particles.new("shader_shield_temp", 1, {toback=false, size_factor=1.5, y=-0.3, img="healgreen", life=25}, {type="healing", time_factor=2000, beamsCount=20, noup=1.0, circleDescendSpeed=3.5}))
end
end,
callbackOnKill = function(self, t)
if self.turn_procs.blood_splash_on_kill then return end
self.turn_procs.blood_splash_on_kill = true
self:heal(t.heal(self, t), self)
if core.shader.active(4) then
self:addParticles(Particles.new("shader_shield_temp", 1, {toback=true , size_factor=1.5, y=-0.3, img="healgreen", life=25}, {type="healing", time_factor=2000, beamsCount=20, noup=2.0, circleDescendSpeed=3.5}))
self:addParticles(Particles.new("shader_shield_temp", 1, {toback=false, size_factor=1.5, y=-0.3, img="healgreen", life=25}, {type="healing", time_factor=2000, beamsCount=20, noup=1.0, circleDescendSpeed=3.5}))
end
end,
info = function(self, t)
return ([[Inflicting pain and death invogorates you.
Each time you deal a critical strike you gain %d life (this effect can only happen once per turn).
Each time you kill a creature you gain %d life (this effect can only happen once per turn).]]):
format(t.heal(self, t), t.heal(self, t))
end,
}
newTalent{
name = "Elemental Discord",
type = {"corruption/vile-life", 2},
require = corrs_req2,
points = 5,
cooldown = 20,
vim = 30,
range = 10,
radius = 2,
tactical = { DISABLE = 2 },
direct_hit = true,
requires_target = true,
target = function(self, t)
return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), talent=t}
end,
getCDincrease = function(self, t) return self:combatTalentScale(t, 0.15, 0.5) 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:project(tg, x, y, function(tx, ty)
local target = game.level.map(tx, ty, Map.ACTOR)
if not target or target == self then return end
target:setEffect(target.EFF_BURNING_HEX, 20, {src=self, dam=self:spellCrit(self:combatTalentSpellDamage(t, 4, 90)), power=1 + t.getCDincrease(self, t), apply_power=self:combatSpellpower()})
end)
local _ _, _, _, x, y = self:canProject(tg, x, y)
game.level.map:particleEmitter(x, y, tg.radius, "circle", {oversize=0.7, g=100, b=100, a=90, limit_life=8, appear=8, speed=2, img="blight_circle", radius=self:getTalentRadius(t)})
game:playSoundNear(self, "talents/slime")
return true
end,
info = function(self, t)
return ([[Hexes your target and everything within a radius 2 ball around it for 20 turns. Each time an affected target uses a resource (stamina, mana, vim, ...), it takes %0.2f fire damage.
In addition, the cooldown of any talent used while so hexed is increased by %d%% + 1 turn.
The damage will increase with your Spellpower.]]):
format(damDesc(self, DamageType.FIRE, self:combatTalentSpellDamage(t, 4, 90)), t.getCDincrease(self, t)*100)
end,
}
newTalent{
name = "Healing Inversion",
type = {"corruption/vile-life", 3},
require = corrs_req3,
points = 5,
cooldown = 20,
vim = 30,
range = 10,
radius = 2,
tactical = { DISABLE = 2 },
direct_hit = true,
requires_target = true,
target = function(self, t)
return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), friendlyfire=false, talent=t}
end,
recoil = function(self,t) return self:combatLimit(self:combatTalentSpellDamage(t, 4, 20), 100, 0, 0, 12.1, 12.1) end, -- Limit to <100%
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:project(tg, x, y, function(tx, ty)
local target = game.level.map(tx, ty, Map.ACTOR)
if not target or target == self then return end
target:setEffect(target.EFF_EMPATHIC_HEX, 20, {power=t.recoil(self,t), apply_power=self:combatSpellpower()})
end)
local _ _, _, _, x, y = self:canProject(tg, x, y)
game.level.map:particleEmitter(x, y, tg.radius, "circle", {oversize=0.7, r=100, b=100, a=90, limit_life=8, appear=8, speed=2, img="blight_circle", radius=self:getTalentRadius(t)})
game:playSoundNear(self, "talents/slime")
return true
end,
info = function(self, t)
return ([[Hexes your target and everything within a radius 2 ball around it. Each time they do damage, they take %d%% of the same damage for 20 turns.
The damage will increase with your Spellpower.]]):format(t.recoil(self,t))
end,
}
newTalent{
name = "Vile Transplant",
type = {"corruption/vile-life", 4},
require = corrs_req4,
points = 5,
cooldown = 20,
vim = 30,
range = 10,
no_npc_use = true,
direct_hit = true,
requires_target = true,
target = function(self, t)
return {type="hit", range=self:getTalentRange(t), talent=t}
end,
getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 3, 7)) 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:project(tg, x, y, function(tx, ty)
local target = game.level.map(tx, ty, Map.ACTOR)
if not target or target == self then return end
if target:canBe("instakill") then
target:setEffect(target.EFF_DOMINATION_HEX, t.getDuration(self, t), {src=self, apply_power=self:combatSpellpower(), faction = self.faction})
end
end)
local _ _, _, _, x, y = self:canProject(tg, x, y)
game.level.map:particleEmitter(x, y, tg.radius, "circle", {oversize=0.7, g=100, r=100, a=90, limit_life=8, appear=8, speed=2, img="blight_circle", radius=self:getTalentRadius(t)})
game:playSoundNear(self, "talents/slime")
return true
end,
info = function(self, t)
return ([[Hexes your target, forcing it to be your thrall for %d turns.
If you damage the target, it will be freed from the hex.]]):format(t.getDuration(self, t))
end,
}
......@@ -117,8 +117,10 @@ newTalent{
actors[#actors+1] = target
end)
local _ _, x, y = self:canProject(tg, x, y)
game.level.map:particleEmitter(x, y, 1, "demon_teleport")
game.level.map:particleEmitter(self.x, self.y, 1, "demon_teleport")
game.level.map:particleEmitter(x, y, tg.radius, "circle", {empty_start=8, oversize=1, a=80, appear=8, limit_life=11, speed=5, img="green_demon_fire_circle", radius=tg.radius})
game.level.map:particleEmitter(x, y, tg.radius, "circle", {oversize=1, a=80, appear=8, limit_life=11, speed=5, img="demon_fire_circle", radius=tg.radius})
game.level.map:particleEmitter(self.x, self.y, tg.radius, "circle", {appear_size=2, empty_start=8, oversize=1, a=80, appear=11, limit_life=8, speed=5, img="green_demon_fire_circle", radius=tg.radius})
game.level.map:particleEmitter(self.x, self.y, tg.radius, "circle", {appear_size=2, oversize=1, a=80, appear=8, limit_life=11, speed=5, img="demon_fire_circle", radius=tg.radius})
for i, a in ipairs(actors) do
local tx, ty = util.findFreeGrid(self.x, self.y, 20, true, {[Map.ACTOR]=true})
......
......@@ -105,7 +105,7 @@ newTalent{
DamageType.CIRCLE_DEATH, {dam=self:spellCrit(t.getDamage(self, t)), dur=t.getBaneDur(self,t), ff=isFF(self)},
self:getTalentRadius(t),
5, nil,
{type="circle_of_death", overlay_particle={zdepth=6, only_one=true, type="circle", args={oversize=1, a=80, appear=8, speed=-0.05, img="necromantic_circle", radius=self:getTalentRadius(t)}}},
{type="circle_of_death", overlay_particle={zdepth=6, only_one=true, type="circle", args={oversize=1, a=100, appear=8, speed=-0.05, img="necromantic_circle", radius=self:getTalentRadius(t)}}},
-- {zdepth=6, only_one=true, type="circle", args={oversize=1, a=130, appear=8, speed=-0.03, img="arcane_circle", radius=self:getTalentRadius(t)}},
nil, false
)
......
......@@ -22,3 +22,22 @@ load("/data/general/grids/forest.lua")
load("/data/general/grids/water.lua")
load("/data/general/grids/lava.lua")
load("/data/general/grids/burntland.lua")
newEntity{ base = "ALTAR",
define_as = "ALTAR_CORRUPT",
on_move = function(self, x, y, who)
if not who.player then return end
local o, inven, item = who:findInAllInventoriesBy("define_as", "SANDQUEEN_HEART")
if not o then return end
require("engine.ui.Dialog"):yesnoPopup("Heart of the Sandworm Queen", "The altar seems to react to the heart. You feel you could corrupt it here.", function(ret)
if ret then return end
who:removeObject(inven, item, true)
local o = game.zone:makeEntityByName(game.level, "object", "CORRUPTED_SANDQUEEN_HEART", true)
o:identify(true)
who:addObject(inven, o)
who:sortInven(inven)
game.log("#GREEN#You put the heart on the altar. The heart shrivels and shakes, vibrating with new corrupt forces.")
end, "Cancel", "Corrupt", nil, true)
end,
}
......@@ -26,3 +26,44 @@ newEntity{ base = "BASE_LORE",
rarity = false,
encumberance = 0,
}
newEntity{
power_source = {nature=true},
define_as = "CORRUPTED_SANDQUEEN_HEART",
type = "corpse", subtype = "heart", image = "object/artifact/corrupted_queen_heart.png",
name = "Corrupted heart of the Sandworm Queen", unique=true, unided_name="pulsing organ",
display = "*", color=colors.VIOLET,
desc = [[The heart of the Sandworm Queen, ripped from her dead body and corrupted in the mark of the spellblaze altar. You could ... consume it, should you feel mad enough.]],
cost = 3000,
quest = 1,
use_simple = { name="consume the heart", use = function(self, who)
game.logPlayer(who, "#00FFFF#You consume the heart and feel the corruption fill you!")
who.unused_stats = who.unused_stats + 3
who.unused_talents = who.unused_talents + 1
who.unused_generics = who.unused_generics + 1
game.logPlayer(who, "You have %d stat point(s) to spend. Press G to use them.", who.unused_stats)
game.logPlayer(who, "You have %d class talent point(s) to spend. Press G to use them.", who.unused_talents)
game.logPlayer(who, "You have %d generic talent point(s) to spend. Press G to use them.", who.unused_generics)
if not who:attr("forbid_arcane") then
if who:knowTalentType("corruption/vile-life") then
who:setTalentTypeMastery("corruption/vile-life", who:getTalentTypeMastery("corruption/vile-life") + 0.2)
elseif who:knowTalentType("corruption/vile-life") == false then
who:learnTalentType("corruption/vile-life", true)
else
who:learnTalentType("corruption/vile-life", false)
end
-- Make sure a previous amulet didnt bug it out
if who:getTalentTypeMastery("corruption/vile-life") == 0 then who:setTalentTypeMastery("corruption/vile-life", 1) end
game.logPlayer(who, "You are transformed by the corrupted heart of the Queen!.")
game.logPlayer(who, "#00FF00#You gain an affinity for blight. You can now learn new Vile Life talents (press G).")
who:attr("drake_touched", 1)
end
-- game:setAllowedBuild("wilder_wyrmic", true)
return {used=true, id=true, destroy=true}
end}
}
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