Forked from
tome / Tales of MajEyal
15051 commits behind the upstream repository.
-
dg authored
git-svn-id: http://svn.net-core.org/repos/t-engine4@53 51575b47-30f0-44d4-a5cc-537603b46e54
dg authoredgit-svn-id: http://svn.net-core.org/repos/t-engine4@53 51575b47-30f0-44d4-a5cc-537603b46e54
Game.lua 12.22 KiB
require "engine.class"
require "engine.GameTurnBased"
require "engine.KeyCommand"
require "engine.LogDisplay"
local Savefile = require "engine.Savefile"
local DebugConsole = require "engine.DebugConsole"
local Tooltip = require "engine.Tooltip"
local QuitDialog = require "mod.dialogs.Quit"
local Calendar = require "engine.Calendar"
local Zone = require "engine.Zone"
local Map = require "engine.Map"
local Target = require "engine.Target"
local Level = require "engine.Level"
local Grid = require "engine.Grid"
local Actor = require "mod.class.Actor"
local ActorStats = require "engine.interface.ActorStats"
local ActorAbilities = require "engine.interface.ActorAbilities"
local Player = require "mod.class.Player"
local NPC = require "mod.class.NPC"
module(..., package.seeall, class.inherit(engine.GameTurnBased))
function _M:init()
engine.GameTurnBased.init(self, engine.KeyCommand.new(), 1000, 100)
-- Same init as when loaded from a savefile
self:loaded()
end
function _M:run()
-- Actor stats
ActorStats:defineStat("Strength", "str", 10, 1, 100)
ActorStats:defineStat("Dexterity", "dex", 10, 1, 100)
ActorStats:defineStat("Magic", "mag", 10, 1, 100)
ActorStats:defineStat("Willpower", "wil", 10, 1, 100)
ActorStats:defineStat("Cunning", "cun", 10, 1, 100)
ActorStats:defineStat("Constitution", "con", 10, 1, 100)
ActorAbilities:loadDefinition("/data/abilities.lua")
self.log = engine.LogDisplay.new(0, self.h * 0.80, self.w * 0.5, self.h * 0.20, nil, nil, nil, {255,255,255}, {30,30,30})
self.calendar = Calendar.new("/data/calendar_rivendell.lua", "Today is the %s %s of the %s year of the Fourth Age of Middle-earth.\nThe time is %02d:%02d.", 122)
self.tooltip = engine.Tooltip.new(nil, nil, {255,255,255}, {30,30,30})
self.log("Welcome to #00FF00#Tales of Middle Earth!")
self.logSeen = function(e, ...) if e and self.level.map.seens(e.x, e.y) then self.log(...) end end
-- Setup inputs
self:setupCommands()
self:setupMouse()
-- Starting from here we create a new game
if not self.player then self:newGame() end
self.target = Target.new(Map, self.player)
self.target.target.entity = self.player
self.old_tmx, self.old_tmy = 0, 0
-- Ok everything is good to go, activate the game in the engine!
self:setCurrent()
end
function _M:newGame()
self.zone = Zone.new("ancient_ruins")
self.player = Player.new{name="player", image='player.png', display='@', color_r=230, color_g=230, color_b=230}
self:changeLevel(1)
-- self:registerDialog(require('mod.dialogs.EnterName').new())
end
function _M:loaded()
Zone:setup{npc_class="mod.class.NPC", grid_class="mod.class.Grid", object_class="engine.Entity"}
-- Map:setViewPort(0, 0, self.w, math.floor(self.h * 0.80), 20, 20, "/data/font/10X20.FON", 20)
Map:setViewPort(self.w * 0.2, 0, self.w * .8, math.floor(self.h * 0.80), 16, 16)
engine.GameTurnBased.loaded(self)
self.key = engine.KeyCommand.new()
end
function _M:save()
return class.save(self, {w=true, h=true, zone=true, player=true, level=true,
energy_to_act=true, energy_per_tick=true, turn=true, paused=true, save_name=true,
}, true)
end
function _M:getSaveDescription()
return {
name = self.player.name,
description = [[Strolling in the old places of the world!]],
}
end
function _M:changeLevel(lev)
self.zone:getLevel(self, lev)
self.player:move(self.level.start.x, self.level.start.y, true)
self.level:addEntity(self.player)
end
function _M:tick()
engine.GameTurnBased.tick(self)
if not self.day_of_year or self.day_of_year ~= self.calendar:getDayOfYear(self.turn) then
self.log(self.calendar:getTimeDate(self.turn))
self.day_of_year = self.calendar:getDayOfYear(self.turn)
end
end
function _M:display()
self.log:display():toScreen(self.log.display_x, self.log.display_y)
if self.level and self.level.map then
-- Display the map and compute FOV for the player if needed
if self.level.map.changed then
self.level.map:fov(self.player.x, self.player.y, 20)
self.level.map:fovLite(self.player.x, self.player.y, 4)
end
self.level.map:display():toScreen(self.level.map.display_x, self.level.map.display_y)
-- Display the targetting system if active
self.target: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 tt = self.level.map:checkAllEntities(tmx, tmy, "tooltip")
if tt and self.level.map.seens(tmx, tmy) then
self.tooltip:set(tt)
local t = self.tooltip:display()
mx = mx - self.tooltip.w
my = my - self.tooltip.h
if mx < 0 then mx = 0 end
if my < 0 then my = 0 end
if t then t:toScreen(mx, my) end
end
if self.old_tmx ~= tmx or self.old_tmy ~= tmy then
self.target.target.x, self.target.target.y = tmx, tmy
end
self.old_tmx, self.old_tmy = tmx, tmy
end
engine.GameTurnBased.display(self)
end
function _M:targetMode(v, msg)
if not v then
Map:setViewerFaction(nil)
if msg then self.log("Tactical display disabled. Press 't' or right mouse click to enable.") end
self.level.map.changed = true
self.target:setActive(false)
else
Map:setViewerFaction("players")
if msg then self.log("Tactical display enabled. Press 't' to disable.") end
self.level.map.changed = true
self.target:setActive(true)
end
end
function _M:setupCommands()
self.key:addCommands
{
_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,
[{"_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
end,
_GREATER = {"alias", "_LESS"},
-- Toggle tactical displau
_t = function()
if Map.view_faction then
self:targetMode(false, true)
else
self:targetMode(true, true)
-- Find nearest target
self.target:scan(5)
end
end,
-- Toggle tactical displau
[{"_t","ctrl"}] = function()
self.log(self.calendar:getTimeDate(self.turn))
end,
-- Exit the game
[{"_x","ctrl"}] = function()
self:onQuit()
end,
-- Lua console
[{"_l","ctrl"}] = function()
self:registerDialog(DebugConsole.new())
end,
-- Targeting movement
[{"_LEFT","ctrl","shift"}] = function() self.target.target.entity=nil self.target.target.x = self.target.target.x - 1 end,
[{"_RIGHT","ctrl","shift"}] = function() self.target.target.entity=nil self.target.target.x = self.target.target.x + 1 end,
[{"_UP","ctrl","shift"}] = function() self.target.target.entity=nil self.target.target.y = self.target.target.y - 1 end,
[{"_DOWN","ctrl","shift"}] = function() self.target.target.entity=nil self.target.target.y = self.target.target.y + 1 end,
[{"_KP4","ctrl","shift"}] = function() self.target.target.entity=nil self.target.target.x = self.target.target.x - 1 end,
[{"_KP6","ctrl","shift"}] = function() self.target.target.entity=nil self.target.target.x = self.target.target.x + 1 end,
[{"_KP8","ctrl","shift"}] = function() self.target.target.entity=nil self.target.target.y = self.target.target.y - 1 end,
[{"_KP2","ctrl","shift"}] = function() self.target.target.entity=nil self.target.target.y = self.target.target.y + 1 end,
[{"_KP1","ctrl","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","ctrl","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","ctrl","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","ctrl","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","ctrl"}] = function() self.target:scan(4) end,
[{"_RIGHT","ctrl"}] = function() self.target:scan(6) end,
[{"_UP","ctrl"}] = function() self.target:scan(8) end,
[{"_DOWN","ctrl"}] = function() self.target:scan(2) end,
[{"_KP4","ctrl"}] = function() self.target:scan(4) end,
[{"_KP6","ctrl"}] = function() self.target:scan(6) end,
[{"_KP8","ctrl"}] = function() self.target:scan(8) end,
[{"_KP2","ctrl"}] = function() self.target:scan(2) end,
[{"_KP1","ctrl"}] = function() self.target:scan(1) end,
[{"_KP3","ctrl"}] = function() self.target:scan(3) end,
[{"_KP7","ctrl"}] = function() self.target:scan(7) end,
[{"_KP9","ctrl"}] = function() self.target:scan(9) end,
-- Save the game
[{"_s","ctrl"}] = function()
local save = Savefile.new(self.save_name)
save:saveGame(self)
save:close()
self.log("Saved game.")
end,
}
self.key:setCurrent()
end
function _M:setupMouse()
-- Those 2 locals will be "absorbed" into the mosue event handler function, this is a closure
local derivx, derivy = 0, 0
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 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
self:targetMode(true, true)
end
elseif button == "left" and xrel and yrel then
derivx = derivx + xrel
derivy = derivy + yrel
game.level.map.changed = true
if derivx >= game.level.map.tile_w then
game.level.map.mx = game.level.map.mx - 1
derivx = derivx - game.level.map.tile_w
elseif derivx <= -game.level.map.tile_w then
game.level.map.mx = game.level.map.mx + 1
derivx = derivx + game.level.map.tile_w
end
if derivy >= game.level.map.tile_h then
game.level.map.my = game.level.map.my - 1
derivy = derivy - game.level.map.tile_h
elseif derivy <= -game.level.map.tile_h then
game.level.map.my = game.level.map.my + 1
derivy = derivy + game.level.map.tile_h
end
end
end)
self.mouse:registerZone(self.log.display_x, self.log.display_y, self.w, self.h, function(button)
if button == "wheelup" then self.log:scrollUp(1) end
if button == "wheeldown" then self.log:scrollUp(-1) end
end, {button=true})
end
--- Ask if we realy want to close, if so, save the game first
function _M:onQuit()
if not self.quit_dialog then
self.quit_dialog = QuitDialog.new()
self:registerDialog(self.quit_dialog)
end
end