2024-04-27 22:32:05 +03:00
|
|
|
package state
|
|
|
|
|
|
|
|
import (
|
2024-05-06 20:43:35 +03:00
|
|
|
"mvvasilev/last_light/engine"
|
2024-06-06 23:17:22 +03:00
|
|
|
"mvvasilev/last_light/game/model"
|
|
|
|
"mvvasilev/last_light/game/systems"
|
2024-05-06 20:43:35 +03:00
|
|
|
"mvvasilev/last_light/game/ui/menu"
|
2024-04-27 22:32:05 +03:00
|
|
|
|
|
|
|
"github.com/gdamore/tcell/v2"
|
|
|
|
)
|
|
|
|
|
|
|
|
type InventoryScreenState struct {
|
2024-06-06 23:17:22 +03:00
|
|
|
eventLog *engine.GameEventLog
|
|
|
|
inputSystem *systems.InputSystem
|
|
|
|
turnSystem *systems.TurnSystem
|
|
|
|
dungeon *model.Dungeon
|
2024-05-30 23:39:54 +03:00
|
|
|
|
|
|
|
prevState GameState
|
2024-04-27 22:32:05 +03:00
|
|
|
exitMenu bool
|
|
|
|
|
2024-05-06 20:43:35 +03:00
|
|
|
inventoryMenu *menu.PlayerInventoryMenu
|
2024-05-06 21:47:20 +03:00
|
|
|
selectedInventorySlot engine.Position
|
2024-04-27 22:32:05 +03:00
|
|
|
|
2024-06-06 23:28:06 +03:00
|
|
|
player *model.Player
|
2024-04-27 22:32:05 +03:00
|
|
|
}
|
|
|
|
|
2024-06-06 23:28:06 +03:00
|
|
|
func CreateInventoryScreenState(eventLog *engine.GameEventLog, dungeon *model.Dungeon, inputSystem *systems.InputSystem, turnSystem *systems.TurnSystem, player *model.Player, prevState GameState) *InventoryScreenState {
|
2024-04-27 22:32:05 +03:00
|
|
|
iss := new(InventoryScreenState)
|
|
|
|
|
2024-06-06 23:17:22 +03:00
|
|
|
iss.eventLog = eventLog
|
2024-05-30 23:39:54 +03:00
|
|
|
iss.inputSystem = inputSystem
|
|
|
|
iss.turnSystem = turnSystem
|
2024-04-27 22:32:05 +03:00
|
|
|
iss.prevState = prevState
|
|
|
|
iss.player = player
|
2024-05-06 21:47:20 +03:00
|
|
|
iss.selectedInventorySlot = engine.PositionAt(0, 0)
|
2024-05-06 20:43:35 +03:00
|
|
|
iss.exitMenu = false
|
|
|
|
iss.inventoryMenu = menu.CreatePlayerInventoryMenu(43, 0, player.Inventory(), tcell.StyleDefault, tcell.StyleDefault.Background(tcell.ColorDarkSlateGray))
|
2024-06-06 23:17:22 +03:00
|
|
|
iss.dungeon = dungeon
|
2024-04-27 22:32:05 +03:00
|
|
|
|
|
|
|
return iss
|
|
|
|
}
|
|
|
|
|
2024-06-06 23:17:22 +03:00
|
|
|
func (s *InventoryScreenState) InputContext() systems.InputContext {
|
|
|
|
return systems.InputContext_Inventory
|
2024-04-27 22:32:05 +03:00
|
|
|
}
|
|
|
|
|
2024-05-30 23:39:54 +03:00
|
|
|
func (iss *InventoryScreenState) OnTick(dt int64) (nextState GameState) {
|
|
|
|
nextAction := iss.inputSystem.NextAction()
|
|
|
|
nextState = iss
|
2024-04-27 22:32:05 +03:00
|
|
|
|
2024-05-30 23:39:54 +03:00
|
|
|
switch nextAction {
|
2024-06-06 23:17:22 +03:00
|
|
|
case systems.InputAction_Menu_Exit:
|
2024-05-30 23:39:54 +03:00
|
|
|
nextState = iss.prevState
|
2024-06-06 23:17:22 +03:00
|
|
|
case systems.InputAction_InteractItem:
|
|
|
|
item := iss.player.Inventory().ItemAt(iss.selectedInventorySlot.XY())
|
|
|
|
|
|
|
|
if item == nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
if item.Usable() != nil {
|
|
|
|
item.Usable().Use(iss.eventLog, iss.dungeon, iss.player)
|
2024-06-15 17:46:09 +03:00
|
|
|
|
|
|
|
iss.player.Inventory().ReduceQuantityAt(iss.selectedInventorySlot.X(), iss.selectedInventorySlot.Y(), 1)
|
|
|
|
return
|
2024-06-06 23:17:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if item.Equippable() != nil {
|
|
|
|
if iss.player.Inventory().AtSlot(item.Equippable().Slot) != nil {
|
|
|
|
iss.player.Inventory().Push(iss.player.Inventory().AtSlot(item.Equippable().Slot))
|
|
|
|
}
|
|
|
|
|
|
|
|
iss.player.Inventory().Equip(item, item.Equippable().Slot)
|
|
|
|
}
|
|
|
|
|
2024-06-15 17:46:09 +03:00
|
|
|
iss.player.Inventory().Drop(iss.selectedInventorySlot.X(), iss.selectedInventorySlot.Y())
|
2024-06-06 23:17:22 +03:00
|
|
|
|
|
|
|
case systems.InputAction_DropItem:
|
2024-05-03 13:46:32 +03:00
|
|
|
iss.player.Inventory().Drop(iss.selectedInventorySlot.XY())
|
2024-06-06 23:17:22 +03:00
|
|
|
case systems.InputAction_Menu_HighlightUp:
|
2024-05-30 23:39:54 +03:00
|
|
|
if iss.selectedInventorySlot.Y() == 0 {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
iss.selectedInventorySlot = iss.selectedInventorySlot.WithOffset(0, -1)
|
|
|
|
iss.inventoryMenu.SelectSlot(iss.selectedInventorySlot.XY())
|
2024-06-06 23:17:22 +03:00
|
|
|
case systems.InputAction_Menu_HighlightDown:
|
2024-05-30 23:39:54 +03:00
|
|
|
if iss.selectedInventorySlot.Y() == iss.player.Inventory().Shape().Height()-1 {
|
|
|
|
break
|
|
|
|
}
|
2024-05-03 13:46:32 +03:00
|
|
|
|
2024-05-30 23:39:54 +03:00
|
|
|
iss.selectedInventorySlot = iss.selectedInventorySlot.WithOffset(0, +1)
|
|
|
|
iss.inventoryMenu.SelectSlot(iss.selectedInventorySlot.XY())
|
2024-06-06 23:17:22 +03:00
|
|
|
case systems.InputAction_Menu_HighlightLeft:
|
2024-05-30 23:39:54 +03:00
|
|
|
if iss.selectedInventorySlot.X() == 0 {
|
|
|
|
break
|
2024-05-03 13:46:32 +03:00
|
|
|
}
|
|
|
|
|
2024-05-30 23:39:54 +03:00
|
|
|
iss.selectedInventorySlot = iss.selectedInventorySlot.WithOffset(-1, 0)
|
|
|
|
iss.inventoryMenu.SelectSlot(iss.selectedInventorySlot.XY())
|
2024-06-06 23:17:22 +03:00
|
|
|
case systems.InputAction_Menu_HighlightRight:
|
2024-05-30 23:39:54 +03:00
|
|
|
if iss.selectedInventorySlot.X() == iss.player.Inventory().Shape().Width()-1 {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
iss.selectedInventorySlot = iss.selectedInventorySlot.WithOffset(+1, 0)
|
2024-05-06 20:43:35 +03:00
|
|
|
iss.inventoryMenu.SelectSlot(iss.selectedInventorySlot.XY())
|
2024-05-03 13:46:32 +03:00
|
|
|
}
|
|
|
|
|
2024-05-30 23:39:54 +03:00
|
|
|
return
|
2024-04-27 22:32:05 +03:00
|
|
|
}
|
|
|
|
|
2024-05-06 20:43:35 +03:00
|
|
|
func (iss *InventoryScreenState) CollectDrawables() []engine.Drawable {
|
2024-05-03 13:46:32 +03:00
|
|
|
drawables := append(
|
2024-04-27 22:32:05 +03:00
|
|
|
iss.prevState.CollectDrawables(),
|
|
|
|
iss.inventoryMenu,
|
|
|
|
)
|
2024-05-03 13:46:32 +03:00
|
|
|
|
|
|
|
return drawables
|
2024-04-27 22:32:05 +03:00
|
|
|
}
|