chore: use Radiance scenes

This commit is contained in:
Kazhnuz 2021-11-25 10:57:13 +01:00
parent 8c04e08b25
commit 66b77d59ed
165 changed files with 8506 additions and 2399 deletions

View file

@ -0,0 +1,140 @@
local Parent = require("scenes.battlesystem.actors.movable")
local Battler = Parent:extend()
local outputColor = {
good = {0, 1, 0},
bad = {1, 0, 0},
pp = {0.3, 0.8, 1}
}
function Battler:new(world, x, y, z, owner)
Battler.super.new(self, world, x, y, z)
self.isBattler = true
self.isActive = false
self.debugActiveTimer = 0
self.output = {}
self.output.string = "0"
self.output.isBad = true
self.output.type = ""
self.showOutput = false
self.outputY = 0
self.isSelected = false
self.owner = owner
self.isDefending = false
end
function Battler:destroy()
Battler.super.destroy(self)
end
function Battler:getOutputY()
return self.sprHeight or 32
end
function Battler:avoidedAttack()
self:newOutput("", "MISS")
end
function Battler:setDamageNumber(number, isPP)
local type = "good"
if (isPP == true) then type = "pp" end
if (number < 0) then type = "bad" end
local string = math.abs(math.floor(number))
self:newOutput(type, string)
end
function Battler:newOutput(type, string)
self.output.type = type or ""
self.output.string = string or "error"
self.outputY = self:getOutputY() - 8
self.showOutput = true
self.tweens:newTween(0, 0.4, {outputY = self:getOutputY()}, "outQuad")
self.tweens:newTimer(0.5, "removeOutput")
end
function Battler:getOuputColor(type)
return outputColor[type] or {1,1,1}
end
function Battler:setActive()
core.debug:print("cbs/actor","actor " .. self.id .. " is active")
self.isActive = true
self.debugActiveTimer = 0
end
function Battler:update(dt)
Battler.super.update(self, dt)
if (self.isActive) then
self.debugActiveTimer = self.debugActiveTimer + dt
if self.debugActiveTimer >= 0.5 then
core.debug:print("cbs/battler", "counter ended, switching active battler")
self.isActive = false
self.world:switchActiveBattler()
end
end
end
-- Movement
-- Some specific movement function
function Battler:land()
self:changeAnimation("idle")
end
-- CHOREGRAPHY FUNCTIONS
-- All functions related to the choregraphy system
function Battler:choregraphyEnded()
self:resetMovement()
end
-- DAMAGE FUNCTIONS
function Battler:getHurt()
end
function Battler:die()
self:destroy()
end
-- DRAW FUNCTIONS
function Battler:drawOutput()
if (self.showOutput) then
local x, y = self.world.map:gridToPixel(self.x, self.y, true)
local color = self:getOuputColor(self.output.type)
love.graphics.setColor(color[1], color[2], color[3], 1)
self.assets.fonts["hudnbrs_small"]:print(self.output.string, x, y - self.outputY - self.z, "center")
utils.graphics.resetColor()
end
end
function Battler:draw()
local x, y = self.world.map:gridToPixel(self.x, self.y, true)
love.graphics.setColor(1, 0, 0, 1)
love.graphics.rectangle("fill", x - 8, y - 32, 16, 32)
love.graphics.setColor(1, 1, 1, 1)
end
function Battler:initSprite()
if (self.assets.sprites[self.owner.name] == nil) then
self.assets:addSprite(self.owner.name, self:getSpritePath())
end
self.assets.sprites[self.owner.name]:setCustomSpeed(16)
self:setSprite(self.owner.name, 32, 48, true)
self:cloneSprite()
self:changeAnimation("idle")
end
function Battler:validateAction()
end
return Battler

View file

@ -0,0 +1,55 @@
local Battler = require("scenes.battlesystem.actors.battler")
local Ennemy = Battler:extend()
function Ennemy:new(world, x, y, owner)
Ennemy.super.new(self, world, x, y, 0, owner)
self.isEnnemy = true
self.actionPerTurn = 2
self:initSprite()
if (self.owner:haveProtecType("aerial")) then
self.z = 10
self.start.z = 10
end
self.sprHeight = self.owner.abstract.data.hudHeight + 14
end
function Ennemy:setCheapEffect(cheapEffect)
if (cheapEffect) then
self.sprite.sx = 2
self.sprite.sy = 2
end
end
function Ennemy:draw()
self:drawSprite(0, -self.z)
local x, y = self.world.map:gridToPixel(self.x, self.y, true)
self.owner:drawOversprite(x - 12, y - ((self.sprHeight - 8) * self.sprite.sy) - self.z)
if (self.isSelected) then
self.assets.images["cursorpeak"]:draw(x - 7, (y - 24 - self.sprHeight) - self.z)
end
self:drawOutput()
end
function Ennemy:die()
self.assets.sfx["badnicsBoom"]:play()
self.world.obj.GFX(self.world, self.x, self.y, self.z, "boom1", self, false)
self:destroy()
end
function Ennemy:getStats()
return self.data.stats
end
-- ASSETS FUNCTIONS
-- Load and play assets needed by the character
function Ennemy:getSpritePath()
return "datas/gamedata/ennemies/" .. self.owner.category .. "/" .. self.owner.name .. "/sprites"
end
return Ennemy

View file

@ -0,0 +1,73 @@
local Parent = require("scenes.battlesystem.actors.movable")
local GFX = Parent:extend()
local GFX_DIRECTORY = "assets/sprites/gfx/"
function GFX:new(world, x, y, z, spritename, creator, blockProcess, tag)
GFX.super.new(self, world, x, y, z)
if (creator.choregraphy ~= nil) then
self.char = self:getCharacter(creator.choregraphy.fighter)
end
self:setAnimation(spritename)
self.creator = creator
self.blockProcess = blockProcess or false
self.tag = tag or ""
if (not utils.string.isEmpty(self.tag)) then
self:setIndexName(self.tag)
end
self.direction = 1
end
function GFX:getCharacter(fighter)
if (fighter.isHero) then
return fighter.abstract.simplename
end
return nil
end
function GFX:setAnimation(spritename)
local defaultPath = GFX_DIRECTORY .. spritename
if (utils.string.isEmpty(self.char)) then
self:loadAnimation(spritename, defaultPath)
else
local charGFXPath = "datas/gamedata/characters/" .. self.char .. "/gfx/" .. spritename
if (utils.filesystem.exists(charGFXPath .. ".lua")) then
self:loadAnimation(self.char .. spritename, charGFXPath)
else
self:loadAnimation(spritename, defaultPath)
end
end
end
function GFX:loadAnimation(spritename, path)
if self.world.assets.sprites[spritename] == nil then
self.world.assets:addSprite(spritename, path)
end
local width, height = self.world.assets.sprites[spritename]:getDimensions()
self:setSprite(spritename, width/2, height, true)
self:cloneSprite()
end
function GFX:animationEnded(animation)
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
if ((self.creator ~= nil) and (self.creator.choregraphy ~= nil) and (not utils.string.isEmpty(self.tag))) then
self.creator.choregraphy:finishTagAction(self.tag)
end
self:destroy()
end
function GFX:draw()
self:drawSprite(0, -self.z)
end
function GFX:drawShadow()
end
return GFX

View file

@ -0,0 +1,94 @@
local Battler = require("scenes.battlesystem.actors.battler")
local Hero = Battler:extend()
-- INIT FUNCTIONS
-- Initialize the hero
function Hero:new(world, x, y, owner, charnumber)
Hero.super.new(self, world, x, y, 0, owner)
self:initSprite()
self.isKo = false
self.sprHeight = 32
end
-- UPDATE FUNCTION
-- Update the hero
function Hero:update(dt)
Hero.super.update(self, dt)
self:updateAnimation(dt)
end
-- HURT/DEATH FUNCTIONS
function Hero:getHurt()
self:changeAnimation("hurt")
end
function Hero:die()
if (not self.isKo) then
self:changeAnimation("getKo")
self.isKo = true
end
end
function Hero:revive()
if (self.isKo) then
self:changeAnimation("idle")
self.isKo = false
self.isDefending = false
end
end
function Hero:setAsKo()
self:changeAnimation("ko")
self.isKo = true
end
-- ASSETS FUNCTIONS
-- Load and play assets needed by the character
function Hero:getSpritePath()
return "datas/gamedata/characters/" .. self.owner.name .. "/sprites"
end
function Hero:updateAnimation(dt)
if (self.z > 0 and self.jump.useDefaultAnimation) then
if self.zspeed > 0 then
self:changeAnimation("jump")
else
self:changeAnimation("fall")
end
end
self:setCustomSpeed(self.speed * 160 * dt)
end
function Hero:getNewAnimation(animation)
if (animation == "hurt") then
self:changeAnimation("idle")
end
end
function Hero:flee()
if (not self.isKo) then
self:changeAnimation("walk")
self:goTo(-80, self.y, 3)
end
end
-- DRAW FUNCTIONS
-- Draw everything related to the hero
function Hero:draw()
self:drawSprite(0, -self.z)
if (self.isSelected) then
local x, y = self.world.map:gridToPixel(self.x, self.y, true)
self.assets.images["cursorpeak"]:draw(x - 7, y - 24 - 32)
end
self:drawOutput()
end
return Hero

View file

@ -0,0 +1,10 @@
local entities = {}
local baseURI = "scenes.battlesystem.actors."
entities.Hero = require(baseURI .. "hero")
entities.Ennemy = require(baseURI .. "ennemy")
entities.Battler = require(baseURI .. "battler")
entities.GFX = require(baseURI .. "gfx")
return entities

View file

@ -0,0 +1,267 @@
local ParentObject = require "scenes.battlesystem.actors.parent"
local Movable = ParentObject:extend()
local MOVEMENT_NONE = "none"
local MOVEMENT_MOTION = "motion"
local MOVEMENT_TARGET = "target"
local ZGRAVITY = 12
local MIDDLE_ARENA = 6
function Movable:new(world, x, y, z)
Movable.super.new(self, world, x, y, z)
self.direction = utils.math.sign(MIDDLE_ARENA - x)
self.start = {}
self.start.x = x
self.start.y = y
self.start.z = z
self.start.direction = self.direction
self:resetMovement()
end
-- MOVE FUNCTIONS
-- All functions handling the moving
function Movable:resetMovement()
self:resetMotion()
self:resetJump()
self:resetDirection()
self:resetTarget()
end
function Movable:resetMovementType()
self.movementType = MOVEMENT_NONE
end
function Movable:stopMoving()
self:resetMotion()
self:finishAction("goTo")
end
function Movable:update(dt)
Movable.super.update(self, dt)
self:updateMotion(dt)
self:updateDirection()
self:updatePreviousPosition()
end
function Movable:updatePreviousPosition()
self.xprevious = self.x
self.yprevious = self.y
self.zprevious = self.z
end
-- GoTo movement functions
function Movable:goTo(dx, dy, duration)
self:resetMotion()
self:setTarget(dx, dy)
local speed = utils.math.pointDistance(self.x, self.y, dx, dy) / duration
self:setMotionToPoint(speed, dx, dy)
self.movementType = MOVEMENT_TARGET
end
function Movable:goTo3D(dx, dy, dz, duration)
self:resetMotion()
self:resetJump()
self:setTarget(dx, dy, dz)
local speed = utils.math.pointDistance3D(self.x, self.y, self.z, dx, dy, dz) / duration
self:setMotionToPoint(speed, dx, dy, dz)
self.movementType = MOVEMENT_TARGET
end
-- MOTION HANDLING
function Movable:resetMotion()
self.speed, self.angle = 0, 0
self.xspeed, self.yspeed = 0,0
self:updatePreviousPosition()
self:resetMovementType()
end
function Movable:setMotion(speed, angle, vertAngle)
self.speed = speed
self.angle = angle
self.motion3D = (vertAngle ~= nil)
if (self.motion3D) then
self.vertAngle = vertAngle
end
self.movementType = MOVEMENT_MOTION
end
function Movable:setMotionToPoint(speed, dx, dy, dz)
local angle = utils.math.pointDirection(self.x, self.y, dx, dy)
local vertAngle = nil
if (dz ~= nil) then
local distance2D = utils.math.pointDistance(self.x, self.y, dx, dy)
vertAngle = utils.math.pointDirection(0, self.z, distance2D, dz)
end
self:setMotion(speed, angle, vertAngle)
end
function Movable:updateMotion(dt)
self:checkTarget(dt)
self.xspeed, self.yspeed, self.zspeed = self:getMotionCoord()
self.x = self.x + (self.xspeed) * dt
self.y = self.y + (self.yspeed) * dt
self.z = self.z + (self.zspeed) * dt
self:checkGround()
end
function Movable:getMotionCoord()
local gspeed, xspeed, yspeed, zspeed
if (self.motion3D) then
gspeed, zspeed = utils.math.lengthdir(self.speed, self.vertAngle)
xspeed, yspeed = utils.math.lengthdir(gspeed, self.angle)
else
xspeed, yspeed = utils.math.lengthdir(self.speed, self.angle)
zspeed = self:getJumpMotion()
end
return xspeed, yspeed, zspeed
end
-- Target handling
function Movable:setTarget(x, y, z)
self.target = {}
self.target.x = x
self.target.y = y
self.target.z = z
end
function Movable:isTargetActive()
return (self.target ~= nil)
end
function Movable:resetTarget()
self.target = nil
end
function Movable:isNearTarget(distance)
if (not self:isTargetActive()) then
return false
end
if (self.target.z == nil) then
return (utils.math.pointDistance(self.x, self.y, self.target.x, self.target.y) <= distance)
else
return (utils.math.pointDistance3D(self.x, self.y, self.z, self.target.x, self.target.y, self.target.z) <= distance)
end
end
function Movable:checkTarget(dt)
if (self:isTargetActive()) then
local isNearTarget = self:isNearTarget(self.speed * dt)
if (isNearTarget) then
self:finishTarget()
end
end
end
function Movable:finishTarget()
-- TODO: add a one-time signal to target handling
if (self.movementType == MOVEMENT_TARGET) then
self.x = self.target.x
self.y = self.target.y
if (self.target.z ~= nil) then
self.z = self.target.z
end
self:stopMoving()
end
self:resetTarget()
end
-- Direction handling
function Movable:resetDirection()
self.direction = self.start.direction
self.directionPrevious = self.start.direction
self.directionLocked = false
end
function Movable:updateDirection()
-- Handle direction
if math.abs(self.xspeed) >= 0.01 then
if not (self.directionLocked or self.jump.lockDir) then
self.direction = utils.math.sign(self.xspeed)
end
end
end
-- Jump system
function Movable:resetJump()
self.jump = {}
self.jump.useDefaultAnimation = true
self.jump.isJumping = false
self.jump.bounceNumber = 0
self.jump.stopWhenLanding = false
self.jump.lockDir = false
self.zspeed = 0
self.motion3D = false
self.vertAngle = 0
end
function Movable:stopJumping()
self.z = 0
self.tweens:newTimer(0.01, "jump")
if (self.jump.stopWhenLanding) then
self:resetMotion()
end
self:resetJump()
self:land()
end
function Movable:land()
-- Empty function
end
function Movable:setJump(power, bounceNumber, useDefaultAnimation)
self.zspeed = (power * 60)
self.jump.useDefaultAnimation = useDefaultAnimation
self.jump.bounceNumber = bounceNumber
self.jump.isJumping = true
end
function Movable:jumpTo(dx, dy, height, speed, useDefaultAnimation)
height = height or 4
self:setMotionToPoint(speed, dx, dy)
self:setJump(height, 0, useDefaultAnimation)
self.jump.stopWhenLanding = true
end
function Movable:jumpBack(height, speed)
self:jumpTo(self.start.x, self.start.y, height, speed, true)
self.jump.lockDir = true
end
function Movable:getJumpMotion()
if (self.jump.isJumping) then
return self.zspeed - ZGRAVITY
else
return 0
end
end
function Movable:checkGround()
if (self.z <= 0 and self.jump.isJumping) then
if (self.jump.bounceNumber > 0) then
self.zspeed = self.zspeed * -0.5
self.jump.bounceNumber = self.jump.bounceNumber - 1
else
self:stopJumping()
end
end
end
return Movable

View file

@ -0,0 +1,296 @@
local Parent = Object:extend() -- On créer la classe des entitées, c'est la classe de base
local maputils = require "scenes.battlesystem.utils"
local TweenManager = require "birb.classes.time"
-- INIT FUNCTION
-- Initilize the actor
function Parent:new(world, x, y, z)
self.depth = 0
self.x = x
self.y = y
self.z = z or 0
self.direction = 1
--self.id = self.world.creationID
self.world = world
self.assets = self.world.assets
self.scene = self.world.scene
self.map = self.world.map
self.maputils = maputils
self.isHero = false
self.isActor = false
self.isEnnemy = false
self.isDestroyed = false
self.tweens = TweenManager(self)
self:resetTags()
self:setSprite()
self:register()
end
function Parent:setIndexName(indexName)
self.indexName = indexName
self.world.index[self.indexName] = self
end
function Parent:register()
self.world:registerActor(self)
end
function Parent:destroy()
self.world:destroyActor(self)
self.isDestroyed = true
if (self.indexName ~= nil) then
self.world.index[self.indexName] = nil
end
end
function Parent:update(dt)
self:updateSprite(dt)
self.tweens:update(dt)
end
-- GET FUNCTIONS
-- Get informations
function Parent:getCoordinate()
return self.x, self.y, self.z
end
-- SPRITE FUNCTIONS
-- Handle the character sprite
function Parent:setSprite(spritename, ox, oy, active)
self.sprite = {}
self.sprite.name = spritename or nil
self.sprite.ox = ox or 0
self.sprite.oy = oy or 0
self.sprite.sx = 1
self.sprite.sy = 1
self.sprite.exist = (spritename ~= nil)
self.sprite.clone = nil
self.sprite.active = active or false
self:resetFrameSignal()
end
function Parent:cloneSprite()
if self.sprite.name ~= nil then
self.sprite.clone = self.assets.sprites[self.sprite.name]:clone()
self.sprite.clone:setCallback(self)
end
end
function Parent:changeAnimation(animation, restart)
self:resetFrameSignal()
if (self.sprite.clone == nil) then
self.assets.sprites[self.sprite.name]:changeAnimation(animation, restart)
else
self.sprite.clone:changeAnimation(animation, restart)
end
end
function Parent:setAnimSpeed(speed)
if (self.sprite.clone == nil) then
self.assets.sprites[self.sprite.name]:setSpeedFactor(speed)
else
self.sprite.clone:setSpeedFactor(speed)
end
end
function Parent:animationEnded(animation)
if (self.currentlyBlocking ~= nil and self.blockedBy=="animation") then
self:unblockChoregraphy()
end
self:unlockTag("animation")
self:getNewAnimation(animation)
end
function Parent:getNewAnimation(animation)
end
function Parent:setCustomSpeed(customSpeed)
if (self.sprite.clone == nil) then
self.assets.sprites[self.sprite.name]:setCustomSpeed(customSpeed)
else
self.sprite.clone:setCustomSpeed(customSpeed)
end
end
function Parent:updateSprite(dt)
if (self.sprite.clone ~= nil) then
self.sprite.clone:update(dt)
end
end
function Parent:setSpriteScallingX(sx)
local sx = sx or 1
self.sprite.sx = sx
end
function Parent:setSpriteScallingY(sy)
local sy = sy or 1
self.sprite.sy = sy
end
function Parent:getCurrentAnimation()
if (self.sprite.clone == nil) then
return self.assets.sprites[self.sprite.name]:getCurrentAnimation()
else
return self.sprite.clone:getCurrentAnimation()
end
end
function Parent:getSpriteScalling()
return self.sprite.sx, self.sprite.sy
end
function Parent:getFrame()
if (self.sprite.name ~= nil) then
if (self.sprite.clone ~= nil) then
return self.sprite.clone:getFrame()
else
return self.assets.sprites[self.sprite.name]:getFrame()
end
end
end
function Parent:getRelativeFrame()
if (self.sprite.name ~= nil) then
if (self.sprite.clone ~= nil) then
return self.sprite.clone:getRelativeFrame()
else
return self.assets.sprites[self.sprite.name]:getRelativeFrame()
end
end
end
function Parent:getAnimationDuration()
if (self.sprite.name ~= nil) then
if (self.sprite.clone ~= nil) then
return self.sprite.clone:getAnimationDuration()
else
return self.assets.sprites[self.sprite.name]:getAnimationDuration()
end
end
end
function Parent:drawSprite(tx, ty)
utils.graphics.resetColor()
local x, y = self.world.map:gridToPixel(self.x, self.y, true)
local tx = tx or 0
local ty = ty or 0
if (self.sprite.active) then
local sx = self.direction * self.sprite.sx
local sy = self.sprite.sy
if (self.sprite.clone ~= nil) then
self.sprite.clone:draw(x + tx, y + ty, 0, sx, sy, self.sprite.ox, self.sprite.oy)
else
self.assets.sprites[self.sprite.name]:draw(x + tx, y + ty, 0, sx, sy, self.sprite.ox, self.sprite.oy)
end
end
end
-- FRAME SIGNAL
-- Get signals from specific frames of the animation
function Parent:resetFrameSignal()
self.frameSignals = {}
end
function Parent:receiveFrameSignal(signal)
table.insert(self.frameSignals, signal)
end
function Parent:haveFrameSignal(signal)
return utils.table.contain(self.frameSignals, signal)
end
-- TAGS
-- Handle tags
function Parent:resetTags()
self.tags = {}
self.choregraphy = nil
end
function Parent:addTaggedAction(tag, choregraphy, taggedBy)
if (not utils.string.isEmpty(tag)) then
self.tags[tag] = taggedBy
self.choregraphy = choregraphy
end
end
function Parent:unlockTag(taggedBy)
for tag, actionTag in pairs(self.tags) do
if (self.choregraphy ~= nil) and (actionTag == taggedBy) then
self.choregraphy:finishTagAction(tag)
self.tags[tag] = nil
end
end
end
-- CHOREGRAPHY BLOCKING
-- Handle blocking/unblocking the choregraphy
function Parent:blockChoregraphy(isBlocking, currentlyBlocking, blockedBy)
if (isBlocking) then
self.currentlyBlocking = currentlyBlocking
self.blockedBy = blockedBy
end
end
function Parent:unblockChoregraphy()
self.currentlyBlocking:finish()
self.currentlyBlocking = nil
end
function Parent:timerResponse(signal)
self:finishAction(signal)
if (signal == "removeOutput") then
self.showOutput = false
end
end
function Parent:finishAction(signal)
if ((self.currentlyBlocking ~= nil) and (signal == self.blockedBy)) then
self:unblockChoregraphy()
end
self:unlockTag(signal)
end
-- DRAW FUNCTIONS
-- Handle draw functions
function Parent:draw()
end
function Parent:drawShadow()
local x, y = self.world.map:gridToPixel(self.x, self.y, true)
self.assets.images["actorsShadow"]:draw(x, y, 0, self.sprite.sx, self.sprite.sy, 12, 5)
if (self.isSelected == true) then
self.assets.sprites["cursorground"]:draw(x - 2, y - 1, 0, 1, 1, 12, 5)
end
end
function Parent:drawHUD()
end
return Parent

View file

@ -0,0 +1,43 @@
local Conditions = {}
function Conditions.sentDamage(cond, predicate, asker)
return asker.haveSentDamage
end
function Conditions.qteSuccess(cond, predicate, asker)
return asker:isQteSuccess(tonumber(cond[2]))
end
function Conditions.qteFailure(cond, predicate, asker)
return (Conditions.qteSuccess(cond, predicate, asker) == false)
end
function Conditions.none(cond, predicate, asker)
return true
end
function Conditions.actionFinished(cond, predicate, asker)
return asker:testTagAction(cond[2], 2)
end
function Conditions.actionStarted(cond, predicate, asker)
return asker:testTagAction(cond[2], 1)
end
function Conditions.counter(cond, predicate, asker)
return predicate.utils.testVariables(asker:getCounter(cond[2]), cond[3], cond[4])
end
function Conditions.haveFrameSignal(cond, predicate, asker)
return asker:haveFrameSignal(cond[2])
end
function Conditions.hasNextTarget(cond, predicate, asker)
return asker:hasNextTarget()
end
function Conditions.hasSubChoregraphiesActive(cond, predicate, asker)
return asker:hasSubChoregraphiesActive()
end
return Conditions

View file

@ -0,0 +1,51 @@
local ChoregraphySystem = Object:extend()
local QteMixin = require "scenes.battlesystem.choregraphy.mixins.qtes"
local StepsMixin = require "scenes.battlesystem.choregraphy.mixins.steps"
local TagsMixin = require "scenes.battlesystem.choregraphy.mixins.tags"
local CountersMixin = require "scenes.battlesystem.choregraphy.mixins.counters"
local WrappersMixin = require "scenes.battlesystem.choregraphy.mixins.wrappers"
local SubChoregraphiesMixin = require "scenes.battlesystem.choregraphy.mixins.subchoregraphies"
local TweenManager = require "birb.classes.time"
ChoregraphySystem:implement(QteMixin)
ChoregraphySystem:implement(StepsMixin)
ChoregraphySystem:implement(TagsMixin)
ChoregraphySystem:implement(CountersMixin)
ChoregraphySystem:implement(WrappersMixin)
ChoregraphySystem:implement(SubChoregraphiesMixin)
function ChoregraphySystem:new(action, choregraphy, subChoregraphy)
self:initWrappers(action)
self:initSteps(choregraphy)
self:initQte()
self:initTagActions()
self:initCounters()
self:initSubchoregraphies(subChoregraphy)
self.tweens = TweenManager(self)
self.actor:resetFrameSignal()
end
function ChoregraphySystem:update(dt)
self:updateSteps(dt)
self.tweens:update(dt)
self:updateSubChoregraphies(dt)
end
function ChoregraphySystem:timerResponse(signal)
if (signal == "startNextTarget") then
self:startNextTarget()
end
end
function ChoregraphySystem:endChoregraphy()
self.actor:choregraphyEnded()
self.action:choregraphyEnded()
self.fighter.turnSystem:applyDeath()
end
return ChoregraphySystem

View file

@ -0,0 +1,18 @@
local CountersMixin = Object:extend()
function CountersMixin:initCounters()
self.counters = {}
end
function CountersMixin:getCounter(counterName)
return (self.counters[counterName] or 0)
end
function CountersMixin:setCounter(counterName, number, relative)
if (relative == true) then
number = number + self:getCounter(counterName)
end
self.counters[counterName] = number
end
return CountersMixin

View file

@ -0,0 +1,54 @@
local QteMixin = Object:extend()
local qteObjectList = require "scenes.battlesystem.choregraphy.qte"
function QteMixin:initQte()
self.qte = {}
self.qte.current = nil
self.qte.wasSuccess = false
self.qte.isActive = false
self.qte.list = {}
end
function QteMixin:updateQte(dt)
if (self.qte.current ~= nil) then
self.qte.current:updateQte(dt, self.qte.isActive)
end
end
function QteMixin:isQteSuccess(qteID)
qteID = qteID or #self.qte.list
return self.qte.list[qteID]
end
function QteMixin: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 QteMixin:endQte(success)
self.qte.isActive = false
self.qte.wasSuccess = success
table.insert(self.qte.list, success)
self.rewards:addQTE(success)
end
function QteMixin:removeQte()
self.qte.current = nil
end
function QteMixin:drawQte()
if (self.qte.current ~= nil) then
self.qte.current:draw()
end
end
return QteMixin

View file

@ -0,0 +1,74 @@
local StepsMixins = Object:extend()
local Predicate = require "birb.classes.predicate"
local Conditions = require "scenes.battlesystem.choregraphy.conditions"
local stepObjectList = require "scenes.battlesystem.choregraphy.step"
function StepsMixins:initSteps(choregraphy)
self.currentStepId = 0
self.currentStep = nil
self.stepList = choregraphy
end
function StepsMixins:haveNextStep()
return ((self.currentStepId + 1) <= #self.stepList)
end
-- UPDATE
function StepsMixins:updateSteps(dt)
if (self.currentStep ~= nil) then
self.currentStep:updateStep(dt)
else
self:switchStep()
end
end
function StepsMixins:checkCondition(condition)
local predicate = Predicate.createPredicate(condition, Conditions, self)
return predicate:solve()
end
function StepsMixins: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 StepsMixins: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)
self.currentStep:addTag(tagName)
end
else
self:endChoregraphy()
end
end
-- SKIP OR END STEPS
function StepsMixins:skipToStepByTag(tag)
self:skipToStep(self:findTaggedAction(tag))
end
function StepsMixins:skipToStep(id)
if (self.stepList[id] ~= nil) then
self.currentStepId = id - 1
self:switchStep()
end
end
function StepsMixins:endStep()
self.currentStep = nil
end
return StepsMixins

View file

@ -0,0 +1,73 @@
local SubChoregraphiesMixin = Object:extend()
local SubChoregraphy = require "scenes.battlesystem.choregraphy.subchoregraphy"
function SubChoregraphiesMixin:initSubchoregraphies(subChoregraphy)
self.subChoregraphies = {}
self.subChoregraphies.isActive = (self.target == nil)
self.subChoregraphies.steps = subChoregraphy
self.subChoregraphies.currentTarget = 0
self.subChoregraphies.waitTime = 0
self.subChoregraphies.list = {}
end
function SubChoregraphiesMixin:startSubChoregraphies(waitTime)
self.subChoregraphies.currentTarget = 0
self.subChoregraphies.waitTime = waitTime
self:startNextTarget()
end
function SubChoregraphiesMixin:updateSubChoregraphies(dt)
for _, subchoregraphy in ipairs(self.subChoregraphies.list) do
subchoregraphy:update(dt)
end
end
function SubChoregraphiesMixin:startNextTarget()
local target = self:getNextTarget()
if (target ~= nil) then
SubChoregraphy(self, target, self.subChoregraphies.steps)
self.tweens:newTimer(self.subChoregraphies.waitTime, "startNextTarget")
end
end
function SubChoregraphiesMixin:registerSubChoregraphy(subChoregraphy)
table.insert(self.subChoregraphies.list, subChoregraphy)
self:updateSubChoregraphyIds()
end
function SubChoregraphiesMixin:removeSubChoregraphy(subChoregraphy)
self:updateSubChoregraphyIds()
table.remove(self.subChoregraphies.list, subChoregraphy.id)
self:updateSubChoregraphyIds()
end
function SubChoregraphiesMixin:updateSubChoregraphyIds()
for id, subchoregraphy in ipairs(self.subChoregraphies.list) do
subchoregraphy.id = id
end
end
function SubChoregraphiesMixin:getNextTarget()
if (self:hasNextTarget()) then
self.subChoregraphies.currentTarget = self.subChoregraphies.currentTarget + 1
return self.targetList[self.subChoregraphies.currentTarget]
end
end
function SubChoregraphiesMixin:hasNextTarget()
return (self.targetList[self.subChoregraphies.currentTarget + 1] ~= nil)
end
function SubChoregraphiesMixin:hasSubChoregraphiesActive()
return (#self.subChoregraphies.list > 0)
end
function SubChoregraphiesMixin:drawSubChoregraphies()
for _, subchoregraphy in ipairs(self.subChoregraphies.list) do
subchoregraphy:draw()
end
end
return SubChoregraphiesMixin

View file

@ -0,0 +1,33 @@
local TagsMixin = Object:extend()
local ACTION_STARTED = 1
local ACTION_FINISHED = 2
function TagsMixin:initTagActions()
self.finishedTagActions = {}
end
function TagsMixin: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 TagsMixin:testTagAction(tag, statut)
local tagStatut = self.finishedTagActions[tag] or 0
return (statut <= tagStatut)
end
function TagsMixin:startTagAction(tag)
self.finishedTagActions[tag] = ACTION_STARTED
end
function TagsMixin:finishTagAction(tag)
core.debug:print("choregraphy/step", "Tag action " .. tag .. " finished.")
self.finishedTagActions[tag] = ACTION_FINISHED
end
return TagsMixin

View file

@ -0,0 +1,70 @@
local InfosMixin = Object:extend()
function InfosMixin:initWrappers(action, target)
self.action = action
self.fighter = action.fighter
self.actor = self.fighter.actor
self.assets = self.fighter.actor.assets
self.world = self.actor.world
self.scene = self.world.scene
self.turns = self.scene.turns
self.rewards = self.turns.rewards
self:initTargets(target or action.target)
end
function InfosMixin:initTargets(target)
self.target = target
self.haveSentDamage = false
if (self.target == nil) then
local _, targetEnnemies = self.action:needTarget()
self.targetList = self.fighter:getTargets(targetEnnemies == false)
end
end
function InfosMixin:getActor(name)
if (name == "actor") then
return self.actor
elseif (name == "target") then
return self:getTargetActor()
else
return self.fighter.world:getActorByName(name)
end
end
function InfosMixin:getTargetActor()
return self.target.actor
end
function InfosMixin:sendDamage(power, type, element, isSpecial)
if (self.fighter.isAlive) then
if (self.target ~= nil) then
self.haveSentDamage = self.fighter:sendDamage(self.target, power, type, element, isSpecial)
else
self.haveSentDamage = self.fighter:sendDamageToAll(self.targetList, power, type, element, isSpecial)
end
else
self.haveSentDamage = false
end
end
function InfosMixin:sendStatus(status, duration, force)
if (self.fighter.isAlive) then
if (self.target ~= nil) then
self.fighter:sendStatus(self.target, status, duration, force)
else
self.fighter:sendStatus(self.targetList, status, duration, force)
end
end
end
function InfosMixin:haveFrameSignal(signal)
return self.actor:haveFrameSignal(signal)
end
function InfosMixin:useItemEffect()
self.action:useItemEffect()
end
return InfosMixin

View file

@ -0,0 +1,7 @@
local qtes = {}
local baseURI = "scenes.battlesystem.choregraphy.qte."
qtes["simplePrompt"] = require (baseURI .. "simpleprompt")
return qtes

View file

@ -0,0 +1,169 @@
local GuiElements = require "birb.modules.gui.elements.parent"
local QteParent = GuiElements:extend()
local Prompts = require "scenes.battlesystem.choregraphy.qte.prompts"
function QteParent:new(choregraphySystem, arguments)
self.choregraphy = choregraphySystem
self.arguments = arguments
self.isBlocking = nil
self.prompts = Prompts(self)
self.timer = 0
self.timerActive = false
self.isSuccess = false
self.tag = ""
QteParent.super.new(self, "qte", -1, -1, 1, 1)
self:start()
self.isStarted = true
self:getFocus()
end
function QteParent:setTag(tag)
self.tag = tag
end
function QteParent:blockAction(action, isBlocked)
if (isBlocked) then
self.isBlocking = action
end
end
function QteParent:endQte()
self.choregraphy:endQte(self.isSuccess)
if (self.isBlocking ~= nil) then
self.isBlocking:getSignal("qteEnded")
end
if (not utils.string.isEmpty(self.tag)) then
self.choregraphy:finishTagAction(self.tag)
end
end
function QteParent:setOrigin(origin)
local x, y, z = 424/2, 240/2, 0
local argy = 16
local battleCoord = false
if (origin == "target") then
local target = self.choregraphy.action.target
x, y = target.actor:getCoordinate()
z = target.actor.z
battleCoord = true
elseif (origin == "start") then
x, y = self.choregraphy.actor.start.x, self.choregraphy.actor.start.y
battleCoord = true
elseif (origin == "actor") then
x, y = self.choregraphy.actor:getCoordinate()
z = self.choregraphy.actor.z
battleCoord = true
end
if (not battleCoord) then
self.x, self.y = x, y
else
x, y = self.choregraphy.world.map:gridToPixel(x, y, true)
self.x, self.y = x, y - argy - z
end
end
function QteParent:updateElement(dt)
QteParent.super.updateElement(self, dt)
self.prompts:update(dt)
end
function QteParent:keypressed(key)
self:verifyPrompts(key)
end
function QteParent:timerResponse(timer)
if (timer == "qteTimer") then
core.debug:print("qte", "Timer finished")
if (self.timerActive) then
self:finish(self:isSuccessOnEnd())
end
elseif (timer == "startTimer") then
core.debug:print("qte", "Timer started with " .. self.timer .. " seconds")
self.tweens:newTimer(self.timer, "qteTimer")
self.timerActive = true
self.prompts.defaultTimerValue = 0
elseif (timer == "endQte") then
self.choregraphy:removeQte()
self:destroy()
end
end
function QteParent:finish(success)
self.isSuccess = success
self.timerActive = false
self.tweens:newTimer(self.prompts.BEGINTIME, "endQte")
self:endQte()
end
function QteParent:verifyPrompts(key)
local promptResult = self.prompts:verifyPrompts(key)
if (promptResult == 1) then
self:promptSuccess()
elseif (promptResult == -1) then
self:fail()
end
end
function QteParent:draw()
self:drawOverButtons()
self.prompts:draw(self.x, self.y)
self:drawUnderButtons()
end
-- USABLE FUNCTIONS
-- Use these functions to access some of the API
function QteParent:setTimer(time)
core.debug:print("qte", "Timer started with " .. time .. " prepared")
self.timer = time
self.tweens:newTimer(self.prompts.BEGINTIME, "startTimer")
end
function QteParent:delay(time)
core.debug:print("qte", "Timer delayed by " .. time .. " seconds")
self.tweens:delayTimer(time, "qteTimer", false)
end
function QteParent:getTimerInfo()
return self.tweens:getTimerInfo("qteTimer")
end
function QteParent:success()
self:finish(true)
end
function QteParent:fail()
self:finish(false)
end
-- PUBLIC API
-- The functions that the children must overrides
function QteParent:start()
end
function QteParent:update(dt)
--
end
function QteParent:promptSuccess()
end
function QteParent:isSuccessOnEnd()
return false
end
function QteParent:drawOverButtons()
end
function QteParent:drawUnderButtons()
end
return QteParent

View file

@ -0,0 +1,139 @@
local Button = Object:extend()
local ButtonCircle = Object:extend()
local TweenManager = require "birb.classes.time"
local keys = {"A", "B", "C", "select", "up", "down", "left", "right"}
local BTN_SIZE = 21
local CANVAS_SIZE = 21+2
local SHAKETIME = 0.02
local SHAKEPOWER = 4
local function myStencilFunction()
love.graphics.circle("fill", CANVAS_SIZE/2, CANVAS_SIZE/2, BTN_SIZE/2 - 1)
end
function Button:new(prompt, key, number, beginTime)
self.prompt = prompt
self.key = key
self.number = number or 1
self.showNumber = (self.number > 1)
self.isPressed = false
self.lum = 1
self.opacity = 0
self.frame = self:getFrame()
self.scale = 1.25
self.isFailed = false
self.shakeTimer = SHAKETIME
self.shakex, self.shakey = 0, 0
self.circles = {}
self.timerTexture = nil
self.tweens = TweenManager(self)
self.tweens:newTween(0, beginTime, {opacity = 1, scale = 1}, "inOutQuart")
end
function Button:getFrame()
for i, key in ipairs(keys) do
if (key == self.key) then
return i
end
end
error("Non existing key " .. self.key)
end
function Button:update(dt, isFirst)
self.tweens:update(dt)
for i, circle in ipairs(self.circles) do
circle:update(dt)
end
if (self.isFailed) then
self.shakeTimer = self.shakeTimer - dt
if (self.shakeTimer < 0) then
self.shakeTimer = SHAKETIME
self.shakex = math.random(SHAKEPOWER*2) - (SHAKEPOWER)
self.shakey = math.random(SHAKEPOWER*2) - (SHAKEPOWER)
end
end
if (isFirst) then
self.timerTexture = love.graphics.newCanvas(CANVAS_SIZE, CANVAS_SIZE)
love.graphics.setCanvas({self.timerTexture, stencil = true})
love.graphics.setColor(0.5, 0.5, 0.5, 1)
love.graphics.circle("fill", CANVAS_SIZE/2, CANVAS_SIZE/2, BTN_SIZE/2)
utils.graphics.setColorHSV(self.prompt:getTimer()/3, 1, 1)
love.graphics.stencil(myStencilFunction, "replace", 1)
love.graphics.setStencilTest("greater", 0)
love.graphics.arc("fill", CANVAS_SIZE/2, CANVAS_SIZE/2, BTN_SIZE/2, 0 - (math.pi/2), ((math.pi*2*self.prompt:getTimer()) - (math.pi/2)), 16)
love.graphics.setStencilTest()
love.graphics.setCanvas()
utils.graphics.resetColor()
end
end
function Button:verifyPrompts(key, removeWhenPressed)
local mustBeRemoved = false
local keyValue = 0
self.lum = 1
if (key == self.key) then
keyValue = 1
self.lum = 0.8
table.insert(self.circles, ButtonCircle())
else
keyValue = -1
self.isFailed = true
end
if (removeWhenPressed and keyValue == 1) then
self.number = self.number - 1
if (self.number == 0) then
mustBeRemoved = true
end
end
return keyValue, mustBeRemoved
end
function Button:finish(success)
local scale = 0.75
if (success == true) then
scale = 1.25
end
self.tweens:newTween(0, 0.15, {opacity = 0, scale = scale}, "inOutQuart")
end
function Button:draw(x, y, isFirst)
local x, y = x + self.shakex, y + self.shakey
love.graphics.setColor(1,1,1,self.circleOpacity)
for i, circle in ipairs(self.circles) do
circle:draw(x, y)
end
love.graphics.setColor(self.lum,self.lum,self.lum,self.opacity)
if (isFirst and self.timerTexture ~= nil) then
love.graphics.draw(self.timerTexture, x, y, 0, -self.scale, self.scale, 12, 11)
end
self.prompt.assets.tileset["qtebtn"]:drawTile(self.frame, x, y, 0, self.scale, self.scale, 8, 8)
love.graphics.setColor(1,1,1,1)
if (self.number > 0 and self.showNumber) then
self.prompt.assets.fonts["hudnbrs_small"]:draw(utils.math.numberToString(self.number, 2), x, y + 2, -1, "left")
end
end
function ButtonCircle:new()
self.radius = 6
self.opacity = 1
self.tweens = TweenManager(self)
self.tweens:newTween(0, 0.2, {radius = 12}, "inOutQuart")
self.tweens:newTween(0.1, 0.1, {opacity = 0}, "inOutQuart")
end
function ButtonCircle:update(dt)
self.tweens:update(dt)
end
function ButtonCircle:draw(x, y)
love.graphics.setColor(1,1,1,self.opacity)
love.graphics.circle("line",x,y,self.radius, 16)
end
return Button

View file

@ -0,0 +1,65 @@
local QtePrompts = Object:extend()
local Button = require "scenes.battlesystem.choregraphy.qte.prompts.button"
QtePrompts.BEGINTIME = 0.2
function QtePrompts:new(qte)
self.qte = qte
self.canPress = true
self.removeWhenPressed = true
self.assets = qte.choregraphy.assets
self.scene = core.scenemanager.currentScene
self.current = 1
self.defaultTimerValue = 1
self.list = {}
end
function QtePrompts:add(key, number)
table.insert(self.list, Button(self, key, number, QtePrompts.BEGINTIME))
end
function QtePrompts:getTimer()
local defaultValue = self.defaultTimerValue
local _, _, timerValue = self.qte:getTimerInfo()
return timerValue or defaultValue
end
function QtePrompts:update(dt)
for i, button in ipairs(self.list) do
button:update(dt, (i == self.current))
end
end
function QtePrompts:verifyPrompts(key)
local buttonValue, mustBeRemoved = 0, false
if (self.list[self.current] ~= nil) then
buttonValue, mustBeRemoved = self.list[self.current]:verifyPrompts(key, self.removeWhenPressed)
if (not self.canPress and buttonValue == 1) then
buttonValue = -1
end
if (mustBeRemoved) then
self.list[self.current]:finish(true)
self.current = self.current + 1
end
end
for i, button in ipairs(self.list) do
if (buttonValue == -1 and (i ~= self.current)) then
button:finish(false)
end
end
return buttonValue
end
function QtePrompts:isOver()
return (self.current > #self.list)
end
function QtePrompts:draw(x, y)
local SIZE = 20
for i, button in ipairs(self.list) do
button:draw(x + (SIZE*(i-1)) - ((SIZE/2)*(#self.list-1)), y, (i == self.current))
end
end
return QtePrompts

View file

@ -0,0 +1,17 @@
local Parent = require "scenes.battlesystem.choregraphy.qte.parent"
local SimplePrompt = Parent:extend()
function SimplePrompt:start()
self:setTimer(self.arguments.duration)
for i, keyData in ipairs(self.arguments.key) do
self.prompts:add(keyData[1], keyData[2])
end
end
function SimplePrompt:promptSuccess()
if (self.prompts:isOver()) then
self:success()
end
end
return SimplePrompt

View file

@ -0,0 +1,29 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local StepGFX = StepParent:extend()
function StepGFX:new(controller, args)
StepGFX.super.new(self, controller, args, true)
end
function StepGFX:start()
local x, y, z = self:getStepCoordinate()
self.choregraphy.world.obj.GFX(self.choregraphy.world, x, y, z, self.arguments.sprite, self, self.arguments.blockProcess, self.tag)
if (not self.arguments.blockProcess) then
self:finish()
end
end
function StepGFX:update(dt)
end
function StepGFX:getSignal(signal)
if (signal == "gfxEnded") then
self:finish()
end
end
return StepGFX

View file

@ -0,0 +1,26 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local StepQTE = StepParent:extend()
function StepQTE:new(controller, args)
StepQTE.super.new(self, controller, args, true)
end
function StepQTE:start()
self.choregraphy:addQTE(self, self.arguments.origin, self.arguments.qteData, self.arguments.blockProcess, self.tag)
if (not self.arguments.blockProcess) then
self:finish()
end
end
function StepQTE:update(dt)
end
function StepQTE:getSignal(signal)
if (signal == "qteEnded") then
self:finish()
end
end
return StepQTE

View file

@ -0,0 +1,30 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local GoToStep = StepParent:extend()
function GoToStep:new(controller, args)
GoToStep.super.new(self, controller, args, true)
end
function GoToStep:start()
local x, y = self:getStepCoordinate()
local actor = self:getActor(self.arguments.who)
actor:goTo(x, y, self.arguments.duration)
actor:addTaggedAction(self.tag, self.choregraphy, "goTo")
if (self.arguments.blockProcess == false) then
self:finish()
else
actor:blockChoregraphy(self.arguments.blockProcess, self, "goTo")
end
end
function GoToStep:update(dt)
end
function GoToStep:getSignal(signal)
end
return GoToStep;

View file

@ -0,0 +1,30 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local GoTo3DStep = StepParent:extend()
function GoTo3DStep:new(controller, args)
GoTo3DStep.super.new(self, controller, args, true)
end
function GoTo3DStep:start()
local x, y, z = self:getStepCoordinate()
local actor = self:getActor(self.arguments.who)
actor:goTo3D(x, y, z, self.arguments.duration)
actor:addTaggedAction(self.tag, self.choregraphy, "goTo")
if (self.arguments.blockProcess == false) then
self:finish()
else
actor:blockChoregraphy(self.arguments.blockProcess, self, "goTo")
end
end
function GoTo3DStep:update(dt)
end
function GoTo3DStep:getSignal(signal)
end
return GoTo3DStep;

View file

@ -0,0 +1,25 @@
local actions = {}
local baseURI = "scenes.battlesystem.choregraphy.step."
actions["addGFX"] = require(baseURI .. "addGFX")
actions["addQTE"] = require(baseURI .. "addQTE")
actions["goTo"] = require(baseURI .. "goTo")
actions["goTo3D"] = require(baseURI .. "goTo3D")
actions["stopMov"] = require(baseURI .. "stopMov")
actions["jumpBack"] = require(baseURI .. "jumpBack")
actions["jump"] = require(baseURI .. "jump")
actions["playSFX"] = require(baseURI .. "playSFX")
actions["sendDamage"] = require(baseURI .. "sendDamage")
actions["sendStatus"] = require(baseURI .. "sendStatus")
actions["setAnimation"] = require(baseURI .. "setAnimation")
actions["setAnimSpeed"] = require(baseURI .. "setAnimSpeed")
actions["wait"] = require(baseURI .. "wait")
actions["waitFor"] = require(baseURI .. "waitFor")
actions["skipTo"] = require(baseURI .. "skipTo")
actions["waitActorFinished"] = require(baseURI .. "waitActorFinished")
actions["useItemEffect"] = require(baseURI .. "useItemEffect")
actions["setCounter"] = require(baseURI .. "setCounter")
actions["startSubChoregraphies"] = require(baseURI .. "startSubChoregraphies")
return actions

View file

@ -0,0 +1,29 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local JumpStep = StepParent:extend()
function JumpStep:new(controller, args)
JumpStep.super.new(self, controller, args, true)
end
function JumpStep:start()
local actor = self:getActor(self.arguments.who)
actor:setJump(self.arguments.power, 0, self.arguments.useDefaultAnimation)
actor:addTaggedAction(self.tag, self.choregraphy, "jump")
if (self.arguments.blockProcess == false) then
self:finish()
else
actor:blockChoregraphy(self.arguments.blockProcess, self, "jump")
end
end
function JumpStep:update(dt)
end
function JumpStep:getSignal(signal)
end
return JumpStep;

View file

@ -0,0 +1,29 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local JumpBackStep = StepParent:extend()
function JumpBackStep:new(controller, args)
JumpBackStep.super.new(self, controller, args, true)
end
function JumpBackStep:start()
local actor = self:getActor(self.arguments.who)
actor:jumpBack(self.arguments.height, self.arguments.speed)
actor:addTaggedAction(self.tag, self.choregraphy, "jump")
if (self.arguments.blockProcess == false) then
self:finish()
else
actor:blockChoregraphy(self.arguments.blockProcess, self, "jump")
end
end
function JumpBackStep:update(dt)
end
function JumpBackStep:getSignal(signal)
end
return JumpBackStep;

View file

@ -0,0 +1,60 @@
local StepParent = Object:extend()
function StepParent:new(choregraphySystem, arguments, canBeAsync)
self.choregraphy = choregraphySystem
self.arguments = arguments
self.isStarted = false
self.canBeAsync = (canBeAsync == true)
self.tag = ""
end
function StepParent:addTag(tag)
if (not utils.string.isEmpty(tag)) then
if (self.canBeAsync) then
core.debug:print("choregraphy/step", "Tag " .. tag .. " added to step.")
self.tag = tag
end
self.choregraphy:startTagAction(tag)
end
end
function StepParent:updateStep(dt)
if (not self.isStarted) then
self:start()
self.isStarted = true
else
self:update(dt)
end
end
function StepParent:getActor(name)
return self.choregraphy:getActor(name)
end
function StepParent:getStepCoordinate()
local argx, argy, argz = self.arguments.x, self.arguments.y, self.arguments.z or 0
local x, y, z
argx = argx * self.choregraphy.actor.start.direction
local source = self.arguments.origin
if (source == "start") then
x, y, z = self.choregraphy.actor.start.x, self.choregraphy.actor.start.y, self.choregraphy.actor.start.z
elseif (source == "center") then
x, y, z = 6, 3, 0
else
local actor = self:getActor(source)
if (actor == nil) then
error("source " .. source .. " not found")
end
x, y, z = actor.x, actor.y, actor.z
end
return x + argx, y + argy, z + argz
end
function StepParent:finish()
self.choregraphy:endStep()
self.choregraphy:switchStep()
end
return StepParent

View file

@ -0,0 +1,13 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local PlaySFX = StepParent:extend()
function PlaySFX:new(system, args)
PlaySFX.super.new(self, system, args)
end
function PlaySFX:start()
self.choregraphy.assets.sfx[self.arguments.sfx]:play()
self:finish()
end
return PlaySFX

View file

@ -0,0 +1,20 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local SendDamage = StepParent:extend()
local maputils = require "scenes.battlesystem.utils"
function SendDamage:new(system, args)
SendDamage.super.new(self, system, args)
end
function SendDamage:start()
local power = self.arguments.power
local isSpecial = self.arguments.isSpecial
local type = self.arguments.type
local element = self.arguments.element
self.choregraphy:sendDamage(power, type, element, isSpecial)
self:finish()
end
return SendDamage

View file

@ -0,0 +1,17 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local SendStatus = StepParent:extend()
function SendStatus:new(system, args)
SendStatus.super.new(self, system, args)
end
function SendStatus:start()
local status = self.arguments.status
local force = self.arguments.force
local duration = self.arguments.duration
self.choregraphy:sendStatus(status, duration, force)
self:finish()
end
return SendStatus

View file

@ -0,0 +1,23 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local SetAnimSpeedStep = StepParent:extend()
function SetAnimSpeedStep:new(controller, args)
SetAnimSpeedStep.super.new(self, controller, args)
end
function SetAnimSpeedStep:start()
local actor = self:getActor(self.arguments.who)
actor:setAnimSpeed(self.arguments.speed)
self:finish()
end
function SetAnimSpeedStep:update(dt)
end
function SetAnimSpeedStep:getSignal(signal)
end
return SetAnimSpeedStep;

View file

@ -0,0 +1,29 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local AnimationSetterStep = StepParent:extend()
function AnimationSetterStep:new(controller, args)
AnimationSetterStep.super.new(self, controller, args, true)
end
function AnimationSetterStep:start()
local actor = self:getActor(self.arguments.who)
actor:changeAnimation(self.arguments.animation)
actor:addTaggedAction(self.tag, self.choregraphy, "animation")
if (self.arguments.blockProcess == false) then
self:finish()
else
actor:blockChoregraphy(self.arguments.blockProcess, self, "animation")
end
end
function AnimationSetterStep:update(dt)
end
function AnimationSetterStep:getSignal(signal)
end
return AnimationSetterStep;

View file

@ -0,0 +1,13 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local SetCounterStep = StepParent:extend()
function SetCounterStep:new(system, args)
SetCounterStep.super.new(self, system, args)
end
function SetCounterStep:start()
self.choregraphy:setCounter(self.arguments.counterName, self.arguments.number, self.arguments.relative)
self:finish()
end
return SetCounterStep

View file

@ -0,0 +1,12 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local SkipToStep = StepParent:extend()
function SkipToStep:new(system, args)
SkipToStep.super.new(self, system, args)
end
function SkipToStep:start()
self.choregraphy:skipToStepByTag(self.arguments.skipTo)
end
return SkipToStep

View file

@ -0,0 +1,21 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local StartSubchoregraphiesStep = StepParent:extend()
function StartSubchoregraphiesStep:new(controller, args)
StartSubchoregraphiesStep.super.new(self, controller, args)
end
function StartSubchoregraphiesStep:start()
self.choregraphy:startSubChoregraphies(self.arguments.waitTime)
if (not self.arguments.blockProcess) then
self:finish()
end
end
function StartSubchoregraphiesStep:update(dt)
if (not self.choregraphy:hasNextTarget()) then
self:finish()
end
end
return StartSubchoregraphiesStep;

View file

@ -0,0 +1,23 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local StopMovStep = StepParent:extend()
function StopMovStep:new(controller, args)
StopMovStep.super.new(self, controller, args, true)
end
function StopMovStep:start()
local actor = self:getActor(self.arguments.who)
actor:stopMoving()
self:finish()
end
function StopMovStep:update(dt)
end
function StopMovStep:getSignal(signal)
end
return StopMovStep;

View file

@ -0,0 +1,13 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local UseItemEffect = StepParent:extend()
function UseItemEffect:new(system, args)
UseItemEffect.super.new(self, system, args)
end
function UseItemEffect:start()
self.choregraphy:useItemEffect()
self:finish()
end
return UseItemEffect

View file

@ -0,0 +1,19 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local WaitStep = StepParent:extend()
function WaitStep:new(controller, args)
WaitStep.super.new(self, controller, args)
end
function WaitStep:start()
self.timer = 0
end
function WaitStep:update(dt)
self.timer = self.timer + dt
if (self.timer > self.arguments.duration) then
self:finish()
end
end
return WaitStep;

View file

@ -0,0 +1,20 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local WaitActorFinishedStep = StepParent:extend()
function WaitActorFinishedStep:new(controller, args)
WaitActorFinishedStep.super.new(self, controller, args)
end
function WaitActorFinishedStep:start()
self.choregraphy.actor:blockChoregraphy(true, self, self.arguments.waitFor)
end
function WaitActorFinishedStep:update(dt)
end
function WaitActorFinishedStep:getSignal(signal)
end
return WaitActorFinishedStep;

View file

@ -0,0 +1,18 @@
local StepParent = require "scenes.battlesystem.choregraphy.step.parent"
local WaitForStep = StepParent:extend()
function WaitForStep:new(controller, args)
WaitForStep.super.new(self, controller, args)
end
function WaitForStep:start()
end
function WaitForStep:update(dt)
--print(self.arguments.waitFor)
if (self.choregraphy:checkCondition(self.arguments.waitFor)) then
self:finish()
end
end
return WaitForStep

View file

@ -0,0 +1,44 @@
local SubChoregraphy = Object:extend()
local QteMixin = require "scenes.battlesystem.choregraphy.mixins.qtes"
local StepsMixin = require "scenes.battlesystem.choregraphy.mixins.steps"
local TagsMixin = require "scenes.battlesystem.choregraphy.mixins.tags"
local CountersMixin = require "scenes.battlesystem.choregraphy.mixins.counters"
local WrappersMixin = require "scenes.battlesystem.choregraphy.mixins.wrappers"
SubChoregraphy:implement(QteMixin)
SubChoregraphy:implement(StepsMixin)
SubChoregraphy:implement(TagsMixin)
SubChoregraphy:implement(CountersMixin)
SubChoregraphy:implement(WrappersMixin)
function SubChoregraphy:new(parent, target, choregraphy)
self.parent = parent
self:initWrappers(parent.action, target)
self:initSteps(choregraphy)
self:initQte()
self:initTagActions()
self:initCounters()
self:register()
end
function SubChoregraphy:register()
self.parent:registerSubChoregraphy(self)
end
function SubChoregraphy:update(dt)
self:updateQte(dt)
self:updateSteps(dt)
end
function SubChoregraphy:endChoregraphy()
self.parent:removeSubChoregraphy(self)
end
function SubChoregraphy:draw()
self:drawQte()
end
return SubChoregraphy

View file

@ -0,0 +1,17 @@
local ActionParent = require "scenes.battlesystem.fighters.character.actions.parent"
local AttackAction = ActionParent:extend()
function AttackAction:new(fighter)
AttackAction.super.new(self, fighter)
end
function AttackAction:needTarget()
return true, true
end
function AttackAction:startAction()
core.debug:print("cbs/action", "Starting attack action")
self:loadChoregraphy("attack")
end
return AttackAction

View file

@ -0,0 +1,20 @@
local ActionParent = require "scenes.battlesystem.fighters.character.actions.parent"
local DefendAction = ActionParent:extend()
function DefendAction:new(fighter)
DefendAction.super.new(self, fighter)
end
function DefendAction:needTarget()
return false, false
end
function DefendAction:startAction()
core.debug:print("cbs/action", "Starting defend action")
self.fighter.isDefending = true
self.fighter.actor:changeAnimation("defend")
self.fighter.actor.isDefending = true
self:finishAction()
end
return DefendAction

View file

@ -0,0 +1,34 @@
local ActionParent = require "scenes.battlesystem.fighters.character.actions.parent"
local FleeAction = ActionParent:extend()
local STATS = require "datas.consts.stats"
function FleeAction:new(fighter)
FleeAction.super.new(self, fighter)
end
function FleeAction:needTarget()
return false, false
end
function FleeAction:startAction()
core.debug:print("cbs/action", "Starting flee action")
local stats = self.fighter.abstract.stats
if (self.fighter.abstract.name == "shadow") then
self.fighter.turnSystem.scene:showMessage("You won't flee the battle")
self:finishAction()
return
end
local chanceToFlee = self.fighter.turnSystem:getChanceTooFlee(self.fighter:getStat(STATS.SPEED))
if (math.random(100) < chanceToFlee) then
self.fighter.turnSystem.scene:showMessage("You flee the battle")
self.fighter.turnSystem:fleeBattle()
else
self.fighter.turnSystem.scene:showMessage("You failed to flee the battle")
self:finishAction()
end
end
return FleeAction

View file

@ -0,0 +1,9 @@
local actions = {}
actions.attack = require "scenes.battlesystem.fighters.character.actions.attack"
actions.skill = require "scenes.battlesystem.fighters.character.actions.skill"
actions.item = require "scenes.battlesystem.fighters.character.actions.item"
actions.defend = require "scenes.battlesystem.fighters.character.actions.defend"
actions.flee = require "scenes.battlesystem.fighters.character.actions.flee"
return actions

View file

@ -0,0 +1,28 @@
local ActionParent = require "scenes.battlesystem.fighters.character.actions.parent"
local ItemAction = ActionParent:extend()
local EffectManager = require "game.loot.effectManager"
function ItemAction:new(fighter, category, item)
ItemAction.super.new(self, fighter)
self.category = category
self.item = item
self.itemdata = core.datas:get("items", item)
self.effectManager = EffectManager()
self.effectManager:getItemData(category, item)
end
function ItemAction:needTarget()
return (not self.itemdata.affectEverybody), (self.category == "wisps")
end
function ItemAction:useItemEffect()
self.effectManager:applyEffectsBattle(self.target)
end
function ItemAction:startAction()
core.debug:print("cbs/action", "Starting item action")
self:loadChoregraphy("useitem")
game.loot:removeItem(self.category, self.item, 1)
end
return ItemAction

View file

@ -0,0 +1,56 @@
local ActionParent = Object:extend()
local ChoregraphySystem = require "scenes.battlesystem.choregraphy"
function ActionParent:new(fighter)
self.fighter = fighter
self.target = nil
self.choregraphy = nil
self.isStarted = false
end
function ActionParent:update(dt)
if (self.choregraphy ~= nil) then
self.choregraphy:update(dt)
end
end
function ActionParent:loadChoregraphy(skillname)
local skill = core.datas:get("skills", skillname)
self:loadChoregraphyFromSkill(skill)
end
function ActionParent:loadChoregraphyFromSkill(skill)
self.choregraphy = ChoregraphySystem(self, skill.choregraphy, skill.subChoregraphy)
end
function ActionParent:needTarget()
-- needTarget, targetEnnemies
return false, false
end
function ActionParent:setTarget(target)
self.target = target
end
function ActionParent:start()
self.isStarted = true
self:startAction()
end
function ActionParent:choregraphyEnded()
self.choregraphy = nil
self:finishAction()
end
function ActionParent:startAction()
self:finishAction()
end
function ActionParent:finishAction()
self.fighter:finishAction()
end
return ActionParent

View file

@ -0,0 +1,19 @@
local ActionParent = require "scenes.battlesystem.fighters.character.actions.parent"
local SkillAction = ActionParent:extend()
function SkillAction:new(fighter, skill)
self.data = core.datas:get("skills", skill)
SkillAction.super.new(self, fighter)
end
function SkillAction:needTarget()
return (self.data.targetNumber == 1), self.data.targetEnnemies
end
function SkillAction:startAction()
core.debug:print("cbs/action", "Starting flee action")
self:loadChoregraphyFromSkill(self.data)
self.fighter:setPP(self.data.cost * -1, true)
end
return SkillAction

View file

@ -0,0 +1,131 @@
local FighterParent = require "scenes.battlesystem.fighters.fighter"
local HeroFighter = FighterParent:extend()
local SelectionSystem = require "scenes.battlesystem.fighters.character.selection"
local actionList = require "scenes.battlesystem.fighters.character.actions"
local HEROES_LINE = 2;
function HeroFighter:new(owner, character, id)
self.name = character
self.super.new(self, owner, true, id)
self:initVoices()
self.exp = self.abstract.exp
end
function HeroFighter:update(dt)
HeroFighter.super.update(self, dt)
end
function HeroFighter:getAbstract()
return game.characters.list[self.name]
end
function HeroFighter:createActor()
local x, y = HEROES_LINE, ((self.id-1)*(4/(#game.characters.team-1))+1)
local hero = self.world.obj.Hero(self.world, x, y, self)
if (self.abstract.hp <= 0) then
hero:setAsKo()
end
return hero
end
function HeroFighter:startAction()
core.debug:print("cbs/heroFighter", "launching the action menu")
self.action = nil
self:talk("turnstart")
self.turnSystem.scene.gui.screens["hud"]:buildMenu( self )
end
function HeroFighter:endAction()
end
-- Basic actions
function HeroFighter:doNothing()
self:setInactive()
end
function HeroFighter:doBasicAction(action)
self.action = actionList[action](self)
self:verifyTargets()
end
function HeroFighter:useItem(category, item)
self.action = actionList["item"](self, category, item)
self:verifyTargets()
end
function HeroFighter:useSkill(skill)
self.action = actionList["skill"](self, skill)
self:verifyTargets()
end
function HeroFighter:verifyTargets()
local needTarget, targetEnnemies = self.action:needTarget()
if (needTarget) then
if (targetEnnemies) then
SelectionSystem(self, self.owner.turnSystem.ennemies, true)
else
SelectionSystem(self, self.owner, false)
end
else
self.action:start()
end
end
function HeroFighter:attack()
self:doBasicAction("attack")
end
function HeroFighter:receiveTarget(target)
if (self.action ~= nil) then
self.action:setTarget(target)
self.action:start()
end
end
function HeroFighter:goBackToMenu()
self.turnSystem.scene.gui:setFocus("battleMenu")
end
-- LIFE functions
function HeroFighter:updatePP()
local elem = self.turnSystem.scene.gui:getElement(self.abstract.name .. "StatutBar")
elem:updatePP()
end
function HeroFighter:updateHP()
local elem = self.turnSystem.scene.gui:getElement(self.abstract.name .. "StatutBar")
elem:updateHP()
end
-- VOICE SYSTEM
function HeroFighter:initVoices()
self:addVoiceEffect("move")
self:addVoiceEffect("turnstart")
end
function HeroFighter:addVoiceEffect(name)
local completename = self.name .. "_" .. name
local path = "datas/gamedata/characters/" .. self.name .. "/voices/" .. name .. ".wav"
self.assets:newSFX(completename, path)
end
function HeroFighter:talk(name)
local completename = self.name .. "_" .. name
self.assets.sfx[completename]:play()
end
-- DRAW FUNCTIONS
function HeroFighter:drawIcon(x, y)
local iconID = self.abstract.data.icon
self.assets.tileset["charicons"]:drawTile(iconID, x, y)
end
return HeroFighter

View file

@ -0,0 +1,66 @@
local GuiElement = require "birb.modules.gui.elements.parent"
local SelectionSystem = GuiElement:extend()
function SelectionSystem:new(owner, fighterSide, onlyAlive)
SelectionSystem.super.new(self, "selection", 0, 0, 1, 1)
self.fighterList = fighterSide:getTargets(onlyAlive)
self.owner = owner
self.assets = self.owner.assets
self.selectedTarget = 1
self:updateTarget()
self:getFocus()
end
function SelectionSystem:keypressed(key)
if (key == "A") then
self.assets.sfx["mSelect"]:play()
self:selectTarget()
elseif (key == "B") then
self.assets.sfx["mBack"]:play()
self:goBack()
elseif (key == "up") then
self:purgeTarget()
if (self.selectedTarget == 1) then
self.selectedTarget = #self.fighterList
else
self.selectedTarget = self.selectedTarget - 1
end
self.assets.sfx["mBeep"]:play()
self:updateTarget()
elseif (key == "down") then
self:purgeTarget()
if (self.selectedTarget == #self.fighterList) then
self.selectedTarget = 1
else
self.selectedTarget = self.selectedTarget + 1
end
self.assets.sfx["mBeep"]:play()
self:updateTarget()
end
end
function SelectionSystem:purgeTarget()
local target = self.fighterList[self.selectedTarget]
target.actor.isSelected = false
end
function SelectionSystem:updateTarget()
local target = self.fighterList[self.selectedTarget]
target.actor.isSelected = true
end
function SelectionSystem:selectTarget()
self:looseFocus()
self:destroy()
self:purgeTarget()
self.owner:receiveTarget(self.fighterList[self.selectedTarget])
end
function SelectionSystem:goBack()
self:looseFocus()
self:destroy()
self:purgeTarget()
self.owner:goBackToMenu()
end
return SelectionSystem

View file

@ -0,0 +1,52 @@
local FighterControllerParent = require "scenes.battlesystem.fighters.parent"
local EnnemyController = FighterControllerParent:extend()
local Villain = require "scenes.battlesystem.fighters.ennemy"
local STATS = require "datas.consts.stats"
function EnnemyController:new(owner, battleData)
self.super.new(self, owner)
self:initVillains(battleData)
end
function EnnemyController:initVillains(battleData)
for i,ennemyBaseData in ipairs(battleData.ennemies) do
local ennData = core.datas:parse("ennemytype", ennemyBaseData)
if (ennData.type == "normal") then
self:addVillain(ennData)
elseif (ennData.type == "boss") then
self:addBoss(ennData)
else
core.debug:warning("unknown type " .. ennData.type)
end
end
end
function EnnemyController:addVillain(ennData)
for i=1, ennData.number do
self:add(Villain(self, ennData.category, ennData.name, self:count() + 1))
end
end
function EnnemyController:getHighestSpeed()
local highestSpeed = 0
for i, villain in ipairs(self.list) do
local currentSpeed = villain:getStat(STATS.SPEED)
if (currentSpeed > highestSpeed) then
highestSpeed = currentSpeed
end
end
return highestSpeed
end
function EnnemyController:addBoss(ennData)
local boss = Villain(self, ennData.category, ennData.name, self:count() + 1)
boss:setBonus(ennData.pvFactor, ennData.statFactor)
boss.isBoss = true
boss:setCheapEffect(ennData.cheapEffect)
self.turnSystem.canFleeBattle = false
self:add(boss)
boss:createHPBar()
end
return EnnemyController

View file

@ -0,0 +1,22 @@
local ActionParent = require "scenes.battlesystem.fighters.character.actions.parent"
local EnnemyAction = ActionParent:extend()
function EnnemyAction:new(fighter, skill)
self.data = core.datas:get("badskills", skill)
EnnemyAction.super.new(self, fighter)
end
function EnnemyAction:needTarget()
return (self.data.targetNumber == 1), self.data.targetEnnemies
end
function EnnemyAction:startAction()
core.debug:print("cbs/action", "Starting flee action")
self:loadChoregraphyFromSkill(self.data)
end
function EnnemyAction:getData()
return self.data
end
return EnnemyAction

View file

@ -0,0 +1,5 @@
local folder = "scenes.battlesystem.fighters.ennemy.behaviours."
return {
["random"] = require(folder .. "random")
}

View file

@ -0,0 +1,61 @@
local BehaviourParent = Object:extend()
function BehaviourParent:new(fighter, skilldata, targetList, highestScore)
self.fighter = fighter
self.scoreList = {}
self.targetList = targetList
self.skilldata = skilldata
self.highestScore = highestScore
self:initScoreList()
self:calculateAllScores()
end
function BehaviourParent:initScoreList()
for i, target in ipairs(self.targetList) do
self.scoreList[target.name] = 0
end
end
function BehaviourParent:calculateAllScores()
for i, target in ipairs(self.targetList) do
self.scoreList[target.name] = self:calculateScore(target)
end
end
function BehaviourParent:calculateScore(target)
return 0
end
function BehaviourParent:getScore(target)
return self.scoreList[target.name]
end
function BehaviourParent:isBestTarget(target, bestTargetScore, isHighest)
if (bestTargetScore == nil) then
return true
else
if (isHighest) then
return (self:getScore(target) >= bestTargetScore)
else
return (self:getScore(target) <= bestTargetScore)
end
end
end
function BehaviourParent:getTarget()
local bestTargetScore = nil
local finalTarget = nil
for i, target in ipairs(self.targetList) do
if (self:isBestTarget(target, bestTargetScore, self.isHighest)) then
finalTarget = target
bestTargetScore = self:getScore(target)
end
end
return finalTarget
end
return BehaviourParent

View file

@ -0,0 +1,12 @@
local ParentBehaviour = require "scenes.battlesystem.fighters.ennemy.behaviours.parent"
local RandomBehaviour = ParentBehaviour:extend()
function RandomBehaviour:new(fighter, skilldata, targetList)
RandomBehaviour.super.new(self, fighter, skilldata, targetList, true)
end
function RandomBehaviour:calculateScore(target)
return math.random(1, 200)
end
return RandomBehaviour

View file

@ -0,0 +1,110 @@
local FighterParent = require "scenes.battlesystem.fighters.fighter"
local VillainFighter = FighterParent:extend()
local SimpleHPBar = require "game.modules.gui.simplehpbar"
local BossHPBar = require "scenes.battlesystem.gui.hudelements.bosshpbar"
local EnnemyAction = require "scenes.battlesystem.fighters.ennemy.action"
local behaviourList = require "scenes.battlesystem.fighters.ennemy.behaviours"
local POSITIONS = {1, 3, 5}
local ENNEMY_LINE = 11;
function VillainFighter:new(owner, category, ennemy, id)
self.name = ennemy
self.category = category
self.super.new(self, owner, false, id)
self.hpbar = SimpleHPBar(self.abstract.hp)
self.isBoss = false
end
function VillainFighter:setCheapEffect(cheapEffect)
self.actor:setCheapEffect(cheapEffect)
end
function VillainFighter:updateAssets(dt)
self.hpbar:update(dt)
end
function VillainFighter:getAbstract()
return game.ennemies:getEnnemyData(self.category, self.name)
end
function VillainFighter:createActor()
local x, y = ENNEMY_LINE, POSITIONS[self.id]
return self.world.obj.Ennemy(self.world, x, y, self)
end
function VillainFighter:startAction()
core.debug:print("cbs/villainFighter", "choosing an action")
self.action = nil
self:selectAction()
end
function VillainFighter:selectAction()
if (#self.abstract.skills < 1) then
self:finishAction()
else
local skillId = math.floor(math.random(1, #self.abstract.skills))
local skill = self.abstract.skills[skillId]
self.action = EnnemyAction(self, skill)
self:verifyTargets()
end
end
function VillainFighter:verifyTargets()
local needTarget, targetEnnemies = self.action:needTarget()
if (needTarget) then
if (targetEnnemies) then
--fighter, skilldata, targetList
local Behaviour = behaviourList[self.abstract.data.behaviour]
local behav = Behaviour(self, self.action:getData(), self.owner.turnSystem.player:getTargets(true))
self.action:setTarget(behav:getTarget())
self.action:start()
else
--self.selection = SelectionSystem(self, self.owner, false)
end
else
self.action:start()
end
end
function VillainFighter:endAction()
end
function VillainFighter:setBonus(pvFactor, statFactor)
self.abstract:setBonus(pvFactor, statFactor)
end
-- LIFE FUNCTIONS
function VillainFighter:setHP(value, relative)
VillainFighter.super.setHP(self, value, relative)
self.hpbar:setHP(self.abstract.hp)
if (self.bossHpBar ~= nil) then
self.bossHpBar:setHP(self.abstract.hp)
end
end
-- DRAW FUNCTIONS
function VillainFighter:drawIcon(x, y)
self.assets.images["badnicsIcon"]:draw(x-1, y-2)
self.assets.fonts["hudnbrs_small"]:print(self.id, x+10, y+8)
end
function VillainFighter:drawOversprite(x, y)
if (not self.isBoss) then
self.hpbar:draw(x, y)
else
self.assets.images["crown"]:draw(x, y - 2)
end
end
function VillainFighter:createHPBar()
self.bossHpBar = BossHPBar(self.abstract.hp)
end
return VillainFighter

View file

@ -0,0 +1,267 @@
local FighterParent = Object:extend()
local battleutils = require "game.utils.battle"
local STATS = require "datas.consts.stats"
function FighterParent:new(owner, isHero, id)
self.owner = owner
self.turnSystem = owner.turnSystem
self.world = owner.world
self.isHero = isHero
self.assets = self.turnSystem.scene.assets
-- Note : l'ID est ici relatif à chaque quand, il n'est donc pas unique,
-- ce qui est unique étant le combo id + isHero
self.id = id
self.abstract = self:getAbstract()
self.actor = self:createActor()
self.isActive = false
self.isAlive = true
self.isDefending = false
self.action = nil
self.statsBonus = {}
end
-- LIFE handling functions
function FighterParent:setHP(value, relative)
local relativeNumber = value
if (not relative) then
relativeNumber = relative - self.abstract.hp
end
self.abstract:setHP(value, relative)
self.actor:setDamageNumber(relativeNumber)
self:updateHP()
end
function FighterParent:setPP(value, relative)
self.abstract:setPP(value, relative)
self:updatePP()
end
function FighterParent:applyDeath()
if (self.abstract:isAlive() ~= self.isAlive ) then
if (self.abstract:isAlive()) then
self:revive()
else
self:die()
end
end
end
function FighterParent:revive()
self.isAlive = true
self.isDefending = false
self.actor:revive()
end
function FighterParent:die()
self.isAlive = false
self.actor:die()
end
function FighterParent:updatePP()
-- Fonction vide
end
function FighterParent:updateHP()
-- Fonction vide
end
function FighterParent:haveProtecType(type)
return self.abstract:haveProtecType(type)
end
function FighterParent:sendDamageToAll(listTarget, value, type, element, isSpecial)
for _, target in ipairs(listTarget) do
self:sendDamage(target, value, type, element, isSpecial)
end
end
function FighterParent:sendStatusToAll(listTarget, status, duration, force)
for _, target in ipairs(listTarget) do
self:sendStatus(target, status, duration, force)
end
end
function FighterParent:getTargets(ourSide)
if (self.isHero == ourSide) then
return self.turnSystem.player:getTargets(true)
else
return self.turnSystem.ennemies:getTargets(true)
end
end
function FighterParent:sendDamage(target, value, type, element, isSpecial)
local damage = battleutils.computeLaunchingDamages(value, self, isSpecial)
core.debug:print("cbs/battler", "Sending " .. damage .." damage at " .. target.name)
if (battleutils.rollDice(self:getStat(STATS.ACCURACY))) then
return target:receiveDamage(damage, type, element, isSpecial, self)
else
target.actor:avoidedAttack()
return false
end
end
function FighterParent:sendStatus(target, status, duration, force)
core.debug:print("cbs/battler", "Sending status " .. status .." at " .. target.name)
if ((not force) or battleutils.rollDice(self:getStat(STATS.ACCURACY))) then
target:receiveStatus(status, duration, force)
end
end
function FighterParent:receiveStatus(status, duration, force)
if (force or (not battleutils.rollDice(self:getStat(STATS.LUCK)))) then
self.abstract:addStatut(status, duration)
end
end
function FighterParent:receiveDamage(value, type, element, isSpecial, fromWho)
local damages = battleutils.computeReceivingDamages(value, self, isSpecial, self.isDefending)
damages = battleutils.applyProtectTypes(damages, type, self.abstract:getProtecTypes())
damages = battleutils.applyResistences(damages, element, self.abstract:getResistences())
damages = battleutils.applyWeaknesses(damages, element, self.abstract:getWeaknesses())
if (battleutils.rollDice(self:getStat(STATS.EVASION))) then
self.actor:avoidedAttack()
return false
else
self:applyDamage(damages)
end
return true
end
function FighterParent:applyDamage(damage)
core.debug:print("cbs/fighter", "Taken " .. damage .. " damage" )
self:setHP(damage * -1, true)
self.owner:registerDamage(damage)
if (not self.isDefending) then
self.actor:getHurt()
end
if (not self.abstract:isAlive()) then
self.owner:registerKO()
end
end
function FighterParent:getAbstract()
return {}
end
function FighterParent:createActor()
return {}
end
function FighterParent:update(dt)
if (self.action ~= nil) then
if (self.action.isStarted) then
self.action:update(dt)
end
end
end
function FighterParent:updateAssets(dt)
-- Vide pour l'instant
end
function FighterParent:setActive()
self.isActive = true
if (self.isDefending) then
self.actor:changeAnimation("idle")
self.actor.isDefending = false
end
self:startAction()
end
function FighterParent:applyRegen()
local regenStat = self:getStat(STATS.HPREGEN)
if (regenStat ~= 0) then
self:setHP(regenStat*self:getStat(STATS.HPMAX)/100, true)
end
local regenStat = self:getStat(STATS.PPREGEN)
if (regenStat ~= 0) then
self:setPP(regenStat*self:getStat(STATS.PPMAX)/100, true)
end
end
function FighterParent:setInactive()
self.isActive = false
self:applyRegen()
self.turnSystem:endAction()
end
function FighterParent:getNbrActionPerTurn()
return self.abstract.turns
end
function FighterParent:getStat(statname)
local stat = (self.abstract.stats:get(statname) * self:getStatBonusValue(statname)) + self.abstract:getStatutsStat(statname)
if (self.abstract:haveStatuts("cursed") and (statname == "evasion")) then
return math.max(0, stat)
end
return stat
end
function FighterParent:getStatBonusValue(statname)
if (utils.table.contain(STATS.NOBONUS, statname)) then
return 1
else
return STATS.BONUS[self:getStatBonus(statname) + 5]
end
end
function FighterParent:getStatBonus(statname)
return self.statsBonus[statname] or 0
end
function FighterParent:setStatBonus(statname, value, relative)
local statBonus = 0
if (relative) then
statBonus = self:getStatBonus(statname)
end
self.statsBonus[statname] = math.max(-4, math.min(statBonus + value, 4))
end
function FighterParent:getStats()
return self.abstract:getStats()
end
function FighterParent:startAction()
end
function FighterParent:finishAction()
self.action = nil
self:setInactive()
end
function FighterParent:getUniqueIdentificator()
local side = 1
if (self.isHero == false) then
side = -1
end
return self.id * side
end
function FighterParent:getNonUniqueIdentificator()
return self.id
end
function FighterParent:canFight()
return self.isAlive
end
-- DRAW FUNCTIONS
function FighterParent:drawIcon(x, y)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.rectangle("fill", x, y, 16, 16)
end
return FighterParent

View file

@ -0,0 +1,104 @@
local FighterControllerParent = Object:extend()
function FighterControllerParent:new(turnSystem)
self.turnSystem = turnSystem
self.world = turnSystem.world
self.list = {}
self.damages = 0
self.ko = 0
end
function FighterControllerParent:get(id)
return self.list[id]
end
function FighterControllerParent:getList()
return self.list
end
function FighterControllerParent:add(fighter)
table.insert(self.list, fighter)
end
function FighterControllerParent:count()
return #self.list
end
function FighterControllerParent:registerDamage(damage)
self.damages = math.floor(self.damages + damage)
end
function FighterControllerParent:registerKO()
self.ko = self.ko + 1
end
function FighterControllerParent:countAlive()
local aliveCount = 0
for i, fighter in ipairs(self.list) do
if (fighter:canFight()) then
aliveCount = aliveCount + 1
end
end
return aliveCount
end
function FighterControllerParent:getTargets(onlyAlive)
local targetList = {}
for i, fighter in ipairs(self.list) do
if (fighter:canFight() or (not onlyAlive)) then
table.insert(targetList, fighter)
end
end
return targetList
end
function FighterControllerParent:applyDeath()
for i, fighter in ipairs(self.list) do
fighter:applyDeath()
end
return self:countAlive()
end
function FighterControllerParent:setActive(activeActor)
self.activeActor = activeActor
activeActor:setActive()
end
function FighterControllerParent:update(dt)
for i, fighter in ipairs(self.list) do
fighter:updateAssets(dt)
end
end
function FighterControllerParent:endAction()
self.owner:nextAction()
end
function FighterControllerParent:putActions(actionList)
for i, fighter in ipairs(self.list) do
for i=1, fighter:getNbrActionPerTurn() do
local action = {}
action.fighter = fighter
action.number = i
table.insert(actionList, action)
end
end
end
function FighterControllerParent:removeFighter(fighterToRemove)
-- remove the actor from the battler liste
for i, fighter in ipairs(self.list) do
if fighter == fighterToRemove then
table.remove(self.list, i)
end
end
-- Also remove all actions related to the actor
self.turnSystem:removeAllActionsFromFighter(fighterToRemove)
end
return FighterControllerParent

View file

@ -0,0 +1,23 @@
local FighterControllerParent = require "scenes.battlesystem.fighters.parent"
local HeroFighterController = FighterControllerParent:extend()
local Character = require "scenes.battlesystem.fighters.character"
function HeroFighterController:new(owner)
self.super.new(self, owner)
self:initHeroes()
end
function HeroFighterController:initHeroes()
for i, hero in ipairs(game.characters.team) do
self:add(Character(self, hero, i))
end
end
function HeroFighterController:fleeBattle()
for i, hero in ipairs(self.list) do
hero.actor:flee()
end
end
return HeroFighterController

View file

@ -0,0 +1,30 @@
local GuiElement = require "birb.modules.gui.elements.parent"
local BossHpBar = GuiElement:extend()
local ComplexHPBar = require "game.modules.gui.complexhpbar"
local POS_X, POS_Y = 280, 28
function BossHpBar:new(hp)
self.hp = hp
self.baseHP = hp
self.hpbar = ComplexHPBar(120)
self.hpbar:setColorForeground(248/255, 160/255, 0, 1)
self.hpbar:setColorBackground(112/255, 0, 0)
self.bossTexture = love.graphics.newImage("assets/gui/strings/boss.png")
local w, h = self.bossTexture:getDimensions()
BossHpBar.super.new(self, "BossHPBar", POS_X, POS_Y, w, h)
end
function BossHpBar:setHP(newHP)
self:newTween(0, 0.1, {hp = newHP}, 'inCubic')
end
function BossHpBar:draw()
self.hpbar:draw(self.x, self.y, self.hp / self.baseHP)
love.graphics.draw(self.bossTexture, self.x + 98, self.y + 10)
end
return BossHpBar

View file

@ -0,0 +1,86 @@
local Parent = require "game.modules.gui.fancymenu"
local BattleMenu = Parent:extend()
local defTransitions = require "birb.modules.transitions"
local radTransitions = require "game.modules.transitions"
local MENU_X, MENU_Y = 88, 72
local MENU_W = 180-32
local MENU_ITEM_NUMBER = 6
function BattleMenu:new()
BattleMenu.super.new(self, "battleMenu", MENU_X, MENU_Y, MENU_W, MENU_ITEM_NUMBER, true)
self.isVisible = false
end
function BattleMenu:rebuild(character)
self:clear()
self:addItem("Attack", "left", function() self:doAction(character, "attack") end)
self:generateSubmenu("skills", "Skill", "main", character.abstract.skills, function(data) return self:createSkillWidget(character, data) end, true)
self:createItemMenus(character)
self:switch("main")
self:addItem("Defend", "left", function() self:doAction(character, "defend") end)
self:addItem("Flee", "left", function() self:doAction(character, "flee") end)
self:getFocus()
self.canvas.needRedraw = true
end
function BattleMenu:createItemMenus(character)
self:addSubmenu("items", "Items", "main", true)
for i,pocket in ipairs(game.loot.inventory) do
if (pocket.inBattle) then
self:generateSubmenu(pocket.name, pocket.fullname, "items", pocket.list,
function(itemInBag)
return self:createItemWidget(character, pocket.name, itemInBag)
end, true)
end
end
end
function BattleMenu:createSkillWidget(character, skill)
local data = core.datas:get("skills", skill.name)
local isOk = (data.cost <= character.abstract.pp)
local cost = {utils.math.numberToString(data.cost or 0, 2), "right"}
local color = utils.math.either(isOk, {1, 1, 1}, {1, 0.3, 0.3})
local sfx = utils.math.either(isOk, "select", "error")
local func = function() self:doSkill(character, skill.name, isOk) end
--text, position, func, type, additionnalItems, color
return character.abstract:getSkillName(skill.name), "left", func, sfx, {cost}, color
end
function BattleMenu:createItemWidget(character, pocketName, itemInBag)
local data = core.datas:get("items", itemInBag.name)
local nbr = game.loot:getItemNumber(pocketName, itemInBag.name)
local nbrLabel = {"x" .. utils.math.numberToString(nbr, 2), "right"}
local func = function() self:useItem(character, pocketName, itemInBag.name) end
--text, position, func, type, additionnalItems, color
return data.fullname, "left", func, "select", {nbrLabel}, {1, 1, 1}
end
function BattleMenu:doAction(character, action)
self:looseFocus()
self.isVisible = false
character:doBasicAction(action)
end
function BattleMenu:useItem(character, pocketName, item)
self:looseFocus()
self.isVisible = false
character:useItem(pocketName, item)
end
function BattleMenu:doSkill(character, skill, isOk)
if (isOk) then
self:looseFocus()
character:useSkill(skill)
self.isVisible = false
else
self.scene:showMessage("You haven't enough PP!")
end
end
return BattleMenu

View file

@ -0,0 +1,68 @@
local GuiElement = require "birb.modules.gui.elements.parent"
local StatusBar = GuiElement:extend()
local TweenManager = require "birb.classes.time"
local Emblem = require "game.modules.gui.emblem"
local ComplexHPBar = require "game.modules.gui.complexhpbar"
local DIST_STATUSBAR = 106
local Y = 200
local STATUSBAR_W = 90
function StatusBar:new(fighter, i)
self:initAbstract(fighter)
StatusBar.super.new(self, self.abstract.name .. "StatutBar", (i-0.5)*DIST_STATUSBAR-(STATUSBAR_W/2), Y, STATUSBAR_W, 64)
self:createParts(self.scene)
end
function StatusBar:initAbstract(fighter)
self.abstract = fighter.abstract
self.hp = self.abstract.hp
self.pp = self.abstract.pp
self.stats = self.abstract:getStats()
end
function StatusBar:createParts(scene)
self.emblem = Emblem(self.abstract, scene)
self.hpbar = ComplexHPBar(58)
self.ppbar = ComplexHPBar(58)
self.hpbar:setColorForeground(248 / 255, 160 / 255, 0, 1)
self.hpbar:setColorBackground(112 / 255, 0, 0)
self.ppbar:setColorForeground(0, 248 / 255, 248 / 255, 1)
self.ppbar:setColorBackground(0, 54 / 255, 229 / 255)
end
function StatusBar:updateHP()
self.tweens:newTween(0, 0.3, {hp = self.abstract.hp}, "linear")
end
function StatusBar:updatePP()
self.tweens:newTween(0, 0.3, {pp = self.abstract.pp}, "linear")
end
function StatusBar:draw()
self.emblem:drawBackground(self.x, self.y)
self:drawStatusArea(self.x + 10, self.y - 8)
self.emblem:drawForeground(self.x, self.y)
end
function StatusBar:drawStatusArea(x, y)
self.assets.images["statusbar"]:draw(x, y)
local hpmax = self.stats:get(self.stats.HPMAX)
local ppmax = self.stats:get(self.stats.PPMAX)
self.assets.fonts["hudnbrs_small"]:set()
self.hpbar:drawWithLabels(x + 6, y + 9, self.hp, hpmax)
self.ppbar:drawWithLabels(x + 18, y + 21, self.pp, ppmax)
local lvl = self.abstract.level
if lvl < 100 then
lvl = "0" .. lvl
end
love.graphics.print(lvl, x + 42, y + 1)
end
return StatusBar

View file

@ -0,0 +1,27 @@
local Parent = require "birb.modules.gui.elements.parent"
local TurnBar = Parent:extend()
local gui = require "game.modules.gui"
function TurnBar:new()
TurnBar.super.new(self, "turnbar", 76, 5, 1, 1)
self.turns = self.scene.turns
self.cursor = self.turns.turns.current
end
function TurnBar:draw()
for i, action in ipairs(self.turns.actionList) do
if action.fighter:canFight() then
action.fighter:drawIcon(self.x + (i-1)*(20), self.y)
else
gui.drawEmptyIcon(self.x + (i-1)*(20), self.y)
end
end
local cursorx = (self.cursor-1) * 20
if #self.turns.actionList > 0 then
self.assets.images["menucursor"]:draw(self.x + cursorx, self.y, math.rad(90), 1, 1, 4, 16)
end
end
return TurnBar

View file

@ -0,0 +1,42 @@
local GuiScreen = require "birb.modules.gui.screen"
local CbsScreen = GuiScreen:extend()
local StatutBar = require "scenes.battlesystem.gui.hudelements.statutbar"
local TurnBar = require "scenes.battlesystem.gui.hudelements.turnbar"
local BattleMenu = require "scenes.battlesystem.gui.hudelements.menu"
local Composite = require "birb.modules.gui.elements.composite"
local Counter = require "birb.modules.gui.elements.counter"
local Asset = require "birb.modules.gui.elements.assets"
local show = {
{"turns", "movement", 0.5, 0.6, 424/2, 80, "inOutQuart"},
}
function CbsScreen:new()
CbsScreen.super.new(self, "hud")
self:show()
end
function CbsScreen:buildMenu(character)
self.elements["battleMenu"]:rebuild(character)
end
function CbsScreen:createElements()
local turns = self.scene.turns
local list = {
{Composite("turns", 10, 10, {
{Asset("turnImg", "images", "hudturn", -1, -1), 0, 0},
{Counter("turnCnt", "hudnbrs", turns.turns, "number", 2, -1, -1), 33, 1},
{TurnBar(), 62, -3},
}), 0},
{BattleMenu(), 0}
}
for i, fighter in ipairs(turns.player:getList()) do
table.insert(list, {StatutBar(fighter, i), 0})
end
return list
end
return CbsScreen

View file

@ -0,0 +1,80 @@
local GuiElement = require "birb.modules.gui.elements.parent"
local CharacterExp = GuiElement:extend()
local gui = require "game.modules.gui"
local charutils = require "game.utils.characters"
function CharacterExp:new(x, y, character, number)
self.character = character
self.started = false
self.done = false
CharacterExp.super.new(self, character.name .. "Exp", x, y, 1, 1)
self.opacity = 0
self.number = number
self:newTween(1.4, 0.4, {opacity = 1}, "inExpo")
if self.number == 1 then
self:startInSeconds(2.5)
end
self.targetExp = self.scene.turns.rewards:getExp(character)
self.exp = character.abstract.exp
end
function CharacterExp:update(dt)
if (not self.done and (self.started)) then
self:addCharacterExp(dt)
end
end
function CharacterExp:startInSeconds(seconds)
self:newFunc(seconds, "startMe", function() self:startExpGain(1) end)
end
function CharacterExp:startExpGain(number)
self.started = true
end
function CharacterExp:addCharacterExp(dt)
local level = self.character.abstract.level
local xpAddRatio = charutils.getLevelExpRange(level) * 0.5
local newExp = self.exp + (xpAddRatio * dt)
if (newExp < self.targetExp) then
self.exp = newExp
local nextLevelExp = charutils.getExpValue(level + 1)
if (self.exp >= nextLevelExp) then
self.character.abstract.abstract:levelUp()
end
else
self.exp = self.targetExp
self.character.abstract.exp = self.targetExp
self.done = true
self.isLast = self.screen:nextExp(self.number + 1)
if (self.isLast) then
self:getFocus()
end
end
end
function CharacterExp:keypressed(key)
if (key == "A" and self.done and self.isLast) then
self.scene:returnToOverworld(false)
self.scene:setPrompt("")
end
end
function CharacterExp:draw()
love.graphics.setColor(1, 1, 1, self.opacity)
self.assets.images["expbar"]:draw(self.x, self.y)
self.character:drawIcon(self.x + 1, self.y + 6)
love.graphics.setColor(0, 0.8, 0.1, self.opacity)
local level = self.character.abstract.level
local exp = self.exp
local remainingExp = charutils.getRemainingExp(exp, level)
local expRatio = charutils.getRelativeExpValue(exp, level) / charutils.getLevelExpRange(level)
gui.drawBar(self.x + 22, self.y + 11, math.floor(56 * expRatio), 7)
love.graphics.setColor(1, 1, 1, self.opacity)
self.assets.fonts["hudnbrs_small"]:print(math.floor(remainingExp), self.x + 71, self.y + 11, "right")
self.assets.fonts["hudnbrs_small"]:print(level, self.x + 72, self.y + 1, "right")
end
return CharacterExp

View file

@ -0,0 +1,122 @@
local Screen = require "birb.modules.gui.screen"
local VictoryScreen = Screen:extend()
local TextElement = require "birb.modules.gui.elements.text"
local ChoiceElement = require "game.modules.gui.choiceElem"
local ConfirmDialog = require "game.modules.confirmdialog"
local TextureElement = require "birb.modules.gui.elements.drawable"
local LootElement = require "scenes.battlesystem.gui.victory.loot"
local ItemsElement = require "scenes.battlesystem.gui.victory.items"
local CharExperience = require "scenes.battlesystem.gui.victory.exp"
local TileElement = require "birb.modules.gui.elements.tile"
local defTransitions = require "birb.modules.transitions"
local gui = require "game.modules.gui"
local HEIGHT = 32
local STARTX, STARTY = 32, HEIGHT + 44
local ENDX, ENDY = 424 - 32, 240 - 24
local SIZE_FEATS = 128+28
local START_ITEMS = STARTX + SIZE_FEATS
local START_EXP = START_ITEMS + 128
local show = {
{"gameText", "movement", 0.9, 0.4, 424/2, HEIGHT, "inExpo"},
--{"rankBox", "tween", 1.4, 0.4, {opacity = 1}, "inExpo"},
{"loot", "tween", 1.4, 0.4, {opacity = 1}, "inExpo"},
{"items", "tween", 1.4, 0.4, {opacity = 1}, "inExpo"},
}
function VictoryScreen:new()
self.feats = 0
self.rankBox = gui.newTextBox("assets/gui/dialogbox.png", 48, 32)
self.itemBox = gui.newTextBox("assets/gui/dialogbox.png", 96, 48)
VictoryScreen.super.new(self, "titleScreen")
self:addTransform("show", show)
self.scene:showOverlay(true)
self:show()
end
function VictoryScreen:createFeats(list)
local ennemyNbr, turns, dmgSent, dmgTaken, ko = self.turns:getDatas()
self:addFeat(list,"Ennemies", ennemyNbr)
self:addFeat(list,"Turns", turns)
self:addFeat(list,"Dmg sent", dmgSent)
if (dmgTaken == 0) then
self:addFeat(list,"No damage !", "")
else
self:addFeat(list,"Dmg taken", dmgTaken)
self:addFeat(list,"KO", ko)
end
local qteRate, haveDoneQte = self.rewards:getQteSuccessRate()
if (not haveDoneQte) then
self:addFeat(list,"No QTE done")
else
self:addFeat(list,"QTE success", math.floor(qteRate * 100) .. "%")
end
self:addRank(list)
end
function VictoryScreen:addFeat(list, text, label)
self.feats = self.feats + 1
local featID = "feat" .. self.feats
label = label or ""
local elem = ChoiceElement(featID, text, "", label, STARTX - 16, STARTY + (16*(self.feats-1)), SIZE_FEATS)
elem.opacity = 0
elem:newTween(1 + (0.2*self.feats), 0.15, {opacity = 1, x = STARTX}, 'inQuad')
table.insert(list, {elem, 0, 1})
end
function VictoryScreen:addRank(list)
local rank = TileElement("rank", "ranks", self.rewards:getRank(), 424/2, ENDY - 28,0,4,4,13,13, 0)
rank:newTween(1.9, 0.4, {sx=1, sy=1, opacity=1}, 'inExpo')
table.insert(list, {rank, 0, 1})
end
function VictoryScreen:nextExp(nbr)
local list = self.scene.turns.player:getList()
local nextChar = list[nbr]
if nextChar ~= nil then
self.elements[nextChar.name .. "Exp"]:startExpGain(nbr)
return false
else
self.scene:setPrompt("Finish")
return true
end
end
function VictoryScreen:createElements()
self.turns = self.scene.turns
self.rewards = self.turns.rewards
local list = {
{TextElement("gameText", "SA2font", "BATTLE COMPLETED", 424/2, -24, "center"), 0, 1},
--{TextureElement("rankBox", self.rankBox, 424/2, ENDY - 4, 0, 1,1, 64/2,48, 0), 0, 1},
{LootElement(START_ITEMS + 2, STARTY - 2), 0, 1},
{ItemsElement(START_ITEMS + 2, STARTY + 40, {"test", "test", "test"}), 0, 1}
}
self:createFeats(list)
for i, character in ipairs(self.scene.turns.player:getList()) do
table.insert(list, {CharExperience(START_EXP - 4, STARTY + (i-1)*24 - 12, character, i), 0, 1})
end
return list
end
function VictoryScreen:returnToTitle()
core.screen:startTransition(defTransitions.default, defTransitions.circle, function() scenes.menus.title(true) end, 424/2, 240/2)
end
function VictoryScreen:loadLastSave()
self.scene.tweens:newTween(0, 0.3, {borderPosition=0}, "inOutQuad")
core.screen:startTransition(defTransitions.default, defTransitions.default, function() game:reload() scenes.overworld() end, 424/2, 240/2)
end
return VictoryScreen

View file

@ -0,0 +1,23 @@
local CanvasElement = require "birb.modules.gui.elements.canvas"
local ItemsElement = CanvasElement:extend()
local gui = require "game.modules.gui"
function ItemsElement:new(x, y, list)
self.background = gui.newTextBox("assets/gui/dialogbox.png", 128, 40+16)
local w, h = self.background:getDimensions()
ItemsElement.super.new(self, "items", x, y, w, h)
self.opacity = 0
self.list = list
end
function ItemsElement:drawTexture()
love.graphics.draw(self.background, 0, 0)
for index, value in ipairs(self.list) do
if (index <= 4) then
self.assets.fonts["small"]:draw(value, 8, 4 + (16*(index-1)), -1, "left")
end
end
end
return ItemsElement

View file

@ -0,0 +1,22 @@
local CanvasElement = require "birb.modules.gui.elements.canvas"
local LootElement = CanvasElement:extend()
local gui = require "game.modules.gui"
function LootElement:new(x, y)
self.background = gui.newTextBox("assets/gui/dialogbox.png", 128, 40)
local w, h = self.background:getDimensions()
LootElement.super.new(self, "loot", x, y, w, h)
self.canvas.isAnimated = true
self.opacity = 0
end
function LootElement:drawTexture()
love.graphics.draw(self.background, 0, 0)
self.assets.fonts["small"]:draw("Rings: ", 8, 4, -1, "left")
self.assets.fonts["small"]:draw("0", self.w - 8, 4, -1, "right")
self.assets.fonts["small"]:draw("Exp: ", 8, 20, -1, "left")
self.assets.fonts["small"]:draw("0", self.w - 8, 20, -1, "right")
end
return LootElement

View file

@ -0,0 +1,86 @@
local Scene = require "game.scenes"
local BattleSystem = Scene:extend()
local World = require "scenes.battlesystem.world"
local Turns = require "scenes.battlesystem.turns"
local VictoryScreen = require "scenes.battlesystem.gui.victory"
local GameOverScreen = require "game.modules.gui.gameover"
local CbsScreen = require "scenes.battlesystem.gui"
local TweenManager = require "birb.classes.time"
function BattleSystem:new(battleData)
BattleSystem.super.new(self)
self.assets:batchImport("assets.battle")
self:playMusic(battleData.music)
self:initManagers(battleData)
self:startBattle()
CbsScreen()
self.screen = nil
self.tweens = TweenManager(self)
end
function BattleSystem:playMusic(music)
self.assets:setMusic("assets/music/" .. music .. ".mp3")
self.assets:playMusic()
end
function BattleSystem:initManagers(battleData)
self.datas = {}
self.world = World(self)
self.turns = Turns(self, battleData)
end
function BattleSystem:startBattle()
self.turns:startBattle()
end
function BattleSystem:finishBattle()
self.assets:setMusic("assets/music/victory.mp3")
self.assets:playMusic()
VictoryScreen(self)
end
function BattleSystem:fleeBattle()
self.tweens:newTimer(2, "flee")
end
function BattleSystem:timerResponse(name)
if (name == "flee") then
self:returnToOverworld(true)
end
end
function BattleSystem:returnToOverworld(isFleeing)
self.assets:silence()
game.cbs:endBattle(isFleeing)
end
function BattleSystem:looseBattle()
GameOverScreen(self)
end
function BattleSystem:haveMenus()
return self.gui.elements["battleMenu"].isVisible
end
function BattleSystem:update(dt)
self.tweens:update(dt)
self.turns:update(dt)
self.world:update(dt)
end
function BattleSystem:exit()
self.world:destroy()
self.battlearena = nil
collectgarbage()
end
return BattleSystem

View file

@ -0,0 +1,79 @@
local Rewards = Object:extend()
local rankFactor = {1, 1.25, 1.5, 1.75, 2}
function Rewards:new(turns)
self.turns = turns
self.qte = 0
self.qteSuccess = 0
end
function Rewards:apply()
local _, rings = self:getRewards(true)
game.loot.rings = game.loot.rings + rings
end
function Rewards:getRank()
local ennemyNbr, turns, _, _, ko = self.turns:getDatas()
local qteSuccess, haveDoneQte = self:getQteSuccessRate()
local rank = 3
if (not haveDoneQte) then
rank = 3
elseif (qteSuccess >= 0.75) then
rank = 4
elseif (qteSuccess >= 0.5) then
rank = 3
elseif (qteSuccess >= 0.25) then
rank = 2
else
rank = 1
end
-- TODO: modifier l'effet de nombre de tour pour les boss
if (turns/ennemyNbr > 3) then
rank = rank - 1
end
if (ko == 0) then
rank = rank + 1
end
return math.max(1, math.min(5, rank))
end
function Rewards:getExp(character)
local exp = self:getRewards(true)
return character.abstract.exp + exp
end
function Rewards:getRewards(real)
local exp, ring = 0, 0
for i, ennemy in ipairs(self.turns.ennemies.list) do
exp = exp + ennemy.abstract.data.giveExp
ring = ring + ennemy.abstract.data.giveRings
end
if (real) then
exp = exp * rankFactor[self:getRank()]
ring = ring * rankFactor[self:getRank()]
end
return exp, ring
end
function Rewards:getQteSuccessRate()
if (self.qte == 0) then
return 0, false
end
return self.qteSuccess/self.qte, true
end
function Rewards:addQTE(success)
self.qte = self.qte + 1
if (success) then
self.qteSuccess = self.qteSuccess + 1
end
end
return Rewards

View file

@ -0,0 +1,170 @@
local TurnController = Object:extend()
local Player = require "scenes.battlesystem.fighters.player"
local Ennemy = require "scenes.battlesystem.fighters.ennemies"
local Rewards = require "scenes.battlesystem.rewards"
local maputils = require "scenes.battlesystem.utils"
function TurnController:new(scene, battleData)
self.scene = scene
self.world = scene.world
self.isActive = false
self.currentlyPlaying = ""
self.turns = {}
self.turns.current = 1
self.turns.number = 0
self.turns.isFinished = true
self.turns.changeBattler = true
self.actionList = {}
self.currentFighter = nil
self.canFleeBattle = true
self.gui = self.scene.gui
self.player = Player(self)
self.ennemies = Ennemy(self, battleData)
self.rewards = Rewards(self)
-- Change the seed at the start of each battle
math.randomseed( os.time() )
self:applyDeath()
end
function TurnController:getChanceTooFlee(value)
if (self.canFleeBattle) then
local speedComparison = math.min(value / self.ennemies:getHighestSpeed(), 1.5)
return 25 + (50 * speedComparison)
end
return 0
end
function TurnController:fleeBattle()
self.player:fleeBattle()
self.scene:fleeBattle()
end
function TurnController:startBattle()
self.isActive = true
end
function TurnController:finishBattle()
self.isActive = false
self.actionlist = {}
self.scene:finishBattle()
self.rewards:apply()
end
function TurnController:looseBattle()
self.isActive = false
self.actionlist = {}
self.scene:looseBattle()
end
function TurnController:update(dt)
self.player:update(dt)
self.ennemies:update(dt)
if (self.isActive) then
if (self.currentFighter ~= nil) then
self.currentFighter:update(dt)
else
if (self.player:countAlive() > 0) then
self:nextAction()
else
self:looseBattle()
end
end
end
end
function TurnController:getRank()
return self.rewards:getRank()
end
function TurnController:getRewards()
return self.rewards:getRewards(false)
end
function TurnController:getDatas()
local ennemyNbr = #self.ennemies.list
local turns = self.turns.current
local dmgSent = self.ennemies.damages
local dmgTaken = self.player.damages
local ko = self.player.ko
return ennemyNbr, turns, dmgSent, dmgTaken, ko
end
function TurnController:nextAction()
if (self.turns.isFinished) or (self.turns.current >= #self.actionList) then
self:startNewTurn()
else
self.turns.current = self.turns.current + 1
core.debug:print("cbs/turns", "switching to next action")
end
self:startAction()
end
function TurnController:startNewTurn()
core.debug:print("cbs/turns", "New Turn Starting")
self.turns.current = 1
self.turns.isFinished = false
self.turns.number = self.turns.number + 1
self:calculateTurn()
end
function TurnController:calculateTurn()
self.actionList = {}
self.player:putActions(self.actionList)
self.ennemies:putActions(self.actionList)
table.sort(self.actionList, maputils.sortBattlers)
end
function TurnController:removeAllActionsFromFighter(fighterToRemove)
for i, action in ipairs(self.actionlist) do
if action.fighter == fighterToRemove then
table.remove(self.actionlist, i)
end
end
end
function TurnController:applyDeath()
local ennemiesAlive = self.ennemies:applyDeath()
if (ennemiesAlive == 0) then
self:finishBattle()
end
self.player:applyDeath()
end
function TurnController:startAction()
core.debug:print("cbs/turns", "Starting action " .. self.turns.current)
local nextAction = self.actionList[self.turns.current]
local nextFighter = nextAction.fighter
if (not nextFighter:canFight()) then
-- On skipe le personnage s'il a été detruit
self:nextAction()
else
self.currentFighter = nextFighter
core.debug:print("cbs/turns", "Activating " .. self.currentFighter.name)
self.currentFighter:setActive()
self.gui:newTween("turnbar", 0, 0.2, {cursor = self.turns.current}, 'inCubic')
end
end
function TurnController:endAction()
self.currentFighter = nil
end
function TurnController:sendSignalToCurrentBattler(signal, subSignal)
self.actionList[self.turns.current].actor:receiveSignal(signal, subSignal)
end
return TurnController

View file

@ -0,0 +1,24 @@
local maputils = {}
local STATS = require "datas.consts.stats"
maputils.CONST = {}
maputils.CONST.STARTX = -8
maputils.CONST.STARTY = 90
function maputils.sortBattlers(a, b)
local aspeed = a.fighter:getStat(STATS.SPEED) / (3 ^ (a.number-1))
local bspeed = b.fighter:getStat(STATS.SPEED) / (3 ^ (b.number-1))
if (aspeed == bspeed) then
if (a.fighter.isHero == b.fighter.isHero) then
return (a.fighter.id < b.fighter.id)
else
return a.fighter.isHero
end
else
return (aspeed > bspeed)
end
end
return maputils

View file

@ -0,0 +1,100 @@
local World = Object:extend()
local Map = require "game.modules.drawing.parallaxBackground"
local HEIGHT = 5
local BORDER_BOTTOM = 2
-- 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.map = Map(scene, HEIGHT, BORDER_BOTTOM, "city")
self.index = {}
self.isBattleActive = false
end
function World:registerActor(actor)
self.globalID = self.globalID + 1
table.insert(self.actors, actor)
actor.id = self.globalID
end
function World:destroyActor(actorToDestroy)
for i, actor in ipairs(self.actors) do
if actor == actorToDestroy then
table.remove(self.actors, i)
end
end
end
-- INFO FUNCTIONS
-- Get info from the world
function World:caseIsEmpty(x, y, notThisActor)
local actor = self:getActorInCase(x, y, notThisActor)
return (actor == nil)
end
function World:getActorInCase(x, y, notThisActor)
for i, actor in ipairs(self.actors) do
if (actor.x == x) and (actor.y == y) and (actor ~= notThisActor) then
core.debug:print("cbs/world", "one actor found in case <" .. x .. ";" .. y .. ">")
return actor
end
end
return nil
end
function World:getActorByName(name)
return self.index[name]
end
-- UPDATE FUNCTION
-- Update all actors
function World:update(dt)
for i, actor in ipairs(self.actors) do
actor:update(dt)
end
end
function World:sendSignalToCurrentBattler(signal, subSignal)
self.scene.turns:sendSignalToCurrentBattler(signal, subSignal)
end
-- DRAW FUNCTION
-- Draw the world
function World:draw()
self.map:draw()
self:drawShadows()
self:drawActors()
end
function World:drawActors()
table.sort(self.actors, function(a, b) return (a.y < b.y) end)
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
return World

View file

@ -1,5 +1,7 @@
return {
test = require "scenes.test_scene",
title = require "scenes.titlescreen",
boost = require "scenes.subgame.sonic-boost"
test = require "scenes.subgames.testBattle",
test2 = require "scenes.subgames.testShoot",
cbs = require "scenes.battlesystem",
menus = require "scenes.menus",
overworld = require "scenes.overworld"
}

View file

@ -0,0 +1,76 @@
local menu = {}
local RadianceListMenu = require "game.modules.menus.fancy"
local defTransitions = require "birb.modules.transitions"
menu.MainMenu = RadianceListMenu.FancyMenu:extend()
menu.DebugMenu = RadianceListMenu.FancyMenu:extend()
menu.SceneWidget = RadianceListMenu.BaseWidget:extend()
local CONST = {}
CONST.MENU = {}
CONST.MENU.X = 16
CONST.MENU.Y = 48
CONST.MENU.W = 424/2
CONST.MENU.ITEM_NUMBER = 8
-- Basic menu structure
function menu.MainMenu:new(scene, name)
local x, y = CONST.MENU.X, CONST.MENU.Y
local w = CONST.MENU.W / 1.5
local itemNumber = CONST.MENU.ITEM_NUMBER
menu.MainMenu.super.new(self, scene, name, x, y, w, itemNumber, false)
end
function menu.DebugMenu:new(scene, name)
local x, y = CONST.MENU.X, CONST.MENU.Y
local w = CONST.MENU.W
local itemNumber = CONST.MENU.ITEM_NUMBER
menu.DebugMenu.super.new(self, scene, name, x, y, w, itemNumber, false)
end
function menu.DebugMenu:setPanel(panel, panelArgument)
self.panel = panel
self.panelArgument = panelArgument
end
function menu.DebugMenu:activationAction()
if (self.panel ~= nil) then
self.scene.panel = self.panel(self.panelArgument)
end
end
function menu.DebugMenu:clone(name)
return menu.DebugMenu(self.scene, name)
end
function menu.DebugMenu:draw()
love.graphics.setColor(0, 0, 0, 0.5)
love.graphics.rectangle("fill", self.x, self.y, self.w, self.h)
utils.graphics.resetColor()
menu.DebugMenu.super.draw(self)
end
-- SceneWidget
function menu.SceneWidget:new(scene, menuName, newScene, newSceneName, sceneArgument)
menu.SceneWidget.super.new(self, scene, menuName, newSceneName, "")
self.newScene = newScene
self.sceneArgument = sceneArgument
end
function menu.SceneWidget:action()
self.scene.assets:playSFX("mSelect")
self.scene:flushKeys()
if (self.sceneArgument ~= nil) then
core.screen:startTransition(defTransitions.default, defTransitions.default,
function() self.newScene(self.sceneArgument) end,
0, 0)
else
core.screen:startTransition(defTransitions.default, defTransitions.default,
function() self.newScene() end,
0, 0)
end
end
return menu

View file

@ -0,0 +1,61 @@
local Scene = require "game.scenes"
local menu = require "scenes.menus.debugmenus.animation.menu"
local CharAnimViewer = Scene:extend()
local Background = require "game.modules.drawing.parallaxBackground"
local Sprite = require "birb.modules.assets.types.sprites"
function CharAnimViewer:new()
CharAnimViewer.super.new(self)
self.assets:batchImport("assets.debug")
local mainMenu = menu.commons.DebugMenu(self, "MainMenu")
self:setBackground("city")
for charName, _ in pairs(game.characters.list) do
mainMenu:addSubMenu(charName, charName)
local sprite = Sprite("datas/gamedata/characters/" .. charName .. "/sprites")
for animName, _ in pairs(sprite.data.animations) do
menu.AnimationWidget(self, charName, animName)
end
end
menu.commons.SceneWidget(self, "MainMenu", scenes.menus.main, "Back")
self.menusystem:activate()
self.menusystem:switchMenu("MainMenu")
self.sprite = nil
end
function CharAnimViewer:constructMenu()
end
function CharAnimViewer:setSpriteAndAnim(character, animationName)
self.sprite = Sprite("datas/gamedata/characters/" .. character .. "/sprites")
self.sprite:changeAnimation(animationName, true)
end
function CharAnimViewer:update(dt)
if (love.keyboard.isDown("z") and (not self.menusystem.isActive)) then
self.menusystem:activate()
end
if (self.sprite ~= nil) then
self.sprite:update(dt)
end
end
function CharAnimViewer:setBackground(newBackground)
self.background = Background(self, 5, 1, newBackground)
end
function CharAnimViewer:draw()
self.background:draw()
if (self.sprite ~= nil) then
self.sprite:draw(424/2, 240/1.5)
end
end
return CharAnimViewer

View file

@ -0,0 +1,19 @@
local commons = require "scenes.menus.commons.menu"
local listMenu = require "game.modules.menus.list"
local menu = {}
menu.commons = commons
menu.AnimationWidget = listMenu.DualTextWidget:extend()
-- ShowBackground
function menu.AnimationWidget:new(scene, menuName, animName)
menu.AnimationWidget.super.new(self, scene, menuName, animName, "")
self.charName = menuName
self.animName = animName
end
function menu.AnimationWidget:action()
self.scene:setSpriteAndAnim(self.charName, self.animName)
self.scene.menusystem:deactivate()
end
return menu

View file

@ -0,0 +1,40 @@
local Scene = require "game.scenes"
local menu = require "scenes.menus.debugmenus.battleBack.menu"
local BackgroundViewer = Scene:extend()
local Background = require "game.modules.drawing.parallaxBackground"
local backgroundList = require "datas.gamedata.maps.shoot.zones"
function BackgroundViewer:new()
BackgroundViewer.super.new(self)
self.assets:batchImport("assets.debug")
menu.commons.DebugMenu(self, "MainMenu")
self:setBackground("city")
for backId, backgroundData in pairs(backgroundList) do
menu.ShowBackgroundWidget(self, "MainMenu", backgroundData.name, backId)
end
menu.commons.SceneWidget(self, "MainMenu", scenes.menus.main, "Back")
self.menusystem:activate()
self.menusystem:switchMenu("MainMenu")
end
function BackgroundViewer:update(dt)
if (love.keyboard.isDown("z") and (not self.menusystem.isActive)) then
self.menusystem:activate()
end
end
function BackgroundViewer:setBackground(newBackground)
self.background = Background(self, 5, 1, newBackground)
end
function BackgroundViewer:draw()
self.background:draw()
end
return BackgroundViewer

View file

@ -0,0 +1,19 @@
local commons = require "scenes.menus.commons.menu"
local listMenu = require "game.modules.menus.list"
local menu = {}
menu.commons = commons
menu.ShowBackgroundWidget = listMenu.DualTextWidget:extend()
-- ShowBackground
function menu.ShowBackgroundWidget:new(scene, menuName, backgroundName, backgroundId)
menu.ShowBackgroundWidget.super.new(self, scene, menuName, backgroundName, "")
self.backgroundId = backgroundId
end
function menu.ShowBackgroundWidget:action()
self.scene:setBackground(self.backgroundId)
self.scene.menusystem:deactivate()
end
return menu

View file

@ -0,0 +1,102 @@
local Scene = require "game.scenes"
local menu = require "scenes.menus.debugmenus.choregraphy.menu"
local ChoregraphyViewer = Scene:extend()
local World = require "scenes.battlesystem.world"
local Fighter = require "scenes.menus.debugmenus.choregraphy.mocks.fighter"
function ChoregraphyViewer:new()
ChoregraphyViewer.super.new(self)
self.assets:batchImport("assets.battle")
self.world = World(self)
self:buildMenu()
self:buildMocks()
end
-- MENU FUNCTIONS
function ChoregraphyViewer:buildMenu()
menu.commons.DebugMenu(self, "MainMenu")
self:buildCharacterMenu()
self.menusystem.menus["MainMenu"]:finalize()
self.menusystem:activate()
self.menusystem:switchMenu("MainMenu")
menu.commons.SceneWidget(self, "MainMenu", scenes.menus.main, "Back")
end
function ChoregraphyViewer:buildCharacterMenu()
for i,category in ipairs(core.datas:getCategories("ennemies")) do
self:buildEnnemyListMenu(category)
end
self:addSubMenu("characters", "MainMenu", "Rivals")
for k, character in pairs(game.characters.list) do
self:addSubMenu(k, "characters", character.fullname)
menu.HeroChoregraphyWidget(self, k, core.datas:get("skills", "attack"))
self:buildSkillMenu(k)
end
end
function ChoregraphyViewer:buildEnnemyListMenu(category)
self:addSubMenu(category, "MainMenu", category)
for i,ennemy in ipairs(core.datas.getFromCategory("ennemies", category)) do
self:buildEnnemySkillMenu(category, ennemy)
end
end
function ChoregraphyViewer:buildEnnemySkillMenu(category, ennemy)
self:addSubMenu(ennemy, category, ennemy)
local data = core.datas:get("ennemies", ennemy)
for j,skillName in ipairs(data.skills) do
if (core.datas:exists("badskills", skillName)) then
menu.EnnemyChoregraphyWidget(self, category, ennemy, core.datas:get("badskills", skillName))
end
end
end
function ChoregraphyViewer:buildSkillMenu(charName)
local skillList = require("datas.gamedata.characters." .. charName .. ".skills")
local skillTreated = {}
for i,skill in ipairs(skillList) do
local skillName = skill[1]
if (skillTreated[skillName] ~= true) then
skillTreated[skillName] = true
if (core.datas:exists("skills", skillName)) then
menu.HeroChoregraphyWidget(self, charName, core.datas:get("skills", skillName))
end
end
end
end
function ChoregraphyViewer:addSubMenu(submenu, parent, name)
local parent = parent or "MainMenu"
self.menusystem.menus[parent]:addSubMenu(submenu, name)
end
-- MOCKS FUNCTIONS
function ChoregraphyViewer:buildMocks()
self.fighter = Fighter(self)
end
function ChoregraphyViewer:playHeroChoregraphy(character, data)
self.fighter:playHeroChoregraphy(character, data)
end
function ChoregraphyViewer:playEnnemyChoregraphy(category, ennemy, data)
self.fighter:playEnnemyChoregraphy(category, ennemy, data)
end
-- OTHER
function ChoregraphyViewer:update(dt)
self.fighter:update(dt)
self.world:update(dt)
end
function ChoregraphyViewer:draw()
end
return ChoregraphyViewer

View file

@ -0,0 +1,34 @@
local commons = require "scenes.menus.commons.menu"
local listMenu = require "game.modules.menus.list"
local menu = {}
menu.commons = commons
menu.HeroChoregraphyWidget = listMenu.DualTextWidget:extend()
menu.EnnemyChoregraphyWidget = listMenu.DualTextWidget:extend()
-- ShowBackground
function menu.HeroChoregraphyWidget:new(scene, charName, skillData)
menu.HeroChoregraphyWidget.super.new(self, scene, charName, skillData.name, "")
self.character = charName
self.skillData = skillData
end
function menu.HeroChoregraphyWidget:action()
self.scene:playHeroChoregraphy(self.character, self.skillData)
self.scene.menusystem:deactivate()
end
-- ShowBackground
function menu.EnnemyChoregraphyWidget:new(scene, category, charName, skillData)
menu.EnnemyChoregraphyWidget.super.new(self, scene, charName, skillData.name, "")
self.category = category
self.character = charName
self.skillData = skillData
end
function menu.EnnemyChoregraphyWidget:action()
self.scene:playEnnemyChoregraphy(self.category, self.character, self.skillData)
self.scene.menusystem:deactivate()
end
return menu

View file

@ -0,0 +1,18 @@
local ActionParent = require "scenes.battlesystem.fighters.character.actions.parent"
local ActionMock = ActionParent:extend()
function ActionMock:new(fighter, data)
ActionMock.super.new(self, fighter)
self.data = data
end
function ActionMock:needTarget()
return (self.data.targetNumber == 1), self.data.targetEnnemies
end
function ActionMock:startAction()
core.debug:print("cbs/action", "Starting mock action")
self:loadChoregraphyFromSkill(self.data)
end
return ActionMock

View file

@ -0,0 +1,50 @@
local FighterMock = Object:extend()
local ActionMock = require "scenes.menus.debugmenus.choregraphy.mocks.action"
local TargetMock = require "scenes.menus.debugmenus.choregraphy.mocks.target"
local TurnSystemMock = require "scenes.menus.debugmenus.choregraphy.mocks.turnSystem"
function FighterMock:new(scene)
self.scene = scene
self.action = nil
self.actor = nil
self.turnSystem = TurnSystemMock()
end
function FighterMock:update(dt)
if (self.action ~= nil) then
self.action:update(dt)
end
end
function FighterMock:playHeroChoregraphy(character, data)
self.name = character
self.abstract = game.characters.list[character]
self.actor = self.scene.world.obj.Hero(self.scene.world, 11, 3, self, 1)
self.action = ActionMock(self, data)
self.action:setTarget(TargetMock(self.scene))
self.action:start()
end
function FighterMock:playEnnemyChoregraphy(category, ennemy, data)
self.name = ennemy
self.category = category
self.abstract = game.ennemies:getEnnemyData(category, ennemy)
self.actor = self.scene.world.obj.Ennemy(self.scene.world, 11, 3, self, 1)
self.action = ActionMock(self, data)
self.action:setTarget(TargetMock(self.scene))
self.action:start()
end
function FighterMock:finishAction()
self.action.target.actor:destroy()
self.actor:destroy()
self.action = nil
self.scene.menusystem:activate()
end
function FighterMock:drawHUD()
end
return FighterMock

View file

@ -0,0 +1,8 @@
local TargetMock = Object:extend()
function TargetMock:new(scene)
self.scene = scene
self.actor = self.scene.world.obj.Battler(self.scene.world, 2, 3, 0, self)
end
return TargetMock

View file

@ -0,0 +1,11 @@
local TurnSystemMock = Object:extend()
function TurnSystemMock:new()
end
function TurnSystemMock:applyDeath()
end
return TurnSystemMock

View file

@ -0,0 +1,10 @@
return {
title = require "scenes.menus.titlescreen",
main = require "scenes.menus.mainmenu",
debug = {
battleBack = require "scenes.menus.debugmenus.battleBack",
choregraphy = require "scenes.menus.debugmenus.choregraphy",
animation = require "scenes.menus.debugmenus.animation",
},
options = require "scenes.menus.options"
}

View file

@ -0,0 +1,31 @@
local Parent = require "scenes.menus.mainmenu.infopanel.parent"
local CharacterPanel = Parent:extend()
function CharacterPanel:new(character)
CharacterPanel.super.new(self)
self.character = character
end
function CharacterPanel:drawContent(x, y)
local stats = self.character.stats
local debugString = "# DEBUG - " .. self.character.name .. "(" .. "Lvl " .. self.character.level .. ")" .. "\n"
local debugString = debugString .. "EXP: " .. self.character.exp .. " / " .. self.character.exp_next .. "\n"
local debugString = debugString .. "HP: " .. self.character.hp .. " / " .. stats:get(stats.HPMAX) .. "\n"
local debugString = debugString .. "PP: " .. self.character.pp .. " / " .. stats:get(stats.PPMAX) .. "\n"
local debugString = debugString .. self:addToDebugString(stats, stats.ATTACK)
local debugString = debugString .. " " .. self:addToDebugString(stats, stats.DEFENSE)
local debugString = debugString .. " " .. self:addToDebugString(stats, stats.SPEED) .. "\n"
local debugString = debugString .. self:addToDebugString(stats, stats.POWER)
local debugString = debugString .. " " .. self:addToDebugString(stats, stats.MIND)
local debugString = debugString .. " " .. self:addToDebugString(stats, stats.TECHNIC) .. "\n"
love.graphics.print(debugString, x, y)
end
function CharacterPanel:addToDebugString(stats, statname)
local stats = stats
return stats.CONST.SIMPLENAME[statname] .. ": " .. stats:get(statname)
end
return CharacterPanel

View file

@ -0,0 +1,17 @@
local Parent = require "scenes.menus.mainmenu.infopanel.parent"
local GamePanel = Parent:extend()
function GamePanel:new()
GamePanel.super.new(self)
end
function GamePanel:drawContent(x, y)
local debugString = "# DEBUG - Save data" .. "\n"
debugString = debugString .. "Current slot: " .. game.slot .. " / " .. game.slotNumber .. "\n"
debugString = debugString .. "Rings: " .. game.loot.rings .. "\n"
debugString = debugString .. "Gametime: " .. game:getTimeString() .. "\n"
love.graphics.print(debugString, x, y)
end
return GamePanel

View file

@ -0,0 +1,7 @@
local folder = "scenes.menus.mainmenu.infopanel."
return {
Gamedata = require(folder .. "gamedata"),
Character = require(folder .. "character"),
Team = require(folder .. "team"),
}

View file

@ -0,0 +1,19 @@
local ParentPanel = Object:extend()
local gui = require "game.modules.gui"
function ParentPanel:new()
self.panelBackground = gui.newTextBox("assets/gui/dialogbox.png", 128+32, 128)
end
function ParentPanel:draw(x, y, w, h)
if (core.debug.active) then
love.graphics.draw(self.panelBackground, x, y)
self:drawContent(x+8, y+8)
end
end
function ParentPanel:drawContent(x, y)
end
return ParentPanel

View file

@ -0,0 +1,22 @@
local Parent = require "scenes.menus.mainmenu.infopanel.parent"
local TeamPanel = Parent:extend()
function TeamPanel:new()
TeamPanel.super.new(self)
end
function TeamPanel:drawContent(x, y)
local debugString = "# DEBUG - Team" .. "\n"
for i,name in ipairs(game.characters.team) do
local char = game.characters.list[name]
debugString = debugString .. "- " .. char.name
if (game.characters.active == i) then
debugString = debugString .. " (Active) "
end
debugString = debugString .. "\n"
end
love.graphics.print(debugString, x, y)
end
return TeamPanel

View file

@ -0,0 +1,15 @@
local Scene = require "game.scenes"
local DebugMenu = Scene:extend()
local MenuBack = require "game.modules.gui.menuback"
local MainMenu = require "scenes.menus.mainmenu.menu"
function DebugMenu:new()
DebugMenu.super.new(self, true, true)
MainMenu()
MenuBack()
end
return DebugMenu;

View file

@ -0,0 +1,48 @@
local Parent = require "game.modules.gui.fancymenu"
local MainMenu = Parent:extend()
local defTransitions = require "birb.modules.transitions"
local radTransitions = require "game.modules.transitions"
local MENU_X, MENU_Y = 24, 48
local MENU_W = 424/3
local MENU_ITEM_NUMBER = 8
function MainMenu:new()
MainMenu.super.new(self, "mainmenu", MENU_X, MENU_Y, MENU_W, MENU_ITEM_NUMBER, false)
self:addItem("Launch game", "left", function() self:launchGame() end)
self:addItem("Options", "left", function() self:launchOptions() end)
self:addItem("Battle Level", "left", function() self:battle() end)
self:addItem("Shadow Shoot Level", "left", function() self:shadowShot() end)
self:addItem("Return to title", "left", function() self:returnToTitle() end, "back")
self:setCancelWidget()
self:addItem("Exit game", "left", function() self:exitGame() end)
self:getFocus()
end
function MainMenu:launchGame()
core.screen:startTransition(defTransitions.circle, defTransitions.default, function() scenes.overworld() end, 424/2, 240/2)
core.scenemanager.currentScene:hideOverlay()
end
function MainMenu:launchOptions()
core.screen:startTransition(defTransitions.default, defTransitions.default, function() scenes.menus.options() end, 424/2, 240/2)
end
function MainMenu:returnToTitle()
core.screen:startTransition(defTransitions.circle, radTransitions.borders, function() scenes.menus.title(true) end, 424/2, 240/2)
end
function MainMenu:battle()
core.screen:startTransition(defTransitions.default, defTransitions.default, function() scenes.test("ebeach") end, 424/2, 240/2)
end
function MainMenu:shadowShot()
core.screen:startTransition(defTransitions.circle, radTransitions.borders, function() scenes.test2() end, 424/2, 240/2)
end
function MainMenu:exitGame()
love.event.quit("000")
end
return MainMenu

View file

@ -0,0 +1,34 @@
local Scene = require "game.scenes"
local OptionsMenu = Scene:extend()
local OptionMenu = require "scenes.menus.options.menu"
local gui = require "game.modules.gui"
local MenuBack = require "game.modules.gui.menuback"
function OptionsMenu:new()
OptionsMenu.super.new(self, true, true)
self.keyDetector = {}
self.keyDetector.widget = nil
OptionMenu()
MenuBack()
end
function OptionsMenu:changeKey(widget)
self.keyDetector.widget = widget
end
function OptionsMenu:keypressed( key )
if (self.keyDetector.widget ~= nil) then
self.assets:playSFX("mSelect")
self.gui.elements["optionMenu"].isVisible = true
self.gui:delayFocus("optionMenu", 0.1)
self.keyDetector.widget:receiveKey( key )
self.keyDetector.isActive = false
self.keyDetector.widget = nil
end
end
return OptionsMenu

View file

@ -0,0 +1,216 @@
local Parent = require "game.modules.gui.boxedmenu"
local MainMenu = Parent:extend()
local TextMenuWidget = require "birb.modules.gui.textmenu.widgets.basic"
local ResolutionWidget = TextMenuWidget:extend()
local SwitchWidget = TextMenuWidget:extend()
local AudioWidget = TextMenuWidget:extend()
local DifficultyWidget = TextMenuWidget:extend()
local KeysWidget = TextMenuWidget:extend()
local defTransitions = require "birb.modules.transitions"
local ConfirmDialog = require "game.modules.confirmdialog"
local MENU_Y = 48
local MENU_W = 424 / 1.5
local MENU_ITEM_NUMBER = 8
function MainMenu:new()
local screenw, screenh = core.screen:getDimensions()
MainMenu.super.new(self, "optionMenu", screenw/2, MENU_Y, MENU_W, MENU_ITEM_NUMBER, true)
self.ox = MENU_W/2
self:addVideoMenu()
self:addAudioMenu()
self:addDifficultyMenu()
self:addInputMenu()
self:switch("main")
self:addItem("Delete save", "left", function() self:deleteSave() end, "select", nil, {1, 0.3, 0.3})
self:addItem("Exit", "left", function() self:exit() end, "back")
self:setCancelWidget()
self:getFocus()
end
function MainMenu:addVideoMenu()
self:addSubmenu("video", "Videos", "main", true)
ResolutionWidget()
SwitchWidget("fullscreen", "Fullscreen")
SwitchWidget("border", "Borders")
SwitchWidget("vsync", "Vsync")
end
function MainMenu:addAudioMenu()
self:addSubmenu("audio", "Audio", "main", true)
AudioWidget("music", "Music")
AudioWidget("sfx", "SFX")
end
function MainMenu:addDifficultyMenu()
self:addSubmenu("difficulty", "Difficulty", "main", true)
DifficultyWidget("hazardMakesKo", "Hazards can make KO")
DifficultyWidget("playerKoChar", "Play KO characters on maps")
DifficultyWidget("easierBattles", "Easier battles")
DifficultyWidget("checkPointRegen", "Checkpoints heal you")
DifficultyWidget("levelUpHeal", "Gaining a level heal")
DifficultyWidget("allDamage", "Hazards damage everybody")
end
function MainMenu:addInputMenu()
self:addSubmenu("input", "Input", "main", true)
local keyList = require "datas.keys"
for j, key in ipairs(keyList) do
KeysWidget(key)
end
end
function MainMenu:exit()
core.screen:startTransition(defTransitions.default, defTransitions.default,
function() scenes.menus.main() end, 0, 0)
end
function MainMenu:deleteSave()
local confirm = ConfirmDialog(core.scenemanager.currentScene,
"Do you want to delete your save ? \nYou won't be able to recover your data.",
function()
core.scenemanager:setStoredScene("mainmenu")
game:deleteCurrentSave()
core.screen:startTransition(defTransitions.default, defTransitions.circle,
function() scenes.menus.title(true) end,
424/2, 240/2)
end)
confirm:setCancelChoice(2)
end
-- WIDGETS
function ResolutionWidget:new()
ResolutionWidget.super.new(self, "optionMenu", core.lang:translate("options", "resolution"), "left")
self:addLabel(self:getSecondLabel(), "right")
end
function ResolutionWidget:getSecondLabel()
return "x" .. core.options.data.video.resolution
end
function ResolutionWidget:action()
core.options.data.video.resolution = ((core.options.data.video.resolution) % 3) + 1
self:replaceLabel(2, self:getSecondLabel())
core.screen:applySettings()
self:invalidateCanvas()
core.options:write()
end
-- SWITCH
function SwitchWidget:new(keyname, label)
self.keyname = keyname
SwitchWidget.super.new(self, "optionMenu", label, "left")
self:addLabel(self:getSecondLabel(), "right")
end
function SwitchWidget:modifyKey()
core.options.data.video[self.keyname] = (core.options.data.video[self.keyname] == false)
core.screen:applySettings()
end
function SwitchWidget:getKey()
return core.options.data.video[self.keyname]
end
function SwitchWidget:getSecondLabel()
return core.lang:translate("commons", utils.math.either(self:getKey(), "true", "false"))
end
function SwitchWidget:action()
self:modifyKey()
self:replaceLabel(2, self:getSecondLabel())
core.options:write()
self:invalidateCanvas()
end
-- AUDIO
function AudioWidget:new(audiotype, label)
self.audiotype = audiotype
SwitchWidget.super.new(self, "optionMenu", label, "left")
self:addLabel(self:getSecondLabel(), "right")
self.order = 0
end
function AudioWidget:getSecondLabel()
return utils.math.numberToString(self:getVolume(), 3) .. "%"
end
function AudioWidget:getVolume()
return core.options.data.audio[self.audiotype]
end
function AudioWidget:setVolume(vol)
core.options.data.audio[self.audiotype] = utils.math.either(vol >= 0, vol, 100)
end
function AudioWidget:action()
local value = self:getVolume()
self:setVolume(value - 20)
self:replaceLabel(2, self:getSecondLabel())
self:invalidateCanvas()
--self.scene.assets.music:setVolume(core.options.data.audio.music / 100)
core.options:write()
end
-- DIFFICULTY
function DifficultyWidget:new(keyname, label)
self.keyname = keyname
SwitchWidget.super.new(self, "optionMenu", label, "left")
self:addLabel(self:getSecondLabel(), "right")
end
function DifficultyWidget:modifyKey()
game.difficulty:toggle(self.keyname)
end
function DifficultyWidget:getKey()
return game.difficulty:get(self.keyname)
end
function DifficultyWidget:getSecondLabel()
return core.lang:translate("commons", utils.math.either(self:getKey(), "true", "false"))
end
function DifficultyWidget:action()
self:modifyKey()
self:replaceLabel(2, self:getSecondLabel())
game:write()
self:invalidateCanvas()
end
-- KEYS
function KeysWidget:new(key)
self.source = 1
self.key = key
SwitchWidget.super.new(self, "optionMenu", self.key, "left")
self:addLabel(self:getSecondLabel(), "right")
self.type = "navigate"
end
function KeysWidget:getSecondLabel()
return core.input.data[self.source].keys[self.key]
end
function KeysWidget:action()
self.menu:playSFX("navigate")
self.scene:changeKey(self)
self.menu.isVisible = false
self.menu:looseFocus()
end
function KeysWidget:receiveKey( key )
core.options:setInputKey(self.source, self.key, key)
self:replaceLabel(2, self:getSecondLabel())
self:invalidateCanvas()
end
return MainMenu

View file

@ -0,0 +1,44 @@
-- scenes/test :: a basic test scene
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Scene = require "game.scenes"
local Title = Scene:extend()
local TitleScreen = require "scenes.menus.titlescreen.screen"
function Title:new(fromMenu)
Title.super.new(self, true, true)
self.assets:addImage("logo", "assets/artworks/logo.png")
self.assets:addTileset("charicons", "assets/sprites/characters/charicons")
TitleScreen(fromMenu)
end
function Title:startPressed()
self.assets:playSFX("mSelect")
self.menusystem:setSoundFromSceneAssets("mBeep")
self.gui.focusedElement = nil
self.gui:playScreenTransform("titleScreen", "showMenu")
end
return Title

View file

@ -0,0 +1,73 @@
local RadianceMenu = require "birb.modules.gui.menus.listbox"
local RadianceWidget = require "birb.modules.gui.menus.widgets.base"
local SaveMenu = RadianceMenu:extend()
local SaveWidget = RadianceWidget:extend()
local gui = require "game.modules.gui"
local defTransitions = require "birb.modules.transitions"
local radTransitions = require "game.modules.transitions"
local HPADDING = 68
local VPADDING = 28
function SaveMenu:new()
local w, h = 424 - (HPADDING * 2), 240 - (VPADDING * 2)
SaveMenu.super.new(self, "save", 424/2, 240/2, w, h, 3)
self.ox = w/2
self.oy = h/2
self.sx = 0.8
self.sy = 0.8
self.opacity = 0
local metadata = game:getMetadata()
for i, save in ipairs(metadata) do
SaveWidget(self.scene, i, save)
end
self.textBox = gui.newTextBox("assets/gui/dialogbox.png", w - 8, (h / 3))
self.isVisible = true
end
function SaveMenu:cancelAction()
self:playSFX("back")
self.gui:playScreenTransform("titleScreen", "hideMenu")
self:looseFocus()
end
function SaveWidget:new(scene, saveid, savedata)
SaveWidget.super.new(self, "save")
self.saveid = saveid
self.savedata = savedata
self.emeralds = gui.getEmeraldsTexture(self.savedata.emeralds)
end
function SaveWidget:drawCanvas()
local basex, basey = 4, 2
love.graphics.draw(self.menu.textBox, basex, basey)
if (self.savedata.exist) then
local str = "Save " .. self.saveid
str = str .. "(" .. utils.math.numberToString(self.savedata.completion,3) .. "%)"
str = str .. " - " .. utils.time.toString(self.savedata.gametime)
str = str .. "\n"
str = str .. self.savedata.location .. "\n"
str = str .. "Rings: " .. self.savedata.rings
self.assets.fonts["small"]:draw(str, basex + 8, basey + 4)
for i, charName in ipairs(self.savedata.team) do
local data = core.datas:get("characters", charName)
local x = 18*(#self.savedata.team - i + 1) + 4 + basex
self.scene.assets.tileset["charicons"]:drawTile(data.icon,self.width - x, basey + 4)
end
love.graphics.draw(self.emeralds, basex + 168, basey + 21)
else
self.assets.fonts["small"]:draw("New save", basex + 8, basey + 4)
end
end
function SaveWidget:action()
game:read(self.saveid)
core.screen:startTransition(radTransitions.borders, defTransitions.circle, function() scenes.menus.main() end, 424/2, 240/2)
end
return SaveMenu

View file

@ -0,0 +1,30 @@
local TextElement = require "birb.modules.gui.elements.text"
local PressStart = TextElement:extend()
function PressStart:new(isVisible)
PressStart.super.new(self, "pressStart", "SA2font", "PRESS START", 424/2, 240/1.33, "center")
self.isVisible = isVisible or false
self.showPressStartTimer = 0
end
function PressStart:update(dt)
self.showPressStartTimer = self.showPressStartTimer - dt
if self.showPressStartTimer < 0 then
self.showPressStart = (self.showPressStart == false)
self.showPressStartTimer = 0.5
end
end
function PressStart:draw()
if (self.showPressStart) then
PressStart.super.draw(self)
end
end
function PressStart:keypressed(key)
if (key == "start") then
self.scene:startPressed()
end
end
return PressStart

View file

@ -0,0 +1,59 @@
local Screen = require "birb.modules.gui.screen"
local TitleScreen = Screen:extend()
local AssetElement = require "birb.modules.gui.elements.assets"
local TextureElement = require "birb.modules.gui.elements.drawable"
local PressStart = require "scenes.menus.titlescreen.pressStart"
local ColorElement = require "birb.modules.gui.elements.color"
local Menu = require "scenes.menus.titlescreen.menu"
local either = utils.math.either
local show = {
{"fade", "tween", 0.3, 0.4, {opacity = 0}, "outExpo"},
{"logo", "movement", 0.5, 0.6, 424/2, 80, "inOutQuart"},
{"flash", "tween", 1.1, 0.03, {opacity = 1}, "inQuart"},
{"flash", "tween", 1.25, 0.2, {opacity = 0}, "outExpo"},
--{"pressStart", "switch", 1.2, {"isVisible"}},
--{"pressStart", "delayFocus", 1.2},
}
local showMenu = {
{"save", "tween", 0, 0.25, {sx = 1, sy = 1, opacity = 1}, "inExpo"},
{"save", "delayFocus", 0.25},
}
local hideMenu = {
{"save", "tween", 0, 0.25, {sx = 0.8, sy = 0.8, opacity = 0}, "outExpo"},
{"pressStart", "delayFocus", 0.25},
}
function TitleScreen:new(fromMenu)
self.fromMenu = (fromMenu == true)
TitleScreen.super.new(self, "titleScreen")
self:addTransform("show", show)
self:addTransform("showMenu", showMenu)
self:addTransform("hideMenu", hideMenu)
if (not self.fromMenu) then
self:show()
else
self.isVisible = true
end
end
function TitleScreen:createElements()
local background = love.graphics.newImage("datas/gamedata/maps/sti/stuff/tilescreen.png")
local o = either(self.fromMenu, 0, 1)
local y = either(self.fromMenu, 80, -190)
local d = either(self.fromMenu, 0, 1.2)
return {
{TextureElement("background", background, 0, 0, 0, 1, 1, 0, 0, 1), 0, 200},
{ColorElement("fade", 0, 0, 0, o), 0, 5},
{AssetElement("logo", "images", "logo", 424/2, y, 0, 1, 1, "center", "center", 1, 0), 0, 4},
{ColorElement("flash", 1, 1, 1, 0), 0, 1},
{PressStart(self.fromMenu), d, 10, true},
{Menu(self), 0, 4},
}
end
return TitleScreen

Some files were not shown because too many files have changed in this diff Show more