Skip to content

Commit

Permalink
Reset placement view model on scene change from result scene
Browse files Browse the repository at this point in the history
  • Loading branch information
bilki committed Feb 22, 2022
1 parent d82138e commit 2ed54cc
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ object LandingScene extends Scene[NavalCombatSetupData, NavalCombatModel, NavalC
type SceneModel = NavalCombatModel
type SceneViewModel = LandingViewModel

def name: SceneName = SceneName("landing")
val name: SceneName = SceneName("landing")

def eventFilters: EventFilters = EventFilters.Permissive

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import com.lambdarat.navalcombat.engine.BoardEngine.*
import com.lambdarat.navalcombat.scenes.placement.view.*
import com.lambdarat.navalcombat.scenes.placement.viewmodel.*
import com.lambdarat.navalcombat.scenes.player.PlayerScene
import com.lambdarat.navalcombat.scenes.result.ResultScene
import com.lambdarat.navalcombat.utils.*
import com.lambdarat.navalcombat.utils.given

import indigo.*
import indigo.scenes.*
import indigo.scenes.SceneEvent.SceneChange
import indigoextras.geometry.*
import indigoextras.subsystems.*
import indigoextras.trees.QuadTree
Expand All @@ -26,7 +28,7 @@ object PlacementScene extends Scene[NavalCombatSetupData, NavalCombatModel, Nava
type SceneModel = NavalCombatModel
type SceneViewModel = PlacementViewModel

def name: SceneName = SceneName("combat")
val name: SceneName = SceneName("combat")

def eventFilters: EventFilters = EventFilters.Permissive

Expand Down Expand Up @@ -117,65 +119,74 @@ object PlacementScene extends Scene[NavalCombatSetupData, NavalCombatModel, Nava
)
end highlightedCells

private def handlePlacement(
mouse: Mouse,
keyboard: Keyboard,
model: NavalCombatModel,
viewModel: PlacementViewModel
): Outcome[PlacementViewModel] =
val gridBounds = viewModel.sceneSettings.gridBounds
val modelSpace = viewModel.sceneSettings.modelSpace

(mouse.mouseClicked, viewModel.dragging) match
case (true, None) =>
val nextPlacingShip = viewModel.sidebarShips.find { ship =>
val shipGraphic = PlacementView.sidebarShipGraphicFor(ship, viewModel.sidebarShipGraphics)
mouse.wasMouseClickedWithin(shipGraphic.bounds)
}.map(PlacingShip(_, Rotation.Horizontal))

val nextSidebarShips = nextPlacingShip.fold(viewModel.sidebarShips) { dragging =>
viewModel.sidebarShips.filterNot(_ == dragging.ship)
}

Outcome(
viewModel.copy(dragging = nextPlacingShip, highlightedCells = List.empty, sidebarShips = nextSidebarShips)
)
case (false, Some(dragged)) =>
val highlighted = highlightedCells(dragged, gridBounds, modelSpace, mouse.position, model)
val newRotation =
if keyboard.keysAreUp(Key.KEY_R) || mouse.pressed(MouseButton.RightMouseButton) then dragged.rotation.reverse
else dragged.rotation
val nextPlacingShip = Some(PlacingShip(dragged.ship, newRotation))

Outcome(viewModel.copy(dragging = nextPlacingShip, highlightedCells = highlighted))
case (true, Some(dragged)) =>
val highlighted = highlightedCells(dragged, gridBounds, modelSpace, mouse.position, model)

val maybeUpdateBoard =
for
highlightedCell <- Option
.when(highlighted.size == dragged.ship.size.toInt)(highlighted.headOption)
.flatten
maybePlaceShip = PlaceShip(dragged.ship, highlightedCell.position, dragged.rotation)
position = highlightedCell.position
placeShip <- Option.when(model.player.canPlace(dragged.ship, dragged.rotation, position.x, position.y))(
maybePlaceShip
)
yield placeShip

Outcome(viewModel.copy(dragging = None, highlightedCells = List.empty)).flatMap { nextViewModel =>
maybeUpdateBoard match
case None =>
Outcome(nextViewModel.copy(sidebarShips = dragged.ship :: nextViewModel.sidebarShips))
case Some(placeShip) =>
Outcome(
nextViewModel.copy(sidebarShips = nextViewModel.sidebarShips.filterNot(_ == placeShip.shipType))
).addGlobalEvents(placeShip)
}

case (false, None) =>
Outcome(viewModel)

def updateViewModel(
context: FrameContext[NavalCombatSetupData],
model: NavalCombatModel,
viewModel: PlacementViewModel
): GlobalEvent => Outcome[PlacementViewModel] =
case FrameTick =>
val gridBounds = viewModel.sceneSettings.gridBounds
val modelSpace = viewModel.sceneSettings.modelSpace

(context.mouse.mouseClicked, viewModel.dragging) match
case (true, None) =>
val nextPlacingShip = viewModel.sidebarShips.find { ship =>
val shipGraphic = PlacementView.sidebarShipGraphicFor(ship, viewModel.sidebarShipGraphics)
context.mouse.wasMouseClickedWithin(shipGraphic.bounds)
}.map(PlacingShip(_, Rotation.Horizontal))

val nextSidebarShips = nextPlacingShip.fold(viewModel.sidebarShips) { dragging =>
viewModel.sidebarShips.filterNot(_ == dragging.ship)
}

Outcome(
viewModel.copy(dragging = nextPlacingShip, highlightedCells = List.empty, sidebarShips = nextSidebarShips)
)
case (false, Some(dragged)) =>
val highlighted = highlightedCells(dragged, gridBounds, modelSpace, context.mouse.position, model)
val newRotation =
if context.keyboard.keysAreUp(Key.KEY_R) || context.mouse.pressed(MouseButton.RightMouseButton) then
dragged.rotation.reverse
else dragged.rotation
val nextPlacingShip = Some(PlacingShip(dragged.ship, newRotation))

Outcome(viewModel.copy(dragging = nextPlacingShip, highlightedCells = highlighted))
case (true, Some(dragged)) =>
val highlighted = highlightedCells(dragged, gridBounds, modelSpace, context.mouse.position, model)

val maybeUpdateBoard =
for
highlightedCell <- Option
.when(highlighted.size == dragged.ship.size.toInt)(highlighted.headOption)
.flatten
maybePlaceShip = PlaceShip(dragged.ship, highlightedCell.position, dragged.rotation)
position = highlightedCell.position
placeShip <- Option.when(model.player.canPlace(dragged.ship, dragged.rotation, position.x, position.y))(
maybePlaceShip
)
yield placeShip

Outcome(viewModel.copy(dragging = None, highlightedCells = List.empty)).flatMap { nextViewModel =>
maybeUpdateBoard match
case None =>
Outcome(nextViewModel.copy(sidebarShips = dragged.ship :: nextViewModel.sidebarShips))
case Some(placeShip) =>
Outcome(
nextViewModel.copy(sidebarShips = nextViewModel.sidebarShips.filterNot(_ == placeShip.shipType))
).addGlobalEvents(placeShip)
}

case (false, None) =>
Outcome(viewModel)
handlePlacement(context.mouse, context.keyboard, model, viewModel)
case SceneChange(ResultScene.name, _, _) =>
Outcome(initialPlacementViewModel(context.startUpData))
case _ =>
Outcome(viewModel)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ object PlayerScene extends Scene[NavalCombatSetupData, NavalCombatModel, NavalCo
type SceneModel = NavalCombatModel
type SceneViewModel = PlayerViewModel

def name: SceneName = SceneName("player")
val name: SceneName = SceneName("player")

def eventFilters: EventFilters = EventFilters.Permissive

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ object ResultScene extends Scene[NavalCombatSetupData, NavalCombatModel, NavalCo
type SceneModel = NavalCombatModel
type SceneViewModel = ResultViewModel

def name: SceneName = SceneName("result")
val name: SceneName = SceneName("result")

def eventFilters: EventFilters = EventFilters.Permissive

Expand Down

0 comments on commit 2ed54cc

Please sign in to comment.