2019-08-14 16:26:23 +02:00
|
|
|
local World = Object:extend()
|
|
|
|
|
|
|
|
local maputils = require "scenes.battlesystem.utils"
|
|
|
|
local Map = require "scenes.battlesystem.map"
|
|
|
|
local Cursor = require "scenes.battlesystem.cursor"
|
|
|
|
|
2019-08-16 23:04:30 +02:00
|
|
|
local TweenManager = require "game.modules.tweenmanager"
|
|
|
|
|
2019-08-14 16:26:23 +02:00
|
|
|
local POSITIONS = {
|
|
|
|
{x = 3, y = 4},
|
|
|
|
{x = 2, y = 2},
|
|
|
|
{x = 2, y = 6},
|
|
|
|
}
|
|
|
|
|
2019-08-15 09:13:08 +02:00
|
|
|
local gui = require "game.modules.gui"
|
|
|
|
|
2019-08-14 16:26:23 +02:00
|
|
|
-- 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
|
2019-08-15 09:13:08 +02:00
|
|
|
self.turns.number = 0
|
2019-08-14 16:26:23 +02:00
|
|
|
self.turns.isFinished = true
|
|
|
|
self.turns.changeBattler = true
|
|
|
|
self.battlers = {}
|
|
|
|
self.actionlist = {}
|
|
|
|
|
|
|
|
self.BattlerCursor = self.turns.current
|
|
|
|
|
|
|
|
self.heroNumber = 0
|
|
|
|
self.ennNumber = 0
|
|
|
|
|
2019-08-16 18:40:00 +02:00
|
|
|
self.playerHUDPosition = -64
|
|
|
|
|
2019-08-14 16:26:23 +02:00
|
|
|
self.map = Map(self, "city")
|
|
|
|
self.cursor = Cursor(self)
|
|
|
|
|
2019-08-16 23:04:30 +02:00
|
|
|
self.tweens = TweenManager(self)
|
|
|
|
|
2019-08-22 22:40:31 +02:00
|
|
|
self:resetActiveGrid()
|
|
|
|
self:resetEffectGrid()
|
|
|
|
|
2019-08-14 16:26:23 +02:00
|
|
|
self:initHeroes()
|
|
|
|
self:initEnnemies()
|
2019-08-15 09:13:08 +02:00
|
|
|
self:initHUD()
|
2019-08-16 18:33:47 +02:00
|
|
|
|
|
|
|
self.isBattleActive = false
|
2019-08-14 16:26:23 +02:00
|
|
|
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
|
|
|
|
|
2019-08-15 15:06:13 +02:00
|
|
|
function World:destroyActor(actorToDestroy)
|
|
|
|
for i, actor in ipairs(self.actors) do
|
|
|
|
if actor == actorToDestroy then
|
|
|
|
table.remove(self.actors, i)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-08-14 16:26:23 +02:00
|
|
|
-- 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
|
|
|
|
|
2019-08-15 19:00:01 +02:00
|
|
|
function World:destroyBattler(actorToDestroy)
|
|
|
|
-- remove the actor from the battler liste
|
|
|
|
for i, actor in ipairs(self.battlers) do
|
|
|
|
if actor == actorToDestroy then
|
|
|
|
table.remove(self.battlers, i)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Also remove all actions related to the actor
|
|
|
|
for i, action in ipairs(self.actionlist) do
|
|
|
|
if action.actor == actorToDestroy then
|
|
|
|
table.remove(self.actionlist, i)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-08-14 16:26:23 +02:00
|
|
|
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
|
|
|
|
|
2019-08-16 18:40:00 +02:00
|
|
|
function World:getPlayerHUDPosition()
|
|
|
|
return self.playerHUDPosition
|
|
|
|
end
|
|
|
|
|
2019-08-14 16:26:23 +02:00
|
|
|
-- UPDATE FUNCTION
|
|
|
|
-- Update all actors
|
|
|
|
|
|
|
|
function World:update(dt)
|
|
|
|
for i, actor in ipairs(self.actors) do
|
|
|
|
actor:update(dt)
|
|
|
|
end
|
|
|
|
|
2019-08-16 18:33:47 +02:00
|
|
|
if (self.isBattleActive) then
|
|
|
|
self:updateTurns(dt)
|
|
|
|
end
|
2019-08-14 16:26:23 +02:00
|
|
|
|
|
|
|
self.cursor:update(dt)
|
2019-08-16 23:04:30 +02:00
|
|
|
self.tweens:update(dt)
|
2019-08-14 16:26:23 +02:00
|
|
|
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
|
|
|
|
|
2019-08-16 18:33:47 +02:00
|
|
|
function World:startBattle()
|
|
|
|
self.isBattleActive = true
|
2019-08-16 23:04:30 +02:00
|
|
|
self.tweens:newTween(0, 0.4, {playerHUDPosition = 36}, 'inCubic')
|
2019-08-16 18:33:47 +02:00
|
|
|
end
|
|
|
|
|
2019-08-14 16:26:23 +02:00
|
|
|
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()
|
2019-08-16 18:33:47 +02:00
|
|
|
if (self:countEnnemies()==0) then
|
|
|
|
self:finishBattle()
|
2019-08-14 16:26:23 +02:00
|
|
|
else
|
2019-08-16 18:33:47 +02:00
|
|
|
if (self.turns.isFinished) or (self.turns.current >= #self.actionlist) then
|
|
|
|
self:switchToNextTurn()
|
|
|
|
else
|
|
|
|
self.turns.current = self.turns.current + 1
|
|
|
|
core.debug:print("cbs/world", "switching to action number " .. self.turns.current)
|
|
|
|
end
|
|
|
|
|
|
|
|
self:selectNextAction()
|
|
|
|
self.turns.changeBattler = false
|
2019-08-16 23:04:30 +02:00
|
|
|
self.tweens:newTween(0, 0.2, {BattlerCursor = self.turns.current}, 'inCubic')
|
2019-08-14 16:26:23 +02:00
|
|
|
end
|
2019-08-16 18:33:47 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
function World:switchToNextTurn()
|
|
|
|
core.debug:print("cbs/world", "turn finished")
|
|
|
|
self.turns.current = 1
|
|
|
|
self.turns.isFinished = false
|
|
|
|
self.turns.number = self.turns.number + 1
|
|
|
|
self:recalculateTurns()
|
|
|
|
end
|
2019-08-14 16:26:23 +02:00
|
|
|
|
2019-08-16 18:33:47 +02:00
|
|
|
function World:selectNextAction()
|
2019-08-15 19:00:01 +02:00
|
|
|
if (self.actionlist[self.turns.current].actor.isDestroyed == true) then
|
|
|
|
self:switchActiveBattler()
|
|
|
|
else
|
|
|
|
self.actionlist[self.turns.current].actor:setActive()
|
|
|
|
end
|
2019-08-16 18:33:47 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
function World:finishBattle()
|
|
|
|
self.isBattleActive = false
|
2019-08-16 23:04:30 +02:00
|
|
|
self.tweens:newTween(0, 0.4, {playerHUDPosition = -64}, 'inCubic')
|
2019-08-16 18:33:47 +02:00
|
|
|
self.actionlist = {}
|
|
|
|
self.scene:finishBattle()
|
2019-08-14 16:26:23 +02:00
|
|
|
end
|
|
|
|
|
2019-08-24 15:44:07 +02:00
|
|
|
function World:sendSignalToCurrentBattler(signal)
|
|
|
|
self.actionlist[self.turns.current].actor:receiveSignal(signal)
|
2019-08-14 16:26:23 +02:00
|
|
|
end
|
|
|
|
|
2019-08-22 22:40:31 +02:00
|
|
|
-- ACTIVEGRID FUNCTIONS
|
|
|
|
-- Help to handle the activeGrid system
|
|
|
|
|
|
|
|
function World:resetActiveGrid()
|
|
|
|
self.activeGrid = maputils.newFullMap()
|
|
|
|
end
|
|
|
|
|
|
|
|
function World:setActiveGrid(ox, oy, shape, size, direction)
|
|
|
|
self.activeGrid = maputils.maskToMap(ox, oy, shape, size, direction)
|
|
|
|
end
|
|
|
|
|
|
|
|
function World:setActiveGridFromGrid(grid)
|
|
|
|
self.activeGrid = grid
|
|
|
|
end
|
|
|
|
|
|
|
|
function World:resetEffectGrid()
|
|
|
|
self.effectGrid = maputils.newEmptyMap()
|
|
|
|
end
|
|
|
|
|
|
|
|
function World:setEffectGrid(ox, oy, shape, size, direction)
|
|
|
|
self.effectGrid = maputils.maskToMap(ox, oy, shape, size, direction)
|
|
|
|
end
|
2019-08-14 16:26:23 +02:00
|
|
|
|
|
|
|
-- DRAW FUNCTION
|
|
|
|
-- Draw the world
|
|
|
|
|
|
|
|
function World:draw()
|
2019-08-22 22:40:31 +02:00
|
|
|
self.map:draw(self.activeGrid, self.effectGrid)
|
2019-08-14 16:26:23 +02:00
|
|
|
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
|
|
|
|
|
2019-08-15 09:13:08 +02:00
|
|
|
function World:initHUD()
|
|
|
|
self.frame = gui.newBorder(424, 30, 4)
|
|
|
|
end
|
|
|
|
|
2019-08-14 16:26:23 +02:00
|
|
|
function World:drawHUD()
|
2019-08-16 18:40:00 +02:00
|
|
|
for i, battler in ipairs(self.battlers) do
|
|
|
|
battler:drawHUD()
|
|
|
|
end
|
|
|
|
|
|
|
|
for i, action in ipairs(self.actionlist) do
|
|
|
|
action.actor:drawIcon(4 + (i-1)*(20), 6)
|
2019-08-14 16:26:23 +02:00
|
|
|
end
|
|
|
|
local cursorx = self.BattlerCursor * 20 - 6
|
|
|
|
|
2019-08-16 18:33:47 +02:00
|
|
|
if #self.actionlist > 0 then
|
|
|
|
self.assets.images["menucursor"]:draw(cursorx, 26, math.rad(-90), 1, 1, 4, 8)
|
|
|
|
end
|
2019-08-14 16:26:23 +02:00
|
|
|
|
2019-08-15 09:13:08 +02:00
|
|
|
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)
|
2019-08-14 16:26:23 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return World
|