diff --git a/engine/bounding_box.go b/engine/bounding_box.go new file mode 100644 index 0000000..0bfd1ea --- /dev/null +++ b/engine/bounding_box.go @@ -0,0 +1,6 @@ +package engine + +type BoundingBox struct { + Positioned + Sized +} diff --git a/engine/grid.go b/engine/grid.go index 47bdae8..4d594c4 100644 --- a/engine/grid.go +++ b/engine/grid.go @@ -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 } diff --git a/engine/raw.go b/engine/raw.go index 0ea632e..f1a4789 100644 --- a/engine/raw.go +++ b/engine/raw.go @@ -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 diff --git a/engine/rectangle.go b/engine/rectangle.go index 5b2d776..596f0a3 100644 --- a/engine/rectangle.go +++ b/engine/rectangle.go @@ -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 } diff --git a/engine/text.go b/engine/text.go index 8c133d6..e2b011e 100644 --- a/engine/text.go +++ b/engine/text.go @@ -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 } diff --git a/util/util.go b/engine/util.go similarity index 96% rename from util/util.go rename to engine/util.go index c8385f7..e3cbac2 100644 --- a/util/util.go +++ b/engine/util.go @@ -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 -} diff --git a/engine/viewport.go b/engine/viewport.go index 6e994f2..6912036 100644 --- a/engine/viewport.go +++ b/engine/viewport.go @@ -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 } diff --git a/game/model/entity.go b/game/model/entity.go index ca74272..d841fc0 100644 --- a/game/model/entity.go +++ b/game/model/entity.go @@ -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 } diff --git a/game/model/inventory.go b/game/model/inventory.go index 32efdcb..3ceb23d 100644 --- a/game/model/inventory.go +++ b/game/model/inventory.go @@ -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 } diff --git a/game/model/item_type.go b/game/model/item_type.go index 25bdd73..5bab2ff 100644 --- a/game/model/item_type.go +++ b/game/model/item_type.go @@ -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 -} diff --git a/game/model/player.go b/game/model/player.go index bf017aa..822dea8 100644 --- a/game/model/player.go +++ b/game/model/player.go @@ -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 } diff --git a/game/model/player_inventory.go b/game/model/player_inventory.go index 1d933fa..26541dd 100644 --- a/game/model/player_inventory.go +++ b/game/model/player_inventory.go @@ -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)), } } diff --git a/game/state/inventory_screen_state.go b/game/state/inventory_screen_state.go index bba2d66..f7ae103 100644 --- a/game/state/inventory_screen_state.go +++ b/game/state/inventory_screen_state.go @@ -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)) diff --git a/game/state/main_menu_state.go b/game/state/main_menu_state.go index 1597dd6..9de6efa 100644 --- a/game/state/main_menu_state.go +++ b/game/state/main_menu_state.go @@ -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() } diff --git a/game/state/pause_game_state.go b/game/state/pause_game_state.go index 32a1717..f190bcd 100644 --- a/game/state/pause_game_state.go +++ b/game/state/pause_game_state.go @@ -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() } diff --git a/game/state/playing_state.go b/game/state/playing_state.go index 319afbd..a865359 100644 --- a/game/state/playing_state.go +++ b/game/state/playing_state.go @@ -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 } diff --git a/game/ui/border_button.go b/game/ui/border_button.go index 913c665..b572cbf 100644 --- a/game/ui/border_button.go +++ b/game/ui/border_button.go @@ -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 } diff --git a/game/ui/container.go b/game/ui/container.go index c955d38..0dde369 100644 --- a/game/ui/container.go +++ b/game/ui/container.go @@ -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 } diff --git a/game/ui/label.go b/game/ui/label.go index fef57f8..6828226 100644 --- a/game/ui/label.go +++ b/game/ui/label.go @@ -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() } diff --git a/game/ui/menu/player_inventory_menu.go b/game/ui/menu/player_inventory_menu.go index 8da4545..6980a3d 100644 --- a/game/ui/menu/player_inventory_menu.go +++ b/game/ui/menu/player_inventory_menu.go @@ -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) } diff --git a/game/ui/simple_button.go b/game/ui/simple_button.go index 5539be7..f6a7cca 100644 --- a/game/ui/simple_button.go +++ b/game/ui/simple_button.go @@ -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() } diff --git a/game/ui/ui.go b/game/ui/ui.go index b6e0c52..0305b24 100644 --- a/game/ui/ui.go +++ b/game/ui/ui.go @@ -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 diff --git a/game/ui/window.go b/game/ui/window.go index 4c8b5c7..b14c466 100644 --- a/game/ui/window.go +++ b/game/ui/window.go @@ -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) { diff --git a/game/world/bsp_map.go b/game/world/bsp_map.go index 2be2b5e..e38b591 100644 --- a/game/world/bsp_map.go +++ b/game/world/bsp_map.go @@ -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 } diff --git a/game/world/empty_map.go b/game/world/empty_map.go index a5b07be..16f7c8c 100644 --- a/game/world/empty_map.go +++ b/game/world/empty_map.go @@ -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() } diff --git a/game/world/entity_map.go b/game/world/entity_map.go index a44a3f8..e62093c 100644 --- a/game/world/entity_map.go +++ b/game/world/entity_map.go @@ -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 }) } diff --git a/game/world/generate_bsp_map.go b/game/world/generate_bsp_map.go index b209def..ba51cbc 100644 --- a/game/world/generate_bsp_map.go +++ b/game/world/generate_bsp_map.go @@ -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() diff --git a/game/world/generate_items.go b/game/world/generate_items.go new file mode 100644 index 0000000..eca0352 --- /dev/null +++ b/game/world/generate_items.go @@ -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 +} diff --git a/game/world/map.go b/game/world/map.go index e4c3841..35873d4 100644 --- a/game/world/map.go +++ b/game/world/map.go @@ -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) { diff --git a/game/world/multilevel_map.go b/game/world/multilevel_map.go index e2979e5..e10fd30 100644 --- a/game/world/multilevel_map.go +++ b/game/world/multilevel_map.go @@ -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() diff --git a/game/world/tile.go b/game/world/tile.go index d138ec3..3be6e0f 100644 --- a/game/world/tile.go +++ b/game/world/tile.go @@ -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() }