chore: completely extract the choregraphy system from actor

This commit is contained in:
Kazhnuz 2020-05-02 13:01:43 +02:00
parent 08ff743754
commit b413946368
13 changed files with 381 additions and 185 deletions

View file

@ -15,6 +15,9 @@ end
function GFX:animationEnded(animation) function GFX:animationEnded(animation)
core.debug:print("gfx", 'Current animation "' .. animation .. '" have ended, destroying gfx') core.debug:print("gfx", 'Current animation "' .. animation .. '" have ended, destroying gfx')
if (self.blockProcess) and (self.creator ~= nil) and (self.creator.getSignal ~= nil) then
self.creator:getSignal("gfxEnded")
end
self:destroy() self:destroy()
end end

View file

@ -4,6 +4,8 @@ local Hero = Battler:extend()
local gui = require "game.modules.gui" local gui = require "game.modules.gui"
local StatusBar = require "scenes.battlesystem.gui.statusbar" local StatusBar = require "scenes.battlesystem.gui.statusbar"
local ChoregraphySystem = require "scenes.battlesystem.actors.systems.choregraphy"
-- INIT FUNCTIONS -- INIT FUNCTIONS
-- Initialize the hero -- Initialize the hero
@ -82,7 +84,7 @@ function Hero:setActive()
self.world.cursor:set(self.startx, self.starty, "cursorMove") self.world.cursor:set(self.startx, self.starty, "cursorMove")
self:talk("turnstart") --self:talk("turnstart")
self.directionPrevious = self.direction self.directionPrevious = self.direction
end end
@ -98,9 +100,7 @@ function Hero:update(dt)
-- Calculate speed to calculate animation speed -- Calculate speed to calculate animation speed
self:updateSpeed(dt) self:updateSpeed(dt)
if (self.isChoregraphyActive) then self:updateChoregraphy(dt)
self:updateChoregraphy()
end
if (self.scene:haveMenus()) then if (self.scene:haveMenus()) then
self:changeDirection(dt) self:changeDirection(dt)
@ -232,8 +232,8 @@ function Hero:applyMotion(dt)
else else
self.x = dx self.x = dx
self.motion = 0 self.motion = 0
if (self.choregraphy.blockedBy == 'action_dashForward') then if (self.blockingChoregraphy == 'action_dashForward') then
self.choregraphy.changeAction = true self:unblockChoregraphy()
self.direction = self.choregraphy.direction self.direction = self.choregraphy.direction
end end
end end
@ -296,9 +296,9 @@ function Hero:timerResponse(timer)
self.direction = self.directionPrevious self.direction = self.directionPrevious
elseif timer == 'action_jumpBack' then elseif timer == 'action_jumpBack' then
self.unlockDirection = true self.unlockDirection = true
self.choregraphy.changeAction = true self:unblockChoregraphy()
elseif timer == self.choregraphy.blockedBy and self.choregraphy.changeAction == false then elseif timer == self.choregraphy.blockedBy then
self.choregraphy.changeAction = true self:unblockChoregraphy()
end end
end end
@ -306,6 +306,7 @@ end
-- All functions related to actions -- All functions related to actions
function Hero:switchActiveBattler() function Hero:switchActiveBattler()
print("Switching Active Battler")
self.tweens:newTimer(0.15, "switchActiveBattler") self.tweens:newTimer(0.15, "switchActiveBattler")
end end
@ -313,198 +314,34 @@ end
-- All functions related to the choregraphy system -- All functions related to the choregraphy system
function Hero:initChoregraphySystem() function Hero:initChoregraphySystem()
self.choregraphy = {} self.choregraphy = ChoregraphySystem(self)
self.choregraphy.current = 0 self.blockingChoregraphy = nil
self.choregraphy.isFinished = false
self.choregraphy.changeAction = true
self.choregraphy.data = {}
self.choregraphy.effectArea = nil
self.choregraphy.dx = self.x
self.choregraphy.dy = self.y
self.choregraphy.blockedBy = ""
self.choregraphy.startx = self.x
self.choregraphy.starty = self.y
self.choregraphy.direction = self.direction
self.isChoregraphyActive = false
end end
function Hero:attack(id, dx, dy) function Hero:attack(id, dx, dy)
local skill = game.skills:getSkillData("attack") local skill = game.skills:getSkillData("attack")
self:startChoregraphy(skill, dx, dy) self.choregraphy:start(skill, dx, dy)
end end
function Hero:useSkill(id, dx, dy) function Hero:useSkill(id, dx, dy)
local skill = game.skills:getSkillData(id) local skill = game.skills:getSkillData(id)
self:setPP(skill.cost * -1, true) self:setPP(skill.cost * -1, true)
self:startChoregraphy(skill, dx, dy) self.choregraphy:start(skill, dx, dy)
end
function Hero:startChoregraphy(skill, dx, dy)
local skill = skill
self.choregraphy.current = 0
self.choregraphy.isFinished = false
self.choregraphy.changeAction = true
self.choregraphy.data = skill.choregraphy
self.choregraphy.effectArea = skill.effectArea
self.choregraphy.startx = self.x
self.choregraphy.starty = self.y
self.choregraphy.direction = self.direction
self.choregraphy.dx = dx or self.x
self.choregraphy.dy = dy or self.y
self.choregraphy.haveSentDamage = false
self.isChoregraphyActive = true
end end
function Hero:updateChoregraphy(dt) function Hero:updateChoregraphy(dt)
if (self.choregraphy.changeAction) then self.choregraphy:update(dt)
self:switchAction()
end
end
function Hero:switchAction()
self.choregraphy.current = self.choregraphy.current + 1
local nextAction = self.choregraphy.data[self.choregraphy.current]
if nextAction == nil then
self.isChoregraphyActive = false
self:switchActiveBattler()
else
local args = game.skills:getActionArguments(nextAction)
local condition = args.condition
if (condition == "sentDamage") and (not self.choregraphy.haveSentDamage) then
core.debug:print("cbs/hero", "you didn't do damage, skipping " .. args.name)
self:switchAction()
else
self:doChoregraphyAction(nextAction)
end
end
end
function Hero:doChoregraphyAction(choregraphyAction)
local args = game.skills:getActionArguments(choregraphyAction)
local type = args.type or "unknown"
local effectArea = self.choregraphy.effectArea
self.choregraphy.changeAction = true
if type == "wait" then
local duration = choregraphyAction[3] or 1
self:wait(args.duration)
elseif type == "setAnimation" then
self:chorSetAnimation(args)
elseif type == "sendDamage" then
self:sendDamageToArea(effectArea, args.power, args.accuracy, args.isSpecial, args.isAerial)
elseif type == "sendDamageToPoint" then
self:chorSendDamageToPoint(args)
elseif type == "addGFX" then
self:chorAddGFX(args)
elseif type == "playSFX" then
self.assets.sfx[args.sfx]:play()
elseif type == "dashForward" then
self:setMotionX(self.direction, args.speed)
self:blockChoregraphy(args.blockProcess, "action_dashForward")
elseif type == "jump" then
self:chorJump(args)
else
core.debug:warning("cbs/hero", "unknown action type " .. type .. ' (' .. args.name .. ')')
end
end
function Hero:chorSetAnimation(args)
self:changeAnimation(args.animation)
self:blockChoregraphy(args.blockProcess, args.animation)
end
function Hero:chorAddGFX(args)
local dx = args.dx
if (args.affectedByDirection) then
dx = dx * self.direction
end
local x = self.x
local y = self.y
local z = 0
self.world.obj.GFX(self.world, x + dx, y + args.dy, z, args.sprite, self, args.blockProcess)
end
function Hero:chorSendDamageToPoint(args)
local xx, yy
if args.name == "sendDamageFromCursor" then
xx = self.choregraphy.dx
yy = self.choregraphy.dy
elseif args.name == "sendDamageFromPos" then
xx = utils.math.round(self.x)
yy = utils.math.round(self.y)
end
local dx = args.dx
if (args.affectedByDirection) then
dx = dx * self.choregraphy.direction
end
xx = xx + dx
yy = yy + args.dy
self.choregraphy.haveSentDamage = self:sendDamage(xx, yy, args.power, args.accuracy, args.isSpecial, args.isAerial)
end
function Hero:chorJump(args)
local xx, yy
local spinjump = true
local factor = 1
local easing = 'inOutQuad'
if args.name == "jumpBack" then
xx, yy = self.choregraphy.startx, self.choregraphy.starty
self.directionLocked = true
spinjump = false
factor = 2
easing = 'outQuad'
elseif args.name == "jumpToCursor" then
xx, yy = self.choregraphy.dx, self.choregraphy.dy
end
local dist = utils.math.pointDistance(self.x, self.y, xx, yy)
local jumpHeight = dist * 16 / factor
self:jumpTo(xx, yy, jumpHeight, "action_jumpBack", spinjump, 1, easing)
self:blockChoregraphy(args.blockProcess, "action_jumpBack")
end end
function Hero:blockChoregraphy(isBlocked, blockedBy) function Hero:blockChoregraphy(isBlocked, blockedBy)
if (isBlocked) then if (isBlocked) then
self.choregraphy.blockedBy = blockedBy self.blockingChoregraphy = blockedBy
self.choregraphy.changeAction = false
end end
end end
function Hero:sendDamageToArea(effectArea, power, accuracy, isSpecial, isAerial) function Hero:unblockChoregraphy()
local dx = effectArea[1] self.choregraphy:endAction()
if effectArea[5] then self.blockingChoregraphy = ""
dx = dx * self.choregraphy.direction
end
local ox = self.choregraphy.startx + dx
local oy = self.choregraphy.starty + effectArea[2]
local grid = self.maputils.maskToMap(ox, oy, effectArea[3], effectArea[4], self.choregraphy.direction)
local test = false
for i, line in ipairs(grid) do
for j, case in ipairs(line) do
if grid[i][j] == 1 then
test = self:sendDamage(j, i, power, accuracy, isSpecial, isAerial)
end
end
end
self.choregraphy.haveSentDamage = test
end
function Hero:wait(time)
self.tweens:newTimer(time, "wait")
self.choregraphy.changeAction = false
end end
-- ASSETS FUNCTIONS -- ASSETS FUNCTIONS
@ -519,9 +356,8 @@ function Hero:initSprite()
end end
function Hero:animationEnded(animation) function Hero:animationEnded(animation)
if (animation == self.choregraphy.blockedBy) then if (animation == self.blockingChoregraphy) then
self.choregraphy.blockedBy = "" self:unblockChoregraphy()
self.choregraphy.changeAction = true
end end
end end

View file

@ -0,0 +1,36 @@
local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent"
local GFXAction = ChoregraphyActionParent:extend()
function GFXAction:new(controller, args, effectArea)
GFXAction.super.new(self, controller, args, effectArea)
end
function GFXAction:start()
local dx = self.args.dx
if (self.args.affectedByDirection) then
dx = dx * self.actor.direction
end
local x = self.actor.x
local y = self.actor.y
local z = 0
self.actor.world.obj.GFX(self.actor.world, x + dx, y + self.args.dy, z, self.args.sprite, self, self.args.blockProcess)
if (not self.args.blockProcess) then
self:finish()
end
end
function GFXAction:update(dt)
end
function GFXAction:getSignal(signal)
if (signal == "gfxEnded") then
self:finish()
end
end
return GFXAction

View file

@ -0,0 +1,19 @@
local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent"
local DashAction = ChoregraphyActionParent:extend()
function DashAction:new(system, args, effectArea)
DashAction.super.new(self, system, args, effectArea)
end
function DashAction:start()
self.actor:setMotionX(self.actor.direction, self.args.speed)
self.actor:blockChoregraphy(self.args.blockProcess, "action_dashForward")
end
function DashAction:getSignal(signal)
if (signal == "actorHaveFinished") then
self:finish()
end
end
return DashAction;

