mirror of
https://github.com/mvvasilev/last_light.git
synced 2025-04-19 12:49:52 +03:00
Create player inventory menu
This commit is contained in:
parent
b7b269e8b8
commit
5d1416bb07
30 changed files with 460 additions and 300 deletions
|
@ -1,4 +1,4 @@
|
||||||
package render
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gdamore/tcell/v2/views"
|
"github.com/gdamore/tcell/v2/views"
|
|
@ -1,4 +1,4 @@
|
||||||
package render
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mvvasilev/last_light/util"
|
"mvvasilev/last_light/util"
|
||||||
|
@ -119,6 +119,10 @@ func (g *Grid) Unhighlight() {
|
||||||
g.isHighlighted = false
|
g.isHighlighted = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *Grid) Position() util.Position {
|
||||||
|
return g.position
|
||||||
|
}
|
||||||
|
|
||||||
// C###T###T###C
|
// C###T###T###C
|
||||||
// # # # #
|
// # # # #
|
||||||
// # # # #
|
// # # # #
|
|
@ -1,4 +1,4 @@
|
||||||
package render
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"slices"
|
"slices"
|
|
@ -1,4 +1,4 @@
|
||||||
package render
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mvvasilev/last_light/util"
|
"mvvasilev/last_light/util"
|
|
@ -1,4 +1,4 @@
|
||||||
package render
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mvvasilev/last_light/util"
|
"mvvasilev/last_light/util"
|
|
@ -1,4 +1,4 @@
|
||||||
package render
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
|
@ -1,4 +1,4 @@
|
||||||
package render
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mvvasilev/last_light/util"
|
"mvvasilev/last_light/util"
|
|
@ -1,4 +1,4 @@
|
||||||
package render
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mvvasilev/last_light/util"
|
"mvvasilev/last_light/util"
|
|
@ -1,8 +1,8 @@
|
||||||
package game
|
package game
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"mvvasilev/last_light/engine"
|
||||||
"mvvasilev/last_light/game/state"
|
"mvvasilev/last_light/game/state"
|
||||||
"mvvasilev/last_light/render"
|
|
||||||
|
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
)
|
)
|
||||||
|
@ -46,6 +46,6 @@ func (g *Game) Tick(dt int64) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) CollectDrawables() []render.Drawable {
|
func (g *Game) CollectDrawables() []engine.Drawable {
|
||||||
return g.state.CollectDrawables()
|
return g.state.CollectDrawables()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package game
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"mvvasilev/last_light/render"
|
"mvvasilev/last_light/engine"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -10,7 +10,7 @@ import (
|
||||||
const TICK_RATE int64 = 50 // tick every 50ms ( 20 ticks per second )
|
const TICK_RATE int64 = 50 // tick every 50ms ( 20 ticks per second )
|
||||||
|
|
||||||
type GameContext struct {
|
type GameContext struct {
|
||||||
renderContext *render.RenderContext
|
renderContext *engine.RenderContext
|
||||||
|
|
||||||
game *Game
|
game *Game
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ type GameContext struct {
|
||||||
func CreateGameContext() *GameContext {
|
func CreateGameContext() *GameContext {
|
||||||
gc := new(GameContext)
|
gc := new(GameContext)
|
||||||
|
|
||||||
rc, err := render.CreateRenderContext()
|
rc, err := engine.CreateRenderContext()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("%~v", err)
|
log.Fatalf("%~v", err)
|
||||||
|
|
|
@ -2,13 +2,21 @@ package model
|
||||||
|
|
||||||
import "mvvasilev/last_light/util"
|
import "mvvasilev/last_light/util"
|
||||||
|
|
||||||
type Inventory struct {
|
type Inventory interface {
|
||||||
|
Items() []*Item
|
||||||
|
Shape() util.Size
|
||||||
|
Push(item Item) bool
|
||||||
|
Drop(x, y int) *Item
|
||||||
|
ItemAt(x, y int) *Item
|
||||||
|
}
|
||||||
|
|
||||||
|
type BasicInventory struct {
|
||||||
contents []*Item
|
contents []*Item
|
||||||
shape util.Size
|
shape util.Size
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateInventory(shape util.Size) *Inventory {
|
func CreateInventory(shape util.Size) *BasicInventory {
|
||||||
inv := new(Inventory)
|
inv := new(BasicInventory)
|
||||||
|
|
||||||
inv.contents = make([]*Item, 0, shape.Height()*shape.Width())
|
inv.contents = make([]*Item, 0, shape.Height()*shape.Width())
|
||||||
inv.shape = shape
|
inv.shape = shape
|
||||||
|
@ -16,15 +24,15 @@ func CreateInventory(shape util.Size) *Inventory {
|
||||||
return inv
|
return inv
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Inventory) Items() (items []*Item) {
|
func (i *BasicInventory) Items() (items []*Item) {
|
||||||
return i.contents
|
return i.contents
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Inventory) Shape() util.Size {
|
func (i *BasicInventory) Shape() util.Size {
|
||||||
return i.shape
|
return i.shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Inventory) Push(item Item) (success bool) {
|
func (i *BasicInventory) Push(item Item) (success bool) {
|
||||||
if len(i.contents) == i.shape.Area() {
|
if len(i.contents) == i.shape.Area() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -60,17 +68,21 @@ func (i *Inventory) Push(item Item) (success bool) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Inventory) Drop(x, y int) {
|
func (i *BasicInventory) Drop(x, y int) *Item {
|
||||||
index := y*i.shape.Width() + x
|
index := y*i.shape.Width() + x
|
||||||
|
|
||||||
if index > len(i.contents)-1 {
|
if index > len(i.contents)-1 {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item := i.contents[index]
|
||||||
|
|
||||||
i.contents[index] = nil
|
i.contents[index] = nil
|
||||||
|
|
||||||
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Inventory) ItemAt(x, y int) (item *Item) {
|
func (i *BasicInventory) ItemAt(x, y int) (item *Item) {
|
||||||
index := y*i.shape.Width() + x
|
index := y*i.shape.Width() + x
|
||||||
|
|
||||||
if index > len(i.contents)-1 {
|
if index > len(i.contents)-1 {
|
||||||
|
|
|
@ -1,126 +1,9 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
|
||||||
|
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ItemType struct {
|
|
||||||
name string
|
|
||||||
description string
|
|
||||||
tileIcon rune
|
|
||||||
itemIcon string
|
|
||||||
maxStack int
|
|
||||||
|
|
||||||
style tcell.Style
|
|
||||||
}
|
|
||||||
|
|
||||||
func (it *ItemType) Name() string {
|
|
||||||
return it.name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (it *ItemType) Description() string {
|
|
||||||
return it.description
|
|
||||||
}
|
|
||||||
|
|
||||||
func (it *ItemType) TileIcon() rune {
|
|
||||||
return it.tileIcon
|
|
||||||
}
|
|
||||||
|
|
||||||
func (it *ItemType) Icon() string {
|
|
||||||
return it.itemIcon
|
|
||||||
}
|
|
||||||
|
|
||||||
func (it *ItemType) Style() tcell.Style {
|
|
||||||
return it.style
|
|
||||||
}
|
|
||||||
|
|
||||||
func (it *ItemType) MaxStack() int {
|
|
||||||
return it.maxStack
|
|
||||||
}
|
|
||||||
|
|
||||||
func ItemTypeFish() *ItemType {
|
|
||||||
return &ItemType{
|
|
||||||
name: "Fish",
|
|
||||||
description: "What's a fish doing down here?",
|
|
||||||
tileIcon: '>',
|
|
||||||
itemIcon: "»o>",
|
|
||||||
style: tcell.StyleDefault.Foreground(tcell.ColorDarkCyan),
|
|
||||||
maxStack: 16,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ItemTypeGold() *ItemType {
|
|
||||||
return &ItemType{
|
|
||||||
name: "Gold",
|
|
||||||
description: "Not all those who wander are lost",
|
|
||||||
tileIcon: '¤',
|
|
||||||
itemIcon: " ¤ ",
|
|
||||||
style: tcell.StyleDefault.Foreground(tcell.ColorGoldenrod),
|
|
||||||
maxStack: 255,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ItemTypeArrow() *ItemType {
|
|
||||||
return &ItemType{
|
|
||||||
name: "Arrow",
|
|
||||||
description: "Ammunition for a bow",
|
|
||||||
tileIcon: '-',
|
|
||||||
itemIcon: "»->",
|
|
||||||
style: tcell.StyleDefault.Foreground(tcell.ColorGoldenrod),
|
|
||||||
maxStack: 32,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ItemTypeBow() *ItemType {
|
|
||||||
return &ItemType{
|
|
||||||
name: "Bow",
|
|
||||||
description: "To shoot arrows with",
|
|
||||||
tileIcon: ')',
|
|
||||||
itemIcon: " |)",
|
|
||||||
style: tcell.StyleDefault.Foreground(tcell.ColorBrown),
|
|
||||||
maxStack: 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ItemTypeLongsword() *ItemType {
|
|
||||||
return &ItemType{
|
|
||||||
name: "Longsword",
|
|
||||||
description: "You know nothing.",
|
|
||||||
tileIcon: '/',
|
|
||||||
itemIcon: "╪══",
|
|
||||||
style: tcell.StyleDefault.Foreground(tcell.ColorSilver),
|
|
||||||
maxStack: 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ItemTypeKey() *ItemType {
|
|
||||||
return &ItemType{
|
|
||||||
name: "Key",
|
|
||||||
description: "Indispensable for unlocking things",
|
|
||||||
tileIcon: '¬',
|
|
||||||
itemIcon: " o╖",
|
|
||||||
style: tcell.StyleDefault.Foreground(tcell.ColorDarkGoldenrod),
|
|
||||||
maxStack: 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type ItemTypeGenTable struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenerateItemType(genTable map[float32]*ItemType) *ItemType {
|
|
||||||
num := rand.Float32()
|
|
||||||
|
|
||||||
for k, v := range genTable {
|
|
||||||
if num > k {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Item struct {
|
type Item struct {
|
||||||
name string
|
name string
|
||||||
description string
|
description string
|
||||||
|
|
119
game/model/item_type.go
Normal file
119
game/model/item_type.go
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/gdamore/tcell/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ItemType struct {
|
||||||
|
name string
|
||||||
|
description string
|
||||||
|
tileIcon rune
|
||||||
|
itemIcon string
|
||||||
|
maxStack int
|
||||||
|
|
||||||
|
style tcell.Style
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *ItemType) Name() string {
|
||||||
|
return it.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *ItemType) Description() string {
|
||||||
|
return it.description
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *ItemType) TileIcon() rune {
|
||||||
|
return it.tileIcon
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *ItemType) Icon() string {
|
||||||
|
return it.itemIcon
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *ItemType) Style() tcell.Style {
|
||||||
|
return it.style
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *ItemType) MaxStack() int {
|
||||||
|
return it.maxStack
|
||||||
|
}
|
||||||
|
|
||||||
|
func ItemTypeFish() *ItemType {
|
||||||
|
return &ItemType{
|
||||||
|
name: "Fish",
|
||||||
|
description: "What's a fish doing down here?",
|
||||||
|
tileIcon: '>',
|
||||||
|
itemIcon: "»o>",
|
||||||
|
style: tcell.StyleDefault.Foreground(tcell.ColorDarkCyan),
|
||||||
|
maxStack: 16,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ItemTypeGold() *ItemType {
|
||||||
|
return &ItemType{
|
||||||
|
name: "Gold",
|
||||||
|
description: "Not all those who wander are lost",
|
||||||
|
tileIcon: '¤',
|
||||||
|
itemIcon: " ¤ ",
|
||||||
|
style: tcell.StyleDefault.Foreground(tcell.ColorGoldenrod),
|
||||||
|
maxStack: 255,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ItemTypeArrow() *ItemType {
|
||||||
|
return &ItemType{
|
||||||
|
name: "Arrow",
|
||||||
|
description: "Ammunition for a bow",
|
||||||
|
tileIcon: '-',
|
||||||
|
itemIcon: "»->",
|
||||||
|
style: tcell.StyleDefault.Foreground(tcell.ColorGoldenrod),
|
||||||
|
maxStack: 32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ItemTypeBow() *ItemType {
|
||||||
|
return &ItemType{
|
||||||
|
name: "Bow",
|
||||||
|
description: "To shoot arrows with",
|
||||||
|
tileIcon: ')',
|
||||||
|
itemIcon: " |)",
|
||||||
|
style: tcell.StyleDefault.Foreground(tcell.ColorBrown),
|
||||||
|
maxStack: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ItemTypeLongsword() *ItemType {
|
||||||
|
return &ItemType{
|
||||||
|
name: "Longsword",
|
||||||
|
description: "You know nothing.",
|
||||||
|
tileIcon: '/',
|
||||||
|
itemIcon: "╪══",
|
||||||
|
style: tcell.StyleDefault.Foreground(tcell.ColorSilver),
|
||||||
|
maxStack: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ItemTypeKey() *ItemType {
|
||||||
|
return &ItemType{
|
||||||
|
name: "Key",
|
||||||
|
description: "Indispensable for unlocking things",
|
||||||
|
tileIcon: '¬',
|
||||||
|
itemIcon: " o╖",
|
||||||
|
style: tcell.StyleDefault.Foreground(tcell.ColorDarkGoldenrod),
|
||||||
|
maxStack: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenerateItemType(genTable map[float32]*ItemType) *ItemType {
|
||||||
|
num := rand.Float32()
|
||||||
|
|
||||||
|
for k, v := range genTable {
|
||||||
|
if num > k {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -11,7 +11,7 @@ type Player struct {
|
||||||
id uuid.UUID
|
id uuid.UUID
|
||||||
position util.Position
|
position util.Position
|
||||||
|
|
||||||
inventory *Inventory
|
inventory *EquippedInventory
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreatePlayer(x, y int) *Player {
|
func CreatePlayer(x, y int) *Player {
|
||||||
|
@ -19,7 +19,7 @@ func CreatePlayer(x, y int) *Player {
|
||||||
|
|
||||||
p.id = uuid.New()
|
p.id = uuid.New()
|
||||||
p.position = util.PositionAt(x, y)
|
p.position = util.PositionAt(x, y)
|
||||||
p.inventory = CreateInventory(util.SizeOf(8, 4))
|
p.inventory = CreatePlayerInventory()
|
||||||
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ func (p *Player) Transparent() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Player) Inventory() *Inventory {
|
func (p *Player) Inventory() *EquippedInventory {
|
||||||
return p.inventory
|
return p.inventory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
72
game/model/player_inventory.go
Normal file
72
game/model/player_inventory.go
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
import "mvvasilev/last_light/util"
|
||||||
|
|
||||||
|
type EquippedSlot int
|
||||||
|
|
||||||
|
const (
|
||||||
|
EquippedSlotOffhand EquippedSlot = iota
|
||||||
|
EquippedSlotDominantHand
|
||||||
|
EquippedSlotHead
|
||||||
|
EquippedSlotChestplate
|
||||||
|
EquippedSlotLeggings
|
||||||
|
EquippedSlotShoes
|
||||||
|
)
|
||||||
|
|
||||||
|
type EquippedInventory struct {
|
||||||
|
offHand *Item
|
||||||
|
dominantHand *Item
|
||||||
|
|
||||||
|
head *Item
|
||||||
|
chestplate *Item
|
||||||
|
leggings *Item
|
||||||
|
shoes *Item
|
||||||
|
|
||||||
|
*BasicInventory
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreatePlayerInventory() *EquippedInventory {
|
||||||
|
return &EquippedInventory{
|
||||||
|
BasicInventory: CreateInventory(util.SizeOf(8, 4)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ei *EquippedInventory) AtSlot(slot EquippedSlot) *Item {
|
||||||
|
switch slot {
|
||||||
|
case EquippedSlotOffhand:
|
||||||
|
return ei.offHand
|
||||||
|
case EquippedSlotDominantHand:
|
||||||
|
return ei.dominantHand
|
||||||
|
case EquippedSlotHead:
|
||||||
|
return ei.head
|
||||||
|
case EquippedSlotChestplate:
|
||||||
|
return ei.chestplate
|
||||||
|
case EquippedSlotLeggings:
|
||||||
|
return ei.leggings
|
||||||
|
case EquippedSlotShoes:
|
||||||
|
return ei.shoes
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ei *EquippedInventory) Equip(item Item, slot EquippedSlot) *Item {
|
||||||
|
ref := &item
|
||||||
|
|
||||||
|
switch slot {
|
||||||
|
case EquippedSlotOffhand:
|
||||||
|
ei.offHand = ref
|
||||||
|
case EquippedSlotDominantHand:
|
||||||
|
ei.dominantHand = ref
|
||||||
|
case EquippedSlotHead:
|
||||||
|
ei.head = ref
|
||||||
|
case EquippedSlotChestplate:
|
||||||
|
ei.chestplate = ref
|
||||||
|
case EquippedSlotLeggings:
|
||||||
|
ei.leggings = ref
|
||||||
|
case EquippedSlotShoes:
|
||||||
|
ei.shoes = ref
|
||||||
|
}
|
||||||
|
|
||||||
|
return ref
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mvvasilev/last_light/render"
|
"mvvasilev/last_light/engine"
|
||||||
|
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
)
|
)
|
||||||
|
@ -9,7 +9,7 @@ import (
|
||||||
type GameState interface {
|
type GameState interface {
|
||||||
OnInput(e *tcell.EventKey)
|
OnInput(e *tcell.EventKey)
|
||||||
OnTick(dt int64) GameState
|
OnTick(dt int64) GameState
|
||||||
CollectDrawables() []render.Drawable
|
CollectDrawables() []engine.Drawable
|
||||||
}
|
}
|
||||||
|
|
||||||
type PausableState interface {
|
type PausableState interface {
|
||||||
|
|
|
@ -1,36 +1,24 @@
|
||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"mvvasilev/last_light/engine"
|
||||||
"mvvasilev/last_light/game/model"
|
"mvvasilev/last_light/game/model"
|
||||||
"mvvasilev/last_light/render"
|
"mvvasilev/last_light/game/ui/menu"
|
||||||
"mvvasilev/last_light/ui"
|
|
||||||
"mvvasilev/last_light/util"
|
"mvvasilev/last_light/util"
|
||||||
|
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
"github.com/gdamore/tcell/v2/views"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type InventoryScreenState struct {
|
type InventoryScreenState struct {
|
||||||
prevState PausableState
|
prevState PausableState
|
||||||
exitMenu bool
|
exitMenu bool
|
||||||
|
|
||||||
inventoryMenu *ui.UIWindow
|
inventoryMenu *menu.PlayerInventoryMenu
|
||||||
armourLabel *ui.UILabel
|
selectedInventorySlot util.Position
|
||||||
armourGrid *render.Grid
|
|
||||||
leftHandLabel *ui.UILabel
|
|
||||||
leftHandBox render.Rectangle
|
|
||||||
rightHandLabel *ui.UILabel
|
|
||||||
rightHandBox render.Rectangle
|
|
||||||
inventoryGrid *render.Grid
|
|
||||||
playerItems *render.ArbitraryDrawable
|
|
||||||
selectedItem *render.ArbitraryDrawable
|
|
||||||
help *ui.UILabel
|
|
||||||
|
|
||||||
player *model.Player
|
player *model.Player
|
||||||
|
|
||||||
moveInventorySlotDirection model.Direction
|
moveInventorySlotDirection model.Direction
|
||||||
selectedInventorySlot util.Position
|
|
||||||
dropSelectedInventorySlot bool
|
dropSelectedInventorySlot bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,88 +27,9 @@ func CreateInventoryScreenState(player *model.Player, prevState PausableState) *
|
||||||
|
|
||||||
iss.prevState = prevState
|
iss.prevState = prevState
|
||||||
iss.player = player
|
iss.player = player
|
||||||
iss.exitMenu = false
|
|
||||||
iss.selectedInventorySlot = util.PositionAt(0, 0)
|
iss.selectedInventorySlot = util.PositionAt(0, 0)
|
||||||
|
iss.exitMenu = false
|
||||||
iss.inventoryMenu = ui.CreateWindow(43, 0, 37, 24, "INVENTORY", tcell.StyleDefault)
|
iss.inventoryMenu = menu.CreatePlayerInventoryMenu(43, 0, player.Inventory(), tcell.StyleDefault, tcell.StyleDefault.Background(tcell.ColorDarkSlateGray))
|
||||||
|
|
||||||
iss.armourLabel = ui.CreateSingleLineUILabel(58, 1, "ARMOUR", tcell.StyleDefault)
|
|
||||||
|
|
||||||
iss.armourGrid = render.CreateGrid(
|
|
||||||
53, 2, 3, 1, 4, 1, '┌', '─', '┬', '┐', '│', ' ', '│', '│', '├', '─', '┼', '┤', '└', '─', '┴', '┘', tcell.StyleDefault, tcell.StyleDefault.Background(tcell.ColorDarkSlateGray),
|
|
||||||
)
|
|
||||||
|
|
||||||
iss.leftHandLabel = ui.CreateUILabel(
|
|
||||||
46, 1, 5, 1, "OFF", tcell.StyleDefault,
|
|
||||||
)
|
|
||||||
|
|
||||||
iss.leftHandBox = render.CreateRectangle(
|
|
||||||
45, 2, 5, 3,
|
|
||||||
'┌', '─', '┐',
|
|
||||||
'│', ' ', '│',
|
|
||||||
'└', '─', '┘',
|
|
||||||
false, true,
|
|
||||||
tcell.StyleDefault,
|
|
||||||
)
|
|
||||||
|
|
||||||
iss.rightHandLabel = ui.CreateUILabel(
|
|
||||||
74, 1, 5, 1, "DOM", tcell.StyleDefault,
|
|
||||||
)
|
|
||||||
|
|
||||||
iss.rightHandBox = render.CreateRectangle(
|
|
||||||
73, 2, 5, 3,
|
|
||||||
'┌', '─', '┐',
|
|
||||||
'│', ' ', '│',
|
|
||||||
'└', '─', '┘',
|
|
||||||
false, true,
|
|
||||||
tcell.StyleDefault,
|
|
||||||
)
|
|
||||||
|
|
||||||
iss.inventoryGrid = render.CreateGrid(
|
|
||||||
45, 5, 3, 1, 8, 4, '┌', '─', '┬', '┐', '│', ' ', '│', '│', '├', '─', '┼', '┤', '└', '─', '┴', '┘', tcell.StyleDefault, tcell.StyleDefault.Background(tcell.ColorDarkSlateGray),
|
|
||||||
)
|
|
||||||
|
|
||||||
iss.playerItems = render.CreateDrawingInstructions(func(v views.View) {
|
|
||||||
for y := range player.Inventory().Shape().Height() {
|
|
||||||
for x := range player.Inventory().Shape().Width() {
|
|
||||||
item := player.Inventory().ItemAt(x, y)
|
|
||||||
isHighlighted := x == iss.selectedInventorySlot.X() && y == iss.selectedInventorySlot.Y()
|
|
||||||
|
|
||||||
if item == nil {
|
|
||||||
|
|
||||||
if isHighlighted {
|
|
||||||
ui.CreateSingleLineUILabel(45+1+x*4, 5+1+y*2, " ", tcell.StyleDefault.Background(tcell.ColorDarkSlateGray)).Draw(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
style := item.Type().Style()
|
|
||||||
|
|
||||||
if isHighlighted {
|
|
||||||
style = style.Background(tcell.ColorDarkSlateGray)
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.CreateSingleLineUILabel(45+1+x*4, 5+y*2, fmt.Sprintf("%03d", item.Quantity()), style).Draw(v)
|
|
||||||
ui.CreateSingleLineUILabel(45+1+x*4, 5+1+y*2, item.Type().Icon(), style).Draw(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
iss.selectedItem = render.CreateDrawingInstructions(func(v views.View) {
|
|
||||||
ui.CreateWindow(45, 14, 33, 8, "ITEM", tcell.StyleDefault).Draw(v)
|
|
||||||
|
|
||||||
item := player.Inventory().ItemAt(iss.selectedInventorySlot.XY())
|
|
||||||
|
|
||||||
if item == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.CreateSingleLineUILabel(46, 15, fmt.Sprintf("Name: %v", item.Name()), tcell.StyleDefault).Draw(v)
|
|
||||||
ui.CreateSingleLineUILabel(46, 16, fmt.Sprintf("Desc: %v", item.Description()), tcell.StyleDefault).Draw(v)
|
|
||||||
})
|
|
||||||
|
|
||||||
iss.help = ui.CreateSingleLineUILabel(45, 22, "hjkl - move, x - drop, e - equip", tcell.StyleDefault)
|
|
||||||
|
|
||||||
return iss
|
return iss
|
||||||
}
|
}
|
||||||
|
@ -190,27 +99,17 @@ func (iss *InventoryScreenState) OnTick(dt int64) GameState {
|
||||||
iss.selectedInventorySlot = iss.selectedInventorySlot.WithOffset(+1, 0)
|
iss.selectedInventorySlot = iss.selectedInventorySlot.WithOffset(+1, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
iss.inventoryGrid.Highlight(iss.selectedInventorySlot)
|
iss.inventoryMenu.SelectSlot(iss.selectedInventorySlot.XY())
|
||||||
iss.moveInventorySlotDirection = model.DirectionNone
|
iss.moveInventorySlotDirection = model.DirectionNone
|
||||||
}
|
}
|
||||||
|
|
||||||
return iss
|
return iss
|
||||||
}
|
}
|
||||||
|
|
||||||
func (iss *InventoryScreenState) CollectDrawables() []render.Drawable {
|
func (iss *InventoryScreenState) CollectDrawables() []engine.Drawable {
|
||||||
drawables := append(
|
drawables := append(
|
||||||
iss.prevState.CollectDrawables(),
|
iss.prevState.CollectDrawables(),
|
||||||
iss.inventoryMenu,
|
iss.inventoryMenu,
|
||||||
iss.armourLabel,
|
|
||||||
iss.armourGrid,
|
|
||||||
iss.leftHandLabel,
|
|
||||||
iss.leftHandBox,
|
|
||||||
iss.rightHandLabel,
|
|
||||||
iss.rightHandBox,
|
|
||||||
iss.inventoryGrid,
|
|
||||||
iss.playerItems,
|
|
||||||
iss.selectedItem,
|
|
||||||
iss.help,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return drawables
|
return drawables
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mvvasilev/last_light/render"
|
"mvvasilev/last_light/engine"
|
||||||
|
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
)
|
)
|
||||||
|
@ -17,6 +17,6 @@ func (ls *LookState) OnTick(dt int64) GameState {
|
||||||
panic("not implemented") // TODO: Implement
|
panic("not implemented") // TODO: Implement
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ls *LookState) CollectDrawables() []render.Drawable {
|
func (ls *LookState) CollectDrawables() []engine.Drawable {
|
||||||
panic("not implemented") // TODO: Implement
|
panic("not implemented") // TODO: Implement
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mvvasilev/last_light/render"
|
"mvvasilev/last_light/engine"
|
||||||
"mvvasilev/last_light/ui"
|
"mvvasilev/last_light/game/ui"
|
||||||
"mvvasilev/last_light/util"
|
"mvvasilev/last_light/util"
|
||||||
|
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MainMenuState struct {
|
type MainMenuState struct {
|
||||||
menuTitle *render.Raw
|
menuTitle *engine.Raw
|
||||||
buttons []*ui.UISimpleButton
|
buttons []*ui.UISimpleButton
|
||||||
currButtonSelected int
|
currButtonSelected int
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ func NewMainMenuState() *MainMenuState {
|
||||||
|
|
||||||
highlightStyle := tcell.StyleDefault.Attributes(tcell.AttrBold)
|
highlightStyle := tcell.StyleDefault.Attributes(tcell.AttrBold)
|
||||||
|
|
||||||
state.menuTitle = render.CreateRawDrawable(
|
state.menuTitle = engine.CreateRawDrawable(
|
||||||
11, 1, tcell.StyleDefault.Attributes(tcell.AttrBold).Foreground(tcell.ColorYellow),
|
11, 1, tcell.StyleDefault.Attributes(tcell.AttrBold).Foreground(tcell.ColorYellow),
|
||||||
" | | | _) | | ",
|
" | | | _) | | ",
|
||||||
" | _` | __| __| | | _` | __ \\ __|",
|
" | _` | __| __| | | _` | __ \\ __|",
|
||||||
|
@ -77,8 +77,8 @@ func (mms *MainMenuState) OnTick(dt int64) GameState {
|
||||||
return mms
|
return mms
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mms *MainMenuState) CollectDrawables() []render.Drawable {
|
func (mms *MainMenuState) CollectDrawables() []engine.Drawable {
|
||||||
arr := make([]render.Drawable, 0)
|
arr := make([]engine.Drawable, 0)
|
||||||
|
|
||||||
arr = append(arr, mms.menuTitle)
|
arr = append(arr, mms.menuTitle)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mvvasilev/last_light/render"
|
"mvvasilev/last_light/engine"
|
||||||
"mvvasilev/last_light/ui"
|
"mvvasilev/last_light/game/ui"
|
||||||
"mvvasilev/last_light/util"
|
"mvvasilev/last_light/util"
|
||||||
|
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
|
@ -26,7 +26,7 @@ func PauseGame(prevState PausableState) *PauseGameState {
|
||||||
|
|
||||||
highlightStyle := tcell.StyleDefault.Attributes(tcell.AttrBold)
|
highlightStyle := tcell.StyleDefault.Attributes(tcell.AttrBold)
|
||||||
|
|
||||||
s.pauseMenuWindow = ui.CreateWindow(int(render.TERMINAL_SIZE_WIDTH)/2-15, int(render.TERMINAL_SIZE_HEIGHT)/2-7, 30, 14, "PAUSED", tcell.StyleDefault)
|
s.pauseMenuWindow = ui.CreateWindow(int(engine.TERMINAL_SIZE_WIDTH)/2-15, int(engine.TERMINAL_SIZE_HEIGHT)/2-7, 30, 14, "PAUSED", tcell.StyleDefault)
|
||||||
s.buttons = make([]*ui.UISimpleButton, 0)
|
s.buttons = make([]*ui.UISimpleButton, 0)
|
||||||
s.buttons = append(
|
s.buttons = append(
|
||||||
s.buttons,
|
s.buttons,
|
||||||
|
@ -96,8 +96,8 @@ func (pg *PauseGameState) OnTick(dt int64) GameState {
|
||||||
return pg
|
return pg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pg *PauseGameState) CollectDrawables() []render.Drawable {
|
func (pg *PauseGameState) CollectDrawables() []engine.Drawable {
|
||||||
arr := make([]render.Drawable, 0)
|
arr := make([]engine.Drawable, 0)
|
||||||
|
|
||||||
arr = append(arr, pg.prevState.CollectDrawables()...)
|
arr = append(arr, pg.prevState.CollectDrawables()...)
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,9 @@ package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"mvvasilev/last_light/engine"
|
||||||
"mvvasilev/last_light/game/model"
|
"mvvasilev/last_light/game/model"
|
||||||
"mvvasilev/last_light/game/world"
|
"mvvasilev/last_light/game/world"
|
||||||
"mvvasilev/last_light/render"
|
|
||||||
"mvvasilev/last_light/util"
|
"mvvasilev/last_light/util"
|
||||||
|
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
|
@ -16,7 +16,7 @@ type PlayingState struct {
|
||||||
entityMap *world.EntityMap
|
entityMap *world.EntityMap
|
||||||
level *world.MultilevelMap
|
level *world.MultilevelMap
|
||||||
|
|
||||||
viewport *render.Viewport
|
viewport *engine.Viewport
|
||||||
|
|
||||||
movePlayerDirection model.Direction
|
movePlayerDirection model.Direction
|
||||||
pauseGame bool
|
pauseGame bool
|
||||||
|
@ -51,7 +51,7 @@ func BeginPlayingState() *PlayingState {
|
||||||
|
|
||||||
s.entityMap.AddEntity(s.player, '@', tcell.StyleDefault)
|
s.entityMap.AddEntity(s.player, '@', tcell.StyleDefault)
|
||||||
|
|
||||||
s.viewport = render.CreateViewport(
|
s.viewport = engine.CreateViewport(
|
||||||
util.PositionAt(0, 0),
|
util.PositionAt(0, 0),
|
||||||
dungeonLevel.PlayerSpawnPoint(),
|
dungeonLevel.PlayerSpawnPoint(),
|
||||||
util.SizeOf(80, 24),
|
util.SizeOf(80, 24),
|
||||||
|
@ -207,8 +207,8 @@ func (ps *PlayingState) OnTick(dt int64) GameState {
|
||||||
return ps
|
return ps
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *PlayingState) CollectDrawables() []render.Drawable {
|
func (ps *PlayingState) CollectDrawables() []engine.Drawable {
|
||||||
return render.Multidraw(render.CreateDrawingInstructions(func(v views.View) {
|
return engine.Multidraw(engine.CreateDrawingInstructions(func(v views.View) {
|
||||||
ps.viewport.DrawFromProvider(v, func(x, y int) (rune, tcell.Style) {
|
ps.viewport.DrawFromProvider(v, func(x, y int) (rune, tcell.Style) {
|
||||||
tile := ps.level.TileAt(x, y)
|
tile := ps.level.TileAt(x, y)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mvvasilev/last_light/render"
|
"mvvasilev/last_light/engine"
|
||||||
|
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
)
|
)
|
||||||
|
@ -17,6 +17,6 @@ func (q *QuitState) OnTick(dt int64) GameState {
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *QuitState) CollectDrawables() []render.Drawable {
|
func (q *QuitState) CollectDrawables() []engine.Drawable {
|
||||||
return render.Multidraw(nil)
|
return engine.Multidraw(nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mvvasilev/last_light/render"
|
"mvvasilev/last_light/engine"
|
||||||
"mvvasilev/last_light/util"
|
"mvvasilev/last_light/util"
|
||||||
|
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
|
@ -12,8 +12,8 @@ import (
|
||||||
type UIBorderedButton struct {
|
type UIBorderedButton struct {
|
||||||
id uuid.UUID
|
id uuid.UUID
|
||||||
|
|
||||||
text render.Text
|
text engine.Text
|
||||||
border render.Rectangle
|
border engine.Rectangle
|
||||||
|
|
||||||
isSelected bool
|
isSelected bool
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mvvasilev/last_light/render"
|
"mvvasilev/last_light/engine"
|
||||||
"mvvasilev/last_light/util"
|
"mvvasilev/last_light/util"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
@ -12,14 +12,14 @@ import (
|
||||||
|
|
||||||
type UILabel struct {
|
type UILabel struct {
|
||||||
id uuid.UUID
|
id uuid.UUID
|
||||||
text *render.Text
|
text *engine.Text
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateUILabel(x, y int, width, height int, content string, style tcell.Style) *UILabel {
|
func CreateUILabel(x, y int, width, height int, content string, style tcell.Style) *UILabel {
|
||||||
label := new(UILabel)
|
label := new(UILabel)
|
||||||
|
|
||||||
label.id = uuid.New()
|
label.id = uuid.New()
|
||||||
label.text = render.CreateText(x, y, width, height, content, style)
|
label.text = engine.CreateText(x, y, width, height, content, style)
|
||||||
|
|
||||||
return label
|
return label
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ func CreateSingleLineUILabel(x, y int, content string, style tcell.Style) *UILab
|
||||||
label := new(UILabel)
|
label := new(UILabel)
|
||||||
|
|
||||||
label.id = uuid.New()
|
label.id = uuid.New()
|
||||||
label.text = render.CreateText(x, y, int(utf8.RuneCountInString(content)), 1, content, style)
|
label.text = engine.CreateText(x, y, int(utf8.RuneCountInString(content)), 1, content, style)
|
||||||
|
|
||||||
return label
|
return label
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ func (t *UILabel) UniqueId() uuid.UUID {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *UILabel) MoveTo(x int, y int) {
|
func (t *UILabel) MoveTo(x int, y int) {
|
||||||
t.text = render.CreateText(x, y, int(t.text.Size().Width()), int(t.Size().Height()), t.text.Content(), t.text.Style())
|
t.text = engine.CreateText(x, y, int(t.text.Size().Width()), int(t.Size().Height()), t.text.Content(), t.text.Style())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *UILabel) Position() util.Position {
|
func (t *UILabel) Position() util.Position {
|
175
game/ui/menu/player_inventory_menu.go
Normal file
175
game/ui/menu/player_inventory_menu.go
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
package menu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"mvvasilev/last_light/engine"
|
||||||
|
"mvvasilev/last_light/game/model"
|
||||||
|
"mvvasilev/last_light/game/ui"
|
||||||
|
"mvvasilev/last_light/util"
|
||||||
|
|
||||||
|
"github.com/gdamore/tcell/v2"
|
||||||
|
"github.com/gdamore/tcell/v2/views"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PlayerInventoryMenu struct {
|
||||||
|
inventory *model.EquippedInventory
|
||||||
|
|
||||||
|
inventoryMenu *ui.UIWindow
|
||||||
|
armourLabel *ui.UILabel
|
||||||
|
armourGrid *engine.Grid
|
||||||
|
leftHandLabel *ui.UILabel
|
||||||
|
leftHandBox engine.Rectangle
|
||||||
|
rightHandLabel *ui.UILabel
|
||||||
|
rightHandBox engine.Rectangle
|
||||||
|
inventoryGrid *engine.Grid
|
||||||
|
playerItems *engine.ArbitraryDrawable
|
||||||
|
selectedItem *engine.ArbitraryDrawable
|
||||||
|
help *ui.UILabel
|
||||||
|
|
||||||
|
selectedInventorySlot util.Position
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreatePlayerInventoryMenu(x, y int, playerInventory *model.EquippedInventory, style tcell.Style, highlightStyle tcell.Style) *PlayerInventoryMenu {
|
||||||
|
menu := new(PlayerInventoryMenu)
|
||||||
|
|
||||||
|
menu.inventory = playerInventory
|
||||||
|
|
||||||
|
menu.inventoryMenu = ui.CreateWindow(x, y, 37, 24, "INVENTORY", style)
|
||||||
|
|
||||||
|
menu.armourLabel = ui.CreateSingleLineUILabel(x+15, y+1, "ARMOUR", style)
|
||||||
|
|
||||||
|
menu.armourGrid = engine.CreateGrid(
|
||||||
|
x+10, y+2, 3, 1, 4, 1, '┌', '─', '┬', '┐', '│', ' ', '│', '│', '├', '─', '┼', '┤', '└', '─', '┴', '┘', style, highlightStyle, //style.Background(tcell.ColorDarkSlateGray),
|
||||||
|
)
|
||||||
|
|
||||||
|
menu.leftHandLabel = ui.CreateUILabel(
|
||||||
|
x+3, y+1, 5, 1, "OFF", style,
|
||||||
|
)
|
||||||
|
|
||||||
|
menu.leftHandBox = engine.CreateRectangle(
|
||||||
|
x+2, y+2, 5, 3,
|
||||||
|
'┌', '─', '┐',
|
||||||
|
'│', ' ', '│',
|
||||||
|
'└', '─', '┘',
|
||||||
|
false, true,
|
||||||
|
style,
|
||||||
|
)
|
||||||
|
|
||||||
|
menu.rightHandLabel = ui.CreateUILabel(
|
||||||
|
x+31, y+1, 5, 1, "DOM", style,
|
||||||
|
)
|
||||||
|
|
||||||
|
menu.rightHandBox = engine.CreateRectangle(
|
||||||
|
x+30, y+2, 5, 3,
|
||||||
|
'┌', '─', '┐',
|
||||||
|
'│', ' ', '│',
|
||||||
|
'└', '─', '┘',
|
||||||
|
false, true,
|
||||||
|
style,
|
||||||
|
)
|
||||||
|
|
||||||
|
menu.inventoryGrid = engine.CreateGrid(
|
||||||
|
x+2, y+5, 3, 1, 8, 4, '┌', '─', '┬', '┐', '│', ' ', '│', '│', '├', '─', '┼', '┤', '└', '─', '┴', '┘', style, highlightStyle,
|
||||||
|
)
|
||||||
|
|
||||||
|
menu.playerItems = engine.CreateDrawingInstructions(func(v views.View) {
|
||||||
|
for y := range playerInventory.Shape().Height() {
|
||||||
|
for x := range playerInventory.Shape().Width() {
|
||||||
|
item := playerInventory.ItemAt(x, y)
|
||||||
|
isHighlighted := x == menu.selectedInventorySlot.X() && y == menu.selectedInventorySlot.Y()
|
||||||
|
|
||||||
|
if item == nil {
|
||||||
|
|
||||||
|
if isHighlighted {
|
||||||
|
ui.CreateSingleLineUILabel(
|
||||||
|
menu.inventoryGrid.Position().X()+1+x*4,
|
||||||
|
menu.inventoryGrid.Position().Y()+1+y*2,
|
||||||
|
" ",
|
||||||
|
highlightStyle,
|
||||||
|
).Draw(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
style := item.Type().Style()
|
||||||
|
|
||||||
|
if isHighlighted {
|
||||||
|
style = highlightStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.CreateSingleLineUILabel(
|
||||||
|
menu.inventoryGrid.Position().X()+1+x*4,
|
||||||
|
menu.inventoryGrid.Position().Y()+y*2,
|
||||||
|
fmt.Sprintf("%03d", item.Quantity()),
|
||||||
|
style,
|
||||||
|
).Draw(v)
|
||||||
|
|
||||||
|
ui.CreateSingleLineUILabel(
|
||||||
|
menu.inventoryGrid.Position().X()+1+x*4,
|
||||||
|
menu.inventoryGrid.Position().Y()+1+y*2,
|
||||||
|
item.Type().Icon(),
|
||||||
|
style,
|
||||||
|
).Draw(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
menu.selectedItem = engine.CreateDrawingInstructions(func(v views.View) {
|
||||||
|
ui.CreateWindow(x+2, y+14, 33, 8, "ITEM", style).Draw(v)
|
||||||
|
|
||||||
|
item := playerInventory.ItemAt(menu.selectedInventorySlot.XY())
|
||||||
|
|
||||||
|
if item == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.CreateSingleLineUILabel(x+3, y+15, fmt.Sprintf("Name: %v", item.Name()), style).Draw(v)
|
||||||
|
ui.CreateSingleLineUILabel(x+3, y+16, fmt.Sprintf("Desc: %v", item.Description()), style).Draw(v)
|
||||||
|
})
|
||||||
|
|
||||||
|
menu.help = ui.CreateSingleLineUILabel(x+2, y+22, "hjkl - move, x - drop, e - equip", style)
|
||||||
|
|
||||||
|
return menu
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pim *PlayerInventoryMenu) MoveTo(x int, y int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pim *PlayerInventoryMenu) Position() util.Position {
|
||||||
|
return pim.inventoryMenu.Position()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pim *PlayerInventoryMenu) Size() util.Size {
|
||||||
|
return pim.inventoryMenu.Size()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pim *PlayerInventoryMenu) Input(e *tcell.EventKey) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pim *PlayerInventoryMenu) UniqueId() uuid.UUID {
|
||||||
|
return pim.inventoryMenu.UniqueId()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pim *PlayerInventoryMenu) SelectSlot(x, y int) {
|
||||||
|
pim.inventoryGrid.Unhighlight()
|
||||||
|
pim.selectedInventorySlot = util.PositionAt(x, y)
|
||||||
|
pim.inventoryGrid.Highlight(pim.selectedInventorySlot)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pim *PlayerInventoryMenu) Draw(v views.View) {
|
||||||
|
pim.inventoryMenu.Draw(v)
|
||||||
|
pim.armourLabel.Draw(v)
|
||||||
|
pim.armourGrid.Draw(v)
|
||||||
|
pim.leftHandLabel.Draw(v)
|
||||||
|
pim.leftHandBox.Draw(v)
|
||||||
|
pim.rightHandLabel.Draw(v)
|
||||||
|
pim.rightHandBox.Draw(v)
|
||||||
|
pim.inventoryGrid.Draw(v)
|
||||||
|
pim.playerItems.Draw(v)
|
||||||
|
pim.selectedItem.Draw(v)
|
||||||
|
pim.help.Draw(v)
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mvvasilev/last_light/render"
|
"mvvasilev/last_light/engine"
|
||||||
"mvvasilev/last_light/util"
|
"mvvasilev/last_light/util"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
@ -14,7 +14,7 @@ import (
|
||||||
type UISimpleButton struct {
|
type UISimpleButton struct {
|
||||||
id uuid.UUID
|
id uuid.UUID
|
||||||
isHighlighted bool
|
isHighlighted bool
|
||||||
text *render.Text
|
text *engine.Text
|
||||||
selectHandler func()
|
selectHandler func()
|
||||||
unhighlightedStyle tcell.Style
|
unhighlightedStyle tcell.Style
|
||||||
highlightedStyle tcell.Style
|
highlightedStyle tcell.Style
|
||||||
|
@ -24,7 +24,7 @@ func CreateSimpleButton(x, y int, text string, unhighlightedStyle, highlightedSt
|
||||||
sb := new(UISimpleButton)
|
sb := new(UISimpleButton)
|
||||||
|
|
||||||
sb.id = uuid.New()
|
sb.id = uuid.New()
|
||||||
sb.text = render.CreateText(x, y, int(utf8.RuneCountInString(text)), 1, text, unhighlightedStyle)
|
sb.text = engine.CreateText(x, y, int(utf8.RuneCountInString(text)), 1, text, unhighlightedStyle)
|
||||||
sb.isHighlighted = false
|
sb.isHighlighted = false
|
||||||
sb.selectHandler = onSelect
|
sb.selectHandler = onSelect
|
||||||
sb.highlightedStyle = highlightedStyle
|
sb.highlightedStyle = highlightedStyle
|
||||||
|
@ -50,7 +50,7 @@ func (sb *UISimpleButton) Highlight() {
|
||||||
|
|
||||||
newContent := "[ " + sb.text.Content() + " ]"
|
newContent := "[ " + sb.text.Content() + " ]"
|
||||||
|
|
||||||
sb.text = render.CreateText(
|
sb.text = engine.CreateText(
|
||||||
int(sb.Position().X()-2), int(sb.Position().Y()),
|
int(sb.Position().X()-2), int(sb.Position().Y()),
|
||||||
int(utf8.RuneCountInString(newContent)), 1,
|
int(utf8.RuneCountInString(newContent)), 1,
|
||||||
newContent,
|
newContent,
|
||||||
|
@ -65,7 +65,7 @@ func (sb *UISimpleButton) Unhighlight() {
|
||||||
content = strings.Trim(content, "[ ")
|
content = strings.Trim(content, "[ ")
|
||||||
contentLen := utf8.RuneCountInString(content)
|
contentLen := utf8.RuneCountInString(content)
|
||||||
|
|
||||||
sb.text = render.CreateText(
|
sb.text = engine.CreateText(
|
||||||
int(sb.Position().X()+2), int(sb.Position().Y()),
|
int(sb.Position().X()+2), int(sb.Position().Y()),
|
||||||
int(contentLen), 1,
|
int(contentLen), 1,
|
||||||
content,
|
content,
|
||||||
|
@ -82,7 +82,7 @@ func (sb *UISimpleButton) UniqueId() uuid.UUID {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sb *UISimpleButton) MoveTo(x int, y int) {
|
func (sb *UISimpleButton) MoveTo(x int, y int) {
|
||||||
sb.text = render.CreateText(x, y, int(utf8.RuneCountInString(sb.text.Content())), 1, sb.text.Content(), sb.highlightedStyle)
|
sb.text = engine.CreateText(x, y, int(utf8.RuneCountInString(sb.text.Content())), 1, sb.text.Content(), sb.highlightedStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sb *UISimpleButton) Position() util.Position {
|
func (sb *UISimpleButton) Position() util.Position {
|
|
@ -1,7 +1,7 @@
|
||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mvvasilev/last_light/render"
|
"mvvasilev/last_light/engine"
|
||||||
"mvvasilev/last_light/util"
|
"mvvasilev/last_light/util"
|
||||||
|
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
|
@ -13,7 +13,7 @@ type UIElement interface {
|
||||||
Size() util.Size
|
Size() util.Size
|
||||||
Input(e *tcell.EventKey)
|
Input(e *tcell.EventKey)
|
||||||
|
|
||||||
render.Drawable
|
engine.Drawable
|
||||||
}
|
}
|
||||||
|
|
||||||
type UIHighlightableElement interface {
|
type UIHighlightableElement interface {
|
|
@ -1,7 +1,7 @@
|
||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mvvasilev/last_light/render"
|
"mvvasilev/last_light/engine"
|
||||||
"mvvasilev/last_light/util"
|
"mvvasilev/last_light/util"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ import (
|
||||||
type UIWindow struct {
|
type UIWindow struct {
|
||||||
id uuid.UUID
|
id uuid.UUID
|
||||||
|
|
||||||
title *render.Text
|
title *engine.Text
|
||||||
box render.Rectangle
|
box engine.Rectangle
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateWindow(x, y, width, height int, title string, style tcell.Style) *UIWindow {
|
func CreateWindow(x, y, width, height int, title string, style tcell.Style) *UIWindow {
|
||||||
|
@ -24,9 +24,9 @@ func CreateWindow(x, y, width, height int, title string, style tcell.Style) *UIW
|
||||||
|
|
||||||
titlePos := (width / 2) - int(titleLen/2)
|
titlePos := (width / 2) - int(titleLen/2)
|
||||||
|
|
||||||
w.title = render.CreateText(x+titlePos, y, int(titleLen), 1, title, style)
|
w.title = engine.CreateText(x+titlePos, y, int(titleLen), 1, title, style)
|
||||||
|
|
||||||
w.box = render.CreateRectangle(
|
w.box = engine.CreateRectangle(
|
||||||
x, y, width, height,
|
x, y, width, height,
|
||||||
'┌', '─', '┐',
|
'┌', '─', '┐',
|
||||||
'│', ' ', '│',
|
'│', ' ', '│',
|
|
@ -1,15 +1,11 @@
|
||||||
package world
|
package world
|
||||||
|
|
||||||
import "mvvasilev/last_light/game/model"
|
|
||||||
|
|
||||||
type dungeonLevel struct {
|
type dungeonLevel struct {
|
||||||
groundLevel Map
|
groundLevel *Map
|
||||||
entityLevel *EntityMap
|
entityLevel *EntityMap
|
||||||
itemLevel *Map
|
itemLevel *Map
|
||||||
}
|
}
|
||||||
|
|
||||||
type Dungeon struct {
|
type Dungeon struct {
|
||||||
player *model.Player
|
|
||||||
|
|
||||||
levels []*dungeonLevel
|
levels []*dungeonLevel
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue