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

Integrated Stone Wardens in the base game

(later on I'll add an unlock .. mwawawa)
parent 0634bea8
No related branches found
No related tags found
No related merge requests found
Pipeline #
Showing
with 441 additions and 1 deletion
......@@ -501,7 +501,10 @@ function _M:loadAddons(mod, saveuse)
table.remove(adds, i) removed = true
end
else
if add.cheat_only and not config.settings.cheat then
if mod.forbid_addons and table.hasInList(mod.forbid_addons, add.short_name) then
print("Removing addon "..add.short_name..": module forbids it")
table.remove(adds, i) removed = true
elseif add.cheat_only and not config.settings.cheat then
print("Removing addon "..add.short_name..": cheat mode required")
table.remove(adds, i) removed = true
elseif add.dlc == "no" then
......
......@@ -2744,6 +2744,41 @@ function _M:onTakeHit(value, src, death_note)
if self.on_takehit then value = self:check("on_takehit", value, src, death_note) end
local eff = self:hasEffect(self.EFF_ELDRITCH_STONE)
if eff then
local abs = math.min(value, eff.power)
self:incEquilibrium(abs * 2)
if eff.power > abs then
eff.power = eff.power - abs
value = 0
else
value = value - abs
self:removeEffect(self.EFF_ELDRITCH_STONE)
end
game:delayedLogDamage(src, self, 0, ("#SLATE#(%d to stone)#LAST#"):format(abs), false)
end
if self:knowTalent(self.T_STONESHIELD) and not self.turn_procs.stoneshield then
local t = self:getTalentFromId(self.T_STONESHIELD)
local m, mm, e, em = t.getValues(self, t)
self:incMana(math.min(mm, value * m))
self:incEquilibrium(-math.min(em, value * e))
self.turn_procs.stoneshield = true
end
local eff = self:hasEffect(self.EFF_STONE_LINK)
if eff then
if eff.src:attr("dead") then
self:removeEffect(self.EFF_STONE_LINK)
else
game:delayedLogMessage(eff.src, self, "stone_link"..(self.uid or ""), "#OLIVE_DRAB##Source# redirects damage from #Target# to %s!#LAST#", string.his_her_self(eff.src))
game:delayedLogDamage(src, self, 0, ("#OLIVE_DRAB#(%d redirected)#LAST#"):format(value), false)
eff.src:takeHit(value, src)
game:delayedLogDamage(src, eff.src, value, ("#OLIVE_DRAB#%d redirected#LAST#"):format(value), false)
value = 0
end
end
local cb = {value=value}
if self:fireTalentCheck("callbackOnHit", cb, src, death_note) then
value = cb.value
......@@ -4128,6 +4163,7 @@ end
--- Returns the possible offslot
function _M:getObjectOffslot(o)
if o.type == "armor" and o.subtype == "shield" and self:knowTalent(self.T_STONESHIELD) then return "MAINHAND" end
if o.dual_wieldable and self:attr("allow_any_dual_weapons") then
return "OFFHAND"
else
......
......@@ -264,6 +264,8 @@ end
function _M:getObjectCombat(o, kind)
if kind == "barehand" then return self.combat end
if not o then return nil end
if kind == "mainhand" and o.type == "armor" and o.subtype == "shield" and self:knowTalent(self.T_STONESHIELD) then return o.special_combat end
if kind == "offhand" and o.type == "armor" and o.subtype == "shield" and self:knowTalent(self.T_STONESHIELD) then return o.special_combat end
if kind == "mainhand" then return o.combat end
if kind == "offhand" then return o.combat end
return nil
......@@ -1069,6 +1071,13 @@ function _M:attackTargetHitProcs(target, weapon, dam, apr, armor, damtype, mult,
end
end
if target:isTalentActive(target.T_SHARDS) and hitted and not target.dead and not target.turn_procs.shield_shards then
local t = target:getTalentFromId(target.T_SHARDS)
target.turn_procs.shield_shards = true
self.logCombat(target, self, "#Source# counter attacks #Target# with %s shield shards!", string.his_her(target))
target:attackTarget(self, DamageType.NATURE, self:combatTalentWeaponDamage(t, 0.4, 1), true)
end
self:fireTalentCheck("callbackOnMeleeAttack", target, hitted, crit, weapon, damtype, mult, dam)
local hd = {"Combat:attackTargetWith", hitted=hitted, crit=crit, target=target, weapon=weapon, damtype=damtype, mult=mult, dam=dam}
......@@ -1092,6 +1101,7 @@ _M.weapon_talents = {
mindstar ="T_PSIBLADES",
dream = "T_DREAM_CRUSHER",
unarmed = "T_UNARMED_MASTERY",
shield = {"T_STONESHIELD"},
}
--- Static!
......
......@@ -36,6 +36,7 @@ newBirthDescriptor{
Summoner = "allow",
Wyrmic = "allow",
Oozemancer = "allow",
["Stone Warden"] = "allow",
},
},
copy = {
......@@ -229,3 +230,56 @@ newBirthDescriptor{
life_rating = -3,
},
}
newBirthDescriptor{
type = "subclass",
name = "Stone Warden",
desc = {
"Stone Wardens are dwarves trained in both the eldritch arts and the worship of nature.",
"While other races are stuck in their belief that arcane forces and natural forces are meant to oppose, dwarves have found a way to combine them in harmony.",
"Stone Wardens are armoured fighters, dual wielding shields to channel many of their powers.",
"#GOLD#Stat modifiers:",
"#LIGHT_BLUE# * +2 Strength, +0 Dexterity, +0 Constitution",
"#LIGHT_BLUE# * +4 Magic, +3 Willpower, +0 Cunning",
"#GOLD#Life per level:#LIGHT_BLUE# +2",
},
special_check = function(birth)
if birth.descriptors_by_type.race ~= "Dwarf" then return false end
return true
end,
power_source = {nature=true, arcane=true},
not_on_random_boss = true,
stats = { str=2, wil=3, mag=4, },
talents_types = {
["wild-gift/call"]={true, 0.2},
["wild-gift/earthen-power"]={true, 0.3},
["wild-gift/earthen-vines"]={true, 0.3},
["wild-gift/dwarven-nature"]={true, 0.3},
["spell/stone-alchemy"]={false, 0.3},
["spell/eldritch-stone"]={false, 0.3},
["spell/eldritch-shield"]={true, 0.3},
["spell/deeprock"]={false, 0.3},
["spell/earth"]={true, 0.2},
["spell/stone"]={false, 0.2},
["cunning/survival"]={true, 0},
["technique/combat-training"]={true, 0},
},
talents = {
[ActorTalents.T_STONE_VINES] = 1,
[ActorTalents.T_STONESHIELD] = 1,
[ActorTalents.T_ELDRITCH_BLOW] = 1,
[ActorTalents.T_ARMOUR_TRAINING] = 3,
[ActorTalents.T_WEAPON_COMBAT] = 1,
},
copy = {
max_life = 110,
resolvers.equipbirth{ id=true,
{type="armor", subtype="shield", name="iron shield", autoreq=true, ego_chance=-1000, ego_chance=-1000},
{type="armor", subtype="shield", name="iron shield", autoreq=true, ego_chance=-1000, ego_chance=-1000},
{type="armor", subtype="heavy", name="iron mail armour", autoreq=true, ego_chance=-1000, ego_chance=-1000}
},
},
copy_add = {
life_rating = 2,
},
}
-- ToME - Tales of Maj'Eyal
-- Copyright (C) 2009 - 2016 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
base_size = 32
local nb = 0
return { generator = function()
local ad = rng.range(0, 360)
local a = math.rad(ad)
local dir = math.rad(ad + 90)
local r = rng.avg(1, 40 * radius)
local dirv = math.rad(5)
return {
trail = 1,
life = 50,
size = rng.range(3, 6), sizev = -0.1, sizea = 0,
x = r * math.cos(a), xv = 0, xa = 0,
y = r * math.sin(a), yv = 0, ya = 0,
dir = dir, dirv = dirv, dira = 0,
vel = 5, velv = 0, vela = 0,
r = rng.range(180, 220)/255, rv = 0, ra = 0,
g = rng.range(0, 0)/255, gv = 0, ga = 0,
b = rng.range(200, 255)/255, bv = 0, ba = 0,
a = rng.range(80, 220)/255, av = 0, aa = 0,
}
end, },
function(self)
if nb < 5 then
self.ps:emit(30)
nb = nb + 1
end
end,
500,
"weather/snowflake"
-- ToME - Tales of Maj'Eyal
-- Copyright (C) 2009 - 2016 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
base_size = 32
local r = 1
local g = 1
local b = 0
local a = 1
return { generator = function()
return {
trail = 0,
life = 10,
size = 36 * (size_factor or 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 = r, rv = 0, ra = 0,
g = g, gv = 0, ga = 0,
b = b, bv = 0, ba = 0,
a = a, av = -0.02, aa = 0.005,
}
end, },
function(self)
self.ps:emit(1)
end,
1,
"shield_bubble"
-- ToME - Tales of Maj'Eyal
-- Copyright (C) 2009 - 2016 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
base_size = 32
local nb = 0
return { generator = function()
local ad = rng.range(0, 360)
local a = math.rad(ad)
local dir = math.rad(ad + 90)
local r = rng.avg(1, 40 * radius)
local dirv = math.rad(5)
return {
trail = 1,
life = 20,
size = rng.range(12, 18), sizev = -0.1, sizea = 0,
x = r * math.cos(a), xv = 0, xa = 0,
y = r * math.sin(a), yv = 0, ya = 0,
dir = dir, dirv = dirv, dira = 0,
vel = 10, velv = 0, vela = 0,
r = rng.range(200, 230)/255, rv = 0, ra = 0,
g = rng.range(200, 230)/255, gv = 0, ga = 0,
b = rng.range(200, 230)/255, bv = 0, ba = 0,
a = rng.range(200, 255)/255, av = 0, aa = 0,
}
end, },
function(self)
if nb < 6 then
self.ps:emit(20)
nb = nb + 1
end
end,
200,
"shockbolt/object/shield_voratun"
-- ToME - Tales of Maj'Eyal
-- Copyright (C) 2009 - 2016 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
base_size = 64
local nb = 0
return { generator = function()
local size = rng.range(15, 32)
return {
trail = 0,
life = 6,
size = size, sizev = 0, sizea = 0,
x = rng.range(-64+size/2, 64-size/2), xv = 0, xa = 0,
y = rng.range(-64+size/2, 64-size/2), yv = 0, ya = 0,
dir = 0, dirv = dirv, dira = 0,
vel = 0, velv = 0, vela = 0,
r = 0.6, rv = 0, ra = 0,
g = 0.4, gv = 0, ga = 0,
b = 0.3, bv = 0, ba = 0,
a = 0.5, av = 0.1, aa = 0.01,
}
end, },
function(self)
if nb < 2 then self.ps:emit(4) nb = nb + 1 end
end,
8,
"shockbolt/trap/trap_ground_spikes_01"
-- ToME - Tales of Maj'Eyal
-- Copyright (C) 2009 - 2016 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
-- Make the 2 main forks
local tx = tx * engine.Map.tile_w
local ty = ty * engine.Map.tile_h
local basesize = math.sqrt((ty*ty)+(tx*tx))
local basedir = math.atan2(ty, tx)
local nbp = 0
local points = {}
local function make_beam(fork_i)
local bc = rng.float(0.8, 1)
local c = 1
local a = 1 or rng.float(0.3, 0.6)
local size = fork_i == 1 and 8 or 2
local starta = basedir+math.pi/2
local starts = rng.range(-0, 0)
points[#points+1] = {bc=bc, c=c, a=a, size=size, x=math.cos(starta) * starts, y=math.sin(starta) * starts, prev=-1}
local nb = 3
for i = 0, nb - 1 do
-- Split point in the segment
local split = rng.range(0, basesize / nb) + i * (basesize / nb)
local dev = rng.range(-6, 6) * (9 + fork_i) / 10
points[#points+1] = {
bc=bc, c=c, a=a,
movea=basedir+dev+math.pi/2,
size=size + rng.range(-2, 2),
x=math.cos(basedir) * split + math.cos(basedir+math.pi/2) * dev,
y=math.sin(basedir) * split + math.sin(basedir+math.pi/2) * dev,
prev=#points-1
}
end
points[#points+1] = {bc=bc, c=c, a=a, size=size, x=tx, y=ty, prev=#points-1}
nbp = #points
end
for fork_i = 1, 10 do make_beam(fork_i) end
local last_id = -1
-- Populate the lightning based on the forks
return { engine=core.particles.ENGINE_LINES, blend_mode=core.particles.BLEND_SHINY, generator = function(id)
local p = table.remove(points, 1)
local ret = {
life = 6, trail=(p.prev == -1) and -1 or last_id,
size = p.size, sizev = 0, sizea = 0,
x = p.x, xv = 0, xa = 0,
y = p.y, yv = 0, ya = 0,
dir = p.movea, dirv = 0, dira = 0,
vel = rng.float(-1, 1), velv = 0, vela = 0,
r = 0xD7/255, rv = 0, ra = 0,
g = 0x8E/255, gv = 0, ga = 0,
b = 0x45/255, bv = 0, ba = 0,
a = 0.1, av = 0, aa = 0.001,
}
last_id = id
return ret
end, },
function(self)
if nbp > 0 then
self.ps:emit(10)
nbp = nbp - 10
else
for fork_i = 1, 10 do make_beam(fork_i) end
end
end,
nbp, "particles_images/beam"
-- ToME - Tales of Maj'Eyal
-- Copyright (C) 2009 - 2016 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
base_size = 32
return { generator = function()
local ad = rng.range(0, 360)
local a = math.rad(ad)
local dir = math.rad(ad)
local r = rng.range(8, 18)
return {
life = 10,
size = 1, sizev = 0.3, sizea = -0.01,
x = r * math.cos(a), xv = 0, xa = 0,
y = r * math.sin(a), yv = 0, ya = 0,
dir = 0, dirv = 0, dira = 0,
vel = 0, velv = 0, vela = 0,
r = 0xD7/255, rv = 0, ra = 0,
g = 0x8E/255, gv = 0, ga = 0,
b = 0x45/255, bv = 0, ba = 0,
a = rng.range(100, 220)/255, av = 0.05, aa = 0,
}
end, },
function(self)
self.ps:emit(2)
end,
10
game/modules/tome/data/gfx/particles_images/runicshield_stonewarden.png

170 KiB

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

3.77 KiB

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

3.76 KiB

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

2.78 KiB

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

4.17 KiB

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

4.03 KiB

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

5.3 KiB

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

3.32 KiB

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

3.31 KiB

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

3.81 KiB

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