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

lasting spell effects

noxious cloud


git-svn-id: http://svn.net-core.org/repos/t-engine4@77 51575b47-30f0-44d4-a5cc-537603b46e54
parent 7f500223
No related branches found
No related tags found
No related merge requests found
......@@ -23,6 +23,12 @@ function _M:tick()
while not self.paused do
engine.GameEnergyBased.tick(self)
self.turn = self.turn + 1
self:onTurn()
end
end
end
--- Called every game turns
-- Does nothing, you can override it
function _M:onTurn()
end
......@@ -2,6 +2,7 @@ require "engine.class"
local Entity = require "engine.Entity"
local Tiles = require "engine.Tiles"
local Faction = require "engine.Faction"
local DamageType = require "engine.DamageType"
--- Represents a level map, handles display and various low level map work
module(..., package.seeall, class.make)
......@@ -55,6 +56,7 @@ function _M:init(w, h)
self.lites = {}
self.seens = {}
self.remembers = {}
self.effects = {}
for i = 0, w * h - 1 do self.map[i] = {} end
self:loaded()
......@@ -223,6 +225,9 @@ function _M:display()
end end
]]
end
self:displayEffects()
return self.surface
end
......@@ -345,3 +350,78 @@ function _M:isBound(x, y)
if x < 0 or x >= self.w or y < 0 or y >= self.h then return false end
return true
end
--- Adds a zone (temporary) effect
-- @param src the source actor
-- @param x the epicenter coords
-- @param y the epicenter coords
-- @param duration the number of turns to persist
-- @param damtype the DamageType to apply
-- @param radius the radius of the effect
-- @param dir the numpad direction of the effect, 5 for a ball effect
-- @param overlay a simple display entity to draw upon the map
function _M:addEffect(src, x, y, duration, damtype, dam, radius, dir, angle, overlay, update_fct)
table.insert(self.effects, {
src=src, x=x, y=y, duration=duration, damtype=damtype, dam=dam, radius=radius, dir=dir, angle=angle, overlay=overlay,
update_fct=update_fct,
})
self.changed = true
end
--- Display the overlay effects, called by self:display()
function _M:displayEffects()
for i, e in ipairs(self.effects) do
local grids
local s = self.tiles:get(e.overlay.display, e.overlay.color_r, e.overlay.color_g, e.overlay.color_b, e.overlay.color_br, e.overlay.color_bg, e.overlay.color_bb, e.overlay.image)
s:alpha(e.alpha or 150)
-- Handle balls
if e.dir == 5 then
grids = core.fov.circle_grids(e.x, e.y, e.radius, true)
-- Handle beams
else
grids = core.fov.beam_grids(e.x, e.y, e.radius, e.dir, e.angle, true)
end
-- Now display each grids
for lx, ys in pairs(grids) do
for ly, _ in pairs(ys) do
if self.seens(lx, ly) then
self.surface:merge(s, (lx - self.mx) * self.tile_w, (ly - self.my) * self.tile_h)
end
end
end
end
end
--- Process the overlay effects, call it from your tick function
function _M:processEffects()
local todel = {}
for i, e in ipairs(self.effects) do
local grids
-- Handle balls
if e.dir == 5 then
grids = core.fov.circle_grids(e.x, e.y, e.radius, true)
-- Handle beams
else
grids = core.fov.beam_grids(e.x, e.y, e.radius, e.dir, e.angle, true)
end
-- Now display each grids
for lx, ys in pairs(grids) do
for ly, _ in pairs(ys) do
DamageType:get(e.damtype).projector(e.src, lx, ly, e.damtype, e.dam)
end
end
e.duration = e.duration - 1
if e.duration <= 0 then
table.insert(todel, i)
elseif e.update_fct then
e:update_fct()
end
end
for i = #todel, 1, -1 do table.remove(self.effects, todel[i]) end
end
......@@ -199,3 +199,35 @@ function util.bound(i, min, max)
elseif i > max then i = max end
return i
end
function core.fov.circle_grids(x, y, radius, block)
local grids = {}
core.fov.calc_circle(x, y, radius, function(self, lx, ly)
if not grids[lx] then grids[lx] = {} end
grids[lx][ly] = true
if block and game.level.map:checkEntity(lx, ly, engine.Map.TERRAIN, "block_move") then return true end
end, function()end, self)
-- point of origin
if not grids[x] then grids[x] = {} end
grids[x][y] = true
return grids
end
function core.fov.beam_grids(x, y, radius, dir, angle, block)
local grids = {}
core.fov.calc_beam(x, y, radius, dir, angle, function(self, lx, ly)
if not grids[lx] then grids[lx] = {} end
grids[lx][ly] = true
if block and game.level.map:checkEntity(lx, ly, engine.Map.TERRAIN, "block_move") then return true end
end, function()end, self)
-- point of origin
if not grids[x] then grids[x] = {} end
grids[x][y] = true
return grids
end
......@@ -81,7 +81,7 @@ function _M:levelup()
-- Healp up on new level
self.life = self.max_life
self.mana = self.max_mana
self.stamina = self.man_stamina
self.stamina = self.max_stamina
-- Auto levelup ?
if self.autolevel then
......
......@@ -124,6 +124,16 @@ function _M:tick()
-- Fun stuff: this can make the game realtime, although callit it in display() will make it work better
-- (since display is on a set FPS while tick() ticks as much as possible
-- engine.GameEnergyBased.tick(self)
end
--- Called every game turns
-- Does nothing, you can override it
function _M:onTurn()
-- The following happens only every 10 game turns (once for every turn of 1 mod speed actors)
if self.turn % 10 ~= 0 then return end
-- Process overlay effects
self.level.map:processEffects()
if not self.day_of_year or self.day_of_year ~= self.calendar:getDayOfYear(self.turn) then
self.log(self.calendar:getTimeDate(self.turn))
......@@ -259,6 +269,9 @@ function _M:setupCommands()
_a = function()
self.player:useTalent(ActorTalents.T_FIREFLASH)
end,
_e = function()
self.player:useTalent(ActorTalents.T_NOXIOUS_CLOUD)
end,
_z = function()
self.player:useTalent(ActorTalents.T_BLINK)
end,
......
......@@ -147,3 +147,37 @@ newTalent{
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,
}
......@@ -7,6 +7,7 @@ return {
autolevel = "warrior",
max_life = 20,
max_mana = 1000,
max_stamina = 1000,
energy = { mod=0.5 },
has_blood = true,
stats = { str=15, dex=8, mag=12, },
......@@ -20,6 +21,7 @@ return {
autolevel = "caster",
max_life = 30,
max_mana = 1000,
max_stamina = 1000,
energy = { mod=0.3 },
has_blood = {nb=3, color={50,255,120}},
combat = { dam=5, atk=6, def=2, apr=1, armor=2},
......
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