chore: initial non-working port of the gameplay

This commit is contained in:
Kazhnuz 2021-11-25 11:28:31 +01:00
parent bc8d61728b
commit ca3d486a83
102 changed files with 3468 additions and 1028 deletions

View file

@ -3,7 +3,9 @@ return {
{"shadow", "assets/sprites/shadow.png"}
},
["sprites"] = {
{"ring", "assets/sprites/items/ring"}
{"ring", "assets/sprites/items/ring"},
{"ringtoss", "assets/sprites/items/ringtoss"},
{"ringweapon", "assets/sprites/items/ringweapon"},
},
["imagefonts"] = {
{"menu", "assets/gui/fonts/SA2font"},

View file

@ -0,0 +1,32 @@
local CharacterData = Object:extend()
function CharacterData:getCommonData()
self.data = core.datas:get("characters", self.simplename)
self.name = self.data.name
self.fullname = self.data.fullname
self.turns = self.data.turns
end
function CharacterData:getWeaknesses()
return self.data.weakTo
end
function CharacterData:getResistences()
return self.data.resists
end
function CharacterData:getSkillName(skill)
local skilldata = core.datas:get("skills", skill)
local name = skilldata.fullname
if (skilldata.altName ~= nil) then
if (skilldata.altName[self.simplename] ~= nil) then
name = skilldata.altName[self.simplename]
end
end
print(name)
return name
end
return CharacterData

View file

@ -0,0 +1,60 @@
local CharacterEquip = Object:extend()
local categories = {"gloves", "shoes", "accessories"}
function CharacterEquip:initEquip()
self.equip = {}
if self.data.inventory == nil then
core.debug:warning("character/equip", "Initial equip not set for " .. self.simplename)
for _, category in ipairs(categories) do
self.equip[category] = ""
end
else
for _, category in ipairs(categories) do
self.equip[category] = self.data.inventory[category] or ""
end
end
end
function CharacterEquip:setEquip(category, name)
if (not utils.string.isEmpty(self.equip[category])) then
game.loot:addItem(category, self.equip[category], 1)
end
self.equip[category] = name
game.loot:removeItem(category, name, 1)
self:updateHPPP()
end
function CharacterEquip:removeEquip(category)
if (not utils.string.isEmpty(self.equip[category])) then
game.loot:addItem(category, self.equip[category], 1)
self.equip[category] = ""
self:updateHPPP()
end
end
function CharacterEquip:predictStat(statName, category, name)
return self.stats:predictStat(statName, category, name)
end
function CharacterEquip:getEquipStats(stat, ignore)
local boost = 0
local ignore = ignore or ""
for _, category in ipairs(categories) do
if (category ~= ignore) then
boost = boost + self:getEquipStatByType(stat, category)
end
end
return boost
end
function CharacterEquip:getEquipStatByType(stat, category)
if (not utils.string.isEmpty(self.equip[category])) then
local data = core.datas:get("items", self.equip[category])
local boost = data.statsBoost[stat] or 0
return boost
end
return 0
end
return CharacterEquip

View file

@ -0,0 +1,7 @@
local CharacterHealth = Object:extend()
function CharacterHealth:heal()
self:initLife()
end
return CharacterHealth

View file

@ -0,0 +1,74 @@
local AbstractMobParent = require "game.abstractmobs.parent"
local AbstractCharacter = AbstractMobParent:extend()
local CharacterHealth = require "game.abstractmobs.character.health"
local CharacterLevels = require "game.abstractmobs.character.levels"
local CharacterDatas = require "game.abstractmobs.character.datas"
local CharacterEquip = require "game.abstractmobs.character.equip"
AbstractCharacter:implement(CharacterHealth)
AbstractCharacter:implement(CharacterLevels)
AbstractCharacter:implement(CharacterDatas)
AbstractCharacter:implement(CharacterEquip)
local CharacterStatManager = require "game.abstractmobs.character.statmanager"
function AbstractCharacter:new(name)
self.simplename = name
AbstractCharacter.super.new(self, {"simplename", "level", "exp", "exp_next", "hp", "pp", "statuts", "equip"}, nil, CharacterStatManager)
self:updateHPPP()
end
function AbstractCharacter:initBasicElements()
self:getCommonData()
self:initEquip()
self:initLevel()
end
function AbstractCharacter:updateHPPP()
if (self.hp ~= nil) then
self.hp = math.min(self.hp, self.stats:get(self.stats.HPMAX))
end
if (self.pp ~= nil) then
self.pp = math.min(self.pp, self.stats:get(self.stats.PPMAX))
end
end
function AbstractCharacter:getStat(statName, ignoreEquip)
return self.stats:get(statName, ignoreEquip)
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:finishDeserialization()
self.skills = self:createSkills()
end
return AbstractCharacter

View file

@ -0,0 +1,61 @@
local CharacterLevel = Object:extend()
local charutils = require "game.utils.characters"
local STATS = require "datas.consts.stats"
function CharacterLevel:initLevel()
self.level = self.data.startlevel
self.exp = charutils.getExpValue(self.level)
self.exp_next = charutils.getExpValue(self.level + 1)
end
function CharacterLevel:setLevel(newlevel)
self.level = newlevel
local exp
local exp_min = charutils.getExpValue(self.level)
local 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:updateHPPP()
self.skills = self:createSkills()
end
function CharacterLevel:levelUp()
if (game.difficulty:get("levelUpHeal")) then
self:heal()
end
self:setLevel(self.level + 1)
end
function CharacterLevel:getLevelStat(statname)
local baseStat = self.data.stats[statname]
if (baseStat == nil) then
error("Stat " .. statname .. " doesn't exist")
else
local stat = 0
if (statname == "hpmax") then
stat = charutils.getHPValue(self.level, baseStat)
elseif (statname == "ppmax") then
stat = charutils.getPPValue(self.level, baseStat)
else
stat = charutils.getStatValue(self.level, baseStat)
end
return stat
end
end
function CharacterLevel:getComputedStat(statname)
core.debug:warning("CharacterLevel", "Function getComputedStat is deprecated")
return self:getLevelStat(statname)
end
function CharacterLevel:getStatList()
return STATS.LIST
end
return CharacterLevel

View file

@ -0,0 +1,27 @@
local StatManager = require "game.abstractmobs.statmanager"
local CharacterStatManager = StatManager:extend()
function CharacterStatManager:new(owner)
CharacterStatManager.super.new(self, owner)
end
function CharacterStatManager:computeStat(statname, ignoreEquip)
local stat = self:getBaseStat(statname) + self.owner:getEquipStats(statname, ignoreEquip)
return stat
end
function CharacterStatManager:predictStat(statname, category, name)
local data = core.datas:get("items", name)
local boost = data.statsBoost[statname] or 0
return self:computeStat(statname, category) + boost
end
function CharacterStatManager:getBaseStat(statname)
if (self:isBattleStat(statname)) then
return self:getBattleStat(statname)
else
return self.owner:getLevelStat(statname)
end
end
return CharacterStatManager

View file

@ -0,0 +1,47 @@
local AbstractMobParent = require "game.abstractmobs.parent"
local AbstractEnnemy = AbstractMobParent:extend()
local elements = require "datas.gamedata.battles.elements"
local EnnemyStatManager = require "game.abstractmobs.ennemy.statmanager"
function AbstractEnnemy:new(directory, name)
self.simplename = name
self.directory = directory
AbstractEnnemy.super.new(self, nil, nil, EnnemyStatManager)
end
function AbstractEnnemy:getWeaknesses()
local elementData = elements[self.data.element] or elements["none"]
return elementData.weakTo
end
function AbstractEnnemy:getResistences()
local elementData = elements[self.data.element] or elements["none"]
return elementData.resists
end
function AbstractEnnemy:haveProtecType(protectype)
return utils.table.contain(self.data.protectypes, protectype)
end
function AbstractEnnemy:getProtecTypes()
return self.data.protectypes
end
function AbstractEnnemy:initBasicElements()
self.data = core.datas:get("ennemies", self.simplename)
self.name = self.data.name
self.fullname = self.data.fullname
self.turns = self.data.turns
end
function AbstractEnnemy:createSkills()
return self.data.skills
end
function AbstractEnnemy:setBonus(pvFactor, statFactor)
self.stats:setBonus(pvFactor, statFactor)
self.hp = self.stats:get(self.stats.HPMAX)
end
return AbstractEnnemy

View file

@ -0,0 +1,31 @@
local StatManager = require "game.abstractmobs.statmanager"
local EnnemyStatManager = StatManager:extend()
function EnnemyStatManager:new(owner)
EnnemyStatManager.super.new(self, owner, "ENNEMI")
self.pvFactor = 1
self.statFactor = 1
end
function EnnemyStatManager:setBonus(pvFactor, statFactor)
self.pvFactor = pvFactor or 1
self.statFactor = statFactor or 1
end
function EnnemyStatManager:computeStat(statname)
local stat = self.owner.data.stats[statname]
if (self:isBattleStat(statname)) then
return self:getBattleStat(statname)
end
if statname == EnnemyStatManager.HPMAX then
return stat * self.pvFactor
elseif (statname ~= EnnemyStatManager.PPMAX) then
return stat * self.statFactor
else
return stat
end
end
return EnnemyStatManager

View file

@ -0,0 +1,179 @@
local Serializable = require "birb.classes.serializable"
local AbstractMobParent = Serializable:extend()
local StatManager = require "game.abstractmobs.statmanager"
local statutStatList = require "datas.gamedata.statuses"
function AbstractMobParent:new(serializeFields, listSerializable, statManager)
local statManager = statManager or StatManager
self:initBasicElements()
self.stats = statManager(self)
self.skills = self:createSkills()
self.statuts = {}
self:initLife()
AbstractMobParent.super.new(self, serializeFields, listSerializable)
end
function AbstractMobParent:initBasicElements()
self.name = "PlaceHolder"
self.fullname = "PlaceHolder"
self.turns = 2
end
function AbstractMobParent:haveProtecType()
return false
end
function AbstractMobParent:getProtecTypes()
return {}
end
function AbstractMobParent:createSkills()
return {}
end
-- LIFE FUNCTIONS
-- Handle HP and stuff like that
function AbstractMobParent:initLife()
self.hp = self.stats:get(self.stats.HPMAX)
self.pp = self.stats:get(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
self.hp = math.floor(math.max(0, self.hp))
if (self.hp == 0) then
self:die()
end
self.hp = math.min(self.hp, self.stats:get(self.stats.HPMAX))
end
function AbstractMobParent:setPP(newPP, relative)
if (relative) then
self.pp = self.pp + newPP
else
self.pp = newPP
end
self.pp = math.floor(math.max(0, self.pp))
self.pp = math.min(self.pp, self.stats:get(self.stats.PPMAX))
end
function AbstractMobParent:getStats()
return self.stats
end
-- STATUT HANDLING
function AbstractMobParent:addStatut(name, duration, source)
local statut = self:getStatutData(name)
local duration = duration or 1
if (statut.remove ~= nil) then
duration = - self:removeStatutTurns(statut.remove, duration)
end
if (duration > 0) then
if (statut.replaceAll == true) then
self:resetStatut()
else
self:removeStatut(name)
end
self.statuts[name] = {}
self.statuts[name].duration = duration
end
end
function AbstractMobParent:getStatutKey(statutName)
local statut = self:getStatutData(statutName)
local key = ""
if (self.statuts[statutName] ~= nil) then
key = statutName
end
if (statut.alternative ~= nil) then
for _, alternative in ipairs(statut.alternative) do
if (self.statuts[alternative] ~= nil) then
key = alternative
end
end
end
return key
end
function AbstractMobParent:haveStatuts(statutName)
return (self.statuts[self:getStatutKey(statutName)] ~= nil)
end
function AbstractMobParent:removeStatut(statutName)
local key = self:getStatutKey(statutName)
if (key ~= nil) then
self.statuts[key] = nil
return true
end
return false
end
function AbstractMobParent:removeStatutTurns(statutName, turns)
local statut = self:getStatutData(statutName)
if (statut.temporary == false) then
return 0
end
if (not self:haveStatuts(statutName)) then
return turns
end
local key = self:getStatutKey(statutName)
local relativeTurns = self.statuts[key].duration - turns
if (relativeTurns <= 0) then
self:removeStatut(statutName)
else
self.statuts[key].duration = relativeTurns
end
return relativeTurns
end
function AbstractMobParent:resetStatut()
self.statuts = {}
end
function AbstractMobParent:die()
self:addStatut("ko")
end
function AbstractMobParent:isAlive()
return (not self:haveStatuts("ko"))
end
function AbstractMobParent:removeOneTurnToStatut()
for name, _ in pairs(self.statuts) do
self:removeStatutTurns(name, 1)
end
end
function AbstractMobParent:getStatutsStat(statName)
local stat = 0
for statutName, _ in pairs(self.statuts) do
local statut = self:getStatutData(statutName)
if (statut.stats ~= nil) then
for _, statutStat in ipairs(statut.stats) do
if (statutStat[1] == statName) then
stat = stat + statutStat[2]
end
end
end
end
return stat
end
function AbstractMobParent:getStatutData(statutName)
return statutStatList[statutName]
end
return AbstractMobParent

View file

@ -0,0 +1,36 @@
local StatManager = Object:extend()
local CONST = require "datas.consts.stats"
StatManager.CONST = CONST
StatManager.HPMAX = CONST.HPMAX
StatManager.PPMAX = CONST.PPMAX
StatManager.ATTACK = CONST.ATTACK
StatManager.POWER = CONST.POWER
StatManager.DEFENSE = CONST.DEFENSE
StatManager.MIND = CONST.MIND
StatManager.TECHNIC = CONST.TECHNIC
StatManager.SPEED = CONST.SPEED
function StatManager:new(owner, battleStatType)
local battleStatType = battleStatType or "HERO"
self.owner = owner
self.battleStats = CONST.BATTLESTAT[battleStatType]
end
function StatManager:get(statname)
return self:computeStat(statname)
end
function StatManager:computeStat(statname)
return self.list[statname]
end
function StatManager:isBattleStat(statname)
return utils.table.contain(CONST.BATTLELIST, statname)
end
function StatManager:getBattleStat(statname)
return self.battleStats[statname]
end
return StatManager

View file

@ -0,0 +1,37 @@
local CoreCBS = Object:extend()
local defTransitions = require "birb.modules.transitions"
local radTransitions = require "game.modules.transitions"
local DEFAULTX = 424/2
local DEFAULTY = 240/2
function CoreCBS:new()
self.lastx, self.lasty = DEFAULTX, DEFAULTY
end
function CoreCBS:startBattle(category, name, x, y)
local data = core.datas:get("battles", name)
self.lastx, self.lasty = x or DEFAULTX, y or DEFAULTY
core.screen:startTransition(radTransitions.eggman, radTransitions.borders, function() scenes.cbs(data) end, x, y)
end
function CoreCBS:endBattle(isFleeing)
local transitionEnd = radTransitions.sonic
if (isFleeing) then
transitionEnd = defTransitions.circle;
end
core.screen:startTransition(radTransitions.borders, transitionEnd,
function()
if (core.scenemanager:haveStoredScene("afterBattle")) then
core.scenemanager:setStoredScene("afterBattle")
else
scenes.menus.main()
end
end, self.lastx, self.lasty)
self.lastx, self.lasty = DEFAULTX, DEFAULTY
end
return CoreCBS

View file

@ -22,127 +22,167 @@
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local CharacterManager = Object:extend()
local Serializable = require "birb.classes.serializable"
local CharacterManager = Serializable:extend()
local AbstractCharacter = require "game.abstractmobs.character"
local startdata = require "datas.gamedata.startdata"
function CharacterManager:new(controller)
self.controller = controller
self.namelist = require "datas.gamedata.characters"
self.list = {}
self.team = require "datas.gamedata.characters.baseteam"
self.team = startdata.baseteam
self.active = 1
self:init()
CharacterManager.super.new(self, {"team"}, {"list"}, {list = AbstractCharacter})
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 (core.datas:exists("characters", 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.stats = require(charfolder .. ".stats")
character.assets = require(charfolder .. ".assets")
character.skills = require(charfolder .. ".skills")
character.actions = require(charfolder .. ".actions")
-- WRAPPER FUNCTIONS
-- Simple wrappers around characters functions
return character
function CharacterManager:setLevel(name, newlevel)
self.list[name]:setLevel(newlevel)
end
function CharacterManager:initCharacter(id)
local character = self:getCharacterData(id)
local startlevel = character.stats.startlevel
character.stats.level = startlevel
character.stats.exp = self:getExpValue(startlevel)
character.stats.exp_next = self:getExpValue(startlevel + 1)
character.stats.hp = character.stats.hpmax
character.stats.pp = 100
character.stats.status = 0
self.list[id] = character
function CharacterManager:levelUp(name)
self.list[name]:levelUp()
end
function CharacterManager:getExpValue(level)
return math.floor( ( 4 * ( level ^ 3 ) ) / 5 )
function CharacterManager:heal(name)
self.list[name]:heal()
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
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
-- DATA FUNCTIONS
-- function to handle saving
function CharacterManager:getData()
local data = {}
data.list = self.list
data.team = self.team
data.list = {}
for name, character in pairs(self.list) do
data.list[name] = character:getData()
end
return data
end
function CharacterManager:setData(data)
local data = data
self.list = data.list
self.team = data.team
for name, charData in pairs(data.list) do
self.list[name]:setData(charData)
end
end
function CharacterManager:heal(id)
self.list[id].stats.hp = self.list[id].stats.hpmax
self.list[id].stats.pp = 100
self.list[id].stats.status = 0
end
-- TEAM FUNCTIONS
-- Team handling and management
function CharacterManager:addToTeam(id)
self:heal(id)
table.insert(self.team, id)
function CharacterManager:addToTeam(name)
self:heal(name)
if (#self.team < 4) then
table.insert(self.team, name)
end
end
function CharacterManager:removeToTeam(teamid)
self.team[teamid] = ""
if (#self.team > 1) then
table.remove(self.team, teamid)
end
end
function CharacterManager:getPositionInTeam(charName)
local charId = -1
for i,name in ipairs(self.team) do
if (name == charName) then
charId = i
end
end
return charId
end
function CharacterManager:addOrRemoveToTeam(charName)
local charId = self:getPositionInTeam(charName)
if (charId == -1) then
self:addToTeam(charName)
else
self:removeToTeam(charId)
if (charId < self.active) then
self.active = self.active - 1
end
end
self:fixActiveCharacter()
end
function CharacterManager:setActiveCharacter(direction)
local direction = direction or 1
local count = direction
self.active = self.active + utils.math.sign(direction)
if (self.active > #self.team) then
self.active = 1
end
if (self.active < 1) then
self.active = #self.team
end
if (self.list[self.team[self.active]].hp <= 0) and not game.difficulty:get("playerKoChar") then
count = count + self:setActiveCharacter(direction)
end
return count
end
function CharacterManager:fixActiveCharacter()
if (self.active < 1) then
self.active = 1
elseif (self.active > #self.team) then
self.active = #self.team
end
end
function CharacterManager:getActiveCharacter()
return self.team[self.active]
end
function CharacterManager:getActiveCharacterData()
return self.list[self.team[self.active]]
end
-- SCENES FUNCTIONS
-- Handle damages from the scenes
function CharacterManager:sendDamageFromMap(name, damageRatio)
local character = self.list[name]
if (character.hp > 0) then
local newHP = math.floor(character.hp - (character.stats:get(character.stats.HPMAX) * damageRatio))
if (not game.difficulty:get("hazardMakesKo")) then
newHP = math.max(1, newHP)
end
self.list[name]:setHP(newHP, false)
end
end
function CharacterManager:loadSprite(assets, name)
assets:addSprite(name, "datas/gamedata/characters/" .. name .. "/sprites")
end
-- DEBUG FUNCTIONS
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)")
core.debug:print(id .. ". " .. character.fullname)
core.debug:print("Lvl " .. character.level .. " (" .. character.exp .. "/" .. character.exp_next .. " exp)")
end
function CharacterManager:printTeam()
for i,v in ipairs(self.team) do
self:printCharacter(v)
print("-----")
core.debug:print("-----")
end
end

View file

@ -0,0 +1,23 @@
local Serializable = require "birb.classes.serializable"
local Difficulty = Serializable:extend()
function Difficulty:new()
self.toggles = {}
self.toggles.hazardMakesKo = false
self.toggles.playerKoChar = true
self.toggles.easierBattles = false
self.toggles.checkPointRegen = false
self.toggles.levelUpHeal = false
self.toggles.allDamage = true
Difficulty.super.new(self, {"toggles"})
end
function Difficulty:toggle(toggleName)
self.toggles[toggleName] = (self.toggles[toggleName] == false)
end
function Difficulty:get(toggleName)
return self.toggles[toggleName]
end
return Difficulty

View file

@ -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
function EnnemyManager:getEnnemyData(category, ennemy)
return AbstractEnnemy(category, ennemy)
end
return EnnemyManager

View file

@ -0,0 +1,12 @@
local Conditions = {}
function Conditions.haveMoney(cond, predicate, asker)
return predicate.utils.testVariables(game.loot.rings , cond[2], cond[3])
end
function Conditions.default(cond, predicate, asker)
local flag = predicate.utils.merge(cond)
return asker:haveFlag(flag)
end
return Conditions

View file

@ -0,0 +1,67 @@
local StepParent = require "game.events.event.parent"
local DialogBox = StepParent:extend()
local Talkies = require('birb.libs.talkies')
function DialogBox:new(controller, args)
DialogBox.super.new(self, controller, args)
Talkies.font = love.graphics.newFont("assets/gui/fonts/PixelOperator.ttf", 16)
Talkies.talkSound = love.audio.newSource("assets/sfx/talk.wav", "static")
Talkies.optionOnSelectSound = love.audio.newSource("assets/sfx/menus/select.wav", "static")
Talkies.optionSwitchSound = love.audio.newSource("assets/sfx/menus/beep.wav", "static")
end
function DialogBox:start()
local args = self:addOptions()
if (args == nil) then
Talkies.say(self.arguments.title, self.arguments.message)
else
Talkies.say(self.arguments.title, self.arguments.message, args)
end
end
function DialogBox:addOptions()
local args = {}
args.options = {}
local haveAddedSomething = false
if (self.arguments.option1 ~= nil) then
table.insert(args.options, {self.arguments.option1, function() self:setOption(1) end})
haveAddedSomething = true
end
if (self.arguments.option2 ~= nil) then
table.insert(args.options, {self.arguments.option2, function() self:setOption(2) end})
haveAddedSomething = true
end
if (self.arguments.option3 ~= nil) then
table.insert(args.options, {self.arguments.option3, function() self:setOption(3) end})
haveAddedSomething = true
end
if (haveAddedSomething) then
return args
end
end
function DialogBox:setOption(num)
self.events:addFlag(self.arguments.flag, num)
self:finish()
end
function DialogBox:update(dt)
Talkies.update(dt)
if (not Talkies.isOpen()) then
self:finish()
end
local keys = self.events.scene.sources[1].keys
if (keys["up"].isPressed) then Talkies.prevOption();
elseif (keys["down"].isPressed) then Talkies.nextOption();
elseif (keys["A"].isPressed) then Talkies.onAction();
end
end
function DialogBox:draw()
Talkies.draw()
end
return DialogBox;

View file

@ -0,0 +1,16 @@
local StepParent = require "game.events.event.parent"
local SimpleMessageStep = StepParent:extend()
function SimpleMessageStep:new(controller, args)
SimpleMessageStep.super.new(self, controller, args)
end
function SimpleMessageStep:start()
game.loot:addItem(self.arguments.type, self.arguments.item, self.arguments.number)
end
function SimpleMessageStep:update(dt)
self:finish()
end
return SimpleMessageStep;

View file

@ -0,0 +1,16 @@
local StepParent = require "game.events.event.parent"
local SimpleMessageStep = StepParent:extend()
function SimpleMessageStep:new(controller, args)
SimpleMessageStep.super.new(self, controller, args)
end
function SimpleMessageStep:start()
game.loot.rings = game.loot.rings + self.arguments.number
end
function SimpleMessageStep:update(dt)
self:finish()
end
return SimpleMessageStep;

View file

@ -0,0 +1,11 @@
return {
["wait"] = require("game.events.event.wait"),
["simpleMessage"] = require("game.events.event.simpleMessage"),
["dialogBox"] = require("game.events.event.dialogbox"),
["optionBox"] = require("game.events.event.dialogbox"),
["playSFX"] = require("game.events.event.playSFX"),
["getRings"] = require("game.events.event.getRings"),
["getItems"] = require("game.events.event.getItems"),
["teleport"] = require("game.events.event.teleport"),
["showGFX"] = require("game.events.event.showGFX")
}

View file

@ -0,0 +1,26 @@
local StepParent = Object:extend()
function StepParent:new(eventSystem, arguments)
self.events = eventSystem
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:finish()
self.events:endStep()
end
function StepParent:draw()
end
return StepParent

View file

@ -0,0 +1,16 @@
local StepParent = require "game.events.event.parent"
local SimpleMessageStep = StepParent:extend()
function SimpleMessageStep:new(controller, args)
SimpleMessageStep.super.new(self, controller, args)
end
function SimpleMessageStep:start()
self.events.scene.assets.sfx[self.arguments.sfx]:play()
end
function SimpleMessageStep:update(dt)
self:finish()
end
return SimpleMessageStep;

View file

@ -0,0 +1,16 @@
local StepParent = require "game.events.event.parent"
local SimpleMessageStep = StepParent:extend()
function SimpleMessageStep:new(controller, args)
SimpleMessageStep.super.new(self, controller, args)
end
function SimpleMessageStep:start()
self.events.scene.world.obj.GFX(self.events.scene.world, self.arguments.x, self.arguments.y, self.arguments.spritename)
end
function SimpleMessageStep:update(dt)
self:finish()
end
return SimpleMessageStep;

View file

@ -0,0 +1,16 @@
local StepParent = require "game.events.event.parent"
local SimpleMessageStep = StepParent:extend()
function SimpleMessageStep:new(controller, args)
SimpleMessageStep.super.new(self, controller, args)
end
function SimpleMessageStep:start()
self.events.scene:showMessage(self.arguments.message)
end
function SimpleMessageStep:update(dt)
self:finish()
end
return SimpleMessageStep;

View file

@ -0,0 +1,23 @@
local StepParent = require "game.events.event.parent"
local SimpleMessageStep = StepParent:extend()
local defTransitions = require "birb.modules.transitions"
function SimpleMessageStep:new(controller, args)
SimpleMessageStep.super.new(self, controller, args)
end
function SimpleMessageStep:start()
local charDir = self.arguments.charDir
if (charDir == "default") then
charDir = self.events.scene.world.players[1].actor.charDir or "down"
end
core.screen:startTransition(defTransitions.default, defTransitions.default,
function() self.events.scene.world:teleport(self.arguments.area, self.arguments.x, self.arguments.y, charDir) end,
0, 0)
end
function SimpleMessageStep:update(dt)
self:finish()
end
return SimpleMessageStep;

View file

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

View file

@ -0,0 +1,101 @@
local EventManager = Object:extend()
local stepObjectList = require "game.events.event"
local Conditions = require "game.events.conditions"
local Predicates = require "birb.classes.predicate"
function EventManager:new(scene)
self.scene = scene
self.world = scene.world
self.isStarted = false
self.currentStepId = 0
self.currentStep = nil
self.stepList = {}
self.flags = {}
end
function EventManager:startEvent(owner, stepList)
self.stepList = stepList
self.flags = {}
self.owner = owner
self.isStarted = true
self.currentStepId = 0
self.currentStep = nil
self.scene:startEvent()
end
function EventManager:addFlag(flagname, flagcontent)
if (flagcontent == true) then
flagcontent = "V"
end
if (flagcontent == false) then
flagcontent = "F"
end
local flag = flagname .. ":" .. flagcontent
table.insert(self.flags, flag)
end
function EventManager:testCondition(condition)
local predicate = Predicates.createPredicate(condition, Conditions, self)
return predicate:solve()
end
function EventManager:haveFlag(flagToTest)
if (flagToTest == nil or flagToTest == "") then
return true
end
return utils.table.contain(self.flags, flagToTest)
end
function EventManager:update(dt)
if (self.isStarted) then
if (self.currentStep ~= nil) then
self.currentStep:updateStep(dt)
else
self:switchStep()
end
end
end
function EventManager:switchStep()
if self:haveNextStep() then
self.currentStepId = self.currentStepId + 1
local stepData = core.datas:parse("eventstep", self.stepList[self.currentStepId])
core.debug:print("event", "Starting step " .. stepData.name)
if (not self:testCondition(stepData.condition)) then
self:switchStep()
else
if (stepObjectList[stepData.name] ~= nil) then
self.currentStep = stepObjectList[stepData.name](self, stepData.arguments)
end
end
else
self:endEvent()
end
end
function EventManager:endStep()
self.currentStep = nil
end
function EventManager:endEvent()
core.debug:print("event", "Ending event, giving back controle")
self.scene:endEvent()
self.isStarted = false
end
function EventManager:haveNextStep()
return ((self.currentStepId + 1) <= #self.stepList)
end
function EventManager:draw()
if (self.isStarted) then
if (self.currentStep ~= nil) then
self.currentStep:draw()
end
end
end
return EventManager

View file

@ -23,79 +23,119 @@
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Game = Object:extend()
local Serializer = require "birb.classes.serializable.serializer"
local Game = Serializer:extend()
local Characters = require "game.characters"
local Ennemies = require "game.ennemies"
local Loot = require "game.loot"
local CBSCore = require "game.battle"
local Difficulty = require "game.difficulty"
local Metadata = require "game.metadata"
local binser = require "core.modules.gamesystem.libs.binser"
local startdata = require "datas.gamedata.startdata"
Game.utils = require "game.modules.utils"
Game.utils = require "game.utils"
Game.gui = require "game.modules.gui"
local VAR_TO_SERIALIZE = {
"gametime",
"destroyedGizmo",
"variables",
"flags",
"position",
"actions",
"characters",
"loot",
"difficulty"
}
function Game:new()
self.slot = -1
self.slotNumber = 3
self.version = core.conf.gameversion or "N/A"
self:reset()
self.metadata = Metadata(self)
Game.super.new(self, VAR_TO_SERIALIZE)
end
function Game:initPosition()
self.position = {}
self.position.x = startdata.position.x
self.position.y = startdata.position.y
self.position.area = startdata.position.area
end
function Game:getMetadataFile(absolute)
local dir = ""
if absolute then
dir = love.filesystem.getSaveDirectory() .. "/"
if not utils.filesystem.exists(dir) then
love.filesystem.createDirectory( "" )
end
end
local filepath = dir .. "metadata.save"
return filepath
end
function Game:getMetadata()
return self.metadata:get()
end
function Game:reset()
self.gametime = 0
self.characters = Characters(self)
self.ennemies = Ennemies(self)
self.loot = Loot(self)
self.cbs = CBSCore(self)
self.difficulty = Difficulty(self)
self:initPosition()
self.flags = {}
self.destroyedGizmo = {}
self.variables = {}
self.completion = 0
self.mapName = ""
self.actions = startdata.actions
end
function Game:setData(data)
local data = data
self.gametime = data.gametime
self.characters:setData(data.characters)
end
function Game:getData()
local data = {}
data.gametime = self.gametime
data.characters = self.characters:getData()
return data
function Game:reload()
self:read(self.slot)
end
function Game:read(save_id)
self.slot = save_id
if (self.slot > 0) then
filepath = self:getSaveFile(self.slot, true)
if love.filesystem.exists("save" .. self.slot .. ".save") then
local loadedDatas = binser.readFile(filepath)
self:setData(loadedDatas[1])
end
self:deserialize(self:getSaveName())
end
end
function Game:write(save_id)
function Game:deleteCurrentSave()
if (self.slot > 0) then
local data = self:getData()
filepath = self:getSaveFile(self.slot, true)
binser.writeFile(filepath, data)
self:delete(self:getSaveName())
self.metadata:remove(self.slot)
end
end
function Game:getSaveFile(saveslot, absolute)
local dir = ""
if absolute then
dir = love.filesystem.getSaveDirectory() .. "/"
if not love.filesystem.exists(dir) then
love.filesystem.createDirectory( "" )
end
function Game:write()
if (self.slot > 0) then
self:serialize(self:getSaveName())
self.metadata:update()
end
end
local filepath = dir .. "save" .. saveslot .. ".save"
return filepath
function Game:getSaveName(saveslot)
local saveslot = saveslot or self.slot
return "save" .. saveslot .. ".save"
end
function Game:resetSaves()
for i=1, 3 do
filepath = self:getSaveFile(i, true)
if love.filesystem.exists("save" .. i .. ".save") then
love.filesystem.remove( "save" .. i .. ".save" )
end
for i=1, self.slotNumber do
self:delete(self:getSaveName(i))
end
end
@ -104,46 +144,15 @@ function Game:update(dt)
end
function Game:getTime()
local time = self.gametime
local hours, minute, seconds
seconds = math.floor(self.gametime)
minutes = math.floor(seconds / 60)
hours = math.floor(minutes / 60)
seconds = seconds % 60
minutes = minutes % 60
hours = hours
return seconds, minutes, hours
return utils.time.getFields(self.gametime)
end
function Game:getTimeString()
local string
local seconds, minutes, hours = self:getTime()
local stringSeconds, stringMinutes, stringHours
if (seconds <= 9) then
stringSeconds = 0 .. seconds
else
stringSeconds = seconds
end
if (minutes <= 9) then
stringMinutes = 0 .. minutes
else
stringMinutes = minutes
end
if (hours <= 9) then
stringHours = 0 .. hours
else
stringHours = hours
end
string = stringHours .. ":" .. stringMinutes .. ":" .. stringSeconds
return string
return utils.time.toString(self.gametime)
end
function Game:printTime()
print(self:getTimeString())
core.debug:print(self:getTimeString())
end
return Game

View file

@ -0,0 +1,55 @@
local EffectManager = Object:extend()
local effectList = require "game.loot.effects"
function EffectManager:new()
self.itemdata = nil;
end
function EffectManager:getItemData(category, item)
self.itemdata = core.datas:get("items", item)
end
function EffectManager:applyEffects(character)
for _, effect in ipairs(self.itemdata.effects) do
local effectInstance = self:getEffectObject(effect, character, self.itemdata.duration)
effectInstance:applyEffect()
end
end
function EffectManager:applyEffectsBattle(battleTarget)
local character = battleTarget.abstract
for _, effect in ipairs(self.itemdata.effects) do
local effectInstance = self:getEffectObject(effect, character, self.itemdata.duration)
effectInstance:applyEffect()
effectInstance:battleCallback(battleTarget)
end
end
function EffectManager:getEffectStrings(character)
local returnString = "No Effect";
if (#self.itemdata.effects >= 1) then
local effectInstance = self:getEffectObject(self.itemdata.effects[1], character, self.itemdata.duration)
if (effectInstance ~= nil) then
returnString = effectInstance:getText() .. "\n"
end
end
if (#self.itemdata.effects >= 2) then
local effectInstance = self:getEffectObject(self.itemdata.effects[2], character, self.itemdata.duration)
if (effectInstance ~= nil) then
returnString = returnString .. effectInstance:getText()
end
end
return returnString
end
function EffectManager:getEffectObject(rawEffectData, character, duration)
local effect = core.datas:parse("itemeffects", rawEffectData)
if (effectList[effect.type] ~= nil) then
return effectList[effect.type](effect, character, duration)
else
return nil
end
end
return EffectManager

View file

@ -0,0 +1,17 @@
local ParentEffect = require "game.loot.effects.parent"
local BlockStatusEffect = ParentEffect:extend()
function BlockStatusEffect:new(effect, character)
self.effect = effect
self.character = character
end
function BlockStatusEffect:applyEffect()
end
function BlockStatusEffect:getText()
return "Block " .. self.effect.blockWhat .. " " .. "effects"
end
return BlockStatusEffect

View file

@ -0,0 +1,79 @@
local ParentEffect = require "game.loot.effects.parent"
local HealEffect = ParentEffect:extend()
function HealEffect:new(effect, character)
self.effect = effect
self.character = character
self.recovered = 0
end
function HealEffect:applyEffect()
self:autosetHealFactor()
self:heal(self.recovered)
end
function HealEffect:autosetHealFactor()
local recovered = 0
local max = self:getMaxValue()
if (self.character:isAlive()) then
if (self.effect.computationMode == "percent") then
recovered = max * (self.effect.value/100)
else
recovered = self.effect.value
end
recovered = math.min(recovered, max - self:getCurrentValue())
end
self.recovered = recovered
end
function HealEffect:getCurrentValue()
if (self.effect.healType == "hp") then
return self.character.hp
elseif (self.effect.healType == "mp") then
return self.character.pp
end
end
function HealEffect:getMaxValue()
local stats = self.character.stats
if (self.effect.healType == "hp") then
return stats:get(stats.HPMAX)
elseif (self.effect.healType == "mp") then
return stats:get(stats.PPMAX)
end
end
function HealEffect:heal(value)
if (self.effect.healType == "hp") then
self.character:setHP(value, true)
elseif (self.effect.healType == "mp") then
self.character:setPP(value, true)
end
end
function HealEffect:battleCallback(fighter)
if (self.effect.healType == "hp") then
fighter.actor:setDamageNumber(self.recovered)
fighter:updateHP()
elseif (self.effect.healType == "mp") then
fighter.actor:setDamageNumber(self.recovered, true)
fighter:updatePP()
end
end
function HealEffect:getText()
local num = self.effect.value
if (self.effect.computationMode == "percent") then
num = num .. "%"
end
local type = ""
if (self.effect.healType == "hp") then
type = "HP"
end
if (self.effect.healType == "mp") then
type = "MP"
end
return "Heal " .. num .. " " .. type;
end
return HealEffect

View file

@ -0,0 +1,6 @@
return {
heal = require "game.loot.effects.heal",
setStatus = require "game.loot.effects.setstatus",
protectElement = require "game.loot.effects.protectelem",
blockStatus = require "game.loot.effects.blockstatus"
}

View file

@ -0,0 +1,21 @@
local EffectParent = Object:extend()
function EffectParent:new(effect, character, duration)
self.effect = effect
self.character = character
self.duration = duration
end
function EffectParent:applyEffect()
end
function EffectParent:getText()
return "No effect"
end
function EffectParent:battleCallback(fighter)
end
return EffectParent

View file

@ -0,0 +1,19 @@
local ParentEffect = require "game.loot.effects.parent"
local ProtectElemEffect = ParentEffect:extend()
function ProtectElemEffect:new(effect, character)
self.effect = effect
self.character = character
end
function ProtectElemEffect:applyEffect()
end
function ProtectElemEffect:getText()
local returnString = "Protect from " .. self.effect.element
return returnString
end
return ProtectElemEffect

View file

@ -0,0 +1,43 @@
local ParentEffect = require "game.loot.effects.parent"
local StatusEffect = ParentEffect:extend()
function StatusEffect:new(effect, character, duration)
self.effect = effect
self.character = character
self.duration = duration or -1
end
function StatusEffect:applyEffect()
if (self.effect.set) then
self:addStatut()
else
self:removeStatut()
end
end
function StatusEffect:addStatut()
self.character:addStatut(self.effect.status, self.duration)
end
function StatusEffect:removeStatut()
self.character:removeStatut(self.effect.status)
end
function StatusEffect:getText()
local returnString = ""
if (self.effect.set) then
returnString = returnString .. "Give "
else
returnString = returnString .. "Remove "
end
if (self.effect.status == "allNegative") then
returnString = returnString .. "all negative effects"
else
returnString = returnString .. self.effect.status .. " " .. "effect"
end
return returnString
end
return StatusEffect

View file

@ -0,0 +1,67 @@
local Serializable = require "birb.classes.serializable"
local LootManager = Serializable:extend()
local Pocket = require "game.loot.pocket"
local EffectManager = require "game.loot.effectManager"
function LootManager:new(controller)
self.controller = controller
self.rings = 0
self.inventory = {}
self.pocketIndex = {}
self.effects = EffectManager()
self:generatePockets()
LootManager.super.new(self, {}, {"inventory"})
end
function LootManager:generatePockets()
local structure = require "datas.gamedata.items"
for i,pocketdata in ipairs(structure) do
local pocket = Pocket(pocketdata)
self.pocketIndex[pocketdata.name] = i
table.insert(self.inventory, pocket)
end
end
function LootManager:getPocketIdByName(name)
return self.pocketIndex[name]
end
function LootManager:getPocketById(id)
return self.inventory[id]
end
function LootManager:getPocketByName(name)
return self.inventory[self.pocketIndex[name]]
end
function LootManager:addItem(type, item, number)
local pocket = self:getPocketByName(type)
if (core.datas:exists("items", item)) then
pocket:addItem(item, number)
end
end
function LootManager:removeItem(type, item, number)
local pocket = self:getPocketByName(type)
if (core.datas:exists("items", item)) then
pocket:removeItem(item, number)
end
end
function LootManager:getItemNumber(type, item)
local pocket = self:getPocketByName(type)
return pocket:getItemNumber(item)
end
function LootManager:applyItemEffect(category, item, target)
self.effects:getItemData(category, item)
self.effects:applyItemEffect(target)
end
function LootManager:getEffectStrings(category, item)
self.effects:getItemData(category, item)
return self.effects:getEffectStrings(nil)
end
return LootManager

View file

@ -0,0 +1,62 @@
local Serializable = require "birb.classes.serializable"
local Pocket = Serializable:extend()
function Pocket:new(pocketdata)
self.name = pocketdata.name
self.fullname = pocketdata.fullname
self.inBattle = pocketdata.inBattle
self.description = pocketdata.description
self.isEquipement = pocketdata.isEquipement
self.list = {}
Pocket.super.new(self, {"list"})
end
function Pocket:addItem(item, number)
local success = false
for i,itemData in ipairs(self.list) do
if (itemData.name == item) then
itemData.number = itemData.number + number
success = true
end
end
if (not success) then
local itemData = {}
itemData.name = item
itemData.number = number
table.insert(self.list, itemData)
end
end
function Pocket:removeItem(item, number)
for i,itemData in ipairs(self.list) do
if (itemData.name == item) then
if (itemData.number > number) then
itemData.number = itemData.number - number
else
table.remove(self.list, i)
end
end
end
end
function Pocket:getItem(name)
for i, itemData in ipairs(self.list) do
if (itemData.name == name) then
return itemData
end
end
return nil
end
function Pocket:getItemNumber(name)
local item = self:getItem(name)
if (item == nil) then
return 0
else
return item.number
end
end
return Pocket

View file

@ -0,0 +1,83 @@
-- game.metadata :: Basic metadata subsystem
--[[
Copyright © 2021 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 Serializer = require "birb.classes.serializable.serializer"
local Metadata = Serializer:extend()
local META_FILE = "metadata.save"
function Metadata:new(game)
self.game = game
self:reset()
Metadata.super.new(self, {"data"})
end
function Metadata:reset()
self.data = {}
for i = 1, self.game.slotNumber, 1 do
local newMetadata = {}
newMetadata.exist = false
newMetadata.completion = 0
newMetadata.gametime = 0
newMetadata.team = {}
newMetadata.rings = 0
newMetadata.emeralds = 0
newMetadata.location = ""
table.insert(self.data, newMetadata)
end
end
function Metadata:update()
self:read()
if (self.data[self.game.slot] == nil) then
self.data[self.game.slot] = {}
end
self.data[self.game.slot].exist = true
self.data[self.game.slot].completion = self.game.completion
self.data[self.game.slot].gametime = self.game.gametime
self.data[self.game.slot].team = self.game.characters.team
self.data[self.game.slot].rings = self.game.loot.rings
self.data[self.game.slot].emeralds = 0
self.data[self.game.slot].location = self.game.mapName
self:write()
end
function Metadata:get()
self:read()
return self.data
end
function Metadata:write()
self:serialize(META_FILE)
end
function Metadata:read()
self:deserialize(META_FILE)
end
function Metadata:remove(slot)
self.data[slot].exist = false
self:write()
end
return Metadata

View file

@ -0,0 +1,97 @@
local GuiElement = require "birb.modules.gui.elements.canvas"
local ConfirmDialog = GuiElement:extend()
local gui = require "game.modules.gui"
local WIDTH = 256
local PADWIDTH = 16
local PADHEIGHT = 16
local DEFAULT_LINES = 2
function ConfirmDialog:new(scene, message, choice1func, choice1, choice2func, choice2)
self.scene = scene
self.lines = DEFAULT_LINES
self.message = message
self.choiceLabel = {}
self.choiceFunc = {}
self.choiceSound = {}
self.choiceLabel[1] = choice1 or "Yes"
self.choiceLabel[2] = choice2 or "No"
self.choiceFunc[1] = choice1func
self.choiceFunc[2] = choice2func or function() self:dismiss() end
self.choiceSound[1] = "mSelect"
self.choiceSound[2] = "mBack"
self.autoDismiss = false
self.darken = true
self.currentChoice = 0
self.cancelChoice = -1
ConfirmDialog.super.new(self, "dialog", 424/2, 240/2, WIDTH + PADWIDTH, self:computeHeight())
self.back = gui.newTextBox("assets/gui/dialogbox.png", self.w, self.h)
self.ox = self.w/2
self.oy = self.h/2
self.canvas.padding = 0
self.depth = 0
self.isVisible = 1
self:getFocus()
end
function ConfirmDialog:setLines(lines)
self.lines = lines
self.h = self:computeHeight()
self.oy = self.h/2
self.canvas.needRedraw = true
self.back = gui.newTextBox("assets/gui/dialogbox.png", self.w, self.h)
end
function ConfirmDialog:computeHeight()
return 32 + (self.lines * 16) + PADHEIGHT
end
function ConfirmDialog:setCancelChoice(choice)
self.cancelChoice = choice - 1
end
function ConfirmDialog:keypressed(key)
if (key == "up" or key == "down") then
self.currentChoice = (self.currentChoice + 1) % 2
self.scene.assets.sfx["mBeep"]:play()
self.canvas.needRedraw = true
elseif (key == "A") then
self:doAction(self.currentChoice)
elseif (key == "B") then
self:doAction(self.cancelChoice)
end
end
function ConfirmDialog:doAction(choice)
if (self.choiceFunc[choice + 1] ~= nil) then
self.scene.assets.sfx[self.choiceSound[choice + 1]]:play()
self.choiceFunc[choice + 1]()
if (self.autoDismiss) then
self:dismiss()
end
end
end
function ConfirmDialog:dismiss()
self.gui:setLastFocus()
self:destroy()
end
function ConfirmDialog:drawTexture()
love.graphics.draw(self.back, 0)
local padx, pady = 8, 6
self.scene.assets.fonts["small"]:draw(self.message ,padx, pady, WIDTH,"left")
for i = 1, 2, 1 do
self.scene.assets.fonts["small"]:draw(self.choiceLabel[i], padx + 8, pady + (self.lines + i - 1)*16)
if ((self.currentChoice + 1) == i) then
self.scene.assets.fonts["small"]:draw(">", padx, pady + (self.lines + i - 1)*16)
end
end
end
return ConfirmDialog

View file

@ -0,0 +1,23 @@
local GrayScale = {}
local greyscaleShader = love.graphics.newShader[[
vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords ){
vec4 pixel = Texel(texture, texture_coords );//This is the current pixel color
number average = (pixel.r+pixel.b+pixel.g)/3.0;
pixel.r = average;
pixel.g = average;
pixel.b = average;
return pixel;
}
]]
function GrayScale.startShader()
love.graphics.setShader(greyscaleShader)
end
function GrayScale.endShader()
love.graphics.setShader()
end
return GrayScale

View file

@ -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(datas.tiles)
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(-maputils.CONST.STARTX, -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

View file

@ -0,0 +1,52 @@
local CanvasElement = require "birb.modules.gui.elements.parent"
local ActionPrompt = CanvasElement:extend()
function ActionPrompt:new()
self.text = ""
ActionPrompt.super.new(self, "actionPrompt", 0, 0, 424, 240)
self.depth = -2
self.opacity = 0
self.isShown = false
end
function ActionPrompt:setText(text)
if (utils.string.isEmpty(text)) then
self:hide()
else
self.text = text
self:show()
end
end
function ActionPrompt:hide()
if (self.isShown) then
self.tweens.tweens = {}
self:newTween(0.0, 0.6, {opacity = 0}, "outExpo")
end
self.isShown = false
end
function ActionPrompt:show()
if (not self.isShown) then
self.tweens.tweens = {}
self:newTween(0.0, 0.6, {opacity = 1}, "outExpo")
end
self.isShown = true
end
function ActionPrompt:draw()
if (not utils.string.isEmpty(self.text)) then
local w = self.assets.fonts["small"]:getWidth(self.text) + 16
love.graphics.setColor(0,0,0,0.5 * self.opacity)
local x, y = 424 - w/2 - 4, 240 - 20
love.graphics.rectangle("fill", x - w/2, y + 1, w, 15, 8, 8)
love.graphics.setColor(1, 1, 1, self.opacity)
self.assets.fonts["small"]:setColor(1, 1, 1, self.opacity)
self.assets.fonts["small"]:draw(self.text, x, y, -1, "center")
self.assets.fonts["small"]:setColor(1, 1, 1, 1)
utils.graphics.resetColor()
end
end
return ActionPrompt

View file

@ -0,0 +1,71 @@
local ParentMenu = require "birb.modules.gui.textmenu"
local BoxedList = ParentMenu:extend()
local gui = require "game.modules.gui"
function BoxedList:new(name, x, y, w, slotNumber, isBoxed, smallborder)
BoxedList.super.new(self, name, "small", x, y, w, slotNumber, 0)
self.paddingLeft = 12
self.paddingRight = 4
self.cursorTexture = love.graphics.newImage("assets/gui/cursor-menulist.png")
self.cursorTransition = 0
self.isBoxed = isBoxed
if (isBoxed) then
local border = self.h + 16
if (smallborder == true) then
border = self.h + 8
end
self.box = gui.newTextBox("assets/gui/dialogbox.png", w + 8, border)
end
end
function BoxedList:finalize()
self:setCancelWidget()
end
function BoxedList:update(dt)
BoxedList.super.update(self, dt)
self:updateCursorPosition(dt)
end
function BoxedList:updateCursorPosition(dt)
local relativecursor = self.widget.selected - self.view.firstSlot
local transition = self.cursorTransition - relativecursor
if math.abs(transition) < 0.1 then
self.cursorTransition = relativecursor
else
local speed = dt * 45
local movement = ((relativecursor) - (self.cursorTransition))
self.cursorTransition = (self.cursorTransition) + movement * speed
end
end
function BoxedList:drawCursor()
local x, y = self:getCursorPosition()
love.graphics.draw(self.cursorTexture, x, y)
end
function BoxedList:getCursorPosition()
local addition = self.lineHeight
local x = self.x + 6
local y = self.y + ((self.cursorTransition) * addition) + 1
return x, y
end
function BoxedList:draw()
if (self.isBoxed) then
local dy = 8
if (self.smallborder) then
dy = 4
end
local w, h = self.box:getDimensions()
local diff = (w-self.w)/2
love.graphics.draw(self.box, self.x - self.ox - diff, self.y - self.oy - dy)
end
BoxedList.super.draw(self)
end
return BoxedList

View file

@ -0,0 +1,22 @@
local CanvasElement = require "birb.modules.gui.elements.canvas"
local ChoiceElement = CanvasElement:extend()
local gui = require "game.modules.gui"
function ChoiceElement:new(name, label1, label2, label3, x, y, approximateWidth)
self.background = gui.newChoiceBack(approximateWidth)
local w, h = self.background:getDimensions()
ChoiceElement.super.new(self, name, x, y, w, h)
self.label1 = label1
self.label2 = label2
self.label3 = label3
end
function ChoiceElement:drawTexture()
love.graphics.draw(self.background, 0, 0)
self.assets.fonts["small"]:draw(self.label1, 16, -2, -1, "left")
self.assets.fonts["small"]:draw(self.label2, self.w/2, -2, -1, "center")
self.assets.fonts["small"]:draw(self.label3, self.w - 20, -2, -1, "right")
end
return ChoiceElement

View file

@ -0,0 +1,85 @@
local ComplexHPBar = Object:extend()
local gui = require "game.modules.gui"
local VALUE_MARGIN = 11
local HEIGHT = 7
function ComplexHPBar:new(width)
self.width = width
self:setColorForeground(1, 1, 1)
self:setColorBackground(0, 0, 0)
self.background = self:createBack( "assets/gui/hpbar_back.png" )
self.foreground = self:createBack( "assets/gui/hpbar_fore.png" )
end
function ComplexHPBar:setColorForeground(r, g, b)
self.barcolor = {}
self.barcolor.r = r
self.barcolor.g = g
self.barcolor.b = b
end
function ComplexHPBar:setColorBackground(r, g, b)
self.backcolor = {}
self.backcolor.r = r
self.backcolor.g = g
self.backcolor.b = b
end
function ComplexHPBar:createBack( filepath )
local image = love.graphics.newImage( filepath )
local imageWidth, imageHeight = image:getDimensions()
local middleImageWidth = imageWidth - VALUE_MARGIN*2
local totalWidth = self.width + 8 -- On récupère la taille à partir de la base
local middleWidth = totalWidth - VALUE_MARGIN*2
local iteration = math.ceil((middleWidth) / (middleImageWidth))
local tilequad = {}
tilequad[1] = love.graphics.newQuad(0, 0, VALUE_MARGIN, imageHeight, imageWidth, imageHeight)
tilequad[2] = love.graphics.newQuad(VALUE_MARGIN, 0, middleImageWidth, imageHeight, imageWidth, imageHeight)
tilequad[3] = love.graphics.newQuad(imageWidth - VALUE_MARGIN, 0, VALUE_MARGIN, imageHeight, imageWidth, imageHeight)
local canvas1 = love.graphics.newCanvas(middleWidth, imageHeight)
love.graphics.setCanvas( canvas1 )
local combinedWidth = 0
for i = 1, iteration do
love.graphics.draw(image, tilequad[2], combinedWidth, 0)
combinedWidth = combinedWidth + middleImageWidth
end
local canvas2 = love.graphics.newCanvas(totalWidth, imageHeight)
love.graphics.setCanvas( canvas2 )
love.graphics.draw(image, tilequad[1], 0, 0)
love.graphics.draw(canvas1, VALUE_MARGIN, 0)
love.graphics.draw(image, tilequad[3], totalWidth - 11, 0)
love.graphics.setCanvas( )
local imagedata = canvas2:newImageData()
local texture = love.graphics.newImage( imagedata )
imagedata:release()
canvas2:release()
return texture
end
function ComplexHPBar:draw(x, y, percent)
utils.graphics.resetColor()
love.graphics.draw(self.foreground, x, y)
love.graphics.setColor(self.backcolor.r, self.backcolor.g, self.backcolor.b, 1)
love.graphics.draw(self.background, x, y)
utils.graphics.resetColor()
love.graphics.setColor(self.barcolor.r, self.barcolor.g, self.barcolor.b, 1)
gui.drawBar(x + 4, y + 2, math.floor((self.width) * percent), HEIGHT)
utils.graphics.resetColor()
end
function ComplexHPBar:drawWithLabels(x, y, value, valuemax)
local percent = value / valuemax
self:draw(x, y, percent)
love.graphics.print(math.floor(value) .. "/" .. valuemax, x+10, y+2)
end
return ComplexHPBar

View file

@ -0,0 +1,45 @@
local Emblem = Object:extend()
local greyscale = require "game.modules.drawing.greyscale"
function Emblem:new(abstract, scene)
self.assets = scene.assets
self.abstract = abstract
self.charid = self.abstract.simplename
self.stats = self.abstract:getStats()
end
function Emblem:draw(x, y)
self:drawBackground(x, y)
self:drawForeground(x, y)
end
function Emblem:drawForeground(x, y)
local emblem2 = "m_" .. self.abstract.data.class
core.screen:setScissor(x, y-16, 32, 40)
if (self.abstract.hp > 0) then
self.assets.sprites[self.charid]:draw(x+14, y+14)
else
greyscale.startShader()
self.assets.sprites[self.charid]:drawFrame(1, x+14, y+14)
end
core.screen:resetScissor( )
self.assets.images[emblem2]:draw(x, y)
greyscale.endShader()
end
function Emblem:drawBackground(x, y)
local emblem1 = "e_" .. self.abstract.data.class
if (self.abstract.hp > 0) then
self.assets.images[emblem1]:draw(x, y)
else
greyscale.startShader()
self.assets.images[emblem1]:draw(x, y)
greyscale.endShader()
end
end
return Emblem

View file

@ -0,0 +1,32 @@
local ParentMenu = require "birb.modules.gui.textmenu"
local FancyMenu = ParentMenu:extend()
local gui = require "game.modules.gui"
function FancyMenu:new(name, x, y, w, itemNumber, haveBiseau)
FancyMenu.super.new(self, name, "small", x, y, w, itemNumber)
self.biseau = utils.math.either(haveBiseau, 8, 0)
self.itemNumber = itemNumber
self.box = gui.newChoiceBack(self.w + 24)
self.cursorTexture = love.graphics.newImage("assets/gui/cursor-menulist.png")
end
function FancyMenu:getDimensions()
local w, h = FancyMenu.super.getDimensions(self)
return w + (self.biseau*self.itemNumber), h
end
function FancyMenu:getListPart(i)
local x, y, w, h = FancyMenu.super.getListPart(self, i)
return x + (self.biseau*i), y, w, h
end
function FancyMenu:drawWidgetBackground(x, y, w, h)
love.graphics.draw(self.box, x - 8, y + 2)
end
function FancyMenu:drawGraphicalCursor(x, y, w, h)
love.graphics.draw(self.cursorTexture, x - 3, y + 1)
end
return FancyMenu

View file

@ -1,17 +0,0 @@
local Frame = Object:extend()
function Frame:new()
self.guiborder = game.gui.newBorder(424, 20, 6)
self.guiborder2 = game.gui.newBorder(424, 40, 12)
end
function Frame:draw()
love.graphics.setColor(0.256, 0.632, 0.852, 1)
love.graphics.rectangle("fill", 0, 220, 424, 20)
utils.graphics.resetColor()
love.graphics.draw(self.guiborder, 424, 20, 0, -1, -1)
love.graphics.draw(self.guiborder2, 424, 220, 0, 1, 1, 424, 0)
love.graphics.print(love.timer.getFPS(), 200, 8)
end
return Frame

View file

@ -0,0 +1,44 @@
local Screen = require "birb.modules.gui.screen"
local GameOverScreen = Screen:extend()
local TextElement = require "birb.modules.gui.elements.text"
local ConfirmDialog = require "game.modules.confirmdialog"
local defTransitions = require "birb.modules.transitions"
local HEIGHT = 40
local show = {
{"gameText", "movement", 0.9, 0.4, 424/2 - 4, HEIGHT, "inExpo"},
{"overText", "movement", 0.9, 0.4, 424/2 + 4, HEIGHT, "inExpo"}
}
function GameOverScreen:new()
GameOverScreen.super.new(self, "titleScreen")
self:addTransform("show", show)
self.scene:showOverlay(true)
self:show()
end
function GameOverScreen:createElements()
return {
{TextElement("gameText", "SA2font", "GAME", 0, HEIGHT, "right"), 0, 1},
{TextElement("overText", "SA2font", "OVER", 424, HEIGHT, "left"), 0, 1},
{ConfirmDialog(self.scene, "Do you want to return to title ? \nYou can also reload your latest save.",
function() self:returnToTitle() end, "Return to title",
function() self:loadLastSave() end, "Reload last save"),
1.8, 0}
}
end
function GameOverScreen:returnToTitle()
core.screen:startTransition(defTransitions.default, defTransitions.circle, function() scenes.menus.title(true) end, 424/2, 240/2)
end
function GameOverScreen:loadLastSave()
self.scene.tweens:newTween(0, 0.3, {borderPosition=0}, "inOutQuad")
core.screen:startTransition(defTransitions.default, defTransitions.default, function() game:reload() scenes.overworld() end, 424/2, 240/2)
end
return GameOverScreen

View file

@ -1,9 +1,9 @@
local gui = {}
local barborder = love.graphics.newImage("assets/gui/status/barborder.png")
local barborder = love.graphics.newImage("assets/gui/barborder.png")
function gui.newBorder(width, height, middlePosition)
local tileset = love.graphics.newImage("assets/gui/system/borders.png")
local tileset = love.graphics.newImage("assets/gui/borders.png")
local tilequad = {}
local w, h = tileset:getDimensions()
tilequad[1] = love.graphics.newQuad(0, 0, 20, 20, w, h)
@ -11,9 +11,9 @@ function gui.newBorder(width, height, middlePosition)
tilequad[3] = love.graphics.newQuad(40, 0, 20, 20, w, h)
tilequad[4] = love.graphics.newQuad(60, 0, 20, 20, w, h)
local Texture = love.graphics.newCanvas(width, height)
local canvas = love.graphics.newCanvas(width, height)
love.graphics.setCanvas(Texture)
love.graphics.setCanvas(canvas)
utils.graphics.resetColor()
local height = math.ceil(height / 20)
@ -37,7 +37,45 @@ function gui.newBorder(width, height, middlePosition)
love.graphics.setCanvas( )
return Texture
local imagedata = canvas:newImageData()
local texture = love.graphics.newImage( imagedata )
imagedata:release()
canvas:release()
return texture
end
function gui.newChoiceBack(approximateWidth)
local asset = love.graphics.newImage("assets/gui/attacklist.png")
local sw, sh = asset:getDimensions()
local startAsset = love.graphics.newQuad(0, 0, 21, sh, sw, sh)
local midAsset = love.graphics.newQuad(21, 0, 12, sh, sw, sh)
local endAsset = love.graphics.newQuad(sw-25, 0, 25, sh, sw, sh)
local iterations = math.floor((approximateWidth / 12) - 4)
local width = (iterations * 12)
local height = 16
local canvasWidth = width + 21 + 25
local canvas = love.graphics.newCanvas(canvasWidth, height)
love.graphics.setCanvas(canvas)
love.graphics.draw(asset, startAsset, 0, 0)
love.graphics.draw(asset, endAsset, 21 + width, 0)
for i=1, (iterations) do
love.graphics.draw(asset, midAsset, 21 + ((i-1)*12), 0)
end
love.graphics.setCanvas( )
local imagedata = canvas:newImageData()
local texture = love.graphics.newImage( imagedata )
imagedata:release()
canvas:release()
return texture
end
function gui.drawBar(x, y, width, height)
@ -52,9 +90,8 @@ function gui.drawBar(x, y, width, height)
end
end
function gui.newTextBox(type, width, height)
local filepath = "assets/gui/dialogs/" .. type .. ".png"
local baseimage = love.graphics.newImage(filepath)
function gui.newTextBox(filename, width, height)
local baseimage = love.graphics.newImage(filename)
local quad = {}
quad[1] = love.graphics.newQuad(00, 00, 8, 8, 24, 24)
quad[2] = love.graphics.newQuad(00, 08, 8, 8, 24, 24)
@ -109,7 +146,50 @@ function gui.newTextBox(type, width, height)
love.graphics.setCanvas( )
return canvas
local imagedata = canvas:newImageData()
local texture = love.graphics.newImage( imagedata )
imagedata:release()
canvas:release()
return texture
end
function gui.getEmeraldsTexture(number)
local canvas = love.graphics.newCanvas(95, 31)
local emeralds = love.graphics.newImage("assets/gui/emeralds.png")
love.graphics.setCanvas( canvas )
for i = 1, 7, 1 do
local emerald
local x = (i-1)*12
if (i > number) then
emerald = love.graphics.newQuad(0,0,23,17,23*8, 17)
else
emerald = love.graphics.newQuad((i*23),0,23,17,23*8, 17)
--emerald = love.graphics.newQuad((i*23),0,23,17,23*7, 17)
end
local isPair = (i%2 == 0)
local y = 0
if (isPair == true) then
y = 14
end
love.graphics.draw(emeralds, emerald,x,y)
emerald:release()
end
love.graphics.setCanvas( )
local imagedata = canvas:newImageData()
local texture = love.graphics.newImage( imagedata )
imagedata:release()
canvas:release()
return texture
end
function gui.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

View file

@ -0,0 +1,72 @@
local TextureElement = require "birb.modules.gui.elements.parent"
local MenuBack = TextureElement:extend()
local backx = 0
local bordery = 0
local turn = 0
local fancyBackShader = love.graphics.newShader[[
uniform number screenWidth;
uniform number screenHeight;
vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords ){
vec4 pixel = Texel(texture, texture_coords); //This is the current pixel color
number value = (screen_coords.x / screenWidth) * (screen_coords.y / screenHeight) * 0.5;
number lighten = 0.25;
return vec4(0.5 + value + lighten,0.0 + lighten,0.5 - value + lighten, 1 - pixel.r);
//return vec4(1,1,1, pixel.r);
}
]]
function MenuBack:new()
self.back = love.graphics.newImage("assets/gui/back/background.png")
self.border = love.graphics.newImage("assets/gui/back/border.png")
self.emblem = love.graphics.newImage("assets/gui/back/emblem.png")
self.star = love.graphics.newImage("assets/gui/back/star.png")
self.backImage = love.graphics.newImage("assets/artworks/back.png")
self.canvas = nil
local w, h = love.graphics.getDimensions()
fancyBackShader:send("screenWidth",w)
fancyBackShader:send("screenHeight",h)
MenuBack.super.new(self, "menuBack", 0, 0, w, h)
self.depth = 200
end
function MenuBack:update(dt)
backx = (backx + dt * 20) % 96
bordery = (bordery + dt * 35) % 160
turn = turn + (dt/1.5) % 1
self.canvas = love.graphics.newCanvas( 424, 240 )
love.graphics.setCanvas(self.canvas)
for i = 0, (math.ceil(424/96)), 1 do
for j = 0, (math.ceil(240/96)), 1 do
love.graphics.draw(self.back, backx + ((i - 1 ) * 96), backx + ((j - 1 ) * 96))
end
end
for j = 0, (math.ceil(240/160)), 1 do
love.graphics.draw(self.border, 0, bordery + ((j - 1) * 160))
end
love.graphics.draw(self.emblem, 424, 240 - 32, 0, 0.8, 0.8, 200, 200)
love.graphics.draw(self.star, 424, 240 - 32, turn, 0.8, 0.8, 200, 200)
love.graphics.setColor(1, 1, 1, 1)
love.graphics.setCanvas()
end
function MenuBack:draw()
love.graphics.setColor(1, 1, 1, 1)
love.graphics.rectangle("fill", 0, 0, 424, 240)
love.graphics.setShader(fancyBackShader)
if (self.canvas ~= nil) then
love.graphics.draw(self.canvas, 0, 0)
end
love.graphics.setShader()
utils.graphics.resetColor()
love.graphics.draw(self.backImage, 0, 0)
end
return MenuBack

View file

@ -0,0 +1,96 @@
local GuiScreen = require "birb.modules.gui.screen"
local TextureElement = require "birb.modules.gui.elements.drawable"
local ColorElement = require "birb.modules.gui.elements.color"
local TextElement = require "birb.modules.gui.elements.text"
local OverlayScreen = GuiScreen:extend()
local gui = require "game.modules.gui"
local either = utils.math.either
local OVERLAY_OPACITY = 0.5
local wasActive = false
local hadVersion = false
local animateAppear = {
{"upBorder", "movement", 0.0, 0.5, 0, 30, "inOutQuart"},
{"downBorder", "movement", 0.0, 0.5, 424, 210, "inOutQuart"}
}
local animateDisappear = {
{"upBorder", "movement", 0.0, 0.5, 0, 0, "inOutQuart"},
{"downBorder", "movement", 0.0, 0.5, 424, 240, "inOutQuart"},
{"version", "movement", 0.0, 0.5, 380, 250, "inOutQuart"},
{"overlayDarken", "tween", 0.0, 0.6, {opacity = 0}, "outExpo"}
}
local showBackground = {
{"overlayDarken", "tween", 0.0, 0.6, {opacity = OVERLAY_OPACITY}, "inExpo"}
}
local hideBackground = {
{"overlayDarken", "tween", 0.0, 0.6, {opacity = 0}, "outExpo"}
}
local showVersion = {
{"version", "movement", 0.0, 0.5, 380, 220, "inOutQuart"},
}
local hideVersion = {
{"version", "movement", 0.0, 0.5, 380, 250, "inOutQuart"},
}
function OverlayScreen:new(active, doShowVersion)
self.borders = gui.newBorder(424, 30, 8)
self.doShowVersion = doShowVersion
OverlayScreen.super.new(self, "overlay")
local transformStuff = false
if (active == wasActive) then
self.isVisible = active
else
transformStuff = true
end
self:addTransform("show", animateAppear)
self:addTransform("hide", animateDisappear)
self:addTransform("showBackground", showBackground)
self:addTransform("hideBackground", hideBackground)
self:addTransform("showVersion", showVersion)
self:addTransform("hideVersion", hideVersion)
if (transformStuff) then
if (active) then
self:show()
else
self:hide()
end
end
if (active) then
if (self.doShowVersion) then
self:playTransform("showVersion")
else
self:playTransform("hideVersion")
end
end
end
function OverlayScreen:update(dt)
wasActive = self.isVisible
hadVersion = self.doShowVersion
end
function OverlayScreen:createElements()
local d = either(wasActive, 30, 0)
local v = either(hadVersion, 30, 0)
return {
{TextureElement("upBorder", self.borders, 0, d, 0, 1, -1, 0, 0, 1), 0, -1},
{TextureElement("downBorder", self.borders, 424, 240 - d, 0, -1, 1, 0, 0, 1), 0, -1},
{ColorElement("overlayDarken", 0, 0, 0, 0), 0, 5},
{TextElement("version", "small", "v" .. game.version, 380, 250 - v, "left"), 0, -1}
}
end
return OverlayScreen

View file

@ -0,0 +1,30 @@
local SimpleHPBar = Object:extend()
local TweenManager = require "birb.classes.time"
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.rectangle("fill", x, y, 24, 4)
love.graphics.setColor(248/255, 160/255, 0, 1)
local bar = math.max(0, math.floor(22 * (self.hp / self.baseHP)))
love.graphics.rectangle("fill", x + 1, y + 1, math.floor(bar), 2)
love.graphics.setColor(1, 1, 1, 1)
end
return SimpleHPBar

View file

@ -1,60 +0,0 @@
local StatusArea = Object:extend()
function StatusArea:new(character, type, hpmax)
self.type = "e_" .. type;
self.hpmax = hpmax;
self.hp = hpmax;
self.pp = 100;
self.ppmax = 100;
self.assets = character.assets
self.weapon = 0
self.rings = 0
end
function StatusArea:setWeapon(weapon)
self.weapon = weapon
end
function StatusArea:setRings(rings)
self.rings = rings
end
function StatusArea:setHp(hp)
self.hp = hp
end
function StatusArea:setPp(pp)
self.pp = pp
end
function StatusArea:draw(x, y)
local x = x or 0
local y = y or 0
self.assets.images[self.type]:draw(x, y)
if (self.weapon ~= 0) then
self.assets.tileset["weapons"]:drawTile(self.weapon, x-2, y-2)
end
self.assets.images["statusbar"]:draw(x+8, y-2)
local bar1 = math.floor((self.hp/self.hpmax)*107)
local bar2 = math.floor((self.pp/100)*108)
love.graphics.setColor(248/255, 160/255, 0, 1)
game.gui.drawBar(x+25, y+9, bar1, 7)
love.graphics.setColor(0, 248/255, 248/255, 1)
game.gui.drawBar(x+13, y+21, bar2, 7)
utils.graphics.resetColor()
self.assets.fonts["smallnumbers"]:set()
love.graphics.print(math.floor(self.hp) .. "/" .. self.hpmax, x+34, y+9)
love.graphics.print(math.floor(self.pp) .. "%", x+34, y+21)
self.assets.fonts["numbers"]:set()
love.graphics.print(utils.math.numberToString(self.rings, 3), x+88, y-5)
self.assets.images["hudring"]:draw(x+125, y-6)
end
return StatusArea

View file

@ -0,0 +1,78 @@
local List = require "game.modules.menus.list"
local fancy = {}
fancy.FancyMenu = List.ListMenu:extend()
fancy.BaseWidget = List.CenteredWidget:extend()
fancy.SubMenuWidget = fancy.BaseWidget:extend()
local MENU_ITEM_HEIGHT = 16
local gui = require "game.modules.gui"
function fancy.FancyMenu:new(scene, name, x, y, w, itemNumber, haveBiseau)
fancy.FancyMenu.super.new(self, scene, name, x, y, w, itemNumber, false)
self.haveBiseau = haveBiseau
end
function fancy.FancyMenu:getCursorPosition()
if (self.haveBiseau) then
local addition = MENU_ITEM_HEIGHT
local x = self.x + 4 + ((self.cursorTransition) * addition)/2
local y = self.y + ((self.cursorTransition) * addition)
return x, y
else
return fancy.FancyMenu.super.getCursorPosition(self)
end
end
function fancy.FancyMenu:getNextPosition(x, y, h)
if (self.haveBiseau) then
return (x + (h/2)), y+h
else
return fancy.FancyMenu.super.getNextPosition(self, x, y, h)
end
end
function fancy.FancyMenu:clone(name)
return fancy.FancyMenu(self.scene, name, self.x, self.y, self.w, self.itemNumber, self.haveBiseau)
end
function fancy.FancyMenu:addSubMenuWidget(newmenu, name)
fancy.SubMenuWidget(self.scene, self.name, newmenu, name)
end
-- FancyWidgets
-- Add Fancy Widgets
function fancy.BaseWidget:new(scene, menu_name, label, label2)
self.label2 = label2
fancy.BaseWidget.super.new(self, scene, menu_name, label)
self.box = gui.newChoiceBack(self.menu.w + 24)
end
function fancy.BaseWidget:drawCanvas()
love.graphics.draw(self.box, 0, 0)
local h = math.floor(self.height / 2) - (self.font:getHeight() / 2) - 2
self.font:setColor(self.color[1], self.color[2], self.color[3], 1)
self.font:draw(self.label, 16, h, -1, "left")
self.font:draw(self.label2, self.width -8, h, -1, "right")
self.font:setColor(1, 1, 1, 1)
utils.graphics.resetColor()
end
-- Widget de sous-menu
function fancy.SubMenuWidget:new(scene, menu_name, newmenu, label)
local label2 = ""
if (label ~= "Back") then
label2 = ">"
end
fancy.SubMenuWidget.super.new(self, scene, menu_name, label, label2)
self.newmenu = newmenu
end
function fancy.SubMenuWidget:action()
self.scene.assets:playSFX("mBeep")
self.scene.menusystem:switchMenu(self.newmenu)
self.scene.menusystem.menus[self.newmenu]:activationAction()
end
return fancy

View file

@ -0,0 +1,172 @@
local ParentMenu = require "game.modules.menus.parents.menu"
local Widget = require "birb.modules.menusystem.widgets"
local list = {}
list.ListMenu = ParentMenu:extend()
list.CenteredWidget = Widget.Text:extend()
list.DualTextWidget = list.CenteredWidget:extend()
list.SubMenuWidget = list.DualTextWidget:extend()
local MENU_ITEM_HEIGHT = 16
local gui = require "game.modules.gui"
-- ListMenu
function list.ListMenu:new(scene, name, x, y, w, itemNumber, isBoxed, smallborder)
self.scene = scene
self.name = name
local h = itemNumber * MENU_ITEM_HEIGHT
list.ListMenu.super.new(self, scene, name, x, y, w, h, itemNumber)
self.cursorTexture = love.graphics.newImage("assets/gui/cursor-menulist.png")
self.cursorTransition = 0
self.submenus = {}
self.itemNumber = itemNumber
self.smallborder = (smallborder == true)
self.isBoxed = isBoxed
if (self.isBoxed) then
local border = h+16
if (self.smallborder) then
border = h+8
end
self.box = gui.newTextBox("assets/gui/dialogbox.png", w, border)
end
end
function list.ListMenu:addSubMenu(name, nicerName)
local submenu = self:clone(name)
self:addSubMenuWidget(name, nicerName)
table.insert(self.submenus, name)
end
function list.ListMenu:addSubMenuWidget(newmenu, name)
list.SubMenuWidget(self.scene, self.name, newmenu, name)
end
function list.ListMenu:finalize(parent)
if (parent ~= "" and parent ~= nil) then
self:addSubMenuWidget(parent, "Back")
self:setCancelWidget()
end
for i,name in ipairs(self.submenus) do
if (self.menusystem.menus[name] ~= nil) then
self.menusystem.menus[name]:finalize(self.name)
end
end
end
function list.ListMenu:clone(name)
return list.ListMenu(self.scene, name, self.x, self.y, self.w, self.itemNumber, self.isBoxed)
end
function list.ListMenu:update(dt)
list.ListMenu.super.update(self, dt)
self:updateCursorPosition(dt)
end
function list.ListMenu:updateCursorPosition(dt)
local relativecursor = self.widget.selected - self.view.firstSlot
local transition = self.cursorTransition - relativecursor
if math.abs(transition) < 0.1 then
self.cursorTransition = relativecursor
else
local speed = dt*45
local movement = ((relativecursor) - (self.cursorTransition))
self.cursorTransition = (self.cursorTransition) + movement * speed
end
end
function list.ListMenu:drawCursor()
local x, y = self:getCursorPosition()
love.graphics.draw(self.cursorTexture, x, y)
end
function list.ListMenu:getCursorPosition()
local addition = MENU_ITEM_HEIGHT
local x = self.x + 6
local y = self.y + ((self.cursorTransition) * addition) + 1
return x, y
end
function list.ListMenu:draw()
if (self.isBoxed) then
local dy = 8
if (self.smallborder) then
dy = 4
end
love.graphics.draw(self.box, self.x, self.y - dy)
end
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
widgetx, widgety = self:getNextPosition(widgetx, widgety, self.widget.h)
end
end
end
function list.ListMenu:getNextPosition(x, y, h)
return x, y+h
end
-- Widgets
-- Tout les widgets pour la liste de base
-- Widget centré
function list.CenteredWidget:new(scene, menu_name, label)
local font = scene.assets.fonts["small"]
font:setFilter("shadow")
self.scene = scene
local widgetMenu = scene.menusystem.menus[menu_name]
list.CenteredWidget.super.new(self, widgetMenu, font, label)
end
function list.CenteredWidget:drawCanvas()
local h = math.floor(self.height / 2) - (self.font:getHeight() / 2) - 2
self.font:setColor(self.color[1], self.color[2], self.color[3], 1)
self.font:draw(self.label, self.width / 2, h, -1, "center")
self.font:setColor(1, 1, 1, 1)
utils.graphics.resetColor()
end
-- Widget avec deux bouts de textes
function list.DualTextWidget:new(scene, menu_name, label, label2)
self.label2 = label2
list.DualTextWidget.super.new(self, scene, menu_name, label)
end
function list.DualTextWidget:drawCanvas()
local h = math.floor(self.height / 2) - (self.font:getHeight() / 2)
self.font:setColor(self.color[1], self.color[2], self.color[3], 1)
self.font:draw(self.label, 16, h, -1, "left")
self.font:draw(self.label2, self.width - 8, h, -1, "right")
self.font:setColor(1, 1, 1, 1)
utils.graphics.resetColor()
end
-- Widget de sous-menu
function list.SubMenuWidget:new(scene, menu_name, newmenu, label)
local label2 = ""
if (label ~= "Back") then
label2 = ">"
end
list.SubMenuWidget.super.new(self, scene, menu_name, label, label2)
self.newmenu = newmenu
end
function list.SubMenuWidget:action()
self.scene.assets:playSFX("mBeep")
self.scene.menusystem:switchMenu(self.newmenu)
self.scene.menusystem.menus[self.newmenu]:activationAction()
end
return list

View file

@ -0,0 +1,36 @@
local ListBox = require "birb.modules.menusystem.listbox"
local TweenManager = require "birb.classes.time"
local RadianceMenu = ListBox:extend()
function RadianceMenu:new(scene, name, x, y, w, h, itemNumber)
self.scene = scene
self.tweens = TweenManager(self)
RadianceMenu.super.new(self, self.scene.menusystem, name, x, y, w, h, itemNumber)
end
function RadianceMenu:update(dt)
self.tweens:update(dt)
RadianceMenu.super.update(self, dt)
end
function RadianceMenu:moveFrom(x, y)
local newX, newY = self.x, self.y
self.x, self.y = x, y
self.tweens:addTween(0, 0.3, {x = newX, y = newY}, "inOutQuad")
end
function RadianceMenu:moveTo(newX, newY)
self.tweens:addTween(0, 0.3, {x = newX, y = newY}, "inOutQuad")
end
function RadianceMenu:getCenter()
return self.x + self.width, self.y + self.height
end
function RadianceMenu:activationAction()
-- Do nothing
end
return RadianceMenu

View file

@ -0,0 +1,13 @@
local Widget = require "birb.modules.menusystem.widgets"
local RadianceWidget = Widget.Text:extend()
function RadianceWidget:new(scene, name, label, color)
self.scene = scene
local label = label or ""
local font = scene.assets.fonts["small"]
font:setFilter("shadow")
local widgetMenu = scene.menusystem.menus[name]
RadianceWidget.super.new(self, widgetMenu, font, label, color)
end
return RadianceWidget

View file

@ -0,0 +1,40 @@
local GuiElement = require "birb.modules.gui.elements.parent"
local MessageQueue = GuiElement:extend()
local Message = require "game.modules.messagequeue.message"
local MAX = 3
function MessageQueue:new(scene)
self.messages = {}
self.permaMessage = nil
self.scene = scene
MessageQueue.super.new(self, "messageQueue", 0, 0, 424, 240)
self.depth = 0
end
function MessageQueue:addMessage(newMessage)
for _, message in ipairs(self.messages) do
message:move()
end
table.insert(self.messages, 1, Message(self.scene, newMessage, false))
self.messages[MAX + 1] = nil
end
function MessageQueue:pinMessage(message)
if (self.permaMessage ~= nil and self.permaMessage.text ~= message) then
self.permaMessage = Message(self.scene, message, true)
end
end
function MessageQueue:update(dt)
for _, message in ipairs(self.messages) do
message:update(dt)
end
end
function MessageQueue:draw()
for _, message in ipairs(self.messages) do
message:draw()
end
end
return MessageQueue

View file

@ -0,0 +1,42 @@
local Message = Object:extend()
local TweenManager = require "birb.classes.time"
local SPACING = 20
local PLAYER_MESSAGE = 240 - 24
function Message:new(scene, message, isPinned)
self.message = message
self.scene = scene
assert(message ~= nil, "the message must be set")
self.isPinned = isPinned or false
self.opacity = 0
self.y = 0
self.tweens = TweenManager(self)
self.tweens:newTween(0, 0.2, {opacity = 1}, "inOutCubic")
self.tweens:newTween(1, 0.2, {opacity = 0}, "inOutCubic")
end
function Message:move()
self.tweens:newTween(0, 0.2, {y = self.y - SPACING}, "inOutCubic")
end
function Message:update(dt)
self.tweens:update(dt)
end
function Message:draw()
local yTransparency = math.max(0, math.min(1, (math.abs(self.y) - 32) / SPACING))
local opacity = math.max(0, math.min(1, self.opacity - yTransparency))
love.graphics.setColor(0, 0, 0, 0.5 * opacity)
if (opacity > 0) then
love.graphics.rectangle("fill", 0, PLAYER_MESSAGE + self.y, 424, 16)
self.scene.assets.fonts["small"]:setColor(1, 1, 1, opacity)
self.scene.assets.fonts["small"]:draw(self.message, 424 / 2, PLAYER_MESSAGE - 1 + self.y, -1, "center")
self.scene.assets.fonts["small"]:setColor(1, 1, 1, 1)
end
utils.graphics.resetColor()
end
return Message

View file

@ -1,29 +0,0 @@
return {
["textures"] = {
{"shadow", "assets/sprites/shadow.png"},
{"e_power", "assets/gui/status/emblem_power.png"},
{"e_fly", "assets/gui/status/emblem_technic.png"},
{"e_speed", "assets/gui/status/emblem_speedster.png"},
{"statusbar", "assets/gui/status/status_bar.png"},
{"hudring", "assets/gui/hud/ring.png"}
},
["sprites"] = {
{"ring", "assets/sprites/items/ring"},
{"ringweapon", "assets/sprites/items/ringweapon"},
{"ringtoss", "assets/sprites/items/ringtoss"}
},
["imagefonts"] = {
{"menu", "assets/gui/fonts/SA2font"},
{"numbers", "assets/gui/fonts/numbers"},
{"smallnumbers", "assets/gui/fonts/smallnumbers"},
},
["sfx"] = {
{"navigate", "assets/sfx/menu/select.wav"},
{"confirm", "assets/sfx/menu/validate.wav"},
{"cancel", "assets/sfx/menu/cancel.wav"},
},
["tilesets"] = {
{"weapons", "assets/gui/status/weapons"},
{"sptiles", "assets/backgrounds/specialtile"}
}
}

View file

@ -1,74 +0,0 @@
local ListBox = require "core.modules.menusystem.listbox"
local PauseMenu = ListBox:extend()
local Widget = require "core.modules.menusystem.widgets"
local ResumeWidget = Widget.Text:extend()
local RestartWidget = Widget.Text:extend()
local ExitWidget = Widget.Text:extend()
function PauseMenu:new(playstyle)
local height, width, x, y
height = 72
width = 128
x = 424/2 - width/2
y = 240/2 - height/2
PauseMenu.super.new(self, playstyle.menusystem, "pauseMenu", x, y, width, height, 3)
self.playstyle = playstyle
self:setSound(self.playstyle.assets.sfx["navigate"])
self.isActive = false
self.isVisible = false
local font = self.playstyle.assets.fonts["menu"]
self.textbox = game.gui.newTextBox("basic", width+16, height+16)
ResumeWidget(self, font)
RestartWidget(self, font)
ExitWidget(self, font)
end
function PauseMenu:draw()
love.graphics.draw(self.textbox, self.x-8, self.y-8)
PauseMenu.super.draw(self)
end
--- MENU WIDGETS
function ResumeWidget:new(menu, font)
ResumeWidget.super.new(self, menu, font, "resume")
end
function ResumeWidget:action()
self.menu.isActive = false
self.menu.isVisible = false
self.menu.playstyle.world.isActive = true
self.menu.playstyle.assets.isActive = true
self.menu.playstyle:flushKeys()
end
function RestartWidget:new(menu, font)
ResumeWidget.super.new(self, menu, font, "restart")
end
function RestartWidget:action()
self.menu.playstyle:restartLevel()
self.menu.isActive = false
self.menu.isVisible = false
self.menu.playstyle.world.isActive = true
self.menu.playstyle.assets.isActive = true
self.menu.playstyle:flushKeys()
end
function ExitWidget:new(menu, font)
ExitWidget.super.new(self, menu, font, "exit")
end
function ExitWidget:action()
self.menu.playstyle:exitLevel()
end
return PauseMenu

View file

@ -1,25 +1,22 @@
Scene = require("core.modules.scenes")
local Scene = require("game.scenes")
local PlayStyle = Scene:extend()
local PauseMenu = require("game.modules.playstyle.pause")
local TestWorld = require("game.modules.world.parent")
function PlayStyle:new(supportedLevels, missionfile, playerList)
local playerList = playerList or {"sonic"}
local PauseMenu = require("game.modules.subgames.pause")
local TestWorld = require("game.modules.subgames.world.parent")
function PlayStyle:new(supportedLevels, missionfile)
PlayStyle.super.new(self)
self.timer = 0
self.assets:batchImport("game.modules.playstyle.assets")
self:loadMissionFile(supportedLevels, missionfile)
self.assets:batchImport("assets.subgames")
--self:loadMissionFile(supportedLevels, missionfile)
PauseMenu(self)
self:initWorld()
self:initMission()
self:initCharacters(playerList)
self:initCharacters()
self:startLevel()
self.haveStarted = false
end
function PlayStyle:loadMissionFile(supportedLevels, missionfile)
@ -35,18 +32,9 @@ function PlayStyle:initMission()
-- NOTHING
end
function PlayStyle:initCharacters(characterList)
self.characterList = characterList
self.world:setPlayerNumber(#characterList)
function PlayStyle:initCharacters()
self.world:setPlayerNumber(1)
self.world.cameras:setMode("split")
for i, characterName in ipairs(characterList) do
self:initCharacterRessources(characterName)
end
end
function PlayStyle:initCharacterRessources(characterName)
local folder = "assets/sprites/characters/"
self.assets:addSprite(characterName, folder .. characterName)
end
function PlayStyle:getCharacterName(charID)
@ -54,7 +42,15 @@ function PlayStyle:getCharacterName(charID)
end
function PlayStyle:update(dt)
PlayStyle.super.update(self, dt)
if (self.haveStarted) then
PlayStyle.super.update(self, dt)
self:updatePauseMenus(dt)
else
self:startLevel()
end
end
function PlayStyle:updatePauseMenus(dt)
if self.menusystem.menus["pauseMenu"].isActive == false then
self.timer = self.timer + dt
end
@ -78,8 +74,9 @@ function PlayStyle:update(dt)
end
function PlayStyle:startLevel()
self.haveStarted = true
self.world:loadMap()
self.assets:playMusic()
--self.assets:playMusic()
end
function PlayStyle:restartLevel()
@ -87,7 +84,7 @@ function PlayStyle:restartLevel()
end
function PlayStyle:exitLevel()
scenes.title()
scenes.menus.title()
end
return PlayStyle

View file

@ -0,0 +1,63 @@
local RadianceListMenu = require "game.modules.menus.list"
local PauseMenu = RadianceListMenu.ListMenu:extend()
local ResumeWidget = RadianceListMenu.DualTextWidget:extend()
local RestartWidget = RadianceListMenu.DualTextWidget:extend()
local ExitWidget = RadianceListMenu.DualTextWidget:extend()
local WIDTH = 80
function PauseMenu:new(subgame)
local x, y
x = 424/2 - WIDTH/2
y = 240/2 - (3*17)/2
PauseMenu.super.new(self, subgame, "pauseMenu", x, y, WIDTH, 3, true)
self:setSound(self.scene.assets.sfx["navigate"])
self.isActive = false
self.isVisible = false
ResumeWidget(subgame)
self:setCancelWidget()
RestartWidget(subgame)
ExitWidget(subgame)
end
--- MENU WIDGETS
function ResumeWidget:new(scene)
ResumeWidget.super.new(self, scene, "pauseMenu", "Resume", "")
end
function ResumeWidget:action()
self.menu.isActive = false
self.menu.isVisible = false
self.scene.world.isActive = true
self.scene.assets.isActive = true
self.scene:flushKeys()
end
function RestartWidget:new(scene)
ResumeWidget.super.new(self, scene, "pauseMenu", "Restart", "")
end
function RestartWidget:action()
self.scene:restartLevel()
self.menu.isActive = false
self.menu.isVisible = false
self.scene.world.isActive = true
self.scene.assets.isActive = true
self.scene:flushKeys()
end
function ExitWidget:new(scene)
ExitWidget.super.new(self, scene, "pauseMenu", "Exit", "")
end
function ExitWidget:action()
self.scene:exitLevel()
end
return PauseMenu

View file

@ -1,4 +1,4 @@
local Base = require "core.modules.world.actors.actor3D"
local Base = require "birb.modules.world.actors.actor3D"
local FakeFloor = Base:extend()
function FakeFloor:new(world, x, y, z, w, h, d)

View file

@ -1,4 +1,4 @@
local Base = require "core.modules.world.actors.actor3D"
local Base = require "birb.modules.world.actors.actor3D"
local Floor = Base:extend()
function Floor:new(world, x, y, z, w, h, d)

View file

@ -1,4 +1,4 @@
local Base = require "core.modules.world.actors.actor3D"
local Base = require "birb.modules.world.actors.actor3D"
local Invisible = Base:extend()
function Invisible:new(world, x, y, z, w, h, d)

View file

@ -1,4 +1,4 @@
local Base = require "core.modules.world.actors.actor3D"
local Base = require "birb.modules.world.actors.actor3D"
local Textured = Base:extend()
function Textured:new(world, x, y, z, w, h, d, top, bottom)

View file

@ -1,4 +1,4 @@
local Base = require "core.modules.world.actors.actor3D"
local Base = require "birb.modules.world.actors.actor3D"
local Wall = Base:extend()
function Wall:new(world, x, y, z, w, h, d)

View file

@ -0,0 +1,6 @@
local Parent = require "game.modules.subgames.world.actors.ennemies.parent"
local Motobug = Parent:extend()
return Motobug

View file

@ -1,4 +1,4 @@
local Parent = require "game.modules.world.actors.parent"
local Parent = require "game.modules.subgames.world.actors.parent"
local EnnemyParent = Parent:extend()
function EnnemyParent:new(world, x, y, z, w, h, d)

View file

@ -1,4 +1,4 @@
local Parent = require "game.modules.world.actors.parent"
local Parent = require "game.modules.subgames.world.actors.parent"
local Collectible = Parent:extend()
function Collectible:new(world, x, y, z, w, h, d)

View file

@ -1,4 +1,4 @@
local Base = require "core.modules.world.actors.actor3D"
local Base = require "birb.modules.world.actors.actor3D"
local Parent = Base:extend()
function Parent:new(world, type, x, y, z, w, h, d, isSolid)

View file

@ -0,0 +1,146 @@
local cwd = (...):gsub('%.player$', '') .. "."
local Parent = require(cwd .. "parent")
local Player = Parent:extend()
local Emblem = require "game.modules.gui.emblem"
local Weapons = require(cwd .. "player.weapons")
function Player:new(world, x, y, z, id)
Player.super.new(self, world, "player", x, y, 0, 16, 12, 24, true)
self:setGravity(480*2)
self:initPlayer()
self.weapons = Weapons(self)
self.action = "normal"
self.rings = 0
self.score = 0
end
function Player:initPlayer()
self.charName = game.characters:getActiveCharacter()
self.assets:addSprite(self.charName, "datas/gamedata/characters/" .. self.charName .. "/sprites")
self:setSprite(self.charName, true, 8, 10)
self.emblem = Emblem(game.characters:getActiveCharacterData(), self.scene)
self.guiborder = game.gui.newBorder(424, 20, 6)
end
function Player:updateStart(dt)
self.xfrc, self.yfrc = 480*3, 480*3
self:basicMovements()
if self.keys["A"].isPressed and (self.onGround) then
self.zsp = 280*1.33
end
if self.keys["B"].isPressed then
self.weapons:shoot(self.x, self.y+1, self.z+8, 1)
end
end
function Player:basicMovements()
local xsp, ysp = 0, 0
local speed = 160
if self.keys["up"].isDown then
ysp = -1
end
if self.keys["down"].isDown then
ysp = 1
end
if (self.world.autorun == true) then
xsp = 1
else
if self.keys["left"].isDown then
xsp = -1
end
if self.keys["right"].isDown then
xsp = 1
end
end
if (xsp ~= 0 or ysp ~= 0) then
local angle = utils.math.pointDirection(0, 0, xsp, ysp)
self.xsp, self.ysp = utils.math.lengthdir(160, angle)
end
end
function Player:collisionResponse(collision)
if collision.other.type == "collectible" then
collision.other.owner:getPicked(self)
end
end
function Player:animationEnded(name)
end
function Player:updateEnd(dt)
self:setAnimation()
end
function Player:setAnimation()
local gsp = utils.math.pointDistance(0, 0, self.xsp, self.ysp)
self.sprite:setCustomSpeed(math.abs(gsp) / 12)
self:setDirection(self.xsp)
if (self.action == "punching") then
--the animation system is already active
else
if (self.onGround) then
if (math.abs(self.xsp) > 0) or (math.abs(self.ysp) > 0) then
self.sprite:changeAnimation("walk", false)
else
self.sprite:changeAnimation("idle", false)
end
else
if (self.zsp) > 0 then
self.sprite:changeAnimation("jump", false)
else
self.sprite:changeAnimation("fall", false)
end
end
end
end
function Player:setDirection(direction)
direction = direction or 0
if direction ~= 0 then
direction = utils.math.sign(direction)
self.direction = direction
self.sprite:setScallingX(direction)
end
end
function Player:getViewCenter()
local x, y = Player.super.getViewCenter(self)
return x, y-16
end
function Player:draw()
Player.super.draw(self)
end
function Player:drawHUD(id)
love.graphics.draw(self.guiborder, 0, 20, 0, 1, -1)
self.emblem:draw(424 - 40, 12)
end
function Player:setRing(value, isRelative)
if (isRelative == false) then
self.rings = 0
end
self.rings = self.rings + value
end
function Player:setScore(value, isRelative)
if (isRelative == false) then
self.score = 0
end
self.score = self.score + value
end
return Player

View file

@ -10,12 +10,12 @@ end
function WeaponManager:switch(newWeapon)
if (weaponList[newWeapon] ~= nil) then
self.currentWeapon = newWeapon;
self.player.statusbar:setWeapon(self.currentWeapon);
--self.player.statusbar:setWeapon(self.currentWeapon);
end
end
function WeaponManager:shoot(x, y, z, dir)
weaponData = weaponList[self.currentWeapon]
local weaponData = weaponList[self.currentWeapon]
for i,coord in ipairs(weaponData.launch) do
self.player.obj.Weapon(self.player.world, x + coord[1], y + coord[2], z + coord[3], dir, weaponData)

View file

@ -1,4 +1,4 @@
local Parent = require "game.modules.world.actors.parent"
local Parent = require "game.modules.subgames.world.actors.parent"
local WeaponShot = Parent:extend()
function WeaponShot:new(world, x, y, z, direction, data)
@ -7,17 +7,19 @@ function WeaponShot:new(world, x, y, z, direction, data)
self.direction = direction
self.data = data
self.zsp = self.data.zspeed
self.xsp = self.data.xspeed * direction
self.xsp = (self.data.xspeed * direction)
self.xfrc, self.yfrc = 0, 0
if (self.zsp ~= 0) then
self:setGravity(480*2)
end
print(self.xsp)
end
function WeaponShot:updateStart(dt)
if (self.xsp == 0) then
self:destroy()
end
print(self.xsp)
-- if (self.xsp == 0) then
-- self:destroy()
-- end
end
function WeaponShot:draw()
@ -26,7 +28,7 @@ function WeaponShot:draw()
love.graphics.setColor(self.data.color[1], self.data.color[2], self.data.color[3], 0.6)
local x, y = self.x + self.y/2 + 8, self.y - self.z - 3
local angle = utils.math.pointDirection(0, 0, self.xsp, self.zsp * -1)
self.scene.assets.sprites["ringtoss"]:drawAnimation(x, y, angle)
self.scene.assets.sprites["ringtoss"]:draw(x, y, angle)
love.graphics.setColor(1, 1, 1, 1)
end

View file

@ -1,7 +1,7 @@
local ParentWorld = require "game.modules.world.parent"
local ParentWorld = require "game.modules.subgames.world.parent"
local BattleWorld = ParentWorld:extend()
local customMap = require "game.modules.world.maps"
local customMap = require "game.modules.subgames.world.maps"
function BattleWorld:new(scene, mapname)
local mappath = game.utils.getMapPath("battle", mapname)

View file

@ -1,9 +1,9 @@
local BaseMap = require "core.modules.world.maps.parent"
local BaseMap = require "birb.modules.world.maps.parent"
local BattleMap = BaseMap:extend()
function BattleMap:new(world, maptype, mapname)
BattleMap.super.new(self, world)
self:setPadding(0, 128, 0, 20)
self:setPadding(0, 128, 0, 0)
self.directory = game.utils.getMapDirectory(maptype, mapname)
self.mappath = game.utils.getMapPath(maptype, mapname)

View file

@ -0,0 +1,7 @@
local customMap = {}
customMap.Test = require "game.modules.subgames.world.maps.test"
customMap.Battle = require "game.modules.subgames.world.maps.battle"
customMap.Shoot = require "game.modules.subgames.world.maps.shoot"
return customMap

View file

@ -1,19 +1,20 @@
local BaseMap = require "core.modules.world.maps.parent"
local BaseMap = require "birb.modules.world.maps.parent"
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"
local Chunk = require "game.modules.world.maps.tools.chunk"
local Chunk = require "game.modules.subgames.world.maps.tools.chunk"
function ShootMap:new(world, maptype, mapname)
ShootMap.super.new(self, world)
self:setPadding(0, 0, 0, 0)
self:getLevelData(mapname)
self:generateTextures(self.datas.tiles, self.datas.background)
self.parallaxBackground = Background(world.scene, 5, 1, self.datas.background)
self.layout = {}
self.chunklist = {}
@ -26,7 +27,7 @@ function ShootMap:updateWidth()
end
function ShootMap:getLevelData(mapname)
local file = file or "testlevel.test1"
local file = mapname or "testlevel.test1"
local level = require("datas.gamedata.maps.shoot." .. file)
self.zone = level.datas.zone
@ -137,7 +138,7 @@ function ShootMap:addBlock(x, y, w, h, top, bottom)
end
function ShootMap:getDimensions()
return self.width, 100
return 3000, 100
end
function ShootMap:loadPlayers()
@ -148,107 +149,12 @@ 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(x, y, w, h)
self:drawChunks(x)
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")
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)
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
self.parallaxBackground:drawParallax(x, y, w, h)
end
function ShootMap:drawChunks(x)

View file

@ -0,0 +1,48 @@
local BaseMap = require "birb.modules.world.maps.parent"
local TestMap = BaseMap:extend()
function TestMap:new(world)
TestMap.super.new(self, world)
self:setPadding(0, 96, 0, 0)
self.background = love.graphics.newImage("assets/backgrounds/parallax/test-back.png")
end
function TestMap:loadCollisions()
self.world:newCollision("wall", 0, 0, -16, 8*64, 8*32, 16)
self.world:newCollision("wall", 64*1, 32*1, 0, 64*1, 32*3, 48)
self.world:newCollision("wall", 64*4, 32*1, 0, 64*3, 32*1, 48)
self.world:newCollision("wall", 64*6, 32*4, 0, 64*1, 32*3, 48)
self.world:newCollision("wall", 64*1, 32*6, 0, 64*3, 32*1, 48)
end
function TestMap:getDimensions()
return 8*64, 8*32
end
function TestMap:loadPlayers()
self.world:addPlayer(16, 16, 0, 1)
end
function TestMap:loadActors()
-- Empty Placeholder function
end
function TestMap:draw()
-- Empty Placeholder function
end
function TestMap:drawParallax(x, y, w, h)
local imax, jmax = (w/32)+1, (h/32)+1
local x, y = x or 0, y or 0
local x = math.floor(x/4) % 32
local y = math.floor((y+96)/6) % 32
for i=0, math.ceil(imax) do
for j=0, math.ceil(jmax) do
love.graphics.draw(self.background, (i-1)*32-x, (j-1)*32-y)
end
end
end
return TestMap

View file

@ -1,5 +1,5 @@
local Chunk = Object:extend()
local ChunkTerrain = require "game.modules.world.maps.tools.chunkterrain"
local ChunkTerrain = require "game.modules.subgames.world.maps.tools.chunkterrain"
function Chunk:new(map, data)
self.map = map

View file

@ -1,13 +1,13 @@
local World3D = require "core.modules.world.world3D"
local World3D = require "birb.modules.world.world3D"
local ParentWorld = World3D:extend()
local customMap = require "game.modules.world.maps"
local customMap = require "game.modules.subgames.world.maps"
function ParentWorld:new(scene, maptype, mapname)
local mappath = game.utils.getMapPath("test", "test")
self.customMap = customMap
ParentWorld.super.new(self, scene, "game.modules.world.actors", mappath, maptype)
ParentWorld.super.new(self, scene, "game.modules.subgames.world.actors", mappath, maptype)
self.mapname = mapname
self.autorun = false
@ -28,7 +28,6 @@ end
function ParentWorld:addInvisibleWalls()
local w, h = self:getDimensions()
print(w, h)
self.obj.collisions["invisible"](self, 0, -16, 0, w, 16, 1000)
self.obj.collisions["invisible"](self, 0, h, 0, w, 16, 1000)
self.obj.collisions["invisible"](self, w, 0, 0, 16, h, 1000)

View file

@ -1,7 +1,7 @@
local ParentWorld = require "game.modules.world.parent"
local ParentWorld = require "game.modules.subgames.world.parent"
local ShootWorld = ParentWorld:extend()
local customMap = require "game.modules.world.maps"
local customMap = require "game.modules.subgames.world.maps"
function ShootWorld:new(scene, mapname)
local mappath = game.utils.getMapPath("shoot", mapname)

View file

@ -0,0 +1,8 @@
local DecalTransition = require "birb.modules.transitions.decal"
local EggmanTransition = DecalTransition:extend()
function EggmanTransition:new(func, ox, oy, fadeOut)
EggmanTransition.super.new(self, func, ox, oy, fadeOut, "eggdecal")
end
return EggmanTransition

View file

@ -0,0 +1,5 @@
return {
sonic = require "game.modules.transitions.sonic",
eggman = require "game.modules.transitions.eggman",
borders = require "game.modules.transitions.zigzag",
}

View file

@ -0,0 +1,8 @@
local DecalTransition = require "birb.modules.transitions.decal"
local SonicTransition = DecalTransition:extend()
function SonicTransition:new(func, ox, oy, fadeOut)
SonicTransition.super.new(self, func, ox, oy, fadeOut, "sonicdecal")
end
return SonicTransition

View file

@ -0,0 +1,41 @@
local CanvasTransition = require "birb.modules.transitions.canvas"
local ZigZagTransition = CanvasTransition:extend()
function ZigZagTransition:new(func, ox, oy, fadeOut)
self.offset = 0
ZigZagTransition.super.new(self, func, ox, oy, fadeOut, "inQuad", "outQuad", 1, 0.1)
end
function ZigZagTransition:loadResources()
self.border = love.graphics.newImage("assets/transitions/border.png")
end
function ZigZagTransition:drawCanvas(dt)
local w, _ = self.border:getDimensions()
self.offset = (self.offset + (dt * 256)) % w
utils.graphics.resetColor()
love.graphics.rectangle("fill", 0, 0, 424, 240)
love.graphics.setColor(0,0,0,1)
local max = 120 + 16
self:drawBorder(0 + max * (self.value), false)
utils.graphics.resetColor()
self:drawBorder(240 - max * (self.value), true)
end
function ZigZagTransition:drawBorder(y, reversed)
local offset = self.offset
local sy = 1
if (reversed) then
offset = self.offset * -1
sy = -1
end
local w, h = self.border:getDimensions()
local ox, oy = 0, h
for i = -1, math.ceil(424 / w), 1 do
love.graphics.draw(self.border,(i * w) + offset,y,0,1,sy,ox,oy)
end
end
return ZigZagTransition

View file

@ -1,88 +0,0 @@
local TweenManager = Object:extend()
local tween = require "game.modules.tweenmanager.libs.tween"
local Timer = require "core.modules.world.actors.utils.timer"
function TweenManager:new(subject)
self.subject = subject
self.time = 0
self.tweens = {}
self.switches = {}
self.timers = {}
end
function TweenManager:newTween(start, duration, target, easing)
local newTween = {}
-- we add the data into a tween wrapper
newTween.tween = tween.new(duration, self.subject, target, easing)
newTween.start = self.time + start -- /!\ START IS RELATIVE TO CURRENT TIME
newTween.clear = newTween.start + duration
table.insert(self.tweens, newTween)
end
function TweenManager:newTimer(start, name)
self.timers[name] = Timer(self, name, start)
end
function TweenManager:newSwitch(start, bools)
local newSwitch = {}
-- we add the data into a tween wrapper
newSwitch.bools = bools
newSwitch.start = self.time + start -- /!\ START IS RELATIVE TO CURRENT TIME
newSwitch.clear = newSwitch.start + 1
table.insert(self.switches, newSwitch)
end
function TweenManager:update(dt)
self.time = self.time + dt
for i, tweenWrapper in ipairs(self.tweens) do
if (self.time > tweenWrapper.start) then
tweenWrapper.tween:update(dt)
end
end
for i, switch in ipairs(self.switches) do
if (self.time > switch.start) then
-- We test each boolean in the switch
for i, bool in ipairs(switch.bools) do
-- if it's nil, we set it to true
if self.subject[bool] == nil then
self.subject[bool] = true
else
-- if it's not nil, we reverse the boolean
self.subject[bool] = (self.subject[bool] == false)
end
end
table.remove(self.switches, i)
end
end
for k, timer in pairs(self.timers) do
timer:update(dt)
end
self:clearEndedTweens()
end
function TweenManager:timerResponse(timername)
if self.subject.timerResponse == nil then
core.debug:warning("tweenmanager", "the subject have no timerResponse function")
return 0
end
self.subject:timerResponse(timername)
end
function TweenManager:clearEndedTweens(dt)
for i, tweenWrapper in ipairs(self.tweens) do
if (self.time > tweenWrapper.clear) then
table.remove(self.tweens, i)
end
end
end
return TweenManager

View file

@ -1,367 +0,0 @@
local tween = {
_VERSION = 'tween 2.1.1',
_DESCRIPTION = 'tweening for lua',
_URL = 'https://github.com/kikito/tween.lua',
_LICENSE = [[
MIT LICENSE
Copyright (c) 2014 Enrique García Cota, Yuichi Tateno, Emmanuel Oga
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.
]]
}
-- easing
-- Adapted from https://github.com/EmmanuelOga/easing. See LICENSE.txt for credits.
-- For all easing functions:
-- t = time == how much time has to pass for the tweening to complete
-- b = begin == starting property value
-- c = change == ending - beginning
-- d = duration == running time. How much time has passed *right now*
local pow, sin, cos, pi, sqrt, abs, asin = math.pow, math.sin, math.cos, math.pi, math.sqrt, math.abs, math.asin
-- linear
local function linear(t, b, c, d) return c * t / d + b end
-- quad
local function inQuad(t, b, c, d) return c * pow(t / d, 2) + b end
local function outQuad(t, b, c, d)
t = t / d
return -c * t * (t - 2) + b
end
local function inOutQuad(t, b, c, d)
t = t / d * 2
if t < 1 then return c / 2 * pow(t, 2) + b end
return -c / 2 * ((t - 1) * (t - 3) - 1) + b
end
local function outInQuad(t, b, c, d)
if t < d / 2 then return outQuad(t * 2, b, c / 2, d) end
return inQuad((t * 2) - d, b + c / 2, c / 2, d)
end
-- cubic
local function inCubic (t, b, c, d) return c * pow(t / d, 3) + b end
local function outCubic(t, b, c, d) return c * (pow(t / d - 1, 3) + 1) + b end
local function inOutCubic(t, b, c, d)
t = t / d * 2
if t < 1 then return c / 2 * t * t * t + b end
t = t - 2
return c / 2 * (t * t * t + 2) + b
end
local function outInCubic(t, b, c, d)
if t < d / 2 then return outCubic(t * 2, b, c / 2, d) end
return inCubic((t * 2) - d, b + c / 2, c / 2, d)
end
-- quart
local function inQuart(t, b, c, d) return c * pow(t / d, 4) + b end
local function outQuart(t, b, c, d) return -c * (pow(t / d - 1, 4) - 1) + b end
local function inOutQuart(t, b, c, d)
t = t / d * 2
if t < 1 then return c / 2 * pow(t, 4) + b end
return -c / 2 * (pow(t - 2, 4) - 2) + b
end
local function outInQuart(t, b, c, d)
if t < d / 2 then return outQuart(t * 2, b, c / 2, d) end
return inQuart((t * 2) - d, b + c / 2, c / 2, d)
end
-- quint
local function inQuint(t, b, c, d) return c * pow(t / d, 5) + b end
local function outQuint(t, b, c, d) return c * (pow(t / d - 1, 5) + 1) + b end
local function inOutQuint(t, b, c, d)
t = t / d * 2
if t < 1 then return c / 2 * pow(t, 5) + b end
return c / 2 * (pow(t - 2, 5) + 2) + b
end
local function outInQuint(t, b, c, d)
if t < d / 2 then return outQuint(t * 2, b, c / 2, d) end
return inQuint((t * 2) - d, b + c / 2, c / 2, d)
end
-- sine
local function inSine(t, b, c, d) return -c * cos(t / d * (pi / 2)) + c + b end
local function outSine(t, b, c, d) return c * sin(t / d * (pi / 2)) + b end
local function inOutSine(t, b, c, d) return -c / 2 * (cos(pi * t / d) - 1) + b end
local function outInSine(t, b, c, d)
if t < d / 2 then return outSine(t * 2, b, c / 2, d) end
return inSine((t * 2) -d, b + c / 2, c / 2, d)
end
-- expo
local function inExpo(t, b, c, d)
if t == 0 then return b end
return c * pow(2, 10 * (t / d - 1)) + b - c * 0.001
end
local function outExpo(t, b, c, d)
if t == d then return b + c end
return c * 1.001 * (-pow(2, -10 * t / d) + 1) + b
end
local function inOutExpo(t, b, c, d)
if t == 0 then return b end
if t == d then return b + c end
t = t / d * 2
if t < 1 then return c / 2 * pow(2, 10 * (t - 1)) + b - c * 0.0005 end
return c / 2 * 1.0005 * (-pow(2, -10 * (t - 1)) + 2) + b
end
local function outInExpo(t, b, c, d)
if t < d / 2 then return outExpo(t * 2, b, c / 2, d) end
return inExpo((t * 2) - d, b + c / 2, c / 2, d)
end
-- circ
local function inCirc(t, b, c, d) return(-c * (sqrt(1 - pow(t / d, 2)) - 1) + b) end
local function outCirc(t, b, c, d) return(c * sqrt(1 - pow(t / d - 1, 2)) + b) end
local function inOutCirc(t, b, c, d)
t = t / d * 2
if t < 1 then return -c / 2 * (sqrt(1 - t * t) - 1) + b end
t = t - 2
return c / 2 * (sqrt(1 - t * t) + 1) + b
end
local function outInCirc(t, b, c, d)
if t < d / 2 then return outCirc(t * 2, b, c / 2, d) end
return inCirc((t * 2) - d, b + c / 2, c / 2, d)
end
-- elastic
local function calculatePAS(p,a,c,d)
p, a = p or d * 0.3, a or 0
if a < abs(c) then return p, c, p / 4 end -- p, a, s
return p, a, p / (2 * pi) * asin(c/a) -- p,a,s
end
local function inElastic(t, b, c, d, a, p)
local s
if t == 0 then return b end
t = t / d
if t == 1 then return b + c end
p,a,s = calculatePAS(p,a,c,d)
t = t - 1
return -(a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b
end
local function outElastic(t, b, c, d, a, p)
local s
if t == 0 then return b end
t = t / d
if t == 1 then return b + c end
p,a,s = calculatePAS(p,a,c,d)
return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p) + c + b
end
local function inOutElastic(t, b, c, d, a, p)
local s
if t == 0 then return b end
t = t / d * 2
if t == 2 then return b + c end
p,a,s = calculatePAS(p,a,c,d)
t = t - 1
if t < 0 then return -0.5 * (a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b end
return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p ) * 0.5 + c + b
end
local function outInElastic(t, b, c, d, a, p)
if t < d / 2 then return outElastic(t * 2, b, c / 2, d, a, p) end
return inElastic((t * 2) - d, b + c / 2, c / 2, d, a, p)
end
-- back
local function inBack(t, b, c, d, s)
s = s or 1.70158
t = t / d
return c * t * t * ((s + 1) * t - s) + b
end
local function outBack(t, b, c, d, s)
s = s or 1.70158
t = t / d - 1
return c * (t * t * ((s + 1) * t + s) + 1) + b
end
local function inOutBack(t, b, c, d, s)
s = (s or 1.70158) * 1.525
t = t / d * 2
if t < 1 then return c / 2 * (t * t * ((s + 1) * t - s)) + b end
t = t - 2
return c / 2 * (t * t * ((s + 1) * t + s) + 2) + b
end
local function outInBack(t, b, c, d, s)
if t < d / 2 then return outBack(t * 2, b, c / 2, d, s) end
return inBack((t * 2) - d, b + c / 2, c / 2, d, s)
end
-- bounce
local function outBounce(t, b, c, d)
t = t / d
if t < 1 / 2.75 then return c * (7.5625 * t * t) + b end
if t < 2 / 2.75 then
t = t - (1.5 / 2.75)
return c * (7.5625 * t * t + 0.75) + b
elseif t < 2.5 / 2.75 then
t = t - (2.25 / 2.75)
return c * (7.5625 * t * t + 0.9375) + b
end
t = t - (2.625 / 2.75)
return c * (7.5625 * t * t + 0.984375) + b
end
local function inBounce(t, b, c, d) return c - outBounce(d - t, 0, c, d) + b end
local function inOutBounce(t, b, c, d)
if t < d / 2 then return inBounce(t * 2, 0, c, d) * 0.5 + b end
return outBounce(t * 2 - d, 0, c, d) * 0.5 + c * .5 + b
end
local function outInBounce(t, b, c, d)
if t < d / 2 then return outBounce(t * 2, b, c / 2, d) end
return inBounce((t * 2) - d, b + c / 2, c / 2, d)
end
tween.easing = {
linear = linear,
inQuad = inQuad, outQuad = outQuad, inOutQuad = inOutQuad, outInQuad = outInQuad,
inCubic = inCubic, outCubic = outCubic, inOutCubic = inOutCubic, outInCubic = outInCubic,
inQuart = inQuart, outQuart = outQuart, inOutQuart = inOutQuart, outInQuart = outInQuart,
inQuint = inQuint, outQuint = outQuint, inOutQuint = inOutQuint, outInQuint = outInQuint,
inSine = inSine, outSine = outSine, inOutSine = inOutSine, outInSine = outInSine,
inExpo = inExpo, outExpo = outExpo, inOutExpo = inOutExpo, outInExpo = outInExpo,
inCirc = inCirc, outCirc = outCirc, inOutCirc = inOutCirc, outInCirc = outInCirc,
inElastic = inElastic, outElastic = outElastic, inOutElastic = inOutElastic, outInElastic = outInElastic,
inBack = inBack, outBack = outBack, inOutBack = inOutBack, outInBack = outInBack,
inBounce = inBounce, outBounce = outBounce, inOutBounce = inOutBounce, outInBounce = outInBounce
}
-- private stuff
local function copyTables(destination, keysTable, valuesTable)
valuesTable = valuesTable or keysTable
local mt = getmetatable(keysTable)
if mt and getmetatable(destination) == nil then
setmetatable(destination, mt)
end
for k,v in pairs(keysTable) do
if type(v) == 'table' then
destination[k] = copyTables({}, v, valuesTable[k])
else
destination[k] = valuesTable[k]
end
end
return destination
end
local function checkSubjectAndTargetRecursively(subject, target, path)
path = path or {}
local targetType, newPath
for k,targetValue in pairs(target) do
targetType, newPath = type(targetValue), copyTables({}, path)
table.insert(newPath, tostring(k))
if targetType == 'number' then
assert(type(subject[k]) == 'number', "Parameter '" .. table.concat(newPath,'/') .. "' is missing from subject or isn't a number")
elseif targetType == 'table' then
checkSubjectAndTargetRecursively(subject[k], targetValue, newPath)
else
assert(targetType == 'number', "Parameter '" .. table.concat(newPath,'/') .. "' must be a number or table of numbers")
end
end
end
local function checkNewParams(duration, subject, target, easing)
assert(type(duration) == 'number' and duration > 0, "duration must be a positive number. Was " .. tostring(duration))
local tsubject = type(subject)
assert(tsubject == 'table' or tsubject == 'userdata', "subject must be a table or userdata. Was " .. tostring(subject))
assert(type(target)== 'table', "target must be a table. Was " .. tostring(target))
assert(type(easing)=='function', "easing must be a function. Was " .. tostring(easing))
checkSubjectAndTargetRecursively(subject, target)
end
local function getEasingFunction(easing)
easing = easing or "linear"
if type(easing) == 'string' then
local name = easing
easing = tween.easing[name]
if type(easing) ~= 'function' then
error("The easing function name '" .. name .. "' is invalid")
end
end
return easing
end
local function performEasingOnSubject(subject, target, initial, clock, duration, easing)
local t,b,c,d
for k,v in pairs(target) do
if type(v) == 'table' then
performEasingOnSubject(subject[k], v, initial[k], clock, duration, easing)
else
t,b,c,d = clock, initial[k], v - initial[k], duration
subject[k] = easing(t,b,c,d)
end
end
end
-- Tween methods
local Tween = {}
local Tween_mt = {__index = Tween}
function Tween:set(clock)
assert(type(clock) == 'number', "clock must be a positive number or 0")
self.initial = self.initial or copyTables({}, self.target, self.subject)
self.clock = clock
if self.clock <= 0 then
self.clock = 0
copyTables(self.subject, self.initial)
elseif self.clock >= self.duration then -- the tween has expired
self.clock = self.duration
copyTables(self.subject, self.target)
else
performEasingOnSubject(self.subject, self.target, self.initial, self.clock, self.duration, self.easing)
end
return self.clock >= self.duration
end
function Tween:reset()
return self:set(0)
end
function Tween:update(dt)
assert(type(dt) == 'number', "dt must be a number")
return self:set(self.clock + dt)
end
-- Public interface
function tween.new(duration, subject, target, easing)
easing = getEasingFunction(easing)
checkNewParams(duration, subject, target, easing)
return setmetatable({
duration = duration,
subject = subject,
target = target,
easing = easing,
clock = 0
}, Tween_mt)
end
return tween

View file

@ -1,6 +0,0 @@
local Parent = require "game.modules.world.actors.ennemies.parent"
local Motobug = Parent:extend()
return Motobug

View file

@ -1,7 +0,0 @@
local customMap = {}
customMap.Test = require "game.modules.world.maps.test"
customMap.Battle = require "game.modules.world.maps.battle"
customMap.Shoot = require "game.modules.world.maps.shoot"
return customMap

View file

@ -1,46 +0,0 @@
local BaseMap = require "core.modules.world.maps.parent"
local TestMap = BaseMap:extend()
function TestMap:new(world)
TestMap.super.new(self, world)
--self:setPadding(0, 0, 0, 0)
self.background = love.graphics.newImage("assets/backgrounds/dumbtestmap.png")
end
function TestMap:loadCollisions()
local w, h = self:getDimensions()
self.world:newCollision("floor", 0, 0, -16, w, h, 16)
end
function TestMap:getDimensions()
return self.background:getDimensions()
end
function TestMap:loadPlayers()
self.world:addPlayer(16, 16, 0, 1)
end
function TestMap:loadActors()
-- Empty Placeholder function
end
function TestMap:draw()
-- Empty Placeholder function
love.graphics.draw(self.background, 0, 0)
end
function TestMap:drawParallax(x, y, w, h)
-- local imax, jmax = (w/32)+1, (h/32)+1
-- local x, y = x or 0, y or 0
-- local x = math.floor(x/4) % 32
-- local y = math.floor((y+96)/6) % 32
--
-- for i=0, math.ceil(imax) do
-- for j=0, math.ceil(jmax) do
-- love.graphics.draw(self.background, (i-1)*32-x, (j-1)*32-y)
-- end
-- end
end
return TestMap

View file

@ -0,0 +1,45 @@
local BirbScene = require "birb.modules.scenes"
local RadianceScene = BirbScene:extend()
local Overlay = require "game.modules.gui.overlay"
local MessageQueue = require "game.modules.messagequeue"
local ActionPrompt = require "game.modules.gui.actionPrompt"
function RadianceScene:new(haveBorder, showVersion)
RadianceScene.super.new(self)
-- Importation Global des assets
self.assets:batchImport("assets.commons")
self.assets.fonts["small"]:setLineHeight(16/18)
self.assets.fonts["small"]:setFilter("shadow")
self.gui:addSFX("select", "mSelect")
self.gui:addSFX("navigate", "mBeep")
self.gui:addSFX("back", "mBack")
self.gui:addSFX("error", "mError")
Overlay(haveBorder, showVersion)
MessageQueue(self)
ActionPrompt()
end
function RadianceScene:hideOverlay()
self.gui:hideScreen("overlay")
end
function RadianceScene:showMessage(message)
self.gui.elements["messageQueue"]:addMessage(message)
end
function RadianceScene:setPrompt(message)
self.gui.elements["actionPrompt"]:setText(message)
end
function RadianceScene:showOverlay(darken)
self.gui:showScreen("overlay")
if (darken) then
self.gui:playScreenTransform("overlay", "showBackground")
end
end
return RadianceScene

View file

@ -1,18 +0,0 @@
local SonicBoost = Object:extend()
function SonicBoost:new(controller)
self.controller = controller
self.datas = {}
self.datas.characters = require "datas.subgame.sonic-boost.characters"
end
function SonicBoost:getCharacterData(name)
return self.datas.characters[name]
end
function SonicBoost:getData()
return self.datas
end
return SonicBoost

View file

@ -0,0 +1,84 @@
local BattleUtils = {}
local CONSTS = require "datas.consts.battle"
local protectypes = require "datas.gamedata.battles.protectypes"
local STATS = require "datas.consts.stats"
function BattleUtils.computeLaunchingDamages(base, fighter, isSpecial)
local damages = base / CONSTS.DAMAGE.DIVISOR
if (isSpecial) then
damages = damages * fighter:getStat(STATS.POWER)
else
damages = damages * fighter:getStat(STATS.ATTACK)
end
damages = damages * BattleUtils.computerArmorAndDamage(fighter:getStat(STATS.DAMAGE))
if (BattleUtils.rollDice(fighter:getStat(STATS.CRITICAL))) then
damages = damages * 2
end
return damages
end
function BattleUtils.computeReceivingDamages(base, fighter, isSpecial, isDefending)
local damages = base
if (isSpecial) then
damages = damages / fighter:getStat(STATS.MIND)
else
damages = damages / fighter:getStat(STATS.DEFENSE)
end
damages = damages * BattleUtils.computerArmorAndDamage(fighter:getStat(STATS.ARMOR), true)
if (isDefending) then
damages = damages * CONSTS.DAMAGE.DEFFACTOR
end
return damages
end
function BattleUtils.applyProtectTypes(value, type, protectypeList)
for _, protectype in ipairs(protectypeList) do
local protecttypeData = protectypes[protectype]
if protecttypeData ~= nil then
if (utils.table.contain(protecttypeData.resistTo, type)) then
value = value * CONSTS.ATKWRONGTYPE
end
else
core.debug:warning("battleutils", "protectype " .. protectype .. " doesn't exists ")
end
end
return value
end
function BattleUtils.applyWeaknesses(damages, element, weaknessList)
if (utils.table.contain(weaknessList, element)) then
damages = damages * 1.2
end
return damages
end
function BattleUtils.applyResistences(damages, element, resistsList)
if (utils.table.contain(resistsList, element)) then
damages = damages * 0.8
end
return damages
end
function BattleUtils.rollDice(stat)
local stat = stat or 100
return (math.random(100) <= stat)
end
function BattleUtils.computerArmorAndDamage(stat, isNegative)
if (isNegative) then
stat = stat * -1
end
if (stat < 0) then
stat = stat * STATS.ARMOR_AND_DAMAGE_RATIO
end
return (100 + (stat))/100
end
return BattleUtils

View file

@ -0,0 +1,33 @@
local CharUtils = {}
local CONST = require "datas.consts.stats"
function CharUtils.getExpValue(level)
return math.floor( ( CONST.EXP_MULTIPLICATOR * ( level ^ 3 ) ) / CONST.EXP_RATIO )
end
function CharUtils.getRelativeExpValue(exp, level)
return exp - CharUtils.getExpValue(level)
end
function CharUtils.getLevelExpRange(level)
return CharUtils.getExpValue(level + 1) - CharUtils.getExpValue(level)
end
function CharUtils.getRemainingExp(exp, level)
return CharUtils.getExpValue(level + 1) - exp
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( (((CONST.SALT_HP + 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
return CharUtils

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