sonic-radiance/sonic-radiance.love/scenes/battlesystem/world.lua

267 lines
5.4 KiB
Lua

local World = Object:extend()
local maputils = require "scenes.battlesystem.utils"
local Map = require "scenes.battlesystem.map"
local Cursor = require "scenes.battlesystem.cursor"
local POSITIONS = {
{x = 3, y = 4},
{x = 2, y = 2},
{x = 2, y = 6},
}
local gui = require "game.modules.gui"
-- INIT FUNCTIONS
-- Initialize the battle world
function World:new(scene, battlefile)
self.scene = scene
self.assets = scene.assets
self.obj = require "scenes.battlesystem.actors"
self.actors = {}
self.globalID = 0
self.turns = {}
self.turns.current = 1
self.turns.number = 0
self.turns.isFinished = true
self.turns.changeBattler = true
self.battlers = {}
self.actionlist = {}
self.BattlerCursor = self.turns.current
self.heroNumber = 0
self.ennNumber = 0
self.map = Map(self, "city")
self.cursor = Cursor(self)
self:initHeroes()
self:initEnnemies()
self:initHUD()
end
function World:initHeroes(battlefile)
for i, hero in ipairs(game.characters.team) do
self:addHero(POSITIONS[i].x, POSITIONS[i].y, hero, i)
end
end
function World:initEnnemies(battlefile)
self:addEnnemy(10, 3, "motobug")
self:addEnnemy(10, 5, "motobug")
end
function World:registerActor(actor)
self.globalID = self.globalID + 1
table.insert(self.actors, actor)
actor.id = self.globalID
end
-- INFO FUNCTIONS
-- Get info from the world
function World:caseIsEmpty(x, y)
local isEmpty = true
for i, actor in ipairs(self.actors) do
if (actor.x == x) and (actor.y == y) then
isEmpty = false
else
isEmpty = true
end
end
return isEmpty
end
function World:getActorInCase(x, y)
for i, actor in ipairs(self.actors) do
if (actor.x == x) and (actor.y == y) then
core.debug:print("cbs/world", "one actor found in case <" .. x .. ";" .. y .. ">")
return actor
end
end
return nil
end
-- BATTLER FUNCTIONS
-- Handle the actual battle participants
function World:addHero(x, y, id)
self.heroNumber = self.heroNumber + 1
local hero = self.obj.Hero(self, x, y, id, self.heroNumber)
table.insert(self.battlers, hero)
end
function World:addEnnemy(x, y, id)
self.ennNumber = self.ennNumber + 1
local enn = self.obj.Ennemy(self, x, y, id, self.ennNumber)
table.insert(self.battlers, enn)
end
function World:generateActionList()
self.actionlist = {}
for i,v in ipairs(self.battlers) do
for i=1, v.actionPerTurn do
local action = {}
action.actor = v
action.number = i
table.insert(self.actionlist, action)
end
end
end
function World:countHeroes()
local count = 0
for i, battler in ipairs(self.battlers) do
if (battler.isHero) then
count = count + 1
end
end
return count
end
function World:countEnnemies()
local count = 0
for i, battler in ipairs(self.battlers) do
if (battler.isEnnemy) then
count = count + 1
end
end
return count
end
-- UPDATE FUNCTION
-- Update all actors
function World:update(dt)
for i, actor in ipairs(self.actors) do
actor:update(dt)
end
self:updateTurns(dt)
self:moveBattleCursor(dt)
self.cursor:update(dt)
end
function World:moveBattleCursor(dt)
local cursorSpeed = 16
if (self.turns.current == 1) then
cursorSpeed = 16 * 4
end
if math.abs(self.BattlerCursor - self.turns.current) > (cursorSpeed * dt) then
self.BattlerCursor = self.BattlerCursor - utils.math.sign(self.BattlerCursor - self.turns.current) * cursorSpeed * dt
else
self.BattlerCursor = self.turns.current
end
end
-- TURNS FUNCTIONS
-- Handle everything related to the turn system
function World:recalculateTurns()
self:generateActionList()
table.sort(self.actionlist, maputils.sortBattlers)
end
function World:updateTurns(dt)
if (self.turns.changeBattler) then
self:switchActiveBattler( )
end
end
function World:switchActiveBattler()
if (self.turns.isFinished) or (self.turns.current >= #self.actionlist) then
self.turns.current = 1
self.turns.isFinished = false
self.turns.number = self.turns.number + 1
self:recalculateTurns()
else
self.turns.current = self.turns.current + 1
end
self.actionlist[self.turns.current].actor:setActive()
self.turns.changeBattler = false
end
function World:sendSignalToCurrentBattler()
self.actionlist[self.turns.current].actor:validateAction()
end
-- DRAW FUNCTION
-- Draw the world
function World:draw()
local activeGrid = self.cursor:getGrid()
self.map:draw(activeGrid)
self.cursor:drawBottom()
self:drawShadows()
self:drawActors()
self.cursor:drawTop()
self:drawHUD()
end
function World:drawActors()
for i, actor in ipairs(self.actors) do
actor:draw()
end
end
function World:drawShadows()
for i, actor in ipairs(self.actors) do
actor:drawShadow()
end
end
function World:initHUD()
self.frame = gui.newBorder(424, 30, 4)
end
function World:drawHUD()
for i,v in ipairs(self.actionlist) do
v.actor:drawIcon(4 + (i-1)*(20), 6)
end
local cursorx = self.BattlerCursor * 20 - 6
self.assets.images["menucursor"]:draw(cursorx, 26, math.rad(-90), 1, 1, 4, 8)
for i,v in ipairs(self.battlers) do
v:drawHUD()
end
local x, y = 362, 3
love.graphics.draw(self.frame, 424, 20, 0, -1, -1)
self.assets.images["hudturn"]:draw(x, y)
self.assets.fonts["hudnbrs"]:set()
local turnnbr = self.turns.number
if (turnnbr < 10) then
turnnbr = "0" .. turnnbr
end
love.graphics.print(turnnbr, x + 33, y + 1)
end
return World