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

spells

git-svn-id: http://svn.net-core.org/repos/t-engine4@101 51575b47-30f0-44d4-a5cc-537603b46e54
parent fb5c93da
No related branches found
No related tags found
No related merge requests found
Showing
with 310 additions and 202 deletions
......@@ -9,6 +9,7 @@ module(..., package.seeall, class.make)
function _M:init(t)
self.max_life = t.max_life or 100
self.life = t.life or self.max_life
self.life_regen = t.life_regen or 0
end
--- Checks if something bumps in us
......@@ -24,8 +25,8 @@ end
--- Regenerate life, call it from your actor class act() method
function _M:regenLife()
if self.regen_life then
self.life = util.bound(self.life + self.regen_life, 0, self.max_life)
if self.life_regen then
self.life = util.bound(self.life + self.life_regen, 0, self.max_life)
end
end
......
......@@ -9,7 +9,8 @@ _M.talents_types_def = {}
--- Defines actor talents
-- Static!
function _M:loadDefinition(file)
local f = loadfile(file)
local f, err = loadfile(file)
if not f and err then error(err) end
setfenv(f, setmetatable({
DamageType = require("engine.DamageType"),
newTalent = function(t) self:newTalent(t) end,
......@@ -65,6 +66,7 @@ function _M:init(t)
self.talents = t.talents or {}
self.talents_types = t.talents_types or {}
self.talents_cd = {}
self.sustain_talents = {}
end
--- Make the actor use the talent
......@@ -72,7 +74,7 @@ function _M:useTalent(id)
local ab = _M.talents_def[id]
assert(ab, "trying to cast talent "..tostring(id).." but it is not defined")
if ab.action then
if ab.mode == "activated" and ab.action then
if self:isTalentCoolingDown(ab) then
game.logPlayer(self, "%s is still on cooldown for %d turns.", ab.name:capitalize(), self.talents_cd[ab.id])
return
......@@ -88,6 +90,33 @@ function _M:useTalent(id)
end)
local ok, err = coroutine.resume(co)
if not ok and err then error(err) end
elseif ab.mode == "sustained" and ab.activate and ab.deactivate then
if self:isTalentCoolingDown(ab) then
game.logPlayer(self, "%s is still on cooldown for %d turns.", ab.name:capitalize(), self.talents_cd[ab.id])
return
end
if not self:preUseTalent(ab) then return end
local co = coroutine.create(function()
if not self.sustain_talents[id] then
local ret = ab.activate(self)
if not self:postUseTalent(ab, ret) then return end
self.sustain_talents[id] = ret
else
local ret = ab.deactivate(self, self.sustain_talents[id])
if not self:postUseTalent(ab, ret) then return end
-- Everything went ok? then start cooldown if any
self:startTalentCooldown(ab)
self.sustain_talents[id] = nil
end
end)
local ret, err = coroutine.resume(co)
if not ret and err then error(err) end
else
error("Activating non activable or sustainable talent: "..id.." :: "..ab.name.." :: "..ab.mode)
end
end
......@@ -116,6 +145,11 @@ function _M:postUseTalent(talent, ret)
return true
end
--- Is the sustained talent activated ?
function _M:isTalentActive(t_id)
return self.sustain_talents[t_id]
end
--- Returns how many talents of this type the actor knows
function _M:numberKnownTalent(type)
local nb = 0
......
......@@ -135,6 +135,10 @@ function _M:preUseTalent(ab)
if ab.message then
game.logSeen(self, "%s", self:useTalentMessage(ab))
elseif ab.mode == "sustained" and not self:isTalentActive(ab.id) then
game.logSeen(self, "%s activates %s.", self.name:capitalize(), ab.name)
elseif ab.mode == "sustained" and self:isTalentActive(ab.id) then
game.logSeen(self, "%s deactivates %s.", self.name:capitalize(), ab.name)
elseif ab.type[1]:find("^spell/") then
game.logSeen(self, "%s casts %s.", self.name:capitalize(), ab.name)
else
......
......@@ -285,7 +285,6 @@ function _M:setupCommands()
-- talent use
_m = function()
self.player:useTalents()
self.player:setEffect(self.player.EFF_CUT, 10, {power=4}, self.player)
end,
[{"_g","shift"}] = function()
......
......@@ -12,7 +12,7 @@ function _M:init(t)
self.combat = { dam=10, atk=40, apr=2, def=6, armor=4 }
self.mana_regen = self.mana_regen or 1
self.stamina_regen = self.stamina_regen or 1
self.regen_life = self.regen_life or 0.5
self.life_regen = self.life_regen or 0.5
self.descriptor = {}
self.hotkey = {}
end
......
newTalent{
name = "Manathrust",
type = {"spell/arcane", 1},
mana = 10,
tactical = {
ATTACK = 10,
},
action = function(self)
local t = {type="bolt", range=20}
local x, y = self:getTarget(t)
if not x or not y then return nil end
self:project(t, x, y, DamageType.ARCANE, 10 + self:getMag())
return true
end,
require = { stat = { mag=10 }, },
info = function(self)
return ([[Conjures up mana into a powerful bolt doing %0.2f arcane damage
The damage will increase with the Magic stat]]):format(10 + self:getMag())
end,
}
newTalent{
name = "Disruption Shield",
type = {"spell/arcane",2},
mode = "sustained",
sustain_mana = 60,
tactical = {
DEFEND = 10,
},
action = function(self)
return true
end,
require = { stat = { mag=50 }, },
info = function(self)
return ([[Uses mana instead of life to take damage
The damage to mana ratio increases with the Magic stat]]):format(10 + self:getMag())
end,
}
newTalent{
name = "Manaflow",
type = {"spell/arcane", 3},
mana = 0,
cooldown = 300,
tactical = {
MANA = 20,
},
action = function(self)
if not self:hasEffect(self.EFF_MANAFLOW) then
self:setEffect(self.EFF_MANAFLOW, 10, {power=5+self:getMag(30)})
end
return true
end,
require = { stat = { mag=60 }, },
info = function(self)
return ([[Engulf yourself into a surge of mana, quickly restoring %d mana every turns for 10 turns.
The mana restored will increase with the Magic stat]]):format(5 + self:getMag(30))
end,
}
newTalent{
name = "Blink",
type = {"spell/conveyance",1},
message = "@Source@ blinks.",
mana = 15,
cooldown = 9,
tactical = {
ESCAPE = 4,
},
action = function(self)
local x, y = self.x, self.y
if self:knowTalent(self.T_TELEPORT_CONTROL) then
x, y = self:getTarget{type="ball", range=10 + self:getMag(10), radius=5 - self:getMag(4)}
if not x then return nil end
-- Target code doesnot restrict the target coordinates to the range, it lets the poject function do it
-- but we cant ...
x, y = game.target:pointAtRange(self.x, self.y, x, y, 10 + self:getMag(10))
self:teleportRandom(x, y, 5 - self:getMag(4))
else
self:teleportRandom(x, y, 10 + self:getMag(10))
end
return true
end,
require = { stat = { mag=12 }, },
info = function(self)
return ([[Teleports you randomly on a small scale range (%d)
The range will increase with the Magic stat]]):format(10 + self:getMag(10))
end,
}
newTalent{
name = "Teleport Control",
type = {"spell/conveyance",2},
mode = "passive",
require = { stat = { mag=38 }, },
info = function(self)
return ([[Allows teleport spells to specify a target area. You will blink in this radius randomly.
The radius (%d) of the target area decreases with Magic stat]]):format(5 - self:getMag(4))
end,
}
newTalent{
name = "Noxious Cloud",
type = {"spell/earth",1},
mana = 45,
cooldown = 8,
tactical = {
ATTACKAREA = 10,
},
action = function(self)
local duration = 5 + self:getMag(10)
local radius = 3
local t = {type="ball", range=15, radius=radius}
local x, y = self:getTarget(t)
if not x or not y then return nil end
x, y = game.target:pointAtRange(self.x, self.y, x, y, 15)
-- Add a lasting map effect
game.level.map:addEffect(self,
x, y, duration,
DamageType.NATURE, 4 + self:getMag(30),
radius,
5, nil,
engine.Entity.new{alpha=100, display='', color_br=30, color_bg=180, color_bb=60}
)
return true
end,
require = { stat = { mag=16 }, },
info = function(self)
return ([[Noxious fumes raises from the ground doing %0.2f nature damage in a radius of 3 each turns for %d turns.
Cooldown: 8 turns
The damage and duration will increase with the Magic stat]]):format(4 + self:getMag(30), 5 + self:getMag(10))
end,
}
newTalent{
name = "Stone Skin",
type = {"spell/earth", 1},
mode = "sustained",
mana = 45,
cooldown = 10,
tactical = {
DEFEND = 10,
},
activate = function(self)
local power = 1 + self:getMag(15)
self.combat.armor = self.combat.armor + power
return {power=power}
end,
deactivate = function(self, p)
self.combat.armor = self.combat.armor - p.power
end,
require = { stat = { mag=14 }, },
info = function(self)
return ([[The caster skin grows as hard as stone, granting %d bonus to armor.
The bonus to armor will increase with the Magic stat]]):format(1 + self:getMag(15))
end,
}
newTalent{
name = "Globe of Light",
type = {"spell/fire",1},
mana = 5,
tactical = {
ATTACKAREA = 3,
},
action = function(self)
local t = {type="ball", range=0, friendlyfire=false, radius=5 + self:getMag(10)}
self:project(t, self.x, self.y, DamageType.LIGHT, 1)
return true
end,
require = { stat = { mag=10 }, },
info = function(self)
return ([[Creates a globe of pure light with a radius of %d that illuminates the area.
The radius will increase with the Magic stat]]):format(5 + self:getMag(10))
end,
}
newTalent{
name = "Fireflash",
type = {"spell/fire",2},
mana = 35,
cooldown = 6,
tactical = {
ATTACKAREA = 10,
},
action = function(self)
local t = {type="ball", range=15, radius=math.min(6, 3 + self:getMag(6))}
local x, y = self:getTarget(t)
if not x or not y then return nil end
self:project(t, x, y, DamageType.FIRE, 28 + self:getMag(70))
return true
end,
require = { stat = { mag=16 }, },
info = function(self)
return ([[Conjures up a flash of fire doing %0.2f fire damage in a radius of %d.
Cooldown: 6 turns
The damage will increase with the Magic stat]]):format(8 + self:getMag(70), math.min(6, 3 + self:getMag(6)))
end,
}
newTalent{
name = "Regeneration",
type = {"spell/nature", 1},
mana = 30,
cooldown = 10,
tactical = {
HEAL = 10,
},
action = function(self)
self:setEffect(self.EFF_REGENERATION, 10, {power=5 + self:getMag(35)})
return true
end,
require = { stat = { mag=10 }, },
info = function(self)
return ([[Call upon the forces of nature to regenerate your body for %d life every turns for 10 turns.
The life healed will increase with the Magic stat]]):format(5 + self:getMag(35))
end,
}
newTalent{
name = "Heal",
type = {"spell/nature", 2},
mana = 60,
cooldown = 10,
tactical = {
HEAL = 10,
},
action = function(self)
self:heal(10 + self:getMag(200), self)
return true
end,
require = { stat = { mag=20 }, },
info = function(self)
return ([[Call upon the forces of nature to heal your body for %d life.
The life healed will increase with the Magic stat]]):format(10 + self:getMag(200))
end,
}
......@@ -2,202 +2,25 @@
newTalentType{ type="spell/arcane", name = "arcane", description = "Arcane manipulates the raw magic energies to shape them into both offensive and defensive spells." }
newTalentType{ type="spell/fire", name = "fire", description = "Harness the power of fire to burn your foes to ashes." }
newTalentType{ type="spell/earth", name = "earth", description = "Harness the power of the earth to protect and destroy." }
newTalentType{ type="spell/cold", name = "cold", description = "Harness the power of winter to shatter your foes." }
newTalentType{ type="spell/water", name = "water", description = "Harness the power of water to drown your foes." }
newTalentType{ type="spell/air", name = "air", description = "Harness the power of the air to fry your foes." }
newTalentType{ type="spell/conveyance", name = "conveyance", description = "Conveyance is the school of travel. It allows you to travel faster and to track others." }
newTalentType{ type="spell/nature", name = "nature", description = "Summons the power of nature to rejuvenate yourself and the world." }
newTalent{
name = "Manathrust",
type = {"spell/arcane", 1},
mana = 10,
tactical = {
ATTACK = 10,
},
action = function(self)
local t = {type="bolt", range=20}
local x, y = self:getTarget(t)
if not x or not y then return nil end
self:project(t, x, y, DamageType.ARCANE, 10 + self:getMag())
return true
end,
require = { stat = { mag=10 }, },
info = function(self)
return ([[Conjures up mana into a powerful bolt doing %0.2f arcane damage
The damage will increase with the Magic stat]]):format(10 + self:getMag())
end,
}
newTalent{
name = "Disruption Shield",
type = {"spell/arcane",2},
mode = "sustained",
sustain_mana = 60,
tactical = {
DEFEND = 10,
},
action = function(self)
return true
end,
require = { stat = { mag=12 }, },
info = function(self)
return ([[Uses mana instead of life to take damage
The damage to mana ratio increases with the Magic stat]]):format(10 + self:getMag())
end,
}
newTalent{
name = "Globe of Light",
type = {"spell/fire",1},
mana = 5,
tactical = {
ATTACKAREA = 3,
},
action = function(self)
local t = {type="ball", range=0, friendlyfire=false, radius=5 + self:getMag(10)}
self:project(t, self.x, self.y, DamageType.LIGHT, 1)
return true
end,
require = { stat = { mag=10 }, },
info = function(self)
return ([[Creates a globe of pure light with a radius of %d that illuminates the area.
The radius will increase with the Magic stat]]):format(5 + self:getMag(10))
end,
}
newTalent{
name = "Fireflash",
type = {"spell/fire",2},
mana = 35,
cooldown = 6,
tactical = {
ATTACKAREA = 10,
},
action = function(self)
local t = {type="ball", range=15, radius=math.min(6, 3 + self:getMag(6))}
local x, y = self:getTarget(t)
if not x or not y then return nil end
self:project(t, x, y, DamageType.FIRE, 28 + self:getMag(70))
return true
end,
require = { stat = { mag=16 }, },
info = function(self)
return ([[Conjures up a flash of fire doing %0.2f fire damage in a radius of %d.
Cooldown: 6 turns
The damage will increase with the Magic stat]]):format(8 + self:getMag(70), math.min(6, 3 + self:getMag(6)))
end,
}
newTalent{
name = "Blink",
type = {"spell/conveyance",1},
message = "@Source@ blinks.",
mana = 15,
cooldown = 9,
tactical = {
ESCAPE = 4,
},
action = function(self)
local x, y = self.x, self.y
if self:knowTalent(self.T_TELEPORT_CONTROL) then
x, y = self:getTarget{type="ball", range=10 + self:getMag(10), radius=5 - self:getMag(4)}
if not x then return nil end
-- Target code doesnot restrict the target coordinates to the range, it lets the poject function do it
-- but we cant ...
x, y = game.target:pointAtRange(self.x, self.y, x, y, 10 + self:getMag(10))
self:teleportRandom(x, y, 5 - self:getMag(4))
else
self:teleportRandom(x, y, 10 + self:getMag(10))
end
return true
end,
require = { stat = { mag=16 }, },
info = function(self)
return ([[Teleports you randomly on a small scale range (%d)
The range will increase with the Magic stat]]):format(10 + self:getMag(10))
end,
}
newTalent{
name = "Teleport Control",
type = {"spell/conveyance",2},
mode = "passive",
require = { stat = { mag=38 }, },
info = function(self)
return ([[Allows teleport spells to specify a target area. You will blink in this radius randomly.
The radius (%d) of the target area decreases with Magic stat]]):format(5 - self:getMag(4))
end,
}
newTalent{
name = "Noxious Cloud",
type = {"spell/earth",1},
mana = 45,
cooldown = 8,
tactical = {
ATTACKAREA = 10,
},
action = function(self)
local duration = 5 + self:getMag(10)
local radius = 3
local t = {type="ball", range=15, radius=math.min(6, 3 + self:getMag(6))}
local x, y = self:getTarget(t)
if not x or not y then return nil end
x, y = game.target:pointAtRange(self.x, self.y, x, y, 15)
-- Add a lasting map effect
game.level.map:addEffect(self,
x, y, duration,
DamageType.NATURE, 4 + self:getMag(30),
radius,
5, nil,
engine.Entity.new{alpha=100, display='', color_br=30, color_bg=180, color_bb=60}
)
return true
end,
require = { stat = { mag=16 }, },
info = function(self)
return ([[Noxious fumes raises from the ground doing %0.2f nature damage in a radius of 3 each turns for %d turns.
Cooldown: 8 turns
The damage and duration will increase with the Magic stat]]):format(4 + self:getMag(30), 5 + self:getMag(10))
end,
}
newTalent{
name = "Manaflow",
type = {"spell/arcane", 2},
mana = 10,
cooldown = 300,
tactical = {
MANA = 20,
},
action = function(self)
if not self:hasEffect(self.EFF_MANAFLOW) then
self:setEffect(self.EFF_MANAFLOW, 10, {power=5+self:getMag(30)})
end
return true
end,
require = { stat = { mag=10 }, },
info = function(self)
return ([[Engulf yourself into a surge of mana, quickly restoring %d mana every turns for 10 turns.
The mana restored will increase with the Magic stat]]):format(5 + self:getMag(30))
end,
}
newTalent{
name = "Heal",
type = {"spell/nature", 1},
mana = 30,
cooldown = 10,
tactical = {
HEAL = 10,
},
action = function(self)
self:heal(10 + self:getMag(200), self)
return true
end,
require = { stat = { mag=10 }, },
info = function(self)
return ([[Call upon the forces of nature to heal your body for %d life.
The life healed will increase with the Magic stat]]):format(10 + self:getMag(200))
end,
}
newTalentType{ type="spell/meta", name = "meta", description = "Meta spells alter the working of magic itself." }
newTalentType{ type="spell/divination", name = "divination", description = "Divination allows the caster to sense its surroundings, find hidden things." }
newTalentType{ type="spell/temporal", name = "temporal", description = "Temporal the school of time manipulation." }
newTalentType{ type="spell/mind", name = "mind", description = "Mind the caster to directly attack the mind of its foes." }
newTalentType{ type="spell/necromancy", name = "necromancy", description = "Necromancy is a dark school of magic dealing with death, and undeath." }
load("/data/talents/spells/arcane.lua")
load("/data/talents/spells/fire.lua")
load("/data/talents/spells/earth.lua")
load("/data/talents/spells/cold.lua")
load("/data/talents/spells/air.lua")
load("/data/talents/spells/conveyance.lua")
load("/data/talents/spells/nature.lua")
load("/data/talents/spells/meta.lua")
load("/data/talents/spells/divination.lua")
load("/data/talents/spells/temporal.lua")
load("/data/talents/spells/mind.lua")
load("/data/talents/spells/necromancy.lua")
......@@ -26,3 +26,19 @@ newEffect{
self.mana_regen = self.mana_regen - eff.power
end,
}
newEffect{
name = "REGENERATION",
desc = "Regeneration",
type = "magical",
status = "beneficial",
parameters = { power=10 },
on_gain = function(self, err) return "#Target# starts to regenerating heath quickly.", "+Regen" end,
on_lose = function(self, err) return "#Target# stops regenerating health quickly.", "-Regen" end,
activate = function(self, eff)
self.life_regen = self.life_regen + eff.power
end,
deactivate = function(self, eff)
self.life_regen = self.life_regen - eff.power
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