Move some things around

This commit is contained in:
Miroslav Vasilev 2024-05-06 21:19:08 +03:00
parent 5d1416bb07
commit a56e3d3c91
31 changed files with 209 additions and 219 deletions

6
engine/bounding_box.go Normal file
View file

@ -0,0 +1,6 @@
package engine
type BoundingBox struct {
Positioned
Sized
}

View file

@ -1,8 +1,6 @@
package engine
import (
"mvvasilev/last_light/util"
"github.com/gdamore/tcell/v2"
"github.com/gdamore/tcell/v2/views"
"github.com/google/uuid"
@ -11,10 +9,10 @@ import (
type Grid struct {
id uuid.UUID
internalCellSize util.Size
internalCellSize Size
numCellsHorizontal int
numCellsVertical int
position util.Position
position Position
style tcell.Style
highlightStyle tcell.Style
@ -38,7 +36,7 @@ type Grid struct {
crossJunction rune
isHighlighted bool
highlightedGrid util.Position
highlightedGrid Position
fillRune rune
}
@ -79,11 +77,11 @@ func CreateGrid(
) *Grid {
return &Grid{
id: uuid.New(),
internalCellSize: util.SizeOf(cellWidth, cellHeight),
internalCellSize: SizeOf(cellWidth, cellHeight),
numCellsHorizontal: numCellsHorizontal,
numCellsVertical: numCellsVertical,
isHighlighted: false,
position: util.PositionAt(x, y),
position: PositionAt(x, y),
style: style,
highlightStyle: highlightStyle,
northBorder: northBorder,
@ -110,7 +108,7 @@ func (g *Grid) UniqueId() uuid.UUID {
return g.id
}
func (g *Grid) Highlight(highlightedGrid util.Position) {
func (g *Grid) Highlight(highlightedGrid Position) {
g.isHighlighted = true
g.highlightedGrid = highlightedGrid
}
@ -119,7 +117,7 @@ func (g *Grid) Unhighlight() {
g.isHighlighted = false
}
func (g *Grid) Position() util.Position {
func (g *Grid) Position() Position {
return g.position
}

View file

@ -1,8 +1,6 @@
package engine
import (
"mvvasilev/last_light/util"
"github.com/gdamore/tcell/v2"
"github.com/gdamore/tcell/v2/views"
"github.com/google/uuid"
@ -11,14 +9,14 @@ import (
type Raw struct {
id uuid.UUID
buffer [][]rune
position util.Position
position Position
style tcell.Style
}
func CreateRawDrawable(x, y int, style tcell.Style, buffer ...string) *Raw {
r := new(Raw)
r.position = util.PositionAt(x, y)
r.position = PositionAt(x, y)
r.buffer = make([][]rune, 0)
for _, row := range buffer {
@ -33,7 +31,7 @@ func CreateRawDrawable(x, y int, style tcell.Style, buffer ...string) *Raw {
func CreateRawDrawableFromBuffer(x, y int, style tcell.Style, buffer [][]rune) *Raw {
r := new(Raw)
r.position = util.PositionAt(x, y)
r.position = PositionAt(x, y)
r.buffer = buffer
return r

View file

@ -1,8 +1,6 @@
package engine
import (
"mvvasilev/last_light/util"
"github.com/gdamore/tcell/v2"
"github.com/gdamore/tcell/v2/views"
"github.com/google/uuid"
@ -11,8 +9,8 @@ import (
type Rectangle struct {
id uuid.UUID
size util.Size
position util.Position
size Size
position Position
style tcell.Style
northBorder rune
@ -103,8 +101,8 @@ func CreateRectangle(
) Rectangle {
return Rectangle{
id: uuid.New(),
size: util.SizeOf(width, height),
position: util.PositionAt(x, y),
size: SizeOf(width, height),
position: PositionAt(x, y),
style: style,
northBorder: northBorder,
eastBorder: eastBorder,
@ -124,7 +122,7 @@ func (rect Rectangle) UniqueId() uuid.UUID {
return rect.id
}
func (rect Rectangle) Position() util.Position {
func (rect Rectangle) Position() Position {
return rect.position
}

View file

@ -1,7 +1,6 @@
package engine
import (
"mvvasilev/last_light/util"
"strings"
"unicode/utf8"
@ -13,8 +12,8 @@ import (
type Text struct {
id uuid.UUID
content []string
position util.Position
size util.Size
position Position
size Size
style tcell.Style
}
@ -29,8 +28,8 @@ func CreateText(
text.id = uuid.New()
text.content = strings.Split(content, " ")
text.style = style
text.size = util.SizeOf(width, height)
text.position = util.PositionAt(x, y)
text.size = SizeOf(width, height)
text.position = PositionAt(x, y)
return text
}
@ -39,7 +38,7 @@ func (t *Text) UniqueId() uuid.UUID {
return t.id
}
func (t *Text) Position() util.Position {
func (t *Text) Position() Position {
return t.position
}
@ -47,7 +46,7 @@ func (t *Text) Content() string {
return strings.Join(t.content, " ")
}
func (t *Text) Size() util.Size {
func (t *Text) Size() Size {
return t.size
}

View file

@ -1,4 +1,4 @@
package util
package engine
import "math/rand"
@ -110,8 +110,3 @@ func LimitDecrement(i int, limit int) int {
func RandInt(min, max int) int {
return min + rand.Intn(max-min)
}
type Room struct {
Positioned
Sized
}

View file

@ -1,8 +1,6 @@
package engine
import (
"mvvasilev/last_light/util"
"github.com/gdamore/tcell/v2"
"github.com/gdamore/tcell/v2/views"
"github.com/google/uuid"
@ -10,15 +8,15 @@ import (
type Viewport struct {
id uuid.UUID
screenLocation util.Position
screenLocation Position
viewportCenter util.Position
viewportSize util.Size
viewportCenter Position
viewportSize Size
style tcell.Style
}
func CreateViewport(screenLoc, viewportCenter util.Position, size util.Size, style tcell.Style) *Viewport {
func CreateViewport(screenLoc, viewportCenter Position, size Size, style tcell.Style) *Viewport {
v := new(Viewport)
v.id = uuid.New()
@ -34,19 +32,19 @@ func (vp *Viewport) UniqueId() uuid.UUID {
return vp.id
}
func (vp *Viewport) Center() util.Position {
func (vp *Viewport) Center() Position {
return vp.viewportCenter
}
func (vp *Viewport) SetCenter(pos util.Position) {
func (vp *Viewport) SetCenter(pos Position) {
vp.viewportCenter = pos
}
func (vp *Viewport) Size() util.Size {
func (vp *Viewport) Size() Size {
return vp.viewportSize
}
func (vp *Viewport) ScreenLocation() util.Position {
func (vp *Viewport) ScreenLocation() Position {
return vp.screenLocation
}

View file

@ -1,7 +1,7 @@
package model
import (
"mvvasilev/last_light/util"
"mvvasilev/last_light/engine"
"github.com/gdamore/tcell/v2"
"github.com/google/uuid"
@ -39,8 +39,8 @@ type Entity interface {
}
type MovableEntity interface {
Position() util.Position
MoveTo(newPosition util.Position)
Position() engine.Position
MoveTo(newPosition engine.Position)
Entity
}

View file

@ -1,10 +1,10 @@
package model
import "mvvasilev/last_light/util"
import "mvvasilev/last_light/engine"
type Inventory interface {
Items() []*Item
Shape() util.Size
Shape() engine.Size
Push(item Item) bool
Drop(x, y int) *Item
ItemAt(x, y int) *Item
@ -12,10 +12,10 @@ type Inventory interface {
type BasicInventory struct {
contents []*Item
shape util.Size
shape engine.Size
}
func CreateInventory(shape util.Size) *BasicInventory {
func CreateInventory(shape engine.Size) *BasicInventory {
inv := new(BasicInventory)
inv.contents = make([]*Item, 0, shape.Height()*shape.Width())
@ -28,7 +28,7 @@ func (i *BasicInventory) Items() (items []*Item) {
return i.contents
}
func (i *BasicInventory) Shape() util.Size {
func (i *BasicInventory) Shape() engine.Size {
return i.shape
}

View file

@ -1,8 +1,6 @@
package model
import (
"math/rand"
"github.com/gdamore/tcell/v2"
)
@ -105,15 +103,3 @@ func ItemTypeKey() *ItemType {
maxStack: 1,
}
}
func GenerateItemType(genTable map[float32]*ItemType) *ItemType {
num := rand.Float32()
for k, v := range genTable {
if num > k {
return v
}
}
return nil
}

View file

@ -1,7 +1,7 @@
package model
import (
"mvvasilev/last_light/util"
"mvvasilev/last_light/engine"
"github.com/gdamore/tcell/v2"
"github.com/google/uuid"
@ -9,7 +9,7 @@ import (
type Player struct {
id uuid.UUID
position util.Position
position engine.Position
inventory *EquippedInventory
}
@ -18,7 +18,7 @@ func CreatePlayer(x, y int) *Player {
p := new(Player)
p.id = uuid.New()
p.position = util.PositionAt(x, y)
p.position = engine.PositionAt(x, y)
p.inventory = CreatePlayerInventory()
return p
@ -28,11 +28,11 @@ func (p *Player) UniqueId() uuid.UUID {
return p.id
}
func (p *Player) Position() util.Position {
func (p *Player) Position() engine.Position {
return p.position
}
func (p *Player) MoveTo(newPos util.Position) {
func (p *Player) MoveTo(newPos engine.Position) {
p.position = newPos
}

View file

@ -1,6 +1,6 @@
package model
import "mvvasilev/last_light/util"
import "mvvasilev/last_light/engine"
type EquippedSlot int
@ -27,7 +27,7 @@ type EquippedInventory struct {
func CreatePlayerInventory() *EquippedInventory {
return &EquippedInventory{
BasicInventory: CreateInventory(util.SizeOf(8, 4)),
BasicInventory: CreateInventory(engine.SizeOf(8, 4)),
}
}

View file

@ -2,9 +2,9 @@ package state
import (
"mvvasilev/last_light/engine"
engine1 "mvvasilev/last_light/engine"
"mvvasilev/last_light/game/model"
"mvvasilev/last_light/game/ui/menu"
"mvvasilev/last_light/util"
"github.com/gdamore/tcell/v2"
)
@ -14,7 +14,7 @@ type InventoryScreenState struct {
exitMenu bool
inventoryMenu *menu.PlayerInventoryMenu
selectedInventorySlot util.Position
selectedInventorySlot engine1.Position
player *model.Player
@ -27,7 +27,7 @@ func CreateInventoryScreenState(player *model.Player, prevState PausableState) *
iss.prevState = prevState
iss.player = player
iss.selectedInventorySlot = util.PositionAt(0, 0)
iss.selectedInventorySlot = engine1.PositionAt(0, 0)
iss.exitMenu = false
iss.inventoryMenu = menu.CreatePlayerInventoryMenu(43, 0, player.Inventory(), tcell.StyleDefault, tcell.StyleDefault.Background(tcell.ColorDarkSlateGray))

View file

@ -2,8 +2,8 @@ package state
import (
"mvvasilev/last_light/engine"
engine1 "mvvasilev/last_light/engine"
"mvvasilev/last_light/game/ui"
"mvvasilev/last_light/util"
"github.com/gdamore/tcell/v2"
)
@ -50,13 +50,13 @@ func NewMainMenuState() *MainMenuState {
func (mms *MainMenuState) OnInput(e *tcell.EventKey) {
if e.Key() == tcell.KeyDown {
mms.buttons[mms.currButtonSelected].Unhighlight()
mms.currButtonSelected = util.LimitIncrement(mms.currButtonSelected, 2)
mms.currButtonSelected = engine1.LimitIncrement(mms.currButtonSelected, 2)
mms.buttons[mms.currButtonSelected].Highlight()
}
if e.Key() == tcell.KeyUp {
mms.buttons[mms.currButtonSelected].Unhighlight()
mms.currButtonSelected = util.LimitDecrement(mms.currButtonSelected, 0)
mms.currButtonSelected = engine1.LimitDecrement(mms.currButtonSelected, 0)
mms.buttons[mms.currButtonSelected].Highlight()
}

View file

@ -2,8 +2,8 @@ package state
import (
"mvvasilev/last_light/engine"
engine1 "mvvasilev/last_light/engine"
"mvvasilev/last_light/game/ui"
"mvvasilev/last_light/util"
"github.com/gdamore/tcell/v2"
)
@ -68,13 +68,13 @@ func (pg *PauseGameState) OnInput(e *tcell.EventKey) {
if e.Key() == tcell.KeyDown {
pg.buttons[pg.currButtonSelected].Unhighlight()
pg.currButtonSelected = util.LimitIncrement(pg.currButtonSelected, 1)
pg.currButtonSelected = engine1.LimitIncrement(pg.currButtonSelected, 1)
pg.buttons[pg.currButtonSelected].Highlight()
}
if e.Key() == tcell.KeyUp {
pg.buttons[pg.currButtonSelected].Unhighlight()
pg.currButtonSelected = util.LimitDecrement(pg.currButtonSelected, 0)
pg.currButtonSelected = engine1.LimitDecrement(pg.currButtonSelected, 0)
pg.buttons[pg.currButtonSelected].Highlight()
}

View file

@ -1,11 +1,10 @@
package state
import (
"math/rand"
"mvvasilev/last_light/engine"
engine1 "mvvasilev/last_light/engine"
"mvvasilev/last_light/game/model"
"mvvasilev/last_light/game/world"
"mvvasilev/last_light/util"
"github.com/gdamore/tcell/v2"
"github.com/gdamore/tcell/v2/views"
@ -27,11 +26,18 @@ type PlayingState struct {
func BeginPlayingState() *PlayingState {
s := new(PlayingState)
mapSize := util.SizeOf(128, 128)
mapSize := engine1.SizeOf(128, 128)
dungeonLevel := world.CreateBSPDungeonMap(mapSize.Width(), mapSize.Height(), 4)
itemTiles := spawnItems(dungeonLevel)
genTable := make(map[float32]*model.ItemType, 0)
genTable[0.2] = model.ItemTypeFish()
genTable[0.05] = model.ItemTypeBow()
genTable[0.051] = model.ItemTypeLongsword()
genTable[0.052] = model.ItemTypeKey()
itemTiles := world.SpawnItems(dungeonLevel.Rooms(), 0.025, genTable)
itemLevel := world.CreateEmptyDungeonLevel(mapSize.Width(), mapSize.Height())
@ -52,57 +58,15 @@ func BeginPlayingState() *PlayingState {
s.entityMap.AddEntity(s.player, '@', tcell.StyleDefault)
s.viewport = engine.CreateViewport(
util.PositionAt(0, 0),
engine1.PositionAt(0, 0),
dungeonLevel.PlayerSpawnPoint(),
util.SizeOf(80, 24),
engine1.SizeOf(80, 24),
tcell.StyleDefault,
)
return s
}
func spawnItems(level *world.BSPDungeonMap) []world.Tile {
rooms := level.Rooms()
genTable := make(map[float32]*model.ItemType)
genTable[0.2] = model.ItemTypeFish()
genTable[0.05] = model.ItemTypeBow()
genTable[0.051] = model.ItemTypeLongsword()
genTable[0.052] = model.ItemTypeKey()
itemTiles := make([]world.Tile, 0, 10)
for _, r := range rooms {
maxItems := int(0.10 * float64(r.Size().Area()))
if maxItems < 1 {
continue
}
numItems := rand.Intn(maxItems)
for range numItems {
itemType := model.GenerateItemType(genTable)
if itemType == nil {
continue
}
pos := util.PositionAt(
util.RandInt(r.Position().X()+1, r.Position().X()+r.Size().Width()-1),
util.RandInt(r.Position().Y()+1, r.Position().Y()+r.Size().Height()-1),
)
itemTiles = append(itemTiles, world.CreateItemTile(
pos, itemType, 1,
))
}
}
return itemTiles
}
func (ps *PlayingState) Pause() {
ps.pauseGame = true
}

View file

@ -2,7 +2,7 @@ package ui
import (
"mvvasilev/last_light/engine"
"mvvasilev/last_light/util"
engine1 "mvvasilev/last_light/engine"
"github.com/gdamore/tcell/v2"
"github.com/gdamore/tcell/v2/views"
@ -45,11 +45,11 @@ func (b *UIBorderedButton) MoveTo(x int, y int) {
panic("not implemented") // TODO: Implement
}
func (b *UIBorderedButton) Position() util.Position {
func (b *UIBorderedButton) Position() engine1.Position {
panic("not implemented") // TODO: Implement
}
func (b *UIBorderedButton) Size() util.Size {
func (b *UIBorderedButton) Size() engine1.Size {
panic("not implemented") // TODO: Implement
}

View file

@ -1,7 +1,7 @@
package ui
import (
"mvvasilev/last_light/util"
"mvvasilev/last_light/engine"
"github.com/gdamore/tcell/v2"
"github.com/gdamore/tcell/v2/views"
@ -28,8 +28,8 @@ const (
type UIContainer struct {
id uuid.UUID
layout UIContainerLayout
position util.Position
size util.Size
position engine.Position
size engine.Size
elements []UIElement
}
@ -38,8 +38,8 @@ func CreateUIContainer(x, y int, width, height int, layout UIContainerLayout) *U
container.id = uuid.New()
container.layout = layout
container.position = util.PositionAt(x, y)
container.size = util.SizeOf(width, height)
container.position = engine.PositionAt(x, y)
container.size = engine.SizeOf(width, height)
container.elements = make([]UIElement, 0)
return container
@ -58,14 +58,14 @@ func (uic *UIContainer) UniqueId() uuid.UUID {
}
func (uic *UIContainer) MoveTo(x, y int) {
uic.position = util.PositionAt(x, y)
uic.position = engine.PositionAt(x, y)
}
func (uic *UIContainer) Position() util.Position {
func (uic *UIContainer) Position() engine.Position {
return uic.position
}
func (uic *UIContainer) Size() util.Size {
func (uic *UIContainer) Size() engine.Size {
return uic.size
}

View file

@ -2,7 +2,7 @@ package ui
import (
"mvvasilev/last_light/engine"
"mvvasilev/last_light/util"
engine1 "mvvasilev/last_light/engine"
"unicode/utf8"
"github.com/gdamore/tcell/v2"
@ -41,11 +41,11 @@ func (t *UILabel) MoveTo(x int, y int) {
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() engine1.Position {
return t.text.Position()
}
func (t *UILabel) Size() util.Size {
func (t *UILabel) Size() engine1.Size {
return t.text.Size()
}

View file

@ -3,9 +3,9 @@ package menu
import (
"fmt"
"mvvasilev/last_light/engine"
engine1 "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"
@ -27,7 +27,7 @@ type PlayerInventoryMenu struct {
selectedItem *engine.ArbitraryDrawable
help *ui.UILabel
selectedInventorySlot util.Position
selectedInventorySlot engine1.Position
}
func CreatePlayerInventoryMenu(x, y int, playerInventory *model.EquippedInventory, style tcell.Style, highlightStyle tcell.Style) *PlayerInventoryMenu {
@ -138,11 +138,11 @@ func (pim *PlayerInventoryMenu) MoveTo(x int, y int) {
}
func (pim *PlayerInventoryMenu) Position() util.Position {
func (pim *PlayerInventoryMenu) Position() engine1.Position {
return pim.inventoryMenu.Position()
}
func (pim *PlayerInventoryMenu) Size() util.Size {
func (pim *PlayerInventoryMenu) Size() engine1.Size {
return pim.inventoryMenu.Size()
}
@ -156,7 +156,7 @@ func (pim *PlayerInventoryMenu) UniqueId() uuid.UUID {
func (pim *PlayerInventoryMenu) SelectSlot(x, y int) {
pim.inventoryGrid.Unhighlight()
pim.selectedInventorySlot = util.PositionAt(x, y)
pim.selectedInventorySlot = engine1.PositionAt(x, y)
pim.inventoryGrid.Highlight(pim.selectedInventorySlot)
}

View file

@ -2,7 +2,7 @@ package ui
import (
"mvvasilev/last_light/engine"
"mvvasilev/last_light/util"
engine1 "mvvasilev/last_light/engine"
"strings"
"unicode/utf8"
@ -85,11 +85,11 @@ func (sb *UISimpleButton) MoveTo(x int, y int) {
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() engine1.Position {
return sb.text.Position()
}
func (sb *UISimpleButton) Size() util.Size {
func (sb *UISimpleButton) Size() engine1.Size {
return sb.text.Size()
}

View file

@ -2,15 +2,15 @@ package ui
import (
"mvvasilev/last_light/engine"
"mvvasilev/last_light/util"
engine1 "mvvasilev/last_light/engine"
"github.com/gdamore/tcell/v2"
)
type UIElement interface {
MoveTo(x, y int)
Position() util.Position
Size() util.Size
Position() engine1.Position
Size() engine1.Size
Input(e *tcell.EventKey)
engine.Drawable

View file

@ -2,7 +2,7 @@ package ui
import (
"mvvasilev/last_light/engine"
"mvvasilev/last_light/util"
engine1 "mvvasilev/last_light/engine"
"unicode/utf8"
"github.com/gdamore/tcell/v2"
@ -45,12 +45,12 @@ func (w *UIWindow) MoveTo(x int, y int) {
}
func (w *UIWindow) Position() util.Position {
func (w *UIWindow) Position() engine1.Position {
return w.box.Position()
}
func (w *UIWindow) Size() util.Size {
return util.SizeOf(0, 0)
func (w *UIWindow) Size() engine1.Size {
return engine1.SizeOf(0, 0)
}
func (w *UIWindow) Draw(v views.View) {

View file

@ -1,21 +1,21 @@
package world
import (
"mvvasilev/last_light/util"
"mvvasilev/last_light/engine"
)
type BSPDungeonMap struct {
level *BasicMap
playerSpawnPoint util.Position
rooms []util.Room
playerSpawnPoint engine.Position
rooms []engine.BoundingBox
}
func (bsp *BSPDungeonMap) PlayerSpawnPoint() util.Position {
func (bsp *BSPDungeonMap) PlayerSpawnPoint() engine.Position {
return bsp.playerSpawnPoint
}
func (bsp *BSPDungeonMap) Size() util.Size {
func (bsp *BSPDungeonMap) Size() engine.Size {
return bsp.level.Size()
}
@ -30,6 +30,6 @@ func (bsp *BSPDungeonMap) TileAt(x int, y int) Tile {
func (bsp *BSPDungeonMap) Tick(dt int64) {
}
func (bsp *BSPDungeonMap) Rooms() []util.Room {
func (bsp *BSPDungeonMap) Rooms() []engine.BoundingBox {
return bsp.rooms
}

View file

@ -1,12 +1,12 @@
package world
import "mvvasilev/last_light/util"
import "mvvasilev/last_light/engine"
type EmptyDungeonMap struct {
level *BasicMap
}
func (edl *EmptyDungeonMap) Size() util.Size {
func (edl *EmptyDungeonMap) Size() engine.Size {
return edl.level.Size()
}

View file

@ -2,8 +2,8 @@ package world
import (
"maps"
"mvvasilev/last_light/engine"
"mvvasilev/last_light/game/model"
"mvvasilev/last_light/util"
"github.com/gdamore/tcell/v2"
"github.com/google/uuid"
@ -12,13 +12,13 @@ import (
type EntityMap struct {
entities map[int]EntityTile
util.Sized
engine.Sized
}
func CreateEntityMap(width, height int) *EntityMap {
return &EntityMap{
entities: make(map[int]EntityTile, 0),
Sized: util.WithSize(util.SizeOf(width, height)),
Sized: engine.WithSize(engine.SizeOf(width, height)),
}
}
@ -55,11 +55,7 @@ func (em *EntityMap) AddEntity(entity model.MovableEntity, presentation rune, st
func (em *EntityMap) DropEntity(uuid uuid.UUID) {
maps.DeleteFunc(em.entities, func(i int, et EntityTile) bool {
if et.Entity().UniqueId() == uuid {
return true
}
return false
return et.Entity().UniqueId() == uuid
})
}

View file

@ -2,7 +2,7 @@ package world
import (
"math/rand"
"mvvasilev/last_light/util"
"mvvasilev/last_light/engine"
)
type splitDirection bool
@ -13,10 +13,10 @@ const (
)
type bspNode struct {
origin util.Position
size util.Size
origin engine.Position
size engine.Size
room util.Room
room engine.BoundingBox
hasRoom bool
left *bspNode
@ -28,8 +28,8 @@ type bspNode struct {
func CreateBSPDungeonMap(width, height int, numSplits int) *BSPDungeonMap {
root := new(bspNode)
root.origin = util.PositionAt(0, 0)
root.size = util.SizeOf(width, height)
root.origin = engine.PositionAt(0, 0)
root.size = engine.SizeOf(width, height)
split(root, numSplits)
@ -39,13 +39,13 @@ func CreateBSPDungeonMap(width, height int, numSplits int) *BSPDungeonMap {
tiles[h] = make([]Tile, width)
}
rooms := make([]util.Room, 0, 2^numSplits)
rooms := make([]engine.BoundingBox, 0, 2^numSplits)
iterateBspLeaves(root, func(leaf *bspNode) {
x := util.RandInt(leaf.origin.X(), leaf.origin.X()+leaf.size.Width()/4)
y := util.RandInt(leaf.origin.Y(), leaf.origin.Y()+leaf.size.Height()/4)
w := util.RandInt(3, leaf.size.Width()-1)
h := util.RandInt(3, leaf.size.Height()-1)
x := engine.RandInt(leaf.origin.X(), leaf.origin.X()+leaf.size.Width()/4)
y := engine.RandInt(leaf.origin.Y(), leaf.origin.Y()+leaf.size.Height()/4)
w := engine.RandInt(3, leaf.size.Width()-1)
h := engine.RandInt(3, leaf.size.Height()-1)
if x+w >= width {
w = w - (x + w - width) - 1
@ -55,9 +55,9 @@ func CreateBSPDungeonMap(width, height int, numSplits int) *BSPDungeonMap {
h = h - (y + h - height) - 1
}
room := util.Room{
Positioned: util.WithPosition(util.PositionAt(x, y)),
Sized: util.WithSize(util.SizeOf(w, h)),
room := engine.BoundingBox{
Positioned: engine.WithPosition(engine.PositionAt(x, y)),
Sized: engine.WithSize(engine.SizeOf(w, h)),
}
rooms = append(rooms, room)
@ -74,11 +74,11 @@ func CreateBSPDungeonMap(width, height int, numSplits int) *BSPDungeonMap {
zCorridor(
tiles,
util.PositionAt(
engine.PositionAt(
roomLeft.Position().X()+roomLeft.Size().Width()/2,
roomLeft.Position().Y()+roomLeft.Size().Height()/2,
),
util.PositionAt(
engine.PositionAt(
roomRight.Position().X()+roomRight.Size().Width()/2,
roomRight.Position().Y()+roomRight.Size().Height()/2,
),
@ -92,7 +92,7 @@ func CreateBSPDungeonMap(width, height int, numSplits int) *BSPDungeonMap {
bsp.rooms = rooms
bsp.level = CreateBasicMap(tiles)
bsp.playerSpawnPoint = util.PositionAt(
bsp.playerSpawnPoint = engine.PositionAt(
spawnRoom.Position().X()+spawnRoom.Size().Width()/2,
spawnRoom.Position().Y()+spawnRoom.Size().Height()/2,
)
@ -100,7 +100,7 @@ func CreateBSPDungeonMap(width, height int, numSplits int) *BSPDungeonMap {
return bsp
}
func findRoom(parent *bspNode) util.Room {
func findRoom(parent *bspNode) engine.BoundingBox {
if parent.hasRoom {
return parent.room
}
@ -112,7 +112,7 @@ func findRoom(parent *bspNode) util.Room {
}
}
func zCorridor(tiles [][]Tile, from util.Position, to util.Position, direction splitDirection) {
func zCorridor(tiles [][]Tile, from engine.Position, to engine.Position, direction splitDirection) {
switch direction {
case splitDirectionHorizontal:
xMidPoint := (from.X() + to.X()) / 2
@ -164,30 +164,30 @@ func split(parent *bspNode, numSplits int) {
// split vertically
if parent.size.Width() > parent.size.Height() {
// New splits will be between 45% and 65% of the parent's width
leftSplitWidth := util.RandInt(int(float32(parent.size.Width())*0.45), int(float32(parent.size.Width())*0.65))
leftSplitWidth := engine.RandInt(int(float32(parent.size.Width())*0.45), int(float32(parent.size.Width())*0.65))
parent.splitDir = splitDirectionVertical
parent.left = new(bspNode)
parent.left.origin = parent.origin
parent.left.size = util.SizeOf(leftSplitWidth, parent.size.Height())
parent.left.size = engine.SizeOf(leftSplitWidth, parent.size.Height())
parent.right = new(bspNode)
parent.right.origin = parent.origin.WithOffset(leftSplitWidth, 0)
parent.right.size = util.SizeOf(parent.size.Width()-leftSplitWidth, parent.size.Height())
parent.right.size = engine.SizeOf(parent.size.Width()-leftSplitWidth, parent.size.Height())
} else { // split horizontally
// New splits will be between 45% and 65% of the parent's height
leftSplitHeight := util.RandInt(int(float32(parent.size.Height())*0.45), int(float32(parent.size.Height())*0.65))
leftSplitHeight := engine.RandInt(int(float32(parent.size.Height())*0.45), int(float32(parent.size.Height())*0.65))
parent.splitDir = splitDirectionHorizontal
parent.left = new(bspNode)
parent.left.origin = parent.origin
parent.left.size = util.SizeOf(parent.size.Width(), leftSplitHeight)
parent.left.size = engine.SizeOf(parent.size.Width(), leftSplitHeight)
parent.right = new(bspNode)
parent.right.origin = parent.origin.WithOffset(0, leftSplitHeight)
parent.right.size = util.SizeOf(parent.size.Width(), parent.size.Height()-leftSplitHeight)
parent.right.size = engine.SizeOf(parent.size.Width(), parent.size.Height()-leftSplitHeight)
}
split(parent.left, numSplits-1)
@ -256,7 +256,7 @@ func placeWallAtIfNotPassable(tiles [][]Tile, x, y int) {
tiles[y][x] = CreateStaticTile(x, y, TileTypeWall())
}
func makeRoom(tiles [][]Tile, room util.Room) {
func makeRoom(tiles [][]Tile, room engine.BoundingBox) {
width := room.Size().Width()
height := room.Size().Height()
x := room.Position().X()

View file

@ -0,0 +1,52 @@
package world
import (
"math/rand"
"mvvasilev/last_light/engine"
"mvvasilev/last_light/game/model"
)
func SpawnItems(spawnableAreas []engine.BoundingBox, maxItemRatio float32, genTable map[float32]*model.ItemType) []Tile {
rooms := spawnableAreas
itemTiles := make([]Tile, 0, 10)
for _, r := range rooms {
maxItems := int(maxItemRatio * float32(r.Size().Area()))
if maxItems < 1 {
continue
}
numItems := rand.Intn(maxItems)
for range numItems {
itemType := GenerateItemType(genTable)
if itemType == nil {
continue
}
pos := engine.PositionAt(
engine.RandInt(r.Position().X()+1, r.Position().X()+r.Size().Width()-1),
engine.RandInt(r.Position().Y()+1, r.Position().Y()+r.Size().Height()-1),
)
itemTiles = append(itemTiles, CreateItemTile(pos, itemType, 1))
}
}
return itemTiles
}
func GenerateItemType(genTable map[float32]*model.ItemType) *model.ItemType {
num := rand.Float32()
for k, v := range genTable {
if num > k {
return v
}
}
return nil
}

View file

@ -1,23 +1,23 @@
package world
import (
"mvvasilev/last_light/util"
"mvvasilev/last_light/engine"
)
type Map interface {
Size() util.Size
Size() engine.Size
SetTileAt(x, y int, t Tile)
TileAt(x, y int) Tile
Tick(dt int64)
}
type WithPlayerSpawnPoint interface {
PlayerSpawnPoint() util.Position
PlayerSpawnPoint() engine.Position
Map
}
type WithRooms interface {
Rooms() []util.Room
Rooms() []engine.BoundingBox
Map
}
@ -36,8 +36,8 @@ func CreateBasicMap(tiles [][]Tile) *BasicMap {
func (bm *BasicMap) Tick() {
}
func (bm *BasicMap) Size() util.Size {
return util.SizeOf(len(bm.tiles[0]), len(bm.tiles))
func (bm *BasicMap) Size() engine.Size {
return engine.SizeOf(len(bm.tiles[0]), len(bm.tiles))
}
func (bm *BasicMap) SetTileAt(x int, y int, t Tile) {

View file

@ -1,6 +1,6 @@
package world
import "mvvasilev/last_light/util"
import "mvvasilev/last_light/engine"
type MultilevelMap struct {
layers []Map
@ -14,9 +14,9 @@ func CreateMultilevelMap(maps ...Map) *MultilevelMap {
return m
}
func (mm *MultilevelMap) Size() util.Size {
func (mm *MultilevelMap) Size() engine.Size {
if len(mm.layers) == 0 {
return util.SizeOf(0, 0)
return engine.SizeOf(0, 0)
}
return mm.layers[0].Size()

View file

@ -1,8 +1,8 @@
package world
import (
"mvvasilev/last_light/engine"
"mvvasilev/last_light/game/model"
"mvvasilev/last_light/util"
"github.com/gdamore/tcell/v2"
)
@ -98,27 +98,27 @@ func TileTypeOpenDoor() TileType {
}
type Tile interface {
Position() util.Position
Position() engine.Position
Presentation() (rune, tcell.Style)
Passable() bool
Transparent() bool
}
type StaticTile struct {
position util.Position
position engine.Position
t TileType
}
func CreateStaticTile(x, y int, t TileType) Tile {
st := new(StaticTile)
st.position = util.PositionAt(x, y)
st.position = engine.PositionAt(x, y)
st.t = t
return st
}
func (st *StaticTile) Position() util.Position {
func (st *StaticTile) Position() engine.Position {
return st.position
}
@ -139,12 +139,12 @@ func (st *StaticTile) Type() TileType {
}
type ItemTile struct {
position util.Position
position engine.Position
itemType *model.ItemType
quantity int
}
func CreateItemTile(position util.Position, itemType *model.ItemType, quantity int) *ItemTile {
func CreateItemTile(position engine.Position, itemType *model.ItemType, quantity int) *ItemTile {
it := new(ItemTile)
it.position = position
@ -162,7 +162,7 @@ func (it *ItemTile) Quantity() int {
return it.quantity
}
func (it *ItemTile) Position() util.Position {
func (it *ItemTile) Position() engine.Position {
return it.position
}
@ -202,7 +202,7 @@ func (bet *BasicEntityTile) Entity() model.MovableEntity {
return bet.entity
}
func (bet *BasicEntityTile) Position() util.Position {
func (bet *BasicEntityTile) Position() engine.Position {
return bet.entity.Position()
}