local ChoregraphySystem = Object:extend() local stepObjectList = require "scenes.battlesystem.controllers.fighters.systems.choregraphy.step" local qteObjectList = require "scenes.battlesystem.controllers.fighters.systems.choregraphy.qte" local Predicate = require "birb.classes.predicate" local Conditions = require "scenes.battlesystem.controllers.fighters.systems.choregraphy.conditions" local ACTION_STARTED = 1 local ACTION_FINISHED = 2 function ChoregraphySystem:new(action, choregraphy) self.action = action self.fighter = action.fighter self.actor = self.fighter.actor self.actor:purgeFrameSignal() self.assets = self.fighter.actor.assets self.world = self.actor.world self.target = action.target self.haveSentDamage = false self.currentStepId = 0 self.currentStep = nil self.stepList = choregraphy self.qte = {} self.qte.current = nil self.qte.wasSuccess = false self.qte.isActive = false self.qte.list = {} self.finishedTagActions = {} self.counters = {} end function ChoregraphySystem:update(dt) if (self.qte.current ~= nil) then self.qte.current:updateQte(dt, self.qte.isActive) end if (self.currentStep ~= nil) then self.currentStep:updateStep(dt) else self:switchStep() end end function ChoregraphySystem:findTaggedAction(tag) for stepId, step in ipairs(self.stepList) do if (step[1] == "taggedAction") and (step[2] == tag) then return stepId end end return 0 end function ChoregraphySystem:skipToStepByTag(tag) self:skipToStep(self:findTaggedAction(tag)) end function ChoregraphySystem:skipToStep(id) if (self.stepList[id] ~= nil) then self.currentStepId = id - 1 self:switchStep() end end function ChoregraphySystem:switchStep() if self:haveNextStep() then self.currentStepId = self.currentStepId + 1 local stepData, tagName = self:parseStep(self.stepList[self.currentStepId]) if (stepObjectList[stepData.name] ~= nil and self:checkCondition(stepData.condition)) then self.currentStep = stepObjectList[stepData.name](self, stepData.arguments) if (not utils.string.isEmpty(tagName)) then self.currentStep:addTag(tagName) self:startTagAction(tagName) end end else self:endChoregraphy() end end function ChoregraphySystem:parseStep(step) local tagName = "" if (step[1] == "taggedAction") then tagName = step[2] step = step[3] end local stepData = core.datas:parse("choregraphystep", step) core.debug:print("cbs/choregraphy", "Starting step " .. stepData.name) return stepData, tagName end function ChoregraphySystem:checkCondition(condition) local predicate = Predicate.createPredicate(condition, Conditions, self) return predicate:solve() end function ChoregraphySystem:addQTE(action, origin, qteBaseData, blockProcess, tag) local qteData = core.datas:parse("qtesteps", qteBaseData) if (qteObjectList[qteData.name] ~= nil) then core.debug:print("cbs/choregraphy", "Starting qte " .. qteData.name) self.qte.current = qteObjectList[qteData.name](self, qteData.arguments, 0, 0) self.qte.current:blockAction(action, blockProcess) self.qte.current:setOrigin(origin) self.qte.current:setTag(tag) self.qte.isActive = true end end function ChoregraphySystem:isQteSuccess(qteID) qteID = qteID or #self.qte.list return self.qte.list[qteID] end function ChoregraphySystem:endQte(success) self.qte.isActive = false self.qte.wasSuccess = success table.insert(self.qte.list, success) end function ChoregraphySystem:removeQte() self.qte.current = nil end function ChoregraphySystem:testTagAction(tag, statut) local tagStatut = self.finishedTagActions[tag] or 0 return (statut <= tagStatut) end function ChoregraphySystem:startTagAction(tag) self.finishedTagActions[tag] = ACTION_STARTED end function ChoregraphySystem:finishTagAction(tag) core.debug:print("choregraphy/step", "Tag action " .. tag .. " finished.") self.finishedTagActions[tag] = ACTION_FINISHED end function ChoregraphySystem:getCounter(counterName) return (self.counters[counterName] or 0) end function ChoregraphySystem:setCounter(counterName, number, relative) if (relative == true) then number = number + self:getCounter(counterName) end self.counters[counterName] = number end function ChoregraphySystem:haveFrameSignal(signal) return self.actor:haveFrameSignal(signal) end function ChoregraphySystem:sendDamage(power, type, element, isSpecial) if (self.target ~= nil) then if (self.fighter.isAlive) then self.haveSentDamage = self.fighter:sendDamage(self.target, power, type, element, isSpecial) else self.haveSentDamage = false end end end function ChoregraphySystem:useItemEffect() self.action:useItemEffect() end function ChoregraphySystem:endStep() self.currentStep = nil end function ChoregraphySystem:endChoregraphy() self.actor:choregraphyEnded() self.action:choregraphyEnded() self.fighter.turnSystem:applyDeath() end function ChoregraphySystem:haveNextStep() return ((self.currentStepId + 1) <= #self.stepList) end function ChoregraphySystem:draw() if (self.qte.current ~= nil) then self.qte.current:draw() end end return ChoregraphySystem