chore: use Radiance scenes
This commit is contained in:
parent
8c04e08b25
commit
66b77d59ed
165 changed files with 8506 additions and 2399 deletions
140
sonic-bluestreak.love/scenes/battlesystem/actors/battler.lua
Normal file
140
sonic-bluestreak.love/scenes/battlesystem/actors/battler.lua
Normal 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
|
55
sonic-bluestreak.love/scenes/battlesystem/actors/ennemy.lua
Normal file
55
sonic-bluestreak.love/scenes/battlesystem/actors/ennemy.lua
Normal 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
|
73
sonic-bluestreak.love/scenes/battlesystem/actors/gfx.lua
Normal file
73
sonic-bluestreak.love/scenes/battlesystem/actors/gfx.lua
Normal 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
|
94
sonic-bluestreak.love/scenes/battlesystem/actors/hero.lua
Normal file
94
sonic-bluestreak.love/scenes/battlesystem/actors/hero.lua
Normal 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
|
10
sonic-bluestreak.love/scenes/battlesystem/actors/init.lua
Normal file
10
sonic-bluestreak.love/scenes/battlesystem/actors/init.lua
Normal 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
|
267
sonic-bluestreak.love/scenes/battlesystem/actors/movable.lua
Normal file
267
sonic-bluestreak.love/scenes/battlesystem/actors/movable.lua
Normal 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
|
296
sonic-bluestreak.love/scenes/battlesystem/actors/parent.lua
Normal file
296
sonic-bluestreak.love/scenes/battlesystem/actors/parent.lua
Normal 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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
local qtes = {}
|
||||
|
||||
local baseURI = "scenes.battlesystem.choregraphy.qte."
|
||||
|
||||
qtes["simplePrompt"] = require (baseURI .. "simpleprompt")
|
||||
|
||||
return qtes
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,5 @@
|
|||
local folder = "scenes.battlesystem.fighters.ennemy.behaviours."
|
||||
|
||||
return {
|
||||
["random"] = require(folder .. "random")
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
267
sonic-bluestreak.love/scenes/battlesystem/fighters/fighter.lua
Normal file
267
sonic-bluestreak.love/scenes/battlesystem/fighters/fighter.lua
Normal 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
|
104
sonic-bluestreak.love/scenes/battlesystem/fighters/parent.lua
Normal file
104
sonic-bluestreak.love/scenes/battlesystem/fighters/parent.lua
Normal 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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
42
sonic-bluestreak.love/scenes/battlesystem/gui/init.lua
Normal file
42
sonic-bluestreak.love/scenes/battlesystem/gui/init.lua
Normal 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
|
|
@ -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
|
122
sonic-bluestreak.love/scenes/battlesystem/gui/victory/init.lua
Normal file
122
sonic-bluestreak.love/scenes/battlesystem/gui/victory/init.lua
Normal 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
|
|
@ -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
|
|
@ -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
|
86
sonic-bluestreak.love/scenes/battlesystem/init.lua
Normal file
86
sonic-bluestreak.love/scenes/battlesystem/init.lua
Normal 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
|
79
sonic-bluestreak.love/scenes/battlesystem/rewards.lua
Normal file
79
sonic-bluestreak.love/scenes/battlesystem/rewards.lua
Normal 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
|
170
sonic-bluestreak.love/scenes/battlesystem/turns.lua
Normal file
170
sonic-bluestreak.love/scenes/battlesystem/turns.lua
Normal 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
|
24
sonic-bluestreak.love/scenes/battlesystem/utils.lua
Normal file
24
sonic-bluestreak.love/scenes/battlesystem/utils.lua
Normal 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
|
100
sonic-bluestreak.love/scenes/battlesystem/world.lua
Normal file
100
sonic-bluestreak.love/scenes/battlesystem/world.lua
Normal 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
|
|
@ -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"
|
||||
}
|
||||
|
|
76
sonic-bluestreak.love/scenes/menus/commons/menu.lua
Normal file
76
sonic-bluestreak.love/scenes/menus/commons/menu.lua
Normal 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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,11 @@
|
|||
local TurnSystemMock = Object:extend()
|
||||
|
||||
function TurnSystemMock:new()
|
||||
|
||||
end
|
||||
|
||||
function TurnSystemMock:applyDeath()
|
||||
|
||||
end
|
||||
|
||||
return TurnSystemMock
|
10
sonic-bluestreak.love/scenes/menus/init.lua
Normal file
10
sonic-bluestreak.love/scenes/menus/init.lua
Normal 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"
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
local folder = "scenes.menus.mainmenu.infopanel."
|
||||
|
||||
return {
|
||||
Gamedata = require(folder .. "gamedata"),
|
||||
Character = require(folder .. "character"),
|
||||
Team = require(folder .. "team"),
|
||||
}
|
|
@ -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
|
|
@ -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
|
15
sonic-bluestreak.love/scenes/menus/mainmenu/init.lua
Normal file
15
sonic-bluestreak.love/scenes/menus/mainmenu/init.lua
Normal 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;
|
48
sonic-bluestreak.love/scenes/menus/mainmenu/menu.lua
Normal file
48
sonic-bluestreak.love/scenes/menus/mainmenu/menu.lua
Normal 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
|
34
sonic-bluestreak.love/scenes/menus/options/init.lua
Normal file
34
sonic-bluestreak.love/scenes/menus/options/init.lua
Normal 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
|
216
sonic-bluestreak.love/scenes/menus/options/menu.lua
Normal file
216
sonic-bluestreak.love/scenes/menus/options/menu.lua
Normal 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
|
44
sonic-bluestreak.love/scenes/menus/titlescreen/init.lua
Normal file
44
sonic-bluestreak.love/scenes/menus/titlescreen/init.lua
Normal 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
|
73
sonic-bluestreak.love/scenes/menus/titlescreen/menu.lua
Normal file
73
sonic-bluestreak.love/scenes/menus/titlescreen/menu.lua
Normal 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
|
|
@ -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
|
59
sonic-bluestreak.love/scenes/menus/titlescreen/screen.lua
Normal file
59
sonic-bluestreak.love/scenes/menus/titlescreen/screen.lua
Normal 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
Loading…
Reference in a new issue