chore: initial non-working port of the gameplay
This commit is contained in:
parent
bc8d61728b
commit
ca3d486a83
102 changed files with 3468 additions and 1028 deletions
|
@ -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"},
|
||||
|
|
32
sonic-bluestreak.love/game/abstractmobs/character/datas.lua
Normal file
32
sonic-bluestreak.love/game/abstractmobs/character/datas.lua
Normal 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
|
60
sonic-bluestreak.love/game/abstractmobs/character/equip.lua
Normal file
60
sonic-bluestreak.love/game/abstractmobs/character/equip.lua
Normal 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
|
|
@ -0,0 +1,7 @@
|
|||
local CharacterHealth = Object:extend()
|
||||
|
||||
function CharacterHealth:heal()
|
||||
self:initLife()
|
||||
end
|
||||
|
||||
return CharacterHealth
|
74
sonic-bluestreak.love/game/abstractmobs/character/init.lua
Normal file
74
sonic-bluestreak.love/game/abstractmobs/character/init.lua
Normal 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
|
61
sonic-bluestreak.love/game/abstractmobs/character/levels.lua
Normal file
61
sonic-bluestreak.love/game/abstractmobs/character/levels.lua
Normal 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
|
|
@ -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
|
47
sonic-bluestreak.love/game/abstractmobs/ennemy/init.lua
Normal file
47
sonic-bluestreak.love/game/abstractmobs/ennemy/init.lua
Normal 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
|
|
@ -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
|
179
sonic-bluestreak.love/game/abstractmobs/parent.lua
Normal file
179
sonic-bluestreak.love/game/abstractmobs/parent.lua
Normal 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
|
36
sonic-bluestreak.love/game/abstractmobs/statmanager.lua
Normal file
36
sonic-bluestreak.love/game/abstractmobs/statmanager.lua
Normal 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
|
37
sonic-bluestreak.love/game/battle.lua
Normal file
37
sonic-bluestreak.love/game/battle.lua
Normal 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
|
|
@ -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
|
||||
|
||||
|
|
23
sonic-bluestreak.love/game/difficulty.lua
Normal file
23
sonic-bluestreak.love/game/difficulty.lua
Normal 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
|
|
@ -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
|
||||
|
|
12
sonic-bluestreak.love/game/events/conditions.lua
Normal file
12
sonic-bluestreak.love/game/events/conditions.lua
Normal 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
|
67
sonic-bluestreak.love/game/events/event/dialogbox.lua
Normal file
67
sonic-bluestreak.love/game/events/event/dialogbox.lua
Normal 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;
|
16
sonic-bluestreak.love/game/events/event/getItems.lua
Normal file
16
sonic-bluestreak.love/game/events/event/getItems.lua
Normal 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;
|
16
sonic-bluestreak.love/game/events/event/getRings.lua
Normal file
16
sonic-bluestreak.love/game/events/event/getRings.lua
Normal 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;
|
11
sonic-bluestreak.love/game/events/event/init.lua
Normal file
11
sonic-bluestreak.love/game/events/event/init.lua
Normal 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")
|
||||
}
|
26
sonic-bluestreak.love/game/events/event/parent.lua
Normal file
26
sonic-bluestreak.love/game/events/event/parent.lua
Normal 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
|
16
sonic-bluestreak.love/game/events/event/playSFX.lua
Normal file
16
sonic-bluestreak.love/game/events/event/playSFX.lua
Normal 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;
|
16
sonic-bluestreak.love/game/events/event/showGFX.lua
Normal file
16
sonic-bluestreak.love/game/events/event/showGFX.lua
Normal 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;
|
16
sonic-bluestreak.love/game/events/event/simpleMessage.lua
Normal file
16
sonic-bluestreak.love/game/events/event/simpleMessage.lua
Normal 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;
|
23
sonic-bluestreak.love/game/events/event/teleport.lua
Normal file
23
sonic-bluestreak.love/game/events/event/teleport.lua
Normal 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;
|
19
sonic-bluestreak.love/game/events/event/wait.lua
Normal file
19
sonic-bluestreak.love/game/events/event/wait.lua
Normal 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;
|
101
sonic-bluestreak.love/game/events/init.lua
Normal file
101
sonic-bluestreak.love/game/events/init.lua
Normal 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
|
|
@ -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( "" )
|
||||
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
|
||||
|
|
55
sonic-bluestreak.love/game/loot/effectManager.lua
Normal file
55
sonic-bluestreak.love/game/loot/effectManager.lua
Normal 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
|
17
sonic-bluestreak.love/game/loot/effects/blockstatus.lua
Normal file
17
sonic-bluestreak.love/game/loot/effects/blockstatus.lua
Normal 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
|
79
sonic-bluestreak.love/game/loot/effects/heal.lua
Normal file
79
sonic-bluestreak.love/game/loot/effects/heal.lua
Normal 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
|
6
sonic-bluestreak.love/game/loot/effects/init.lua
Normal file
6
sonic-bluestreak.love/game/loot/effects/init.lua
Normal 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"
|
||||
}
|
21
sonic-bluestreak.love/game/loot/effects/parent.lua
Normal file
21
sonic-bluestreak.love/game/loot/effects/parent.lua
Normal 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
|
19
sonic-bluestreak.love/game/loot/effects/protectelem.lua
Normal file
19
sonic-bluestreak.love/game/loot/effects/protectelem.lua
Normal 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
|
43
sonic-bluestreak.love/game/loot/effects/setstatus.lua
Normal file
43
sonic-bluestreak.love/game/loot/effects/setstatus.lua
Normal 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
|
67
sonic-bluestreak.love/game/loot/init.lua
Normal file
67
sonic-bluestreak.love/game/loot/init.lua
Normal 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
|
62
sonic-bluestreak.love/game/loot/pocket.lua
Normal file
62
sonic-bluestreak.love/game/loot/pocket.lua
Normal 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
|
83
sonic-bluestreak.love/game/metadata.lua
Normal file
83
sonic-bluestreak.love/game/metadata.lua
Normal 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
|
97
sonic-bluestreak.love/game/modules/confirmdialog/init.lua
Normal file
97
sonic-bluestreak.love/game/modules/confirmdialog/init.lua
Normal 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
|
23
sonic-bluestreak.love/game/modules/drawing/greyscale.lua
Normal file
23
sonic-bluestreak.love/game/modules/drawing/greyscale.lua
Normal 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
|
|
@ -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
|
52
sonic-bluestreak.love/game/modules/gui/actionPrompt.lua
Normal file
52
sonic-bluestreak.love/game/modules/gui/actionPrompt.lua
Normal 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
|
71
sonic-bluestreak.love/game/modules/gui/boxedmenu.lua
Normal file
71
sonic-bluestreak.love/game/modules/gui/boxedmenu.lua
Normal 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
|
22
sonic-bluestreak.love/game/modules/gui/choiceElem.lua
Normal file
22
sonic-bluestreak.love/game/modules/gui/choiceElem.lua
Normal 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
|
85
sonic-bluestreak.love/game/modules/gui/complexhpbar.lua
Normal file
85
sonic-bluestreak.love/game/modules/gui/complexhpbar.lua
Normal 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
|
45
sonic-bluestreak.love/game/modules/gui/emblem.lua
Normal file
45
sonic-bluestreak.love/game/modules/gui/emblem.lua
Normal 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
|
32
sonic-bluestreak.love/game/modules/gui/fancymenu.lua
Normal file
32
sonic-bluestreak.love/game/modules/gui/fancymenu.lua
Normal 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
|
|
@ -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
|
44
sonic-bluestreak.love/game/modules/gui/gameover.lua
Normal file
44
sonic-bluestreak.love/game/modules/gui/gameover.lua
Normal 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
|
|
@ -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
|
||||
|
||||
|
||||
|
|
72
sonic-bluestreak.love/game/modules/gui/menuback.lua
Normal file
72
sonic-bluestreak.love/game/modules/gui/menuback.lua
Normal 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
|
96
sonic-bluestreak.love/game/modules/gui/overlay.lua
Normal file
96
sonic-bluestreak.love/game/modules/gui/overlay.lua
Normal 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
|
30
sonic-bluestreak.love/game/modules/gui/simplehpbar.lua
Normal file
30
sonic-bluestreak.love/game/modules/gui/simplehpbar.lua
Normal 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
|
|
@ -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
|
78
sonic-bluestreak.love/game/modules/menus/fancy.lua
Normal file
78
sonic-bluestreak.love/game/modules/menus/fancy.lua
Normal 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
|
172
sonic-bluestreak.love/game/modules/menus/list.lua
Normal file
172
sonic-bluestreak.love/game/modules/menus/list.lua
Normal 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
|
36
sonic-bluestreak.love/game/modules/menus/parents/menu.lua
Normal file
36
sonic-bluestreak.love/game/modules/menus/parents/menu.lua
Normal 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
|
13
sonic-bluestreak.love/game/modules/menus/parents/widget.lua
Normal file
13
sonic-bluestreak.love/game/modules/menus/parents/widget.lua
Normal 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
|
40
sonic-bluestreak.love/game/modules/messagequeue/init.lua
Normal file
40
sonic-bluestreak.love/game/modules/messagequeue/init.lua
Normal 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
|
42
sonic-bluestreak.love/game/modules/messagequeue/message.lua
Normal file
42
sonic-bluestreak.love/game/modules/messagequeue/message.lua
Normal 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
|
|
@ -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"}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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)
|
||||
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
|
63
sonic-bluestreak.love/game/modules/subgames/pause.lua
Normal file
63
sonic-bluestreak.love/game/modules/subgames/pause.lua
Normal 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
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -0,0 +1,6 @@
|
|||
local Parent = require "game.modules.subgames.world.actors.ennemies.parent"
|
||||
local Motobug = Parent:extend()
|
||||
|
||||
|
||||
|
||||
return Motobug
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
||||
|
|
@ -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)
|
|
@ -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)
|
||||
|
|
@ -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
|
|
@ -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 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)
|
|
@ -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
|
|
@ -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
|
|
@ -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)
|
|
@ -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)
|
|
@ -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
|
5
sonic-bluestreak.love/game/modules/transitions/init.lua
Normal file
5
sonic-bluestreak.love/game/modules/transitions/init.lua
Normal file
|
@ -0,0 +1,5 @@
|
|||
return {
|
||||
sonic = require "game.modules.transitions.sonic",
|
||||
eggman = require "game.modules.transitions.eggman",
|
||||
borders = require "game.modules.transitions.zigzag",
|
||||
}
|
8
sonic-bluestreak.love/game/modules/transitions/sonic.lua
Normal file
8
sonic-bluestreak.love/game/modules/transitions/sonic.lua
Normal 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
|
41
sonic-bluestreak.love/game/modules/transitions/zigzag.lua
Normal file
41
sonic-bluestreak.love/game/modules/transitions/zigzag.lua
Normal 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
|
|
@ -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
|
|
@ -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
|
|
@ -1,6 +0,0 @@
|
|||
local Parent = require "game.modules.world.actors.ennemies.parent"
|
||||
local Motobug = Parent:extend()
|
||||
|
||||
|
||||
|
||||
return Motobug
|
|
@ -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
|
|
@ -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
|
45
sonic-bluestreak.love/game/scenes/init.lua
Normal file
45
sonic-bluestreak.love/game/scenes/init.lua
Normal 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
|
|
@ -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
|
84
sonic-bluestreak.love/game/utils/battle/init.lua
Normal file
84
sonic-bluestreak.love/game/utils/battle/init.lua
Normal 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
|
33
sonic-bluestreak.love/game/utils/characters.lua
Normal file
33
sonic-bluestreak.love/game/utils/characters.lua
Normal 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
Loading…
Reference in a new issue