gdritter repos animaltransiro / master entity.lua
master

Tree @master (Download .tar.gz)

entity.lua @master

b682204
ebab62a
b682204
 
 
 
a114db3
ebab62a
c79df9e
ebab62a
 
 
 
 
 
b682204
a114db3
b682204
 
 
 
ebab62a
c6568f2
ebab62a
b682204
ebab62a
b682204
 
 
 
 
 
c831fbd
 
2a25787
a114db3
 
 
 
2a25787
c831fbd
c6568f2
c831fbd
c6568f2
c831fbd
c6568f2
c831fbd
c6568f2
c831fbd
 
b682204
 
0c3e780
 
 
 
 
 
 
 
 
c6568f2
f0c2586
c6568f2
0c3e780
 
 
 
 
c6568f2
 
b682204
 
c6568f2
a114db3
 
 
e13c4dc
 
 
 
 
c6568f2
0b365e4
ebab62a
c6568f2
 
ebab62a
c6568f2
 
 
 
 
0b365e4
ebab62a
c6568f2
 
ebab62a
c6568f2
 
 
 
0c3e780
 
 
 
 
 
 
 
 
 
32554bb
 
0c3e780
 
 
b682204
 
 
 
 
 
 
 
 
 
 
 
 
 
2a25787
b682204
c831fbd
 
b682204
c831fbd
b682204
 
2a25787
b682204
c831fbd
 
b682204
c831fbd
b682204
 
 
 
a114db3
 
 
 
 
b682204
 
6f822a9
 
d558512
6f822a9
d558512
6f822a9
b682204
 
13df580
f0c2586
 
 
 
 
 
 
13df580
 
b682204
 
 
local consts = require 'constants'
local tile = require 'tile'

local Entity = {}
Entity.__index = Entity

function Entity:new(state, x, y, name)
   local file = io.open('entities/' .. name .. '.lua')
   local char_data = load('return' .. file:read('*all'))()

   local sprites = {}
   for name, sprite in pairs(char_data.sprites) do
      sprites[name] = tile.getTile(sprite)
   end

   local t = {
      state = state,
      x = x,
      y = y,
      dx = 0,
      dy = 0,
      sprites = sprites,
      direction = {0, 1},
      facing = 'down',
   }

   return setmetatable(t, Entity)
end

function Entity:checkCollision(dx, dy)
   local bx = math.floor((self.x + dx) / consts.tileSize)
   local by = math.floor((self.y + dy) / consts.tileSize)
   local alignX = ((self.x + dx) % consts.tileSize) == 0
   local alignY = ((self.y + dy) % consts.tileSize) == 0

   local a = self.state.board:passable(bx, by)
   local b = self.state.board:passable(bx + 1, by)
   local c = self.state.board:passable(bx, by + 1)
   local d = self.state.board:passable(bx + 1, by + 1)

   if alignX and alignY then
      return a
   elseif alignX then
      return a and c
   elseif alignY then
      return a and b
   else
      return a and b and c and d
   end

end

function Entity:goingOffside(dx, dy)
   local bx = math.floor((self.x + dx) / consts.tileSize)
   local by = math.floor((self.y + dy) / consts.tileSize)
   return self.state.board:offside(bx, by) or
      self.state.board:offside(bx + 1, by) or
      self.state.board:offside(bx, by + 1) or
      self.state.board:offside(bx, by + 1)
end

function Entity:getFocus(board)
   local gx, gy = self:gameCoords()

   local es = board:lookupEntity(gx + self.direction[1],
                                 gy + self.direction[2])
   if es then
      return es[1]
   end
end

function Entity:move(board)
   local movement = true

   local gX, gY = self:gameCoords()
   debug = string.format(' {x=%d, y=%d, gx=%d, gy=%d}\n',
                         self.x, self.y, gX, gY)

   if self.dx == 0 and self.dy == 0 then
      return
   end

   if self.dx > 0 then
      self.direction[1] = 1
      self.facing = 'right'
   elseif self.dx < 0 then
      self.direction[1] = -1
      self.facing = 'left'
   elseif self.dy ~= 0 then
      self.direction[1] = 0
   end

   if self.dy > 0 then
      self.direction[2] = 1
      self.facing = 'down'
   elseif self.dy < 0 then
      self.direction[2] = -1
      self.facing = 'up'
   elseif self.dx ~= 0 then
      self.direction[2] = 0
   end

   local off = self:goingOffside(self.dx, self.dy)
   if off and self.state.board[off] then
      print('loading areas/' .. self.state.board[off] ..  '.lua')
      self.state:loadMap(self.state.board[off])
      if off == 'south' then
         self.y = 0
      elseif off == 'north' then
         self.y = consts.tileSize * (consts.boardHeight - 1)
      elseif off == 'west' then
         self.x = consts.tileSize * (consts.boardWidth - 1)
      elseif off == 'east' then
         self.x = 0
      end
   end

   if self:checkCollision(self.dx, self.dy) then
      self.x = self.x + self.dx
      self.y = self.y + self.dy
   elseif self:checkCollision(self.dx, 0) then
      self.x = self.x + self.dx
   elseif self:checkCollision(0, self.dy) then
      self.y = self.y + self.dy
   else
      movement = false
   end

   if movement then
      if self.dx ~= 0 and self.dy ~= 0 then
         -- nothing

      elseif self.dy ~= 0 then
         local xm = self.x % consts.halfTile
         if 0 < xm and xm < consts.quarterTile and self:checkCollision(-1, 0) then
            self.x = self.x - 1
         elseif xm >= consts.quarterTile and self:checkCollision(1, 0) then
            self.x = self.x + 1
         end

      elseif self.dx ~= 0 then
         local ym = self.y % consts.halfTile
         if 0 < ym and ym < consts.quarterTile and self:checkCollision(0, -1) then
            self.y = self.y - 1
         elseif ym >= consts.quarterTile and self:checkCollision(0, 1) then
            self.y = self.y + 1
         end
      end
   end

   local nX, nY = self:gameCoords()
   if nX ~= gX or nY ~= gY then
      self.state.board:enterSquare(nX, nY, self.state)
   end
end

function Entity:draw(t)
   if self.dx == 0 and self.dy == 0 then
      return self.sprites[self.facing]:drawPx(self.x, self.y, t)
   else
      return self.sprites[self.facing .. 'Moving']:drawPx(self.x, self.y, t)
   end
end

function Entity:gameCoords()
   return math.floor((self.x + consts.halfTile) / consts.tileSize),
   math.floor((self.y + consts.halfTile) / consts.tileSize)
end

function Entity:gameTopCoords()
   return math.floor(self.x / consts.tileSize),
   math.floor(self.y / consts.tileSize)
end

return {
   Entity = Entity
}