last_light/game/model/world_map.go

189 lines
3.8 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"
)
type Map_V2 interface {
Size() engine.Size
Tiles() [][]Tile_V2
ExploredTiles() map[engine.Position]Tile_V2
ExploredTileStyle() tcell.Style
DefaultTile() Tile_V2
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
tiles [][]Tile_V2
exploredTiles map[engine.Position]Tile_V2
exploredStyle tcell.Style
defaultTile Tile_V2
playerSpawnPos *Map_PlayerSpawnPointComponent
rooms *Map_RoomsComponent
nextLevel *Map_NextLevelStaircaseComponent
prevLevel *Map_PreviousLevelStaircaseComponent
}
func CreateMap(size engine.Size, tiles [][]Tile_V2, exploredStyle tcell.Style, defaultTile Tile_V2, components ...func(*BaseMap)) Map_V2 {
m := &BaseMap{
size: size,
tiles: tiles,
exploredTiles: make(map[engine.Position]Tile_V2, 0),
exploredStyle: exploredStyle,
defaultTile: defaultTile,
}
for _, c := range components {
c(m)
}
return m
}
func (m *BaseMap) Size() engine.Size {
return m.size
}
func (m *BaseMap) Tiles() [][]Tile_V2 {
return m.tiles
}
func (m *BaseMap) ExploredTiles() map[engine.Position]Tile_V2 {
return m.exploredTiles
}
func (m *BaseMap) ExploredTileStyle() tcell.Style {
return m.exploredStyle
}
func (m *BaseMap) DefaultTile() Tile_V2 {
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,
}
}
}
func Map_SetTileAt(bm Map_V2, x int, y int, t Tile_V2) Tile_V2 {
if !Map_IsInBounds(bm, x, y) {
return bm.DefaultTile()
}
bm.Tiles()[y][x] = t
return bm.Tiles()[y][x]
}
func Map_TileAt(bm Map_V2, x int, y int) Tile_V2 {
if !Map_IsInBounds(bm, x, y) {
return bm.DefaultTile()
}
tile := bm.Tiles()[y][x]
if tile == nil {
return bm.DefaultTile()
}
return tile
}
func Map_IsInBounds(bm Map_V2, x, y int) bool {
if x < 0 || y < 0 {
return false
}
if x >= bm.Size().Width() || y >= bm.Size().Height() {
return false
}
return true
}
func Map_ExploredTileAt(bm Map_V2, x, y int) Tile_V2 {
return bm.ExploredTiles()[engine.PositionAt(x, y)]
}
func Map_MarkExplored(bm Map_V2, x, y int) {
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(),
}
}