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) }