chore(cbs/menu): refactor the menu system to make adding widget simpler

This commit is contained in:
Kazhnuz 2019-08-31 14:09:48 +02:00
parent 7927146864
commit d39440fa29

View file

@ -4,10 +4,11 @@ local Widget = require "core.modules.menusystem.widgets"
local MenuConstructor = Object:extend() local MenuConstructor = Object:extend()
local CharacterMenu = ListBox:extend() local CharacterMenu = ListBox:extend()
local CharMenuWidget = Widget.Text:extend() local BattleWidget = Widget.Text:extend()
local SubMenuWidget = CharMenuWidget:extend() local ActionWidget = BattleWidget:extend()
local BackMenuWidget = CharMenuWidget:extend() local SubMenuWidget = BattleWidget:extend()
local SkillWidget = Widget.Text:extend() local BackMenuWidget = BattleWidget:extend()
local SkillWidget = BattleWidget:extend()
local MENUPOS_X1, MENUPOS_X2, MENUPOS_Y = 32, 32, 110 local MENUPOS_X1, MENUPOS_X2, MENUPOS_Y = 32, 32, 110
local MENU_WIDTH, MENU_ITEM_HEIGHT = 112, 17 local MENU_WIDTH, MENU_ITEM_HEIGHT = 112, 17
@ -32,12 +33,12 @@ end
function MenuConstructor:buildBaseMenu(character) function MenuConstructor:buildBaseMenu(character)
CharacterMenu(self.controller, "BaseMenu", MENUPOS_X1 - 16, MENUPOS_Y) CharacterMenu(self.controller, "BaseMenu", MENUPOS_X1 - 16, MENUPOS_Y)
CharMenuWidget(self.controller, "BaseMenu", "attack", "", character) ActionWidget(character, "BaseMenu", "attack")
SubMenuWidget(self.controller, "BaseMenu", "skills", "SkillMenu", character) SubMenuWidget(character, "BaseMenu", "skills", "SkillMenu")
SubMenuWidget(self.controller, "BaseMenu", "objects", "ObjectMenu", character) SubMenuWidget(character, "BaseMenu", "objects", "ObjectMenu")
CharMenuWidget(self.controller, "BaseMenu", "defend", "", character) ActionWidget(character, "BaseMenu", "defend")
CharMenuWidget(self.controller, "BaseMenu", "flee", "", character) ActionWidget(character, "BaseMenu", "flee")
BackMenuWidget(self.controller, "BaseMenu", "back", character) BackMenuWidget(character, "BaseMenu")
self.controller.menusystem.menus["BaseMenu"]:setCancelWidget() self.controller.menusystem.menus["BaseMenu"]:setCancelWidget()
end end
@ -50,9 +51,9 @@ function MenuConstructor:buildSkillMenu(character)
CharacterMenu(self.controller, "SkillMenu", MENUPOS_X1 - 16, MENUPOS_Y) CharacterMenu(self.controller, "SkillMenu", MENUPOS_X1 - 16, MENUPOS_Y)
local list = game.characters:getSkillList(character.charid) local list = game.characters:getSkillList(character.charid)
for k, skill in pairs(list) do for k, skill in pairs(list) do
SkillWidget(self.controller, "SkillMenu", skill.name, "", character) SkillWidget(character, "SkillMenu", skill.name, "")
end end
SubMenuWidget(self.controller, "SkillMenu", "back", "BaseMenu", character) SubMenuWidget(character, "SkillMenu", "back", "BaseMenu")
self.controller.menusystem.menus["SkillMenu"]:setCancelWidget() self.controller.menusystem.menus["SkillMenu"]:setCancelWidget()
end end
@ -66,16 +67,16 @@ function MenuConstructor:buildObjectMenu(character)
CharacterMenu(self.controller, "OtherMenu", MENUPOS_X1 - 16, MENUPOS_Y) CharacterMenu(self.controller, "OtherMenu", MENUPOS_X1 - 16, MENUPOS_Y)
SubMenuWidget(self.controller, "ObjectMenu", "heal", "MedMenu", character) SubMenuWidget(character, "ObjectMenu", "heal", "MedMenu")
SubMenuWidget(self.controller, "ObjectMenu", "rings", "RingMenu", character) SubMenuWidget(character, "ObjectMenu", "rings", "RingMenu")
SubMenuWidget(self.controller, "ObjectMenu", "wisps", "WispMenu", character) SubMenuWidget(character, "ObjectMenu", "wisps", "WispMenu")
SubMenuWidget(self.controller, "ObjectMenu", "other", "OtherMenu", character) SubMenuWidget(character, "ObjectMenu", "other", "OtherMenu")
SubMenuWidget(self.controller, "ObjectMenu", "back", "BaseMenu", character) SubMenuWidget(character, "ObjectMenu", "back", "BaseMenu")
SubMenuWidget(self.controller, "MedMenu", "back", "ObjectMenu", character) SubMenuWidget(character, "MedMenu", "back", "ObjectMenu")
SubMenuWidget(self.controller, "RingMenu", "back", "ObjectMenu", character) SubMenuWidget(character, "RingMenu", "back", "ObjectMenu")
SubMenuWidget(self.controller, "WispMenu", "back", "ObjectMenu", character) SubMenuWidget(character, "WispMenu", "back", "ObjectMenu")
SubMenuWidget(self.controller, "OtherMenu", "back", "ObjectMenu", character) SubMenuWidget(character, "OtherMenu", "back", "ObjectMenu")
self.controller.menusystem.menus["ObjectMenu"]:setCancelWidget() self.controller.menusystem.menus["ObjectMenu"]:setCancelWidget()
@ -125,35 +126,68 @@ end
-- WIDGETS -- WIDGETS
-- All widgets used by the Characters menus -- All widgets used by the Characters menus
function CharMenuWidget:new(scene, menu_name, label1, label2, character) -- Basic Battle Widget
self.character = character -- The base used by all battle widgets
self.menuname = menu_name
self.scene = scene
self.actionType = label1
local menu = scene.menusystem.menus[menu_name] or error("menu " ..menu_name .. " doesn't exist") function BattleWidget:new(character, menu_name, label1, label2, translationdata)
local font = scene.assets.fonts["small"] local menu = self:getControllers(character, menu_name)
CharMenuWidget.super.new(self, menu, font, core.lang:translate("battle", label1))
self.label2 = label2 or "" local translationdata = translationdata or "battle"
self.isSelected = false local label1 = label1 or ""
local label2 = label2 or ""
label1 = core.lang:translate(translationdata, label1)
local font = self.assets.fonts["small"]
BattleWidget.super.new(self, menu, font, label1)
self.label2 = label2
end end
function CharMenuWidget:update(dt) function BattleWidget:getControllers(character, menu_name)
CharMenuWidget.super.update(self, dt) self.character = character or core.debug:error("cbs/widget", "character must not be nil")
self.scene = self.character.scene
self.assets = self.character.assets
self.menusystem = self.scene.menusystem
self.menuname = menu_name
local menu = self.menusystem.menus[menu_name] or error("menu " ..menu_name .. " doesn't exist")
return menu
end end
function CharMenuWidget:selectAction() -- Internal functions
self.isSelected = true
if self.actionType == "attack" then function BattleWidget:update(dt)
self.scene.world:resetActiveGrid() BattleWidget.super.update(self, dt)
self.scene.world:setEffectGrid(self.character.x + self.character.direction, self.character.y, "point", 1, 1) end
function BattleWidget:selectAction()
self:setActiveGrid()
self:setEffectGrid()
end
function BattleWidget:setActiveGrid()
if (self:haveActiveGrid()) then
local ox, oy, shape, size, idk = self:getActiveGrid()
self.scene.world:setActiveGrid(ox, oy, shape, size, idk)
else else
self.scene.world:resetActiveGrid() self.scene.world:resetActiveGrid()
end
end
function BattleWidget:setEffectGrid()
if (self:haveEffectGrid()) then
local ox, oy, shape, size, idk = self:getEffectGrid()
self.scene.world:setEffectGrid(ox, oy, shape, size, idk)
else
self.scene.world:resetEffectGrid() self.scene.world:resetEffectGrid()
end end
end end
function CharMenuWidget:drawCanvas() function BattleWidget:drawCanvas()
local h local h
local asset = love.graphics.newImage("assets/gui/attacklist.png") local asset = love.graphics.newImage("assets/gui/attacklist.png")
love.graphics.draw(asset, 0, (self.height - 13) / 2) love.graphics.draw(asset, 0, (self.height - 13) / 2)
@ -166,18 +200,63 @@ function CharMenuWidget:drawCanvas()
self.font:print(self.label2, self.width - 9, h, "right") self.font:print(self.label2, self.width - 9, h, "right")
end end
function CharMenuWidget:action() function BattleWidget:action()
self.scene.world:resetActiveGrid() self.scene.world:resetActiveGrid()
self.scene.world:resetEffectGrid() self.scene.world:resetEffectGrid()
self.character:receiveSignal(self.actionType)
self:sendCharacterData()
self.scene:flushKeys() self.scene:flushKeys()
self.scene.menusystem:reset() self.scene.menusystem:reset()
end end
-- Submenu Widget -- External functions
function SubMenuWidget:new(scene, menu_name, label, newmenu, character) function BattleWidget:haveActiveGrid()
SubMenuWidget.super.new(self, scene, menu_name, label, "", character) return false
end
function BattleWidget:getActiveGrid()
return 0, 0, "point", 0, 0
end
function BattleWidget:haveEffectGrid()
return false
end
function BattleWidget:getEffectGrid()
return 0, 0, "point", 0, 0
end
function BattleWidget:sendCharacterData()
self.character:receiveSignal()
end
-- ActionWidget
-- The basic action widget
function ActionWidget:new(character, menu_name, action)
self.actionType = action or ""
ActionWidget.super.new(self, character, menu_name, action, "")
end
function ActionWidget:haveEffectGrid()
return (self.actionType == "attack")
end
function ActionWidget:getEffectGrid()
return self.character.x + self.character.direction, self.character.y, "point", 1, 1
end
function ActionWidget:sendCharacterData()
self.character:receiveSignal(self.actionType)
end
-- SubMenuWidget
-- A simple widget to change menu
function SubMenuWidget:new(character, menu_name, label, newmenu)
SubMenuWidget.super.new(self, character, menu_name, label, "")
self.newmenu = newmenu or "BaseMenu" self.newmenu = newmenu or "BaseMenu"
end end
@ -185,107 +264,88 @@ function SubMenuWidget:action()
self.scene.menusystem:switchMenu(self.newmenu) self.scene.menusystem:switchMenu(self.newmenu)
end end
-- Back Widget -- BackMenuWidget
-- Quit the menu
function BackMenuWidget:new(scene, menu_name, label, character) function BackMenuWidget:new(character, menu_name)
BackMenuWidget.super.new(self, scene, menu_name, "back", "", character) BackMenuWidget.super.new(self, character, menu_name, "back", "")
end end
function BackMenuWidget:action() function BackMenuWidget:sendCharacterData()
self.scene.world:resetActiveGrid()
self.scene.world:resetEffectGrid()
self.character:receiveBackSignal() self.character:receiveBackSignal()
self.scene:flushKeys()
self.scene.menusystem:reset()
end end
-- Skill Widget -- SkillWidget
-- A widget to handle skills
function SkillWidget:new(scene, menu_name, label1, label2, character) function SkillWidget:new(character, menu_name, skill)
self.character = character self.skillname = skill
self.menuname = menu_name local label2 = "00"
self.scene = scene
self.actionType = label1
local menu = scene.menusystem.menus[menu_name] or error("menu " ..menu_name .. " doesn't exist") self.skilldata = game.skills:getSkillData(skill)
local font = scene.assets.fonts["small"]
self.skilldata = game.skills:getSkillData(self.actionType)
CharMenuWidget.super.new(self, menu, font, core.lang:translate("skills", label1))
if self.skilldata ~= nil then if self.skilldata ~= nil then
self.label2 = self.skilldata.cost or 0 label2 = self.skilldata.cost or 0
if self.label2 < 10 then if label2 < 10 then
self.label2 = "0" .. self.label2 label2 = "0" .. label2
end end
else
self.label2 = "n"
end end
SkillWidget.super.new(self, character, menu_name, self.skillname, "-" .. label2, "skills")
end end
function SkillWidget:selectAction() function SkillWidget:selectAction()
if self.skilldata ~= nil then if self.skilldata ~= nil then
if self.skilldata.target == nil then SkillWidget.super.selectAction(self)
local x = self.character.x + self.skilldata.effectArea[1]
local y = self.character.y + self.skilldata.effectArea[2]
local shape = self.skilldata.effectArea[3]
local size = self.skilldata.effectArea[4]
local direction = self.character.direction
self.scene.world:resetActiveGrid()
self.scene.world:setEffectGrid(x, y, shape, size, direction)
else
local x = self.character.x + self.skilldata.target[1]
local y = self.character.y + self.skilldata.target[2]
local shape = self.skilldata.target[3]
local size = self.skilldata.target[4]
local direction = self.character.direction
self.scene.world:setActiveGrid(x, y, shape, size, direction)
self.scene.world:resetEffectGrid()
end
else else
self.scene.world:resetActiveGrid() self.scene.world:resetActiveGrid()
self.scene.world:resetEffectGrid() self.scene.world:resetEffectGrid()
end end
end end
function SkillWidget:haveActiveGrid()
function SkillWidget:drawCanvas() return (self.skilldata.target ~= nil)
local h
local asset = love.graphics.newImage("assets/gui/attacklist.png")
love.graphics.draw(asset, 0, (self.height - 13) / 2)
h = math.floor(self.height / 2) - (self.font:getHeight() / 2)
love.graphics.setColor(0, 0, 0, .8)
self.font:print(self.label, 17, h, "left")
self.font:print(self.label2, self.width - 8, h, "right")
utils.graphics.resetColor()
self.font:print(self.label, 16, h, "left")
self.font:print(self.label2, self.width - 9, h, "right")
end end
function SkillWidget:action() function SkillWidget:haveEffectGrid()
self.scene.world:resetActiveGrid() return ((self.skilldata.target == nil) and (self.skilldata.effectArea ~= nil))
self.scene.world:resetEffectGrid() end
function SkillWidget:getActiveGrid()
local x = self.character.x + self.skilldata.target[1]
local y = self.character.y + self.skilldata.target[2]
local shape = self.skilldata.target[3]
local size = self.skilldata.target[4]
local direction = self.character.direction
return x, y, shape, size, direction
end
function SkillWidget:getEffectGrid()
local x = self.character.x + self.skilldata.effectArea[1]
local y = self.character.y + self.skilldata.effectArea[2]
local shape = self.skilldata.effectArea[3]
local size = self.skilldata.effectArea[4]
local direction = self.character.direction
return x, y, shape, size, direction
end
function SkillWidget:sendCharacterData()
if self.skilldata ~= nil then if self.skilldata ~= nil then
if self.skilldata.target == nil then if self:haveActiveGrid() then
self.character:useSkill(self.actionType, self.character.x, self.character.y) local x, y, shape, size, direction = self:getActiveGrid()
else
local x = self.character.x + self.skilldata.target[1]
local y = self.character.y + self.skilldata.target[2]
local shape = self.skilldata.target[3]
local size = self.skilldata.target[4]
local direction = self.character.direction
self.scene.world.cursor:setGridIgnoreActor(x, y, shape, size, direction) self.scene.world.cursor:setGridIgnoreActor(x, y, shape, size, direction)
self.scene.world.cursor:set(self.character.x, self.character.y, "skill", self.actionType) self.scene.world.cursor:set(self.character.x, self.character.y, "skill", self.skillname)
else
self.character:useSkill(self.skillname, self.character.x, self.character.y)
end end
else else
core.debug:warning("cbs/menu", "skill " .. self.actionType .. " doesn't exist") core.debug:warning("cbs/menu", "skill " .. self.skillname .. " doesn't exist")
self.character:receiveSignal("none") self.character:receiveSignal("none")
end end
self.scene:flushKeys()
self.scene.menusystem:reset()
end end
return MenuConstructor return MenuConstructor