All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.robocode.tankroyale.gui.ui.newbattle.NewBattleDialog.kt Maven / Gradle / Ivy

package dev.robocode.tankroyale.gui.ui.newbattle

import dev.robocode.tankroyale.gui.ui.MainFrame
import dev.robocode.tankroyale.gui.client.Client
import dev.robocode.tankroyale.gui.model.BotInfo
import dev.robocode.tankroyale.gui.settings.ConfigSettings
import dev.robocode.tankroyale.gui.settings.GamesSettings
import dev.robocode.tankroyale.gui.ui.Hints
import dev.robocode.tankroyale.gui.ui.components.RcDialog
import dev.robocode.tankroyale.gui.ui.config.SetupRulesDialog
import dev.robocode.tankroyale.gui.ui.extensions.JComponentExt.addButton
import dev.robocode.tankroyale.gui.ui.extensions.JComponentExt.addLabel
import dev.robocode.tankroyale.gui.ui.Strings
import dev.robocode.tankroyale.gui.ui.extensions.JComponentExt.addCancelButton
import dev.robocode.tankroyale.gui.util.Event
import net.miginfocom.swing.MigLayout
import java.awt.Dimension
import java.awt.event.ItemEvent
import javax.swing.*

object NewBattleDialog : RcDialog(MainFrame, "select_bots_dialog") {

    private val selectBotsAndStartPanel = NewBattlePanel()

    init {
        contentPane.add(selectBotsAndStartPanel)
        size = Dimension(950, 750)
        setLocationRelativeTo(MainFrame) // center on main window
    }
}

class NewBattlePanel : JPanel(MigLayout("fill", "[]", "[][grow][][]")) {

    private val onStartBattle = Event()
    private val onCancel = Event()
    private val onSetupRules = Event()

    private val startBattleButton: JButton

    private var selectedBots = emptyList()
    private var gameTypeDropdown = GameTypeDropdown()

    init {
        val topPanel = JPanel(MigLayout("left, insets 5")).apply {
            border = BorderFactory.createTitledBorder(Strings.get("select_game_type"))

            val hint = Hints.get("new_battle.game_type")
            addLabel("game_type").apply {
                toolTipText = hint
            }
            gameTypeDropdown.toolTipText = hint
            add(gameTypeDropdown)

            addButton("setup_rules", onSetupRules).apply {
                toolTipText = Hints.get("new_battle.setup_rules")
            }
        }

        val buttonPanel = JPanel(MigLayout("center, insets 0"))

        add(topPanel, "wrap")
        add(BotSelectionPanel, "grow, wrap")
        add(BotInfoPanel, "grow, wrap")
        add(buttonPanel, "center")

        buttonPanel.apply {
            startBattleButton = addButton("start_battle", onStartBattle)
            addCancelButton(onCancel)
        }
        startBattleButton.isEnabled = false
        updateStartButtonHint()

        BotSelectionEvents.onSelectedBotListUpdated.subscribe(this) {
            selectedBots = it

            val selectedCount = calcNumberOfParticipants(it)
            val maxParticipants = maxNumberOfParticipants()

            startBattleButton.isEnabled = selectedCount >= minNumberOfParticipants() &&
                    (maxParticipants == null || selectedCount <= maxParticipants)
        }

        onStartBattle.subscribe(this) { startGame() }
        onCancel.subscribe(this) { NewBattleDialog.dispose() }
        onSetupRules.subscribe(this) { SetupRulesDialog.isVisible = true }

        gameTypeDropdown.apply {
            addActionListener {
                ConfigSettings.apply {
                    gameType = gameTypeDropdown.getSelectedGameType()
                    save()
                }
                updateStartButtonHint()
            }

            addItemListener {
                if (it.stateChange == ItemEvent.SELECTED) {
                    BotSelectionPanel.update()
                }
            }
        }

        BotSelectionPanel.update()
    }

    // Calculate the number of participants (team of bots) and individual bots
    private fun calcNumberOfParticipants(bots: Collection): Int {

        data class Participant(val name: String, val version: String, val id: Int? = null)

        val participants = HashSet()
        var fakeId = 1

        bots.forEach {
            participants.add(
                if (it.teamId != null) {
                    Participant(it.teamName!!, it.teamVersion!!, it.teamId)
                } else {
                    Participant(it.name, it.version, fakeId++)
                }
            )
        }
        return participants.size
    }

    private fun minNumberOfParticipants(): Int =
        GamesSettings.games[ConfigSettings.gameType.displayName]?.minNumberOfParticipants ?: 2

    private fun maxNumberOfParticipants(): Int? =
        GamesSettings.games[ConfigSettings.gameType.displayName]?.maxNumberOfParticipants

    private fun updateStartButtonHint() {
        startBattleButton.toolTipText = Hints.get("new_battle.start_button")
            .format(minNumberOfParticipants(), maxNumberOfParticipants()?.toString() ?: Strings.get("unlimited"))
    }

    private fun startGame() {
        isVisible = true

        val botAddresses = selectedBots.map { it.botAddress }
        Client.startGame(botAddresses.toSet())

        NewBattleDialog.dispose()
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy