From b1a7bdc2af631967ed02f6fcfe1992189214cd39 Mon Sep 17 00:00:00 2001 From: Kazhnuz Date: Tue, 4 Aug 2020 23:21:45 +0200 Subject: [PATCH] feat: make ennemies able to be choregraphied --- .../ennemies/classics/motobug/skills.lua | 2 +- .../datas/gamedata/ennemies/skills/tackle.lua | 26 +++ sonic-radiance.love/game/skills.lua | 12 ++ .../scenes/battlesystem/actors/battler.lua | 191 +++++++++++++++++ .../scenes/battlesystem/actors/hero.lua | 194 ------------------ .../scenes/debug/viewers/choregraphy/init.lua | 19 +- .../scenes/debug/viewers/choregraphy/menu.lua | 14 ++ .../viewers/choregraphy/mocks/fighter.lua | 14 ++ 8 files changed, 274 insertions(+), 198 deletions(-) create mode 100644 sonic-radiance.love/datas/gamedata/ennemies/skills/tackle.lua diff --git a/sonic-radiance.love/datas/gamedata/ennemies/classics/motobug/skills.lua b/sonic-radiance.love/datas/gamedata/ennemies/classics/motobug/skills.lua index 849dc74..77087dc 100644 --- a/sonic-radiance.love/datas/gamedata/ennemies/classics/motobug/skills.lua +++ b/sonic-radiance.love/datas/gamedata/ennemies/classics/motobug/skills.lua @@ -1,3 +1,3 @@ return { ---{attack_name}, + "tackle", } diff --git a/sonic-radiance.love/datas/gamedata/ennemies/skills/tackle.lua b/sonic-radiance.love/datas/gamedata/ennemies/skills/tackle.lua new file mode 100644 index 0000000..ae8b60d --- /dev/null +++ b/sonic-radiance.love/datas/gamedata/ennemies/skills/tackle.lua @@ -0,0 +1,26 @@ +-- A basic file describing the basic attack, in order to make it customizable one +-- day ? + +-- Also serve as a tutoriel for how to create a file attack and choregraphy + +return { + name = "tackle", + cost = 0, + + targetNumber = 1, -- 0 for targeting all ennemies + targetEnnemies = true, + + choregraphy = { -- the main attack choregraphy + {"goTo", "none", "target", -0.4, 0, 0.5, true}, + {"sendDamage", "none", 120, 100, false, false}, + {'addGFX', "sentDamage", 'hitGFX', "target", -0.4, 0, true, false}, + {'playSFX', "sentDamage", 'hitconnect'}, + {'jumpBack', "none", 0.3, true}, + {"wait", "none", 0.1}, + {'goTo', "none", "start", 0, 0, 0.3, true}, + }, + + onContact = { -- if the attack move and touch multiple ennemies, you can add + -- specific effect when you touch the ennemy. + }, +} diff --git a/sonic-radiance.love/game/skills.lua b/sonic-radiance.love/game/skills.lua index 39383ee..00f335e 100644 --- a/sonic-radiance.love/game/skills.lua +++ b/sonic-radiance.love/game/skills.lua @@ -16,6 +16,18 @@ function SkillManager:skillDataExists(skillname) return (fileinfo ~= nil) end +function SkillManager:getEnnemySkillData(skillname) + if self:ennemySkillDataExists(skillname) then + return require("datas.gamedata.ennemies.skills." .. skillname ) + end +end + +function SkillManager:ennemySkillDataExists(skillname) + local dir = "datas/gamedata/ennemies/skills/" .. skillname .. ".lua" + local fileinfo = love.filesystem.getInfo(dir) + return (fileinfo ~= nil) +end + function SkillManager:getActionArguments(choregraphyAction) local choregraphyData = require "datas.gamedata.skills" local args = {} diff --git a/sonic-radiance.love/scenes/battlesystem/actors/battler.lua b/sonic-radiance.love/scenes/battlesystem/actors/battler.lua index db41947..3cedfdb 100644 --- a/sonic-radiance.love/scenes/battlesystem/actors/battler.lua +++ b/sonic-radiance.love/scenes/battlesystem/actors/battler.lua @@ -1,6 +1,12 @@ local Parent = require("scenes.battlesystem.actors.parent") local Battler = Parent:extend() +local MOVEMENT_NONE = "none" +local MOVEMENT_TWEENER = "tweener" +local MOVEMENT_MOTION = "motion" + +local ZGRAVITY = 0.2 + local MIDDLE_ARENA = 6 function Battler:new(world, x, y, z, owner) @@ -13,6 +19,8 @@ function Battler:new(world, x, y, z, owner) self.start.y = y self.start.direction = self.direction + self:initMovementSystem() + self.isBattler = true self.speed = 3 self.isActive = false @@ -42,8 +50,185 @@ function Battler:update(dt) self.world:switchActiveBattler() end end + + self:updateMovement(dt) end +-- MOVE FUNCTIONS +-- All functions handling the moving + +local MOVEMENT_DURATION = 0.20 + +function Battler:initMovementSystem() + self.xprevious, self.yprevious, self.zprevious = self.x, self.y, self.z + self.xspeed, self.yspeed, self.zspeed = 0,0,0 + self.direction = self.start.direction + self.directionPrevious = self.start.direction + self.directionLocked = false + + self.movementType = MOVEMENT_NONE + + self:initJump() +end + +function Battler:updateMovement(dt) + if (self.movementType == MOVEMENT_TWEENER) then + self:updateTweenerSpeed(dt) + elseif (self.movementType == MOVEMENT_MOTION) then + self:updateMotion(dt) + end + self.gspeed = math.sqrt(self.xspeed^2 + self.yspeed^2) + + self:updateDirection(dt) + self:updateJump(dt) + self:updatePreviousPosition(dt) +end + +function Battler:updatePreviousPosition() + self.xprevious = self.x + self.yprevious = self.y + self.zprevious = self.z +end + +-- Tweener movement functions + +function Battler:goTo(dx, dy, duration, easing) + local easing = easing or 'inOutQuad' + if duration > 0 then + self.tweens:newTween(0, duration, {x = dx, y = dy}, easing) + end + self.tweens:newTimer(duration + 0.02, "goTo") + self.tweens:newTimer(duration + 0.02, "resetMovement") + + self.movementType = MOVEMENT_TWEENER +end + +function Battler:jumpTo(dx, dy, sizeFactor, duration, spinjump, easing) + local easing = easing or 'inOutQuad' + local dist = utils.math.pointDistance(self.x, self.y, dx, dy) + local jumpHeight = dist * 8 * sizeFactor + self.tweens:newTween(0, duration, {x = dx, y = dy}, easing) + self.tweens:newTimer(duration + 0.02, "jumpTo") + self:setJump(jumpHeight, spinjump, duration) +end + +function Battler:updateTweenerSpeed(dt) + self.xspeed = (self.x - self.xprevious) / dt + self.yspeed = (self.y - self.yprevious) / dt +end + +-- MOTION HANDLING + +function Battler:setMotion(xspeed, yspeed) + self.xspeed = xspeed + self.yspeed = yspeed + self.movementType = MOVEMENT_MOTION +end + +function Battler:updateMotion(dt) + self.x = self.x + (self.xspeed) * dt + self.y = self.y + (self.yspeed) * dt +end + +function Battler:endMotion() + self.movementType = MOVEMENT_NONE + self.xspeed = 0 + self.yspeed = 0 +end + +-- Direction handling + +function Battler:updateDirection() + -- Handle direction + if math.abs(self.xspeed) >= 0.01 then + if (self.directionLocked == false) then + self.direction = utils.math.sign(self.xspeed) + end + end +end + +-- Jump system + +function Battler:initJump() + self.jump = {} + self.jump.useDefaultAnimation = true + self.jump.isJumping = false + self.jump.bounceNumber = 0 + self.jump.isJumpingBack = false +end + +function Battler:setJump(power, bounceNumber, useDefaultAnimation) + self.zspeed = power + self.jump.spin = spinjump + self.jump.bounceNumber = bounceNumber + self.jump.isJumping = true +end + +function Battler:jumpBack() + self:setJump(4, 0, true) + local dir = utils.math.pointDirection(self.x, self.y, self.start.x, self.start.y) + local hspeed, vspeed = utils.math.lengthdir(8, dir) + self:setMotion(hspeed, vspeed) + self.jump.isJumpingBack = true +end + +function Battler:updateJump(dt) + if (self.jump.isJumping) then + self.zspeed = self.zspeed - ZGRAVITY + self.z = self.z + self.zspeed + if (self.z <= 0) then + if (self.jump.bounceNumber > 0) then + self.zspeed = self.zspeed * -0.5 + self.jump.bounceNumber = self.jump.bounceNumber - 1 + else + self.z = 0 + self.jump.isJumping = false + self.jump.spin = false + self:timerResponse("jump") + if (self.jump.isJumpingBack) then + self:endMotion() + end + self:changeAnimation("idle") + end + end + end +end + +-- CHOREGRAPHY FUNCTIONS +-- All functions related to the choregraphy system + +function Battler:blockChoregraphy(isBlocking, currentlyBlocking, blockedBy) + if (isBlocking) then + self.currentlyBlocking = currentlyBlocking + self.blockedBy = blockedBy + end +end + +function Battler:unblockChoregraphy() + self.currentlyBlocking:finish() + self.currentlyBlocking = nil +end + +function Battler:timerResponse(signal) + if ((self.currentlyBlocking ~= nil) and (signal == self.blockedBy)) then + self:unblockChoregraphy() + end + + if (signal == "resetMovement") then + self.movementType = MOVEMENT_NONE + end +end + +function Battler:choregraphyEnded() + self.direction = self.start.direction + self.x = self.start.x + self.y = self.start.y + self.xspeed = 0 + self.yspeed = 0 + self.movementType = MOVEMENT_NONE +end + +-- DRAW FUNCTIONS function Battler:draw() local x, y = self.world.map:gridToPixel(self.x, self.y, true) love.graphics.setColor(1, 0, 0, 1) @@ -61,6 +246,12 @@ function Battler:initSprite() self:changeAnimation("idle") end +function Battler:animationEnded(animation) + if (self.currentlyBlocking ~= nil and self.blockedBy=="animation") then + self:unblockChoregraphy() + end +end + function Battler:validateAction() end diff --git a/sonic-radiance.love/scenes/battlesystem/actors/hero.lua b/sonic-radiance.love/scenes/battlesystem/actors/hero.lua index 3a76373..514910b 100644 --- a/sonic-radiance.love/scenes/battlesystem/actors/hero.lua +++ b/sonic-radiance.love/scenes/battlesystem/actors/hero.lua @@ -1,24 +1,12 @@ local Battler = require("scenes.battlesystem.actors.battler") local Hero = Battler:extend() -local MOVEMENT_NONE = "none" -local MOVEMENT_TWEENER = "tweener" -local MOVEMENT_MOTION = "motion" - -local ZGRAVITY = 0.2 - -- INIT FUNCTIONS -- Initialize the hero function Hero:new(world, x, y, owner, charnumber) Hero.super.new(self, world, x, y, 0, owner) - self.isHero = true - - self:initMovementSystem() - self:initSprite() - - self.side = "heroes" end -- UPDATE FUNCTION @@ -26,185 +14,9 @@ end function Hero:update(dt) Hero.super.update(self, dt) - self:updateMovement(dt) - self:updateAnimation(dt) end --- MOVE FUNCTIONS --- All functions handling the moving - -local MOVEMENT_DURATION = 0.20 - -function Hero:initMovementSystem() - self.xprevious, self.yprevious, self.zprevious = self.x, self.y, self.z - self.xspeed, self.yspeed, self.zspeed = 0,0,0 - self.direction = self.start.direction - self.directionPrevious = self.start.direction - self.directionLocked = false - - self.movementType = MOVEMENT_NONE - - self:initJump() -end - -function Hero:updateMovement(dt) - if (self.movementType == MOVEMENT_TWEENER) then - self:updateTweenerSpeed(dt) - elseif (self.movementType == MOVEMENT_MOTION) then - self:updateMotion(dt) - end - self.gspeed = math.sqrt(self.xspeed^2 + self.yspeed^2) - - self:updateDirection(dt) - self:updateJump(dt) - self:updatePreviousPosition(dt) -end - -function Hero:updatePreviousPosition() - self.xprevious = self.x - self.yprevious = self.y - self.zprevious = self.z -end - --- Tweener movement functions - -function Hero:goTo(dx, dy, duration, easing) - local easing = easing or 'inOutQuad' - if duration > 0 then - self.tweens:newTween(0, duration, {x = dx, y = dy}, easing) - end - self.tweens:newTimer(duration + 0.02, "goTo") - self.tweens:newTimer(duration + 0.02, "resetMovement") - - self.movementType = MOVEMENT_TWEENER -end - -function Hero:jumpTo(dx, dy, sizeFactor, duration, spinjump, easing) - local easing = easing or 'inOutQuad' - local dist = utils.math.pointDistance(self.x, self.y, dx, dy) - local jumpHeight = dist * 8 * sizeFactor - self.tweens:newTween(0, duration, {x = dx, y = dy}, easing) - self.tweens:newTimer(duration + 0.02, "jumpTo") - self:setJump(jumpHeight, spinjump, duration) -end - -function Hero:updateTweenerSpeed(dt) - self.xspeed = (self.x - self.xprevious) / dt - self.yspeed = (self.y - self.yprevious) / dt -end - --- MOTION HANDLING - -function Hero:setMotion(xspeed, yspeed) - self.xspeed = xspeed - self.yspeed = yspeed - self.movementType = MOVEMENT_MOTION -end - -function Hero:updateMotion(dt) - self.x = self.x + (self.xspeed) * dt - self.y = self.y + (self.yspeed) * dt -end - -function Hero:endMotion() - self.movementType = MOVEMENT_NONE - self.xspeed = 0 - self.yspeed = 0 -end - --- Direction handling - -function Hero:updateDirection() - -- Handle direction - if math.abs(self.xspeed) >= 0.01 then - if (self.directionLocked == false) then - self.direction = utils.math.sign(self.xspeed) - end - end -end - --- Jump system - -function Hero:initJump() - self.jump = {} - self.jump.useDefaultAnimation = true - self.jump.isJumping = false - self.jump.bounceNumber = 0 - self.jump.isJumpingBack = false -end - -function Hero:setJump(power, bounceNumber, useDefaultAnimation) - self.zspeed = power - self.jump.spin = spinjump - self.jump.bounceNumber = bounceNumber - self.jump.isJumping = true -end - -function Hero:jumpBack() - self:setJump(3, 0, true) - local dir = utils.math.pointDirection(self.x, self.y, self.start.x, self.start.y) - local hspeed, vspeed = utils.math.lengthdir(10, dir) - self:setMotion(hspeed, vspeed) - self.jump.isJumpingBack = true -end - -function Hero:updateJump(dt) - if (self.jump.isJumping) then - self.zspeed = self.zspeed - ZGRAVITY - self.z = self.z + self.zspeed - if (self.z <= 0) then - if (self.jump.bounceNumber > 0) then - self.zspeed = self.zspeed * -0.5 - self.jump.bounceNumber = self.jump.bounceNumber - 1 - else - self.z = 0 - self.jump.isJumping = false - self.jump.spin = false - self:timerResponse("jump") - if (self.jump.isJumpingBack) then - self:endMotion() - end - self:changeAnimation("idle") - end - end - end -end - --- CHOREGRAPHY FUNCTIONS --- All functions related to the choregraphy system - -function Hero:blockChoregraphy(isBlocking, currentlyBlocking, blockedBy) - if (isBlocking) then - self.currentlyBlocking = currentlyBlocking - self.blockedBy = blockedBy - end -end - -function Hero:unblockChoregraphy() - self.currentlyBlocking:finish() - self.currentlyBlocking = nil -end - -function Hero:timerResponse(signal) - if ((self.currentlyBlocking ~= nil) and (signal == self.blockedBy)) then - self:unblockChoregraphy() - end - - if (signal == "resetMovement") then - self.movementType = MOVEMENT_NONE - end -end - -function Hero:choregraphyEnded() - self.direction = self.start.direction - self.x = self.start.x - self.y = self.start.y - self.xspeed = 0 - self.yspeed = 0 - self.movementType = MOVEMENT_NONE -end - -- ASSETS FUNCTIONS -- Load and play assets needed by the character @@ -212,12 +24,6 @@ function Hero:getSpritePath() return "datas/gamedata/characters/" .. self.owner.name .. "/sprites" end -function Hero:animationEnded(animation) - if (self.currentlyBlocking ~= nil and self.blockedBy=="animation") then - self:unblockChoregraphy() - end -end - function Hero:updateAnimation(dt) if (self.z > 0 and self.jump.useDefaultAnimation) then if self.zspeed > 0 then diff --git a/sonic-radiance.love/scenes/debug/viewers/choregraphy/init.lua b/sonic-radiance.love/scenes/debug/viewers/choregraphy/init.lua index 2fce748..bd659ff 100644 --- a/sonic-radiance.love/scenes/debug/viewers/choregraphy/init.lua +++ b/sonic-radiance.love/scenes/debug/viewers/choregraphy/init.lua @@ -46,13 +46,22 @@ end function ChoregraphyViewer:buildEnnemyListMenu(category) self:addSubMenu(category, "MainMenu", category) for i,ennemy in ipairs(ennutils.getEnnemiesFromCategory(category)) do - self:addSubMenu(ennemy, category, ennemy) - - menu.commons.SubMenuWidget(self, ennemy, category, "Back") + self:buildEnnemySkillMenu(category, ennemy) end menu.commons.SubMenuWidget(self, category, "MainMenu", "Back") end +function ChoregraphyViewer:buildEnnemySkillMenu(category, ennemy) + self:addSubMenu(ennemy, category, ennemy) + local data = ennutils.getData(category, ennemy) + for j,skillName in ipairs(data.skills) do + if (game.skills:ennemySkillDataExists(skillName)) then + menu.EnnemyChoregraphyWidget(self, category, ennemy, game.skills:getEnnemySkillData(skillName)) + end + end + menu.commons.SubMenuWidget(self, ennemy, category, "Back") +end + function ChoregraphyViewer:buildSkillMenu(charName) local skillList = require("datas.gamedata.characters." .. charName .. ".skills") local skillTreated = {} @@ -82,6 +91,10 @@ 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) diff --git a/sonic-radiance.love/scenes/debug/viewers/choregraphy/menu.lua b/sonic-radiance.love/scenes/debug/viewers/choregraphy/menu.lua index 8a370ee..804f50b 100644 --- a/sonic-radiance.love/scenes/debug/viewers/choregraphy/menu.lua +++ b/sonic-radiance.love/scenes/debug/viewers/choregraphy/menu.lua @@ -3,6 +3,7 @@ local menu = {} menu.commons = commons menu.ShowBackgroundWidget = menu.commons.DebugWidget:extend() menu.HeroChoregraphyWidget = commons.DebugWidget:extend() +menu.EnnemyChoregraphyWidget = commons.DebugWidget:extend() -- ShowBackground function menu.ShowBackgroundWidget:new(scene, menuName, backgroundName, backgroundId) @@ -27,5 +28,18 @@ function menu.HeroChoregraphyWidget:action() 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 diff --git a/sonic-radiance.love/scenes/debug/viewers/choregraphy/mocks/fighter.lua b/sonic-radiance.love/scenes/debug/viewers/choregraphy/mocks/fighter.lua index 2428387..ec9df07 100644 --- a/sonic-radiance.love/scenes/debug/viewers/choregraphy/mocks/fighter.lua +++ b/sonic-radiance.love/scenes/debug/viewers/choregraphy/mocks/fighter.lua @@ -26,6 +26,16 @@ function FighterMock:playHeroChoregraphy(character, data) 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() @@ -33,4 +43,8 @@ function FighterMock:finishAction() self.scene.menusystem:activate() end +function FighterMock:drawHUD() + +end + return FighterMock