mirror of
https://github.com/mvvasilev/last_light.git
synced 2025-04-19 12:49:52 +03:00
186 lines
3.9 KiB
Go
186 lines
3.9 KiB
Go
package state
|
|
|
|
import (
|
|
"mvvasilev/last_light/engine"
|
|
engine1 "mvvasilev/last_light/engine"
|
|
"mvvasilev/last_light/game/model"
|
|
"mvvasilev/last_light/game/world"
|
|
|
|
"github.com/gdamore/tcell/v2"
|
|
"github.com/gdamore/tcell/v2/views"
|
|
)
|
|
|
|
type PlayingState struct {
|
|
player *model.Player
|
|
entityMap *world.EntityMap
|
|
level *world.MultilevelMap
|
|
|
|
viewport *engine.Viewport
|
|
|
|
movePlayerDirection model.Direction
|
|
pauseGame bool
|
|
openInventory bool
|
|
pickUpUnderPlayer bool
|
|
}
|
|
|
|
func BeginPlayingState() *PlayingState {
|
|
s := new(PlayingState)
|
|
|
|
mapSize := engine1.SizeOf(128, 128)
|
|
|
|
dungeonLevel := world.CreateBSPDungeonMap(mapSize.Width(), mapSize.Height(), 4)
|
|
|
|
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())
|
|
|
|
for _, it := range itemTiles {
|
|
itemLevel.SetTileAt(it.Position().X(), it.Position().Y(), it)
|
|
}
|
|
|
|
s.player = model.CreatePlayer(dungeonLevel.PlayerSpawnPoint().XY())
|
|
|
|
s.entityMap = world.CreateEntityMap(mapSize.WH())
|
|
|
|
s.level = world.CreateMultilevelMap(
|
|
dungeonLevel,
|
|
itemLevel,
|
|
s.entityMap,
|
|
)
|
|
|
|
s.entityMap.AddEntity(s.player, '@', tcell.StyleDefault)
|
|
|
|
s.viewport = engine.CreateViewport(
|
|
engine1.PositionAt(0, 0),
|
|
dungeonLevel.PlayerSpawnPoint(),
|
|
engine1.SizeOf(80, 24),
|
|
tcell.StyleDefault,
|
|
)
|
|
|
|
return s
|
|
}
|
|
|
|
func (ps *PlayingState) Pause() {
|
|
ps.pauseGame = true
|
|
}
|
|
|
|
func (ps *PlayingState) Unpause() {
|
|
ps.pauseGame = false
|
|
}
|
|
|
|
func (ps *PlayingState) SetPaused(paused bool) {
|
|
ps.pauseGame = paused
|
|
}
|
|
|
|
func (ps *PlayingState) MovePlayer() {
|
|
if ps.movePlayerDirection == model.DirectionNone {
|
|
return
|
|
}
|
|
|
|
newPlayerPos := ps.player.Position().WithOffset(model.MovementDirectionOffset(ps.movePlayerDirection))
|
|
tileAtMovePos := ps.level.TileAt(newPlayerPos.XY())
|
|
|
|
if tileAtMovePos.Passable() {
|
|
dx, dy := model.MovementDirectionOffset(ps.movePlayerDirection)
|
|
ps.entityMap.MoveEntity(ps.player.UniqueId(), dx, dy)
|
|
ps.viewport.SetCenter(ps.player.Position())
|
|
}
|
|
|
|
ps.movePlayerDirection = model.DirectionNone
|
|
}
|
|
|
|
func (ps *PlayingState) PickUpItemUnderPlayer() {
|
|
pos := ps.player.Position()
|
|
tile := ps.level.TileAtHeight(pos.X(), pos.Y(), 1)
|
|
|
|
itemTile, ok := tile.(*world.ItemTile)
|
|
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
item := model.CreateItem(itemTile.Type(), itemTile.Quantity())
|
|
|
|
success := ps.player.Inventory().Push(item)
|
|
|
|
if !success {
|
|
return
|
|
}
|
|
|
|
ps.level.SetTileAtHeight(pos.X(), pos.Y(), 1, nil)
|
|
}
|
|
|
|
func (ps *PlayingState) OnInput(e *tcell.EventKey) {
|
|
ps.player.Input(e)
|
|
|
|
if e.Key() == tcell.KeyEsc {
|
|
ps.pauseGame = true
|
|
return
|
|
}
|
|
|
|
if e.Key() == tcell.KeyRune && e.Rune() == 'i' {
|
|
ps.openInventory = true
|
|
return
|
|
}
|
|
|
|
if e.Key() == tcell.KeyRune && e.Rune() == 'p' {
|
|
ps.pickUpUnderPlayer = true
|
|
return
|
|
}
|
|
|
|
switch e.Key() {
|
|
case tcell.KeyUp:
|
|
ps.movePlayerDirection = model.DirectionUp
|
|
case tcell.KeyDown:
|
|
ps.movePlayerDirection = model.DirectionDown
|
|
case tcell.KeyLeft:
|
|
ps.movePlayerDirection = model.DirectionLeft
|
|
case tcell.KeyRight:
|
|
ps.movePlayerDirection = model.DirectionRight
|
|
}
|
|
}
|
|
|
|
func (ps *PlayingState) OnTick(dt int64) GameState {
|
|
ps.player.Tick(dt)
|
|
|
|
if ps.pauseGame {
|
|
return PauseGame(ps)
|
|
}
|
|
|
|
if ps.openInventory {
|
|
ps.openInventory = false
|
|
return CreateInventoryScreenState(ps.player, ps)
|
|
}
|
|
|
|
if ps.movePlayerDirection != model.DirectionNone {
|
|
ps.MovePlayer()
|
|
}
|
|
|
|
if ps.pickUpUnderPlayer {
|
|
ps.pickUpUnderPlayer = false
|
|
ps.PickUpItemUnderPlayer()
|
|
}
|
|
|
|
return ps
|
|
}
|
|
|
|
func (ps *PlayingState) CollectDrawables() []engine.Drawable {
|
|
return engine.Multidraw(engine.CreateDrawingInstructions(func(v views.View) {
|
|
ps.viewport.DrawFromProvider(v, func(x, y int) (rune, tcell.Style) {
|
|
tile := ps.level.TileAt(x, y)
|
|
|
|
if tile != nil {
|
|
return tile.Presentation()
|
|
}
|
|
|
|
return ' ', tcell.StyleDefault
|
|
})
|
|
}))
|
|
}
|