diff --git a/sonic-radiance.love/assets/backgrounds/options.png b/sonic-radiance.love/assets/backgrounds/options.png new file mode 100644 index 0000000..20941e8 Binary files /dev/null and b/sonic-radiance.love/assets/backgrounds/options.png differ diff --git a/sonic-radiance.love/assets/backgrounds/parallax/forest-back.png b/sonic-radiance.love/assets/backgrounds/parallax/forest-back.png index 760bccc..3e87be8 100644 Binary files a/sonic-radiance.love/assets/backgrounds/parallax/forest-back.png and b/sonic-radiance.love/assets/backgrounds/parallax/forest-back.png differ diff --git a/sonic-radiance.love/assets/backgrounds/parallax/forest-fore.png b/sonic-radiance.love/assets/backgrounds/parallax/forest-fore.png index 4389e55..dfd4c6e 100644 Binary files a/sonic-radiance.love/assets/backgrounds/parallax/forest-fore.png and b/sonic-radiance.love/assets/backgrounds/parallax/forest-fore.png differ diff --git a/sonic-radiance.love/assets/backgrounds/parallax/hills-back.png b/sonic-radiance.love/assets/backgrounds/parallax/hills-back.png index 9fd9409..da44d1c 100644 Binary files a/sonic-radiance.love/assets/backgrounds/parallax/hills-back.png and b/sonic-radiance.love/assets/backgrounds/parallax/hills-back.png differ diff --git a/sonic-radiance.love/assets/backgrounds/parallax/hills-fore.png b/sonic-radiance.love/assets/backgrounds/parallax/hills-fore.png index 6353414..1cb948f 100644 Binary files a/sonic-radiance.love/assets/backgrounds/parallax/hills-fore.png and b/sonic-radiance.love/assets/backgrounds/parallax/hills-fore.png differ diff --git a/sonic-radiance.love/assets/gui/fonts/SA2font.lua b/sonic-radiance.love/assets/gui/fonts/SA2font.lua new file mode 100644 index 0000000..8b7e7ff --- /dev/null +++ b/sonic-radiance.love/assets/gui/fonts/SA2font.lua @@ -0,0 +1,4 @@ +return { + glyphs = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZÇÂÄÀÆÉÊËÈÎÏÔÖŒÜÛÙ[\\]^_`abcdefghijklmnopqrstuvwxyzçâäàæéêëèïîôöœûüù{|}", + extraspacing = 0, +} diff --git a/sonic-radiance.love/assets/gui/fonts/SA2font.png b/sonic-radiance.love/assets/gui/fonts/SA2font.png new file mode 100644 index 0000000..f377f4c Binary files /dev/null and b/sonic-radiance.love/assets/gui/fonts/SA2font.png differ diff --git a/sonic-radiance.love/assets/gui/fonts/sadv.lua b/sonic-radiance.love/assets/gui/fonts/sadv.lua new file mode 100644 index 0000000..956a37b --- /dev/null +++ b/sonic-radiance.love/assets/gui/fonts/sadv.lua @@ -0,0 +1,4 @@ +return { + glyphs = "abcdefghijklmnopqrstuvwxyz0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ", + extraspacing = 1 +} diff --git a/sonic-radiance.love/assets/sprites/charset/perso.png b/sonic-radiance.love/assets/sprites/charset/perso.png new file mode 100644 index 0000000..0cc9985 Binary files /dev/null and b/sonic-radiance.love/assets/sprites/charset/perso.png differ diff --git a/sonic-radiance.love/assets/sprites/gfx/smallsmoke.lua b/sonic-radiance.love/assets/sprites/gfx/smallsmoke.lua new file mode 100644 index 0000000..4dbd8f2 --- /dev/null +++ b/sonic-radiance.love/assets/sprites/gfx/smallsmoke.lua @@ -0,0 +1,18 @@ +return { + metadata = { + height = 16, + width = 16, + defaultAnim = "default", + ox = 8, + oy = 8, + }, + animations = { + ["default"] = { + startAt = 1, + endAt = 8, + loop = 1, + speed = 15, + pauseAtEnd = false, + }, + } +} diff --git a/sonic-radiance.love/assets/sprites/gfx/smallsmoke.png b/sonic-radiance.love/assets/sprites/gfx/smallsmoke.png new file mode 100644 index 0000000..94ac95d Binary files /dev/null and b/sonic-radiance.love/assets/sprites/gfx/smallsmoke.png differ diff --git a/sonic-radiance.love/core/input.lua b/sonic-radiance.love/core/input.lua index 4653aa1..2d6c4c6 100644 --- a/sonic-radiance.love/core/input.lua +++ b/sonic-radiance.love/core/input.lua @@ -158,13 +158,13 @@ function VirtualPad:checkKey(key) local isDown = self:isDown(key) if (isDown) then if not (self.keys[key].isDown) then - core.debug:print("virtualpad", "key " .. key .. " is Pressed") + --core.debug:print("virtualpad", "key " .. key .. " is Pressed") self.keys[key].isDown = true self.keys[key].isPressed = true self.keys[key].isReleased = false else if (self.keys[key].isPressed) then - core.debug:print("virtualpad", "key " .. key .. " is Down") + --core.debug:print("virtualpad", "key " .. key .. " is Down") self.keys[key].isPressed = false end end @@ -175,7 +175,7 @@ function VirtualPad:checkKey(key) self.keys[key].isReleased = true else if (self.keys[key].isReleased) then - core.debug:print("virtualpad", "key " .. key .. " is Released") + --core.debug:print("virtualpad", "key " .. key .. " is Released") self.keys[key].isReleased = false end end diff --git a/sonic-radiance.love/core/modules/menusystem/listbox.lua b/sonic-radiance.love/core/modules/menusystem/listbox.lua index b8e47e7..10e4f85 100644 --- a/sonic-radiance.love/core/modules/menusystem/listbox.lua +++ b/sonic-radiance.love/core/modules/menusystem/listbox.lua @@ -126,10 +126,10 @@ function ListBox:draw() local widgety = self.y for i,v in ipairs(self.widget.list) do if (i >= self.view.firstSlot) and (i < self.view.firstSlot + self.view.slotNumber) then - v:draw(self.x, widgety, self.w, self.widget.h) if self.widget.selected == i and self:haveFocus() == true then v:drawSelected(self.x, widgety, self.w, self.widget.h) else + utils.graphics.resetColor() v:draw(self.x, widgety, self.w, self.widget.h) end widgety = widgety + self.widget.h diff --git a/sonic-radiance.love/core/modules/menusystem/widgets/init.lua b/sonic-radiance.love/core/modules/menusystem/widgets/init.lua index 9c02e5a..15ab5b2 100644 --- a/sonic-radiance.love/core/modules/menusystem/widgets/init.lua +++ b/sonic-radiance.love/core/modules/menusystem/widgets/init.lua @@ -91,7 +91,6 @@ end function BaseWidget:draw(x, y) if self.canvas.texture ~= nil then - utils.graphics.resetColor() love.graphics.draw(self.canvas.texture, x, y) end end diff --git a/sonic-radiance.love/datas/gamedata/characters/sonic/skills.lua b/sonic-radiance.love/datas/gamedata/characters/sonic/skills.lua index b68f655..2aed1c1 100644 --- a/sonic-radiance.love/datas/gamedata/characters/sonic/skills.lua +++ b/sonic-radiance.love/datas/gamedata/characters/sonic/skills.lua @@ -1,7 +1,7 @@ return { --{attack_name, level}, {"spinattack", 2}, - {"spinjump", 3}, + --{"spinjump", 3}, {"spindash", 8}, {"hommingattack", 11}, {"spinattack", 15}, diff --git a/sonic-radiance.love/datas/gamedata/maps/battle/crouge/init.lua b/sonic-radiance.love/datas/gamedata/maps/battle/crouge/init.lua index f485ed8..d1d0918 100644 --- a/sonic-radiance.love/datas/gamedata/maps/battle/crouge/init.lua +++ b/sonic-radiance.love/datas/gamedata/maps/battle/crouge/init.lua @@ -1,5 +1,5 @@ return { - name = "Chao Ruins", + name = "Club Rouge", blocks = { { 56, 128, 16, 96, "top1", "side1"}, {248, 128, 16, 96, "top1", "side1"}, diff --git a/sonic-radiance.love/datas/gamedata/maps/battle/init.lua b/sonic-radiance.love/datas/gamedata/maps/battle/init.lua new file mode 100644 index 0000000..5a88bd3 --- /dev/null +++ b/sonic-radiance.love/datas/gamedata/maps/battle/init.lua @@ -0,0 +1 @@ +return {"aroom", "bhighway", "crouge", "cruins", "ebeach", "ghill", "hsummit", "library", "mdepot", "tlab"} diff --git a/sonic-radiance.love/datas/gamedata/skills/attack.lua b/sonic-radiance.love/datas/gamedata/skills/attack.lua index 021eee9..d3ba280 100644 --- a/sonic-radiance.love/datas/gamedata/skills/attack.lua +++ b/sonic-radiance.love/datas/gamedata/skills/attack.lua @@ -8,37 +8,41 @@ return { cost = 00, -- the pp cost of the attack. Will be ignored if it's set -- as character default attack - target = nil, -- which area can be selected as a target with the cursor. - -- if not nil : {ox, oy, shape, size, affectedByDirection} - - targetNumber = 1, -- how many ennemy you can target with the attack. - - effectArea = {1, 0, "point", 1, true}, -- which area is affected by the attack - -- if not nil : {ox, oy, shape, size, affectedByDirection} + needTarget = true, + targetNumber = 1, -- 0 for targeting all ennemies choregraphy = { -- the main attack choregraphy + {"setAnimation", "none", "walk", false}, + {'goTo', "none", "target", -1, 0, 0.3, true}, + + {"addQTE", "none", {"simplePrompt", "A", 0.2}, "target", false}, {'playSFX', "none", 'hit'}, {'setAnimation', "none", 'hit1start', true}, {'sendDamage', "none", 33, 100, false, false}, - {'addGFX',"sentDamage", 'hitGFX', 0.75, 0, true, false}, + {'addGFX',"sentDamage", 'hitGFX', "actor", 0.75, 0, true, false}, {'playSFX', "sentDamage", 'hitconnect'}, {'setAnimation', "none", 'hit1end', true}, + {"addQTE", "none", {"simplePrompt", "A", 0.2}, "target", false}, {'playSFX', "none", 'hit'}, {'setAnimation', "none", 'hit2start', true}, {'sendDamage', "none", 33, 100, false, false}, - {'addGFX',"sentDamage", 'hitGFX', 0.75, 0, true, false}, + {'addGFX',"sentDamage", 'hitGFX', "actor", 0.75, 0, true, false}, {'playSFX', "sentDamage", 'hitconnect'}, {'setAnimation', "none", 'hit2end', true}, + {"addQTE", "none", {"simplePrompt", "A", 0.2}, "target", false}, {'playSFX', "none", 'hit'}, {'setAnimation', "none", 'hit3start', true}, {'sendDamage', "none", 33, 100, false, false}, - {'addGFX',"sentDamage", 'hitGFX', 0.75, 0, true, false}, + {'addGFX',"sentDamage", 'hitGFX', "actor", 0.75, 0, true, false}, {'playSFX', "sentDamage", 'hitconnect'}, {'setAnimation', "none", 'hit3end', true}, {'setAnimation', "none", 'idle', false}, - {'wait', "none", 0.5} + {'wait', "none", 0.2}, + {"setAnimation", "none", "walk", false}, + {'goTo', "none", "start", 0, 0, 0.3, true}, + {'setAnimation', "none", 'idle', false}, }, onContact = { -- if the attack move and touch multiple ennemies, you can add diff --git a/sonic-radiance.love/datas/gamedata/skills/spinattack.lua b/sonic-radiance.love/datas/gamedata/skills/spinattack.lua index f70ae50..1616646 100644 --- a/sonic-radiance.love/datas/gamedata/skills/spinattack.lua +++ b/sonic-radiance.love/datas/gamedata/skills/spinattack.lua @@ -1,19 +1,33 @@ +-- 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 = "spinattack", - cost = 05, - target = nil, -- No targeting capacity - effectArea = {0, 0, "line", 5, true}, -- which area is affected by the attack - choregraphy = { - {"setAnimation", "none", "spindash", false}, - {'playSFX', "none", 'spincharge'}, - {"wait", "none", 0.5}, + cost = 03, + + targetNumber = 1, -- 0 for targeting all ennemies + targetEnnemies = true, + + choregraphy = { -- the main attack choregraphy + {"setAnimation", "none", "walk", false}, + {"goTo", "none", "target", 0, 0, 0.6, false}, + {"wait", "none", 0.3}, {"setAnimation", "none", "spin", false}, {'playSFX', "none", 'spinrelease'}, - {"dashForward", "none", 12, true}, - {"sendDamageFromPos", "none", 0, 0, 120, 100, false, false, true}, - {'addGFX', "sentDamage", 'hitGFX', 0, 0, true, false}, + {"waitActorFinished", "none", "goTo"}, + {"sendDamage", "none", 120, 100, false, false}, + {'addGFX', "sentDamage", 'hitGFX', "target", 0, 0, true, false}, {'playSFX', "sentDamage", 'hitconnect'}, - {'jumpBack', "none", true}, + {'jumpBack', "none", 0.3, true}, + {"wait", "none", 0.1}, + {"setAnimation", "none", "walk", false}, + {'goTo', "none", "start", 0, 0, 0.3, true}, {'setAnimation', "none", 'idle', false}, - } + }, + + 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/datas/gamedata/skills/spindash.lua b/sonic-radiance.love/datas/gamedata/skills/spindash.lua new file mode 100644 index 0000000..02a2076 --- /dev/null +++ b/sonic-radiance.love/datas/gamedata/skills/spindash.lua @@ -0,0 +1,22 @@ +return { + name = "spindash", + cost = 05, + targetNumber = 1, -- 0 for targeting all ennemies + targetEnnemies = true, + choregraphy = { + {"setAnimation", "none", "spindash", false}, + {'playSFX', "none", 'spincharge'}, + {"wait", "none", 0.5}, + {"setAnimation", "none", "spin", false}, + {'playSFX', "none", 'spinrelease'}, + {"goTo", "none", "target", 0, 0, 0.3, true}, + {"sendDamage", "none", 120, 100, false, false}, + {'addGFX', "sentDamage", 'hitGFX', "target", 0, 0, true, false}, + {'playSFX', "sentDamage", 'hitconnect'}, + {'jumpBack', "none", 0.3, true}, + {"wait", "none", 0.1}, + {"setAnimation", "none", "walk", false}, + {'goTo', "none", "start", 0, 0, 0.3, true}, + {'setAnimation', "none", 'idle', false}, + } +} diff --git a/sonic-radiance.love/datas/gamedata/skills/spinjump.lua b/sonic-radiance.love/datas/gamedata/skills/spinjump.lua deleted file mode 100644 index e0518cd..0000000 --- a/sonic-radiance.love/datas/gamedata/skills/spinjump.lua +++ /dev/null @@ -1,33 +0,0 @@ --- 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 = "spinjump", -- unused for this attack, but still usefull sometimes - cost = 03, -- the pp cost of the attack. Will be ignored if it's set - -- as character default attack - - target = {2, -1, "square", 3, true}, -- which area can be selected as a target with the cursor. - -- if not nil : {ox, oy, shape, size, affectedByDirection} - - targetNumber = 1, -- how many ennemy you can target with the attack. - - effectArea = {1, 0, "point", 1, true}, -- which area is affected by the attack - -- if not nil : {ox, oy, shape, size, affectedByDirection} - - choregraphy = { -- the main attack choregraphy - {"setAnimation", "none", "spinjump", false}, - {'playSFX', "none", 'jump'}, - {'jumpToCursor', 'none', true}, - {"sendDamageFromCursor", "none", 0, 0, 110, 100, false, true, true}, - {'addGFX', "sentDamage", 'hitGFX', 0, 0, true, false}, - {'playSFX', "sentDamage", 'hitconnect'}, - {'jumpBack', "none", true}, - {'setAnimation', "none", 'idle', false}, - }, - - 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/datas/languages/en/init.lua b/sonic-radiance.love/datas/languages/en/init.lua new file mode 100644 index 0000000..532eaa3 --- /dev/null +++ b/sonic-radiance.love/datas/languages/en/init.lua @@ -0,0 +1,5 @@ +return { + name = "English", + name_ascii = "English", + subfolder = "en" +} diff --git a/sonic-radiance.love/datas/languages/en/options.lua b/sonic-radiance.love/datas/languages/en/options.lua new file mode 100644 index 0000000..2e5406e --- /dev/null +++ b/sonic-radiance.love/datas/languages/en/options.lua @@ -0,0 +1,11 @@ +return { + ["inputs"] = "Inputs", + ["video"] = "Video", + ["audio"] = "Audio", + ["langs"] = "Languages", + ["resolution"] = "Resolution", + ["fullscreen"] = "Fullscreen", + ["borders"] = "Borders", + ["vsync"] = "V-Sync", + ["back"] = "Back", +} diff --git a/sonic-radiance.love/datas/languages/fr/init.lua b/sonic-radiance.love/datas/languages/fr/init.lua new file mode 100644 index 0000000..0c9be78 --- /dev/null +++ b/sonic-radiance.love/datas/languages/fr/init.lua @@ -0,0 +1,5 @@ +return { + name = "Français", + name_ascii = "Francais", + subfolder = "fr" +} diff --git a/sonic-radiance.love/datas/languages/fr/options.lua b/sonic-radiance.love/datas/languages/fr/options.lua new file mode 100644 index 0000000..d0b2d8f --- /dev/null +++ b/sonic-radiance.love/datas/languages/fr/options.lua @@ -0,0 +1,11 @@ +return { + ["inputs"] = "Controles", + ["video"] = "Affichage", + ["audio"] = "Sons", + ["langs"] = "Langues", + ["resolution"] = "Resolution", + ["fullscreen"] = "Plein Ecran", + ["borders"] = "Bordures", + ["vsync"] = "Sync Vert.", + ["back"] = "Retour", +} diff --git a/sonic-radiance.love/game/abstractmobs/character.lua b/sonic-radiance.love/game/abstractmobs/character.lua new file mode 100644 index 0000000..535072a --- /dev/null +++ b/sonic-radiance.love/game/abstractmobs/character.lua @@ -0,0 +1,92 @@ +AbstractMobParent = require "game.abstractmobs.parent" + +AbstractCharacter = AbstractMobParent:extend() + +local charutils = require "game.abstractmobs.utils" + +function AbstractCharacter:new(name) + self.simplename = name + self.super.new(self) +end + +function AbstractCharacter:initBasicElements() + self.data = charutils.getCharacterData(self.simplename) + self.name = self.data.name + self.fullname = self.data.fullname + self.turns = self.data.turns + + self.level = self.data.startlevel + self.exp = charutils.getExpValue(self.level) + self.exp_next = charutils.getExpValue(self.level + 1) +end + +function AbstractCharacter:createStats() + local stats = {} + local base_stats = self.data.stats + + stats.hpmax = charutils.getHPValue(self.level, base_stats.hpmax) + stats.ppmax = charutils.getPPValue(self.level, base_stats.ppmax) + stats.attack = charutils.getStatValue(self.level, base_stats.attack) + stats.power = charutils.getStatValue(self.level, base_stats.power) + stats.defense = charutils.getStatValue(self.level, base_stats.defense) + stats.mind = charutils.getStatValue(self.level, base_stats.mind) + stats.technic = charutils.getStatValue(self.level, base_stats.technic) + stats.speed = charutils.getStatValue(self.level, base_stats.speed) + + return stats +end + +function AbstractCharacter:createSkills() + local learnedlist = {} + + for i, v in ipairs(self.data.skills) do + local tech_name, tech_level, isLearned = v[1], v[2], false + if tech_level <= self.level then + local canLearn = true + for i, learnedSkill in ipairs(learnedlist) do + + -- We check if the skill have already been learned, to level-up it + if learnedSkill.name == tech_name then + canLearn = false + learnedSkill.level = learnedSkill.level + 1 + end + end + + if (canLearn) then + local skilldata = {} + skilldata.name = tech_name + skilldata.level = 1 + skilldata.learnedAt = tech_level + + table.insert(learnedlist, skilldata) + end + + end + -- On continue ensuite d'itérer dans la liste + end + + return learnedlist +end + +function AbstractCharacter:setLevel(newlevel) + self.level = newlevel + local exp, exp_next, exp_current + exp_min = charutils.getExpValue(self.level) + exp_max = charutils.getExpValue(self.level + 1) + exp = self.exp + + self.exp = math.max(math.min(exp, exp_max - 1), exp_min) + self.exp_next = exp_max + + self.stats = self:createStats() +end + +function AbstractCharacter:levelUp() + self:setLevel(self.level + 1) +end + +function AbstractCharacter:heal() + self:initLife() +end + +return AbstractCharacter diff --git a/sonic-radiance.love/game/abstractmobs/ennemy.lua b/sonic-radiance.love/game/abstractmobs/ennemy.lua new file mode 100644 index 0000000..65df743 --- /dev/null +++ b/sonic-radiance.love/game/abstractmobs/ennemy.lua @@ -0,0 +1,26 @@ +AbstractMobParent = require "game.abstractmobs.parent" + +AbstractEnnemy = AbstractMobParent:extend() + +function AbstractEnnemy:new(name) + self.simplename = name + self.super.new(self) +end + +function AbstractEnnemy:initBasicElements() + self.data = require("datas.gamedata.ennemies." .. self.simplename) + self.name = self.data.name + self.fullname = self.data.fullname + self.turns = self.data.turns + +end + +function AbstractEnnemy:createStats() + return require("datas.gamedata.ennemies." .. self.simplename .. ".stats") +end + +function AbstractEnnemy:createSkills() + return require("datas.gamedata.ennemies." .. self.simplename .. ".skills") +end + +return AbstractEnnemy diff --git a/sonic-radiance.love/game/abstractmobs/parent.lua b/sonic-radiance.love/game/abstractmobs/parent.lua new file mode 100644 index 0000000..61c2e0a --- /dev/null +++ b/sonic-radiance.love/game/abstractmobs/parent.lua @@ -0,0 +1,68 @@ +local AbstractMobParent = Object:extend() + +function AbstractMobParent:new() + self:initBasicElements() + self.stats = self:createStats() + self.skills = self:createSkills() + self:initLife() +end + +function AbstractMobParent:initBasicElements() + self.name = "PlaceHolder" + self.fullname = "PlaceHolder" + self.turns = 2 +end + +function AbstractMobParent:createStats() + local stats = {} + + stats.hpmax = 0 + stats.ppmax = 0 + stats.attack = 0 + stats.power = 0 + stats.defense = 0 + stats.technic = 0 + stats.mind = 0 + stats.speed = 0 + + return stats +end + +function AbstractMobParent:createSkills() + return {} +end + +-- LIFE FUNCTIONS +-- Handle HP and stuff like that + +function AbstractMobParent:initLife() + self.hp = self.stats.hpmax + self.pp = self.stats.ppmax + self.status = 0 +end + +function AbstractMobParent:setHP(newHP, relative) + if (relative) then + self.hp = self.hp + newHP + else + self.hp = newHP + end +end + +function AbstractMobParent:setPP(newPP, relative) + if (relative) then + self.pp = self.pp + newPP + else + self.pp = newPP + end +end + +function AbstractMobParent:isAlive() + return (self.hp > 0) +end + +function AbstractMobParent:getStats() + return self.stats +end + +return AbstractMobParent diff --git a/sonic-radiance.love/game/abstractmobs/utils.lua b/sonic-radiance.love/game/abstractmobs/utils.lua new file mode 100644 index 0000000..bc56593 --- /dev/null +++ b/sonic-radiance.love/game/abstractmobs/utils.lua @@ -0,0 +1,49 @@ +local CharUtils = {} + +local CONST = {} + +CONST.EXP_MULTIPLICATOR = 4 +CONST.EXP_RATIO = 5 + +CONST.BASE_STAT = 5 +CONST.BASE_HP = 15 +CONST.BASE_MP = 8 + +CONST.MULT_STAT = 2 +CONST.MULT_HP = 2.7 +CONST.MULT_MP = 1.5 + +function CharUtils.getExpValue(level) + return math.floor( ( CONST.EXP_MULTIPLICATOR * ( level ^ 3 ) ) / CONST.EXP_RATIO ) +end + +function CharUtils.getStatValue(level, base) + return math.floor( (((base * CONST.MULT_STAT) * level)/100) ) + CONST.BASE_STAT +end + +function CharUtils.getHPValue(level, base) + return math.floor( (((base * CONST.MULT_HP) * level)/100) ) + CONST.BASE_HP + level +end + +function CharUtils.getPPValue(level, base) + return math.floor( (((base * CONST.MULT_MP) * level)/100) ) + CONST.BASE_MP +end + +function CharUtils.charDataExists(name) + local dir = "datas/gamedata/characters/" .. name .. "/init.lua" + local fileinfo = love.filesystem.getInfo(dir) + return (fileinfo ~= nil) +end + +function CharUtils.getCharacterData(charname) + -- va eprmettre de récupérer les données d'un personnage + local charfolder = "datas.gamedata.characters." .. charname + local character = require(charfolder) + character.stats = require(charfolder .. ".stats") + character.inventory = require(charfolder .. ".inventory") + character.skills = require(charfolder .. ".skills") + + return character +end + +return CharUtils diff --git a/sonic-radiance.love/game/characters.lua b/sonic-radiance.love/game/characters.lua index 1d45d8c..6b1dac7 100644 --- a/sonic-radiance.love/game/characters.lua +++ b/sonic-radiance.love/game/characters.lua @@ -24,6 +24,9 @@ local CharacterManager = Object:extend() +local charutils = require "game.abstractmobs.utils" +local AbstractCharacter = require "game.abstractmobs.character" + function CharacterManager:new(controller) self.controller = controller self.namelist = require "datas.gamedata.characters" @@ -34,87 +37,19 @@ function CharacterManager:new(controller) end function CharacterManager:init() - for k, v in pairs(self.namelist) do - local dir = "datas/gamedata/characters/" .. v .. "/init.lua" - local fileinfo = love.filesystem.getInfo(dir) - if fileinfo ~= nil then - self:initCharacter(v) + for k, name in pairs(self.namelist) do + if (charutils.charDataExists(name)) then + self.list[name] = AbstractCharacter(name) end end end -function CharacterManager:getCharacterData(charname) - -- va eprmettre de récupérer les données d'un personnage - local charfolder = "datas.gamedata.characters." .. charname - local character = require(charfolder) - character.base_stats = require(charfolder .. ".stats") - character.inventory = require(charfolder .. ".inventory") - character.skills = require(charfolder .. ".skills") - - return character +function CharacterManager:setLevel(name, newlevel) + self.list[name]:setLevel(newlevel) end -function CharacterManager:initCharacter(id) - local stats = {} - local character = self:getCharacterData(id) - - stats.level = character.startlevel - stats.exp = self:getExpValue(stats.level) - stats.exp_next = self:getExpValue(stats.level + 1) - stats.hpmax = character.base_stats.hpmax - stats.ppmax = character.base_stats.ppmax - stats.attack = character.base_stats.attack - stats.power = character.base_stats.power - stats.defense = character.base_stats.defense - stats.technic = character.base_stats.technic - stats.mind = character.base_stats.mind - stats.speed = character.base_stats.speed - - character.stats = stats - self.list[id] = character - - self:recalculateStats(id) - - stats.hp = stats.hpmax - stats.pp = stats.ppmax - stats.status = 0 - - character.stats = stats - self.list[id] = character -end - -function CharacterManager:getExpValue(level) - return math.floor( ( 4 * ( level ^ 3 ) ) / 5 ) -end - -function CharacterManager:setLevel(id, newlevel) - self.list[id].stats.level = newlevel - local stats = self.list[id].stats - local exp, exp_next, exp_current - exp = self:getExpValue(stats.level) - exp_next = self:getExpValue(stats.level + 1) - exp_current = self.list[id].stats.exp - - self.list[id].stats.exp = math.max(math.min(exp_current, exp_next - 1), exp) - self.list[id].stats.exp_next = exp_next - - self:recalculateStats(id) -end - -function CharacterManager:levelUp(id) - self:setLevel(id, self.list[id].stats.level + 1) -end - -function CharacterManager:getStatValue(level, base) - return math.floor( (((base * 2) * level)/100) ) + 5 -end - -function CharacterManager:getHPValue(level, base) - return math.floor( (((base * 2.7) * level)/100) ) + 15 + level -end - -function CharacterManager:getPPValue(level, base) - return math.floor( (((base * 1.5) * level)/100) ) + 8 +function CharacterManager:levelUp(name) + self.list[name]:levelUp() end function CharacterManager:recalculateStats(id) @@ -122,47 +57,14 @@ function CharacterManager:recalculateStats(id) local stats = character.stats local base_stats = character.base_stats - stats.hpmax = self:getHPValue(stats.level, base_stats.hpmax) - stats.ppmax = self:getPPValue(stats.level, base_stats.ppmax) - stats.attack = self:getStatValue(stats.level, base_stats.attack) - stats.power = self:getStatValue(stats.level, base_stats.power) - stats.defense = self:getStatValue(stats.level, base_stats.defense) - stats.mind = self:getStatValue(stats.level, base_stats.mind) - stats.technic = self:getStatValue(stats.level, base_stats.technic) - stats.speed = self:getStatValue(stats.level, base_stats.speed) -end - -function CharacterManager:getSkillList(id) - local character = self.list[id] - local learnedlist = {} - - for i, v in ipairs(character.skills) do - local tech_name, tech_level, isLearned = v[1], v[2], false - if tech_level <= character.stats.level then - local canLearn = true - for i, learnedSkill in ipairs(learnedlist) do - - -- We check if the skill have already been learned, to level-up it - if learnedSkill.name == tech_name then - canLearn = false - learnedSkill.level = learnedSkill.level + 1 - end - end - - if (canLearn) then - local skilldata = {} - skilldata.name = tech_name - skilldata.level = 1 - skilldata.learnedAt = tech_level - - table.insert(learnedlist, skilldata) - end - - end - -- On continue ensuite d'itérer dans la liste - end - - return learnedlist + stats.hpmax = charutils.getHPValue(stats.level, base_stats.hpmax) + stats.ppmax = charutils.getPPValue(stats.level, base_stats.ppmax) + stats.attack = charutils.getStatValue(stats.level, base_stats.attack) + stats.power = charutils.getStatValue(stats.level, base_stats.power) + stats.defense = charutils.getStatValue(stats.level, base_stats.defense) + stats.mind = charutils.getStatValue(stats.level, base_stats.mind) + stats.technic = charutils.getStatValue(stats.level, base_stats.technic) + stats.speed = charutils.getStatValue(stats.level, base_stats.speed) end function CharacterManager:getData() @@ -178,15 +80,13 @@ function CharacterManager:setData(data) self.team = data.team end -function CharacterManager:heal(id) - self.list[id].stats.hp = self.list[id].stats.hpmax - self.list[id].stats.hp = self.list[id].stats.ppmax - self.list[id].stats.status = 0 +function CharacterManager:heal(name) + self.list[name]:heal() end -function CharacterManager:addToTeam(id) - self:heal(id) - table.insert(self.team, id) +function CharacterManager:addToTeam(name) + self:heal(name) + table.insert(self.team, name) end function CharacterManager:removeToTeam(teamid) @@ -201,9 +101,8 @@ end function CharacterManager:printCharacter(id) local character = self.list[id] - local stats = character.stats print(id .. ". " .. character.fullname) - print("Lvl " .. character.stats.level .. " (" .. stats.exp .. "/" .. stats.exp_next .. " exp)") + print("Lvl " .. character.level .. " (" .. character.exp .. "/" .. character.exp_next .. " exp)") end function CharacterManager:printTeam() diff --git a/sonic-radiance.love/game/ennemies.lua b/sonic-radiance.love/game/ennemies.lua index 60336f1..4a656eb 100644 --- a/sonic-radiance.love/game/ennemies.lua +++ b/sonic-radiance.love/game/ennemies.lua @@ -1,15 +1,13 @@ local EnnemyManager = Object:extend() +local AbstractEnnemy = require "game.abstractmobs.ennemy" + function EnnemyManager:new(controller) self.controller = controller end function EnnemyManager:getEnnemyData(ennemy) - local data = require("datas.gamedata.ennemies." .. ennemy) - data.skills = require("datas.gamedata.ennemies." .. ennemy .. ".skills") - data.stats = require("datas.gamedata.ennemies." .. ennemy .. ".stats") - - return data + return AbstractEnnemy(ennemy) end return EnnemyManager diff --git a/sonic-radiance.love/game/init.lua b/sonic-radiance.love/game/init.lua index c95d3f1..5e7d67b 100644 --- a/sonic-radiance.love/game/init.lua +++ b/sonic-radiance.love/game/init.lua @@ -35,11 +35,14 @@ Game.gui = require "game.modules.gui" function Game:new() self.slot = -1 + self.slotNumber = 3 self.gametime = 0 self.characters = Characters(self) self.ennemies = Ennemies(self) self.skills = Skills(self) + + self.version = "0.0.0" end function Game:setData(data) @@ -93,7 +96,7 @@ function Game:getSaveFile(saveslot, absolute) end function Game:resetSaves() - for i=1, 3 do + for i=1, self.slotNumber do filepath = self:getSaveFile(i, true) if love.filesystem.exists("save" .. i .. ".save") then love.filesystem.remove( "save" .. i .. ".save" ) diff --git a/sonic-radiance.love/game/modules/drawing/parallaxBackground.lua b/sonic-radiance.love/game/modules/drawing/parallaxBackground.lua new file mode 100644 index 0000000..9eb2e8a --- /dev/null +++ b/sonic-radiance.love/game/modules/drawing/parallaxBackground.lua @@ -0,0 +1,165 @@ +local ParallaxBackground = Object:extend() + +local maputils = require "scenes.battlesystem.utils" + +function ParallaxBackground:new(scene, height, bottomBorder, type) + self.scene = scene + self.assets = self.scene.assets + + self.datas = {} + self.datas.type = type or "forest" + + self.height = height + self.bottomBorder = bottomBorder + + local zones = require "datas.gamedata.maps.shoot.zones" + local datas = zones[self.datas.type] + self.datas.background = datas.background + self.datas.tiles = datas.tiles + self.datas.borders = datas.borders + + self.assets:addTileset("normaltiles", "assets/backgrounds/normaltile") + self.assets:addTileset("borders", "assets/backgrounds/borders") + + local backpath = "assets/backgrounds/parallax/" .. self.datas.background + self.assets:addImage("back1", backpath .. "-back.png") + self.assets:addImage("back2", backpath .. "-fore.png") + self.assets:addImage("cliff", backpath .. "-cliff.png") + + self.texture = {} + self.texture.floor = self:generateFloor(tile) +end + +-- GET FUNCTIONS +-- Get information from the map + +function ParallaxBackground:getTotalHeight() + return self.height + self.bottomBorder; +end + +function ParallaxBackground:getTerrain(x, y) + if (y <= self.height) then + return 0 + else + return nil + end +end + +function ParallaxBackground:isInGrid(x, y) + return ( self:getTerrain(x, y) ~= nil ) +end + +function ParallaxBackground:getStartY() + return 240 - (self:getTotalHeight() * 20) - 10 +end + +function ParallaxBackground:gridToPixel(x, y, center) + local pixelx, pixely + local center = center or false + local x, y = x, y + + if (center) then + x = x + .5 + y = y + .5 + end + + pixelx = maputils.CONST.STARTX + ((x-1) * 31) + ((y-1) * 10) + pixely = self:getStartY() + ((y-1) * 20) + + return math.floor(pixelx), math.floor(pixely) +end + +-- DRAW FUNCTIONS +-- Draw the battle map + +function ParallaxBackground:generateFloor(tile) + local canvas = love.graphics.newCanvas(31*16, self:getTotalHeight() * 20) + local tile = tile or 1 + + love.graphics.setCanvas( canvas ) + + for i=1, self:getTotalHeight() do + for j=0, 18 do + local tiley = (i-1)*20 + local tilex = (j-2)*31 + (i-1)*10 + local variant = 1 + ((i + j) % 2) + local tiles = self.datas.tiles*2 + variant + if (not self:isInGrid(j, i)) then + love.graphics.setColor(.66, .66, .66, 1) + end + self.assets.tileset["normaltiles"]:drawTile(tiles, tilex, tiley) + utils.graphics.resetColor() + end + end + + love.graphics.setCanvas( ) + + local imagedata = canvas:newImageData() + local texture = love.graphics.newImage( imagedata ) + imagedata:release() + canvas:release() + return texture +end + +function ParallaxBackground:draw() + self:drawParallax(0, -self:getStartY(), 424, 240) +end + +function ParallaxBackground:drawParallax(x, y, w, h) + self:drawBackground(x, y, w, h) + self:drawForeground(x, y, w, h) + --love.graphics.draw(self.texture.floor, maputils.CONST.STARTX, self:getStartY()) + local w2, _ = self.texture.floor:getDimensions() + for i=1, 2 do + local x2 = x % w2 + love.graphics.draw(self.texture.floor, ((i-1)*31*16)-x2, -y) + end + self:drawBorders(x, y, w, h) +end + + +function ParallaxBackground:drawBackgrounds() + local w, _ = core.screen:getDimensions() + + local w2, h2 = self.assets.images["back1"]:getDimensions() + local imax = math.ceil(w / w2) + 1 + for i=1, imax do + self.assets.images["back1"]:draw((i-1)*w2, 0, 0, 1, 1) + end + + local w2, h2 = self.assets.images["back2"]:getDimensions() + local imax = math.ceil(w / w2) + 1 + for i=1, imax do + self.assets.images["back2"]:draw((i-1)*w2, self:getStartY()-h2, 0, 1, 1) + end + +end + +function ParallaxBackground:drawBackground(x, y, w, h) + local w2, h2 = self.assets.images["back1"]:getDimensions() + local imax = math.ceil(w / w2) + 1 + for i=1, imax do + local x1 = (x / 5) % w2 + self.assets.images["back1"]:draw((i-1)*w2 - x1, 0, 0, 1, 1, 0, 0) + end +end + +function ParallaxBackground:drawForeground(x, y, w, h) + local w2, h2 = self.assets.images["back2"]:getDimensions() + local imax = math.ceil(w / w2) + 1 + for i=1, imax do + local x1 = (x / 2) % w2 + self.assets.images["back2"]:draw((i-1)*w2 - x1, -y-10, 0, 1, 1, 0, h2) + end +end + +function ParallaxBackground:drawBorders(x, y) + local border = self.datas.borders + 1 + for i=1, 7 do + local x2 = x % 80 + self.assets.tileset["borders"]:drawTile(border, (i-1)*80 - x2, -y, 0, 1, 1, 0, 10) + self.assets.tileset["borders"]:drawTile(border, (i-1)*80 - x2, -(y-self:getTotalHeight()*20), 0, 1, 1) + end +end + +return ParallaxBackground diff --git a/sonic-radiance.love/game/modules/world/maps/shoot.lua b/sonic-radiance.love/game/modules/world/maps/shoot.lua index 9d31340..cf3c1e9 100644 --- a/sonic-radiance.love/game/modules/world/maps/shoot.lua +++ b/sonic-radiance.love/game/modules/world/maps/shoot.lua @@ -4,13 +4,15 @@ local ShootMap = BaseMap:extend() local TILESIZE = 31 local TESTZONE = "forest" -local zoneDatas = require "datas.gamedata.maps.shoot.zones" +local zoneDatas = require "datas.gamedata.maps.shoot.zones" +local Background = require "game.modules.drawing.parallaxBackground" + function ShootMap:new(world, maptype, mapname) ShootMap.super.new(self, world) self:setPadding(0, 0, 0, 0) - self:generateTextures(2, "tunnel") + self.parallaxBackground = Background(world.scene, 5, 1, "tunnel") end function ShootMap:loadCollisions() @@ -34,112 +36,14 @@ function ShootMap:loadActors() -- Empty Placeholder function end -function ShootMap:generateTextures(tile, background) - - self.texture = {} - self.texture.floor = self:generateFloor(tile) - self.texture.border = love.graphics.newImage("assets/backgrounds/borders.png") - self.quads = {} - local w, h = self.texture.border:getDimensions() - self.quads.borders = love.graphics.newQuad(0, tile*10, 80, 10, w, h) - - self:addParallax(background) -end - -function ShootMap:generateFloor(tile) - local canvas = love.graphics.newCanvas(31*16, 100) - local tile = tile or 1 - - local tileTexture = love.graphics.newImage("assets/backgrounds/normaltile.png") - local tileQuad = {} - local w, h = tileTexture:getDimensions() - tileQuad[1] = love.graphics.newQuad( 0, tile*24, 40, 24, w, h) - tileQuad[2] = love.graphics.newQuad(40, tile*24, 40, 24, w, h) - - love.graphics.setCanvas( canvas ) - - for i=1, 5 do - for j=0, 18 do - local tiley = (i-1)*20 - 4 - local tilex = (j-2)*31 + (i-1)*10 - local variant = 1 + ((i + j) % 2) - love.graphics.draw(tileTexture, tileQuad[variant], tilex, tiley) - end - end - - love.graphics.setCanvas( ) - - local imagedata = canvas:newImageData() - local texture = love.graphics.newImage( imagedata ) - imagedata:release() - canvas:release() - return texture -end - function ShootMap:draw() for i=1, 10 do --love.graphics.draw(self.texture.floor, ((i-1)*31*16), 0) end end -function ShootMap:addParallax(filename) - -- Empty Placeholder function - local filename = filename or "forest" - local backfolder = "assets/backgrounds/parallax/" - filename = backfolder .. filename - self.texture.back1 = love.graphics.newImage(filename .. "-back.png") - self.texture.back2 = love.graphics.newImage(filename .. "-fore.png") - self.texture.cliff = love.graphics.newImage(filename .. "-cliff.png") -end - function ShootMap:drawParallax(x, y, w, h) - - self:drawBackground(x, y, w, h) - self:drawForeground(x, y + 10, w, h) - local w2, _ = self.texture.floor:getDimensions() - for i=1, 2 do - local x2 = x % w2 - love.graphics.draw(self.texture.floor, ((i-1)*31*16)-x2, -y) - end - - self:drawBorder(x, y + 10) - self:drawBorder(x, y - 100) - self:drawCliff(x, y - 110, w, h) + self.parallaxBackground:drawParallax(x, y, w, h) end -function ShootMap:drawBackground(x, y, w, h) - local w2, h2 = self.texture.back1:getDimensions() - local imax = math.ceil(w / w2) + 1 - for i=1, imax do - local x1 = (x / 5) % w2 - love.graphics.draw(self.texture.back1, (i-1)*w2 - x1, 0, 0, 1, 1, 0, 0) - end -end - -function ShootMap:drawForeground(x, y, w, h) - local w2, h2 = self.texture.back2:getDimensions() - local imax = math.ceil(w / w2) + 1 - for i=1, imax do - local x1 = (x / 2) % w2 - love.graphics.draw(self.texture.back2, (i-1)*w2 - x1, -y, 0, 1, 1, 0, h2) - end -end - -function ShootMap:drawBorder(x, y) - for i=1, 7 do - local x2 = x % 80 - love.graphics.draw(self.texture.border, self.quads.borders, (i-1)*80 - x2, -y, 0, 1, 1) - end -end - -function ShootMap:drawCliff(x, y, w, h) - local w2, h2 = self.texture.cliff:getDimensions() - local imax = math.ceil(w / w2) + 1 - for i=1, imax do - local x1 = (x) % w2 - love.graphics.draw(self.texture.cliff, (i-1)*w2 - x1, -y, 0, 1, 1, 0, 0) - end -end - - return ShootMap diff --git a/sonic-radiance.love/game/utils/choregraphy/arguments.lua b/sonic-radiance.love/game/utils/choregraphy/arguments.lua new file mode 100644 index 0000000..a400c51 --- /dev/null +++ b/sonic-radiance.love/game/utils/choregraphy/arguments.lua @@ -0,0 +1,24 @@ +return { + ["wait"] = {"duration"}, + ["addGFX"] = {'sprite', "origin", "x", "y", "affectedByDirection", 'blockProcess'}, + ["playSFX"] = {"sfx"}, + ["sendDamage"] = {"power", "accuracy", "isSpecial", "isAerial"}, + ["goTo"] = {"origin", "x", "y", "duration", "blockProcess"}, + ["setAnimation"] = {"animation", "blockProcess"}, + ["jump"] = {"power", "bounceNumber", "blockProcess"}, + ["jumpTo"] = {"origin", "x", "y", "duration", "blockProcess"}, + ["jumpBack"] = {"duration", "blockProcess"}, + ["waitActorFinished"] = {"waitFor"}, + ["addQTE"] = {"qteData", "origin", "blockProcess"} + --[name] = {args}, +} + +-- The "origin" argument can have the different values +-- - "target" : the action target. if there is multiple target, it'll +-- be equal to the middle of the ennemy line +-- +-- - "self" : the fighter's actor position +-- +-- - "start" : the fighter's starting position +-- +-- - "absolute" : the 0,0 coordinates diff --git a/sonic-radiance.love/game/utils/choregraphy/init.lua b/sonic-radiance.love/game/utils/choregraphy/init.lua new file mode 100644 index 0000000..5f8f831 --- /dev/null +++ b/sonic-radiance.love/game/utils/choregraphy/init.lua @@ -0,0 +1,89 @@ +ChoregraphyUtils = {} + +-- steps utils + +function ChoregraphyUtils.getStepStructure(stepName) + local stepTypeList = require "game.utils.choregraphy.arguments" + return stepTypeList[stepName] +end + +function ChoregraphyUtils.stepExists(stepName) + return (ChoregraphyUtils.getStepStructure(stepName) ~= nil) +end + +function ChoregraphyUtils.validateStep(stepBaseDatas) + local structure = ChoregraphyUtils.getStepStructure(stepBaseDatas[1]) + if (structure == nil) then + return false + else + return ((#structure + 2) == #stepBaseDatas) + end +end + +function ChoregraphyUtils.getStepDatas(stepBaseDatas) + + local stepData = {} + stepData.name = stepBaseDatas[1] + + if (ChoregraphyUtils.validateStep(stepBaseDatas)) then + stepData.condition = stepBaseDatas[2] + + local structure = ChoregraphyUtils.getStepStructure(stepData.name) + + stepData.arguments = {} + + for i, argumentName in ipairs(structure) do + local argumentContent = stepBaseDatas[i + 2] + stepData.arguments[argumentName] = argumentContent + end + + return stepData + else + error("L'étape " .. stepData.name .. " à un nbr d'argument incorrect") + end + +end + +-- QTE utils + +function ChoregraphyUtils.getQteStructure(qteName) + local stepTypeList = require "game.utils.choregraphy.qte" + return stepTypeList[qteName] +end + +function ChoregraphyUtils.qteExists(qteName) + return (ChoregraphyUtils.getQteStructure(qteName) ~= nil) +end + +function ChoregraphyUtils.validateQte(qteBaseDatas) + local structure = ChoregraphyUtils.getQteStructure(qteBaseDatas[1]) + if (structure == nil) then + return false + else + return ((#structure + 1) == #qteBaseDatas) + end +end + +function ChoregraphyUtils.getQteDatas(qteBaseDatas) + + local qteData = {} + qteData.name = qteBaseDatas[1] + + if (ChoregraphyUtils.validateQte(qteBaseDatas)) then + local structure = ChoregraphyUtils.getQteStructure(qteData.name) + + qteData.arguments = {} + + for i, argumentName in ipairs(structure) do + local argumentContent = qteBaseDatas[i + 1] + qteData.arguments[argumentName] = argumentContent + end + + return qteData + else + error("Le QTE " .. qteData.name .. " à un nbr d'argument incorrect") + end + +end + +return ChoregraphyUtils diff --git a/sonic-radiance.love/game/utils/choregraphy/qte.lua b/sonic-radiance.love/game/utils/choregraphy/qte.lua new file mode 100644 index 0000000..4414f08 --- /dev/null +++ b/sonic-radiance.love/game/utils/choregraphy/qte.lua @@ -0,0 +1,3 @@ +return { + ["simplePrompt"] = {"key", "duration"} +} diff --git a/sonic-radiance.love/main.lua b/sonic-radiance.love/main.lua index f3e47c7..32ffdc6 100644 --- a/sonic-radiance.love/main.lua +++ b/sonic-radiance.love/main.lua @@ -30,7 +30,7 @@ function love.load() core = Core(true) game = Game() - scenes.cbs() + scenes.debug.menu() end function love.update(dt) diff --git a/sonic-radiance.love/scenes/battlesystem/actors/battler.lua b/sonic-radiance.love/scenes/battlesystem/actors/battler.lua index c531968..c7a3f5e 100644 --- a/sonic-radiance.love/scenes/battlesystem/actors/battler.lua +++ b/sonic-radiance.love/scenes/battlesystem/actors/battler.lua @@ -4,15 +4,20 @@ local Battler = Parent:extend() function Battler:new(world, x, y, z) Battler.super.new(self, world, x, y, z) + self.start = {} + self.start.x = x + self.start.y = y + self.isBattler = true self.speed = 3 self.isActive = false self.debugActiveTimer = 0 + + self.isSelected = false end function Battler:destroy() Battler.super.destroy(self) - self.world:destroyBattler(self) end function Battler:setActive() @@ -37,40 +42,4 @@ function Battler:validateAction() end -function Battler:sendDamage(x, y, value, accuracy, isSpecial, isAerial) - local stats = self:getStats() - local value = value / 10 - - if (isSpecial) then - value = value * stats.power - else - value = value * stats.attack - end - core.debug:print("battler", "sending " .. value .." damage at position <" .. x .. ";" .. y .. ">") - - local fromEnnemy = self.isEnnemy - - local other = self.world:getActorInCase(x, y, self) - if (other ~= nil) then - core.debug:print("battler", "sending damage to actor at position <" .. x .. ";" .. y .. ">") - other:receiveDamage(value, accuracy, isSpecial, isAerial, fromWho) - return true - else - return false - end -end - -function Battler:receiveDamage(value, accuracy, isSpecial, isAerial) - local stats = self:getStats() - if (fromEnnemy ~= self.isEnnemy) then - if (isSpecial) then - value = value / stats.mind - else - value = value / stats.defense - end - core.debug:print("battler", "taken " .. value .. " damage" ) - self:setHP(value * -1, true) - end -end - return Battler diff --git a/sonic-radiance.love/scenes/battlesystem/actors/ennemy.lua b/sonic-radiance.love/scenes/battlesystem/actors/ennemy.lua index 58aeadc..cd30f60 100644 --- a/sonic-radiance.love/scenes/battlesystem/actors/ennemy.lua +++ b/sonic-radiance.love/scenes/battlesystem/actors/ennemy.lua @@ -3,57 +3,25 @@ local Ennemy = Battler:extend() local gui = require "game.modules.gui" -function Ennemy:new(world, x, y, id, number) +function Ennemy:new(world, x, y, owner) Ennemy.super.new(self, world, x, y, 0) self.isEnnemy = true - self.ennid = id or "motobug" + self.owner = owner self.actionPerTurn = 2 - - self:receiveDatas() - self.hp = self.data.stats.hpmax - self.pp = self.data.stats.ppmax - - self.shownHP = self.hp end function Ennemy:draw() - local x, y = self.maputils.gridToPixel(self.x, self.y, true) + 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 Ennemy:drawHUD() - local x, y = self.maputils.gridToPixel(self.x, self.y, true) - love.graphics.setColor(0, 0, 0, 1) - gui.drawBar(x - 14, y - 38, 26, 4) - love.graphics.setColor(248/255, 160/255, 0, 1) - local bar = math.floor(24 * (self.shownHP / self.data.stats.hpmax)) - gui.drawBar(x - 14, y - 37, bar, 2) - love.graphics.setColor(1, 1, 1, 1) + self.owner:drawHUD(x - 14, y - 38) -end - -function Ennemy:drawIcon(x, y) - love.graphics.setColor(1, 0, 0, 1) - love.graphics.rectangle("fill", x, y, 16, 16) - love.graphics.setColor(1, 1, 1, 1) -end - -function Ennemy:receiveDatas() - self.data = game.ennemies:getEnnemyData(self.ennid) -end - -function Ennemy:setHP(value, relative) - if (relative) then - value = self.hp + value - end - - self.hp = value - self.tweens:newTween(0, 0.1, {shownHP = self.hp}, 'inCubic') - if (self.hp <= 0) then - self:destroy() + if (self.isSelected) then + local height = 32 + self.assets.images["cursorpeak"]:draw(x - 7, y - 24 - 32) end end diff --git a/sonic-radiance.love/scenes/battlesystem/actors/hero.lua b/sonic-radiance.love/scenes/battlesystem/actors/hero.lua index db3d113..00ecd7c 100644 --- a/sonic-radiance.love/scenes/battlesystem/actors/hero.lua +++ b/sonic-radiance.love/scenes/battlesystem/actors/hero.lua @@ -1,116 +1,35 @@ local Battler = require("scenes.battlesystem.actors.battler") local Hero = Battler:extend() -local gui = require "game.modules.gui" -local StatusBar = require "scenes.battlesystem.gui.statusbar" +local MOVEMENT_NONE = "none" +local MOVEMENT_TWEENER = "tweener" +local MOVEMENT_MOTION = "motion" -local ChoregraphySystem = require "scenes.battlesystem.actors.systems.choregraphy" +local ZGRAVITY = 0.2 -- INIT FUNCTIONS -- Initialize the hero -function Hero:new(world, x, y, charid, charnumber) +function Hero:new(world, x, y, owner, charnumber) Hero.super.new(self, world, x, y, 0) self.isHero = true + self.owner = owner self:initMovementSystem() - self:initCharacter(charid) - self:initSprite() - self:initChoregraphySystem() - - self:initVoices() - - self.statusbar = StatusBar(self) self.side = "heroes" end --- CHARACTER FUNCTIONS --- All functions related to character handling - -function Hero:initCharacter(charid) - if charid == nil then - core.debug:error("FATAL ERROR: charid not set") - end - self.charid = charid - self.charnumber = charnumber or 1 - - self.hp = game.characters.list[self.charid].stats.hp - self.pp = game.characters.list[self.charid].stats.pp - - self.actionPerTurn = game.characters.list[self.charid].turns - - self.turnAction = nil -end - -function Hero:getStats() - return game.characters.list[self.charid].stats -end - -function Hero:setHP(value, relative) - if relative == true then - value = game.characters.list[self.charid].stats.hp + value - end - - game.characters.list[self.charid].stats.hp = value - self.statusbar:updateHP() -end - -function Hero:setPP(value, relative) - if relative == true then - value = game.characters.list[self.charid].stats.pp + value - end - - game.characters.list[self.charid].stats.pp = value - self.statusbar:updatePP() -end - - --- ACTIVITY FUNCTION --- Function to set or unset activity to the character - -function Hero:setActive() - core.debug:print("cbs/hero", "hero " .. self.charid .. " is now active") - local gridsize = game.characters.list[self.charid].move - if (gridsize == nil) then - gridsize = 3 - core.debug:warning("cbs/character", "move value is nil") - end - self.world.cursor:setGrid(self.x, self.y, "circle", gridsize, 1, self) - self.x, self.y = utils.math.round(self.x), utils.math.round(self.y) - self.startx, self.starty = self.x, self.y - - self.world.cursor:set(self.startx, self.starty, "cursorMove") - - --self:talk("turnstart") - - self.directionPrevious = self.direction -end - -- UPDATE FUNCTION -- Update the hero function Hero:update(dt) Hero.super.update(self, dt) - -- Get keys to have some keyboard functions - self.keys = self.scene:getKeys(1) + self:updateMovement(dt) - -- Calculate speed to calculate animation speed - self:updateSpeed(dt) - - self:updateChoregraphy(dt) - - if (self.scene:haveMenus()) then - self:changeDirection(dt) - end - - self.xprevious = self.x - self.yprevious = self.y - self.zprevious = self.z - - self.statusbar:update(dt) + self:updateAnimation(dt) end -- MOVE FUNCTIONS @@ -119,65 +38,191 @@ end local MOVEMENT_DURATION = 0.20 function Hero:initMovementSystem() - self.startx, self.starty = self.x, self.y self.xprevious, self.yprevious, self.zprevious = self.x, self.y, self.z + self.xspeed, self.yspeed, self.zspeed = 0,0,0 self.direction = 1 self.directionPrevious = 1 self.directionLocked = false - self.unlockDirection = true + + self.movementType = MOVEMENT_NONE self:initJump() end -function Hero:getMovementDuration(dx, dy, factor) - local factor = factor or 1 - local duration = MOVEMENT_DURATION / factor - local coef = 0.5 - local dx, dy = dx, dy - local distance = utils.math.pointDistance(self.x, self.y, dx, dy) * coef - return duration * distance +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:goTo(dx, dy, timerName, factor, easing) +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' - local factor = factor or 1 - local duration = math.max(self:getMovementDuration(dx, dy, factor), 0.30) if duration > 0 then self.tweens:newTween(0, duration, {x = dx, y = dy}, easing) end - self.tweens:newTimer(duration + 0.02, timerName) + self.tweens:newTimer(duration + 0.02, "goTo") + self.tweens:newTimer(duration + 0.02, "resetMovement") + + self.movementType = MOVEMENT_TWEENER end -function Hero:jumpTo(dx, dy, size, timerName, spinjump, factor, easing) +function Hero:jumpTo(dx, dy, sizeFactor, duration, spinjump, easing) local easing = easing or 'inOutQuad' - local factor = factor or 1 - local duration = math.max(self:getMovementDuration(dx, dy, factor), 0.30) + 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, timerName) - self:setJump(size, spinjump, duration) + self.tweens:newTimer(duration + 0.02, "jumpTo") + self:setJump(jumpHeight, spinjump, duration) end -function Hero:updateSpeed(dt) - self:applyMotion(dt) - self.xspeed = self.x - self.xprevious - self.yspeed = self.y - self.yprevious - self.zspeed = self.z - self.zprevious +function Hero:updateTweenerSpeed(dt) + self.xspeed = (self.x - self.xprevious) / dt + self.yspeed = (self.y - self.yprevious) / dt +end - self.gspeed = math.sqrt(self.xspeed^2 + self.yspeed^2) +-- 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 then + if math.abs(self.xspeed) >= 0.01 then if (self.directionLocked == false) then self.direction = utils.math.sign(self.xspeed) end - else - if self.unlockDirection then - self.unlockDirection = false - self.directionLocked = false + 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) + self:setMotion(-10, 0) + 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 - if self.z > 0 and self.jump.spin == false then +-- 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 = 1 + 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 + +function Hero:initSprite() + self.assets:addSprite(self.owner.name, "datas/gamedata/characters/" .. self.owner.name .. "/sprites") + self.assets.sprites[self.owner.name]:setCustomSpeed(16) + self:setSprite(self.owner.name, 32, 48, true) + self:cloneSprite() + self:changeAnimation("idle") +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 self:changeAnimation("jump") else @@ -185,209 +230,7 @@ function Hero:updateSpeed(dt) end end - self:setCustomSpeed(self.gspeed * 320) -end - -function Hero:changeDirection(dt) - -- Change direction by pressing left or right when selecting the next action - if (self.keys["left"].isPressed) then - self.direction = -1 - elseif (self.keys["right"].isPressed) then - self.direction = 1 - end -end - -function Hero:initJump() - self.jump = {} - self.jump.spin = false -end - -function Hero:setJump(size, spinjump, duration) - local tweenDuration = duration / 2 - self.tweens:newTween(0, tweenDuration, {z = size}, 'outQuad') - self.tweens:newTween(tweenDuration, tweenDuration, {z = 0}, 'inQuad') - self.jump.spin = spinjump -end - -function Hero:setMotionX(direction, speed) - self.motion = speed - self.motionDirection = direction -end - -function Hero:applyMotion(dt) - if self.motion ~= 0 and self.motion ~= nil then - local dx = self.x + self.motion * self.motionDirection * dt - -- {1, 0, "line", 5, true} - local ox = self.choregraphy.startx + (self.choregraphy.effectArea[1] * self.choregraphy.direction) - local oy = self.choregraphy.starty + self.choregraphy.effectArea[2] - local shape = self.choregraphy.effectArea[3] - local size = self.choregraphy.effectArea[4] - local direction = self.choregraphy.direction - - local new_case_x = utils.math.round(dx) - local new_case_y = utils.math.round(self.y) - print(new_case_x, new_case_y, self.world:caseIsEmpty(new_case_x, new_case_y, self)) - if self.maputils.isInMask(dx, self.y, ox, oy, shape, size, direction) and self.world:caseIsEmpty(new_case_x, new_case_y, self) then - self.x = dx - else - self.x = dx - self.motion = 0 - if (self.blockingChoregraphy == 'action_dashForward') then - self:unblockChoregraphy() - self.direction = self.choregraphy.direction - end - end - end -end - --- SIGNAL FUNCTIONS --- All functions related to signal receiving - -function Hero:receiveSignal(action_type, id) - if id == nil then - core.debug:print("battler/hero", "action selected : " .. action_type) - else - core.debug:print("battler/hero", "action selected : " .. action_type .. " (" .. id .. ")") - end - if (action_type == "defend") then - self.turnAction = "defend" - self:switchActiveBattler( ) - elseif (action_type == "attack") then - --self:changeAnimation("hit1") - self:attack() - elseif (action_type == "skill") then - self.world.cursor:unset( ) - self:useSkill(id, self.world.cursor.x, self.world.cursor.y) - elseif (action_type == "cursorMove") then - if (self.x ~= self.world.cursor.x) or (self.y ~= self.world.cursor.y) then - self:changeAnimation("walk", true) - self:goTo(self.world.cursor.x, self.world.cursor.y, 'cursorMove', 1) - self.assets.sfx["woosh"]:play() - else - self.world:resetActiveGrid() - self.scene.menu:set( self ) - end - self.world.cursor:unset( ) - else - self:switchActiveBattler( ) - end -end - -function Hero:positionSelected(x, y) - self:changeAnimation("walk", true) - self:goTo(self.world.cursor.x, self.world.cursor.y, 'cursorMove', 1) - self.assets.sfx["woosh"]:play() -end - -function Hero:receiveBackSignal() - self.world.cursor:set(self.x, self.y, "cursorMove") - if (self.x ~= self.startx) or (self.y ~= self.starty) then - self.world.cursor:set(self.x, self.y, "cursorMove") - self.assets.sfx["woosh"]:play() - self:changeAnimation("walk") - end -end - -function Hero:timerResponse(timer) - if timer == "switchActiveBattler" then - self.scene.turns:nextAction() - elseif timer == "wait" then - self.choregraphy.changeAction = true - elseif timer == "cursorMove" then - self:changeAnimation("idle") - self.world:resetActiveGrid() - self.scene.menu:set( self ) - elseif timer == 'backMove' then - self:changeAnimation("idle") - self.direction = self.directionPrevious - elseif timer == 'action_jumpBack' then - self.unlockDirection = true - self:unblockChoregraphy() - elseif timer == self.choregraphy.blockedBy then - self:unblockChoregraphy() - end -end - --- ACTION FUNCTIONS --- All functions related to actions - -function Hero:switchActiveBattler() - print("Switching Active Battler") - self.tweens:newTimer(0.15, "switchActiveBattler") -end - --- CHOREGRAPHY FUNCTIONS --- All functions related to the choregraphy system - -function Hero:initChoregraphySystem() - self.choregraphy = ChoregraphySystem(self) - self.blockingChoregraphy = nil -end - -function Hero:attack(id, dx, dy) - local skill = game.skills:getSkillData("attack") - self.choregraphy:start(skill, dx, dy) -end - -function Hero:useSkill(id, dx, dy) - local skill = game.skills:getSkillData(id) - self:setPP(skill.cost * -1, true) - self.choregraphy:start(skill, dx, dy) -end - -function Hero:updateChoregraphy(dt) - self.choregraphy:update(dt) -end - -function Hero:blockChoregraphy(isBlocked, blockedBy) - if (isBlocked) then - self.blockingChoregraphy = blockedBy - end -end - -function Hero:unblockChoregraphy() - self.choregraphy:endAction() - self.blockingChoregraphy = "" -end - --- INFO FUNCTIONS --- Getting info about the actor - -function Hero:getCharacterData() - return game.characters.list[self.charid] -end - --- ASSETS FUNCTIONS --- Load and play assets needed by the character - -function Hero:initSprite() - self.assets:addSprite(self.charid, "datas/gamedata/characters/" .. self.charid .. "/sprites") - self.assets.sprites[self.charid]:setCustomSpeed(16) - self:setSprite(self.charid, 32, 48, true) - self:cloneSprite() - self:changeAnimation("idle") -end - -function Hero:animationEnded(animation) - if (animation == self.blockingChoregraphy) then - self:unblockChoregraphy() - end -end - -function Hero:initVoices() - self:addVoiceEffect("move") - self:addVoiceEffect("turnstart") -end - -function Hero:addVoiceEffect(name) - local completename = self.charid .. "_" .. name - local path = "datas/gamedata/characters/" .. self.charid .. "/voices/" .. name .. ".wav" - self.assets:newSFX(completename, path) -end - -function Hero:talk(name) - local completename = self.charid .. "_" .. name - self.assets.sfx[completename]:play() + self:setCustomSpeed(self.gspeed * 160 * dt) end -- DRAW FUNCTIONS @@ -397,13 +240,4 @@ function Hero:draw() self:drawSprite(0, -self.z) end -function Hero:drawIcon(x, y) - local iconID = 1 - self.assets.tileset["charicons"]:drawTile(iconID, x, y) -end - -function Hero:drawHUD() - self.statusbar:draw() -end - return Hero diff --git a/sonic-radiance.love/scenes/battlesystem/actors/parent.lua b/sonic-radiance.love/scenes/battlesystem/actors/parent.lua index 0ae9d8f..d2d4775 100644 --- a/sonic-radiance.love/scenes/battlesystem/actors/parent.lua +++ b/sonic-radiance.love/scenes/battlesystem/actors/parent.lua @@ -47,6 +47,13 @@ function Parent:update(dt) self.tweens:update(dt) end +-- GET FUNCTIONS +-- Get informations + +function Parent:getCoordinate() + return self.x, self.y +end + -- SPRITE FUNCTIONS -- Handle the character sprite @@ -153,7 +160,7 @@ end function Parent:drawSprite(tx, ty) utils.graphics.resetColor() - local x, y = self.maputils.gridToPixel(self.x, self.y, true) + local x, y = self.world.map:gridToPixel(self.x, self.y, true) local tx = tx or 0 local ty = ty or 0 @@ -176,8 +183,11 @@ function Parent:draw() end function Parent:drawShadow() - local x, y = self.maputils.gridToPixel(self.x, self.y, true) + local x, y = self.world.map:gridToPixel(self.x, self.y, true) self.assets.images["actorsShadow"]:draw(x, y, 0, 1, 1, 12, 5) + if (self.isSelected == true) then + self.assets.sprites["cursorground"]:drawAnimation(x - 2, y - 1, 0, 1, 1, 12, 5) + end end function Parent:drawHUD() diff --git a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/addGFX.lua b/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/addGFX.lua deleted file mode 100644 index 08f88c9..0000000 --- a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/addGFX.lua +++ /dev/null @@ -1,36 +0,0 @@ -local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent" -local GFXAction = ChoregraphyActionParent:extend() - -function GFXAction:new(controller, args, effectArea) - GFXAction.super.new(self, controller, args, effectArea) -end - -function GFXAction:start() - local dx = self.args.dx - - if (self.args.affectedByDirection) then - dx = dx * self.actor.direction - end - - local x = self.actor.x - local y = self.actor.y - local z = 0 - - self.actor.world.obj.GFX(self.actor.world, x + dx, y + self.args.dy, z, self.args.sprite, self, self.args.blockProcess) - if (not self.args.blockProcess) then - self:finish() - end -end - -function GFXAction:update(dt) - -end - -function GFXAction:getSignal(signal) - if (signal == "gfxEnded") then - self:finish() - end -end - - -return GFXAction diff --git a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/dashForward.lua b/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/dashForward.lua deleted file mode 100644 index 02e3918..0000000 --- a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/dashForward.lua +++ /dev/null @@ -1,19 +0,0 @@ -local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent" -local DashAction = ChoregraphyActionParent:extend() - -function DashAction:new(system, args, effectArea) - DashAction.super.new(self, system, args, effectArea) -end - -function DashAction:start() - self.actor:setMotionX(self.actor.direction, self.args.speed) - self.actor:blockChoregraphy(self.args.blockProcess, "action_dashForward") -end - -function DashAction:getSignal(signal) - if (signal == "actorHaveFinished") then - self:finish() - end -end - -return DashAction; diff --git a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/init.lua b/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/init.lua deleted file mode 100644 index 4c819f9..0000000 --- a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/init.lua +++ /dev/null @@ -1,14 +0,0 @@ -local actions = {} - -local baseURI = "scenes.battlesystem.actors.systems.actions." - -actions["addGFX"] = require(baseURI .. "addGFX") -actions["dashForward"] = require(baseURI .. "dashForward") -actions["jump"] = require(baseURI .. "jump") -actions["playSFX"] = require(baseURI .. "playSFX") -actions["sendDamage"] = require(baseURI .. "sendDamage") -actions["sendDamageToPoint"] = require(baseURI .. "sendDamageToPoint") -actions["setAnimation"] = require(baseURI .. "setAnimation") -actions["wait"] = require(baseURI .. "wait") - -return actions diff --git a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/jump.lua b/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/jump.lua deleted file mode 100644 index ba8507c..0000000 --- a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/jump.lua +++ /dev/null @@ -1,40 +0,0 @@ -local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent" -local JumpAction = ChoregraphyActionParent:extend() - -function JumpAction:new(system, args, effectArea) - JumpAction.super.new(self, system, args, effectArea) -end - -function JumpAction:start() - local xx, yy - local spinjump = true - local factor = 1 - local easing = 'inOutQuad' - if self.args.name == "jumpBack" then - xx, yy = self.controller.startx, self.controller.starty - self.actor.directionLocked = true - spinjump = false - factor = 2 - easing = 'outQuad' - elseif self.args.name == "jumpToCursor" then - xx, yy = self.controller.dx, self.controller.dy - end - - local dist = utils.math.pointDistance(self.actor.x, self.actor.y, xx, yy) - local jumpHeight = dist * 16 / factor - - self.actor:jumpTo(xx, yy, jumpHeight, "action_jumpBack", spinjump, 1, easing) - self.actor:blockChoregraphy(self.args.blockProcess, "action_jumpBack") - if (not self.args.blockProcess) then - self:finish() - end -end - -function JumpAction:getSignal(signal) - if (signal == "actorHaveFinished") then - self:finish() - end -end - - -return JumpAction diff --git a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/parent.lua b/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/parent.lua deleted file mode 100644 index 38ec360..0000000 --- a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/parent.lua +++ /dev/null @@ -1,29 +0,0 @@ -local ChoregraphyAction = Object:extend() - -function ChoregraphyAction:new(controller, args, effectArea) - self.controller = controller - self.actor = controller.actor - - self.args = args; - self.effectArea = effectArea; - self:start() -end - -function ChoregraphyAction:start() - self:finish() -end - -function ChoregraphyAction:update(dt) - -end - -function ChoregraphyAction:getSignal(signal) - -end - -function ChoregraphyAction:finish() - print("action finished") - self.controller:endAction() -end - -return ChoregraphyAction; diff --git a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/playSFX.lua b/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/playSFX.lua deleted file mode 100644 index 8f085b0..0000000 --- a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/playSFX.lua +++ /dev/null @@ -1,14 +0,0 @@ -local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent" -local PlaySFX = ChoregraphyActionParent:extend() - -function PlaySFX:new(system, args, effectArea) - PlaySFX.super.new(self, system, args, effectArea) -end - -function PlaySFX:start() - self.actor.assets.sfx[self.args.sfx]:play() - self:finish() -end - - -return PlaySFX diff --git a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/sendDamage.lua b/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/sendDamage.lua deleted file mode 100644 index 262fbf9..0000000 --- a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/sendDamage.lua +++ /dev/null @@ -1,38 +0,0 @@ -local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent" -local SendDamage = ChoregraphyActionParent:extend() - -local maputils = require "scenes.battlesystem.utils" - -function SendDamage:new(system, args, effectArea) - SendDamage.super.new(self, system, args, effectArea) -end - -function SendDamage:start() - local power = self.args.power - local accuracy = self.args.accuracy - local isSpecial = self.args.isSpecial - local isAerial = self.args.isAerial - - local dx = self.effectArea[1] - if self.effectArea[5] then - dx = dx * self.controller.direction - end - local ox = self.controller.startx + dx - local oy = self.controller.starty + self.effectArea[2] - local grid = maputils.maskToMap(ox, oy, self.effectArea[3], self.effectArea[4], self.controller.direction) - - local test = false - - for i, line in ipairs(grid) do - for j, case in ipairs(line) do - if grid[i][j] == 1 then - test = self.actor:sendDamage(j, i, power, accuracy, isSpecial, isAerial) - end - end - end - - self.controller.haveSentDamage = test - self:finish() -end - -return SendDamage diff --git a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/sendDamageToPoint.lua b/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/sendDamageToPoint.lua deleted file mode 100644 index c90cb49..0000000 --- a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/sendDamageToPoint.lua +++ /dev/null @@ -1,29 +0,0 @@ -local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent" -local SendDamage = ChoregraphyActionParent:extend() - -function SendDamage:new(system, args, effectArea) - SendDamage.super.new(self, system, args, effectArea) -end - -function SendDamage:start() - local xx, yy - if self.args.name == "sendDamageFromCursor" then - xx = self.controller.dx - yy = self.controller.dy - elseif self.args.name == "sendDamageFromPos" then - xx = utils.math.round(self.actor.x) - yy = utils.math.round(self.actor.y) - end - - local dx = self.args.dx - if (self.args.affectedByDirection) then - dx = dx * self.controller.direction - end - xx = xx + dx - yy = yy + self.args.dy - self.controller.haveSentDamage = self.actor:sendDamage(xx, yy, self.args.power, self.args.accuracy, self.args.isSpecial, self.args.isAerial) - - self:finish() -end - -return SendDamage diff --git a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/setAnimation.lua b/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/setAnimation.lua deleted file mode 100644 index ee26427..0000000 --- a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/setAnimation.lua +++ /dev/null @@ -1,24 +0,0 @@ -local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent" -local AnimationSetterAction = ChoregraphyActionParent:extend() - -function AnimationSetterAction:new(controller, args, effectArea) - AnimationSetterAction.super.new(self, controller, args, effectArea) -end - -function AnimationSetterAction:start() - self.actor:changeAnimation(self.args.animation) - self.actor:blockChoregraphy(self.args.blockProcess, self.args.animation) - if (self.args.blockProcess == false) then - self:finish() - end -end - -function AnimationSetterAction:update(dt) - -end - -function AnimationSetterAction:getSignal(signal) - -end - -return AnimationSetterAction; diff --git a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/wait.lua b/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/wait.lua deleted file mode 100644 index 53cf628..0000000 --- a/sonic-radiance.love/scenes/battlesystem/actors/systems/actions/wait.lua +++ /dev/null @@ -1,19 +0,0 @@ -local ChoregraphyActionParent = require "scenes.battlesystem.actors.systems.actions.parent" -local WaitAction = ChoregraphyActionParent:extend() - -function WaitAction:new(controller, args, effectArea) - WaitAction.super.new(self, controller, args, effectArea) -end - -function WaitAction:start() - self.timer = 0 -end - -function WaitAction:update(dt) - self.timer = self.timer + dt - if (self.timer > self.args.duration) then - self:finish() - end -end - -return WaitAction; diff --git a/sonic-radiance.love/scenes/battlesystem/actors/systems/choregraphy.lua b/sonic-radiance.love/scenes/battlesystem/actors/systems/choregraphy.lua deleted file mode 100644 index 4e0855d..0000000 --- a/sonic-radiance.love/scenes/battlesystem/actors/systems/choregraphy.lua +++ /dev/null @@ -1,95 +0,0 @@ -local ChoregraphySystem = Object:extend() - -local actionList = require "scenes.battlesystem.actors.systems.actions" - -function ChoregraphySystem:new(actor) - self.actor = actor - self:init({}, nil, self.actor.x, self.actor.y, false) -end - -function ChoregraphySystem:init(choregraphy, effectArea, dx, dy, isActive) - self.current = 0 - self.action = nil - self.isFinished = false - - self.data = choregraphy - self.effectArea = effectArea - - self.startx = self.actor.x - self.starty = self.actor.y - self.direction = self.actor.direction - - self.dx = dx or self.actor.x - self.dy = dy or self.actor.y - - self.haveSentDamage = false - - self.isActive = isActive - self.actionHaveEnded = false -end - -function ChoregraphySystem:start(skill, dx, dy) - local skill = skill - self:init(skill.choregraphy, skill.effectArea, dx, dy, true) -end - -function ChoregraphySystem:finish() - self.isActive = false - self.actor:switchActiveBattler() -end - -function ChoregraphySystem:update(dt) - if (self.actionHaveEnded) then - self.action = nil - self.actionHaveEnded = false - end - - if (self.isActive) then - if (self.action == nil) then - self:switchAction() - else - self.action:update(dt) - end - end -end - -function ChoregraphySystem:switchAction() - self.current = self.current + 1 - local nextAction = self.data[self.current] - - if (nextAction == nil) then - print("finished") - self:finish() - else - local args = game.skills:getActionArguments(nextAction) - local condition = args.condition - if (condition == "sentDamage") and (not self.haveSentDamage) then - core.debug:print("cbs/hero", "you didn't do damage, skipping " .. args.name) - self:switchAction() - else - self:doAction(nextAction) - end - - end -end - -function ChoregraphySystem:doAction(choregraphyAction) - local args = game.skills:getActionArguments(choregraphyAction) - local type = args.type or "unknown" - local effectArea = self.effectArea - - local action = actionList[type] - - if (action == nil) then - core.debug:warning("cbs/hero", "unknown action type " .. type .. ' (' .. args.name .. ')') - else - self.action = action(self, args, effectArea) - end -end - -function ChoregraphySystem:endAction() - self.action = nil - self.actionHaveEnded = true -end - -return ChoregraphySystem diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/ennemy.lua b/sonic-radiance.love/scenes/battlesystem/controllers/ennemy.lua new file mode 100644 index 0000000..9860b98 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/ennemy.lua @@ -0,0 +1,21 @@ +local FighterControllerParent = require "scenes.battlesystem.controllers.parent" +local EnnemyController = FighterControllerParent:extend() + +local Villain = require "scenes.battlesystem.controllers.fighters.villain" + +function EnnemyController:new(owner) + self.super.new(self, owner) + self:initVillains() +end + +function EnnemyController:initVillains() + self:addVillain("motobug") + self:addVillain("motobug") + self:addVillain("motobug") +end + +function EnnemyController:addVillain(name) + self:add(Villain(self, name, self:count() + 1)) +end + +return EnnemyController diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/character.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/character.lua new file mode 100644 index 0000000..3a6e604 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/character.lua @@ -0,0 +1,155 @@ +local FighterParent = require "scenes.battlesystem.controllers.fighters.parent" +local HeroFighter = FighterParent:extend() + +local StatusBar = require "scenes.battlesystem.gui.statusbar" +local SelectionSystem = require "scenes.battlesystem.controllers.fighters.systems.selection" +local actionList = require "scenes.battlesystem.controllers.fighters.systems.actions" + +local POSITIONS = {3, 1, 5} +local HEROES_LINE = 2; + +function HeroFighter:new(owner, character, id) + self.name = character + self.super.new(self, owner, true, id) + + self.statusbar = StatusBar(self) + self:initVoices() + + self.action = nil + + self.selection = nil +end + +function HeroFighter:updateAssets(dt) + self.statusbar:update(dt) + + if (self.action ~= nil) then + if (self.action.isStarted) then + self.action:update(dt) + end + end +end + +function HeroFighter:update(dt) + if (self.selection ~= nil) then + self.selection:update(dt) + end +end + +function HeroFighter:getAbstract() + return game.characters.list[self.name] +end + +function HeroFighter:createActor() + local x, y = HEROES_LINE, POSITIONS[self.id] + return self.world.obj.Hero(self.world, x, y, self) +end + +function HeroFighter:startAction() + core.debug:print("cbs/heroFighter", "launching the action menu") + self.action = nil + self:talk("turnstart") + self.turnSystem.scene.menu:set( 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(item) + self.action = actionList["item"](self, 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 + self.selection = SelectionSystem(self, self.owner.turnSystem.ennemies, true) + else + self.selection = SelectionSystem(self, self.owner, false) + end + else + self.action:start() + end + +end + +function HeroFighter:attack() + self:doBasicAction("attack") +end + +function HeroFighter:receiveTarget(target) + self.selection = nil + if (self.action ~= nil) then + self.action:setTarget(target) + self.action:start() + end +end + +function HeroFighter:goBackToMenu() + self.owner.turnSystem.scene.menusystem:activate() + self.selection = nil +end + +function HeroFighter:finishAction() + self.action = nil + self:setInactive() +end + +-- LIFE functions +function HeroFighter:setHP(value, relative) + HeroFighter.super.setHP(self, value, relative) + self.statusbar:updateHP() +end + +function HeroFighter:setPP(value, relative) + HeroFighter.super.setPP(self, value, relative) + self.statusbar:updatePP() +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 = 1 + self.assets.tileset["charicons"]:drawTile(iconID, x, y) +end + +function HeroFighter:drawHUD() + self.statusbar:draw() +end + +return HeroFighter diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/parent.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/parent.lua new file mode 100644 index 0000000..6399b6b --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/parent.lua @@ -0,0 +1,137 @@ +local FighterParent = Object:extend() + +local counter = 0 + +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 +end + +-- LIFE handling functions + +function FighterParent:setHP(value, relative) + self.abstract:setHP(value, relative) +end + +function FighterParent:setPP(value, relative) + self.abstract:setPP(value, relative) +end + +function FighterParent:applyDeath() + if (self.abstract.hp <= 0 and self.isAlive) then + self:die() + end +end + +function FighterParent:die() + self.isAlive = false +end + +function FighterParent:sendDamage(target, value, accuracy, isSpecial, isAerial) + local stats = self:getStats() + local value = value / 10 + + if (isSpecial) then + value = value * stats.power + else + value = value * stats.attack + end + + core.debug:print("cbs/battler", "Sending " .. value .." damage at " .. target.name) + + target:receiveDamage(value, accuracy, isSpecial, isAerial, fromWho) +end + +function FighterParent:receiveDamage(value, accuracy, isSpecial, isAerial) + local stats = self:getStats() + + if (isSpecial) then + value = value / stats.mind + else + value = value / stats.defense + end + + core.debug:print("cbs/fighter", "Taken " .. value .. " damage" ) + self:setHP(value * -1, true) +end + +function FighterParent:getAbstract() + return {} +end + +function FighterParent:createActor() + return {} +end + +function FighterParent:update(dt) + counter = counter + dt + if (counter > 1) then + counter = 0 + self:setInactive() + end +end + +function FighterParent:updateAssets(dt) + -- Vide pour l'instant +end + +function FighterParent:setActive() + counter = 0 + self.isActive = true + self:startAction() +end + +function FighterParent:setInactive() + self.isActive = false + self.turnSystem:endAction() +end + +function FighterParent:getNbrActionPerTurn() + return self.abstract.turns +end + +function FighterParent:getStats() + return self.abstract:getStats() +end + +function FighterParent:startAction() + +end + +function FighterParent:getUniqueIdentificator() + local side = 1 + if (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 diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/attack.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/attack.lua new file mode 100644 index 0000000..7697633 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/attack.lua @@ -0,0 +1,17 @@ +local ActionParent = require "scenes.battlesystem.controllers.fighters.systems.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 diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/defend.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/defend.lua new file mode 100644 index 0000000..10597b9 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/defend.lua @@ -0,0 +1,17 @@ +local ActionParent = require "scenes.battlesystem.controllers.fighters.systems.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:finishAction() +end + +return DefendAction diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/flee.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/flee.lua new file mode 100644 index 0000000..def62b6 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/flee.lua @@ -0,0 +1,17 @@ +local ActionParent = require "scenes.battlesystem.controllers.fighters.systems.actions.parent" +local FleeAction = ActionParent:extend() + +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") + self:finishAction() +end + +return FleeAction diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/init.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/init.lua new file mode 100644 index 0000000..1bc71ec --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/init.lua @@ -0,0 +1,9 @@ +local actions = {} + +actions.attack = require "scenes.battlesystem.controllers.fighters.systems.actions.attack" +actions.skill = require "scenes.battlesystem.controllers.fighters.systems.actions.skill" +actions.item = require "scenes.battlesystem.controllers.fighters.systems.actions.item" +actions.defend = require "scenes.battlesystem.controllers.fighters.systems.actions.defend" +actions.flee = require "scenes.battlesystem.controllers.fighters.systems.actions.flee" + +return actions diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/item.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/item.lua new file mode 100644 index 0000000..bd6f7dc --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/item.lua @@ -0,0 +1,17 @@ +local ActionParent = require "scenes.battlesystem.controllers.fighters.systems.actions.parent" +local ItemAction = ActionParent:extend() + +function ItemAction:new(fighter, item) + ItemAction.super.new(self, fighter) +end + +function ItemAction:needTarget() + return false, false +end + +function ItemAction:startAction() + core.debug:print("cbs/action", "Starting flee action") + self:finishAction() +end + +return ItemAction diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/parent.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/parent.lua new file mode 100644 index 0000000..d1f6c5f --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/parent.lua @@ -0,0 +1,56 @@ +local ActionParent = Object:extend() + +local ChoregraphySystem = require "scenes.battlesystem.controllers.fighters.systems.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 = game.skills:getSkillData(skillname) + self.choregraphy = ChoregraphySystem(self, skill.choregraphy) +end + +function ActionParent:loadChoregraphyFromSkill(skill) + self.choregraphy = ChoregraphySystem(self, skill.choregraphy) +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 diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/skill.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/skill.lua new file mode 100644 index 0000000..76a05c1 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/actions/skill.lua @@ -0,0 +1,18 @@ +local ActionParent = require "scenes.battlesystem.controllers.fighters.systems.actions.parent" +local SkillAction = ActionParent:extend() + +function SkillAction:new(fighter, skill) + self.data = game.skills:getSkillData(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) +end + +return SkillAction diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/init.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/init.lua new file mode 100644 index 0000000..3eee591 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/init.lua @@ -0,0 +1,83 @@ +local ChoregraphySystem = Object:extend() + +local choregraphyUtils = require "game.utils.choregraphy" +local stepObjectList = require "scenes.battlesystem.controllers.fighters.systems.choregraphy.step" +local qteObjectList = require "scenes.battlesystem.controllers.fighters.systems.choregraphy.qte" + +function ChoregraphySystem:new(action, choregraphy) + self.action = action + self.fighter = action.fighter + self.actor = self.fighter.actor + self.assets = self.fighter.actor.assets + self.world = self.actor.world + self.target = action.target + + self.currentStepId = 0 + self.currentStep = nil + self.stepList = choregraphy + + self.qte = {} + self.qte.current = nil + self.qte.wasSuccess = false +end + +function ChoregraphySystem:update(dt) + if (self.qte.current ~= nil) then + self.qte.current:update(dt) + end + + if (self.currentStep ~= nil) then + self.currentStep:updateStep(dt) + else + self:switchStep() + end +end + +function ChoregraphySystem:switchStep() + if self:haveNextStep() then + self.currentStepId = self.currentStepId + 1 + local stepData = choregraphyUtils.getStepDatas(self.stepList[self.currentStepId]) + core.debug:print("cbs/choregraphy", "Starting step " .. stepData.name) + if (stepObjectList[stepData.name] ~= nil) then + self.currentStep = stepObjectList[stepData.name](self, stepData.arguments) + end + else + self:endChoregraphy() + end +end + +function ChoregraphySystem:addQTE(action, origin, qteBaseData, blockProcess) + local qteData = choregraphyUtils.getQteDatas(qteBaseData) + if (qteObjectList[qteData.name] ~= nil) then + self.qte.current = qteObjectList[qteData.name](self, qteData.arguments) + self.qte.current:blockAction(action, blockProcess) + self.qte.current:setOrigin(origin) + end +end + +function ChoregraphySystem:sendDamage(power, accuracy, isSpecial, isAerial) + if (self.target ~= nil) then + if (self.fighter.isAlive) then + self.fighter:sendDamage(self.target, power, accuracy, isSpecial, isAerial) + return true + else + return false + end + end +end + +function ChoregraphySystem:endStep() + self.currentStep = nil +end + +function ChoregraphySystem:endChoregraphy() + self.actor:choregraphyEnded() + self.action:choregraphyEnded() + self.fighter.turnSystem:applyDeath() +end + +function ChoregraphySystem:haveNextStep() + return ((self.currentStepId + 1) <= #self.stepList) +end + +return ChoregraphySystem diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/qte/init.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/qte/init.lua new file mode 100644 index 0000000..c3e7f9f --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/qte/init.lua @@ -0,0 +1,5 @@ +local qtes = {} + +local baseURI = "scenes.battlesystem.controllers.fighters.systems.choregraphy.qte." + +return qtes diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/qte/parent.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/qte/parent.lua new file mode 100644 index 0000000..2fdefa7 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/qte/parent.lua @@ -0,0 +1,72 @@ +local QteParent = Object:extend() + +function QteParent:new(choregraphySystem, arguments) + self.choregraphy = choregraphySystem + self.arguments = arguments + self.timer = 0 + self.origin = nil + self.isBlocking = nil +end + +function QteParent:blockAction(action, blockProcess) + if (blockProcess) then + self.isBlocking = action + end +end + +function QteParent:setOrigin(origin) + self.origin = origin +end + +function QteParent:drawButton(x, y, letter) + local grayValue = .44 + local darkValue = .11 + love.graphics.setColor(grayValue, grayValue, grayValue, 1) + love.graphics.circle("fill", x, y, 8, 8) + love.graphics.setColor(darkValue, darkValue, darkValue, 1) + love.graphics.circle("line", x, y, 8, 8) + love.graphics.print(letter, x, y) + utils.graphics.resetColor() +end + +function StepParent:updateStep(dt) + if (not self.isStarted) then + self:start() + self.isStarted = true + else + self:update(dt) + self:updateTimer(dt) + end +end + +function StepParent:update(dt) + -- +end + +function StepParent:updateTimer(dt) + if (self.arguments.duration ~= nil) then + self.timer = self.timer + dt + if (self.timer > self.arguments.duration) then + self:fail() + end + end +end + + +function QteParent:succes() + self:finish(true) +end + +function QteParent:fail() + self:finish(false) +end + +function QteParent:finish(success) + print("action finished") + self.choregraphy:endQte(success) + if (self.isBlocking ~= nil) then + self.isBlocking:finish() + end +end + +return QteParent diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/qte/simplePrompt.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/qte/simplePrompt.lua new file mode 100644 index 0000000..e69de29 diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/addGFX.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/addGFX.lua new file mode 100644 index 0000000..7b70183 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/addGFX.lua @@ -0,0 +1,29 @@ +local StepParent = require "scenes.battlesystem.controllers.fighters.systems.choregraphy.step.parent" +local StepGFX = StepParent:extend() + +function StepGFX:new(controller, args) + StepGFX.super.new(self, controller, args) +end + +function StepGFX:start() + local x, y = self:getStepCoordinate() + + self.choregraphy.world.obj.GFX(self.choregraphy.world, x, y, 0, self.arguments.sprite, self, self.arguments.blockProcess) + + 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 diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/addQTE.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/addQTE.lua new file mode 100644 index 0000000..13fd8f5 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/addQTE.lua @@ -0,0 +1,26 @@ +local StepParent = require "scenes.battlesystem.controllers.fighters.systems.choregraphy.step.parent" +local StepQTE = StepParent:extend() + +function StepQTE:new(controller, args) + StepQTE.super.new(self, controller, args) +end + +function StepQTE:start() + self.choregraphy:addQTE(self, self.arguments.origin, self.arguments.qteData, self.arguments.blockProcess) + if (not self.arguments.blockProcess) then + self:finish() + end +end + +function StepQTE:update(dt) + +end + +function StepQTE:getSignal(signal) + if (signal == "gfxEnded") then + self:finish() + end +end + + +return StepQTE diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/goTo.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/goTo.lua new file mode 100644 index 0000000..a38c982 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/goTo.lua @@ -0,0 +1,28 @@ +local StepParent = require "scenes.battlesystem.controllers.fighters.systems.choregraphy.step.parent" +local GoToStep = StepParent:extend() + +function GoToStep:new(controller, args) + GoToStep.super.new(self, controller, args) +end + +function GoToStep:start() + + local x, y = self:getStepCoordinate() + self.choregraphy.actor:goTo(x, y, self.arguments.duration) + + if (self.arguments.blockProcess == false) then + self:finish() + else + self.choregraphy.actor:blockChoregraphy(self.arguments.blockProcess, self, "goTo") + end +end + +function GoToStep:update(dt) + +end + +function GoToStep:getSignal(signal) + +end + +return GoToStep; diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/init.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/init.lua new file mode 100644 index 0000000..a827847 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/init.lua @@ -0,0 +1,15 @@ +local actions = {} + +local baseURI = "scenes.battlesystem.controllers.fighters.systems.choregraphy.step." + +actions["addGFX"] = require(baseURI .. "addGFX") +actions["addQTE"] = require(baseURI .. "addQTE") +actions["goTo"] = require(baseURI .. "goTo") +actions["jumpBack"] = require(baseURI .. "jumpBack") +actions["playSFX"] = require(baseURI .. "playSFX") +actions["sendDamage"] = require(baseURI .. "sendDamage") +actions["setAnimation"] = require(baseURI .. "setAnimation") +actions["wait"] = require(baseURI .. "wait") +actions["waitActorFinished"] = require(baseURI .. "waitActorFinished") + +return actions diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/jumpBack.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/jumpBack.lua new file mode 100644 index 0000000..bb33e2f --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/jumpBack.lua @@ -0,0 +1,27 @@ +local StepParent = require "scenes.battlesystem.controllers.fighters.systems.choregraphy.step.parent" +local JumpBackStep = StepParent:extend() + +function JumpBackStep:new(controller, args) + JumpBackStep.super.new(self, controller, args) +end + +function JumpBackStep:start() + + self.choregraphy.actor:jumpBack() + + if (self.arguments.blockProcess == false) then + self:finish() + else + self.choregraphy.actor:blockChoregraphy(self.arguments.blockProcess, self, "jump") + end +end + +function JumpBackStep:update(dt) + +end + +function JumpBackStep:getSignal(signal) + +end + +return JumpBackStep; diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/parent.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/parent.lua new file mode 100644 index 0000000..5e5508a --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/parent.lua @@ -0,0 +1,37 @@ +local StepParent = Object:extend() + +function StepParent:new(choregraphySystem, arguments) + self.choregraphy = choregraphySystem + self.arguments = arguments + self.isStarted = false +end + +function StepParent:updateStep(dt) + if (not self.isStarted) then + self:start() + self.isStarted = true + else + self:update(dt) + end +end + +function StepParent:getStepCoordinate() + if (self.arguments.origin == "target") then + local target = self.choregraphy.action.target + local x, y = target.actor:getCoordinate() + return x + self.arguments.x, y + self.arguments.y + elseif (self.arguments.origin == "start") then + local x, y = self.choregraphy.actor.start.x, self.choregraphy.actor.start.y + return x + self.arguments.x, y + self.arguments.y + elseif (self.arguments.origin == "actor") then + local x, y = self.choregraphy.actor:getCoordinate() + return x + self.arguments.x, y + self.arguments.y + end +end + +function StepParent:finish() + print("action finished") + self.choregraphy:endStep() +end + +return StepParent diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/playSFX.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/playSFX.lua new file mode 100644 index 0000000..e5d24ac --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/playSFX.lua @@ -0,0 +1,13 @@ +local StepParent = require "scenes.battlesystem.controllers.fighters.systems.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 diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/sendDamage.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/sendDamage.lua new file mode 100644 index 0000000..92e5548 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/sendDamage.lua @@ -0,0 +1,22 @@ +local StepParent = require "scenes.battlesystem.controllers.fighters.systems.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 accuracy = self.arguments.accuracy + local isSpecial = self.arguments.isSpecial + local isAerial = self.arguments.isAerial + + + + self.choregraphy.haveSentDamage = self.choregraphy:sendDamage(power, accuracy, isSpecial, isAerial) + self:finish() +end + +return SendDamage diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/setAnimation.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/setAnimation.lua new file mode 100644 index 0000000..b7982f9 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/setAnimation.lua @@ -0,0 +1,26 @@ +local StepParent = require "scenes.battlesystem.controllers.fighters.systems.choregraphy.step.parent" +local AnimationSetterStep = StepParent:extend() + +function AnimationSetterStep:new(controller, args) + AnimationSetterStep.super.new(self, controller, args) +end + +function AnimationSetterStep:start() + self.choregraphy.actor:changeAnimation(self.arguments.animation) + + if (self.arguments.blockProcess == false) then + self:finish() + else + self.choregraphy.actor:blockChoregraphy(self.arguments.blockProcess, self, "animation") + end +end + +function AnimationSetterStep:update(dt) + +end + +function AnimationSetterStep:getSignal(signal) + +end + +return AnimationSetterStep; diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/wait.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/wait.lua new file mode 100644 index 0000000..5098318 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/wait.lua @@ -0,0 +1,19 @@ +local StepParent = require "scenes.battlesystem.controllers.fighters.systems.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; diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/waitActorFinished.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/waitActorFinished.lua new file mode 100644 index 0000000..7392a3f --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/choregraphy/step/waitActorFinished.lua @@ -0,0 +1,20 @@ +local StepParent = require "scenes.battlesystem.controllers.fighters.systems.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; diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/selection.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/selection.lua new file mode 100644 index 0000000..1db4db9 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/systems/selection.lua @@ -0,0 +1,65 @@ +local SelectionSystem = Object:extend() + +function SelectionSystem:new(owner, fighterSide, onlyAlive) + self.fighterList = fighterSide:getTargets(onlyAlive) + self.owner = owner + self.assets = self.owner.assets + self.selectedTarget = 1 +end + +function SelectionSystem:update(dt) + --Faire en sorte que cela permette de choisir la cible + local keys = self.owner.turnSystem.scene:getKeys(1) + self:purgeTarget() + if (keys["up"].isPressed) then + if (self.selectedTarget == 1) then + self.selectedTarget = #self.fighterList + else + self.selectedTarget = self.selectedTarget - 1 + end + self.assets.sfx["mBeep"]:play() + end + if (keys["down"].isPressed) then + if (self.selectedTarget == #self.fighterList) then + self.selectedTarget = 1 + else + self.selectedTarget = self.selectedTarget + 1 + end + self.assets.sfx["mBeep"]:play() + end + + self:updateTarget() + + if (keys["A"].isPressed) then + self.assets.sfx["mSelect"]:play() + self:selectTarget() + end + + if (keys["B"].isPressed) then + self.assets.sfx["mBack"]:play() + self:goBack() + 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:purgeTarget() + self.owner:receiveTarget(self.fighterList[self.selectedTarget]) +end + +function SelectionSystem:goBack() + self:purgeTarget() + self.owner:goBackToMenu() +end + +return SelectionSystem diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/fighters/villain.lua b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/villain.lua new file mode 100644 index 0000000..0084169 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/controllers/fighters/villain.lua @@ -0,0 +1,60 @@ +local FighterParent = require "scenes.battlesystem.controllers.fighters.parent" +local VillainFighter = FighterParent:extend() + +local SimpleHPBar = require "scenes.battlesystem.gui.simplehpbar" + +local POSITIONS = {1, 3, 5} +local ENNEMY_LINE = 11; + +function VillainFighter:new(owner, ennemy, id) + self.name = ennemy + self.super.new(self, owner, false, id) + + self.hpbar = SimpleHPBar(self.abstract.hp) +end + +function VillainFighter:updateAssets(dt) + self.hpbar:update(dt) +end + + +function VillainFighter:getAbstract() + return game.ennemies:getEnnemyData(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() + +end + +function VillainFighter:endAction() + +end + +function FighterParent:die() + self.isAlive = false + self.actor:destroy() +end + +-- LIFE FUNCTIONS +function VillainFighter:setHP(value, relative) + VillainFighter.super.setHP(self, value, relative) + self.hpbar:setHP(self.abstract.hp) +end + +-- DRAW FUNCTIONS +function VillainFighter:drawIcon(x, y) + love.graphics.setColor(1, 0, 0, 1) + love.graphics.rectangle("fill", x, y, 16, 16) + love.graphics.setColor(1, 1, 1, 1) +end + +function VillainFighter:drawHUD(x, y) + self.hpbar:draw(x, y) +end + +return VillainFighter diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/init.lua b/sonic-radiance.love/scenes/battlesystem/controllers/init.lua index 9c34d96..26b3826 100644 --- a/sonic-radiance.love/scenes/battlesystem/controllers/init.lua +++ b/sonic-radiance.love/scenes/battlesystem/controllers/init.lua @@ -1,7 +1,9 @@ local TurnController = Object:extend() local Player = require "scenes.battlesystem.controllers.player" -local Ennemy = require "scenes.battlesystem.controllers.player" +local Ennemy = require "scenes.battlesystem.controllers.ennemy" + +local HUD = require "scenes.battlesystem.gui.hud" local maputils = require "scenes.battlesystem.utils" @@ -9,9 +11,6 @@ function TurnController:new(scene) self.scene = scene self.world = scene.world - self.player = Player(self) - --self.ennemies = Ennemy(self) - self.isActive = false self.currentlyPlaying = "" @@ -22,18 +21,34 @@ function TurnController:new(scene) self.turns.isFinished = true self.turns.changeBattler = true self.actionList = {} + + self.currentFighter = nil + + self.hud = HUD(self) + + self.player = Player(self) + self.ennemies = Ennemy(self) end function TurnController:startBattle() self.isActive = true + self.hud:movePlayerHUD(true) +end + +function TurnController:finishBattle() + self.isActive = false + self.actionlist = {} + self.hud:movePlayerHUD(false) + self.scene:finishBattle() end function TurnController:update(dt) + self.player:update(dt) + self.ennemies:update(dt) + self.hud:update(dt) if (self.isActive) then - if (self.currentlyPlaying == "heroes") then - self.player:update(dt) - elseif (self.currentlyPlaying == "ennemies") then - --self.ennemies:update(dt) + if (self.currentFighter ~= nil) then + self.currentFighter:update(dt) else self:nextAction() end @@ -45,15 +60,14 @@ function TurnController:nextAction() self:startNewTurn() else self.turns.current = self.turns.current + 1 - core.debug:print("cbs/world", "switching to next action") + core.debug:print("cbs/turns", "switching to next action") end - self.scene.hud:moveBattleCursor(self.turns.current) self:startAction() end function TurnController:startNewTurn() - core.debug:print("cbs/world", "New Turn Starting") + core.debug:print("cbs/turns", "New Turn Starting") self.turns.current = 1 self.turns.isFinished = false self.turns.number = self.turns.number + 1 @@ -61,41 +75,58 @@ function TurnController:startNewTurn() end function TurnController:calculateTurn() - self.actionList = self.world:generateActionList() + self.actionList = {} + self.player:putActions(self.actionList) + self.ennemies:putActions(self.actionList) table.sort(self.actionList, maputils.sortBattlers) end -function TurnController:startAction() -core.debug:print("cbs/world", "Starting action " .. self.turns.current) - local nextAction = self.actionList[self.turns.current] - print(nextAction) - local nextActor = nextAction.actor - if (nextActor.isDestroyed == true) then - -- On skipe le personnage s'il a été detruit - self:nextAction() - else - if (nextActor.side == "heroes") then - self.player:setActive(nextActor) - self.currentlyPlaying = "heroes" - elseif (nextActor.side == "ennemies") then - --self.ennemies:setActive(nextActor) - self.currentlyPlaying = "ennemies" - self.actionList[self.turns.current].actor:setActive() +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:endAction() - self.currentlyPlaying = "" +function TurnController:applyDeath() + local ennemiesAlive = self.ennemies:applyDeath() + if (ennemiesAlive == 0) then + self:finishBattle() + end + self.player:applyDeath() end -function TurnController:drawTurnList(x, y) +function TurnController:startAction() + core.debug:print("cbs/turns", "Starting action " .. self.turns.current) + local nextAction = self.actionList[self.turns.current] + print(nextAction) + 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.hud:moveBattleCursor(self.turns.current) + end +end + +function TurnController:endAction() + self.currentFighter = nil end function TurnController:sendSignalToCurrentBattler(signal, subSignal) self.actionList[self.turns.current].actor:receiveSignal(signal, subSignal) end +function TurnController:draw() + self.hud:draw() + self.player:draw() + self.ennemies:draw() +end + return TurnController diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/parent.lua b/sonic-radiance.love/scenes/battlesystem/controllers/parent.lua index 01775eb..7ac8d5f 100644 --- a/sonic-radiance.love/scenes/battlesystem/controllers/parent.lua +++ b/sonic-radiance.love/scenes/battlesystem/controllers/parent.lua @@ -1,22 +1,94 @@ -local ControllerParent = Object:extend() +local FighterControllerParent = Object:extend() -function ControllerParent:new(owner) - self.owner = owner - self.activeActor = nil; - self.startData = {} +function FighterControllerParent:new(turnSystem) + self.turnSystem = turnSystem + self.world = turnSystem.world + self.list = {} end -function ControllerParent:setActive(activeActor) +function FighterControllerParent:get(id) + return self.list[id] +end + +function FighterControllerParent:add(fighter) + table.insert(self.list, fighter) +end + +function FighterControllerParent:count() + return #self.list +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 ControllerParent:update(dt) - +function FighterControllerParent:update(dt) + for i, fighter in ipairs(self.list) do + fighter:updateAssets(dt) + end end -function ControllerParent:endAction() +function FighterControllerParent:endAction() self.owner:nextAction() end -return PlayerController +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:draw() + --Aucun dessin par defaut, ils sont géré différements +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 diff --git a/sonic-radiance.love/scenes/battlesystem/controllers/player.lua b/sonic-radiance.love/scenes/battlesystem/controllers/player.lua index 8ec0a5b..007e734 100644 --- a/sonic-radiance.love/scenes/battlesystem/controllers/player.lua +++ b/sonic-radiance.love/scenes/battlesystem/controllers/player.lua @@ -1,28 +1,23 @@ -local PlayerController = Object:extend() +local FighterControllerParent = require "scenes.battlesystem.controllers.parent" +local HeroFighterController = FighterControllerParent:extend() -function PlayerController:new(owner) - self.owner = owner - self.activeActor = nil; - self.startData = {} +local Character = require "scenes.battlesystem.controllers.fighters.character" + +function HeroFighterController:new(owner) + self.super.new(self, owner) + self:initHeroes() end -function PlayerController:setActive(activeActor) - self.activeActor = activeActor - activeActor:setActive() +function HeroFighterController:initHeroes() + for i, hero in ipairs(game.characters.team) do + self:add(Character(self, hero, i)) + end end -function PlayerController:update(dt) - +function HeroFighterController:draw() + for i, hero in ipairs(self.list) do + hero:drawHUD() + end end -function PlayerController:setStartData(x, y, direction) - self.startData.x = x - self.startData.y = y - self.startData.direction = direction -end - -function PlayerController:getStartData() - return self.startData.x, self.startData.y, self.startData.direction -end - -return PlayerController +return HeroFighterController diff --git a/sonic-radiance.love/scenes/battlesystem/cursor.lua b/sonic-radiance.love/scenes/battlesystem/cursor.lua deleted file mode 100644 index ba862c2..0000000 --- a/sonic-radiance.love/scenes/battlesystem/cursor.lua +++ /dev/null @@ -1,214 +0,0 @@ -local Cursor = Object:extend() - -local maputils = require "scenes.battlesystem.utils" -local TweenManager = require "game.modules.tweenmanager" - -function Cursor:new(world) - self.world = world - self.scene = world.scene - self.assets = world.assets - - self.tweens = TweenManager(self) - - self.x = 1 - self.y = 1 - self.isActive = false - self.tx = 1 - self.ty = 1 - - self.signal = "" - - self.grid = maputils.newEmptyMap() -end - -function Cursor:set(x, y, signal, subSignal) - self.x = math.max(math.min(x, 12), 1) - self.y = math.max(math.min(y, 07), 1) - self.initialx = self.x - self.initialy = self.y - - self:placeInGrid() - - self.tx = self.x - self.ty = self.y - - self.isActive = true - self.signal = signal or "" - self.subSignal = subSignal or "" - - self.world:setActiveGridFromGrid(self.grid) -end - -function Cursor:placeInGrid() - while (self.grid[self.y][self.x] == 0) do - core.debug:print("cursor", "testing position " .. self.x .. " " .. self.y) - -- On teste d'abord les position > initialx - if self.x >= self.initialx then - if self.x >= 12 then - -- cependant, si on est au maximum, on se place juste avant - self.x = self.initialx - 1 - else - self.x = self.x + 1 - end - else - if self.x <= 1 then - -- cependant, si on est au minimum, on doit tester une autre ligne - self.x = self.initialx - if self.y >= self.initialy then - -- on test d'abord les positions en dessous de la position initiales - if self.y >= 7 then - self.y = self.initialy - 1 - else - self.y = self.y + 1 - end - else - if self.y <= 1 then - core.debug:error("cursor", "map was empty") - else - self.y = self.y - 1 - end - end - else - -- sinon, on test les positions avant - self.x = self.x - 1 - end - end - end -end - -function Cursor:setGrid(ox, oy, shape, size, direction, whitelistedEntity) - self.grid = maputils.newEmptyMap() - - for y, line in ipairs(self.grid) do - for x, case in ipairs(line) do - if not maputils.isInMask(x, y, ox, oy, shape, size, direction) then - self.grid[y][x] = 0 - else - if (self:testPoint(x, y, whitelistedEntity)) then - self.grid[y][x] = 1 - else - self.grid[y][x] = 0 - end - end - end - end - - self.world:setActiveGridFromGrid(self.grid) -end - -function Cursor:setGridIgnoreActor(ox, oy, shape, size, direction) - self.grid = maputils.newEmptyMap() - - for y, line in ipairs(self.grid) do - for x, case in ipairs(line) do - if maputils.isInMask(x, y, ox, oy, shape, size, direction) then - self.grid[y][x] = 1 - end - end - end - - self.world:setActiveGridFromGrid(self.grid) -end - -function Cursor:testPoint(x, y, whitelistedActor) - if ((self.world:getActorInCase(x, y) == nil) or - (self.world:getActorInCase(x, y) == whitelistedActor) and (whitelistedActor ~= nil)) and - (self.world.map:getTerrain(x, y) ~= 3) then - return true - else - return false - end -end - -function Cursor:gridIsActive(x, y) - if self.grid[y] ~= nil then - return (self.grid[y][x] == 1) - else - return false - end -end - -function Cursor:getGrid() - if (self.isActive) then - return self.grid - else - return maputils.newFullMap() - end -end - -function Cursor:resetGrid() - self.grid = EmptyGrid -end - -function Cursor:unset() - self.isActive = false -end - -function Cursor:update(dt) - if (self.isActive) then - local keys = self.scene:getKeys(1) - - if (keys["up"].isDown and self.y == self.ty) then - dy = math.max(self.y - 1, 1) - if (self.grid[dy][self.x] == 1) then - self.y = dy - self:addTween() - end - end - if (keys["down"].isDown and self.y == self.ty) then - dy = math.min(self.y + 1, 7) - if (self.grid[dy][self.x] == 1) then - self.y = dy - self:addTween() - end - end - if (keys["left"].isDown and self.x == self.tx) then - dx = math.max(self.x - 1, 1) - if (self.grid[self.y][dx] == 1) then - self.x = dx - self:addTween() - end - end - if (keys["right"].isDown and self.x == self.tx) then - dx = math.min(self.x + 1, 12) - if (self.grid[self.y][dx] == 1) then - self.x = dx - self:addTween() - end - end - - if (keys["A"].isPressed and self.x == self.tx and self.y == self.ty) then - self.world:sendSignalToCurrentBattler(self.signal, self.subSignal) - end - - self.tweens:update(dt) - end -end - -function Cursor:addTween() - self.tweens:newTween(0, 0.2, {tx = self.x, ty = self.y}, 'linear') -end - -function Cursor:drawBottom() - - if (self.isActive) then - local x, y, frame - x, y = maputils.gridToPixel(self.tx, self.ty, true) - - self.assets.sprites["cursorground"]:drawAnimation(x, y, 0, 1, 1, 14, 6) - end - -end - -function Cursor:drawTop() - - if (self.isActive) then - local x, y - x, y = maputils.gridToPixel(self.tx, self.ty, true) - - self.assets.images["cursorpeak"]:draw(x, y - 24, 0, 1, 1, 7, 26) - end - -end - -return Cursor diff --git a/sonic-radiance.love/scenes/battlesystem/gui/hud.lua b/sonic-radiance.love/scenes/battlesystem/gui/hud.lua index 469cad4..1916b0c 100644 --- a/sonic-radiance.love/scenes/battlesystem/gui/hud.lua +++ b/sonic-radiance.love/scenes/battlesystem/gui/hud.lua @@ -4,11 +4,11 @@ local gui = require "game.modules.gui" local TweenManager = require "game.modules.tweenmanager" -function HUD:new(scene) - self.scene = scene - self.world = scene.world - self.assets = scene.assets - self.turns = scene.turns +function HUD:new(turns) + self.turns = turns + self.scene = turns.scene + self.world = self.scene.world + self.assets = self.scene.assets self.frame = gui.newBorder(424, 30, 4) self.tweens = TweenManager(self) @@ -23,7 +23,7 @@ end function HUD:movePlayerHUD(beginBattle) if (beginBattle) then - self.tweens:newTween(0, 0.4, {playerHUDPosition = 36}, 'inCubic') + self.tweens:newTween(0, 0.4, {playerHUDPosition = 16}, 'inCubic') else self.tweens:newTween(0, 0.4, {playerHUDPosition = -64}, 'inCubic') end @@ -38,22 +38,22 @@ function HUD:getPlayerHUDPosition() end function HUD:draw() - for i, battler in ipairs(self.world.battlers) do - battler:drawHUD() - end - for i, action in ipairs(self.turns.actionList) do - action.actor:drawIcon(4 + (i-1)*(20), 6) + if action.fighter:canFight() then + action.fighter:drawIcon(4 + (i-1)*(20), 216) + else + self:drawEmptyIcon(4 + (i-1)*(20), 216) + end end - local cursorx = self.battlerCursor * 20 - 6 + local cursorx = self.battlerCursor * 20 - 8 if #self.turns.actionList > 0 then - self.assets.images["menucursor"]:draw(cursorx, 26, math.rad(-90), 1, 1, 4, 8) + self.assets.images["menucursor"]:draw(cursorx, 216, math.rad(90), 1, 1, 4, 8) end - local x, y = 362, 3 + local x, y = 362, 225 - love.graphics.draw(self.frame, 424, 20, 0, -1, -1) + love.graphics.draw(self.frame, 424, 220, 0, -1, 1) self.assets.images["hudturn"]:draw(x, y) self.assets.fonts["hudnbrs"]:set() local turnnbr = self.turns.turns.number @@ -63,4 +63,12 @@ function HUD:draw() love.graphics.print(turnnbr, x + 33, y + 1) end +function HUD:drawEmptyIcon(x, y) + local outlineLight = 0.15 + love.graphics.circle("fill", x + 8, y + 8, 2, 8) + love.graphics.setColor(outlineLight, outlineLight, outlineLight, 1) + love.graphics.circle("line", x + 8, y + 8, 2, 8) + utils.graphics.resetColor() +end + return HUD diff --git a/sonic-radiance.love/scenes/battlesystem/gui/simplehpbar.lua b/sonic-radiance.love/scenes/battlesystem/gui/simplehpbar.lua new file mode 100644 index 0000000..c568eb2 --- /dev/null +++ b/sonic-radiance.love/scenes/battlesystem/gui/simplehpbar.lua @@ -0,0 +1,29 @@ +local SimpleHPBar = Object:extend() + +local TweenManager = require "game.modules.tweenmanager" +local gui = require "game.modules.gui" + +function SimpleHPBar:new(hp) + self.tweens = TweenManager(self) + self.hp = hp + self.baseHP = hp +end + +function SimpleHPBar:setHP(newHP) + self.tweens:newTween(0, 0.1, {hp = newHP}, 'inCubic') +end + +function SimpleHPBar:update(dt) + self.tweens:update(dt) +end + +function SimpleHPBar:draw(x, y) + love.graphics.setColor(0, 0, 0, 1) + gui.drawBar(x, y, 26, 4) + love.graphics.setColor(248/255, 160/255, 0, 1) + local bar = math.floor(24 * (self.hp / self.baseHP)) + gui.drawBar(x, y + 1, bar, 2) + love.graphics.setColor(1, 1, 1, 1) +end + +return SimpleHPBar diff --git a/sonic-radiance.love/scenes/battlesystem/gui/statusbar.lua b/sonic-radiance.love/scenes/battlesystem/gui/statusbar.lua index c0be16f..c7a3dbf 100644 --- a/sonic-radiance.love/scenes/battlesystem/gui/statusbar.lua +++ b/sonic-radiance.love/scenes/battlesystem/gui/statusbar.lua @@ -6,16 +6,17 @@ local gui = require "game.modules.gui" local HUDBASE = 8 local HUDSEP = 152 -function StatusBar:new(actor) - self.actor = actor - self.hud = self.actor.scene.hud - self.assets = self.actor.assets +function StatusBar:new(fighter) + self.fighter = fighter + self.hud = fighter.turnSystem.hud + self.assets = self.fighter.assets - self.charid = self.actor.charid - self.stats = game.characters.list[self.charid].stats + self.charid = self.fighter.name + self.stats = self.fighter:getStats() + self.abstract = self.fighter.abstract - self.hp = self.stats.hp - self.pp = self.stats.pp + self.hp = self.abstract.hp + self.pp = self.abstract.pp self.tweens = TweenManager(self) end @@ -25,11 +26,11 @@ function StatusBar:update(dt) end function StatusBar:updateHP() - self.tweens:newTween(0, 0.3, {hp = game.characters.list[self.charid].stats.hp}, 'linear') + self.tweens:newTween(0, 0.3, {hp = self.abstract.hp}, 'linear') end function StatusBar:updatePP() - self.tweens:newTween(0, 0.3, {pp = game.characters.list[self.charid].stats.pp}, 'linear') + self.tweens:newTween(0, 0.3, {pp = self.abstract.pp}, 'linear') end function StatusBar:drawEmblem(x, y) @@ -41,8 +42,8 @@ function StatusBar:drawEmblem(x, y) end function StatusBar:draw() - local x = HUDBASE + (self.actor.charnumber-1)*HUDSEP - local y = self.actor.scene.hud:getPlayerHUDPosition() + local x = HUDBASE + (self.fighter.id-1)*HUDSEP + local y = self.hud:getPlayerHUDPosition() self:drawEmblem(x, y) self.assets.images["statusbar"]:draw(x+12, y-6) @@ -63,7 +64,7 @@ function StatusBar:draw() love.graphics.print(math.floor(self.hp) .. "/" .. hpmax, x+34, y+5) love.graphics.print(math.floor(self.pp) .. "/" .. ppmax, x+28, y+17) - local lvl = game.characters.list[self.charid].stats.level + local lvl = self.abstract.level if lvl < 100 then lvl = "0" .. lvl diff --git a/sonic-radiance.love/scenes/battlesystem/init.lua b/sonic-radiance.love/scenes/battlesystem/init.lua index 0e99bc9..94573aa 100644 --- a/sonic-radiance.love/scenes/battlesystem/init.lua +++ b/sonic-radiance.love/scenes/battlesystem/init.lua @@ -6,8 +6,6 @@ local World = require "scenes.battlesystem.world" local MenuSystem = require "scenes.battlesystem.menu" local Turns = require "scenes.battlesystem.controllers" -local HUD = require "scenes.battlesystem.gui.hud" - local VictoryScreen = require "scenes.battlesystem.screens.victory" function BattleSystem:new() @@ -15,8 +13,8 @@ function BattleSystem:new() self.assets:batchImport("scenes.battlesystem.assets") - self.assets:setMusic("assets/music/battle1.mp3") - self.assets:playMusic() + --self.assets:setMusic("assets/music/battle1.mp3") + --self.assets:playMusic() self:initManagers() @@ -32,17 +30,13 @@ function BattleSystem:initManagers() self.world = World(self) self.menu = MenuSystem(self) self.turns = Turns(self) - - self.hud = HUD(self) end function BattleSystem:startBattle() self.turns:startBattle() - self.hud:movePlayerHUD(true) end function BattleSystem:finishBattle() - self.hud:movePlayerHUD(false) self.assets:setMusic("assets/music/victory.mp3") self.assets:playMusic() self.screen = VictoryScreen(self) @@ -58,7 +52,6 @@ end function BattleSystem:update(dt) self.world:update(dt) self.turns:update(dt) - self.hud:update(dt) if (self.screen ~= nil) then self.screen:update(dt) end @@ -66,7 +59,7 @@ end function BattleSystem:draw() self.world:draw() - self.hud:draw() + self.turns:draw() if (self.screen ~= nil) then self.screen:draw() end diff --git a/sonic-radiance.love/scenes/battlesystem/map.lua b/sonic-radiance.love/scenes/battlesystem/map.lua deleted file mode 100644 index 006ee05..0000000 --- a/sonic-radiance.love/scenes/battlesystem/map.lua +++ /dev/null @@ -1,170 +0,0 @@ -local Map = Object:extend() - -local maputils = require "scenes.battlesystem.utils" -local TweenManager = require "game.modules.tweenmanager" - -local DURATION = 0.66 -local OPACITY_MIN = 0 -local OPACITY_MAX = 0.75 - -function Map:new(world, type, terrain) - self.world = world - self.assets = self.world.assets - self.scene = self.world.scene - - self.datas = {} - self.datas.type = type or "city" - self.datas.terrains = terrain or maputils.newEmptyMap() - - self.tweens = TweenManager(self) - self.effectOpacity = OPACITY_MIN - self:increaseOpacity() - - local zones = require "datas.gamedata.maps.shoot.zones" - local datas = zones[self.datas.type] - self.datas.background = datas.background - self.datas.tiles = datas.tiles - self.datas.borders = datas.borders - - local backpath = "assets/backgrounds/parallax/" .. self.datas.background - self.assets:addImage("back1", backpath .. "-back.png") - self.assets:addImage("back2", backpath .. "-fore.png") - self.assets:addImage("cliff", backpath .. "-cliff.png") -end - --- GET FUNCTIONS --- Get information from the map - -function Map:getTerrain(x, y) - if self.datas.terrains[y] ~= nil then - return self.datas.terrains[y][x] - else - return nil - end -end - -function Map:isInGrid(x, y) - return ( self:getTerrain(x, y) ~= nil ) -end - -function Map:update(dt) - self.tweens:update(dt) -end - --- OPACITY FUNCTIONS --- Simple functions to work on opacity - -function Map:decreaseOpacity() - self.tweens:newTween(0, DURATION/2, {effectOpacity = OPACITY_MIN}, "inExpo") - self.tweens:newTimer(DURATION/2, "increaseOpacity") -end - -function Map:increaseOpacity() - self.tweens:newTween(0, DURATION/2, {effectOpacity = OPACITY_MAX}, "inExpo") - self.tweens:newTimer(DURATION/2, "decreaseOpacity") -end - -function Map:timerResponse(timer) - if timer == "increaseOpacity" then - self:increaseOpacity() - elseif timer == "decreaseOpacity" then - self:decreaseOpacity() - end -end - --- DRAW FUNCTIONS --- Draw the battle map - -function Map:draw(activeGrid, effectGrid) - self:drawBackgrounds() - self:drawBorders() - self:drawTerrains(activeGrid) - if (effectGrid ~= nil) then - self:drawEffectGrid(effectGrid) - end -end - -function Map:drawBackgrounds() - - local w, _ = core.screen:getDimensions() - - local w2, h2 = self.assets.images["back1"]:getDimensions() - local imax = math.ceil(w / w2) + 1 - for i=1, imax do - self.assets.images["back1"]:draw((i-1)*w2, 0, 0, 1, 1) - end - - local w2, h2 = self.assets.images["back2"]:getDimensions() - local imax = math.ceil(w / w2) + 1 - for i=1, imax do - self.assets.images["back2"]:draw((i-1)*w2, maputils.CONST.STARTY-h2, 0, 1, 1) - end - -end - -function Map:drawBorders() - local border = self.datas.borders + 1 - for i=1, 7 do - self.assets.tileset["borders"]:drawTile(border, (i-1)*80, maputils.CONST.STARTY-10 , 0, 1, 1) - self.assets.tileset["borders"]:drawTile(border, (i-1)*80, maputils.CONST.STARTY+20*7, 0, 1, 1) - end -end - -function Map:drawTerrains(activeGrid) - local vl, vhd, vd = 1, .7, .5 - local isActive = (activeGrid ~= nil) - - - for i=1, 7 do - for j= -2, 17 do - local k = 1 + ((i + j) % 2) - - local terrain = self:getTerrain(j, i) - local x, y = maputils.gridToPixel(j, i, false) - - if (terrain ~= nil) then - if (isActive) then - if (activeGrid[i][j] == 1) then - love.graphics.setColor(vl, vl, vl, 1) - else - love.graphics.setColor(vhd, vhd, vhd, 1) - end - else - love.graphics.setColor(vl, vl, vl, 1) - end - - self:drawTile(x, y, terrain, k) - else - love.graphics.setColor(vd, vd, vd, 1) - self:drawTile(x, y, 0, k) - end - end - end - - love.graphics.setColor(1, 1, 1, 1) -end - -function Map:drawTile(x, y, type, variant) - if type == 0 then - local tiles = self.datas.tiles*2 + variant - self.assets.tileset["normaltiles"]:drawTile(tiles, x, y) - else - self.assets.tileset["sptiles"]:drawTile(type, x, y) - end -end - -function Map:drawEffectGrid(effectGrid) - for i=1,7 do - for j=1,17 do - if (effectGrid[i][j] == 1) then - local x, y = maputils.gridToPixel(j, i) - love.graphics.setColor(1, 1, 1, self.effectOpacity) - self.assets.images["emptytile"]:draw(x, y) - love.graphics.setColor(1, 1, 1, 1) - end - end - end -end - - -return Map diff --git a/sonic-radiance.love/scenes/battlesystem/menu.lua b/sonic-radiance.love/scenes/battlesystem/menu.lua index 0d1f8a3..3741a7c 100644 --- a/sonic-radiance.love/scenes/battlesystem/menu.lua +++ b/sonic-radiance.love/scenes/battlesystem/menu.lua @@ -10,39 +10,39 @@ local SubMenuWidget = BattleWidget:extend() local BackMenuWidget = BattleWidget:extend() local SkillWidget = BattleWidget:extend() -local MENUPOS_X1, MENUPOS_X2, MENUPOS_Y = 32, 32, 110 -local MENU_WIDTH, MENU_ITEM_HEIGHT = 148, 17 +local MENUPOS_X1, MENUPOS_X2, MENUPOS_Y = 96, 32, 96 +local MENU_WIDTH, MENU_ITEM_HEIGHT = 180, 17 local MENU_ITEM_NUMBER = 6 function MenuConstructor:new( controller ) - self.controller = controller + self.scene = controller end function MenuConstructor:reconstruct(character) - self.controller.menusystem:reset() + core.debug:print("cbs/menu", "Reconstructing the menu") + self.scene.menusystem:reset() self:build(character) - self.controller.menusystem:switchMenu("BaseMenu") + self.scene.menusystem:switchMenu("BaseMenu") end function MenuConstructor:build(character) + core.debug:print("cbs/menu", "Building the menu") self:buildBaseMenu(character) self:buildSkillMenu(character) self:buildObjectMenu(character) - self.controller.menusystem:setSoundFromSceneAssets("mBeep") + self.scene.menusystem:setSoundFromSceneAssets("mBeep") + self.scene.menusystem:activate() end function MenuConstructor:buildBaseMenu(character) - CharacterMenu(self.controller, "BaseMenu", MENUPOS_X1 - 16, MENUPOS_Y) + CharacterMenu(self.scene, "BaseMenu", MENUPOS_X1 - 16, MENUPOS_Y) ActionWidget(character, "BaseMenu", "attack") SubMenuWidget(character, "BaseMenu", "skills", "SkillMenu") SubMenuWidget(character, "BaseMenu", "objects", "ObjectMenu") ActionWidget(character, "BaseMenu", "defend") ActionWidget(character, "BaseMenu", "flee") - BackMenuWidget(character, "BaseMenu") - - self.controller.menusystem.menus["BaseMenu"]:setCancelWidget() end function MenuConstructor:set(currentCharacter) @@ -50,23 +50,23 @@ function MenuConstructor:set(currentCharacter) end function MenuConstructor:buildSkillMenu(character) - CharacterMenu(self.controller, "SkillMenu", MENUPOS_X1 - 16, MENUPOS_Y) - local list = game.characters:getSkillList(character.charid) + CharacterMenu(self.scene, "SkillMenu", MENUPOS_X1 - 16, MENUPOS_Y) + local list = character.abstract.skills for k, skill in pairs(list) do SkillWidget(character, "SkillMenu", skill.name, "") end SubMenuWidget(character, "SkillMenu", "back", "BaseMenu") - self.controller.menusystem.menus["SkillMenu"]:setCancelWidget() + self.scene.menusystem.menus["SkillMenu"]:setCancelWidget() end function MenuConstructor:buildObjectMenu(character) - CharacterMenu(self.controller, "ObjectMenu", MENUPOS_X1 - 16, MENUPOS_Y) + CharacterMenu(self.scene, "ObjectMenu", MENUPOS_X1 - 16, MENUPOS_Y) - CharacterMenu(self.controller, "MedMenu", MENUPOS_X1 - 16, MENUPOS_Y) - CharacterMenu(self.controller, "RingMenu", MENUPOS_X1 - 16, MENUPOS_Y) - CharacterMenu(self.controller, "WispMenu", MENUPOS_X1 - 16, MENUPOS_Y) - CharacterMenu(self.controller, "OtherMenu", MENUPOS_X1 - 16, MENUPOS_Y) + CharacterMenu(self.scene, "MedMenu", MENUPOS_X1 - 16, MENUPOS_Y) + CharacterMenu(self.scene, "RingMenu", MENUPOS_X1 - 16, MENUPOS_Y) + CharacterMenu(self.scene, "WispMenu", MENUPOS_X1 - 16, MENUPOS_Y) + CharacterMenu(self.scene, "OtherMenu", MENUPOS_X1 - 16, MENUPOS_Y) SubMenuWidget(character, "ObjectMenu", "heal", "MedMenu") @@ -81,12 +81,12 @@ function MenuConstructor:buildObjectMenu(character) SubMenuWidget(character, "OtherMenu", "back", "ObjectMenu") - self.controller.menusystem.menus["ObjectMenu"]:setCancelWidget() + self.scene.menusystem.menus["ObjectMenu"]:setCancelWidget() - self.controller.menusystem.menus["MedMenu"]:setCancelWidget() - self.controller.menusystem.menus["RingMenu"]:setCancelWidget() - self.controller.menusystem.menus["WispMenu"]:setCancelWidget() - self.controller.menusystem.menus["OtherMenu"]:setCancelWidget() + self.scene.menusystem.menus["MedMenu"]:setCancelWidget() + self.scene.menusystem.menus["RingMenu"]:setCancelWidget() + self.scene.menusystem.menus["WispMenu"]:setCancelWidget() + self.scene.menusystem.menus["OtherMenu"]:setCancelWidget() end @@ -102,7 +102,7 @@ function CharacterMenu:new(scene, name, x, y) local w, h = MENU_WIDTH, MENU_ITEM_NUMBER * MENU_ITEM_HEIGHT CharacterMenu.super.new(self, scene.menusystem, name, x, y, w, h, MENU_ITEM_NUMBER) self.cursorTexture = love.graphics.newImage("assets/gui/cursor-menulist.png") - self.cursorTransition = 1 + self.cursorTransition = 0 end function CharacterMenu:update(dt) @@ -122,7 +122,27 @@ end function CharacterMenu:drawCursor() local addition = 17 - love.graphics.draw(self.cursorTexture, self.x + 4, self.y + (self.cursorTransition) * addition ) + local x = self.x + 4 + ((self.cursorTransition) * addition * 0.5) + local y = self.y + ((self.cursorTransition) * addition) + love.graphics.draw(self.cursorTexture, x, y) +end + +function CharacterMenu:draw() + self:updateView() + local widgety = self.y + local widgetx = self.x + for i,v in ipairs(self.widget.list) do + if (i >= self.view.firstSlot) and (i < self.view.firstSlot + self.view.slotNumber) then + v:draw(widgetx, widgety, self.w, self.widget.h) + if self.widget.selected == i and self:haveFocus() == true then + v:drawSelected(widgetx, widgety, self.w, self.widget.h) + else + v:draw(widgetx, widgety, self.w, self.widget.h) + end + widgety = widgety + self.widget.h + widgetx = widgetx + (self.widget.h/2) + end + end end -- WIDGETS @@ -149,7 +169,7 @@ end function BattleWidget:getControllers(character, menu_name) self.character = character or core.debug:error("cbs/widget", "character must not be nil") - self.scene = self.character.scene + self.scene = self.character.turnSystem.scene self.assets = self.character.assets self.menusystem = self.scene.menusystem @@ -167,26 +187,7 @@ function BattleWidget:update(dt) end function BattleWidget:selectAction() - self:setActiveGrid() - self:setEffectGrid() -end - -function BattleWidget:setActiveGrid() - if (self:haveActiveGrid()) then - local ox, oy, shape, size, idk = self:getActiveGrid() - self.scene.world:setActiveGrid(ox, oy, shape, size, idk) - else - self.scene.world:resetActiveGrid() - end -end - -function BattleWidget:setEffectGrid() - if (self:haveEffectGrid()) then - local ox, oy, shape, size, idk = self:getEffectGrid() - self.scene.world:setEffectGrid(ox, oy, shape, size, idk) - else - self.scene.world:resetEffectGrid() - end + -- Rien de base, à voir ensuite comment je gère end function BattleWidget:drawCanvas() @@ -197,10 +198,12 @@ function BattleWidget:drawCanvas() local midAsset = love.graphics.newQuad(16, 0, 1, sh, sw, sh) local endAsset = love.graphics.newQuad(sw-16, 0, 16, sh, sw, sh) - love.graphics.draw(asset, startAsset, 0, (self.height - 13) / 2) - love.graphics.draw(asset, endAsset, self.width-16, (self.height - 13) / 2) + local trueWidth = self.width - 32 - local iterations = self.width-32 + love.graphics.draw(asset, startAsset, 0, (self.height - 13) / 2) + love.graphics.draw(asset, endAsset, trueWidth-16, (self.height - 13) / 2) + + local iterations = trueWidth-32 for i=0,iterations do love.graphics.draw(asset, midAsset, 16+i, (self.height - 13) / 2) @@ -210,42 +213,23 @@ function BattleWidget:drawCanvas() h = math.floor(self.height / 2) - (self.font:getHeight() / 2) love.graphics.setColor(0, 0, 0, .8) self.font:print(self.label, 17, h, "left") - self.font:print(self.label2, self.width - 8, h, "right") + self.font:print(self.label2, trueWidth - 8, h, "right") utils.graphics.resetColor() self.font:print(self.label, 16, h, "left") - self.font:print(self.label2, self.width - 9, h, "right") + self.font:print(self.label2, trueWidth - 9, h, "right") end function BattleWidget:action() - self.scene.world:resetActiveGrid() - self.scene.world:resetEffectGrid() + self.scene:flushKeys() + self.scene.menusystem:deactivate() self:sendCharacterData() - - self.scene:flushKeys() - self.scene.menusystem:reset() end -- External functions -function BattleWidget:haveActiveGrid() - return false -end - -function BattleWidget:getActiveGrid() - return 0, 0, "point", 0, 0 -end - -function BattleWidget:haveEffectGrid() - return false -end - -function BattleWidget:getEffectGrid() - return 0, 0, "point", 0, 0 -end - function BattleWidget:sendCharacterData() - self.character:receiveSignal() + self.character:doNothing() end -- ActionWidget @@ -256,16 +240,8 @@ function ActionWidget:new(character, menu_name, action) ActionWidget.super.new(self, character, menu_name, action, "") end -function ActionWidget:haveEffectGrid() - return (self.actionType == "attack") -end - -function ActionWidget:getEffectGrid() - return self.character.x + self.character.direction, self.character.y, "point", 1, 1 -end - function ActionWidget:sendCharacterData() - self.character:receiveSignal(self.actionType) + self.character:doBasicAction(self.actionType) end -- SubMenuWidget @@ -318,58 +294,14 @@ function SkillWidget:new(character, menu_name, skill) SkillWidget.super.new(self, character, menu_name, self.skillname, "-" .. label2, "skills") end -function SkillWidget:selectAction() - if self.skilldata ~= nil then - SkillWidget.super.selectAction(self) - else - self.scene.world:resetActiveGrid() - self.scene.world:resetEffectGrid() - end -end - -function SkillWidget:haveActiveGrid() - return (self.skilldata.target ~= nil) -end - -function SkillWidget:haveEffectGrid() - return ((self.skilldata.target == nil) and (self.skilldata.effectArea ~= nil)) -end - -function SkillWidget:getActiveGrid() - local x = self.character.x + self.skilldata.target[1] - local y = self.character.y + self.skilldata.target[2] - local shape = self.skilldata.target[3] - local size = self.skilldata.target[4] - local direction = self.character.direction - - return x, y, shape, size, direction -end - -function SkillWidget:getEffectGrid() - local x = self.character.x + self.skilldata.effectArea[1] - local y = self.character.y + self.skilldata.effectArea[2] - local shape = self.skilldata.effectArea[3] - local size = self.skilldata.effectArea[4] - local direction = self.character.direction - - return x, y, shape, size, direction -end - function SkillWidget:sendCharacterData() if self.skilldata ~= nil then - if self:haveActiveGrid() then - local x, y, shape, size, direction = self:getActiveGrid() - self.scene.world.cursor:setGridIgnoreActor(x, y, shape, size, direction) - self.scene.world.cursor:set(self.character.x, self.character.y, "skill", self.skillname) - self.assets.sfx["mSelect"]:play() - else - self.assets.sfx["mSelect"]:play() - self.character:useSkill(self.skillname, self.character.x, self.character.y) - end + self.assets.sfx["mSelect"]:play() + self.character:useSkill(self.skillname) else core.debug:warning("cbs/menu", "skill " .. self.skillname .. " doesn't exist") - self.character:receiveSignal("none") + self.character:doNothing() self.assets.sfx["mError"]:play() end diff --git a/sonic-radiance.love/scenes/battlesystem/utils.lua b/sonic-radiance.love/scenes/battlesystem/utils.lua index 5f2455a..8c940a0 100644 --- a/sonic-radiance.love/scenes/battlesystem/utils.lua +++ b/sonic-radiance.love/scenes/battlesystem/utils.lua @@ -5,113 +5,18 @@ maputils.CONST = {} maputils.CONST.STARTX = -8 maputils.CONST.STARTY = 90 - -function maputils.newEmptyMap() - return { - {00,00,00,00,00,00,00,00,00,00,00,00}, - {00,00,00,00,00,00,00,00,00,00,00,00}, - {00,00,00,00,00,00,00,00,00,00,00,00}, - {00,00,00,00,00,00,00,00,00,00,00,00}, - {00,00,00,00,00,00,00,00,00,00,00,00}, - {00,00,00,00,00,00,00,00,00,00,00,00}, - {00,00,00,00,00,00,00,00,00,00,00,00}, - } -end - -function maputils.newFullMap() - return { - {01,01,01,01,01,01,01,01,01,01,01,01}, - {01,01,01,01,01,01,01,01,01,01,01,01}, - {01,01,01,01,01,01,01,01,01,01,01,01}, - {01,01,01,01,01,01,01,01,01,01,01,01}, - {01,01,01,01,01,01,01,01,01,01,01,01}, - {01,01,01,01,01,01,01,01,01,01,01,01}, - {01,01,01,01,01,01,01,01,01,01,01,01}, - } -end - -function maputils.isInMask(x, y, ox, oy, shape, size, direction) - local direction = direction or 1 - local shape = shape or "point" - if shape == "point" then - return ((x == ox) and (y == oy)) - elseif shape == "square" then - local x1 = ox - math.floor(size/2) - local x2 = ox + math.ceil(size/2) - - local y1 = oy - math.floor(size/2) - local y2 = oy + math.ceil(size/2) - return ((x >= x1) and (x <= x2) and (y >= y1) and (y <= y2)) - elseif shape == "circle" then - local lenght = utils.math.pointDistance(x, y, ox, oy) - return (lenght <= size) - elseif shape == "fullheight" then - local x2 = ox + (size*direction) - return ((x >= ox) and (x <= x2)) - elseif shape == "fullwidth" then - local y2 = oy + (size*direction) - return ((y >= oy) and (y <= y2)) - elseif shape == "line" then - local x2 = ox + (size*direction) - return ((y == oy) and (x >= ox) and (x <= x2)) - elseif shape == "column" then - local y2 = oy + (size*direction) - return ((x == ox) and (y >= oy) and (y <= y2)) - elseif shape == "everything" then - return true - else - if shape == nil then - shape = "nil" - end - core.debug:warning("maputils", "shape " .. shape .. " doesn't exist") - end -end - -function maputils.maskToMap(ox, oy, shape, size, direction) - local map = maputils.newEmptyMap() - - for i, line in ipairs(map) do - for j, case in ipairs(line) do - local isInMask = maputils.isInMask(j, i, ox, oy, shape, size, direction) - if (isInMask) then - map[i][j] = 1 - else - map[i][j] = 0 - end - end - end - - return map -end - -function maputils.gridToPixel(x, y, center) - local pixelx, pixely - local center = center or false - local x, y = x, y - - if (center) then - x = x + .5 - y = y + .5 - end - - pixelx = maputils.CONST.STARTX + ((x-1) * 31) + ((y-1) * 10) - pixely = maputils.CONST.STARTY + ((y-1) * 20) - - return math.floor(pixelx), math.floor(pixely) -end - function maputils.sortBattlers(a, b) - local astats = a.actor:getStats() - local bstats = b.actor:getStats() + local astats = a.fighter:getStats() + local bstats = b.fighter:getStats() local aspeed = astats.speed / 1.5 * a.number local bspeed = bstats.speed / 1.5 * b.number if (aspeed == bspeed) then - if (a.actor.isHero == b.actor.isHero) then - return (a.actor.id > b.actor.id) + if (a.fighter.isHero == b.fighter.isHero) then + return (a.fighter.id > b.fighter.id) else - return a.actor.isHero + return a.fighter.isHero end else return (aspeed > bspeed) diff --git a/sonic-radiance.love/scenes/battlesystem/world.lua b/sonic-radiance.love/scenes/battlesystem/world.lua index c3d586d..75a5907 100644 --- a/sonic-radiance.love/scenes/battlesystem/world.lua +++ b/sonic-radiance.love/scenes/battlesystem/world.lua @@ -1,8 +1,7 @@ local World = Object:extend() local maputils = require "scenes.battlesystem.utils" -local Map = require "scenes.battlesystem.map" -local Cursor = require "scenes.battlesystem.cursor" +local Map = require "game.modules.drawing.parallaxBackground" local TweenManager = require "game.modules.tweenmanager" @@ -12,6 +11,9 @@ local POSITIONS = { {x = 2, y = 6}, } +local HEIGHT = 5 +local BORDER_BOTTOM = 2 + local gui = require "game.modules.gui" -- INIT FUNCTIONS @@ -26,35 +28,11 @@ function World:new(scene, battlefile) self.actors = {} self.globalID = 0 - self.battlers = {} - - self.heroNumber = 0 - self.ennNumber = 0 - - self.map = Map(self, "city") - self.cursor = Cursor(self) - - self:resetActiveGrid() - self:resetEffectGrid() - - self:initHeroes() - self:initEnnemies() + self.map = Map(scene, HEIGHT, BORDER_BOTTOM, "city") self.isBattleActive = false end -function World:initHeroes(battlefile) - for i, hero in ipairs(game.characters.team) do - self:addHero(POSITIONS[i].x, POSITIONS[i].y, hero, i) - end -end - -function World:initEnnemies(battlefile) - self:addEnnemy(10, 3, "motobug") - self:addEnnemy(10, 5, "motobug") - self:addEnnemy(9, 4, "motobug") -end - function World:registerActor(actor) self.globalID = self.globalID + 1 @@ -90,78 +68,6 @@ function World:getActorInCase(x, y, notThisActor) return nil end --- BATTLER FUNCTIONS --- Handle the actual battle participants - -function World:addHero(x, y, id) - self.heroNumber = self.heroNumber + 1 - local hero = self.obj.Hero(self, x, y, id, self.heroNumber) - - table.insert(self.battlers, hero) -end - -function World:addEnnemy(x, y, id) - self.ennNumber = self.ennNumber + 1 - local enn = self.obj.Ennemy(self, x, y, id, self.ennNumber) - - table.insert(self.battlers, enn) -end - -function World:destroyBattler(actorToDestroy) - -- remove the actor from the battler liste - for i, actor in ipairs(self.battlers) do - if actor == actorToDestroy then - table.remove(self.battlers, i) - end - end - - -- Also remove all actions related to the actor - for i, action in ipairs(self.actionlist) do - if action.actor == actorToDestroy then - table.remove(self.actionlist, i) - end - end -end - -function World:generateActionList() - self.actionlist = {} - - for i,v in ipairs(self.battlers) do - for i=1, v.actionPerTurn do - local action = {} - action.actor = v - action.number = i - table.insert(self.actionlist, action) - end - end - - return self.actionlist -end - -function World:countHeroes() - local count = 0 - - for i, battler in ipairs(self.battlers) do - if (battler.isHero) then - count = count + 1 - end - end - - return count -end - -function World:countEnnemies() - local count = 0 - - for i, battler in ipairs(self.battlers) do - if (battler.isEnnemy) then - count = count + 1 - end - end - - return count -end - -- UPDATE FUNCTION -- Update all actors @@ -169,53 +75,19 @@ function World:update(dt) for i, actor in ipairs(self.actors) do actor:update(dt) end - - self.cursor:update(dt) - self.map:update(dt) -end - -function World:finishBattle() - self.isBattleActive = false - self.actionlist = {} - self.scene:finishBattle() end function World:sendSignalToCurrentBattler(signal, subSignal) self.scene.turns:sendSignalToCurrentBattler(signal, subSignal) end --- ACTIVEGRID FUNCTIONS --- Help to handle the activeGrid system - -function World:resetActiveGrid() - self.activeGrid = maputils.newFullMap() -end - -function World:setActiveGrid(ox, oy, shape, size, direction) - self.activeGrid = maputils.maskToMap(ox, oy, shape, size, direction) -end - -function World:setActiveGridFromGrid(grid) - self.activeGrid = grid -end - -function World:resetEffectGrid() - self.effectGrid = maputils.newEmptyMap() -end - -function World:setEffectGrid(ox, oy, shape, size, direction) - self.effectGrid = maputils.maskToMap(ox, oy, shape, size, direction) -end - -- DRAW FUNCTION -- Draw the world function World:draw() - self.map:draw(self.activeGrid, self.effectGrid) - self.cursor:drawBottom() + self.map:draw() self:drawShadows() self:drawActors() - self.cursor:drawTop() end function World:drawActors() diff --git a/sonic-radiance.love/scenes/debug/commons/assets.lua b/sonic-radiance.love/scenes/debug/commons/assets.lua new file mode 100644 index 0000000..244881b --- /dev/null +++ b/sonic-radiance.love/scenes/debug/commons/assets.lua @@ -0,0 +1,51 @@ +return { + ["tilesets"] = { + {"charicons", "assets/sprites/characters/charicons"}, + {"normaltiles", "assets/backgrounds/normaltile"}, + {"sptiles", "assets/backgrounds/specialtile"}, + {"borders", "assets/backgrounds/borders"}, + }, + ["sprites"] = { + {"cursorground", "assets/gui/cursor/ground"}, + {"hitGFX", "assets/sprites/gfx/hit"}, + }, + ["textures"] = { + {"menucursor", "assets/gui/cursor-menulist.png"}, + {"statusbar", "assets/gui/status_bar.png"}, + {"cursorpeak", "assets/gui/cursor/peak.png"}, + {"actorsShadow", "assets/sprites/shadow.png"}, + {"emptytile", "assets/backgrounds/tilemask.png"}, + + {"e_speedster", "assets/gui/emblem_speedster.png"}, + {"e_technic", "assets/gui/emblem_technic.png"}, + {"e_power", "assets/gui/emblem_power.png"}, + + {"m_speedster", "assets/gui/emblem_speedster_mask.png"}, + {"m_technic", "assets/gui/emblem_technic_mask.png"}, + {"m_power", "assets/gui/emblem_power_mask.png"}, + + {"hudturn", "assets/gui/strings/hudturn.png"}, + {"battlecompleted", "assets/gui/strings/battle_completed.png" } + }, + ["fonts"] = { + {"small", "assets/gui/fonts/PixelOperator.ttf", 16}, + {"victory", "assets/gui/fonts/vipnagorgialla.ttf", 12} + }, + ["imagefonts"] = { + {"hudnbrs", "assets/gui/fonts/hudnumbers"}, + {"hudnbrs_small", "assets/gui/fonts/hudsmallnumbers"}, + }, + ["sfx"] = { + {"hit", "assets/sfx/hit.wav"}, + {"hitconnect", "assets/sfx/hitconnect.wav"}, + {"jump", "assets/sfx/jump.wav"}, + {"woosh", "assets/sfx/woosh.wav"}, + {"spincharge", "assets/sfx/spincharge.wav"}, + {"spinrelease", "assets/sfx/spinrelease.wav"}, + + {"mBack", "assets/sfx/menus/back.wav"}, + {"mBeep", "assets/sfx/menus/beep.wav"}, + {"mSelect", "assets/sfx/menus/select.wav"}, + {"mError", "assets/sfx/menus/error.wav"}, + } +} diff --git a/sonic-radiance.love/scenes/debug/commons/menu.lua b/sonic-radiance.love/scenes/debug/commons/menu.lua new file mode 100644 index 0000000..8f03803 --- /dev/null +++ b/sonic-radiance.love/scenes/debug/commons/menu.lua @@ -0,0 +1,83 @@ +local menu = {} + +local ListBox = require "core.modules.menusystem.listbox" +local Widget = require "core.modules.menusystem.widgets" + +menu.DebugMenu = ListBox:extend() +menu.DebugWidget = Widget.Text:extend() +menu.SubMenuWidget = menu.DebugWidget:extend() +menu.SceneWidget = menu.DebugWidget:extend() + +local CONST = {} +CONST.MENU = {} +CONST.MENU.X = 16 +CONST.MENU.Y = 48 +CONST.MENU.W = 424/2 +CONST.MENU.ITEM_NUMBER = 8 +CONST.MENU.ITEM_HEIGHT = 18 + +-- Basic menu structure +function menu.DebugMenu:new(scene, name) + self.scene = scene + local x, y = CONST.MENU.X, CONST.MENU.Y + local w, h = CONST.MENU.W, CONST.MENU.ITEM_NUMBER * CONST.MENU.ITEM_HEIGHT + menu.DebugMenu.super.new(self, scene.menusystem, name, x, y, w, h, CONST.MENU.ITEM_NUMBER) +end + +function menu.DebugMenu:drawCursor() + +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 + +-- Widget +function menu.DebugWidget:new(scene, menu_name, label) + local font = scene.assets.fonts["small"] + self.scene = scene + local widgetMenu = scene.menusystem.menus[menu_name] + menu.DebugWidget.super.new(self, widgetMenu, font, label) +end + +function menu.DebugWidget:drawCanvas() + local h = math.floor(self.height / 2) - (self.font:getHeight() / 2) + self.font:draw(self.label, 8, h, -1, "left") +end + +function menu.DebugWidget:drawSelected(x, y, w, h) + love.graphics.setColor(1, 1, 0, 1) + self:draw(x, y, w, h) + utils.graphics.resetColor() +end + +-- SubMenuWidget +function menu.SubMenuWidget:new(scene, menu_name, newmenu, name) + menu.SubMenuWidget.super.new(self, scene, menu_name, name) + self.newmenu = newmenu or "BaseMenu" +end + +function menu.SubMenuWidget:action() + self.scene.menusystem:switchMenu(self.newmenu) +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() + if (self.sceneArgument ~= nil) then + self.newScene(self.sceneArgument) + else + self.newScene() + end +end + + +return menu diff --git a/sonic-radiance.love/scenes/debug/init.lua b/sonic-radiance.love/scenes/debug/init.lua new file mode 100644 index 0000000..f255393 --- /dev/null +++ b/sonic-radiance.love/scenes/debug/init.lua @@ -0,0 +1,6 @@ +return { + menu = require "scenes.debug.menu", + viewers = { + battleBack = require "scenes.debug.viewers.battleBack" + } +} diff --git a/sonic-radiance.love/scenes/debug/menu/infopanel/character.lua b/sonic-radiance.love/scenes/debug/menu/infopanel/character.lua new file mode 100644 index 0000000..fd5fe59 --- /dev/null +++ b/sonic-radiance.love/scenes/debug/menu/infopanel/character.lua @@ -0,0 +1,24 @@ +local Parent = require "scenes.debug.menu.infopanel.parent" +local CharacterPanel = Parent:extend() + +function CharacterPanel:new(character) + CharacterPanel.super.new(self) + self.character = character +end + +function CharacterPanel:drawContent(x, y) + local debugString = "# " .. 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 .. " / " .. self.character.stats.hpmax .. "\n" + local debugString = debugString .. "PP: " .. self.character.pp .. " / " .. self.character.stats.ppmax .. "\n" + local debugString = debugString .. "ATK: " .. self.character.stats.attack + local debugString = debugString .. " DEF: " .. self.character.stats.defense + local debugString = debugString .. " SPD: " .. self.character.stats.speed .. "\n" + local debugString = debugString .. "POW: " .. self.character.stats.power + local debugString = debugString .. " MND: " .. self.character.stats.mind + local debugString = debugString .. " TEK: " .. self.character.stats.technic .. "\n" + + love.graphics.print(debugString, x, y) +end + +return CharacterPanel diff --git a/sonic-radiance.love/scenes/debug/menu/infopanel/gamedata.lua b/sonic-radiance.love/scenes/debug/menu/infopanel/gamedata.lua new file mode 100644 index 0000000..69de07d --- /dev/null +++ b/sonic-radiance.love/scenes/debug/menu/infopanel/gamedata.lua @@ -0,0 +1,16 @@ +local Parent = require "scenes.debug.menu.infopanel.parent" +local GamePanel = Parent:extend() + +function GamePanel:new() + GamePanel.super.new(self) +end + +function GamePanel:drawContent(x, y) + local debugString = "# Save system data" .. "\n" + debugString = debugString .. "Current slot: " .. game.slot .. " / " .. game.slotNumber .. "\n" + debugString = debugString .. "Gametime: " .. game:getTimeString() .. "\n" + + love.graphics.print(debugString, x, y) +end + +return GamePanel diff --git a/sonic-radiance.love/scenes/debug/menu/infopanel/init.lua b/sonic-radiance.love/scenes/debug/menu/infopanel/init.lua new file mode 100644 index 0000000..d3b96a1 --- /dev/null +++ b/sonic-radiance.love/scenes/debug/menu/infopanel/init.lua @@ -0,0 +1,6 @@ +local folder = "scenes.debug.menu.infopanel." + +return { + Gamedata = require(folder .. "gamedata"), + Character = require(folder .. "character"), +} diff --git a/sonic-radiance.love/scenes/debug/menu/infopanel/parent.lua b/sonic-radiance.love/scenes/debug/menu/infopanel/parent.lua new file mode 100644 index 0000000..5fb56a4 --- /dev/null +++ b/sonic-radiance.love/scenes/debug/menu/infopanel/parent.lua @@ -0,0 +1,17 @@ +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) + love.graphics.draw(self.panelBackground, x, y) + self:drawContent(x+8, y+8) +end + +function ParentPanel:drawContent(x, y) + +end + +return ParentPanel diff --git a/sonic-radiance.love/scenes/debug/menu/init.lua b/sonic-radiance.love/scenes/debug/menu/init.lua new file mode 100644 index 0000000..189e9d4 --- /dev/null +++ b/sonic-radiance.love/scenes/debug/menu/init.lua @@ -0,0 +1,105 @@ +local Scene = require "core.modules.scenes" +local menu = require "scenes.debug.menu.menu" + +local DebugMenu = Scene:extend() +local panels = require "scenes.debug.menu.infopanel" + +function DebugMenu:new() + DebugMenu.super.new(self) + self.assets:batchImport("scenes.debug.commons.assets") + menu.commons.DebugMenu(self, "BaseMenu") + menu.commons.SceneWidget(self, "BaseMenu", scenes.title, "Launch Game") + self:buildBattleMenu() + self:buildOverworldMenu() + self:buildSaveMenu() + self:buildOtherMenu() + menu.commons.SceneWidget(self, "BaseMenu", scenes.options, "Options") + menu.ExitWidget(self, "BaseMenu") + + self.menusystem:activate() + self.menusystem:switchMenu("BaseMenu") + + self.panel = panels.Gamedata() +end + +function DebugMenu:buildOverworldMenu() + self:addSubMenu("overworld", "BaseMenu", "Overworld") + menu.commons.SceneWidget(self, "overworld", scenes.overworld, "Launch Overworld") + menu.commons.SubMenuWidget(self, "overworld", "BaseMenu", "Back") +end + +function DebugMenu:buildBattleMenu() + self:addSubMenu("combat", "BaseMenu", "Battle System") + menu.commons.SceneWidget(self, "combat", scenes.cbs, "Launch Battle") + menu.commons.SceneWidget(self, "combat", scenes.debug.viewers.battleBack, "Background Viewer") + + menu.commons.SubMenuWidget(self, "combat", "BaseMenu", "Back") +end + +function DebugMenu:buildSaveMenu() + self:addSubMenu("save", "BaseMenu", "Save System") + self:addSubMenu("characters", "save", "Characters") + for name, data in pairs(game.characters.list) do + self:addCharacterMenu(name, data) + end + + self:addSubMenu("load", "save", "Load Saves") + for i=1, game.slotNumber do + menu.LoadWidget(self, "load", i) + end + menu.SaveWidget(self, "save") + + + menu.commons.SubMenuWidget(self, "save", "BaseMenu", "Back") + menu.commons.SubMenuWidget(self, "characters", "save", "Back") + menu.commons.SubMenuWidget(self, "load", "save", "Back") +end + +function DebugMenu:addCharacterMenu(name, data) + self:addSubMenu(name, "characters", data.fullname, panels.Character, data) + menu.SubMenuWidget(self, name, "characters", "Back", panels.Gamedata, nil) +end + +function DebugMenu:buildOtherMenu() + self:addSubMenu("other", "BaseMenu", "Other gameplay") + self:addSubMenu("battle", "other", "Sonic Battle Maps") + local mapList = require "datas.gamedata.maps.battle" + for i, name in ipairs(mapList) do + local mapData = require("datas.gamedata.maps.battle." .. name) + local trueName = mapData.name + menu.commons.SceneWidget(self, "battle", scenes.test, trueName, name) + end + + menu.commons.SceneWidget(self, "other", scenes.test2, "Shadow Shot Maps") + + menu.commons.SubMenuWidget(self, "battle", "other", "Back") + menu.commons.SubMenuWidget(self, "other", "BaseMenu", "Back") +end + + +function DebugMenu:update(dt) + if (love.keyboard.isDown("space") and (not self.menusystem.isActive)) then + self.menusystem:activate() + end +end + +function DebugMenu:addSubMenu(submenu, parent, name, panel, panelArgument) + local parent = parent or "BaseMenu" + menu.commons.DebugMenu(self, submenu) + if (panel == nil) then + menu.commons.SubMenuWidget(self, parent, submenu, name .. " >") + else + menu.SubMenuWidget(self, parent, submenu, name .. " >", panel, panelArgument) + end +end + +function DebugMenu:draw() + if (self.menusystem.isActive) then + self.assets.fonts["small"]:print("## SONIC RADIANCE - DEBUG MENU ##", 424/2, 8, "center") + self.assets.fonts["small"]:print("v" .. game.version, 424 - 8, 240 - 22, "right") + + self.panel:draw(240, 48) + end +end + +return DebugMenu; diff --git a/sonic-radiance.love/scenes/debug/menu/menu.lua b/sonic-radiance.love/scenes/debug/menu/menu.lua new file mode 100644 index 0000000..0ba4c1c --- /dev/null +++ b/sonic-radiance.love/scenes/debug/menu/menu.lua @@ -0,0 +1,61 @@ +local commons = require "scenes.debug.commons.menu" +local menu = {} +menu.commons = commons +menu.ExitWidget = commons.DebugWidget:extend() +menu.ShowBackgroundWidget = commons.DebugWidget:extend() +menu.SaveWidget = commons.DebugWidget:extend() +menu.LoadWidget = commons.DebugWidget:extend() +menu.SubMenuWidget = commons.SubMenuWidget:extend() + +-- ExitWidget +function menu.ExitWidget:new(scene, menuName) + menu.ExitWidget.super.new(self, scene, menuName, "Exit") +end + +function menu.ExitWidget:action() + love.event.quit("000") +end + +-- ShowBackground +function menu.ShowBackgroundWidget:new(scene, menuName) + menu.ShowBackgroundWidget.super.new(self, scene, menuName, "Show Background") +end + +function menu.ShowBackgroundWidget:action() + self.scene.menusystem:deactivate() +end + +-- Save game +function menu.SaveWidget:new(scene, menuName) + menu.SaveWidget.super.new(self, scene, menuName, "Save game") +end + +function menu.SaveWidget:action() + game:write() +end + +-- Save game +function menu.LoadWidget:new(scene, menuName, slot) + menu.LoadWidget.super.new(self, scene, menuName, "Load file " .. slot) + self.slot = slot +end + +function menu.LoadWidget:action() + game:read(self.slot) +end + +-- Submenu +function menu.SubMenuWidget:new(scene, menu_name, newmenu, name, panel, panelArgument) + menu.SubMenuWidget.super.new(self, scene, menu_name, newmenu, name) + self.panel = panel + self.panelArgument = panelArgument +end + +function menu.SubMenuWidget:action() + self.scene.menusystem:switchMenu(self.newmenu) + self.scene.panel = self.panel(self.panelArgument) +end + + + +return menu diff --git a/sonic-radiance.love/scenes/debug/viewers/battleBack/init.lua b/sonic-radiance.love/scenes/debug/viewers/battleBack/init.lua new file mode 100644 index 0000000..e368bb4 --- /dev/null +++ b/sonic-radiance.love/scenes/debug/viewers/battleBack/init.lua @@ -0,0 +1,40 @@ +local Scene = require "core.modules.scenes" +local menu = require "scenes.debug.viewers.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("scenes.debug.commons.assets") + 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.debug.menu, "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 diff --git a/sonic-radiance.love/scenes/debug/viewers/battleBack/menu.lua b/sonic-radiance.love/scenes/debug/viewers/battleBack/menu.lua new file mode 100644 index 0000000..dd1230d --- /dev/null +++ b/sonic-radiance.love/scenes/debug/viewers/battleBack/menu.lua @@ -0,0 +1,18 @@ +local commons = require "scenes.debug.commons.menu" +local menu = {} +menu.commons = commons +menu.ShowBackgroundWidget = menu.commons.DebugWidget: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 diff --git a/sonic-radiance.love/scenes/init.lua b/sonic-radiance.love/scenes/init.lua index 64af5eb..d2e42d8 100644 --- a/sonic-radiance.love/scenes/init.lua +++ b/sonic-radiance.love/scenes/init.lua @@ -1,5 +1,9 @@ return { test = require "scenes.test_scene", + test2 = require "scenes.test_scene2", title = require "scenes.titlescreen", cbs = require "scenes.battlesystem", + debug = require "scenes.debug", + options = require "scenes.options", + overworld = require "scenes.overworld" } diff --git a/sonic-radiance.love/scenes/options/assets.lua b/sonic-radiance.love/scenes/options/assets.lua new file mode 100644 index 0000000..41efadb --- /dev/null +++ b/sonic-radiance.love/scenes/options/assets.lua @@ -0,0 +1,18 @@ +return { + ["sprites"] = { + {"cursorground", "assets/gui/cursor/ground"}, + {"hitGFX", "assets/sprites/gfx/hit"}, + }, + ["textures"] = { + {"background", "assets/backgrounds/options.png"} + }, + ["imagefonts"] = { + {"medium", "assets/gui/fonts/SA2font"}, + }, + ["sfx"] = { + {"mBack", "assets/sfx/menus/back.wav"}, + {"mBeep", "assets/sfx/menus/beep.wav"}, + {"mSelect", "assets/sfx/menus/select.wav"}, + {"mError", "assets/sfx/menus/error.wav"}, + } +} diff --git a/sonic-radiance.love/scenes/options/init.lua b/sonic-radiance.love/scenes/options/init.lua new file mode 100644 index 0000000..281f30f --- /dev/null +++ b/sonic-radiance.love/scenes/options/init.lua @@ -0,0 +1,111 @@ +local Scene = require "core.modules.scenes" +local OptionsMenu = Scene:extend() + +local OptionMenu = require "scenes.options.menu" +local Widgets = require "scenes.options.widgets" + +local gui = require "game.modules.gui" + +function OptionsMenu:new() + OptionsMenu.super.new(self) + + self.assets:batchImport("scenes.options.assets") + self:addMenu("main", true) + self:addSubMenu("video", "video") + self:addSubMenu("audio", "audio") + self:addSubMenu("langs", "langs") + self:addSubMenu("inputs", "inputs") + + Widgets.Resolution(self, "video") + Widgets.Switch(self, "video", "fullscreen") + Widgets.Switch(self, "video", "borders") + Widgets.Switch(self, "video", "vsync") + + self:addPlayerMenus() + + self:setLanguageMenu() + + Widgets.Audio(self, "audio", "sfx") + Widgets.Audio(self, "audio", "music") + + Widgets.Exit(self, "main") + self.menusystem:switchMenu("main") + + self.menusystem:setSoundFromSceneAssets("mBeep") + + self.keyDetector = {} + self.keyDetector.widget = nil + + self.borderY = 25 + self.borders = gui.newBorder(424, 30, 8) + + self.timer = 0 +end + +function OptionsMenu:update(dt) + self.timer = (self.timer + (30 * dt)) % 128 +end + +-- MENU FUNCTION +-- Functions that serve the handling of menus + +function OptionsMenu:addMenu(name, nobackbutton) + OptionMenu(self.menusystem, name) +end + +function OptionsMenu:addSubMenu(name, fullname) + self:addMenu(name) + Widgets.SubMenu(self, "main", name, fullname) + Widgets.SubMenu(self, name, "main", "back", 1, "<") +end + +function OptionsMenu:addPlayerMenus() + for i,v in ipairs(core.input.data) do + local menu = "player" .. i + self:addMenu(menu) + Widgets.PlayerSubMenu(self, "inputs", i) + for k,w in pairs(v.keys) do + -- FIXME: make sure that you can use the order you want for the keys list + -- instead of a random one + Widgets.Key(self, i, k) + end + Widgets.SubMenu(self, menu, "inputs", "back", 1, "<") + end +end + +function OptionsMenu:addScene(submenu, scene, fullname) + Widgets.Dummy(self, submenu, fullname) +end + +function OptionsMenu:setLanguageMenu() + for i,v in ipairs(core.lang.data.available) do + Widgets.Lang(self, "langs", v) + end +end + +function OptionsMenu:changeKey(widget) + self.keyDetector.isActive = true + self.keyDetector.widget = widget +end + +function OptionsMenu:keypressed( key ) + if (self.keyDetector.isActive) then + self.keyDetector.widget:receiveKey( key ) + self.menusystem:activate() + self.keyDetector.isActive = false + end +end + +function OptionsMenu:draw() + local w, h = core.screen:getDimensions() + for i=-1, (w/128) do + for j=-1,(h/128) do + self.assets.images["background"]:draw(i*128 + self.timer, j*128 + self.timer) + end + end + + love.graphics.draw(self.borders, 0, self.borderY, 0, 1, -1) + love.graphics.draw(self.borders, 424, 240 - self.borderY, 0, -1, 1) +end + +return OptionsMenu diff --git a/sonic-radiance.love/scenes/options/menu.lua b/sonic-radiance.love/scenes/options/menu.lua new file mode 100644 index 0000000..98401bf --- /dev/null +++ b/sonic-radiance.love/scenes/options/menu.lua @@ -0,0 +1,14 @@ +local ListBox = require "core.modules.menusystem.listbox" +local OptionMenu = ListBox:extend() +local WIDTH = 424/1.4 +local HEIGHT = 240/1.4 + +function OptionMenu:new(menusystem, name) + local w, h = math.floor(WIDTH), math.floor(HEIGHT) + local screenw, screenh = core.screen:getDimensions() + local x = (screenw/2) - (w/2) + local y = (screenh/2) - (h/2) + OptionMenu.super.new(self, menusystem, name, x, y, w, h, 8) +end + +return OptionMenu diff --git a/sonic-radiance.love/scenes/options/widgets.lua b/sonic-radiance.love/scenes/options/widgets.lua new file mode 100644 index 0000000..b59b38e --- /dev/null +++ b/sonic-radiance.love/scenes/options/widgets.lua @@ -0,0 +1,298 @@ +local widgets = {} + +local Widget = require "core.modules.menusystem.widgets" +local DoubleTextWidget = Widget.Text:extend() + +widgets.SubMenu = DoubleTextWidget:extend() +widgets.Dummy = Widget.Text:extend() +widgets.Exit = Widget.Text:extend() +widgets.Switch = DoubleTextWidget:extend() +widgets.Resolution = DoubleTextWidget:extend() +widgets.Lang = Widget.Text:extend() +widgets.PlayerSubMenu = DoubleTextWidget:extend() +widgets.Key = DoubleTextWidget:extend() +widgets.Audio = DoubleTextWidget:extend() + +-- BASIC WIDGETS +-- Simple and reusables widgets + +-- DoubleText widget : a two-side text widget + +function DoubleTextWidget:new(menu, font, label1, label2) + DoubleTextWidget.super.new(self, menu, font, label1) + self.label2 = label2 or "" +end + +function DoubleTextWidget:drawCanvas() + local w, h + w = math.floor(self.width) + h = math.floor(self.height / 2) - (self.font:getHeight() / 2) + self.font:draw(self.label, 4, h, -1, "left") + self.font:draw(self.label2, w-4, h, -1, "right") +end + +-- Submenu widget :: go to a submenu + +function widgets.SubMenu:new(scene, menu, newmenu, fullname, order, label2) + self.scene = scene + local widgetmenu = self.scene.menusystem.menus[menu] + local font = self.scene.assets.fonts["medium"] + local label = core.lang:translate("options", fullname) + local label2 = label2 or ">" + self.newmenu = newmenu + widgets.SubMenu.super.new(self, widgetmenu, font, label, label2) + self.order = order or 0 +end + +function widgets.SubMenu:action() + self.scene.assets:playSFX("mSelect") + self.scene.menusystem:switchMenu(self.newmenu) +end + +-- Dummy widget :: An empty widget to serve as a base for others + +function widgets.Dummy:new(scene, menu, fullname) + self.scene = scene + local widgetmenu = self.scene.menusystem.menus[menu] + local font = self.scene.assets.fonts["medium"] + widgets.Dummy.super.new(self, widgetmenu, font, fullname) +end + +function widgets.Dummy:action() + -- shoosh +end + +-- Exit Widget : exit the examples + +function widgets.Exit:new(scene, menu) + self.scene = scene + local widgetmenu = self.scene.menusystem.menus[menu] + local font = self.scene.assets.fonts["medium"] + local label = core.lang:translate("commons", "exit") + widgets.Exit.super.new(self, widgetmenu, font, "Exit") +end + +function widgets.Exit:action() + self.scene.assets:playSFX("mSelect") + core.scenemanager:setStoredScene("mainmenu") +end + +-- VIDEO WIDGETS +-- Handle graphical settings + +-- Switch widget (One widget to handle graphical switch) + +function widgets.Switch:new(scene, menu, keyname) + self.scene = scene + local widgetmenu = self.scene.menusystem.menus[menu] + local font = self.scene.assets.fonts["medium"] + self.keyname = keyname + local label = core.lang:translate("options", keyname) + local label2 = self:getLabel() + widgets.Switch.super.new(self, widgetmenu, font, label, label2) + self.order = order or 0 +end + +function widgets.Switch:modifyKey() + --self.key = (self.key == false) + if self.keyname == "fullscreen" then + core.options.data.video.fullscreen = (core.options.data.video.fullscreen == false) + elseif self.keyname == "borders" then + core.options.data.video.border = (core.options.data.video.border == false) + elseif self.keyname == "vsync" then + core.options.data.video.vsync = (core.options.data.video.vsync == false) + end + core.screen:applySettings() +end + +function widgets.Switch:getKey() + if self.keyname == "fullscreen" then + self.key = core.options.data.video.fullscreen + elseif self.keyname == "borders" then + self.key = (core.options.data.video.border) + elseif self.keyname == "vsync" then + self.key = (core.options.data.video.vsync) + end +end + +function widgets.Switch:getLabel() + self:getKey() + local label = "" + if (self.key) then + label = "true" + else + label = "false" + end + + return core.lang:translate("commons", label) +end + +function widgets.Switch:action() + self:modifyKey() + self.scene.assets:playSFX("mSelect") + self.label2 = self:getLabel() + core.options:write() + self:invalidateCanvas() +end + +-- Resolution Widget + +function widgets.Resolution:new(scene, menu) + self.scene = scene + local widgetmenu = self.scene.menusystem.menus[menu] + local font = self.scene.assets.fonts["medium"] + local label = core.lang:translate("options", "resolution") + local label2 = self:getLabel() + widgets.Resolution.super.new(self, widgetmenu, font, label, label2) +end + +function widgets.Resolution:getLabel() + return "x" .. core.options.data.video.resolution +end + +function widgets.Resolution:action() + if core.options.data.video.resolution == 3 then + core.options.data.video.resolution = 1 + else + core.options.data.video.resolution = core.options.data.video.resolution + 1 + end + self.label2 = self:getLabel() + core.screen:applySettings() + self.scene.assets:playSFX("mSelect") + self:invalidateCanvas() + core.options:write() +end + +-- LANGS WIDGET +-- Allow you to change the lang of the game + +function widgets.Lang:new(scene, menu, lang) + self.scene = scene + local widgetmenu = self.scene.menusystem.menus[menu] + local font = self.scene.assets.fonts["medium"] + local label = core.lang:getLangName(lang) + self.lang = lang + widgets.Lang.super.new(self, widgetmenu, font, label) +end + +function widgets.Lang:action() + self.scene.assets:playSFX("mSelect") + core.options:setLanguage(self.lang) + --self.scene.menusystem:invalidateAllWidgets() +end + +-- INPUT WIDGETS +-- Widgets to handle inputs + +function widgets.PlayerSubMenu:new(scene, menu, sourceid) + self.scene = scene + local widgetmenu = self.scene.menusystem.menus[menu] + local font = self.scene.assets.fonts["medium"] + local label = core.lang:translate("options", "player") .. " " .. sourceid + local label2 = ">" + self.newmenu = "player" .. sourceid + widgets.PlayerSubMenu.super.new(self, widgetmenu, font, label, label2) + self.order = 0 +end + +function widgets.PlayerSubMenu:action() + self.scene.assets:playSFX("mSelect") + self.scene.menusystem:switchMenu(self.newmenu) +end + +-- Key widgets + +function widgets.Key:new(scene, sourceid, key) + self.scene = scene + self.source = sourceid + self.key = key + + local menu = "player" .. self.source + + local widgetmenu = self.scene.menusystem.menus[menu] + local font = self.scene.assets.fonts["medium"] + local label = self.key + local label2 = self:getLabel() + + widgets.Key.super.new(self, widgetmenu, font, label, label2) + self.order = 0 +end + +function widgets.Key:getLabel() + return core.input.data[self.source].keys[self.key] +end + +function widgets.Key:action() + self.scene.assets:playSFX("navigate") + self.scene:changeKey(self) + self.scene.menusystem:deactivate() +end + +function widgets.Key:receiveKey( key ) + self.scene.assets:playSFX("mSelect") + core.options:setInputKey(self.source, self.key, key) + self.label2 = self:getLabel() + self:invalidateCanvas() +end + +-- AUDIO FUNCTIONS +-- Sounds/Music functions + +function widgets.Audio:new(scene, menu, audiotype) + self.scene = scene + self.audiotype = key + + + local widgetmenu = self.scene.menusystem.menus[menu] + local font = self.scene.assets.fonts["medium"] + self.audiotype = audiotype + local label = "" + if (self.audiotype == "sfx") then + label = core.lang:translate("options", "sfx") + else + label = core.lang:translate("options", "music") + end + local label2 = self:getLabel() + + widgets.Audio.super.new(self, widgetmenu, font, label, label2) + self.order = 0 +end + +function widgets.Audio:getLabel() + local value = self:getVolume() + string = utils.math.numberToString(value, 3) + local label = string .. "%" + + return label +end + +function widgets.Audio:getVolume() + if (self.audiotype == "sfx") then + return core.options.data.audio.sfx + else + return core.options.data.audio.music + end +end + +function widgets.Audio:setVolume(vol) + if (vol < 0) then vol = 100 end + + if (self.audiotype == "sfx") then + core.options.data.audio.sfx = vol + else + core.options.data.audio.music = vol + end + + self.label2 = self:getLabel() + self:invalidateCanvas() +end + +function widgets.Audio:action() + local value = self:getVolume() + self:setVolume(value - 20) + self.scene.assets:playSFX("mSelect") + --self.scene.assets.music:setVolume(core.options.data.audio.music / 100) + core.options:write() +end + +return widgets diff --git a/sonic-radiance.love/scenes/overworld/actors/init.lua b/sonic-radiance.love/scenes/overworld/actors/init.lua new file mode 100644 index 0000000..9d67a55 --- /dev/null +++ b/sonic-radiance.love/scenes/overworld/actors/init.lua @@ -0,0 +1,13 @@ +local Obj = {} + +-- On charge toutes les différentes types d'acteurs +local cwd = (...):gsub('%.init$', '') .. "." +Obj.Player = require(cwd .. "player") + +Obj.index = {} +Obj.index["player"] = Obj.Player + +Obj.collisions = {} +Obj.collisions["wall"] = require(cwd .. "wall") + +return Obj diff --git a/sonic-radiance.love/scenes/overworld/actors/parent.lua b/sonic-radiance.love/scenes/overworld/actors/parent.lua new file mode 100644 index 0000000..7b27ac1 --- /dev/null +++ b/sonic-radiance.love/scenes/overworld/actors/parent.lua @@ -0,0 +1,15 @@ +local Base = require "core.modules.world.actors.actor2D" +local Parent = Base:extend() + +function Parent:new(world, type, x, y, w, h, isSolid) + self.scene = world.scene + Parent.super.new(self, world, type, x, y, w, h, isSolid) + self.charDir = "down" + self.charset = self.world.scene.charsetManager +end + +function Parent:draw() + love.graphics.rectangle("fill", math.floor(self.x), math.floor(self.y), self.w, self.h) +end + +return Parent diff --git a/sonic-radiance.love/scenes/overworld/actors/player.lua b/sonic-radiance.love/scenes/overworld/actors/player.lua new file mode 100644 index 0000000..7f9187d --- /dev/null +++ b/sonic-radiance.love/scenes/overworld/actors/player.lua @@ -0,0 +1,47 @@ +local cwd = (...):gsub('%.player$', '') .. "." +local Parent = require(cwd .. "parent") +local Player = Parent:extend() + +function Player:new(world, x, y, id) + Player.super.new(self, world, "player", x, y, 16, 16, true) + self.charset:addTexture("perso") +end + +function Player:isMoving() + return ((math.abs(self.ysp) > 0.01) or (math.abs(self.xsp) > 0.01)) +end + +function Player:updateStart(dt) + self.xfrc, self.yfrc = 480*3, 480*3 + + if self.keys["up"].isDown then + self.ysp = -120 + self.charDir = "up" + end + if self.keys["down"].isDown then + self.ysp = 120 + self.charDir = "down" + end + if self.keys["left"].isDown then + self.xsp = -120 + self.charDir = "left" + end + if self.keys["right"].isDown then + self.xsp = 120 + self.charDir = "right" + end +end + +function Player:draw() + if (self:isMoving()) then + self.charset:draw("perso", 1, self.charDir, self.x, self.y) + else + self.charset:drawStanding("perso", 1, self.charDir, self.x, self.y) + end +end + +function Player:drawHUD(id) + love.graphics.print(id .. " test", 4, 4) +end + +return Player diff --git a/sonic-radiance.love/scenes/overworld/actors/wall.lua b/sonic-radiance.love/scenes/overworld/actors/wall.lua new file mode 100644 index 0000000..7e4f18e --- /dev/null +++ b/sonic-radiance.love/scenes/overworld/actors/wall.lua @@ -0,0 +1,14 @@ +local Base = require "core.modules.world.actors.actor2D" +local Wall = Base:extend() + +function Wall:new(world, x, y, w, h) + Wall.super.new(self, world, "wall", x, y, w, h, true) + self:setDebugColor(0,0,0) +end + +function Wall:draw() + --self:drawHitbox() + --utils.graphics.resetColor( ) +end + +return Wall diff --git a/sonic-radiance.love/scenes/overworld/charsetmanager.lua b/sonic-radiance.love/scenes/overworld/charsetmanager.lua new file mode 100644 index 0000000..ffc1b3b --- /dev/null +++ b/sonic-radiance.love/scenes/overworld/charsetmanager.lua @@ -0,0 +1,71 @@ +local Charset = Object:extend() + +local folder = "assets/sprites/charset/" +local animation = {1, 2, 3, 2} +local directionList = {"down", "right", "up", "left"} + +function Charset:new(scene) + self.char = {} + self.list = {} + + for i=1, 2 do + for j=1, 4 do + local id = ((i-1)*4) + j + self.char[id] = self:addChar(i, j) + end + end + self.currentFrame = 0 +end + +function Charset:update(dt) + self.currentFrame = ((self.currentFrame + (dt*5)) % 4) +end + +function Charset:addChar(ii, jj) + local charx, chary = (jj-1)*(24*3), (ii-1)*(32*4) + local char = {} + for i=1, 4 do + animatedDirection = {} + local running = {} + for j=1, 3 do + local x, y = charx + ((j-1)*24), (chary + (i-1)*32) + --print(x, y) + running[j] = love.graphics.newQuad(x, y, 24, 32, 24*12, 32*8) + end + local direction = directionList[i] + char[direction] = running + end + return char +end + +function Charset:addTexture(charsetName) + self.list[charsetName] = love.graphics.newImage(folder .. charsetName .. ".png") +end + +function Charset:getRunningFrame(charID, direction) + local char = self.char[charID] + local animatedDirection = char[direction] + local fakeFrame = math.min(math.floor(self.currentFrame) + 1, 4) + local trueFrame = animation[fakeFrame] + return animatedDirection[trueFrame] +end + +function Charset:getStandingFrame(charID, direction) + local char = self.char[charID] + local animatedDirection = char[direction] + return animatedDirection[2] +end + +function Charset:draw(charsetName, charID, direction, x, y) + local drawable = self.list[charsetName] + local quad = self:getRunningFrame(charID, direction) + love.graphics.draw(drawable, quad, math.floor(x), math.floor(y), 0, 1, 1, 4, 16) +end + +function Charset:drawStanding(charsetName, charID, direction, x, y) + local drawable = self.list[charsetName] + local quad = self:getStandingFrame(charID, direction) + love.graphics.draw(drawable, quad, math.floor(x), math.floor(y), 0, 1, 1, 4, 16) +end + +return Charset diff --git a/sonic-radiance.love/scenes/overworld/init.lua b/sonic-radiance.love/scenes/overworld/init.lua index b42be75..48c27de 100644 --- a/sonic-radiance.love/scenes/overworld/init.lua +++ b/sonic-radiance.love/scenes/overworld/init.lua @@ -1,15 +1,47 @@ +-- scenes/moveplayer :: a basic player movement example + +--[[ + 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 "core.modules.scenes" -local OverWorld = Scene:extend() +local MovePlayer = Scene:extend() -function OverWorld:new() - OverWorld.super.new(self) +local World = require "scenes.overworld.world" +local CharsetManager = require "scenes.overworld.charsetmanager" + +function MovePlayer:new() + MovePlayer.super.new(self) + self.charsetManager = CharsetManager(self) + + World(self, "test", "map") + self.world:setPlayerNumber(1) + self.world:loadMap() end -function OverWorld:update(dt) +function MovePlayer:update(dt) + self.charsetManager:update(dt) end -function OverWorld:draw() +function MovePlayer:draw() end -return OverWorld +return MovePlayer diff --git a/sonic-radiance.love/scenes/overworld/world.lua b/sonic-radiance.love/scenes/overworld/world.lua new file mode 100644 index 0000000..c5f108c --- /dev/null +++ b/sonic-radiance.love/scenes/overworld/world.lua @@ -0,0 +1,11 @@ +local World = require "core.modules.world.world2D" +local RPGWorld = World:extend() +local objFile = "scenes.overworld.actors" +local mapFolder = "datas/gamedata/maps/sti/" + +function RPGWorld:new(scene, folder, map, playerx, playery) + local mapFile = mapFolder .. folder .. "/" .. map .. ".lua" + RPGWorld.super.new(self, scene, objFile, mapFile) +end + +return RPGWorld diff --git a/sonic-radiance.love/scenes/test_scene/init.lua b/sonic-radiance.love/scenes/test_scene/init.lua index 0a19dea..a8e37a4 100644 --- a/sonic-radiance.love/scenes/test_scene/init.lua +++ b/sonic-radiance.love/scenes/test_scene/init.lua @@ -26,17 +26,15 @@ local MovePlayer = Scene:extend() local World = require "game.modules.world" -function MovePlayer:new(playerNumber, cameraMode) - local playerNumber = playerNumber or 1 - local cameraMode = cameraMode or "split" +function MovePlayer:new(map) MovePlayer.super.new(self) self.assets:batchImport("scenes.test_scene.assets") - World(self, "battle", "tlab") + World(self, "battle", map) - self.world:setPlayerNumber(playerNumber) - self.world.cameras:setMode(cameraMode) + self.world:setPlayerNumber(1) + self.world.cameras:setMode("split") self.world:loadMap() end diff --git a/sonic-radiance.love/scenes/test_scene2/assets.lua b/sonic-radiance.love/scenes/test_scene2/assets.lua new file mode 100644 index 0000000..d749a61 --- /dev/null +++ b/sonic-radiance.love/scenes/test_scene2/assets.lua @@ -0,0 +1,17 @@ +return { + ["textures"] = { + {"shadow", "assets/sprites/shadow.png"} + }, + ["sprites"] = { + {"sonic", "datas/gamedata/characters/sonic/sprites"}, + {"ring", "assets/sprites/items/ring"} + }, + ["imagefonts"] = { + --{"medium", "assets/fonts/medium"} + }, + ["sfx"] = { + --{"navigate", "assets/sfx/menu_move.mp3"}, + --{"confirm", "assets/sfx/menu_confirm.mp3"}, + --{"cancel", "assets/sfx/menu_error.mp3"}, + } +} diff --git a/sonic-radiance.love/scenes/test_scene2/init.lua b/sonic-radiance.love/scenes/test_scene2/init.lua new file mode 100644 index 0000000..0550982 --- /dev/null +++ b/sonic-radiance.love/scenes/test_scene2/init.lua @@ -0,0 +1,44 @@ +-- scenes/moveplayer3D :: a basic player movement example in fake3D + +--[[ + 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 "core.modules.scenes" +local MovePlayer = Scene:extend() + +local World = require "game.modules.world" + +function MovePlayer:new(playerNumber, cameraMode) + local playerNumber = playerNumber or 1 + local cameraMode = cameraMode or "split" + + MovePlayer.super.new(self) + self.assets:batchImport("scenes.test_scene.assets") + + World(self, "shoot", "forest") + + self.world:setPlayerNumber(playerNumber) + self.world.cameras:setMode(cameraMode) + + self.world:loadMap() +end + +return MovePlayer