last_light/game/state/character_creation_state.go

172 lines
3.9 KiB
Go
Raw Permalink Normal View History

2024-05-31 23:37:06 +03:00
package state
import (
"mvvasilev/last_light/engine"
2024-06-06 23:17:22 +03:00
"mvvasilev/last_light/game/model"
"mvvasilev/last_light/game/systems"
2024-05-31 23:37:06 +03:00
"mvvasilev/last_light/game/ui/menu"
"github.com/gdamore/tcell/v2"
)
const (
MinStatValue = 1
MaxStatValue = 20
)
type CharacterCreationState struct {
2024-06-06 23:17:22 +03:00
turnSystem *systems.TurnSystem
inputSystem *systems.InputSystem
2024-05-31 23:37:06 +03:00
startGame bool
menuState *menu.CharacterCreationMenuState
ccMenu *menu.CharacterCreationMenu
}
2024-06-06 23:17:22 +03:00
func CreateCharacterCreationState(turnSystem *systems.TurnSystem, inputSystem *systems.InputSystem) *CharacterCreationState {
2024-05-31 23:37:06 +03:00
menuState := &menu.CharacterCreationMenuState{
AvailablePoints: 21,
CurrentHighlight: 0,
Stats: []*menu.StatState{
{
2024-06-06 23:17:22 +03:00
Stat: model.Stat_Attributes_Strength,
2024-05-31 23:37:06 +03:00
Value: 1,
},
{
2024-06-06 23:17:22 +03:00
Stat: model.Stat_Attributes_Dexterity,
2024-05-31 23:37:06 +03:00
Value: 1,
},
{
2024-06-06 23:17:22 +03:00
Stat: model.Stat_Attributes_Intelligence,
2024-05-31 23:37:06 +03:00
Value: 1,
},
{
2024-06-06 23:17:22 +03:00
Stat: model.Stat_Attributes_Constitution,
2024-05-31 23:37:06 +03:00
Value: 1,
},
},
}
ccs := &CharacterCreationState{
turnSystem: turnSystem,
inputSystem: inputSystem,
menuState: menuState,
ccMenu: menu.CreateCharacterCreationMenu(menuState, tcell.StyleDefault),
}
ccs.menuState.RandomizeCharacter = func() {
2024-06-06 23:17:22 +03:00
stats := model.RandomStats(21, 1, 20, []model.Stat{
model.Stat_Attributes_Strength,
model.Stat_Attributes_Constitution,
model.Stat_Attributes_Intelligence,
model.Stat_Attributes_Dexterity,
})
2024-05-31 23:37:06 +03:00
2024-06-01 11:20:51 +03:00
ccs.menuState.AvailablePoints = 0
ccs.menuState.Stats = []*menu.StatState{}
2024-05-31 23:37:06 +03:00
2024-06-01 11:20:51 +03:00
for k, v := range stats {
ccs.menuState.Stats = append(ccs.menuState.Stats, &menu.StatState{
Stat: k,
Value: v,
})
2024-05-31 23:37:06 +03:00
}
ccs.ccMenu.UpdateState(ccs.menuState)
}
ccs.menuState.StartGame = func() {
if ccs.menuState.AvailablePoints > 0 {
return
}
ccs.startGame = true
}
return ccs
}
2024-06-06 23:17:22 +03:00
func (ccs *CharacterCreationState) InputContext() systems.InputContext {
return systems.InputContext_Menu
2024-05-31 23:37:06 +03:00
}
func (ccs *CharacterCreationState) IncreaseStatValue() {
// If there are no points to allocate, stop
if ccs.menuState.AvailablePoints == 0 {
return
}
// If the current highlight is beyond the array range, stop
if ccs.menuState.CurrentHighlight < 0 || ccs.menuState.CurrentHighlight >= len(ccs.menuState.Stats) {
return
}
// If the allowed max state value has already been reached
if ccs.menuState.Stats[ccs.menuState.CurrentHighlight].Value+1 > MaxStatValue {
return
}
ccs.menuState.Stats[ccs.menuState.CurrentHighlight].Value++
ccs.menuState.AvailablePoints--
}
func (ccs *CharacterCreationState) DecreaseStatValue() {
// If the current highlight is beyond the array range, stop
if ccs.menuState.CurrentHighlight < 0 || ccs.menuState.CurrentHighlight >= len(ccs.menuState.Stats) {
return
}
// If the allowed min state value has already been reached
if ccs.menuState.Stats[ccs.menuState.CurrentHighlight].Value-1 < MinStatValue {
return
}
ccs.menuState.Stats[ccs.menuState.CurrentHighlight].Value--
ccs.menuState.AvailablePoints++
}
func (ccs *CharacterCreationState) OnTick(dt int64) GameState {
if ccs.startGame {
2024-06-06 23:17:22 +03:00
stats := map[model.Stat]int{}
2024-05-31 23:37:06 +03:00
for _, s := range ccs.menuState.Stats {
stats[s.Stat] = s.Value
}
return CreatePlayingState(ccs.turnSystem, ccs.inputSystem, stats)
}
action := ccs.inputSystem.NextAction()
switch action {
2024-06-06 23:17:22 +03:00
case systems.InputAction_Menu_HighlightRight:
2024-05-31 23:37:06 +03:00
ccs.IncreaseStatValue()
2024-06-06 23:17:22 +03:00
case systems.InputAction_Menu_HighlightLeft:
2024-05-31 23:37:06 +03:00
ccs.DecreaseStatValue()
2024-06-06 23:17:22 +03:00
case systems.InputAction_Menu_HighlightDown:
2024-06-01 11:20:51 +03:00
if ccs.menuState.CurrentHighlight > len(ccs.menuState.Stats) {
break
}
2024-05-31 23:37:06 +03:00
ccs.menuState.CurrentHighlight++
2024-06-06 23:17:22 +03:00
case systems.InputAction_Menu_HighlightUp:
2024-06-01 11:20:51 +03:00
if ccs.menuState.CurrentHighlight == 0 {
break
}
2024-05-31 23:37:06 +03:00
ccs.menuState.CurrentHighlight--
2024-06-06 23:17:22 +03:00
case systems.InputAction_Menu_Select:
2024-05-31 23:37:06 +03:00
ccs.ccMenu.SelectHighlight()
}
ccs.ccMenu.UpdateState(ccs.menuState)
return ccs
}
func (ccs *CharacterCreationState) CollectDrawables() []engine.Drawable {
return []engine.Drawable{ccs.ccMenu}
}