sonic-radiance/sonic-radiance.love/scenes/battlesystem/menu.lua
2019-08-31 15:44:34 +02:00

379 lines
11 KiB
Lua

local ListBox = require "core.modules.menusystem.listbox"
local Widget = require "core.modules.menusystem.widgets"
local MenuConstructor = Object:extend()
local CharacterMenu = ListBox:extend()
local BattleWidget = Widget.Text:extend()
local ActionWidget = BattleWidget:extend()
local SubMenuWidget = BattleWidget:extend()
local BackMenuWidget = BattleWidget:extend()
local SkillWidget = BattleWidget:extend()
local MENUPOS_X1, MENUPOS_X2, MENUPOS_Y = 32, 32, 110
local MENU_WIDTH, MENU_ITEM_HEIGHT = 148, 17
local MENU_ITEM_NUMBER = 6
function MenuConstructor:new( controller )
self.controller = controller
end
function MenuConstructor:reconstruct(character)
self.controller.menusystem:reset()
self:build(character)
self.controller.menusystem:switchMenu("BaseMenu")
end
function MenuConstructor:build(character)
self:buildBaseMenu(character)
self:buildSkillMenu(character)
self:buildObjectMenu(character)
self.controller.menusystem:setSoundFromSceneAssets("mBeep")
end
function MenuConstructor:buildBaseMenu(character)
CharacterMenu(self.controller, "BaseMenu", MENUPOS_X1 - 16, MENUPOS_Y)
ActionWidget(character, "BaseMenu", "attack")
SubMenuWidget(character, "BaseMenu", "skills", "SkillMenu")
SubMenuWidget(character, "BaseMenu", "objects", "ObjectMenu")
ActionWidget(character, "BaseMenu", "defend")
ActionWidget(character, "BaseMenu", "flee")
BackMenuWidget(character, "BaseMenu")
self.controller.menusystem.menus["BaseMenu"]:setCancelWidget()
end
function MenuConstructor:set(currentCharacter)
self:reconstruct(currentCharacter)
end
function MenuConstructor:buildSkillMenu(character)
CharacterMenu(self.controller, "SkillMenu", MENUPOS_X1 - 16, MENUPOS_Y)
local list = game.characters:getSkillList(character.charid)
for k, skill in pairs(list) do
SkillWidget(character, "SkillMenu", skill.name, "")
end
SubMenuWidget(character, "SkillMenu", "back", "BaseMenu")
self.controller.menusystem.menus["SkillMenu"]:setCancelWidget()
end
function MenuConstructor:buildObjectMenu(character)
CharacterMenu(self.controller, "ObjectMenu", MENUPOS_X1 - 16, MENUPOS_Y)
CharacterMenu(self.controller, "MedMenu", MENUPOS_X1 - 16, MENUPOS_Y)
CharacterMenu(self.controller, "RingMenu", MENUPOS_X1 - 16, MENUPOS_Y)
CharacterMenu(self.controller, "WispMenu", MENUPOS_X1 - 16, MENUPOS_Y)
CharacterMenu(self.controller, "OtherMenu", MENUPOS_X1 - 16, MENUPOS_Y)
SubMenuWidget(character, "ObjectMenu", "heal", "MedMenu")
SubMenuWidget(character, "ObjectMenu", "rings", "RingMenu")
SubMenuWidget(character, "ObjectMenu", "wisps", "WispMenu")
SubMenuWidget(character, "ObjectMenu", "other", "OtherMenu")
SubMenuWidget(character, "ObjectMenu", "back", "BaseMenu")
SubMenuWidget(character, "MedMenu", "back", "ObjectMenu")
SubMenuWidget(character, "RingMenu", "back", "ObjectMenu")
SubMenuWidget(character, "WispMenu", "back", "ObjectMenu")
SubMenuWidget(character, "OtherMenu", "back", "ObjectMenu")
self.controller.menusystem.menus["ObjectMenu"]:setCancelWidget()
self.controller.menusystem.menus["MedMenu"]:setCancelWidget()
self.controller.menusystem.menus["RingMenu"]:setCancelWidget()
self.controller.menusystem.menus["WispMenu"]:setCancelWidget()
self.controller.menusystem.menus["OtherMenu"]:setCancelWidget()
end
function MenuConstructor:unset( )
self.isActive = false
end
-- CHARACTER_MENU
-- The actuals menus in the character menu
function CharacterMenu:new(scene, name, x, y)
self.scene = scene
local w, h = MENU_WIDTH, MENU_ITEM_NUMBER * MENU_ITEM_HEIGHT
CharacterMenu.super.new(self, scene.menusystem, name, x, y, w, h, MENU_ITEM_NUMBER)
self.cursorTexture = love.graphics.newImage("assets/gui/cursor-menulist.png")
self.cursorTransition = 1
end
function CharacterMenu:update(dt)
CharacterMenu.super.update(self, 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
self.cursorTransition = (self.cursorTransition) + ((relativecursor) - (self.cursorTransition)) * dt*45
end
end
function CharacterMenu:drawCursor()
local addition = 17
love.graphics.draw(self.cursorTexture, self.x + 4, self.y + (self.cursorTransition) * addition )
end
-- WIDGETS
-- All widgets used by the Characters menus
-- Basic Battle Widget
-- The base used by all battle widgets
function BattleWidget:new(character, menu_name, label1, label2, translationdata)
local menu = self:getControllers(character, menu_name)
local translationdata = translationdata or "battle"
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
function BattleWidget:getControllers(character, menu_name)
self.character = character or core.debug:error("cbs/widget", "character must not be nil")
self.scene = self.character.scene
self.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
-- Internal functions
function BattleWidget:update(dt)
BattleWidget.super.update(self, dt)
end
function BattleWidget:selectAction()
self:setActiveGrid()
self:setEffectGrid()
end
function BattleWidget:setActiveGrid()
if (self:haveActiveGrid()) then
local ox, oy, shape, size, idk = self:getActiveGrid()
self.scene.world:setActiveGrid(ox, oy, shape, size, idk)
else
self.scene.world:resetActiveGrid()
end
end
function BattleWidget:setEffectGrid()
if (self:haveEffectGrid()) then
local ox, oy, shape, size, idk = self:getEffectGrid()
self.scene.world:setEffectGrid(ox, oy, shape, size, idk)
else
self.scene.world:resetEffectGrid()
end
end
function BattleWidget:drawCanvas()
local h
local asset = love.graphics.newImage("assets/gui/attacklist.png")
local sw, sh = asset:getDimensions()
local startAsset = love.graphics.newQuad(0, 0, 16, sh, sw, sh)
local midAsset = love.graphics.newQuad(16, 0, 1, sh, sw, sh)
local endAsset = love.graphics.newQuad(sw-16, 0, 16, sh, sw, sh)
love.graphics.draw(asset, startAsset, 0, (self.height - 13) / 2)
love.graphics.draw(asset, endAsset, self.width-16, (self.height - 13) / 2)
local iterations = self.width-32
for i=0,iterations do
love.graphics.draw(asset, midAsset, 16+i, (self.height - 13) / 2)
end
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
function BattleWidget:action()
self.scene.world:resetActiveGrid()
self.scene.world:resetEffectGrid()
self:sendCharacterData()
self.scene:flushKeys()
self.scene.menusystem:reset()
end
-- External functions
function BattleWidget:haveActiveGrid()
return false
end
function BattleWidget:getActiveGrid()
return 0, 0, "point", 0, 0
end
function BattleWidget:haveEffectGrid()
return false
end
function BattleWidget:getEffectGrid()
return 0, 0, "point", 0, 0
end
function BattleWidget:sendCharacterData()
self.character:receiveSignal()
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)
local label2 = ""
self.sfx = "mBack"
if label ~= "back" then
label2 = ">"
self.sfx = "mBeep"
end
SubMenuWidget.super.new(self, character, menu_name, label, label2)
self.newmenu = newmenu or "BaseMenu"
end
function SubMenuWidget:action()
self.assets.sfx[self.sfx]:play()
self.scene.menusystem:switchMenu(self.newmenu)
end
-- BackMenuWidget
-- Quit the menu
function BackMenuWidget:new(character, menu_name)
BackMenuWidget.super.new(self, character, menu_name, "back", "")
end
function BackMenuWidget:sendCharacterData()
self.assets.sfx["mBack"]:play()
self.character:receiveBackSignal()
end
-- SkillWidget
-- A widget to handle skills
function SkillWidget:new(character, menu_name, skill)
self.skillname = skill
local label2 = "00"
self.skilldata = game.skills:getSkillData(skill)
if self.skilldata ~= nil then
label2 = self.skilldata.cost or 0
if label2 < 10 then
label2 = "0" .. label2
end
end
SkillWidget.super.new(self, character, menu_name, self.skillname, "-" .. label2, "skills")
end
function SkillWidget:selectAction()
if self.skilldata ~= nil then
SkillWidget.super.selectAction(self)
else
self.scene.world:resetActiveGrid()
self.scene.world:resetEffectGrid()
end
end
function SkillWidget:haveActiveGrid()
return (self.skilldata.target ~= nil)
end
function SkillWidget:haveEffectGrid()
return ((self.skilldata.target == nil) and (self.skilldata.effectArea ~= nil))
end
function SkillWidget:getActiveGrid()
local x = self.character.x + self.skilldata.target[1]
local y = self.character.y + self.skilldata.target[2]
local shape = self.skilldata.target[3]
local size = self.skilldata.target[4]
local direction = self.character.direction
return x, y, shape, size, direction
end
function SkillWidget:getEffectGrid()
local x = self.character.x + self.skilldata.effectArea[1]
local y = self.character.y + self.skilldata.effectArea[2]
local shape = self.skilldata.effectArea[3]
local size = self.skilldata.effectArea[4]
local direction = self.character.direction
return x, y, shape, size, direction
end
function SkillWidget:sendCharacterData()
if self.skilldata ~= nil then
if self:haveActiveGrid() then
local x, y, shape, size, direction = self:getActiveGrid()
self.scene.world.cursor:setGridIgnoreActor(x, y, shape, size, direction)
self.scene.world.cursor:set(self.character.x, self.character.y, "skill", self.skillname)
self.assets.sfx["mSelect"]:play()
else
self.assets.sfx["mSelect"]:play()
self.character:useSkill(self.skillname, self.character.x, self.character.y)
end
else
core.debug:warning("cbs/menu", "skill " .. self.skillname .. " doesn't exist")
self.character:receiveSignal("none")
self.assets.sfx["mError"]:play()
end
end
return MenuConstructor