last_light/game/ui/menu/menu_character_creation_menu.go
2024-06-06 23:17:22 +03:00

198 lines
4.2 KiB
Go

package menu
import (
"fmt"
"mvvasilev/last_light/engine"
"mvvasilev/last_light/game/model"
"mvvasilev/last_light/game/systems"
"mvvasilev/last_light/game/ui"
"github.com/gdamore/tcell/v2"
"github.com/gdamore/tcell/v2/views"
"github.com/google/uuid"
)
type statSelection struct {
stat model.Stat
label *ui.UILabel
plusButton *ui.UILabel
statNumberLabel *ui.UILabel
minusButton *ui.UILabel
}
type StatState struct {
Stat model.Stat
Value int
}
type CharacterCreationMenuState struct {
AvailablePoints int
CurrentHighlight int
Stats []*StatState
RandomizeCharacter func()
StartGame func()
}
type CharacterCreationMenu struct {
window *ui.UIWindow
availablePointsLabel *ui.UILabel
state *CharacterCreationMenuState
stats []*statSelection
randomizeButton *ui.UISimpleButton
startGameButton *ui.UISimpleButton
style tcell.Style
}
func CreateCharacterCreationMenu(state *CharacterCreationMenuState, style tcell.Style) *CharacterCreationMenu {
ccm := &CharacterCreationMenu{
state: state,
window: ui.CreateWindow(0, 0, engine.TERMINAL_SIZE_WIDTH, engine.TERMINAL_SIZE_HEIGHT, "Create Character", style),
style: style,
}
ccm.UpdateState(state)
return ccm
}
func (ccm *CharacterCreationMenu) UpdateState(state *CharacterCreationMenuState) {
ccm.state = state
width, height := ccm.Size().WH()
availablePointsText := fmt.Sprintf("Available Points: %v", state.AvailablePoints)
ccm.availablePointsLabel = ui.CreateSingleLineUILabel(
width/2-len(availablePointsText)/2,
1,
availablePointsText,
ccm.style,
)
statPlaceholderText := fmt.Sprintf("%-12s [ < ] 00 [ > ]", "Placeholder")
statX := width/2 - len(statPlaceholderText)/2
statsArr := make([]*statSelection, 0, 4)
for i, s := range state.Stats {
labelStyle := ccm.style
if i == state.CurrentHighlight {
labelStyle = ccm.style.Attributes(tcell.AttrBold).Background(tcell.ColorWhite).Foreground(tcell.ColorBlack)
}
statsArr = append(
statsArr,
&statSelection{
stat: s.Stat,
label: ui.CreateSingleLineUILabel(
statX,
3+i,
model.StatLongName(s.Stat),
labelStyle,
),
minusButton: ui.CreateSingleLineUILabel(
statX+12+3, // Account for highlighting brackets
3+i,
"<",
ccm.style,
),
statNumberLabel: ui.CreateSingleLineUILabel(
statX+12+3+1+3,
3+i,
fmt.Sprintf("%02v", s.Value),
ccm.style,
),
plusButton: ui.CreateSingleLineUILabel(
statX+12+3+1+3+2+3, // Account for highlighting brackets
3+i,
">",
ccm.style,
),
},
)
}
ccm.stats = statsArr
randomizeLabel := "Randomize"
ccm.randomizeButton = ui.CreateSimpleButton(
width/2-len(randomizeLabel)/2,
3+len(statsArr)+1,
randomizeLabel,
ccm.style,
ccm.style.Attributes(tcell.AttrBold),
state.RandomizeCharacter,
)
startGameLabel := "Start Game"
ccm.startGameButton = ui.CreateSimpleButton(
width/2-len(startGameLabel)/2,
height-2,
startGameLabel,
ccm.style,
ccm.style.Attributes(tcell.AttrBold),
state.StartGame,
)
if state.CurrentHighlight == len(state.Stats) {
ccm.randomizeButton.Highlight()
}
if state.CurrentHighlight == len(state.Stats)+1 {
ccm.startGameButton.Highlight()
}
}
func (ccm *CharacterCreationMenu) SelectHighlight() {
if ccm.state.CurrentHighlight == len(ccm.state.Stats) {
ccm.randomizeButton.Select()
}
if ccm.state.CurrentHighlight == len(ccm.state.Stats)+1 {
ccm.startGameButton.Select()
}
}
func (ccm *CharacterCreationMenu) MoveTo(x int, y int) {
}
func (ccm *CharacterCreationMenu) Position() engine.Position {
return engine.PositionAt(0, 0)
}
func (ccm *CharacterCreationMenu) Size() engine.Size {
return engine.SizeOf(engine.TERMINAL_SIZE_WIDTH, engine.TERMINAL_SIZE_HEIGHT)
}
func (ccm *CharacterCreationMenu) Input(inputAction systems.InputAction) {
}
func (ccm *CharacterCreationMenu) UniqueId() uuid.UUID {
return uuid.New()
}
func (ccm *CharacterCreationMenu) Draw(v views.View) {
ccm.window.Draw(v)
ccm.availablePointsLabel.Draw(v)
for _, val := range ccm.stats {
val.label.Draw(v)
val.minusButton.Draw(v)
val.statNumberLabel.Draw(v)
val.plusButton.Draw(v)
}
ccm.randomizeButton.Draw(v)
ccm.startGameButton.Draw(v)
}