From ddaf6b900053cf34be36a03b3d8688d3a85a508b Mon Sep 17 00:00:00 2001 From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54> Date: Sat, 28 Nov 2009 00:14:17 +0000 Subject: [PATCH] better targetting manathrust works excusive targetting mode targetting with display of future damage projection damage projection git-svn-id: http://svn.net-core.org/repos/t-engine4@55 51575b47-30f0-44d4-a5cc-537603b46e54 --- game/engine/Actor.lua | 1 + game/engine/GameEnergyBased.lua | 1 - game/engine/KeyCommand.lua | 3 + game/engine/Level.lua | 5 + game/engine/Map.lua | 7 + game/engine/Module.lua | 1 + game/engine/Target.lua | 77 ++++++-- game/engine/init.lua | 5 - game/engine/interface/ActorAbilities.lua | 25 ++- game/modules/tome/class/Actor.lua | 26 ++- game/modules/tome/class/Game.lua | 172 ++++++++++-------- game/modules/tome/class/Player.lua | 19 ++ game/modules/tome/class/interface/Combat.lua | 32 +++- game/modules/tome/data/abilities.lua | 13 +- game/modules/tome/data/damage_types.lua | 2 +- .../tome/data/zones/ancient_ruins/zone.lua | 6 +- 16 files changed, 282 insertions(+), 113 deletions(-) diff --git a/game/engine/Actor.lua b/game/engine/Actor.lua index 980bd7324c..b11b2dc40b 100644 --- a/game/engine/Actor.lua +++ b/game/engine/Actor.lua @@ -47,6 +47,7 @@ end function _M:useEnergy(val) val = val or game.energy_to_act self.energy.value = self.energy.value - val + if self.player and self.energy.value < game.energy_to_act then game.paused = false end end --- What is our reaction toward the target diff --git a/game/engine/GameEnergyBased.lua b/game/engine/GameEnergyBased.lua index 437475fda6..b750ef2292 100644 --- a/game/engine/GameEnergyBased.lua +++ b/game/engine/GameEnergyBased.lua @@ -24,7 +24,6 @@ function _M:tick() for uid, e in pairs(self.level.entities) do if e.energy and e.energy.value < self.energy_to_act then e.energy.value = (e.energy.value or 0) + self.energy_per_tick * (e.energy.mod or 1) --- print(e.uid, e.energy.value) if e.energy.value >= self.energy_to_act and e.act then e:act(self) end diff --git a/game/engine/KeyCommand.lua b/game/engine/KeyCommand.lua index 54a67c41dd..b158990005 100644 --- a/game/engine/KeyCommand.lua +++ b/game/engine/KeyCommand.lua @@ -8,6 +8,9 @@ function _M:init() engine.Key.init(self) self.commands = {} self.on_input = false + + -- Fullscreen toggle + self:addCommand(self._RETURN, {"alt"}, function() core.display.fullscreen() end) end function _M:receiveKey(sym, ctrl, shift, alt, meta, unicode) diff --git a/game/engine/Level.lua b/game/engine/Level.lua index aaa8de905c..a2f6ae0d46 100644 --- a/game/engine/Level.lua +++ b/game/engine/Level.lua @@ -25,6 +25,11 @@ function _M:removeEntity(e) if e.deleteFromMap then e:deleteFromMap(self.map) end end +--- Is the entity on the level? +function _M:hasEntity(e) + return self.entities[e.uid] +end + function _M:loaded() -- Loading the game has defined new uids for entities, yet we hard referenced the old ones -- So we fix it diff --git a/game/engine/Map.lua b/game/engine/Map.lua index 9ebbe2b5f8..49ede6760c 100644 --- a/game/engine/Map.lua +++ b/game/engine/Map.lua @@ -310,3 +310,10 @@ function _M:checkMapViewBounded() if self.my > self.h - self.viewport.mheight then self.my = self.h - self.viewport.mheight self.changed = true end end +--- Gets the tile under the mouse +function _M:getMouseTile(mx, my) +-- if mx < self.display_x or my < self.display_y or mx >= self.display_x + self.viewport.width or my >= self.display_y + self.viewport.height then return end + local tmx = math.floor((mx - self.display_x) / self.tile_w) + self.mx + local tmy = math.floor((my - self.display_y) / self.tile_h) + self.my + return tmx, tmy +end diff --git a/game/engine/Module.lua b/game/engine/Module.lua index 1baa31687b..98dfe7b4c7 100644 --- a/game/engine/Module.lua +++ b/game/engine/Module.lua @@ -38,6 +38,7 @@ function _M:loadDefinition(dir) -- Make a function to activate it mod.load = function() + core.display.setWindowTitle(mod.long_name) self:setupWrite(mod) fs.mount(fs.getRealPath(dir), "/mod", false); fs.mount(fs.getRealPath(dir).."/data/", "/data", false); diff --git a/game/engine/Target.lua b/game/engine/Target.lua index 63854dcb95..5c8f843f73 100644 --- a/game/engine/Target.lua +++ b/game/engine/Target.lua @@ -8,15 +8,19 @@ function _M:init(map, source_actor) self.w, self.h = map.viewport.width, map.viewport.height self.tile_w, self.tile_h = map.tile_w, map.tile_h self.active = false + self.target_type = {} self.cursor = core.display.loadImage(engine.Tiles.prefix.."target_cursor.png") self.sr = core.display.newSurface(map.tile_w, map.tile_h) - self.sr:alpha(125) + self.sr:alpha(90) self.sr:erase(255, 0, 0) self.sb = core.display.newSurface(map.tile_w, map.tile_h) - self.sb:alpha(125) + self.sb:alpha(90) self.sb:erase(0, 0, 255) + self.sg = core.display.newSurface(map.tile_w, map.tile_h) + self.sg:alpha(90) + self.sg:erase(0, 255, 0) self.source_actor = source_actor @@ -25,7 +29,7 @@ function _M:init(map, source_actor) -- but it means if the entity field is set to an entity, when it disappears this link wont prevent -- the garbage collection self.target = {x=self.source_actor.x, y=self.source_actor.y, entity=nil} - setmetatable(self.target, {__mode='v'}) +-- setmetatable(self.target, {__mode='v'}) end function _M:display() @@ -42,43 +46,88 @@ function _M:display() local lx, ly = l() while lx and ly do if not game.level.map.seens(lx, ly) then s = self.sr end + if self.target_type.stop_block and game.level.map:checkAllEntities(lx, ly, "block_move") then s = self.sr end + if self.target_type.range and math.sqrt((self.source_actor.x-lx)^2 + (self.source_actor.y-ly)^2) > self.target_type.range then s = self.sr end s:toScreen(self.display_x + (lx - game.level.map.mx) * self.tile_w, self.display_y + (ly - game.level.map.my) * self.tile_h) lx, ly = l() end self.cursor:toScreen(self.display_x + (self.target.x - game.level.map.mx) * self.tile_w, self.display_y + (self.target.y - game.level.map.my) * self.tile_h) + + if self.target_type.ball and s == self.sb then + core.fov.calc_circle(self.target.x, self.target.y, self.target_type.ball, function(self, lx, ly) + self.sg:toScreen(self.display_x + (lx - game.level.map.mx) * self.tile_w, self.display_y + (ly - game.level.map.my) * self.tile_h) + end, function()end, self) + end end -function _M:setActive(v) +--- Returns data for the given target type +-- Hit: simple project in LOS<br/> +-- Beam: hits everything in LOS<br/> +-- Bolt: hits first thing in path<br/> +-- Ball: hits everything in a ball aounrd the target<br/> +-- Cone: hits everything in a cone in the direction<br/> +function _M:getType(t) + if not t or not t.type then return {} end + t.range = t.range or 20 + if t.type == "hit" then + return {range=t.range} + elseif t.type == "beam" then + return {range=t.range, line=true} + elseif t.type == "bolt" then + return {range=t.range, stop_block=true} + elseif t.type == "ball" then + return {range=t.range, ball=t.radius} + elseif t.type == "cone" then + return {range=t.range, cone=t.radius} + else + return {} + end +end + +function _M:setActive(v, type) if v == nil then return self.active else self.active = v + if v and type then + self.target_type = self:getType(type) + else + self.target_type = {} + end end end -function _M:scan(dir, radius) +function _M:scan(dir, radius, sx, sy) + sx = sx or self.target.x + sy = sy or self.target.y radius = radius or 20 local actors = {} local checker = function(self, x, y) - if game.level.map.seens(x, y) and game.level.map(x, y, engine.Map.ACTOR) then - table.insert(actors, { - a = game.level.map(x, y, engine.Map.ACTOR), - dist = math.abs(self.target.x - x)*math.abs(self.target.x - x) + math.abs(self.target.y - y)*math.abs(self.target.y - y) - }) - end - return false + if sx == x and sy == y then return false end + if game.level.map.seens(x, y) and game.level.map(x, y, engine.Map.ACTOR) then + local a = game.level.map(x, y, engine.Map.ACTOR) + + table.insert(actors, { + a = a, + dist = math.abs(sx - x)*math.abs(sx - x) + math.abs(sy - y)*math.abs(sy - y) + }) + actors[a] = true + end + return false end if dir ~= 5 then -- Get a list of actors in the direction given - core.fov.calc_beam(self.target.x, self.target.y, radius, dir, 55, checker, function()end, self) + core.fov.calc_beam(sx, sy, radius, dir, 55, checker, function()end, self) else -- Get a list of actors all around - core.fov.calc_circle(self.target.x, self.target.y, radius, checker, function()end, self) + core.fov.calc_circle(sx, sy, radius, checker, function()end, self) end table.sort(actors, function(a,b) return a.dist<b.dist end) if #actors > 0 then self.target.entity = actors[1].a + self.target.x = self.target.entity.x + self.target.y = self.target.entity.y end end diff --git a/game/engine/init.lua b/game/engine/init.lua index 3f129c9f92..8705b87e24 100644 --- a/game/engine/init.lua +++ b/game/engine/init.lua @@ -15,11 +15,6 @@ engine.Tiles.prefix = "/data/gfx/" local key = engine.KeyCommand.new() key:setCurrent() --- Exit the game, this is brutal for now -key:addCommand(key._x, {"ctrl"}, function() os.exit() end) --- Fullscreen toggle -key:addCommand(key._RETURN, {"alt"}, function() core.display.fullscreen() end) - -- Load the game module game = false diff --git a/game/engine/interface/ActorAbilities.lua b/game/engine/interface/ActorAbilities.lua index 18cf5b871b..c05a875026 100644 --- a/game/engine/interface/ActorAbilities.lua +++ b/game/engine/interface/ActorAbilities.lua @@ -55,6 +55,29 @@ function _M:useAbility(id) assert(ab, "trying to cast ability "..tostring(id).." but it is not defined") if ab.action then - ab.action(self) + if not self:preUseAbility(ab) then return end + local co = coroutine.create(function() + local ret = ab.action(self) + + if not self:postUseAbility(ab, ret) then return end + end) + coroutine.resume(co) end end + +--- Called before an ability is used +-- Redefine as needed +-- @param ab the ability (not the id, the table) +-- @return true to continue, false to stop +function _M:preUseAbility(ab) + return true +end + +--- Called before an ability is used +-- Redefine as needed +-- @param ab the ability (not the id, the table) +-- @param ret the return of the ability action +-- @return true to continue, false to stop +function _M:postUseAbility(ab, ret) + return true +end diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index 254e56e896..6ac0f4ea28 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -30,7 +30,7 @@ function _M:move(x, y, force) local moved = false if force or self:enoughEnergy() then moved = engine.Actor.move(self, game.level.map, x, y, force) - if not force then self:useEnergy() end + if not force and moved then self:useEnergy() end end return moved end @@ -55,3 +55,27 @@ end function _M:attack(target) self:bumpInto(target) end + +--- Tries to get a target from the user +function _M:getTarget() + return self.target.x, self.target.y +end + +--- Called before an ability is used +-- Check the actor can cast it +-- @param ab the ability (not the id, the table) +-- @return true to continue, false to stop +function _M:preUseAbility(ab) + return self:enoughEnergy() +end + +--- Called before an ability is used +-- Check if it must use a turn, mana, stamina, ... +-- @param ab the ability (not the id, the table) +-- @param ret the return of the ability action +-- @return true to continue, false to stop +function _M:postUseAbility(ab, ret) + if ret == nil then return end + self:useEnergy() + return true +end diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index a9ce7476cf..28f9763439 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -100,6 +100,8 @@ end function _M:tick() + if self.target.target.entity and not self.level:hasEntity(self.target.target.entity) then self.target.target.entity = false end + engine.GameTurnBased.tick(self) if not self.day_of_year or self.day_of_year ~= self.calendar:getDayOfYear(self.turn) then @@ -124,7 +126,7 @@ function _M:display() -- Display a tooltip if available local mx, my = core.mouse.get() - local tmx, tmy = math.floor((mx - Map.display_x) / self.level.map.tile_w) + self.level.map.mx, math.floor((my - Map.display_y) / self.level.map.tile_h) + self.level.map.my + local tmx, tmy = self.level.map:getMouseTile(mx, my) local tt = self.level.map:checkAllEntities(tmx, tmy, "tooltip") if tt and self.level.map.seens(tmx, tmy) then self.tooltip:set(tt) @@ -144,29 +146,88 @@ function _M:display() engine.GameTurnBased.display(self) end -function _M:targetMode(v, msg) +function _M:targetMode(v, msg, co, typ) if not v then Map:setViewerFaction(nil) - if msg then self.log("Tactical display disabled. Press 't' or right mouse click to enable.") end + if msg then self.log(type(msg) == "string" and msg or "Tactical display disabled. Press 't' or right mouse click to enable.") end self.level.map.changed = true self.target:setActive(false) + + if tostring(self.target_mode) == "exclusive" then + self.key = self.normal_key + self.key:setCurrent() + if self.target_co then + local co = self.target_co + self.target_co = nil + local ok, err = coroutine.resume(co, self.target.target.x, self.target.target.y) + if not ok and err then error(err) end + end + end else Map:setViewerFaction("players") - if msg then self.log("Tactical display enabled. Press 't' to disable.") end + if msg then self.log(type(msg) == "string" and msg or "Tactical display enabled. Press 't' to disable.") end self.level.map.changed = true - self.target:setActive(true) - end -end + self.target:setActive(true, typ) -function _M:getTarget() - if self.target.target.entity then - return self.target.target.entity.x, self.target.target.entity.y - else - return self.target.target.x, self.target.target.y + -- Exclusive mode means we disable the current key handler and use a specific one + -- that only allows targetting and resumes ability coroutine when done + if tostring(v) == "exclusive" then + self.target_co = co + self.key = self.targetmode_key + self.key:setCurrent() + + if self.target.target.entity and self.level.map.seens(self.target.target.entity.x, self.target.target.entity.y) and self.player ~= self.target.target.entity then + else + self.target:scan(5, nil, self.player.x, self.player.y) + end + end end + self.target_mode = v end function _M:setupCommands() + self.targetmode_key = engine.KeyCommand.new() + self.targetmode_key:addCommands + { + _t = function() + self:targetMode(false, false) + end, + _RETURN = {"alias", "_t"}, + _ESCAPE = function() + self.target.target.entity = nil + self.target.target.x = nil + self.target.target.y = nil + self:targetMode(false, false) + end, + -- Targeting movement + [{"_LEFT","shift"}] = function() self.target.target.entity=nil self.target.target.x = self.target.target.x - 1 end, + [{"_RIGHT","shift"}] = function() self.target.target.entity=nil self.target.target.x = self.target.target.x + 1 end, + [{"_UP","shift"}] = function() self.target.target.entity=nil self.target.target.y = self.target.target.y - 1 end, + [{"_DOWN","shift"}] = function() self.target.target.entity=nil self.target.target.y = self.target.target.y + 1 end, + [{"_KP4","shift"}] = function() self.target.target.entity=nil self.target.target.x = self.target.target.x - 1 end, + [{"_KP6","shift"}] = function() self.target.target.entity=nil self.target.target.x = self.target.target.x + 1 end, + [{"_KP8","shift"}] = function() self.target.target.entity=nil self.target.target.y = self.target.target.y - 1 end, + [{"_KP2","shift"}] = function() self.target.target.entity=nil self.target.target.y = self.target.target.y + 1 end, + [{"_KP1","shift"}] = function() self.target.target.entity=nil self.target.target.x = self.target.target.x - 1 self.target.target.y = self.target.target.y + 1 end, + [{"_KP3","shift"}] = function() self.target.target.entity=nil self.target.target.x = self.target.target.x + 1 self.target.target.y = self.target.target.y + 1 end, + [{"_KP7","shift"}] = function() self.target.target.entity=nil self.target.target.x = self.target.target.x - 1 self.target.target.y = self.target.target.y - 1 end, + [{"_KP9","shift"}] = function() self.target.target.entity=nil self.target.target.x = self.target.target.x + 1 self.target.target.y = self.target.target.y - 1 end, + + _LEFT = function() self.target:scan(4) end, + _RIGHT = function() self.target:scan(6) end, + _UP = function() self.target:scan(8) end, + _DOWN = function() self.target:scan(2) end, + _KP4 = function() self.target:scan(4) end, + _KP6 = function() self.target:scan(6) end, + _KP8 = function() self.target:scan(8) end, + _KP2 = function() self.target:scan(2) end, + _KP1 = function() self.target:scan(1) end, + _KP3 = function() self.target:scan(3) end, + _KP7 = function() self.target:scan(7) end, + _KP9 = function() self.target:scan(9) end, + } + + self.normal_key = self.key self.key:addCommands { -- ability test @@ -174,77 +235,25 @@ function _M:setupCommands() self.player:useAbility(ActorAbilities.AB_MANATHRUST) end, - _LEFT = function() - if self.player:move(self.player.x - 1, self.player.y) then - self.paused = false - end - end, - _RIGHT = function() - if self.player:move(self.player.x + 1, self.player.y) then - self.paused = false - end - end, - _UP = function() - if self.player:move(self.player.x, self.player.y - 1) then - self.paused = false - end - end, - _DOWN = function() - if self.player:move(self.player.x, self.player.y + 1) then - self.paused = false - end - end, - _KP1 = function() - if self.player:move(self.player.x - 1, self.player.y + 1) then - self.paused = false - end - end, - _KP2 = function() - if self.player:move(self.player.x, self.player.y + 1) then - self.paused = false - end - end, - _KP3 = function() - if self.player:move(self.player.x + 1, self.player.y + 1) then - self.paused = false - end - end, - _KP4 = function() - if self.player:move(self.player.x - 1, self.player.y) then - self.paused = false - end - end, - _KP5 = function() - if self.player:move(self.player.x, self.player.y) then - self.paused = false - end - end, - _KP6 = function() - if self.player:move(self.player.x + 1, self.player.y) then - self.paused = false - end - end, - _KP7 = function() - if self.player:move(self.player.x - 1, self.player.y - 1) then - self.paused = false - end - end, - _KP8 = function() - if self.player:move(self.player.x, self.player.y - 1) then - self.paused = false - end - end, - _KP9 = function() - if self.player:move(self.player.x + 1, self.player.y - 1) then - self.paused = false - end - end, + _LEFT = function() self.player:move(self.player.x - 1, self.player.y ) end, + _RIGHT = function() self.player:move(self.player.x + 1, self.player.y ) end, + _UP = function() self.player:move(self.player.x , self.player.y - 1) end, + _DOWN = function() self.player:move(self.player.x , self.player.y + 1) end, + _KP1 = function() self.player:move(self.player.x - 1, self.player.y + 1) end, + _KP2 = function() self.player:move(self.player.x , self.player.y + 1) end, + _KP3 = function() self.player:move(self.player.x + 1, self.player.y + 1) end, + _KP4 = function() self.player:move(self.player.x - 1, self.player.y ) end, + _KP5 = function() self.player:move(self.player.x , self.player.y ) end, + _KP6 = function() self.player:move(self.player.x + 1, self.player.y ) end, + _KP7 = function() self.player:move(self.player.x - 1, self.player.y - 1) end, + _KP8 = function() self.player:move(self.player.x , self.player.y - 1) end, + _KP9 = function() self.player:move(self.player.x + 1, self.player.y - 1) end, + [{"_LESS","anymod"}] = function() local e = self.level.map(self.player.x, self.player.y, Map.TERRAIN) if self.player:enoughEnergy() and e.change_level then -- Do not unpause, the player is allowed first move on next level self:changeLevel(self.level.level + e.change_level) - print(self.level.level) else self.log("There is no way out of this level here.") end @@ -319,17 +328,20 @@ function _M:setupMouse() self.mouse:registerZone(Map.display_x, Map.display_y, Map.viewport.width, Map.viewport.height, function(button, mx, my, xrel, yrel) -- Compute map coordonates if button == "right" then - local tmx, tmy = math.floor((mx - Map.display_x) / self.level.map.tile_w) + self.level.map.mx, math.floor((my - Map.display_x) / self.level.map.tile_h) + self.level.map.my + local tmx, tmy = self.level.map:getMouseTile(mx, my) local actor = self.level.map(tmx, tmy, Map.ACTOR) if actor and self.level.map.seens(tmx, tmy) then self.target.target.entity = actor - self:targetMode(true, true) else self.target.target.entity = nil self.target.target.x = tmx self.target.target.y = tmy + end + if tostring(self.target_mode) == "exclusive" then + self:targetMode(false, false) + else self:targetMode(true, true) end elseif button == "left" and xrel and yrel then diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua index ec9a6372c6..44f6c0306a 100644 --- a/game/modules/tome/class/Player.lua +++ b/game/modules/tome/class/Player.lua @@ -31,3 +31,22 @@ function _M:setName(name) self.name = name game.save_name = name end + +--- Tries to get a target from the user +-- *WARNING* If used inside a coroutine it will yield and resume it later when a target is found. +-- This is usualy just what you want so dont think too much about it :) +function _M:getTarget(typ) + if coroutine.running() then + local msg + if type(typ) == "string" then msg, typ = typ, nil + elseif type(typ) == "table" then msg = typ.msg end + game:targetMode("exclusive", msg, coroutine.running(), typ) + return coroutine.yield() + end + return game.target.target.x, game.target.target.y +end + +--- Quick way to check if the player can see the target +function _M:canSee(entity) + if entity.x and entity.y and game.level.map.seens(entity.x, entity.y) then return true end +end diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 1b75a34d76..d111d1f47f 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -1,6 +1,7 @@ require "engine.class" local DamageType = require "engine.DamageType" local Map = require "engine.Map" +local Target = require "engine.Target" --- Interface to add ToME combat system module(..., package.seeall, class.make) @@ -58,8 +59,35 @@ function _M:attackTarget(target) end --- Project damage to a distance -function _M:project(x, y, type, dam) +function _M:project(t, x, y, damtype, dam) if dam < 0 then return end + local typ = Target:getType(t) - DamageType:get(type).projector(self, x, y, type, dam) + local lx, ly = x, y + if typ.stop_block then + local l = line.new(self.x, self.y, x, y) + lx, ly = l() + while lx and ly do + if typ.stop_block and game.level.map:checkAllEntities(lx, ly, "block_move") then break end + if typ.range and math.sqrt((self.source_actor.x-lx)^2 + (self.source_actor.y-ly)^2) > typ.range then break end + + -- Deam damage: beam + if typ.line then DamageType:get(damtype).projector(self, lx, ly, damtype, dam) end + + lx, ly = l() + end + end + + if typ.ball then + core.fov.calc_circle(lx, ly, typ.ball, function(self, px, py) + -- Deam damage: ball + DamageType:get(damtype).projector(self, px, py, damtype, dam) +-- self.sg:toScreen(self.display_x + (lx - game.level.map.mx) * self.tile_w, self.display_y + (ly - game.level.map.my) * self.tile_h) + end, function()end, self) + DamageType:get(damtype).projector(self, lx, ly, damtype, dam) + elseif typ.cone then + else + -- Deam damage: single + DamageType:get(damtype).projector(self, lx, ly, damtype, dam) + end end diff --git a/game/modules/tome/data/abilities.lua b/game/modules/tome/data/abilities.lua index 19fca6575d..4b75d296b4 100644 --- a/game/modules/tome/data/abilities.lua +++ b/game/modules/tome/data/abilities.lua @@ -1,20 +1,23 @@ -- Mana spells -newAbilityType{ type="spell/mana", name = "mana" } +newAbilityType{ type="spell/arcane", name = "arcane" } newAbility{ name = "Manathrust", - type = "spell/mana", + type = "spell/arcane", mana = 15, tactical = { ATTACK = 10, }, action = function(self) - self:project(game.target.target.x, game.target.target.y, DamageType.MANA, 10 + self:getMag()) + local t = {type="ball", range=20, radius=4} + 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=12 }, }, info = function(self) - return ([[Conjures up mana into a powerful bolt doing %d", - The damage is irresistible and will increase with magic stat]]):format(10 + self:getMag()) + 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 } diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index 8d825a4620..af22895499 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -9,7 +9,7 @@ print(src, x, y, type, dam) end) newDamageType{ - name = "mana", type = "MANA", + name = "arcane", type = "ARCANE", } newDamageType{ name = "fire", type = "FIRE", diff --git a/game/modules/tome/data/zones/ancient_ruins/zone.lua b/game/modules/tome/data/zones/ancient_ruins/zone.lua index 6445bed4ff..9eafda75a4 100644 --- a/game/modules/tome/data/zones/ancient_ruins/zone.lua +++ b/game/modules/tome/data/zones/ancient_ruins/zone.lua @@ -1,14 +1,13 @@ return { name = "ancient ruins", max_level = 5, - width = 50, height = 30, + width = 40, height = 30, all_remembered = true, all_lited = true, persistant = true, - level_npcs = {5, 10}, generator = { map = { - class= "engine.generator.map.Rooms", + class= "engine.generator.map.Empty", floor = "FLOOR", wall = "WALL", up = "UP", @@ -18,6 +17,7 @@ return { actor = { class = "engine.generator.actor.Random", nb_npc = {40, 40}, + levelup = {5, 10}, }, } } -- GitLab