diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/components/AbilityTriggerComponent.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/components/AbilityTriggerComponent.kt index 25c0b53..83a5f1b 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/components/AbilityTriggerComponent.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/components/AbilityTriggerComponent.kt @@ -8,6 +8,7 @@ class AbilityTriggerComponent( // The position of where the trigger happens val targetPosition: Position, val oldPosition: Position, + val isActive: Boolean, ) : Component { companion object { val mapper: ComponentMapper = 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 3e9d3c6..59489f3 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 @@ -24,28 +24,8 @@ class AbilityItemFactory( } fun createAbilityItem(abilityType: AbilityType): Entity { - var cooldown: Int = 3 - - when (abilityType) { - AbilityType.SHIELD -> { - cooldown = 3 - } - AbilityType.EXPLOSION -> { - cooldown = 2 - } - AbilityType.SWAP -> { - cooldown = 2 - } - AbilityType.MIRROR -> { - cooldown = 3 - } - AbilityType.NEW_MOVEMENT -> { - cooldown = 0 - } - } - return Entity().apply { - add(AbilityComponent(abilityType, cooldown, 0)) + add(AbilityComponent(abilityType, abilityType.cooldownTime, 0)) add(AbilityCardComponent()) add(TextureRegionComponent(getAbilityItemTexture(abilityType))) engine.addEntity(this) 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 0cd6500..d9d41ea 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 @@ -1,9 +1,12 @@ package io.github.chessevolved.singletons import com.badlogic.ashley.core.Engine +import com.badlogic.ashley.core.Entity import com.badlogic.ashley.core.Family import com.badlogic.gdx.Gdx import com.badlogic.gdx.scenes.scene2d.Stage +import io.github.chessevolved.components.AbilityComponent +import io.github.chessevolved.components.AbilityTriggerComponent import io.github.chessevolved.components.ActorComponent import io.github.chessevolved.components.PieceTypeComponent import io.github.chessevolved.components.PlayerColorComponent @@ -33,20 +36,30 @@ object EcsEntityMapper { .get() fun extractStateFromEngine(engine: Engine): Pair, List> { - val pieces = - engine.getEntitiesFor(pieceFamily).map { entity -> - val piecePosition = PositionComponent.mapper.get(entity) + val pieces: ArrayList = ArrayList() + for ((_, value) in Game.getPieceDTOS()) { + val pieceDto = PieceDto( position = Position( - piecePosition.position.x, - GameSettings.getBoardSize() - 1 - piecePosition.position.y, + value.position.x, + GameSettings.getBoardSize() - 1 - value.position.y, ), - type = PieceTypeComponent.mapper.get(entity).type, - color = PlayerColorComponent.mapper.get(entity).color, + previousPosition = + Position( + value.previousPosition.x, + GameSettings.getBoardSize() - 1 - value.previousPosition.y, + ), + type = value.type, + color = value.color, + abilityType = value.abilityType, + abilityCurrentCooldown = value.abilityCurrentCooldown, ) - } + + pieces.add(pieceDto) + } + var amount = 0 val boardSquares = engine.getEntitiesFor(boardSquareFamily).map { entity -> @@ -87,8 +100,20 @@ object EcsEntityMapper { if (typeComp.type != receivedPiece.type || colorComp.color != receivedPiece.color) { Gdx.app.debug("ECSEntityMapper", "Replacing piece at ${receivedPiece.position} due to type/color mismatch.") engine.removeEntity(existingEntity) + Game.removeEntityFromPieceDTOS(existingEntity) createPieceFromDto(pieceFactory, stage, receivedPiece) } + + if (receivedPiece.abilityType != null) { + existingEntity.add( + AbilityComponent( + receivedPiece.abilityType!!, + receivedPiece.abilityType!!.cooldownTime, + receivedPiece.abilityCurrentCooldown, + ), + ) + existingEntity.add(AbilityTriggerComponent(receivedPiece.position, receivedPiece.position, false)) + } } else { Gdx.app.debug("ECSEntityMapper", "Creating new piece: ${receivedPiece.type} at ${receivedPiece.position}") createPieceFromDto(pieceFactory, stage, receivedPiece) @@ -98,11 +123,14 @@ object EcsEntityMapper { for (existingEntity in existingPieceEntities) { val pos = PositionComponent.mapper.get(existingEntity).position if (pos !in currentPositions) { + // Most likely it was this that moved. We can trigger the new entity through movement system. Gdx.app.debug("ECSEntityMapper", "Removing piece no longer in state at $pos") val actorComponent = ActorComponent.mapper.get(existingEntity) actorComponent.actor.remove() + + Game.removeEntityFromPieceDTOS(existingEntity) + engine.removeEntity(existingEntity) - println("ActorComp: $actorComponent") } } @@ -140,13 +168,28 @@ object EcsEntityMapper { stage: Stage, pieceData: PieceDto, ) { + val pieceEntity: Entity + when (pieceData.type) { - 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) - PieceType.QUEEN -> pieceFactory.createQueen(pieceData.position, pieceData.color, stage) - PieceType.KING -> pieceFactory.createKing(pieceData.position, pieceData.color, stage) + PieceType.PAWN -> pieceEntity = pieceFactory.createPawn(pieceData.position, pieceData.color, stage) + PieceType.ROOK -> pieceEntity = pieceFactory.createRook(pieceData.position, pieceData.color, stage) + PieceType.KNIGHT -> pieceEntity = pieceFactory.createKnight(pieceData.position, pieceData.color, stage) + PieceType.BISHOP -> pieceEntity = pieceFactory.createBishop(pieceData.position, pieceData.color, stage) + PieceType.QUEEN -> pieceEntity = pieceFactory.createQueen(pieceData.position, pieceData.color, stage) + PieceType.KING -> pieceEntity = pieceFactory.createKing(pieceData.position, pieceData.color, stage) + } + + pieceEntity.apply { + if (pieceData.abilityType != null) { + add(AbilityComponent(pieceData.abilityType!!, pieceData.abilityType!!.cooldownTime, pieceData.abilityCurrentCooldown)) + println("CREATEPIECEFROMDTO: THIS ONE GETS TRIGGERED") + add(AbilityTriggerComponent(pieceData.position, pieceData.previousPosition, true)) + } } + + println("Ability: ${pieceData.abilityType}") + println("AbilityCD: ${pieceData.abilityCurrentCooldown}") + + Game.addPieceDTOS(pieceEntity) } } 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 73a2bd1..af23385 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 @@ -1,8 +1,15 @@ package io.github.chessevolved.singletons +import com.badlogic.ashley.core.Entity +import io.github.chessevolved.components.AbilityComponent +import io.github.chessevolved.components.PieceTypeComponent +import io.github.chessevolved.components.PlayerColorComponent +import io.github.chessevolved.components.PositionComponent +import io.github.chessevolved.data.Position import io.github.chessevolved.dtos.BoardSquareDto import io.github.chessevolved.dtos.GameDto import io.github.chessevolved.dtos.PieceDto +import io.github.chessevolved.enums.AbilityType import io.github.chessevolved.enums.PlayerColor import io.github.chessevolved.singletons.supabase.SupabaseGameHandler import io.github.chessevolved.singletons.supabase.SupabaseLobbyHandler @@ -12,6 +19,9 @@ object Game { private var subscribers = mutableMapOf Unit>() private var hasAskedForRematch = false private var currentTurn: PlayerColor? = null + var turnNumber: Int = 0 + + private var pieceDTOS: MutableMap = mutableMapOf() suspend fun joinGame(gameId: String) { try { @@ -101,4 +111,54 @@ object Game { subscribers.remove(subscriberName) } + + fun getPieceDTOS(): MutableMap { + return pieceDTOS + } + + fun addPieceDTOS(entity: Entity) { + val pieceDTO = + PieceDto( + position = PositionComponent.mapper.get(entity).position, + previousPosition = PositionComponent.mapper.get(entity).position, + type = PieceTypeComponent.mapper.get(entity).type, + color = PlayerColorComponent.mapper.get(entity).color, + abilityType = AbilityComponent.mapper.get(entity)?.ability, + abilityCurrentCooldown = + if (AbilityComponent.mapper.get(entity) != null) { + AbilityComponent.mapper.get( + entity, + ).currentAbilityCDTime + } else { + 0 + }, + ) + + pieceDTOS[entity] = pieceDTO + } + + fun changePieceDTOPosition( + entity: Entity, + targetPosition: Position, + ) { + if (pieceDTOS.containsKey(entity)) { + pieceDTOS[entity]!!.previousPosition = pieceDTOS[entity]!!.position + pieceDTOS[entity]!!.position = targetPosition + } + } + + fun changePieceDTOAbility( + entity: Entity, + abilityType: AbilityType?, + abilityCurrentCooldown: Int, + ) { + if (pieceDTOS.containsKey(entity)) { + pieceDTOS[entity]!!.abilityType = abilityType + pieceDTOS[entity]!!.abilityCurrentCooldown = abilityCurrentCooldown + } + } + + fun removeEntityFromPieceDTOS(entity: Entity) { + pieceDTOS.remove(entity) + } } diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseClient.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseClient.kt index bc96500..3ef192f 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseClient.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseClient.kt @@ -19,9 +19,12 @@ internal object SupabaseClient { } private val supabase: SupabaseClient = + @Suppress("ktlint:standard:max-line-length") createSupabaseClient( - supabaseUrl = dotenv["SUPABASE_URL"] ?: "no_url_found", - supabaseKey = dotenv["SUPABASE_ANON_KEY"] ?: "no_pass_found", + supabaseUrl = "https://tsmubattgglbqaarktnw.supabase.co" ?: "no_url_found", + supabaseKey = + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InRzbXViYXR0Z2dsYnFhYXJrdG53Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDIwNTE5MzksImV4cCI6MjA1NzYyNzkzOX0.O7DqYVCmuvHa3iOvXl53SOaNu-N6Rfb3E3J1Cg5K4Dw" + ?: "no_pass_found", ) { install(Postgrest) install(Realtime) { diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/AbilitySystem.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/AbilitySystem.kt index dd307be..a1b36ee 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/AbilitySystem.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/AbilitySystem.kt @@ -18,6 +18,7 @@ import io.github.chessevolved.enums.AbilityType import io.github.chessevolved.enums.VisualEffectSize import io.github.chessevolved.enums.VisualEffectType import io.github.chessevolved.singletons.EcsEngine +import io.github.chessevolved.singletons.Game class AbilitySystem : IteratingSystem( @@ -30,11 +31,18 @@ class AbilitySystem : val abilityComponent = AbilityComponent.mapper.get(entity) val abilityTriggerComponent = AbilityTriggerComponent.mapper.get(entity) + println(EcsEngine.getEntitiesFor(Family.all(PieceTypeComponent::class.java, AbilityComponent::class.java).get())) + + println("Triggering ability: ${abilityComponent.ability}") + println("Ability CurrentCD: ${abilityComponent.currentAbilityCDTime}") + if (abilityComponent.currentAbilityCDTime <= 0) { abilityComponent.currentAbilityCDTime = abilityComponent.abilityCooldownTime + Game.changePieceDTOAbility(entity!!, abilityComponent.ability, abilityComponent.currentAbilityCDTime) } else { abilityComponent.currentAbilityCDTime-- - entity?.remove(AbilityTriggerComponent::class.java) + Game.changePieceDTOAbility(entity!!, abilityComponent.ability, abilityComponent.currentAbilityCDTime) + entity.remove(AbilityTriggerComponent::class.java) return } @@ -42,7 +50,10 @@ class AbilitySystem : AbilityType.EXPLOSION -> { // Since the trigger doesn't know if it was an active call or passive call. // It is the ability's job to determine. - if (CapturedComponent.mapper.get(entity) == null) { + println("Explosion: isActive? : ${abilityTriggerComponent.isActive}") + + if (abilityTriggerComponent.isActive && CapturedComponent.mapper.get(entity) == null) { + println("Cant enter here?") triggerExplosionEffect(entity, abilityTriggerComponent.targetPosition) } } @@ -54,7 +65,7 @@ class AbilitySystem : AbilityType.MIRROR -> {} } - entity?.remove(AbilityTriggerComponent::class.java) + entity.remove(AbilityTriggerComponent::class.java) } private fun triggerExplosionEffect( @@ -119,10 +130,12 @@ class AbilitySystem : EcsEngine.addEntity(effectEntity) } else if (shieldEffectEntity != null) { abilityComponent.currentAbilityCDTime = 0 + Game.changePieceDTOAbility(entity!!, abilityComponent.ability, abilityComponent.currentAbilityCDTime) PositionComponent.mapper.get(shieldEffectEntity).position = targetPosition } else { abilityComponent.currentAbilityCDTime = 0 - entity?.add(BlockedComponent()) + Game.changePieceDTOAbility(entity!!, abilityComponent.ability, abilityComponent.currentAbilityCDTime) + entity.add(BlockedComponent()) val effectEntity = EcsEngine.createEntity() effectEntity.add(VisualEffectComponent(VisualEffectType.SHIELD_ACTIVE, 3, duration = 0f, squareSize = VisualEffectSize.NORMAL)) diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/CaptureSystem.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/CaptureSystem.kt index 57c5b82..2e2ae2f 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/CaptureSystem.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/CaptureSystem.kt @@ -14,6 +14,7 @@ import io.github.chessevolved.components.PositionComponent import io.github.chessevolved.components.SelectionComponent import io.github.chessevolved.components.ValidMovesComponent import io.github.chessevolved.singletons.EcsEngine +import io.github.chessevolved.singletons.Game class CaptureSystem : IteratingSystem( Family.all(CapturedComponent::class.java).get(), @@ -38,9 +39,7 @@ class CaptureSystem : IteratingSystem( } if (capturedBlockedComponent != null) { - // Trigger the ability. - entity?.add(AbilityTriggerComponent(capturedPosition, capturedPosition)) - // entity?.remove(CapturedComponent::class.java) + entity?.add(AbilityTriggerComponent(capturedPosition, capturedPosition, false)) capturingPiece?.remove(SelectionComponent::class.java) capturingPiece?.remove(ValidMovesComponent::class.java) return @@ -56,6 +55,8 @@ class CaptureSystem : IteratingSystem( val actor = ActorComponent.mapper.get(entity).actor actor.remove() + Game.removeEntityFromPieceDTOS(entity!!) + EcsEngine.removeEntity(entity) } } 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 865fadd..14b6928 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 @@ -10,6 +10,7 @@ import io.github.chessevolved.components.CapturedComponent import io.github.chessevolved.components.ClickEventComponent import io.github.chessevolved.components.MovementIntentComponent import io.github.chessevolved.components.PieceTypeComponent +import io.github.chessevolved.components.PlayerColorComponent import io.github.chessevolved.components.PositionComponent import io.github.chessevolved.components.SelectionComponent import io.github.chessevolved.components.WeatherEventComponent @@ -49,7 +50,8 @@ class InputSystem : } else { if (selectedEntity != null && AbilityCardComponent.mapper.get(selectedEntity) != null && - AbilityCardComponent.mapper.get(selectedEntity).isInInventory + AbilityCardComponent.mapper.get(selectedEntity).isInInventory && + PlayerColorComponent.mapper.get(piece).color == GameSettings.clientPlayerColor ) { if (AbilityComponent.mapper.get(piece) != null) { println("Already has ability") @@ -66,7 +68,9 @@ class InputSystem : ) } - println("Ability got applied to piece!") + Game.changePieceDTOAbility(piece, abilityComponent.ability, abilityComponent.currentAbilityCDTime) + print("Ability got applied to piece!") + print(" For position: ${PositionComponent.mapper.get(piece).position}\n") selectedEntity.removeAll() // Remove abilityCard-entity from the game. } } else { diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/MovementSystem.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/MovementSystem.kt index 143dab1..5fe73e1 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/MovementSystem.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/MovementSystem.kt @@ -3,6 +3,7 @@ package io.github.chessevolved.systems import com.badlogic.ashley.core.Entity import com.badlogic.ashley.core.Family import com.badlogic.ashley.systems.IteratingSystem +import io.github.chessevolved.components.AbilityComponent import io.github.chessevolved.components.AbilityTriggerComponent import io.github.chessevolved.components.ActorComponent import io.github.chessevolved.components.FowComponent @@ -13,6 +14,7 @@ import io.github.chessevolved.components.SelectionComponent import io.github.chessevolved.components.ValidMovesComponent import io.github.chessevolved.data.Position import io.github.chessevolved.singletons.EcsEngine +import io.github.chessevolved.singletons.Game class MovementSystem( private val onTurnComplete: () -> Unit, @@ -43,10 +45,13 @@ class MovementSystem( } val piecePositionComponent = PositionComponent.mapper.get(entity) + val pieceActorComponent = ActorComponent.mapper.get(entity) val pieceMovementRuleComponent = MovementRuleComponent.mapper.get(entity) - entity?.add(AbilityTriggerComponent(targetPosition, piecePositionComponent.position)) + if (AbilityComponent.mapper.get(entity) != null) { + entity?.add(AbilityTriggerComponent(targetPosition, piecePositionComponent.position, true)) + } piecePositionComponent.position = targetPosition pieceActorComponent.actor.setPosition(targetPosition.x.toFloat(), targetPosition.y.toFloat()) @@ -63,6 +68,10 @@ class MovementSystem( entity?.remove(ValidMovesComponent::class.java) entity?.remove(MovementIntentComponent::class.java) + if (entity != null) { + Game.changePieceDTOPosition(entity, targetPosition) + } + onTurnComplete() } diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/RenderingSystem.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/RenderingSystem.kt index fcdb4e0..c9ef3bc 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/RenderingSystem.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/RenderingSystem.kt @@ -37,6 +37,8 @@ class RenderingSystem( batch.color = Color.WHITE } } + + // println("All: " + EcsEngine.getEntitiesFor(Family.all(AbilityTriggerComponent::class.java).get())) } // fun defaultBoardSquaresState() { 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 ad01607..7d10aee 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,11 +13,14 @@ 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.AbilityTriggerComponent import io.github.chessevolved.components.PieceTypeComponent import io.github.chessevolved.components.PlayerColorComponent +import io.github.chessevolved.components.PositionComponent import io.github.chessevolved.components.SelectionComponent import io.github.chessevolved.components.TextureRegionComponent import io.github.chessevolved.data.Position +import io.github.chessevolved.dtos.GameDto import io.github.chessevolved.entities.AbilityItemFactory import io.github.chessevolved.entities.BoardSquareFactory import io.github.chessevolved.entities.PieceFactory @@ -46,7 +49,6 @@ 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, @@ -60,12 +62,12 @@ class GamePresenter( private val gameCamera = OrthographicCamera() private val gameUICamera = OrthographicCamera() - private val boardWorldSize = 8 + private val boardWorldSize = GameSettings.getBoardSize() private val gameViewport: Viewport = FitViewport(boardWorldSize.toFloat(), boardWorldSize.toFloat(), gameCamera) private val gameUIViewport: Viewport = - FitViewport(Gdx.graphics.width.toFloat(), Gdx.graphics.height.toFloat(), gameUICamera) + FitViewport(500f, 500f / (Gdx.graphics.width.toFloat() / Gdx.graphics.height.toFloat()), gameUICamera) private lateinit var gameUIView: GameUIView private lateinit var gameBoardView: GameView private val gameBatch: SpriteBatch = SpriteBatch() @@ -119,10 +121,14 @@ class GamePresenter( resize(Gdx.graphics.width, Gdx.graphics.height) - val testAbilityCard = abilityItemFactory.createAbilityItem(AbilityType.EXPLOSION) - AbilityCardComponent.mapper.get(testAbilityCard).isInInventory = true +// val testAbilityCard = abilityItemFactory.createAbilityItem(AbilityType.EXPLOSION) +// AbilityCardComponent.mapper.get(testAbilityCard).isInInventory = true subscribeToGameUpdates(this.toString(), this::onGameStateUpdate) + +// abilityItemFactory.createAbilityItem(AbilityType.EXPLOSION) +// abilityItemFactory.createAbilityItem(AbilityType.SHIELD) +// abilityItemFactory.createAbilityItem(AbilityType.EXPLOSION) } private fun loadRequiredAssets() { @@ -181,96 +187,124 @@ class GamePresenter( } } - val startX: Int = (boardWorldSize / 2) - 4 - for (startPos in startX until startX + 8) { - pieceFactory - .createPawn( - Position(startPos, 1), - GameSettings.clientPlayerColor, - gameStage, - ) + val startXLocal: Int = (boardWorldSize / 2) - 4 + for (startPos in startXLocal until startXLocal + 8) { + val pawn1 = + pieceFactory + .createPawn( + Position(startPos, 1), + GameSettings.clientPlayerColor, + gameStage, + ) - pieceFactory - .createPawn( - Position(startPos, boardWorldSize - 2), - GameSettings.opponentPlayerColor, - gameStage, - ) + val pawn2 = + pieceFactory + .createPawn( + Position(startPos, boardWorldSize - 2), + GameSettings.opponentPlayerColor, + gameStage, + ) + Game.addPieceDTOS(pawn1) + Game.addPieceDTOS(pawn2) } - val startXLocal: Int = (boardWorldSize / 2) - 4 for (startPos in startXLocal until startXLocal + 8) { when (startPos) { startXLocal -> { for (j in listOf(0, 7)) { - pieceFactory.createRook( - Position(startXLocal + j, 0), - GameSettings.clientPlayerColor, - gameStage, - ) - - pieceFactory.createRook( - Position(startXLocal + j, boardWorldSize - 1), - GameSettings.opponentPlayerColor, - gameStage, - ) + val rook1 = + pieceFactory.createRook( + Position(startXLocal + j, 0), + GameSettings.clientPlayerColor, + gameStage, + ) + + val rook2 = + pieceFactory.createRook( + Position(startXLocal + j, boardWorldSize - 1), + GameSettings.opponentPlayerColor, + gameStage, + ) + + Game.addPieceDTOS(rook1) + Game.addPieceDTOS(rook2) } } startXLocal + 1 -> { for (j in listOf(1, 6)) { - pieceFactory.createKnight( - Position(startXLocal + j, 0), + val knight1 = + pieceFactory.createKnight( + Position(startXLocal + j, 0), + GameSettings.clientPlayerColor, + gameStage, + ) + + val knight2 = + pieceFactory.createKnight( + Position(startXLocal + j, boardWorldSize - 1), + GameSettings.opponentPlayerColor, + gameStage, + ) + + Game.addPieceDTOS(knight1) + Game.addPieceDTOS(knight2) + } + } + startXLocal + 2 -> { + for (j in listOf(2, 5)) { + val bishop1 = + pieceFactory.createBishop( + Position(startXLocal + j, 0), + GameSettings.clientPlayerColor, + gameStage, + ) + + val bishop2 = + pieceFactory.createBishop( + Position(startXLocal + j, boardWorldSize - 1), + GameSettings.opponentPlayerColor, + gameStage, + ) + + Game.addPieceDTOS(bishop1) + Game.addPieceDTOS(bishop2) + } + } + startXLocal + 3 -> { + val queen1 = + pieceFactory.createQueen( + Position(startPos, 0), GameSettings.clientPlayerColor, gameStage, ) - pieceFactory.createKnight( - Position(startXLocal + j, boardWorldSize - 1), + val queen2 = + pieceFactory.createQueen( + Position(startPos, boardWorldSize - 1), GameSettings.opponentPlayerColor, gameStage, ) - } + + Game.addPieceDTOS(queen1) + Game.addPieceDTOS(queen2) } - startXLocal + 2 -> { - for (j in listOf(2, 5)) { - pieceFactory.createBishop( - Position(startXLocal + j, 0), + startXLocal + 4 -> { + val king1 = + pieceFactory.createKing( + Position(startPos, 0), GameSettings.clientPlayerColor, gameStage, ) - pieceFactory.createBishop( - Position(startXLocal + j, boardWorldSize - 1), + val king2 = + pieceFactory.createKing( + Position(startPos, boardWorldSize - 1), GameSettings.opponentPlayerColor, gameStage, ) - } - } - startXLocal + 3 -> { - pieceFactory.createQueen( - Position(startPos, 0), - GameSettings.clientPlayerColor, - gameStage, - ) - - pieceFactory.createQueen( - Position(startPos, boardWorldSize - 1), - GameSettings.opponentPlayerColor, - gameStage, - ) - } - startXLocal + 4 -> { - pieceFactory.createKing( - Position(startPos, 0), - GameSettings.clientPlayerColor, - gameStage, - ) - pieceFactory.createKing( - Position(startPos, boardWorldSize - 1), - GameSettings.opponentPlayerColor, - gameStage, - ) + Game.addPieceDTOS(king1) + Game.addPieceDTOS(king2) } else -> {} } @@ -423,6 +457,8 @@ class GamePresenter( val pieces = gameDto.pieces val boardSquares = gameDto.boardSquares + gameUIView.changeTurnText(gameDto.turn) + if (SupabaseGameHandler.sendingGameState) { SupabaseGameHandler.sendingGameState = false @@ -438,9 +474,32 @@ class GamePresenter( return } + Game.turnNumber++ + checkAddAbilitiesUI() + Gdx.app.postRunnable { EcsEntityMapper.applyStateToEngine(engine, pieceFactory, gameStage, pieces, boardSquares) + EcsEngine + .getEntitiesFor( + Family.all(PieceTypeComponent::class.java, AbilityComponent::class.java).get(), + ).map { + val position = PositionComponent.mapper.get(it).position + val abilityComponent = AbilityComponent.mapper.get(it) + + var cooldown = abilityComponent.currentAbilityCDTime + + if (Game.getCurrentTurn() != GameSettings.clientPlayerColor) { + cooldown++ + } + + abilityComponent.currentAbilityCDTime = cooldown + + if (PlayerColorComponent.mapper.get(it).color == GameSettings.clientPlayerColor) { + it.add(AbilityTriggerComponent(position, position, false)) + } + } + val kings = EcsEngine.getEntitiesFor(Family.all(PieceTypeComponent::class.java).get()).filter { PieceTypeComponent.mapper.get(it).type == PieceType.KING @@ -460,12 +519,49 @@ class GamePresenter( val (pieces, boardSquares) = EcsEntityMapper.extractStateFromEngine(engine) SupabaseGameHandler.sendingGameState = true + Game.turnNumber++ + checkAddAbilitiesUI() Game.updateGameState( Lobby.getLobbyId()!!, pieces, boardSquares, ) + + EcsEngine + .getEntitiesFor( + Family.all(PieceTypeComponent::class.java, AbilityComponent::class.java).get(), + ).map { + val position = PositionComponent.mapper.get(it).position + val abilityComponent = AbilityComponent.mapper.get(it) + val abilityTriggerComponent = AbilityTriggerComponent.mapper.get(it) + + var cooldown = abilityComponent.currentAbilityCDTime + + if (abilityTriggerComponent == null) { + if (Game.getCurrentTurn() == GameSettings.clientPlayerColor) { + cooldown++ + } + + abilityComponent.currentAbilityCDTime = cooldown + + if (PlayerColorComponent.mapper.get(it).color == GameSettings.clientPlayerColor) { + it.add(AbilityTriggerComponent(position, position, false)) + } + } + } + } + } + } + + private fun checkAddAbilitiesUI() { + // Must keep this for now since we don't have all definitions for all abilities + val validAbilities = mutableListOf(AbilityType.EXPLOSION, AbilityType.SHIELD) + + if (Game.turnNumber % 4 == 0 && Game.turnNumber != 0) { + val chosenAbilities = List(3) { validAbilities.random() } + for (ability in chosenAbilities) { + abilityItemFactory.createAbilityItem(ability) } } } diff --git a/chessevolved_shared/src/main/kotlin/io/github/chessevolved/dtos/PieceDto.kt b/chessevolved_shared/src/main/kotlin/io/github/chessevolved/dtos/PieceDto.kt index 7b192a3..bbf80ac 100644 --- a/chessevolved_shared/src/main/kotlin/io/github/chessevolved/dtos/PieceDto.kt +++ b/chessevolved_shared/src/main/kotlin/io/github/chessevolved/dtos/PieceDto.kt @@ -1,13 +1,17 @@ package io.github.chessevolved.dtos import io.github.chessevolved.data.Position +import io.github.chessevolved.enums.AbilityType import io.github.chessevolved.enums.PieceType import io.github.chessevolved.enums.PlayerColor import kotlinx.serialization.Serializable @Serializable data class PieceDto( - val position: Position, + var position: Position, + var previousPosition: Position, val type: PieceType, val color: PlayerColor, + var abilityType: AbilityType?, + var abilityCurrentCooldown: Int = 0, ) diff --git a/chessevolved_shared/src/main/kotlin/io/github/chessevolved/enums/AbilityType.kt b/chessevolved_shared/src/main/kotlin/io/github/chessevolved/enums/AbilityType.kt index adb824b..64a32b7 100644 --- a/chessevolved_shared/src/main/kotlin/io/github/chessevolved/enums/AbilityType.kt +++ b/chessevolved_shared/src/main/kotlin/io/github/chessevolved/enums/AbilityType.kt @@ -2,10 +2,11 @@ package io.github.chessevolved.enums enum class AbilityType( val abilityDescription: String, + val cooldownTime: Int, ) { - SHIELD("Blocks attacks from opponent pieces"), - EXPLOSION("Causes an explosion around the tile that your piece moves to"), - SWAP("Swaps position with a non royal piece"), - MIRROR("Mirrors an ability used against this piece"), - NEW_MOVEMENT("No cluerino"), + SHIELD("Blocks attacks from opponent pieces", 3), + EXPLOSION("Causes an explosion around the tile that your piece moves to", 2), + SWAP("Swaps position with a non royal piece", 2), + MIRROR("Mirrors an ability used against this piece", 3), + NEW_MOVEMENT("No cluerino", 0), } diff --git a/chessevolved_view/src/main/kotlin/io/github/chessevolved/views/GameUIView.kt b/chessevolved_view/src/main/kotlin/io/github/chessevolved/views/GameUIView.kt index 8bbdf2d..4b40a10 100644 --- a/chessevolved_view/src/main/kotlin/io/github/chessevolved/views/GameUIView.kt +++ b/chessevolved_view/src/main/kotlin/io/github/chessevolved/views/GameUIView.kt @@ -11,9 +11,9 @@ import com.badlogic.gdx.scenes.scene2d.ui.ImageButton.ImageButtonStyle import com.badlogic.gdx.scenes.scene2d.ui.Label import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.TextButton -import com.badlogic.gdx.scenes.scene2d.ui.TextField import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable import com.badlogic.gdx.utils.viewport.Viewport +import io.github.chessevolved.enums.PlayerColor import ktx.actors.onClick import ktx.scene2d.imageButton import ktx.scene2d.label @@ -39,11 +39,10 @@ class GameUIView( private var promptedAmountOfPickableAbilities = 0 private lateinit var abilityCardInventory: Table private lateinit var abilityPickerWindow: Table - private lateinit var blackTimer: TextField - private lateinit var whiteTimer: TextField private lateinit var abilityDescriptionLabel: Label private lateinit var abilityInfoTable: Table private lateinit var pickAbilityButton: TextButton + private lateinit var turnText: Label data class AbilityCardInformation( val texture: Texture? = Texture(Gdx.files.internal("pieces/pawn-white.png")), @@ -55,16 +54,10 @@ class GameUIView( val blackInfoBox = scene2d.table { - textField(if (isWhitePlayer) "Black: Opponent" else "Black: You") { - color = blackColor + textField(if (isWhitePlayer) "Black: Opponent" else "White: Opponent") { + color = if (isWhitePlayer) blackColor else whiteColor isDisabled = true }.cell(growX = true) - - blackTimer = - textField("Time: 10:00") { - color = blackColor - isDisabled = true - } row() } @@ -103,15 +96,14 @@ class GameUIView( val whiteInfoBox = scene2d.table { - textField(if (isWhitePlayer) "White: You" else "White: Opponent") { - color = whiteColor + textField(if (isWhitePlayer) "White: You" else "Black: You") { + color = if (isWhitePlayer) whiteColor else blackColor isDisabled = true - }.cell(growX = true) - - whiteTimer = - textField("Time: 10:00") { - color = whiteColor - isDisabled = true + it.left() + }.cell() + turnText = + label("White's Turn") { + style.fontColor = whiteColor } } @@ -134,6 +126,7 @@ class GameUIView( pickAbilityButton = textButton("Select Ability") { onClick { onPickAbilityCardButtonClicked() } + isVisible = false }.cell(padTop = -10f) row() add(abilityCardInventory) @@ -240,14 +233,6 @@ class GameUIView( abilityCards[abilityCardId]?.height = sizeOfAbilityCards.toFloat() + 20f } - fun updateWhiteTimer(time: Int) { - whiteTimer.text = "Time: $time" - } - - fun updateBlackTimer(time: Int) { - blackTimer.text = "Time: $time" - } - override fun render() { stage.act(Gdx.graphics.deltaTime) stage.draw() @@ -269,5 +254,15 @@ class GameUIView( // Gdx.input.inputProcessor = stage } + fun changeTurnText(turn: PlayerColor) { + if (turn == PlayerColor.WHITE) { + turnText.setText("White's Turn") + turnText.color = Color.WHITE + } else { + turnText.setText("Black's Turn") + turnText.color = Color.WHITE + } + } + fun getStage() = stage }