Skip to content
Snippets Groups Projects
Commit 4d82b22b authored by DarkGod's avatar DarkGod
Browse files

New two handed weapons tree "Crusader" for Sun Paladins

parent 65030de1
No related branches found
No related tags found
No related merge requests found
Showing
with 410 additions and 5 deletions
......@@ -508,12 +508,12 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam)
dam = dam + total_conversion
end
target:fireTalentCheck("callbackOnMeleeHit", self)
target:fireTalentCheck("callbackOnMeleeHit", self, dam)
hitted = true
else
self:logCombat(target, "#Source# misses #Target#.")
target:fireTalentCheck("callbackOnMeleeMiss", self)
target:fireTalentCheck("callbackOnMeleeMiss", self, dam)
end
-- cross-tier effect for accuracy vs. defense
......@@ -1641,7 +1641,7 @@ function _M:physicalCrit(dam, weapon, target, atk, def, add_chance, crit_power_a
if self:knowTalent(self.T_EYE_OF_THE_TIGER) then self:triggerTalent(self.T_EYE_OF_THE_TIGER, nil, "physical") end
self:fireTalentCheck("callbackOnCrit", "physical", dam, chance)
self:fireTalentCheck("callbackOnCrit", "physical", dam, chance, target)
end
return dam, crit
end
......
......@@ -78,10 +78,12 @@ newBirthDescriptor{
["celestial/combat"]={true, 0.3},
["celestial/light"]={true, 0.3},
["celestial/guardian"]={false, 0.3},
["celestial/radiance"]={false, 0.3},
["celestial/crusader"]={true, 0.3},
},
birth_example_particles = "golden_shield",
talents = {
[ActorTalents.T_SEARING_LIGHT] = 1,
[ActorTalents.T_SUN_BEAM] = 1,
[ActorTalents.T_WEAPON_OF_LIGHT] = 1,
[ActorTalents.T_CHANT_OF_FORTITUDE] = 1,
[ActorTalents.T_ARMOUR_TRAINING] = 2,
......
game/modules/tome/data/gfx/particles_images/spinningwinds_yellow.png

14.4 KiB

game/modules/tome/data/gfx/talents/absorption_strike.png

2.93 KiB

game/modules/tome/data/gfx/talents/flash_of_the_blade.png

5.24 KiB

game/modules/tome/data/gfx/talents/lightburn.png

2.56 KiB

game/modules/tome/data/gfx/talents/mark_of_light.png

3.87 KiB

game/modules/tome/data/gfx/talents/righteous_strength.png

2.96 KiB

......@@ -22,6 +22,8 @@ newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="celestia
newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="celestial/chants", name = "chants", generic = true, description = "Chant the glory of the Sun." }
newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="celestial/light", name = "light", generic = true, description = "Invoke the power of the light to heal and mend." }
newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="celestial/combat", name = "combat", description = "Your devotion allows you to combat your foes with indomitable determination." }
newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="celestial/radiance", name = "radiance", description = "You channel the light of the sun through your body." }
newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="celestial/crusader", name = "crusader", description = "Forgo your shield for the chance to crush your foes with a mighty two handed weapon." }
newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="celestial/sunlight", name = "sunlight", description = "Summon the power of the Sun to burn your foes." }
newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="celestial/sun", name = "sun", description = "Summon the power of the Sun to burn your foes." }
newTalentType{ allow_random=true, no_silence=true, is_spell=true, type="celestial/glyphs", name = "glyphs", min_lev = 10, description = "Bind the brilliant powers into glyphs to trap your foes." }
......@@ -83,6 +85,8 @@ load("/data/talents/celestial/combat.lua")
load("/data/talents/celestial/light.lua")
load("/data/talents/celestial/glyphs.lua")
load("/data/talents/celestial/guardian.lua")
load("/data/talents/celestial/radiance.lua")
load("/data/talents/celestial/crusader.lua")
load("/data/talents/celestial/twilight.lua")
load("/data/talents/celestial/hymns.lua")
......
-- 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 = "Absorption Strike",
type = {"celestial/crusader", 1},
require = divi_req1,
points = 5,
cooldown = 8,
positive = -7,
tactical = { ATTACK = 2, DISABLE = 1 },
range = 1,
requires_target = true,
getWeakness = function(self, t) return self:combatTalentScale(t, 20, 45, 0.75) end,
getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 1.1, 2.3) end,
on_pre_use = function(self, t, silent) if not self:hasTwoHandedWeapon() then if not silent then game.logPlayer(self, "You require a two handed weapon to use this talent.") end 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 core.fov.distance(self.x, self.y, x, y) > 1 then return nil end
local hit = self:attackTarget(target, nil, t.getDamage(self, t), true)
if hit then
self:project({type="ball", radius=2, selffire=false}, self.x, self.y, function(px, py)
local a = game.level.map(px, py, Map.ACTOR)
if a then
a:setEffect(a.EFF_ABSORPTION_STRIKE, 5, {apply_power=self:combatSpellpower(), power=t.getWeakness(self, t)})
end
end)
end
return true
end,
info = function(self, t)
local damage = t.getDamage(self, t)
return ([[You strike your foe with your two handed weapon, dealing %d%% weapon damage.
If the attack hits all foes in radius 2 will have their light resistance reduced by %d%% for 5 turns.]]):
format(100 * damage, t.getWeakness(self, t))
end,
}
newTalent{
name = "Mark of Light",
type = {"celestial/crusader", 2},
require = divi_req2,
points = 5,
no_energy = true,
cooldown = 15,
positive = 20,
tactical = { ATTACK=0.5, DISABLE=2, HEAL=2 },
range = 1,
requires_target = true,
getPower = function(self, t) return self:combatTalentScale(t, 30, 70) end,
getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 0.2, 0.7) end,
on_pre_use = function(self, t, silent) if not self:hasTwoHandedWeapon() then if not silent then game.logPlayer(self, "You require a two handed weapon to use this talent.") end 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 core.fov.distance(self.x, self.y, x, y) > 1 then return nil end
local hit = self:attackTarget(target, nil, t.getDamage(self, t), true)
if hit then
target:setEffect(target.EFF_MARK_OF_LIGHT, 5, {apply_power=self:combatSpellpower(), src=self, power=t.getPower(self, t)})
end
return true
end,
info = function(self, t)
local damage = t.getDamage(self, t)
return ([[You swifty thrust the hilt of your 2H weapon into your target, dealing %d%% weapon damage.
If the attack hits the creature is marked with light for 5 turns. All melee hits you deal to it will heal you for %d%% of the damage done.]]):
format(100 * damage, t.getPower(self, t))
end,
}
newTalent{
name = "Righteous Strength",
type = {"celestial/crusader",3},
require = divi_req3,
points = 5,
mode = "passive",
getArmor = function(self, t) return self:combatTalentScale(t, 5, 30) end,
getDamage = function(self, t) return self:combatTalentSpellDamage(t, 10, 120) end,
getCrit = function(self, t) return self:combatTalentScale(t, 3, 10, 0.75) end,
getPower = function(self, t) return self:combatTalentScale(t, 5, 20) end,
callbackOnCrit = function(self, t, kind, dam, chance, target)
if kind ~= "physical" or not target then return end
if self.turn_procs.righteous_strength then return end
self.turn_procs.righteous_strength = true
target:setEffect(target.EFF_LIGHTBURN, 5, {apply_power=self:combatSpellpower(), src=self, dam=t.getDamage(self, t)/5, armor=t.getArmor(self, t)})
self:setEffect(self.EFF_RIGHTEOUS_STRENGTH, 4, {power=t.getPower(self, t), max_power=t.getPower(self, t) * 3})
end,
passives = function(self, t, p)
self:talentTemporaryValue(p, "combat_physcrit", t.getCrit(self, t))
end,
info = function(self, t)
return ([[While wielding a two handed weapon, your critical strike chance is increased by %d%%, and your melee criticals instill you with righteous strength, increasing all physical and light damage you deal by %d%%, stacking up to 3 times.
In addition, your melee critical strikes leave a lasting lightburn on the target, dealing %0.2f light damage over 5 turns and reducing opponents armour by %d.
The damage increase with your Spellpower.]]):
format(t.getCrit(self, t), t.getPower(self, t), t.getDamage(self, t), t.getArmor(self, t))
end,
}
newTalent{
name = "Flash of the Blade",
type = {"celestial/crusader", 4},
require = divi_req4,
random_ego = "attack",
points = 5,
cooldown = 10,
positive = 15,
tactical = { ATTACKAREA = {LIGHT = 2} },
range = 0,
radius = 2,
requires_target = true,
target = function(self, t)
return {type="ball", range=self:getTalentRange(t), selffire=false, radius=self:getTalentRadius(t)}
end,
on_pre_use = function(self, t, silent) if not self:hasTwoHandedWeapon() then if not silent then game.logPlayer(self, "You require a two handed weapon to use this talent.") end return false end return true end,
get1Damage = function(self, t) return self:combatTalentWeaponDamage(t, 0.8, 1.6) end,
get2Damage = function(self, t) return self:combatTalentWeaponDamage(t, 0.5, 1.2) end,
action = function(self, t)
local tg1 = self:getTalentTarget(t) tg1.radius = 1
local tg2 = self:getTalentTarget(t)
self:project(tg1, self.x, self.y, function(px, py, tg, self)
local target = game.level.map(px, py, Map.ACTOR)
if target and target ~= self then
self:attackTarget(target, nil, t.get1Damage(self, t), true)
end
end)
self:project(tg2, self.x, self.y, function(px, py, tg, self)
local target = game.level.map(px, py, Map.ACTOR)
if target and target ~= self then
self:attackTarget(target, DamageType.LIGHT, t.get2Damage(self, t), true)
if self:getTalentLevel(t) >= 4 then
target:setEffect(target.EFF_DAZED, 3, {apply_power=self:combatSpellpower()})
end
end
end)
self:addParticles(Particles.new("meleestorm", 2, {radius=2, img="spinningwinds_yellow"}))
self:addParticles(Particles.new("meleestorm", 1, {img="spinningwinds_yellow"}))
return true
end,
info = function(self, t)
return ([[Infuse your two handed weapon with light while spinning around.
All creatures in radius one take %d%% weapon damage.
In addition while spinning your weapon shines so much it deals %d%% light weapon damage to all foes in radius 2.
At level 4 creatures may also be dazed by the light.]]):
format(t.get1Damage(self, t) * 100, t.get2Damage(self, t) * 100)
end,
}
-- 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 = "Radiance",
type = {"celestial/radiance", 1},
mode = "sustained",
require = divi_req1,
points = 5,
cooldown = 10,
sustain_positive = 10,
tactical = { BUFF = 2 },
range = 10,
getDamage = function(self, t) return 7 + self:combatSpellpower(0.092) * self:combatTalentScale(t, 1, 5) end,
activate = function(self, t)
game:playSoundNear(self, "talents/spell_generic2")
local ret = {
}
return ret
end,
deactivate = function(self, t, p)
return true
end,
info = function(self, t)
local damage = t.getDamage(self, t)
return ([[Infuse your weapon with the power of the Sun, doing %0.2f light damage at the cost of 3 positive energy for each blow dealt.
If you do not have enough positive energy, the sustain will have no effect.
The damage dealt will increase with your Spellpower.]]):
format(damDesc(self, DamageType.LIGHT, damage))
end,
}
newTalent{
name = "Illumination",
type = {"celestial/radiance", 2},
require = divi_req2,
points = 5,
random_ego = "attack",
cooldown = 22,
positive = 25,
tactical = { DISABLE = 2 },
range = 6,
reflectable = true,
requires_target = true,
getReturnDamage = function(self, t) return self:combatLimit(self:getTalentLevel(t)^.5, 100, 15, 1, 40, 2.24) end, -- Limit <100%
action = function(self, t)
local tg = {type="bolt", range=self:getTalentRange(t), talent=t}
local x, y = self:getTarget(tg)
if not x or not y then return nil end
local _ _, x, y = self:canProject(tg, x, y)
game:playSoundNear(self, "talents/spell_generic")
local target = game.level.map(x, y, Map.ACTOR)
if target then
target:setEffect(self.EFF_MARTYRDOM, 10, {src = self, power=t.getReturnDamage(self, t), apply_power=self:combatSpellpower()})
else
return
end
return true
end,
info = function(self, t)
local returndamage = t.getReturnDamage(self, t)
return ([[Designate a target as a martyr for 10 turns. When the martyr deals damage, it also damages itself for %d%% of the damage dealt.]]):
format(returndamage)
end,
}
newTalent{
name = "Searing Ray",
type = {"celestial/radiance",3},
require = divi_req3,
points = 5,
random_ego = "attack",
cooldown = 6,
positive = 10,
tactical = { ATTACK = 2 },
requires_target = true,
range = function(self, t) return 2 + math.max(0, self:combatStatScale("str", 0.8, 8)) end,
getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 1.1, 1.9) end,
action = function(self, t)
local tg = {type="bolt", range=self:getTalentRange(t), talent=t}
local x, y = self:getTarget(tg)
if not x or not y then return nil end
local _ _, x, y = self:canProject(tg, x, y)
local target = game.level.map(x, y, Map.ACTOR)
if target then
self:attackTarget(target, nil, t.getDamage(self, t), true)
else
return
end
return true
end,
info = function(self, t)
local damage = t.getDamage(self, t)
return ([[In a pure display of power, you project a melee attack, doing %d%% damage.
The range will increase with your Strength.]]):
format(100 * damage)
end,
}
newTalent{
name = "Light Burst",
type = {"celestial/radiance", 4},
require = divi_req4,
random_ego = "attack",
points = 5,
cooldown = 10,
positive = 10,
tactical = { ATTACK = {LIGHT = 2} },
range = 1,
requires_target = true,
getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 0.8, 1.6) 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 core.fov.distance(self.x, self.y, x, y) > 1 then return nil end
self:attackTarget(target, DamageType.LIGHT, t.getDamage(self, t), true)
self:attackTarget(target, DamageType.LIGHT, t.getDamage(self, t), true)
return true
end,
info = function(self, t)
local damage = t.getDamage(self, t)
return ([[Concentrate the power of the Sun into two blows; each blow does %d%% of your weapon damage as light damage.]]):
format(100 * damage)
end,
}
......@@ -2490,3 +2490,93 @@ newEffect{
self:removeParticles(eff.particle)
end,
}
newEffect{
name = "ABSORPTION_STRIKE", image = "talents/absorption_strike.png",
desc = "Absorption Strike",
long_desc = function(self, eff) return ("The target's light has been drained, reducing light resistance by %d%%."):format(eff.power) end,
type = "magical",
subtype = { sun=true, },
status = "detrimental",
parameters = { power = 10 },
on_gain = function(self, err) return "#Target# is drained from light!", "+Absorption Strike" end,
on_lose = function(self, err) return "#Target#'s light is back.", "-Absorption Strike" end,
activate = function(self, eff)
self:effectTemporaryValue(eff, "resists", {[DamageType.LIGHT]=-eff.power})
end,
}
newEffect{
name = "MARK_OF_LIGHT", image = "talents/mark_of_light.png",
desc = "Mark of Light",
long_desc = function(self, eff) return ("The creature that marked the target with light will be healed for all melee attacks against it by %d%%."):format(eff.power) end,
type = "magical",
subtype = { sun=true, },
status = "detrimental",
parameters = { power = 10 },
on_gain = function(self, err) return "#Target# is marked by light!", "+Mark of Light" end,
on_lose = function(self, err) return "#Target#'s mark disappears.", "-Mark of Light" end,
callbackOnMeleeHit = function(self, eff, src, dam)
if eff.src == src then
src:heal(dam * eff.power / 100, self)
if core.shader.active(4) then
eff.src:addParticles(Particles.new("shader_shield_temp", 1, {toback=true, size_factor=1.5, y=-0.3, img="healcelestial", life=25}, {type="healing", time_factor=2000, beamsCount=20, noup=2.0, beamColor1={0xd8/255, 0xff/255, 0x21/255, 1}, beamColor2={0xf7/255, 0xff/255, 0x9e/255, 1}, circleDescendSpeed=3}))
eff.src:addParticles(Particles.new("shader_shield_temp", 1, {toback=false,size_factor=1.5, y=-0.3, img="healcelestial", life=25}, {type="healing", time_factor=2000, beamsCount=20, noup=1.0, beamColor1={0xd8/255, 0xff/255, 0x21/255, 1}, beamColor2={0xf7/255, 0xff/255, 0x9e/255, 1}, circleDescendSpeed=3}))
end
end
end,
}
newEffect{
name = "RIGHTEOUS_STRENGTH", image = "talents/righteous_strength.png",
desc = "Righteous Strength",
long_desc = function(self, eff) return ("Increase light and physical damage by %d%%."):format(eff.power) end,
type = "magical",
subtype = { sun=true, },
status = "beneficial",
parameters = { power = 10 },
on_gain = function(self, err) return "#Target# shines with light!", "+Righteous Strength" end,
on_lose = function(self, err) return "#Target# stops shining.", "-Righteous Strength" end,
charges = function(self, eff) return eff.charges end,
on_merge = function(self, old_eff, new_eff)
new_eff.charges = math.min(old_eff.charges + 1, 3)
new_eff.power = math.min(new_eff.power + old_eff.power, new_eff.max_power)
self:removeTemporaryValue("inc_damage", old_eff.tmpid)
new_eff.tmpid = self:addTemporaryValue("inc_damage", {[DamageType.PHYSICAL] = new_eff.power, [DamageType.LIGHT] = new_eff.power})
return new_eff
end,
activate = function(self, eff)
eff.charges = 1
eff.tmpid = self:addTemporaryValue("inc_damage", {[DamageType.PHYSICAL] = eff.power, [DamageType.LIGHT] = eff.power})
end,
deactivate = function(self, eff)
self:removeTemporaryValue("inc_damage", eff.tmpid)
end,
}
newEffect{
name = "LIGHTBURN", image = "talents/righteous_strength.png",
desc = "Lightburn",
long_desc = function(self, eff) return ("The creature is burnt by light, dealing %0.2f light damage each turn and reducing armour by %d."):format(eff.dam, eff.armor) end,
type = "magical",
subtype = { sun=true, },
status = "detrimental",
parameters = { armor = 10, dam = 10 },
on_gain = function(self, err) return "#Target# burns with light!", "+Lightburn" end,
on_lose = function(self, err) return "#Target# stops burning.", "-Lightburn" end,
on_merge = function(self, old_eff, new_eff)
-- Merge the flames!
local olddam = old_eff.dam * old_eff.dur
local newdam = new_eff.dam * new_eff.dur
local dur = math.ceil((old_eff.dur + new_eff.dur) / 2)
old_eff.dur = dur
old_eff.dam = (olddam + newdam) / dur
return old_eff
end,
activate = function(self, eff)
self:effectTemporaryValue(eff, "combat_armor", -eff.armor)
end,
on_timeout = function(self, eff)
DamageType:get(DamageType.LIGHT).projector(eff.src, self.x, self.y, DamageType.LIGHT, eff.dam)
end,
}
......@@ -18,7 +18,6 @@
-- darkgod@te4.org
local layout = game.state:alternateZoneTier1(short_name, {"FLOODED", 1})
layout="FLOODED"
if layout == "FLOODED" then
return {
......
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