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

spells and ideas


git-svn-id: http://svn.net-core.org/repos/t-engine4@120 51575b47-30f0-44d4-a5cc-537603b46e54
parent bbdace99
No related branches found
No related tags found
No related merge requests found
Showing
with 201 additions and 27 deletions
......@@ -21,6 +21,12 @@ function _M:init(t)
self.compute_vals = {}
end
--- Called when it is time to act
function _M:act()
if self.dead then return false end
return true
end
--- Moves an actor on the map
-- *WARNING*: changing x and y properties manualy is *WRONG* and will blow up in your face. Use this method. Always.
-- @param map the map to move onto
......@@ -29,6 +35,7 @@ end
-- @param force if true do not check for the presence of an other entity. *Use wisely*
-- @return true if a move was *ATTEMPTED*. This means the actor will proably want to use energy
function _M:move(map, x, y, force)
if self.dead then return true end
if not force and map:checkAllEntities(x, y, "block_move", self) then return true end
if self.x and self.y then
......
......@@ -36,6 +36,6 @@ function _M:newDamageType(t)
end
function _M:get(id)
assert(_M.dam_def[id], "damage type "..id.." used but undefined")
assert(_M.dam_def[id], "damage type "..tostring(id).." used but undefined")
return _M.dam_def[id]
end
......@@ -13,6 +13,7 @@ function _M:loadDefinition(file)
if not f and err then error(err) end
setfenv(f, setmetatable({
DamageType = require("engine.DamageType"),
Talents = self,
newTalent = function(t) self:newTalent(t) end,
newTalentType = function(t) self:newTalentType(t) end,
load = function(f) self:loadDefinition(f) end
......@@ -181,6 +182,8 @@ function _M:learnTalent(t_id, force)
end
end
if t.on_learn then t.on_learn(self) end
self.talents[t_id] = true
self.changed = true
return true
......@@ -190,9 +193,14 @@ end
-- @param t_id the id of the talent to learn
-- @return true if the talent was unlearnt, nil and an error message otherwise
function _M:unlearnTalent(t_id)
local t = _M.talents_def[t_id]
for i, known_t_id in pairs(self.hotkey) do
if known_t_id == t_id then self.hotkey[i] = nil end
end
if t.on_unlearn then t.on_unlearn(self) end
self.talents[t_id] = nil
self.changed = true
return true
......@@ -210,6 +218,11 @@ function _M:canLearnTalent(t)
if t.require.level and self.level < t.require.level then
return nil, "not enough levels"
end
if t.require.talent then
for _, tid in ipairs(t.require.talent) do
if not self:knowTalent(tid) then return nil, "missing dependency" end
end
end
end
-- Check talent type
......@@ -248,6 +261,12 @@ function _M:getTalentReqDesc(t_id)
local c = (self.level >= req.level) and "#00ff00#" or "#ff0000#"
str = str .. ("- %sLevel %d\n"):format(c, req.level)
end
if req.talent then
for _, tid in ipairs(req.talent) do
local c = self:knowTalent(tid) and "#00ff00#" or "#ff0000#"
str = str .. ("- %sTalent %s\n"):format(c, self:getTalentFromId(tid).name)
end
end
return str
end
......
......@@ -10,6 +10,7 @@ _M.tempeffect_def = {}
function _M:loadDefinition(file)
local f = loadfile(file)
setfenv(f, setmetatable({
DamageType = require "engine.DamageType",
newEffect = function(t) self:newEffect(t) end,
load = function(f) self:loadDefinition(f) end
}, {__index=_G}))
......
......@@ -57,6 +57,8 @@ function _M:init(t)
end
function _M:act()
if not engine.Actor.act(self) then return end
-- Cooldown talents
self:cooldownTalents()
-- Regen resources
......@@ -64,6 +66,8 @@ function _M:act()
self:regenResources()
-- Compute timed effects
self:timedEffects()
return true
end
function _M:move(x, y, force)
......
......@@ -93,6 +93,7 @@ function _M:attackTargetWith(target, weapon)
-- If hit is over 0 it connects, if it is 0 we still have 50% chance
if rng.percent(hit) then
local dam = dam - math.max(0, armor - apr)
dam = self:physicalCrit(dam, weapon)
DamageType:get(damtype).projector(self, target.x, target.y, damtype, dam)
else
game.logSeen(target, "%s misses %s.", self.name:capitalize(), target.name)
......@@ -162,3 +163,21 @@ end
function _M:combatSpellSpeed()
return self.combat_spellspeed + (self:getCun() - 10) * 0.3 + 1
end
--- Computes physical crit for a damage
function _M:physicalCrit(dam, weapon)
local chance = self:combatCrit(weapon)
if rng.percent(chance) then
dam = dam * 2
end
return dam
end
--- Computes spell crit for a damage
function _M:spellCrit(dam)
local chance = self:combatSpellCrit()
if rng.percent(chance) then
dam = dam * 2
end
return dam
end
......@@ -41,3 +41,15 @@ newDamageType{
game.level.map.lites(x, y, true)
end,
}
newDamageType{
name = "fireburn", type = "FIREBURN",
projector = function(src, x, y, type, dam)
DamageType:get(DamageType.FIRE).projector(src, x, y, DamageType.FIRE, dam / 2)
local target = game.level.map(x, y, Map.ACTOR)
if target then
-- Set on fire!
target:setEffect(target.EFF_BURNING, 3, {src=src, power=dam / 2 / 3})
end
end,
}
-- Physical combat
newTalentType{ type="physical/2hweapon", name = "two handed weapons", description = "Allows the user to be more proficient with two handed weapons." }
newTalentType{ type="physical/1hweapon", name = "one handed weapons", description = "Allows the user to be more proficient with one handed weapons." }
newTalentType{ type="physical/dualweapon", name = "dual wielding", description = "Allows the user to be more proficient with dual wielding weapons." }
newTalentType{ type="physical/shield", name = "shields", description = "Allows the user to be more proficient with shields." }
newTalentType{ type="physical/shield", name = "weapon and shields", description = "Allows the user to be more proficient with shields and one handed weapons." }
newTalentType{ type="physical/dirty", name = "dirty fighting", description = "Teaches various physical talents to criple your foes." }
newTalentType{ type="physical/weapontraining", name = "weapon training", description = "Grants bonuses to the different weapon types." }
newTalentType{ type="physical/combat training", name = "wombat training", description = "Teaches to use various armors and improves health." }
......@@ -2,14 +2,16 @@ newTalent{
name = "Manathrust",
type = {"spell/arcane", 1},
mana = 10,
cooldown = 3,
tactical = {
ATTACK = 10,
},
action = function(self)
local t = {type="bolt", range=20}
if self:knowTalent(Talents.T_ARCANE_LANCE) then t.type = "beam" end
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:combatSpellpower())
self:project(t, x, y, DamageType.ARCANE, self:spellCrit(10 + self:combatSpellpower()))
return true
end,
require = { stat = { mag=10 }, },
......@@ -19,25 +21,18 @@ newTalent{
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 }, },
name = "Arcane Lance",
type = {"spell/arcane", 2},
mode = "passive",
require = { stat = { mag=24 }, talent = { Talents.T_MANATHRUST }, },
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:combatSpellpower())
return [[Manathrust is now a beam and hits all targets in line.]]
end,
}
newTalent{
name = "Manaflow",
type = {"spell/arcane", 3},
type = {"spell/arcane", 2},
mana = 0,
cooldown = 300,
tactical = {
......@@ -49,9 +44,43 @@ newTalent{
end
return true
end,
require = { stat = { mag=60 }, },
require = { stat = { mag=34 }, },
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:combatSpellpower(0.3))
end,
}
newTalent{
name = "Arcane Power",
type = {"spell/arcane", 3},
mode = "passive",
require = { stat = { mag=40 }, },
on_learn = function(self)
self.combat_spellpower = self.combat_spellpower + 10
end,
on_unlearn = function(self)
self.combat_spellpower = self.combat_spellpower - 10
end,
info = function(self)
return [[Your mastery of magic allows your to permanently increase your spellpower by 10.]]
end,
}
newTalent{
name = "Disruption Shield",
type = {"spell/arcane",4},
mode = "sustained",
sustain_mana = 150,
tactical = {
DEFEND = 10,
},
action = function(self)
return true
end,
require = { stat = { mag=60 }, level=40 },
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:combatSpellpower())
end,
}
......@@ -2,26 +2,61 @@ newTalent{
name = "Globe of Light",
type = {"spell/fire",1},
mana = 5,
cooldown = 14,
tactical = {
ATTACKAREA = 3,
},
action = function(self)
local t = {type="ball", range=0, friendlyfire=false, radius=5 + self:combatSpellpower(0.1)}
local t = {type="ball", range=0, friendlyfire=false, radius=5 + self:combatSpellpower(0.2)}
self:project(t, self.x, self.y, DamageType.LIGHT, 1)
if self:knowTalent(Talents.T_GLOBE_OF_LIGHT) then
self:project(t, self.x, self.y, DamageType.BLIND, 1)
end
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:combatSpellpower(0.1))
The radius will increase with the Magic stat]]):format(5 + self:combatSpellpower(0.2))
end,
}
newTalent{
name = "Blinding Light",
type = {"spell/fire", 2},
mode = "passive",
require = { stat = { mag=24 }, talent = { Talents.T_GLOBE_OF_LIGHT }, },
info = function(self)
return [[Globe of Light will also blind foes.]]
end,
}
newTalent{
name = "Flame",
type = {"spell/fire",1},
mana = 12,
cooldown = 4,
tactical = {
ATTACKAREA = 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.FIREBURN, self:spellCrit(28 + self:combatSpellpower(0.7)))
return true
end,
require = { stat = { mag=10 }, },
info = function(self)
return ([[Conjures up a bolt of fire doing %0.2f fire damage in a radius of %d.
The damage will increase with the Magic stat]]):format(8 + self:combatSpellpower(0.7), math.min(6, 3 + self:combatSpellpower(0.06)))
end,
}
newTalent{
name = "Fireflash",
type = {"spell/fire",2},
mana = 35,
cooldown = 6,
mana = 40,
cooldown = 8,
tactical = {
ATTACKAREA = 10,
},
......@@ -29,13 +64,46 @@ newTalent{
local t = {type="ball", range=15, radius=math.min(6, 3 + self:combatSpellpower(0.06))}
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:combatSpellpower(0.7))
self:project(t, x, y, DamageType.FIRE, self:spellCrit(28 + self:combatSpellpower(0.7)))
return true
end,
require = { stat = { mag=16 }, },
require = { stat = { mag=24 }, level=5, },
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:combatSpellpower(0.7), math.min(6, 3 + self:combatSpellpower(0.06)))
end,
}
newTalent{
name = "Inferno",
type = {"spell/fire",4},
mana = 200,
cooldown = 30,
tactical = {
ATTACKAREA = 40,
},
action = function(self)
local duration = 5 + self:combatSpellpower(0.25)
local radius = 5
local dam = 15 + self:combatSpellpower(0.25)
local t = {type="ball", range=20, 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.NETHERFLAME, dam,
radius,
5, nil,
engine.Entity.new{alpha=100, display='', color_br=180, color_bg=30, color_bb=60}
)
return true
end,
require = { stat = { mag=34 }, level=2},
info = function(self)
return ([[Raging flames burn foes and allies alike doing %0.2f netherflame damage in a radius of 5 each turns for %d turns.
Cooldown: 8 turns
The damage and duration will increase with the Magic stat]]):format(15 + self:combatSpellpower(0.25), 5 + self:combatSpellpower(0.25))
end,
}
......@@ -26,7 +26,7 @@ newTalent{
HEAL = 10,
},
action = function(self)
self:heal(10 + self:combatSpellpower(2), self)
self:heal(self:spellCrit(10 + self:combatSpellpower(2)), self)
return true
end,
require = { stat = { mag=20 }, },
......
......@@ -42,3 +42,16 @@ newEffect{
self:removeTemporaryValue("life_regen", eff.tmpid)
end,
}
newEffect{
name = "BURNING",
desc = "Burning",
type = "magical",
status = "detrimental",
parameters = { power=10 },
on_gain = function(self, err) return "#Target# is on fire!", "+Burn" end,
on_lose = function(self, err) return "#Target# stops burning.", "-Burn" end,
on_timeout = function(self, eff)
DamageType:get(DamageType.FIRE).projector(eff.src, self.x, self.y, DamageType.FIRE, eff.power)
end,
}
No preview for this file type
No preview for this file type
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