last_light/game/model/world_map.go

189 lines
3.7 KiB
Go
Raw Normal View History

2024-06-06 23:17:22 +03:00
package model
import (
"mvvasilev/last_light/engine"
"github.com/gdamore/tcell/v2"
)
2024-06-06 23:28:06 +03:00
type Map interface {
2024-06-06 23:17:22 +03:00
Size() engine.Size
2024-06-06 23:28:06 +03:00
Tiles() [][]Tile
ExploredTiles() map[engine.Position]Tile
2024-06-06 23:17:22 +03:00
ExploredTileStyle() tcell.Style
2024-06-06 23:28:06 +03:00
DefaultTile() Tile
2024-06-06 23:17:22 +03:00
PlayerSpawnPoint() *Map_PlayerSpawnPointComponent
Rooms() *Map_RoomsComponent
NextLevelStaircase() *Map_NextLevelStaircaseComponent
PreviousLevelStaircase() *Map_PreviousLevelStaircaseComponent
}
type Map_PlayerSpawnPointComponent struct {
Position engine.Position
}
type Map_RoomsComponent struct {
Rooms []engine.BoundingBox
}
type Map_NextLevelStaircaseComponent struct {
Position engine.Position
}
type Map_PreviousLevelStaircaseComponent struct {
Position engine.Position
}
type BaseMap struct {
size engine.Size
2024-06-06 23:28:06 +03:00
tiles [][]Tile
exploredTiles map[engine.Position]Tile
2024-06-06 23:17:22 +03:00
exploredStyle tcell.Style
2024-06-06 23:28:06 +03:00
defaultTile Tile
2024-06-06 23:17:22 +03:00
playerSpawnPos *Map_PlayerSpawnPointComponent
rooms *Map_RoomsComponent
nextLevel *Map_NextLevelStaircaseComponent
prevLevel *Map_PreviousLevelStaircaseComponent
}
2024-06-06 23:28:06 +03:00
func CreateMap(size engine.Size, tiles [][]Tile, exploredStyle tcell.Style, defaultTile Tile, components ...func(*BaseMap)) Map {
2024-06-06 23:17:22 +03:00
m := &BaseMap{
size: size,
tiles: tiles,
2024-06-06 23:28:06 +03:00
exploredTiles: make(map[engine.Position]Tile, 0),
2024-06-06 23:17:22 +03:00
exploredStyle: exploredStyle,
defaultTile: defaultTile,
}
for _, c := range components {
c(m)
}
return m
}
func (m *BaseMap) Size() engine.Size {
return m.size
}
2024-06-06 23:28:06 +03:00
func (m *BaseMap) Tiles() [][]Tile {
2024-06-06 23:17:22 +03:00
return m.tiles
}
2024-06-06 23:28:06 +03:00
func (m *BaseMap) ExploredTiles() map[engine.Position]Tile {
2024-06-06 23:17:22 +03:00
return m.exploredTiles
}
func (m *BaseMap) ExploredTileStyle() tcell.Style {
return m.exploredStyle
}
2024-06-06 23:28:06 +03:00
func (m *BaseMap) DefaultTile() Tile {
2024-06-06 23:17:22 +03:00
return m.defaultTile
}
func (m *BaseMap) PlayerSpawnPoint() *Map_PlayerSpawnPointComponent {
return m.playerSpawnPos
}
func (m *BaseMap) Rooms() *Map_RoomsComponent {
return m.rooms
}
func (m *BaseMap) NextLevelStaircase() *Map_NextLevelStaircaseComponent {
return m.nextLevel
}
func (m *BaseMap) PreviousLevelStaircase() *Map_PreviousLevelStaircaseComponent {
return m.prevLevel
}
func Map_WithRooms(rooms []engine.BoundingBox) func(*BaseMap) {
return func(bm *BaseMap) {
bm.rooms = &Map_RoomsComponent{
Rooms: rooms,
}
}
}
func Map_WithPlayerSpawnPoint(pos engine.Position) func(*BaseMap) {
return func(bm *BaseMap) {
bm.playerSpawnPos = &Map_PlayerSpawnPointComponent{
Position: pos,
}
}
}
func Map_WithNextLevelStaircase(pos engine.Position) func(*BaseMap) {
return func(bm *BaseMap) {
bm.nextLevel = &Map_NextLevelStaircaseComponent{
Position: pos,
}
}
}
func Map_WithPreviousLevelStaircase(pos engine.Position) func(*BaseMap) {
return func(bm *BaseMap) {
bm.prevLevel = &Map_PreviousLevelStaircaseComponent{
Position: pos,
}
}
}
2024-06-06 23:28:06 +03:00
func Map_SetTileAt(bm Map, x int, y int, t Tile) Tile {
2024-06-06 23:17:22 +03:00
if !Map_IsInBounds(bm, x, y) {
return bm.DefaultTile()
}
bm.Tiles()[y][x] = t
return bm.Tiles()[y][x]
}
2024-06-06 23:28:06 +03:00
func Map_TileAt(bm Map, x int, y int) Tile {
2024-06-06 23:17:22 +03:00
if !Map_IsInBounds(bm, x, y) {
return bm.DefaultTile()
}
tile := bm.Tiles()[y][x]
if tile == nil {
return bm.DefaultTile()
}
return tile
}
2024-06-06 23:28:06 +03:00
func Map_IsInBounds(bm Map, x, y int) bool {
2024-06-06 23:17:22 +03:00
if x < 0 || y < 0 {
return false
}
if x >= bm.Size().Width() || y >= bm.Size().Height() {
return false
}
return true
}
2024-06-06 23:28:06 +03:00
func Map_ExploredTileAt(bm Map, x, y int) Tile {
2024-06-06 23:17:22 +03:00
return bm.ExploredTiles()[engine.PositionAt(x, y)]
}
2024-06-06 23:28:06 +03:00
func Map_MarkExplored(bm Map, x, y int) {
2024-06-06 23:17:22 +03:00
if !Map_IsInBounds(bm, x, y) {
return
}
tile := Map_TileAt(bm, x, y)
symbol, _ := tile.DefaultPresentation()
bm.ExploredTiles()[engine.PositionAt(x, y)] = &BaseTile{
defaultSymbol: symbol,
defaultStyle: bm.ExploredTileStyle(),
}
}