View file

@ -0,0 +1,14 @@
local actions = {}
local baseURI = "scenes.battlesystem.actors.systems.actions."
actions["addGFX"] = require(baseURI .. "addGFX")
actions["dashForward"] = require(baseURI .. "dashForward")
actions["jump"] = require(baseURI .. "jump")
actions["playSFX"] = require(baseURI .. "playSFX")
actions["sendDamage"] = require(baseURI .. "sendDamage")
actions["sendDamageToPoint"] = require(baseURI .. "sendDamageToPoint")
actions["setAnimation"] = require(baseURI .. "setAnimation")
actions["wait"] = require(baseURI .. "wait")
return actions

View file

@ -0,0 +1,40 @@
local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent"
local JumpAction = ChoregraphyActionParent:extend()
function JumpAction:new(system, args, effectArea)
JumpAction.super.new(self, system, args, effectArea)
end
function JumpAction:start()
local xx, yy
local spinjump = true
local factor = 1
local easing = 'inOutQuad'
if self.args.name == "jumpBack" then
xx, yy = self.controller.startx, self.controller.starty
self.actor.directionLocked = true
spinjump = false
factor = 2
easing = 'outQuad'
elseif self.args.name == "jumpToCursor" then
xx, yy = self.controller.dx, self.controller.dy
end
local dist = utils.math.pointDistance(self.actor.x, self.actor.y, xx, yy)
local jumpHeight = dist * 16 / factor
self.actor:jumpTo(xx, yy, jumpHeight, "action_jumpBack", spinjump, 1, easing)
self.actor:blockChoregraphy(self.args.blockProcess, "action_jumpBack")
if (not self.args.blockProcess) then
self:finish()
end
end
function JumpAction:getSignal(signal)
if (signal == "actorHaveFinished") then
self:finish()
end
end
return JumpAction

View file

@ -0,0 +1,29 @@
local ChoregraphyAction = Object:extend()
function ChoregraphyAction:new(controller, args, effectArea)
self.controller = controller
self.actor = controller.actor
self.args = args;
self.effectArea = effectArea;
self:start()
end
function ChoregraphyAction:start()
self:finish()
end
function ChoregraphyAction:update(dt)
end
function ChoregraphyAction:getSignal(signal)
end
function ChoregraphyAction:finish()
print("action finished")
self.controller:endAction()
end
return ChoregraphyAction;

View file

@ -0,0 +1,14 @@
local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent"
local PlaySFX = ChoregraphyActionParent:extend()
function PlaySFX:new(system, args, effectArea)
PlaySFX.super.new(self, system, args, effectArea)
end
function PlaySFX:start()
self.actor.assets.sfx[self.args.sfx]:play()
self:finish()
end
return PlaySFX

View file

@ -0,0 +1,38 @@
local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent"
local SendDamage = ChoregraphyActionParent:extend()
local maputils = require "scenes.battlesystem.utils"
function SendDamage:new(system, args, effectArea)
SendDamage.super.new(self, system, args, effectArea)
end
function SendDamage:start()
local power = self.args.power
local accuracy = self.args.accuracy
local isSpecial = self.args.isSpecial
local isAerial = self.args.isAerial
local dx = self.effectArea[1]
if self.effectArea[5] then
dx = dx * self.controller.direction
end
local ox = self.controller.startx + dx
local oy = self.controller.starty + self.effectArea[2]
local grid = maputils.maskToMap(ox, oy, self.effectArea[3], self.effectArea[4], self.controller.direction)
local test = false
for i, line in ipairs(grid) do
for j, case in ipairs(line) do
if grid[i][j] == 1 then
test = self.actor:sendDamage(j, i, power, accuracy, isSpecial, isAerial)
end
end
end
self.controller.haveSentDamage = test
self:finish()
end
return SendDamage

View file

