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

New class: Geomancer, earth specialist Archmages (no unlock yet)

git-svn-id: http://svn.net-core.org/repos/t-engine4@1607 51575b47-30f0-44d4-a5cc-537603b46e54
parent 0ea9dba5
No related branches found
No related tags found
No related merge requests found
Showing
with 469 additions and 30 deletions
......@@ -86,7 +86,7 @@ function _M:interact(who)
else
if o:getNumber() > 1 then
local q
q = GetQuantity.new(nil, nil, o:getNumber(), o:getNumber(), function(qty) print("plop", qty) self:doSell(who, o, item, qty, d) end)
q = GetQuantity.new(nil, nil, o:getNumber(), o:getNumber(), function(qty) self:doSell(who, o, item, qty, d) end)
game:registerDialog(q)
else
self:doSell(who, o, item, 1, d)
......@@ -100,22 +100,23 @@ function _M:interact(who)
game:registerDialog(d)
end
function _M:transfer(src, dest, item, nb)
local src_inven, dest_inven = src:getInven("INVEN"), dest:getInven("INVEN")
for i = 1, nb do
local o = src:removeObject(src_inven, item)
dest:addObject(dest_inven, o)
end
self:sortInven(store)
who:sortInven(inven)
end
function _M:doBuy(who, o, item, nb, store_dialog)
local max_nb = o:getNumber()
nb = math.min(nb, max_nb)
nb = math.min(nb, o:getNumber())
nb = self:tryBuy(who, o, item, nb)
if nb then
Dialog:yesnoPopup("Buy", ("Buy %d %s"):format(nb, o:getName{do_color=true, no_count=true}), function(ok) if ok then
self:onBuy(who, o, item, nb, true)
local store, inven = self:getInven("INVEN"), who:getInven("INVEN")
for i = 1, nb do
local o = self:removeObject(store, item)
who:addObject(inven, o)
end
self:sortInven(store)
who:sortInven(inven)
self.changed = true
who.changed = true
self:transfer(self, who, item, nb)
self:onBuy(who, o, item, nb, false)
if store_dialog then store_dialog:updateStore() end
end end, "Buy", "Cancel")
......@@ -123,21 +124,12 @@ function _M:doBuy(who, o, item, nb, store_dialog)
end
function _M:doSell(who, o, item, nb, store_dialog)
local max_nb = o:getNumber()
nb = math.min(nb, max_nb)
nb = math.min(nb, o:getNumber())
nb = self:trySell(who, o, item, nb)
if nb then
Dialog:yesnoPopup("Sell", ("Sell %d %s"):format(nb, o:getName{do_color=true, no_count=true}), function(ok) if ok then
self:onSell(who, o, item, nb, true)
local store, inven = self:getInven("INVEN"), who:getInven("INVEN")
for i = 1, nb do
local o = who:removeObject(inven, item)
self:addObject(store, o)
end
self:sortInven(store)
who:sortInven(inven)
self.changed = true
who.changed = true
self:transfer(who, self, item, nb)
self:onSell(who, o, item, nb, false)
if store_dialog then store_dialog:updateStore() end
end end, "Sell", "Cancel")
......
......@@ -409,6 +409,7 @@ function _M:sortInven(inven)
return ta < tb
end
end)
self.changed = true
end
--- Finds an object by name in an inventory
......
......@@ -292,6 +292,10 @@ function _M:move(x, y, force)
end end
end
if moved and self:isTalentActive(self.T_BODY_OF_STONE) then
self:forceUseTalent(self.T_BODY_OF_STONE, {ignore_energy=true})
end
return moved
end
......
......@@ -80,7 +80,7 @@ function _M:onTakeHit(value, src)
self.ai_target.actor = src
end
if Faction:get(self.faction) and Faction:get(self.faction).hostile_on_attack then
if src and Faction:get(self.faction) and Faction:get(self.faction).hostile_on_attack then
Faction:setFactionReaction(self.faction, src.faction, Faction:factionReaction(self.faction, src.faction) - self.rank * 5, true)
end
......@@ -88,7 +88,7 @@ function _M:onTakeHit(value, src)
end
function _M:die(src)
if Faction:get(self.faction) and Faction:get(self.faction).hostile_on_attack then
if src and Faction:get(self.faction) and Faction:get(self.faction).hostile_on_attack then
Faction:setFactionReaction(self.faction, src.faction, Faction:factionReaction(self.faction, src.faction) - self.rank * 15, true)
end
......
......@@ -30,7 +30,6 @@ function _M:loadStores(f)
end
function _M:init(t, no_default)
t.allow_sell = function() Dialog:simplePopup("Can not sell", "Do you really think I will buy your filthy wreckages found in the wilds? Ah!") end
t.buy_percent = t.buy_percent or 10
t.sell_percent = t.sell_percent or 100
Store.init(self, t, no_default)
......@@ -47,7 +46,7 @@ end
function _M:tryBuy(who, o, item, nb)
local price = o:getPrice() * self.sell_percent / 100
if who.money >= price * nb then
return nb
return nb, price * nb --FINISH ME !!!!
else
Dialog:simplePopup("Not enough gold", "You do not have enough gold!")
end
......@@ -62,7 +61,7 @@ end
function _M:trySell(who, o, item, nb)
local price = o:getPrice() * self.buy_percent / 100
if price <= 0 or nb <= 0 then return end
return nb
return nb, price
end
--- Called on object purchase
......@@ -95,6 +94,34 @@ function _M:onSell(who, o, item, nb, before)
who:incMoney(price * nb)
end
--- Override the default
function _M:doBuy(who, o, item, nb, store_dialog)
nb = math.min(nb, o:getNumber())
nb = self:tryBuy(who, o, item, nb)
if nb then
Dialog:yesnoPopup("Buy", ("Buy %d %s for %0.2f gold"):format(nb, o:getName{do_color=true, no_count=true}), function(ok) if ok then
self:onBuy(who, o, item, nb, true)
self:transfer(self, who, item, nb)
self:onBuy(who, o, item, nb, false)
if store_dialog then store_dialog:updateStore() end
end end, "Buy", "Cancel")
end
end
--- Override the default
function _M:doSell(who, o, item, nb, store_dialog)
nb = math.min(nb, o:getNumber())
nb = self:trySell(who, o, item, nb)
if nb then
Dialog:yesnoPopup("Sell", ("Sell %d %s for %0.2f gold"):format(nb, o:getName{do_color=true, no_count=true}), function(ok) if ok then
self:onSell(who, o, item, nb, true)
self:transfer(who, self, item, nb)
self:onSell(who, o, item, nb, false)
if store_dialog then store_dialog:updateStore() end
end end, "Sell", "Cancel")
end
end
--- Called to describe an object, being to sell or to buy
-- @param who the actor
-- @param what either "sell" or "buy"
......
......@@ -33,6 +33,7 @@ newBirthDescriptor{
Pyromancer = function() return profile.mod.allow_build.mage_pyromancer and "allow" or "disallow" end,
Cryomancer = function() return profile.mod.allow_build.mage_cryomancer and "allow" or "disallow" end,
Tempest = function() return profile.mod.allow_build.mage_tempest and "allow" or "disallow" end,
Geomancer = function() return profile.mod.allow_build.mage_geomancer and "allow" or "disallow" end,
},
},
copy = {
......@@ -318,3 +319,54 @@ newBirthDescriptor{
life_rating = -4,
},
}
newBirthDescriptor{
type = "subclass",
name = "Geomancer",
desc = {
"A Geomancer is an archmage specialized in earth and stone magic.",
"They gain access to the special Stone talents whose main purpose is to crush and destroy.",
"They can even learn to pierce through physical resistance and immunity.",
"Most archmagi lack basic skills that others take for granted (like general fighting sense), but they make up for it by their raw magical power.",
"Archmagi know all schools of magic but the more intricate (Temporal and Meta) from the start. They however usually refuse to have anything to do with Necromancy.",
"All archmagi have been trained in the secret town of Angolwen and posses a unique spell to teleport to it directly.",
"Their most important stats are: Magic and Willpower",
"#GOLD#Stats modifiers:",
"#LIGHT_BLUE# * +0 Strength, +0 Dexterity, +0 Constitution",
"#LIGHT_BLUE# * +5 Magic, +3 Willpower, +1 Cunning",
},
stats = { mag=5, wil=3, cun=1, },
talents_types = {
["spell/arcane"]={true, 0.2},
["spell/earth"]={true, 0.3},
["spell/stone"]={true, 0.4},
["spell/water"]={true, 0.2},
["spell/phantasm"]={true, 0.3},
["spell/temporal"]={false, 0.3},
["spell/meta"]={false, 0.3},
["spell/divination"]={true, 0.3},
["spell/conveyance"]={true, 0.3},
["cunning/survival"]={false, -0.1},
},
talents = {
[ActorTalents.T_ARCANE_POWER] = 1,
[ActorTalents.T_STONE_SKIN] = 1,
[ActorTalents.T_STALACTITIC_MISSILES] = 1,
[ActorTalents.T_PHASE_DOOR] = 1,
[ActorTalents.T_TELEPORT_ANGOLWEN]=1,
},
copy = {
-- All mages are of angolwen faction
faction = "angolwen",
max_life = 90,
life_rating = -4,
resolvers.equip{ id=true,
{type="weapon", subtype="staff", name="elm staff", autoreq=true},
{type="armor", subtype="cloth", name="linen robe", autoreq=true},
},
resolvers.inventory{ id=true,
{type="potion", subtype="potion", name="potion of lesser mana", ego_chance=-1000},
{type="potion", subtype="potion", name="potion of lesser mana", ego_chance=-1000},
},
},
}
......@@ -841,3 +841,34 @@ newDamageType{
hideMessage=true,
hideFlyer=true
}
-- Physical + Stun Chance
newDamageType{
name = "physical stun", type = "PHYSICAL_STUN",
projector = function(src, x, y, type, dam)
DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam)
local target = game.level.map(x, y, Map.ACTOR)
if target and rng.percent(25) then
if target:checkHit(src:combatSpellpower(), target:combatSpellResist(), 0, 95, 15) and target:canBe("stun") then
target:setEffect(target.EFF_STUNNED, 2, {src=src})
else
game.logSeen(target, "%s resists!", target.name:capitalize())
end
end
end,
}
-- Physical Damage/Cut Split
newDamageType{
name = "split bleed", type = "SPLIT_BLEED",
projector = function(src, x, y, type, dam)
DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam / 2)
DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam / 12)
dam = dam - dam / 12
local target = game.level.map(x, y, Map.ACTOR)
if target and target:canBe("cut") then
-- Set on fire!
target:setEffect(target.EFF_CUT, 5, {src=src, power=dam / 11})
end
end,
}
......@@ -50,7 +50,7 @@ newEntity{
if a then
game.logPlayer(a, "You are crushed by the collapsing tunnel! You suffocate!")
a:suffocate(30, self)
engine.DamageType:get(engine.DamageType.PHYSICAL).projector(self, self.x, self.y, engine.DamageType.PHYSICAL, a.life / 2)
engine.DamageType:get(engine.DamageType.PHYSICAL).projector(self, self.x, self.y, engine.DamageType.PHYSICAL, a.life / 4)
end
end
end
......
-- ToME - Tales of Middle-Earth
-- Copyright (C) 2009, 2010 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
return { generator = function()
local ad = rng.range(0, 360)
local a = math.rad(ad)
local dir = math.rad(ad)
local r = rng.range(18, 22)
local dirchance = rng.chance(2)
return {
life = 20,
size = 4, sizev = -0.05, sizea = 0,
x = r * math.cos(a), xv = 0, xa = 0,
y = r * math.sin(a), yv = 0, ya = 0,
dir = dir, dirv = 0.1, dira = 0,
vel = dirchance and 0.2 or -0.2, velv = 0, vela = dirchance and -0.02 or 0.02,
r = rng.range(0, 0)/255, rv = rng.range(0, 10)/100, ra = 0,
g = rng.range(80, 200)/255, gv = 0.005, ga = 0.0005,
b = 0, bv = 0, ba = 0,
a = rng.range(70, 255)/255, av = 0, aa = 0,
}
end, },
function(self)
self.ps:emit(4)
end,
80
-- ToME - Tales of Middle-Earth
-- Copyright (C) 2009, 2010 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
return { generator = function()
local ad = rng.range(0, 360)
local a = math.rad(ad)
local dir = math.rad(ad + 90)
local r = rng.range(1, 20)
local dirv = math.rad(1)
return {
trail = 1,
life = 10,
size = 1, sizev = 0.5, sizea = 0,
x = r * math.cos(a), xv = -0.1, xa = 0,
y = r * math.sin(a), yv = -0.1, ya = 0,
dir = math.rad(rng.range(0, 360)), dirv = 0, dira = 0,
vel = 0.1, velv = 0, vela = 0,
r = rng.range(200, 230)/255, rv = 0, ra = 0,
g = rng.range(130, 160)/255, gv = 0, ga = 0,
b = rng.range(50, 70)/255, bv = 0, ba = 0,
a = rng.range(25, 220)/255, av = 0, aa = 0,
}
end, },
function(self)
self.ps:emit(4)
end,
40
-- ToME - Tales of Middle-Earth
-- Copyright (C) 2009, 2010 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 starts = {}
for i = 1, 4 do
starts[#starts+1] = { a = math.rad(rng.range(0, 360)), r = rng.range(6, 20) }
end
-- Populate the beam based on the forks
return { generator = function()
local rad = rng.range(-3,3)
local s = rng.table(starts)
local ra = s.a
local r = s.r
return {
life = 4,
size = rng.range(4, 6), sizev = -0.1, sizea = 0,
x = 2 * math.cos(ra), xv = 0, xa = 0,
y = 2 * math.sin(ra), 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(30 * 4)
end,
4*30*4
......@@ -26,7 +26,7 @@ newLore{
name = "note from the Master",
lore = [[MINIONS: Perhaps you feel your Master has been lax or absent? Well, I shall amend that. I have been studying an object of great import. It is of much greater interest than your foolish unlives. But do not think that I will let you get away with things because of this.
Skeletons, you have been getting noticeably behind in your adventurer slaughtering quotas. The next skeleton archer I see drinking coffee and chatting with the wights shall be rended limb from limb and fed to the orcs. Also, as a punishment for your general laxness, 1,000 skeletons shall be remanded down to Amun Sul as punishment. A further 250 shall be slaughtered. These orders to be carried out by myself tomorrow at 3am.]],
Skeletons, you have been getting noticeably behind in your adventurer slaughtering quotas. The next skeleton archer I see drinking coffee and chatting with the wights shall be rent limb from limb and fed to the orcs. Also, as a punishment for your general laxness, 1,000 skeletons shall be remanded down to Amun Sul as punishment. A further 250 shall be slaughtered. These orders to be carried out by myself tomorrow at 3am.]],
}
newLore{
......
......@@ -24,6 +24,7 @@ newTalentType{ no_silence=true, is_spell=true, type="spell/arcane", name = "arca
newTalentType{ no_silence=true, is_spell=true, type="spell/fire", name = "fire", description = "Harness the power of fire to burn your foes to ashes." }
newTalentType{ no_silence=true, is_spell=true, type="spell/wildfire", name = "wildfire", description = "Harness the power of wildfire to burn your foes to ashes." }
newTalentType{ no_silence=true, is_spell=true, type="spell/earth", name = "earth", description = "Harness the power of the earth to protect and destroy." }
newTalentType{ no_silence=true, is_spell=true, type="spell/stone", name = "stone", description = "Harness the power of the stone to protect and destroy." }
newTalentType{ no_silence=true, is_spell=true, type="spell/water", name = "water", description = "Harness the power of water to drown your foes." }
newTalentType{ no_silence=true, is_spell=true, type="spell/ice", name = "ice", description = "Harness the power of ice to freeze and shatter your foes." }
newTalentType{ no_silence=true, is_spell=true, type="spell/air", name = "air", description = "Harness the power of the air to fry your foes." }
......@@ -75,6 +76,7 @@ load("/data/talents/spells/arcane.lua")
load("/data/talents/spells/fire.lua")
load("/data/talents/spells/wildfire.lua")
load("/data/talents/spells/earth.lua")
load("/data/talents/spells/stone.lua")
load("/data/talents/spells/water.lua")
load("/data/talents/spells/ice.lua")
load("/data/talents/spells/air.lua")
......
-- ToME - Tales of Middle-Earth
-- Copyright (C) 2009, 2010 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 = "Stalactitic Missiles",
type = {"spell/stone",1},
require = spells_req1,
points = 5,
random_ego = "attack",
mana = 10,
cooldown = 3,
tactical = {
ATTACK = 10,
},
range = 20,
direct_hit = true,
reflectable = true,
proj_speed = 20,
requires_target = true,
action = function(self, t)
local tg = {type="bolt", range=self:getTalentRange(t), talent=t, display={particle="stone_shards", trail="earthtrail"}}
local x, y = self:getTarget(tg)
if not x or not y then return nil end
self:projectile(tg, x, y, DamageType.SPLIT_BLEED, self:spellCrit(self:combatTalentSpellDamage(t, 20, 120)), nil)
game:playSoundNear(self, "talents/earth")
--missile #2 (Talent Level 3 Bonus Missile)
if self:getTalentLevel(t) >= 3 then
local tg2 = {type="bolt", range=self:getTalentRange(t), talent=t, display={particle="stone_shards", trail="earthtrail"}}
local x, y = self:getTarget(tg2)
if not x or not y then return nil end
self:projectile(tg2, x, y, DamageType.SPLIT_BLEED, self:spellCrit(self:combatTalentSpellDamage(t, 20, 120)), nil)
game:playSoundNear(self, "talents/earth")
else end
--missile #3 (Talent Level 5 Bonus Missile)
if self:getTalentLevel(t) >= 5 then
local tg3 = {type="bolt", range=self:getTalentRange(t), talent=t, display={particle="stone_shards", trail="earthtrail"}}
local x, y = self:getTarget(tg3)
if not x or not y then return nil end
self:projectile(tg3, x, y, DamageType.SPLIT_BLEED, self:spellCrit(self:combatTalentSpellDamage(t, 20, 120)), nil)
game:playSoundNear(self, "talents/earth")
else end
return true
end,
info = function(self, t)
return ([[Conjures stalactite shaped rocks that you fire individually at any target or targets in range. Each missile deals %0.2f physical damage and an additional %0.2f bleeding damage over six turns.
At talent level 1 you conjure a single missile, at talent level 3 two missiles, and at talent level 5 three missiles.
The damage will increase with the Magic stat]]):format(damDesc(self, DamageType.PHYSICAL, self:combatTalentSpellDamage(t, 20, 120)/2), damDesc(self, DamageType.PHYSICAL, self:combatTalentSpellDamage(t, 20, 120)/2))
end,
}
newTalent{
name = "Body of Stone",
type = {"spell/stone",2},
require = spells_req2,
points = 5,
mode = "sustained",
sustain_mana = 70,
cooldown = 12,
activate = function(self, t)
local fire = self:combatTalentSpellDamage(t, 5, 80)
local light = self:combatTalentSpellDamage(t, 5, 50)
local phys = self:combatTalentSpellDamage(t, 5, 20)
local kb = self:getTalentLevel(t)/10
local cdr = self:getTalentLevel(t)/2
local rad = 5 + self:combatSpellpower(0.1) * self:getTalentLevel(t)
game:playSoundNear(self, "talents/earth")
return {
particle = self:addParticles(Particles.new("stone_skin", 1)),
move = self:addTemporaryValue("never_move", 1),
knock = self:addTemporaryValue("knockback_immune", kb),
detect = self:addTemporaryValue("detect_range", rad),
tremor = self:addTemporaryValue("detect_actor", 1),
cdred = self:addTemporaryValue("talent_cd_reduction", {
[self.T_STALACTITIC_MISSILES] = cdr,
[self.T_STRIKE] = cdr,
[self.T_EARTHQUAKE] = cdr,
}),
res = self:addTemporaryValue("resists", {
[DamageType.FIRE] = fire,
[DamageType.LIGHTNING] = light,
[DamageType.PHYSICAL] = phys,
}),
}
end,
deactivate = function(self, t, p)
self:removeParticles(p.particle)
self:removeTemporaryValue("never_move", p.move)
self:removeTemporaryValue("knockback_immune", p.knock)
self:removeTemporaryValue("detect_actor", p.tremor)
self:removeTemporaryValue("detect_range", p.detect)
self:removeTemporaryValue("talent_cd_reduction", p.cdred)
self:removeTemporaryValue("resists", p.res)
return true
end,
info = function(self, t)
return ([[You root yourself into the earth and transform your flesh into stone. While this spell is sustained you may not move and any forced movement will end the effect.
Your stoned form and your affinity with the earth while the spell is active has the following effects:
* Reduces the cooldown of Stalactitic Missiles, Earthquake, and Strike by %d
* Grants %d%% Fire Resistance, %d%% Lightning Resistance, %d%% Physical Resistance, and %d%% Knockback Resistance
* Sense foes around you in a radius of %d.
Resistances and Sense radius scale with the Magic Stat.]])
:format((self:getTalentLevel(t)/2), self:combatTalentSpellDamage(t, 5, 80), self:combatTalentSpellDamage(t, 5, 50), self:combatTalentSpellDamage(t, 5, 20), (self:getTalentLevel(t)*10), (5 + self:combatSpellpower(0.1) * self:getTalentLevel(t)))
end,
}
newTalent{
name = "Earthquake",
type = {"spell/stone",3},
require = spells_req3,
points = 5,
random_ego = "attack",
mana = 50,
cooldown = 30,
tactical = {
ATTACKAREA = 40,
},
range = 20,
direct_hit = true,
requires_target = true,
action = function(self, t)
local duration = 3 + self:getTalentLevel(t)
local radius = 2 + (self:getTalentLevel(t)/2)
local dam = self:combatTalentSpellDamage(t, 15, 70)
local tg = {type="ball", range=self:getTalentRange(t), radius=radius}
local x, y = self:getTarget(tg)
if not x or not y then return nil end
local _ _, x, y = self:canProject(tg, x, y)
-- Add a lasting map effect
game.level.map:addEffect(self,
x, y, duration,
DamageType.PHYSICAL_STUN, dam,
radius,
5, nil,
{type="quake"},
nil, self:spellFriendlyFire()
)
game:playSoundNear(self, "talents/earth")
return true
end,
info = function(self, t)
return ([[Causes a violent earthquake that deals %0.2f physical damage in a radius of %d each turn for %d turns and potentially stuns all creatures it affects.
The damage and duration will increase with the Magic stat]]):format(damDesc(self, DamageType.PHYSICAL, self:combatTalentSpellDamage(t, 15, 70)), 2 + (self:getTalentLevel(t)/2), 3 + self:getTalentLevel(t))
end,
}
newTalent{
name = "Crystalline Focus",
type = {"spell/stone",4},
require = spells_req4,
points = 5,
mode = "sustained",
sustain_mana = 80,
cooldown = 30,
activate = function(self, t)
game:playSoundNear(self, "talents/earth")
return {
dam = self:addTemporaryValue("inc_damage", {[DamageType.PHYSICAL] = self:getTalentLevelRaw(t) * 2}),
resist = self:addTemporaryValue("resists_pen", {[DamageType.PHYSICAL] = self:getTalentLevelRaw(t) * 10}),
particle = self:addParticles(Particles.new("crystalline_focus", 1)),
}
end,
deactivate = function(self, t, p)
self:removeParticles(p.particle)
self:removeTemporaryValue("inc_damage", p.dam)
self:removeTemporaryValue("resists_pen", p.resist)
return true
end,
info = function(self, t)
return ([[Concentrate on maintaining a Crystalline Focus, increasing all your physical damage by %d%% and ignoring %d%% physical resistance of your targets.]])
:format(self:getTalentLevelRaw(t) * 2, self:getTalentLevelRaw(t) * 10)
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