mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-04 15:27:50 +07:00
Friends list (#7020)
* created files for friends list screen * redone #3 * fixed some crashes and more additions * changelog in the comment below * Update .gitignore included the FriendsList.json file * changelog in the comment below, again * optimized imports to hopefully fix the error in github build check * replaced imports with the ones from master since OnlineMultiplayer.kt no longer exists * imported ViewFriendsList * used the right package for all friendsList related files and a little bit of cleanup * check if friends list is empty before adding the select friend button * check if the ID is correct when adding a new friend * don't set null as playerID if no friend is selected * added messageTexts for the input TextFields * don't show already selected friends * fixed checkmark not updating after selecting a friend * you can't be your own friend! and other checks for edit button * fix error * replaced error type with enum, replaced nested ifs with when loop, added additional checks when editing friends * fixed error, can't really tell how I managed to do this * reorganized checks for adding and created settings variable to hopefully fix the github build error * actually fixed github error * it now removes selected friends from the list of selectable friends * fixed not being able to change only the id of a friend * made it look half decent * cleanup + improved help button * updated template.properties * renamed variable * some tweaks * moved friends list to GameSettings * tested every feature and fixed what didn't work * removed redundant variables and final cleanup * little improvements * string improvements * removed rightSideButton from ViewFriendsListScreen * removed unnecesary uniformX and decreased padding to allow seeing more friends in ViewFriendsListScreen
This commit is contained in:
85
core/src/com/unciv/logic/multiplayer/FriendList.kt
Normal file
85
core/src/com/unciv/logic/multiplayer/FriendList.kt
Normal file
@ -0,0 +1,85 @@
|
||||
package com.unciv.logic.multiplayer
|
||||
|
||||
import com.unciv.UncivGame
|
||||
|
||||
class FriendList {
|
||||
private val settings = UncivGame.Current.settings
|
||||
var friendList = settings.multiplayer.friendList
|
||||
|
||||
enum class ErrorType {
|
||||
NOERROR,
|
||||
NAME,
|
||||
ID,
|
||||
NONAME,
|
||||
NOID,
|
||||
YOURSELF,
|
||||
ALREADYINLIST;
|
||||
}
|
||||
|
||||
data class Friend(val name: String, val playerID: String) {
|
||||
constructor() : this("", "")
|
||||
}
|
||||
|
||||
fun add(friendName: String, playerID: String): ErrorType {
|
||||
for(index in friendList.indices){
|
||||
if (friendList[index].name == friendName) {
|
||||
return ErrorType.NAME
|
||||
} else if (friendList[index].playerID == playerID) {
|
||||
return ErrorType.ID
|
||||
}
|
||||
}
|
||||
if (friendName == "") {
|
||||
return ErrorType.NONAME
|
||||
} else if (playerID == "") {
|
||||
return ErrorType.NOID
|
||||
} else if (playerID == UncivGame.Current.settings.multiplayer.userId) {
|
||||
return ErrorType.YOURSELF
|
||||
}
|
||||
friendList.add(Friend(friendName, playerID))
|
||||
settings.save()
|
||||
return ErrorType.NOERROR
|
||||
}
|
||||
|
||||
fun edit(friend: Friend, name: String, playerID: String) {
|
||||
friendList.remove(friend)
|
||||
val editedFriend = Friend(name,playerID)
|
||||
friendList.add(editedFriend)
|
||||
settings.save()
|
||||
}
|
||||
|
||||
fun delete(friend: Friend) {
|
||||
friendList.remove(friend)
|
||||
settings.save()
|
||||
}
|
||||
|
||||
fun getFriendsList(): MutableList<Friend> {
|
||||
return friendList
|
||||
}
|
||||
|
||||
fun isFriendNameInFriendList(name: String): ErrorType {
|
||||
for (index in friendList.indices) {
|
||||
if (name == friendList[index].name) {
|
||||
return ErrorType.ALREADYINLIST
|
||||
}
|
||||
}
|
||||
return ErrorType.NOERROR
|
||||
}
|
||||
|
||||
fun isFriendIDInFriendList(id: String): ErrorType {
|
||||
for (index in friendList.indices) {
|
||||
if (id == friendList[index].playerID) {
|
||||
return ErrorType.ALREADYINLIST
|
||||
}
|
||||
}
|
||||
return ErrorType.NOERROR
|
||||
}
|
||||
|
||||
fun getFriendWithId(id: String): Friend? {
|
||||
for (index in friendList.indices) {
|
||||
if (id == friendList[index].playerID) {
|
||||
return friendList[index]
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import com.badlogic.gdx.Application
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.multiplayer.FriendList
|
||||
import com.unciv.ui.utils.Fonts
|
||||
import java.text.Collator
|
||||
import java.time.Duration
|
||||
@ -159,6 +160,7 @@ enum class LocaleCode(var language: String, var country: String) {
|
||||
class GameSettingsMultiplayer {
|
||||
var userId = ""
|
||||
var server = Constants.dropboxMultiplayerServer
|
||||
var friendList: MutableList<FriendList.Friend> = mutableListOf()
|
||||
var turnCheckerEnabled = true
|
||||
var turnCheckerPersistentNotificationEnabled = true
|
||||
var turnCheckerDelay = Duration.ofMinutes(5)
|
||||
|
71
core/src/com/unciv/ui/multiplayer/AddFriendScreen.kt
Normal file
71
core/src/com/unciv/ui/multiplayer/AddFriendScreen.kt
Normal file
@ -0,0 +1,71 @@
|
||||
package com.unciv.ui.multiplayer
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField
|
||||
import com.unciv.logic.IdChecker
|
||||
import com.unciv.logic.multiplayer.FriendList
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import java.util.*
|
||||
|
||||
class AddFriendScreen(backScreen: ViewFriendsListScreen) : PickerScreen() {
|
||||
init {
|
||||
val friendNameTextField = TextField("", skin)
|
||||
val pastePlayerIDButton = "Paste player ID from clipboard".toTextButton()
|
||||
val playerIDTextField = TextField("", skin)
|
||||
val friendlist = FriendList()
|
||||
|
||||
topTable.add("Friend name".toLabel()).row()
|
||||
friendNameTextField.messageText = "Please input a name for your friend!".tr()
|
||||
topTable.add(friendNameTextField).pad(10f).padBottom(30f).width(stage.width/2).row()
|
||||
|
||||
pastePlayerIDButton.onClick {
|
||||
playerIDTextField.text = Gdx.app.clipboard.contents
|
||||
}
|
||||
|
||||
topTable.add("Player ID".toLabel()).row()
|
||||
val gameIDTable = Table()
|
||||
playerIDTextField.messageText = "Please input a player ID for your friend!".tr()
|
||||
gameIDTable.add(playerIDTextField).pad(10f).width(2*stage.width/3 - pastePlayerIDButton.width)
|
||||
gameIDTable.add(pastePlayerIDButton)
|
||||
topTable.add(gameIDTable).padBottom(30f).row()
|
||||
|
||||
//CloseButton Setup
|
||||
closeButton.setText("Back".tr())
|
||||
closeButton.onClick {
|
||||
backScreen.game.setScreen(backScreen)
|
||||
}
|
||||
|
||||
//RightSideButton Setup
|
||||
rightSideButton.setText("Add friend".tr())
|
||||
rightSideButton.enable()
|
||||
rightSideButton.onClick {
|
||||
try {
|
||||
UUID.fromString(IdChecker.checkAndReturnPlayerUuid(playerIDTextField.text))
|
||||
} catch (ex: Exception) {
|
||||
ToastPopup("Player ID is incorrect", this)
|
||||
return@onClick
|
||||
}
|
||||
|
||||
when (friendlist.add(friendNameTextField.text, playerIDTextField.text)) {
|
||||
FriendList.ErrorType.NAME -> ToastPopup("Friend name is already in your friends list!", this)
|
||||
|
||||
FriendList.ErrorType.ID -> ToastPopup("Player ID is already in your friends list!", this)
|
||||
|
||||
FriendList.ErrorType.NONAME -> ToastPopup("You have to write a name for your friend!", this)
|
||||
|
||||
FriendList.ErrorType.NOID -> ToastPopup("You have to write an ID for your friend!", this)
|
||||
|
||||
FriendList.ErrorType.YOURSELF -> ToastPopup("You cannot add your own player ID in your friend list!", this)
|
||||
|
||||
else -> {
|
||||
backScreen.game.setScreen(backScreen)
|
||||
backScreen.refreshFriendsList()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
85
core/src/com/unciv/ui/multiplayer/EditFriendScreen.kt
Normal file
85
core/src/com/unciv/ui/multiplayer/EditFriendScreen.kt
Normal file
@ -0,0 +1,85 @@
|
||||
package com.unciv.ui.multiplayer
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField
|
||||
import com.unciv.logic.IdChecker
|
||||
import com.unciv.logic.multiplayer.FriendList
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.popup.YesNoPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import java.util.*
|
||||
|
||||
class EditFriendScreen(selectedFriend: FriendList.Friend, backScreen: ViewFriendsListScreen) : PickerScreen() {
|
||||
init {
|
||||
val friendNameTextField = TextField(selectedFriend.name, skin)
|
||||
val pastePlayerIDButton = "Player ID from clipboard".toTextButton()
|
||||
val playerIDTextField = TextField(selectedFriend.playerID, skin)
|
||||
val deleteFriendButton = "Delete".toTextButton()
|
||||
val friendlist = FriendList()
|
||||
|
||||
topTable.add("Friend name".toLabel()).row()
|
||||
friendNameTextField.messageText = "Please input a name for your friend!".tr()
|
||||
topTable.add(friendNameTextField).pad(10f).padBottom(30f).width(stage.width/2).row()
|
||||
|
||||
pastePlayerIDButton.onClick {
|
||||
playerIDTextField.text = Gdx.app.clipboard.contents
|
||||
}
|
||||
|
||||
topTable.add("Player ID".toLabel()).row()
|
||||
val gameIDTable = Table()
|
||||
playerIDTextField.messageText = "Please input a player ID for your friend!".tr()
|
||||
gameIDTable.add(playerIDTextField).pad(10f).width(2*stage.width/3 - pastePlayerIDButton.width)
|
||||
gameIDTable.add(pastePlayerIDButton)
|
||||
topTable.add(gameIDTable).padBottom(30f).row()
|
||||
|
||||
deleteFriendButton.onClick {
|
||||
val askPopup = YesNoPopup("Are you sure you want to delete this friend?", {
|
||||
friendlist.delete(selectedFriend)
|
||||
backScreen.game.setScreen(backScreen)
|
||||
backScreen.refreshFriendsList()
|
||||
}, this)
|
||||
askPopup.open()
|
||||
}.apply { color = Color.RED }
|
||||
topTable.add(deleteFriendButton)
|
||||
|
||||
//CloseButton Setup
|
||||
closeButton.setText("Back".tr())
|
||||
closeButton.onClick {
|
||||
backScreen.game.setScreen(backScreen)
|
||||
}
|
||||
|
||||
//RightSideButton Setup
|
||||
rightSideButton.setText("Save".tr())
|
||||
rightSideButton.enable()
|
||||
rightSideButton.onClick {
|
||||
// if no edits have been made, go back to friends list
|
||||
if (selectedFriend.name == friendNameTextField.text && selectedFriend.playerID == playerIDTextField.text) {
|
||||
backScreen.game.setScreen(backScreen)
|
||||
backScreen.refreshFriendsList()
|
||||
}
|
||||
if (friendlist.isFriendNameInFriendList(friendNameTextField.text) == FriendList.ErrorType.ALREADYINLIST
|
||||
&& friendlist.isFriendIDInFriendList(playerIDTextField.text) == FriendList.ErrorType.ALREADYINLIST) {
|
||||
ToastPopup("Player name already used!", this)
|
||||
return@onClick
|
||||
}
|
||||
if (friendlist.isFriendIDInFriendList(playerIDTextField.text) == FriendList.ErrorType.ALREADYINLIST
|
||||
&& friendlist.isFriendNameInFriendList(friendNameTextField.text) == FriendList.ErrorType.ALREADYINLIST) {
|
||||
ToastPopup("Player ID already used!", this)
|
||||
return@onClick
|
||||
}
|
||||
try {
|
||||
UUID.fromString(IdChecker.checkAndReturnPlayerUuid(playerIDTextField.text))
|
||||
} catch (ex: Exception) {
|
||||
ToastPopup("Player ID is incorrect", this)
|
||||
return@onClick
|
||||
}
|
||||
friendlist.edit(selectedFriend, friendNameTextField.text, playerIDTextField.text)
|
||||
backScreen.game.setScreen(backScreen)
|
||||
backScreen.refreshFriendsList()
|
||||
}
|
||||
}
|
||||
}
|
@ -34,6 +34,9 @@ class MultiplayerScreen(previousScreen: BaseScreen) : PickerScreen() {
|
||||
private val copyUserIdText = "Copy user ID"
|
||||
private val copyUserIdButton = createCopyUserIdButton()
|
||||
|
||||
private val friendsListText = "Friends List"
|
||||
private val friendsListButton = createFriendsListButton()
|
||||
|
||||
private val refreshText = "Refresh list"
|
||||
private val refreshButton = createRefreshButton()
|
||||
|
||||
@ -74,6 +77,7 @@ class MultiplayerScreen(previousScreen: BaseScreen) : PickerScreen() {
|
||||
table.add(copyGameIdButton).row()
|
||||
table.add(editButton).row()
|
||||
table.add(addGameButton).padBottom(30f).row()
|
||||
table.add(friendsListButton).padBottom(30f).row()
|
||||
table.add(refreshButton).row()
|
||||
return table
|
||||
}
|
||||
@ -112,6 +116,14 @@ class MultiplayerScreen(previousScreen: BaseScreen) : PickerScreen() {
|
||||
return btn
|
||||
}
|
||||
|
||||
fun createFriendsListButton(): TextButton {
|
||||
val btn = friendsListText.toTextButton()
|
||||
btn.onClick {
|
||||
game.setScreen(ViewFriendsListScreen(this))
|
||||
}
|
||||
return btn
|
||||
}
|
||||
|
||||
private fun createCopyUserIdButton(): TextButton {
|
||||
val btn = copyUserIdText.toTextButton()
|
||||
btn.onClick {
|
||||
|
82
core/src/com/unciv/ui/multiplayer/ViewFriendsListScreen.kt
Normal file
82
core/src/com/unciv/ui/multiplayer/ViewFriendsListScreen.kt
Normal file
@ -0,0 +1,82 @@
|
||||
package com.unciv.ui.multiplayer
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*
|
||||
import com.unciv.logic.multiplayer.FriendList
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||
|
||||
class ViewFriendsListScreen(previousScreen: BaseScreen) : PickerScreen() {
|
||||
private val rightSideTable = Table()
|
||||
private val leftSideTable = Table()
|
||||
private var friendsTable = Table()
|
||||
|
||||
private val addFriendButton = "Add friend".toTextButton()
|
||||
private val editFriendButton = "Edit friend".toTextButton()
|
||||
|
||||
private val friendsList = FriendList().getFriendsList()
|
||||
private var listOfFriendsButtons = arrayListOf<TextButton>()
|
||||
|
||||
private lateinit var selectedFriend: FriendList.Friend
|
||||
|
||||
init {
|
||||
setDefaultCloseAction(previousScreen)
|
||||
rightSideButton.remove()
|
||||
|
||||
//Help Button Setup
|
||||
val tab = Table()
|
||||
val helpButton = "Help".toTextButton()
|
||||
helpButton.onClick {
|
||||
val helpPopup = Popup(this)
|
||||
helpPopup.addGoodSizedLabel("To add a friend, ask him to send you his player ID.\nClick the 'Add friend' button.\nInsert his player ID and a name for him.\nThen click the 'Add friend' button again.\n\nAfter that you will see him in your friends list.\n\nA new button will appear when creating a new\nmultiplayer game, which allows you to select your friend.").row()
|
||||
|
||||
helpPopup.addCloseButton()
|
||||
helpPopup.open()
|
||||
}
|
||||
tab.add(helpButton)
|
||||
tab.x = (stage.width - helpButton.width)
|
||||
tab.y = (stage.height - helpButton.height)
|
||||
stage.addActor(tab)
|
||||
|
||||
val mainTable = Table()
|
||||
mainTable.add(ScrollPane(leftSideTable).apply { setScrollingDisabled(true, false) }).height(stage.height * 2 / 3)
|
||||
mainTable.add(rightSideTable)
|
||||
topTable.add(mainTable).row()
|
||||
scrollPane.setScrollingDisabled(false, true)
|
||||
|
||||
rightSideTable.defaults().fillX()
|
||||
rightSideTable.defaults().pad(20.0f)
|
||||
|
||||
addFriendButton.onClick {
|
||||
game.setScreen(AddFriendScreen(this))
|
||||
}
|
||||
rightSideTable.add(addFriendButton).padBottom(10f).row()
|
||||
|
||||
editFriendButton.onClick {
|
||||
game.setScreen(EditFriendScreen(selectedFriend,this))
|
||||
editFriendButton.disable()
|
||||
}
|
||||
rightSideTable.add(editFriendButton).padBottom(30f).row()
|
||||
editFriendButton.disable()
|
||||
|
||||
refreshFriendsList()
|
||||
}
|
||||
|
||||
fun refreshFriendsList() {
|
||||
listOfFriendsButtons.clear()
|
||||
friendsTable.clear()
|
||||
|
||||
for (index in friendsList.indices) {
|
||||
listOfFriendsButtons.add(friendsList[index].name.toTextButton())
|
||||
|
||||
listOfFriendsButtons[index].onClick {
|
||||
selectedFriend = friendsList[index]
|
||||
editFriendButton.enable()
|
||||
}
|
||||
friendsTable.add(listOfFriendsButtons[index]).padBottom(10f).row()
|
||||
}
|
||||
leftSideTable.clear()
|
||||
leftSideTable.add(friendsTable)
|
||||
}
|
||||
}
|
38
core/src/com/unciv/ui/newgamescreen/FriendTable.kt
Normal file
38
core/src/com/unciv/ui/newgamescreen/FriendTable.kt
Normal file
@ -0,0 +1,38 @@
|
||||
package com.unciv.ui.newgamescreen
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.Constants
|
||||
import com.unciv.logic.multiplayer.FriendList
|
||||
import com.unciv.ui.utils.*
|
||||
|
||||
class FriendTable(val friend: FriendList.Friend, width: Float, minHeight: Float)
|
||||
: Table() {
|
||||
val innerTable = Table()
|
||||
|
||||
init {
|
||||
val innerColor = Color.WHITE//because 0xFFFFFFFF doesn't work for some reason
|
||||
val totalPadding = 30f
|
||||
val internalWidth = width - totalPadding
|
||||
|
||||
val titleTable = Table()
|
||||
|
||||
val titleText = friend.name
|
||||
val friendDisplayNameMaxWidth = internalWidth - 70f // for the friend indicator with padding
|
||||
val friendDisplayLabel = WrappableLabel(titleText, friendDisplayNameMaxWidth, innerColor, Constants.headingFontSize)
|
||||
if (friendDisplayLabel.prefWidth > friendDisplayNameMaxWidth - 2f) {
|
||||
friendDisplayLabel.wrap = true
|
||||
titleTable.add(friendDisplayLabel).width(friendDisplayNameMaxWidth)
|
||||
} else {
|
||||
titleTable.add(friendDisplayLabel).align(Align.center).pad(10f,0f)
|
||||
}
|
||||
|
||||
innerTable.add(titleTable).growX().fillY().row()
|
||||
|
||||
add(innerTable).width(width).minHeight(minHeight - totalPadding)
|
||||
|
||||
touchable = Touchable.enabled
|
||||
}
|
||||
}
|
@ -28,7 +28,6 @@ import java.net.URL
|
||||
import java.util.*
|
||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||
|
||||
|
||||
class NewGameScreen(
|
||||
private val previousScreen: BaseScreen,
|
||||
_gameSetupInfo: GameSetupInfo? = null
|
||||
|
@ -22,6 +22,7 @@ import com.unciv.ui.audio.MusicMood
|
||||
import com.unciv.ui.audio.MusicTrackChooserFlags
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.mapeditor.GameParametersScreen
|
||||
import com.unciv.logic.multiplayer.FriendList
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.utils.*
|
||||
@ -46,6 +47,7 @@ class PlayerPickerTable(
|
||||
): Table() {
|
||||
val playerListTable = Table()
|
||||
val civBlocksWidth = if(blockWidth <= 10f) previousScreen.stage.width / 3 - 5f else blockWidth
|
||||
val friendsBlocksWidth = if(blockWidth <= 10f) previousScreen.stage.width / 5 - 5f else blockWidth / 2
|
||||
|
||||
/** Locks player table for editing, currently unused, was previously used for scenarios and could be useful in the future.*/
|
||||
var locked = false
|
||||
@ -53,6 +55,8 @@ class PlayerPickerTable(
|
||||
/** No random civilization is available, used during map editing.*/
|
||||
var noRandom = false
|
||||
|
||||
private val friendList = FriendList()
|
||||
|
||||
init {
|
||||
for (player in gameParameters.players)
|
||||
player.playerId = "" // This is to stop people from getting other users' IDs and cheating with them in multiplayer games
|
||||
@ -174,6 +178,7 @@ class PlayerPickerTable(
|
||||
errorLabel.apply { setText("✘");setFontColor(Color.RED) }
|
||||
}
|
||||
}
|
||||
onPlayerIdTextUpdated()
|
||||
|
||||
playerIdTextField.addListener { onPlayerIdTextUpdated(); true }
|
||||
val currentUserId = UncivGame.Current.settings.multiplayer.userId
|
||||
@ -189,7 +194,16 @@ class PlayerPickerTable(
|
||||
playerIdTextField.text = Gdx.app.clipboard.contents
|
||||
onPlayerIdTextUpdated()
|
||||
}
|
||||
playerTable.add(copyFromClipboardButton).colspan(3).fillX().pad(5f)
|
||||
playerTable.add(copyFromClipboardButton).right().colspan(3).fillX().pad(5f).row()
|
||||
|
||||
//check if friends list is empty before adding the select friend button
|
||||
if (friendList.friendList.isNotEmpty()) {
|
||||
val selectPlayerFromFriendsList = "Player ID from friends list".toTextButton()
|
||||
selectPlayerFromFriendsList.onClick {
|
||||
popupFriendPicker(player)
|
||||
}
|
||||
playerTable.add(selectPlayerFromFriendsList).left().colspan(3).fillX().pad(5f)
|
||||
}
|
||||
}
|
||||
|
||||
return playerTable
|
||||
@ -216,6 +230,17 @@ class PlayerPickerTable(
|
||||
return nationTable
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens Friend picking popup with all friends,
|
||||
* currently available for [player] to choose, depending on current
|
||||
* friends list and if another friend is selected.
|
||||
* @param player current player
|
||||
*/
|
||||
private fun popupFriendPicker(player: Player) {
|
||||
FriendPickerPopup(this, player).open()
|
||||
update()
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens Nation picking popup with all nations,
|
||||
* currently available for [player] to choose, depending on current
|
||||
@ -241,6 +266,119 @@ class PlayerPickerTable(
|
||||
.filter { it.isMajorCiv() }
|
||||
.filter { it.name == dontSkipNation || gameParameters.players.none { player -> player.chosenCiv == it.name } }
|
||||
|
||||
/**
|
||||
* Returns a list of available friends.
|
||||
* Skips friends already chosen.
|
||||
*
|
||||
* @return [Sequence] of available [FriendList.Friend]s
|
||||
*/
|
||||
internal fun getAvailableFriends(): Sequence<FriendList.Friend> {
|
||||
val friendListWithRemovedFriends = friendList.friendList.toMutableList()
|
||||
for (index in gameParameters.players.indices) {
|
||||
val currentFriendId = previousScreen.gameSetupInfo.gameParameters.players[index].playerId
|
||||
friendListWithRemovedFriends.remove(friendList.getFriendWithId(currentFriendId))
|
||||
}
|
||||
return friendListWithRemovedFriends.asSequence()
|
||||
}
|
||||
}
|
||||
|
||||
private class FriendPickerPopup(
|
||||
private val playerPicker: PlayerPickerTable,
|
||||
private val player: Player
|
||||
) : Popup(playerPicker.previousScreen as BaseScreen) {
|
||||
companion object {
|
||||
// These are used for the Close/OK buttons in the lower left/right corners:
|
||||
const val buttonsCircleSize = 70f
|
||||
const val buttonsIconSize = 50f
|
||||
const val buttonsOffsetFromEdge = 5f
|
||||
val buttonsBackColor: Color = Color.BLACK.cpy().apply { a = 0.67f }
|
||||
}
|
||||
|
||||
// This Popup's body has two halves of same size, either side by side or arranged vertically
|
||||
// depending on screen proportions - determine height for one of those
|
||||
private val partHeight = screen.stage.height * (if (screen.isNarrowerThan4to3()) 0.3f else 0.4f)
|
||||
private val friendsBlocksWidth = playerPicker.friendsBlocksWidth
|
||||
private val friendListTable = Table()
|
||||
private val friendListScroll = ScrollPane(friendListTable)
|
||||
private val friendDetailsTable = Table()
|
||||
private val friendDetailsScroll = ScrollPane(friendDetailsTable)
|
||||
var selectedFriend: FriendList.Friend? = null
|
||||
|
||||
init {
|
||||
friendListScroll.setOverscroll(false, false)
|
||||
add(friendListScroll).size( friendsBlocksWidth + 10f, partHeight )
|
||||
// +10, because the friend table has a 5f pad, for a total of +10f
|
||||
if (screen.isNarrowerThan4to3()) row()
|
||||
friendDetailsScroll.setOverscroll(false, false)
|
||||
add(friendDetailsScroll).size(friendsBlocksWidth + 10f, partHeight) // Same here, see above
|
||||
|
||||
val friends = ArrayList<FriendList.Friend>()
|
||||
|
||||
friends += playerPicker.getAvailableFriends()
|
||||
|
||||
var friendsListScrollY = 0f
|
||||
var currentY = 0f
|
||||
for (friend in friends) {
|
||||
val friendTable = FriendTable(friend, friendsBlocksWidth, 0f) // no need for min height
|
||||
val cell = friendListTable.add(friendTable)
|
||||
cell.padTop(20f)
|
||||
currentY += cell.padBottom + cell.prefHeight + cell.padTop
|
||||
cell.row()
|
||||
friendTable.onClick {
|
||||
setFriendDetails(friend)
|
||||
}
|
||||
}
|
||||
|
||||
friendListScroll.layout()
|
||||
pack()
|
||||
if (friendsListScrollY > 0f) {
|
||||
// center the selected friend vertically, getRowHeight safe because friendListScrollY > 0f ensures at least 1 row
|
||||
friendsListScrollY -= (friendListScroll.height - friendListTable.getRowHeight(0)) / 2
|
||||
friendListScroll.scrollY = friendsListScrollY.coerceIn(0f, friendListScroll.maxY)
|
||||
}
|
||||
|
||||
val closeButton = "OtherIcons/Close".toImageButton(Color.FIREBRICK)
|
||||
closeButton.onClick { close() }
|
||||
closeButton.setPosition(buttonsOffsetFromEdge, buttonsOffsetFromEdge, Align.bottomLeft)
|
||||
innerTable.addActor(closeButton)
|
||||
keyPressDispatcher[KeyCharAndCode.BACK] = { close() }
|
||||
|
||||
val okButton = "OtherIcons/Checkmark".toImageButton(Color.LIME)
|
||||
okButton.onClick { returnSelected() }
|
||||
okButton.setPosition(innerTable.width - buttonsOffsetFromEdge, buttonsOffsetFromEdge, Align.bottomRight)
|
||||
innerTable.addActor(okButton)
|
||||
|
||||
friendDetailsTable.touchable = Touchable.enabled
|
||||
friendDetailsTable.onClick { returnSelected() }
|
||||
}
|
||||
|
||||
private fun String.toImageButton(overColor: Color): Group {
|
||||
val style = ImageButton.ImageButtonStyle()
|
||||
val image = ImageGetter.getDrawable(this)
|
||||
style.imageUp = image
|
||||
style.imageOver = image.tint(overColor)
|
||||
val button = ImageButton(style)
|
||||
button.setSize(buttonsIconSize, buttonsIconSize)
|
||||
|
||||
return button.surroundWithCircle(buttonsCircleSize, false, buttonsBackColor)
|
||||
}
|
||||
|
||||
private fun setFriendDetails(friend: FriendList.Friend) {
|
||||
friendDetailsTable.clearChildren() // .clear() also clears listeners!
|
||||
|
||||
friendDetailsTable.add(FriendTable(friend, friendsBlocksWidth, partHeight))
|
||||
selectedFriend = friend
|
||||
}
|
||||
|
||||
fun returnSelected() {
|
||||
if (selectedFriend == null) {
|
||||
close()
|
||||
return
|
||||
}
|
||||
player.playerId = selectedFriend?.playerID.toString()
|
||||
close()
|
||||
playerPicker.update()
|
||||
}
|
||||
}
|
||||
|
||||
private class NationPickerPopup(
|
||||
|
Reference in New Issue
Block a user