@ -0,0 +1,29 @@
local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent"
local SendDamage = ChoregraphyActionParent:extend()
function SendDamage:new(system, args, effectArea)
SendDamage.super.new(self, system, args, effectArea)
end
function SendDamage:start()
local xx, yy
if self.args.name == "sendDamageFromCursor" then
xx = self.controller.dx
yy = self.controller.dy
elseif self.args.name == "sendDamageFromPos" then
xx = utils.math.round(self.actor.x)
yy = utils.math.round(self.actor.y)
end
local dx = self.args.dx
if (self.args.affectedByDirection) then
dx = dx * self.controller.direction
end
xx = xx + dx
yy = yy + self.args.dy
self.controller.haveSentDamage = self.actor:sendDamage(xx, yy, self.args.power, self.args.accuracy, self.args.isSpecial, self.args.isAerial)
self:finish()
end
return SendDamage

View file

@ -0,0 +1,24 @@
local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent"
local AnimationSetterAction = ChoregraphyActionParent:extend()
function AnimationSetterAction:new(controller, args, effectArea)
AnimationSetterAction.super.new(self, controller, args, effectArea)
end
function AnimationSetterAction:start()
self.actor:changeAnimation(self.args.animation)
self.actor:blockChoregraphy(self.args.blockProcess, self.args.animation)
if (self.args.blockProcess == false) then
self:finish()
end
end
function AnimationSetterAction:update(dt)
end
function AnimationSetterAction:getSignal(signal)
end
return AnimationSetterAction;

View file

@ -0,0 +1,19 @@
local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent"
local WaitAction = ChoregraphyActionParent:extend()
function WaitAction:new(controller, args, effectArea)
WaitAction.super.new(self, controller, args, effectArea)
end
function WaitAction:start()
self.timer = 0
end
function WaitAction:update(dt)
self.timer = self.timer + dt
if (self.timer > self.args.duration) then
self:finish()
end
end
return WaitAction;

View file

@ -0,0 +1,95 @@
local ChoregraphySystem = Object:extend()
local actionList = require "scenes.battlesystem.actors.systems.actions"
function ChoregraphySystem:new(actor)
self.actor = actor
self:init({}, nil, self.actor.x, self.actor.y, false)
end
function ChoregraphySystem:init(choregraphy, effectArea, dx, dy, isActive)
self.current = 0
self.action = nil
self.isFinished = false
self.data = choregraphy
self.effectArea = effectArea
self.startx = self.actor.x
self.starty = self.actor.y
self.direction = self.actor.direction
self.dx = dx or self.actor.x
self.dy = dy or self.actor.y
self.haveSentDamage = false
self.isActive = isActive
self.actionHaveEnded = false
end
function ChoregraphySystem:start(skill, dx, dy)
local skill = skill
self:init(skill.choregraphy, skill.effectArea, dx, dy, true)
end
function ChoregraphySystem:finish()
self.isActive = false
self.actor:switchActiveBattler()
end
function ChoregraphySystem:update(dt)
if (self.actionHaveEnded) then
self.action = nil
self.actionHaveEnded = false
end
if (self.isActive) then
if (self.action == nil) then
self:switchAction()
else
self.action:update(dt)
end
end
end
function ChoregraphySystem:switchAction()
self.current = self.current + 1
local nextAction = self.data[self.current]
if (nextAction == nil) then
print("finished")
self:finish()
else
local args = game.skills:getActionArguments(nextAction)
local condition = args.condition
if (condition == "sentDamage") and (not self.haveSentDamage) then
core.debug:print("cbs/hero", "you didn't do damage, skipping " .. args.name)
self:switchAction()
else
self:doAction(nextAction)
end
end
end
function ChoregraphySystem:doAction(choregraphyAction)
local args = game.skills:getActionArguments(choregraphyAction)
local type = args.type or "unknown"
local effectArea = self.effectArea
local action = actionList[type]
if (action == nil) then
core.debug:warning("cbs/hero", "unknown action type " .. type .. ' (' .. args.name .. ')')
else
self.action = action(self, args, effectArea)
end
end
function ChoregraphySystem:endAction()
self.action = nil
self.actionHaveEnded = true
end
return ChoregraphySystem