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

player run!

git-svn-id: http://svn.net-core.org/repos/t-engine4@222 51575b47-30f0-44d4-a5cc-537603b46e54
parent ebe69f9d
No related branches found
No related tags found
No related merge requests found
...@@ -62,6 +62,13 @@ function _M:move(x, y, force) ...@@ -62,6 +62,13 @@ function _M:move(x, y, force)
return true return true
end end
--- Moves into the given direction (calls actor:move() internally)
function _M:moveDir(dir)
local dx, dy = dir_to_coord[dir][1], dir_to_coord[dir][2]
local x, y = self.x + dx, self.y + dy
return self:move(x, y)
end
--- Can the actor go there --- Can the actor go there
-- @param terrain_only if true checks only the terrain, otherwise checks all entities -- @param terrain_only if true checks only the terrain, otherwise checks all entities
function _M:canMove(x, y, terrain_only) function _M:canMove(x, y, terrain_only)
......
...@@ -40,7 +40,7 @@ end ...@@ -40,7 +40,7 @@ end
-- Rewrite this method to check for mana, life, whatever. By default we alawys return false so resting will never work -- Rewrite this method to check for mana, life, whatever. By default we alawys return false so resting will never work
-- @return true if we can continue to rest, false otherwise -- @return true if we can continue to rest, false otherwise
function _M:restCheck() function _M:restCheck()
return false return false, "player:restCheck() method not defined"
end end
--- Stops resting --- Stops resting
......
require "engine.class"
local Dialog = require "engine.Dialog"
--- Handles player running
-- This should work for running inside tunnel, alongside walls, in open spaces.<br/>
module(..., package.seeall, class.make)
local sides =
{
[1] = {left=2, right=4},
[2] = {left=3, right=1},
[3] = {left=6, right=2},
[4] = {left=1, right=7},
[6] = {left=9, right=3},
[7] = {left=4, right=8},
[8] = {left=7, right=9},
[9] = {left=8, right=6},
}
local turn =
{
[1] = {left=3, right=7},
[2] = {left=6, right=4},
[3] = {left=9, right=1},
[4] = {left=2, right=8},
[6] = {left=8, right=2},
[7] = {left=1, right=9},
[8] = {left=4, right=6},
[9] = {left=7, right=3},
}
local function checkDir(a, dir, dist)
dist = dist or 1
local dx, dy = dir_to_coord[dir][1], dir_to_coord[dir][2]
local x, y = a.x + dx * dist, a.y + dy * dist
return game.level.map:checkAllEntities(x, y, "block_move", a) and true or false
end
--- Initializes running
-- We check the direction sides to know if we are in a tunnel, along a wall or in open space.
function _M:runInit(dir)
local block_left, block_right = false, false
-- Check sides
if checkDir(self, sides[dir].left) then block_left = true end
if checkDir(self, sides[dir].right) then block_right = true end
self.running = {
dir = dir,
block_left = block_left,
block_right = block_right,
cnt = 1,
-- dialog = Dialog:simplePopup("Resting...", "You are running, press any key to stop.", function()
-- self:runStop()
-- end),
}
print("run", dir, block_left, block_right)
self:runStep()
end
--- Run a turn
-- For a turn based game you want in you player's act() something like that:<br/>
-- <pre>
-- if not self:runStep() then game.paused = true end
-- </pre><br/>
-- This will move the actor using the :move() method, this SHOULD have been redefined by the module
-- to use energy, otherwise running will be free.
-- @return true if we can continue to run, false otherwise
function _M:runStep()
if not self.running then return false end
local ret, msg = self:runCheck()
if not ret then
self:runStop(msg)
return false
else
self:moveDir(self.running.dir)
self.running.cnt = self.running.cnt + 1
if self.running.newdir then
self.running.dir = self.running.newdir
self.running.newdir = nil
end
if self.running.ignore_left then
self.running.ignore_left = self.running.ignore_left - 1
if self.running.ignore_left <= 0 then self.running.ignore_left = nil end
end
if self.running.ignore_right then
self.running.ignore_right = self.running.ignore_right - 1
if self.running.ignore_right <= 0 then self.running.ignore_right = nil end
end
return true
end
end
--- Can we continue running ?
-- Rewrite this method to hostiles, interresting terrain, whatever.
-- This method should be called by its submethod, it tries to detect changes in the terrain.<br/>
-- It will also try to follow tunnels when they simply change direction.
-- @return true if we can continue to run, false otherwise
function _M:runCheck()
-- Do we change run direction ? We can only choose to change for left or right, never backwards.
-- We must also be in a tunnel (both sides blocked)
if self.running.block_left and self.running.block_right then
-- Turn left
if not checkDir(self, self.running.dir) and checkDir(self, self.running.dir, 2) and not checkDir(self, sides[self.running.dir].left) and checkDir(self, sides[self.running.dir].right) then
self.running.newdir = turn[self.running.dir].left
self.running.ignore_left = 2
print("will turn left")
return true
end
-- Turn right
if not checkDir(self, self.running.dir) and checkDir(self, self.running.dir, 2) and checkDir(self, sides[self.running.dir].left) and not checkDir(self, sides[self.running.dir].right) then
self.running.newdir = turn[self.running.dir].right
self.running.ignore_right = 2
print("will turn right")
return true
end
end
if not self.running.ignore_left and self.running.block_left ~= checkDir(self, sides[self.running.dir].left) then return false, "terrain change on left side" end
if not self.running.ignore_right and self.running.block_right ~= checkDir(self, sides[self.running.dir].right) then return false, "terrain change on right side" end
if checkDir(self, self.running.dir) then return false, "terrain ahead blocks" end
return true
end
--- Stops running
function _M:runStop(msg)
if not self.running then return false end
-- game:unregisterDialog(self.running.dialog)
if msg then
game.log("Ran for %d turns (stop reason: %s).", self.running.cnt, msg)
end
self.running = nil
return true
end
--- Scan the run direction and sides with the given function
function _M:runScan(fct)
-- Ahead
local dx, dy = dir_to_coord[self.running.dir][1], dir_to_coord[self.running.dir][2]
local x, y = self.x + dx, self.y + dy
fct(x, y)
-- Ahead left
local dx, dy = dir_to_coord[sides[self.running.dir].left][1], dir_to_coord[sides[self.running.dir].left][2]
local x, y = self.x + dx, self.y + dy
fct(x, y)
-- Ahead right
local dx, dy = dir_to_coord[sides[self.running.dir].right][1], dir_to_coord[sides[self.running.dir].right][2]
local x, y = self.x + dx, self.y + dy
fct(x, y)
end
...@@ -297,7 +297,7 @@ function _M:setupCommands() ...@@ -297,7 +297,7 @@ function _M:setupCommands()
[{"_DOWN","shift"}] = function() self.target:freemove(2) end, [{"_DOWN","shift"}] = function() self.target:freemove(2) end,
[{"_KP4","shift"}] = function() self.target:freemove(4) end, [{"_KP4","shift"}] = function() self.target:freemove(4) end,
[{"_KP6","shift"}] = function() self.target:freemove(6) end, [{"_KP6","shift"}] = function() self.target:freemove(6) end,
[{"_KP8","shift"}] = function() self.target:freemove(7) end, [{"_KP8","shift"}] = function() self.target:freemove(8) end,
[{"_KP2","shift"}] = function() self.target:freemove(2) end, [{"_KP2","shift"}] = function() self.target:freemove(2) end,
[{"_KP1","shift"}] = function() self.target:freemove(1) end, [{"_KP1","shift"}] = function() self.target:freemove(1) end,
[{"_KP3","shift"}] = function() self.target:freemove(3) end, [{"_KP3","shift"}] = function() self.target:freemove(3) end,
...@@ -338,6 +338,20 @@ function _M:setupCommands() ...@@ -338,6 +338,20 @@ function _M:setupCommands()
_RIGHTPAREN = function() self.player:activateHotkey(11) end, _RIGHTPAREN = function() self.player:activateHotkey(11) end,
_EQUALS = function() self.player:activateHotkey(12) end, _EQUALS = function() self.player:activateHotkey(12) end,
-- running
[{"_LEFT","shift"}] = function() self.player:runInit(4) end,
[{"_RIGHT","shift"}] = function() self.player:runInit(6) end,
[{"_UP","shift"}] = function() self.player:runInit(8) end,
[{"_DOWN","shift"}] = function() self.player:runInit(2) end,
[{"_KP4","shift"}] = function() self.player:runInit(4) end,
[{"_KP6","shift"}] = function() self.player:runInit(6) end,
[{"_KP8","shift"}] = function() self.player:runInit(8) end,
[{"_KP2","shift"}] = function() self.player:runInit(2) end,
[{"_KP1","shift"}] = function() self.player:runInit(1) end,
[{"_KP3","shift"}] = function() self.player:runInit(3) end,
[{"_KP7","shift"}] = function() self.player:runInit(7) end,
[{"_KP9","shift"}] = function() self.player:runInit(9) end,
-- resting -- resting
[{"_r","shift"}] = function() [{"_r","shift"}] = function()
self.player:restInit() self.player:restInit()
......
require "engine.class" require "engine.class"
require "mod.class.Actor" require "mod.class.Actor"
require "engine.interface.PlayerRest" require "engine.interface.PlayerRest"
require "engine.interface.PlayerRun"
local Savefile = require "engine.Savefile" local Savefile = require "engine.Savefile"
local Map = require "engine.Map" local Map = require "engine.Map"
local Dialog = require "engine.Dialog" local Dialog = require "engine.Dialog"
local ActorTalents = require "engine.interface.ActorTalents" local ActorTalents = require "engine.interface.ActorTalents"
module(..., package.seeall, class.inherit(mod.class.Actor, engine.interface.PlayerRest)) --- Defines the player for ToME
-- It is a normal actor, with some redefined methods to handle user interaction.<br/>
-- It is also able to run and rest.
module(..., package.seeall, class.inherit(
mod.class.Actor,
engine.interface.PlayerRest,
engine.interface.PlayerRun
))
function _M:init(t, no_default) function _M:init(t, no_default)
t.body = { t.body = {
...@@ -74,8 +82,8 @@ function _M:act() ...@@ -74,8 +82,8 @@ function _M:act()
-- Clean log flasher -- Clean log flasher
game.flash:empty() game.flash:empty()
-- Resting ? -- Resting ? Running ? Otherwise pause
if not self:restStep() then if not self:restStep() and not self:runStep() then
game.paused = true game.paused = true
end end
end end
...@@ -148,16 +156,20 @@ function _M:activateHotkey(id) ...@@ -148,16 +156,20 @@ function _M:activateHotkey(id)
end end
end end
--- Can we continue resting ? local function spotHostiles(self)
-- We can rest if no hostiles are in sight, and if we need life/mana/stamina (and their regen rates allows them to fully regen)
function _M:restCheck()
local seen = false local seen = false
-- Check for visible monsters, only see LOS actors, so telepathy wont prevent resting -- Check for visible monsters, only see LOS actors, so telepathy wont prevent resting
core.fov.calc_circle(self.x, self.y, 20, game.level.map.opaque, function(map, x, y) core.fov.calc_circle(self.x, self.y, 20, game.level.map.opaque, function(map, x, y)
local actor = map(x, y, map.ACTOR) local actor = map(x, y, map.ACTOR)
if actor and self:reactionToward(actor) < 0 and self:canSee(actor) then seen = true end if actor and self:reactionToward(actor) < 0 and self:canSee(actor) then seen = true end
end, game.level.map) end, game.level.map)
if seen then return false, "hostile spotted" end return seen
end
--- Can we continue resting ?
-- We can rest if no hostiles are in sight, and if we need life/mana/stamina (and their regen rates allows them to fully regen)
function _M:restCheck()
if spotHostiles(self) then return false, "hostile spotted" end
-- Check ressources, make sure they CAN go up, otherwise we will never stop -- Check ressources, make sure they CAN go up, otherwise we will never stop
if self:getMana() < self:getMaxMana() and self.mana_regen > 0 then return true end if self:getMana() < self:getMaxMana() and self.mana_regen > 0 then return true end
...@@ -166,3 +178,24 @@ function _M:restCheck() ...@@ -166,3 +178,24 @@ function _M:restCheck()
return false, "all resources and life at maximun" return false, "all resources and life at maximun"
end end
--- Can we continue running?
-- We can run if no hostiles are in sight, and if we no interresting terrains are next to us
function _M:runCheck()
if spotHostiles(self) then return false, "hostile spotted" end
-- Notice any noticable terrain
local noticed = false
self:runScan(function(x, y)
-- Only notice interresting terrains
local grid = game.level.map(x, y, Map.TERRAIN)
if grid and grid.notice then noticed = "interresting terrain" end
-- Objects are always interresting
local obj = game.level.map:getObject(x, y, 1)
if obj then noticed = "object seen" end
end)
if noticed then return false, noticed end
return engine.interface.PlayerRun.runCheck(self)
end
...@@ -3,6 +3,7 @@ newEntity{ ...@@ -3,6 +3,7 @@ newEntity{
name = "exit to the wilds", name = "exit to the wilds",
display = '<', color_r=255, color_g=0, color_b=255, display = '<', color_r=255, color_g=0, color_b=255,
always_remember = true, always_remember = true,
notice = true,
change_level = 1, change_level = 1,
change_zone = "wilderness", change_zone = "wilderness",
} }
...@@ -11,6 +12,7 @@ newEntity{ ...@@ -11,6 +12,7 @@ newEntity{
define_as = "UP", define_as = "UP",
name = "previous level", name = "previous level",
display = '<', color_r=255, color_g=255, color_b=0, display = '<', color_r=255, color_g=255, color_b=0,
notice = true,
always_remember = true, always_remember = true,
change_level = -1, change_level = -1,
} }
...@@ -19,6 +21,7 @@ newEntity{ ...@@ -19,6 +21,7 @@ newEntity{
define_as = "DOWN", define_as = "DOWN",
name = "next level", name = "next level",
display = '>', color_r=255, color_g=255, color_b=0, display = '>', color_r=255, color_g=255, color_b=0,
notice = true,
always_remember = true, always_remember = true,
change_level = 1, change_level = 1,
} }
...@@ -43,6 +46,7 @@ newEntity{ ...@@ -43,6 +46,7 @@ newEntity{
define_as = "DOOR", define_as = "DOOR",
name = "door", image = "terrain/granite_door1.png", name = "door", image = "terrain/granite_door1.png",
display = '+', color_r=238, color_g=154, color_b=77, display = '+', color_r=238, color_g=154, color_b=77,
notice = true,
always_remember = true, always_remember = true,
block_sight = true, block_sight = true,
door_opened = "DOOR_OPEN", door_opened = "DOOR_OPEN",
......
...@@ -5,7 +5,7 @@ newTalent{ ...@@ -5,7 +5,7 @@ newTalent{
points = 5, points = 5,
require = { stat = { dex=14 } }, require = { stat = { dex=14 } },
info = function(self, t) info = function(self, t)
return ([[Reduces the damage penality of the off-hand weapon to %d%%]]):format(100 / (2 - self:getTalentLevel(t) / 6)) return ([[Increases the damage of the off-hand weapon to %d%%.]]):format(100 / (2 - self:getTalentLevel(t) / 6))
end, 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