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)
return true
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
-- @param terrain_only if true checks only the terrain, otherwise checks all entities
function _M:canMove(x, y, terrain_only)
......
......@@ -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
-- @return true if we can continue to rest, false otherwise
function _M:restCheck()
return false
return false, "player:restCheck() method not defined"
end
--- 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()
[{"_DOWN","shift"}] = function() self.target:freemove(2) end,
[{"_KP4","shift"}] = function() self.target:freemove(4) 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,
[{"_KP1","shift"}] = function() self.target:freemove(1) end,
[{"_KP3","shift"}] = function() self.target:freemove(3) end,
......@@ -338,6 +338,20 @@ function _M:setupCommands()
_RIGHTPAREN = function() self.player:activateHotkey(11) 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
[{"_r","shift"}] = function()
self.player:restInit()
......
require "engine.class"
require "mod.class.Actor"
require "engine.interface.PlayerRest"
require "engine.interface.PlayerRun"
local Savefile = require "engine.Savefile"
local Map = require "engine.Map"
local Dialog = require "engine.Dialog"
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)
t.body = {
......@@ -74,8 +82,8 @@ function _M:act()
-- Clean log flasher
game.flash:empty()
-- Resting ?
if not self:restStep() then
-- Resting ? Running ? Otherwise pause
if not self:restStep() and not self:runStep() then
game.paused = true
end
end
......@@ -148,16 +156,20 @@ function _M:activateHotkey(id)
end
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()
local function spotHostiles(self)
local seen = false
-- 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)
local actor = map(x, y, map.ACTOR)
if actor and self:reactionToward(actor) < 0 and self:canSee(actor) then seen = true end
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
if self:getMana() < self:getMaxMana() and self.mana_regen > 0 then return true end
......@@ -166,3 +178,24 @@ function _M:restCheck()
return false, "all resources and life at maximun"
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{
name = "exit to the wilds",
display = '<', color_r=255, color_g=0, color_b=255,
always_remember = true,
notice = true,
change_level = 1,
change_zone = "wilderness",
}
......@@ -11,6 +12,7 @@ newEntity{
define_as = "UP",
name = "previous level",
display = '<', color_r=255, color_g=255, color_b=0,
notice = true,
always_remember = true,
change_level = -1,
}
......@@ -19,6 +21,7 @@ newEntity{
define_as = "DOWN",
name = "next level",
display = '>', color_r=255, color_g=255, color_b=0,
notice = true,
always_remember = true,
change_level = 1,
}
......@@ -43,6 +46,7 @@ newEntity{
define_as = "DOOR",
name = "door", image = "terrain/granite_door1.png",
display = '+', color_r=238, color_g=154, color_b=77,
notice = true,
always_remember = true,
block_sight = true,
door_opened = "DOOR_OPEN",
......
......@@ -5,7 +5,7 @@ newTalent{
points = 5,
require = { stat = { dex=14 } },
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,
}
......
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