diff --git a/assets/abilities/cards/explotionCard.png b/assets/abilities/cards/explosionCard.png similarity index 100% rename from assets/abilities/cards/explotionCard.png rename to assets/abilities/cards/explosionCard.png diff --git a/assets/abilities/mirror-card.png b/assets/abilities/cards/new_movementCard.png similarity index 100% rename from assets/abilities/mirror-card.png rename to assets/abilities/cards/new_movementCard.png diff --git a/assets/abilities/new_movement-card.png b/assets/abilities/cards/swapCard.png similarity index 100% rename from assets/abilities/new_movement-card.png rename to assets/abilities/cards/swapCard.png diff --git a/assets/abilities/explosion-card-temp.png b/assets/abilities/explosion-card-temp.png deleted file mode 100644 index b1befe02..00000000 Binary files a/assets/abilities/explosion-card-temp.png and /dev/null differ diff --git a/assets/abilities/explosion-card.png b/assets/abilities/explosion-card.png deleted file mode 100644 index d7f8c40d..00000000 Binary files a/assets/abilities/explosion-card.png and /dev/null differ diff --git a/assets/abilities/shield-card.png b/assets/abilities/shield-card.png deleted file mode 100644 index 6379f6eb..00000000 Binary files a/assets/abilities/shield-card.png and /dev/null differ diff --git a/assets/abilities/swap-card.png b/assets/abilities/swap-card.png deleted file mode 100644 index 6379f6eb..00000000 Binary files a/assets/abilities/swap-card.png and /dev/null differ diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/AbilityItemFactory.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/AbilityItemFactory.kt index 0c9b5bfa..3e9d3c69 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/AbilityItemFactory.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/AbilityItemFactory.kt @@ -18,10 +18,9 @@ class AbilityItemFactory( when (abilityType) { AbilityType.SHIELD -> TextureRegion(assetManager.get("abilities/cards/shieldCard.png", Texture::class.java)) AbilityType.EXPLOSION -> TextureRegion(assetManager.get("abilities/cards/explosionCard.png", Texture::class.java)) - // TODO: update all cards - AbilityType.SWAP -> TextureRegion(assetManager.get("abilities/swap-card.png", Texture::class.java)) + AbilityType.SWAP -> TextureRegion(assetManager.get("abilities/cards/swapCard.png", Texture::class.java)) AbilityType.MIRROR -> TextureRegion(assetManager.get("abilities/cards/mirrorCard.png", Texture::class.java)) - AbilityType.NEW_MOVEMENT -> TextureRegion(assetManager.get("abilities/new_movement-card.png", Texture::class.java)) + AbilityType.NEW_MOVEMENT -> TextureRegion(assetManager.get("abilities/cards/new_movementCard.png", Texture::class.java)) } fun createAbilityItem(abilityType: AbilityType): Entity { diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt index 3144b3e6..c8bf50db 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt @@ -114,24 +114,14 @@ class PieceFactory( } fun createPawn( - isPlayerOne: Boolean, position: Position, color: PlayerColor, stage: Stage, ) = createPiece(position, PieceType.PAWN, color, stage).apply { getComponent(MovementRuleComponent::class.java).apply { - val pawnDirections: List - val pawnCaptureDirections: List - val pawnStartDirections: List - if (isPlayerOne) { - pawnDirections = listOf(Vector2(0f, 1f)) - pawnCaptureDirections = listOf(Vector2(1f, 1f), Vector2(-1f, 1f)) - pawnStartDirections = listOf(Vector2(0f, 2f)) - } else { - pawnDirections = listOf(Vector2(0f, -1f)) - pawnCaptureDirections = listOf(Vector2(1f, -1f), Vector2(-1f, -1f)) - pawnStartDirections = listOf(Vector2(0f, -2f)) - } + val pawnDirections: List = listOf(Vector2(0f, 1f)) + val pawnCaptureDirections: List = listOf(Vector2(1f, 1f), Vector2(-1f, 1f)) + val pawnStartDirections: List = listOf(Vector2(0f, 2f)) addPattern( MovementPattern( diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt index f92e1280..0cd65006 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt @@ -4,6 +4,7 @@ import com.badlogic.ashley.core.Engine import com.badlogic.ashley.core.Family import com.badlogic.gdx.Gdx import com.badlogic.gdx.scenes.scene2d.Stage +import io.github.chessevolved.components.ActorComponent import io.github.chessevolved.components.PieceTypeComponent import io.github.chessevolved.components.PlayerColorComponent import io.github.chessevolved.components.PositionComponent @@ -34,8 +35,14 @@ object EcsEntityMapper { fun extractStateFromEngine(engine: Engine): Pair, List> { val pieces = engine.getEntitiesFor(pieceFamily).map { entity -> + val piecePosition = PositionComponent.mapper.get(entity) + PieceDto( - position = PositionComponent.mapper.get(entity).position, + position = + Position( + piecePosition.position.x, + GameSettings.getBoardSize() - 1 - piecePosition.position.y, + ), type = PieceTypeComponent.mapper.get(entity).type, color = PlayerColorComponent.mapper.get(entity).color, ) @@ -60,6 +67,7 @@ object EcsEntityMapper { receivedBoardSquares: List, ) { Gdx.app.log("ECSEntityMapper", "Applying received state to engine...") + try { val existingPieceEntities = engine.getEntitiesFor(pieceFamily) val existingPiecesMap = @@ -91,7 +99,10 @@ object EcsEntityMapper { val pos = PositionComponent.mapper.get(existingEntity).position if (pos !in currentPositions) { Gdx.app.debug("ECSEntityMapper", "Removing piece no longer in state at $pos") + val actorComponent = ActorComponent.mapper.get(existingEntity) + actorComponent.actor.remove() engine.removeEntity(existingEntity) + println("ActorComp: $actorComponent") } } @@ -130,7 +141,7 @@ object EcsEntityMapper { pieceData: PieceDto, ) { when (pieceData.type) { - PieceType.PAWN -> pieceFactory.createPawn(true, pieceData.position, pieceData.color, stage) + PieceType.PAWN -> pieceFactory.createPawn(pieceData.position, pieceData.color, stage) PieceType.ROOK -> pieceFactory.createRook(pieceData.position, pieceData.color, stage) PieceType.KNIGHT -> pieceFactory.createKnight(pieceData.position, pieceData.color, stage) PieceType.BISHOP -> pieceFactory.createBishop(pieceData.position, pieceData.color, stage) diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Game.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Game.kt index 4c25fd85..73a2bd11 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Game.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Game.kt @@ -17,6 +17,7 @@ object Game { try { SupabaseGameHandler.joinGame(gameId, ::onGameRowUpdate) this.inGame = true + this.currentTurn = PlayerColor.WHITE } catch (e: Exception) { throw Exception("Problem with joining game: " + e.message) } @@ -36,6 +37,11 @@ object Game { } } + suspend fun deleteGame() { + leaveGame() + SupabaseGameHandler.deleteGameRow(Lobby.getLobbyId()!!) + } + suspend fun askForRematch() { if (!isInGame() && !hasAskedForRematch) { throw IllegalStateException("Can't ask for rematch if not in a game or have already asked for rematch!") diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/GameSettings.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/GameSettings.kt index 7fa12f12..f2801cfc 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/GameSettings.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/GameSettings.kt @@ -1,10 +1,14 @@ package io.github.chessevolved.singletons import io.github.chessevolved.dtos.SettingsDto +import io.github.chessevolved.enums.PlayerColor object GameSettings { private var fogOfWar: Boolean = false private var boardSize: Int = 8 + var clientPlayerColor: PlayerColor = PlayerColor.WHITE + var opponentPlayerColor: PlayerColor = PlayerColor.BLACK + var isSecondPlayer: Boolean = false /** * The current setting of FOW diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt index 1b632a5d..c5e880e8 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt @@ -2,6 +2,7 @@ package io.github.chessevolved.singletons import com.badlogic.gdx.Gdx import io.github.chessevolved.dtos.LobbyDto +import io.github.chessevolved.enums.PlayerColor import io.github.chessevolved.singletons.supabase.SupabaseLobbyHandler object Lobby { @@ -19,6 +20,9 @@ object Lobby { try { SupabaseLobbyHandler.joinLobby(lobbyId, ::onLobbyRowUpdate) this.lobbyId = lobbyId + GameSettings.clientPlayerColor = PlayerColor.BLACK + GameSettings.opponentPlayerColor = PlayerColor.WHITE + GameSettings.isSecondPlayer = true } catch (e: Exception) { throw e } @@ -32,6 +36,7 @@ object Lobby { try { SupabaseLobbyHandler.leaveLobbyNoUpdateSecondPlayer(lobbyId!!) SupabaseLobbyHandler.joinLobbyNoUpdateSecondPlayer(lobbyId!!, ::onLobbyRowUpdate) + onLobbyRowUpdate(getLobby()) } catch (e: Exception) { Gdx.app.error("Lobby", "Error when joining rematch lobby: " + e.message) } @@ -44,6 +49,7 @@ object Lobby { try { SupabaseLobbyHandler.leaveLobbyNoUpdateSecondPlayer(lobbyId!!) SupabaseLobbyHandler.joinLobby(lobbyId!!, ::onLobbyRowUpdate) + onLobbyRowUpdate(getLobby()) } catch (e: Exception) { throw e } @@ -54,6 +60,10 @@ object Lobby { val lobbyId = SupabaseLobbyHandler.createLobby(::onLobbyRowUpdate) this.lobbyId = lobbyId Gdx.app.log("Lobby", "Creating lobby with ID: $lobbyId...") + GameSettings.clientPlayerColor = PlayerColor.WHITE + GameSettings.opponentPlayerColor = PlayerColor.BLACK + GameSettings.isSecondPlayer = true + println("Player Color: ${GameSettings.clientPlayerColor}") } catch (e: Exception) { throw Exception("Problem when creating lobby! " + e.message) } diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseGameHandler.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseGameHandler.kt index 699550af..87ba08cc 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseGameHandler.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseGameHandler.kt @@ -20,6 +20,7 @@ import kotlinx.serialization.json.Json object SupabaseGameHandler { private val supabase = getSupabaseClient() private const val SUPABASE_GAME_TABLE_NAME = "games" + var sendingGameState = false suspend fun joinGame( lobbyCode: String, @@ -76,6 +77,18 @@ object SupabaseGameHandler { SupabaseChannelManager.unsubscribeFromChannel("game_$lobbyCode") } + suspend fun deleteGameRow(lobbyCode: String) { + try { + supabase.from(SUPABASE_GAME_TABLE_NAME).delete { + filter { + eq("lobby_code", lobbyCode) + } + } + } catch (e: PostgrestRestException) { + throw e + } + } + suspend fun requestRematch(lobbyCode: String) { try { val response = diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/InputSystem.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/InputSystem.kt index 598e5b37..865fadd1 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/InputSystem.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/InputSystem.kt @@ -15,6 +15,8 @@ import io.github.chessevolved.components.SelectionComponent import io.github.chessevolved.components.WeatherEventComponent import io.github.chessevolved.data.Position import io.github.chessevolved.singletons.EcsEngine +import io.github.chessevolved.singletons.Game +import io.github.chessevolved.singletons.GameSettings class InputSystem : IteratingSystem( @@ -98,6 +100,9 @@ class InputSystem : class InputService { fun clickPieceAtPosition(position: Position) { + println("piece clicked") + if (Game.getCurrentTurn() != GameSettings.clientPlayerColor) return + val entity = EcsEngine .getEntitiesFor(Family.all(PieceTypeComponent::class.java).get()) @@ -107,6 +112,7 @@ class InputService { } fun clickBoardSquareAtPosition(position: Position) { + println("boardsquare clicked") val entity = EcsEngine .getEntitiesFor(Family.all(WeatherEventComponent::class.java).get()) diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/SelectionEntityListener.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/SelectionEntityListener.kt index c2e06c92..284d326a 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/SelectionEntityListener.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/SelectionEntityListener.kt @@ -14,6 +14,7 @@ import io.github.chessevolved.components.PositionComponent import io.github.chessevolved.components.ValidMovesComponent import io.github.chessevolved.components.WeatherEventComponent import io.github.chessevolved.singletons.EcsEngine +import io.github.chessevolved.singletons.GameSettings class SelectionEntityListener( private val boardSize: Int, @@ -35,6 +36,10 @@ class SelectionEntityListener( piece.remove(CanBeCapturedComponent::class.java) } + if (PlayerColorComponent.mapper.get(entity).color != GameSettings.clientPlayerColor) { + return + } + val availablePositions = moveValidator.checkAvailablePositions( PlayerColorComponent.mapper.get(entity).color, diff --git a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/Navigator.kt b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/Navigator.kt index fecc3324..83238c1e 100644 --- a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/Navigator.kt +++ b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/Navigator.kt @@ -69,11 +69,13 @@ class Navigator( } fun goBack() { + print("${PresenterManager.getCurrent()} before") if (!PresenterManager.isEmpty()) { PresenterManager.pop() } if (PresenterManager.isEmpty()) { PresenterManager.push(createMenuPresenter()) } + print("${PresenterManager.getCurrent()} after") } } diff --git a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/EndGamePresenter.kt b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/EndGamePresenter.kt index 1f209383..2758dba5 100644 --- a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/EndGamePresenter.kt +++ b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/EndGamePresenter.kt @@ -19,6 +19,7 @@ class EndGamePresenter( private var otherPlayerLeft = false init { + println("${Game.isInGame()} init") Game.subscribeToGameUpdates(this.toString(), ::onGameUpdate) endGameView.endGameStatus = endGameStatus endGameView.init() @@ -27,6 +28,7 @@ class EndGamePresenter( } private fun requestRematch() { + println("${Game.isInGame()} rematch") endGameView.disableRematchButton() endGameView.updateRematchText("Rematch request\nsent...") runBlocking { @@ -37,6 +39,7 @@ class EndGamePresenter( } private fun returnToMenu() { + println("${Game.isInGame()} returntomenu") runBlocking { launch { val wantsRematch = Game.getWantsRematch() @@ -66,18 +69,27 @@ class EndGamePresenter( } override fun dispose() { + println("${Game.isInGame()} dispose") // Denne e false.... Noe leavea gamen alt for tidlig endGameView.dispose() Game.unsubscribeFromGameUpdates(this.toString()) + // Both isInGame and isInLobby must be checked here + // game and lobby is being left somewhere else leading to a fatal error if not checked runBlocking { launch { val wantsRematch = Game.getWantsRematch() - Game.leaveGame() + if (Game.isInGame()) { + Game.leaveGame() + } + // TODO: This logic doesn't work as of yet. In further iterations, this would be priority. if (wantsRematch && !otherPlayerLeft) { - Lobby.leaveLobbyWithoutUpdating() + // TODO: Need to discern between a player that leaves the rematch-screen, and a player that goes from rematch-screen to a lobby. + // Lobby.leaveLobbyWithoutUpdating() } else { - Lobby.leaveLobby() + if (Lobby.isInLobby()) { + // Lobby.leaveLobby() + } } } } @@ -88,6 +100,7 @@ class EndGamePresenter( } fun onGameUpdate(updatedGame: GameDto) { + println("${Game.isInGame()} gameupdate") if (updatedGame.wantRematch) { if (!Game.getWantsRematch()) { otherPlayerHasAskedForRematch = true @@ -109,7 +122,7 @@ class EndGamePresenter( } else { runBlocking { launch { - Game.leaveGame() + Game.deleteGame() Lobby.joinRematchLobbyAsHost() } } diff --git a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt index 5238a303..ad01607b 100644 --- a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt +++ b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt @@ -13,6 +13,8 @@ import com.badlogic.gdx.utils.viewport.Viewport import io.github.chessevolved.Navigator import io.github.chessevolved.components.AbilityCardComponent import io.github.chessevolved.components.AbilityComponent +import io.github.chessevolved.components.PieceTypeComponent +import io.github.chessevolved.components.PlayerColorComponent import io.github.chessevolved.components.SelectionComponent import io.github.chessevolved.components.TextureRegionComponent import io.github.chessevolved.data.Position @@ -28,7 +30,9 @@ import io.github.chessevolved.singletons.EcsEntityMapper import io.github.chessevolved.singletons.Game import io.github.chessevolved.singletons.Game.subscribeToGameUpdates import io.github.chessevolved.singletons.Game.unsubscribeFromGameUpdates +import io.github.chessevolved.singletons.GameSettings import io.github.chessevolved.singletons.Lobby +import io.github.chessevolved.singletons.supabase.SupabaseGameHandler import io.github.chessevolved.systems.AbilitySystem import io.github.chessevolved.systems.CaptureSystem import io.github.chessevolved.systems.FowRenderingSystem @@ -42,6 +46,7 @@ import io.github.chessevolved.views.GameUIView import io.github.chessevolved.views.GameView import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import ktx.graphics.color class GamePresenter( private val navigator: Navigator, @@ -136,7 +141,8 @@ class GamePresenter( AbilityType.entries.forEach { ability -> val abilityName = ability.name.lowercase() - assetManager.load("abilities/$abilityName-card.png", Texture::class.java) + println("abilities/cards/${abilityName}Card.png") + assetManager.load("abilities/cards/${abilityName}Card.png", Texture::class.java) } } @@ -147,8 +153,7 @@ class GamePresenter( } } - // TODO: Pass in if the player is the white player or not. - gameUIView = GameUIView(gameUIViewport, true, ::onSelectAbilityCardButtonClicked) + gameUIView = GameUIView(gameUIViewport, GameSettings.clientPlayerColor == PlayerColor.WHITE, ::onSelectAbilityCardButtonClicked) gameUIView.init() gameBoardView = GameView(gameUIView.getStage(), gameViewport) @@ -180,17 +185,15 @@ class GamePresenter( for (startPos in startX until startX + 8) { pieceFactory .createPawn( - true, Position(startPos, 1), - PlayerColor.WHITE, + GameSettings.clientPlayerColor, gameStage, ) pieceFactory .createPawn( - false, Position(startPos, boardWorldSize - 2), - PlayerColor.BLACK, + GameSettings.opponentPlayerColor, gameStage, ) } @@ -202,13 +205,13 @@ class GamePresenter( for (j in listOf(0, 7)) { pieceFactory.createRook( Position(startXLocal + j, 0), - PlayerColor.WHITE, + GameSettings.clientPlayerColor, gameStage, ) pieceFactory.createRook( Position(startXLocal + j, boardWorldSize - 1), - PlayerColor.BLACK, + GameSettings.opponentPlayerColor, gameStage, ) } @@ -217,13 +220,13 @@ class GamePresenter( for (j in listOf(1, 6)) { pieceFactory.createKnight( Position(startXLocal + j, 0), - PlayerColor.WHITE, + GameSettings.clientPlayerColor, gameStage, ) pieceFactory.createKnight( Position(startXLocal + j, boardWorldSize - 1), - PlayerColor.BLACK, + GameSettings.opponentPlayerColor, gameStage, ) } @@ -232,13 +235,13 @@ class GamePresenter( for (j in listOf(2, 5)) { pieceFactory.createBishop( Position(startXLocal + j, 0), - PlayerColor.WHITE, + GameSettings.clientPlayerColor, gameStage, ) pieceFactory.createBishop( Position(startXLocal + j, boardWorldSize - 1), - PlayerColor.BLACK, + GameSettings.opponentPlayerColor, gameStage, ) } @@ -246,26 +249,26 @@ class GamePresenter( startXLocal + 3 -> { pieceFactory.createQueen( Position(startPos, 0), - PlayerColor.WHITE, + GameSettings.clientPlayerColor, gameStage, ) pieceFactory.createQueen( Position(startPos, boardWorldSize - 1), - PlayerColor.BLACK, + GameSettings.opponentPlayerColor, gameStage, ) } startXLocal + 4 -> { pieceFactory.createKing( Position(startPos, 0), - PlayerColor.WHITE, + GameSettings.clientPlayerColor, gameStage, ) pieceFactory.createKing( Position(startPos, boardWorldSize - 1), - PlayerColor.BLACK, + GameSettings.opponentPlayerColor, gameStage, ) } @@ -314,19 +317,8 @@ class GamePresenter( gameBatch.dispose() engine.removeAllEntities() unloadAssets() + println("$this") unsubscribeFromGameUpdates(this.toString()) - if (Game.isInGame() && !navigatingToEndGame) { - runBlocking { - launch { - try { - Game.leaveGame() - Lobby.leaveLobby() - } catch (e: Exception) { - error("Non fatal error: Problem with calling leaveGame(). Error: " + e.message) - } - } - } - } } private fun unloadAssets() { @@ -349,7 +341,7 @@ class GamePresenter( } AbilityType.entries.forEach { ability -> val abilityName = ability.name.lowercase() - val filename = "abilities/$abilityName-card.png" + val filename = "abilities/cards/${abilityName}Card.png" if (assetManager.isLoaded(filename)) { assetManager.unload(filename) } @@ -431,7 +423,35 @@ class GamePresenter( val pieces = gameDto.pieces val boardSquares = gameDto.boardSquares - EcsEntityMapper.applyStateToEngine(engine, pieceFactory, gameStage, pieces, boardSquares) + if (SupabaseGameHandler.sendingGameState) { + SupabaseGameHandler.sendingGameState = false + + val kings = pieces.filter { it.type == PieceType.KING } + + if (kings.size != 2) { + val winningColor = kings[0].color + Gdx.app.postRunnable { + goToGameOverScreen(winningColor == GameSettings.clientPlayerColor) + } + } + + return + } + + Gdx.app.postRunnable { + EcsEntityMapper.applyStateToEngine(engine, pieceFactory, gameStage, pieces, boardSquares) + + val kings = + EcsEngine.getEntitiesFor(Family.all(PieceTypeComponent::class.java).get()).filter { + PieceTypeComponent.mapper.get(it).type == PieceType.KING + } + + if (kings.size != 2) { + val winningColor = kings.get(0).getComponent(PlayerColorComponent::class.java).color + + goToGameOverScreen(winningColor == GameSettings.clientPlayerColor) + } + } } private fun onTurnComplete() { @@ -439,6 +459,8 @@ class GamePresenter( launch { val (pieces, boardSquares) = EcsEntityMapper.extractStateFromEngine(engine) + SupabaseGameHandler.sendingGameState = true + Game.updateGameState( Lobby.getLobbyId()!!, pieces,