Skip to content

added 2 unique to change name/appearance of civ #13105

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 80 commits into from

Conversation

Emandac
Copy link
Contributor

@Emandac Emandac commented Mar 27, 2025

Draft PR to change name/appearance of civ using 2 different unique.

-NOTE i must write a doc on how this works for the modders

…of running away

Settler unit will now settle on best tile in dangerous Tiles without escort instead of running away.
with "Founds a new puppet city" in "uniques" of an unit in Units.json.
Making it so you can now settle a puppet city.
@@ -176,7 +177,7 @@ internal class NationPickerPopup(

// Decide by listMode how each block is built -
// for each a factory producing an Actor and info on how to select it
fun getListModeNationActor(element: NationIterationElement): Pair<WidgetGroup, SelectInfo> {
fun getListModeNationActor(element: NationIterationElement): Pair<NationTable, SelectInfo> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems unrelated. A simple explanation probably?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should change it back 😅

@@ -215,7 +216,7 @@ internal class NationPickerPopup(

for (element in getSortedNations()) {
val (nationActor, currentSelectInfo) = nationActorFactory(element)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More trailing blanks. You don't let Android Studio clean them for you?
At least Ctrl-R, check regex, search=[ \t]+$, replace with ``, Replace all... Only in the files you worked on of course.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use intelij 😅

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surely has a comparable setting as it's the same thing just different wrapping.

Copy link
Contributor Author

@Emandac Emandac Mar 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though i didn't manage to remove the white space with it but
It was still useful to replace displayCivName to getDisplayCivName() :D

@@ -238,7 +239,7 @@ internal class NationPickerPopup(
nationListTable.keyShortcuts.add(key) { onKeyPress(key) }
}
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😬

@SomeTroglodyte
Copy link
Collaborator

I agree with Yair's assessment that changing the "foreign key" relation between a Civ and its Nation mid-game opens a dangerous can of worms1. But: With enough warning, why not offer modders a potentially game-breaking tool? No, I'd vote against it because a stable decoupling of Civ and Nation without a mid-game change should come first 1. DisplayName is a first step. Abstracting appearance would be the next. Separating the "primary key" (which then could be anything, including a simple integer) of the Civ from its "Nation pointer key" another - at this point we could allow more than one Civ to play the same nation.

If you want to only change icon, colors, leader portrait and such, a "DisplayNation" might work. We'll then soon wish for a "unplayable" Unique to get true appearance-only Nations...

Footnotes

  1. Think about how to support the concept of one Nation, several available Leaders as in certain non-5 Civ's. 2

@Emandac
Copy link
Contributor Author

Emandac commented Mar 27, 2025

So tomorrow I will remove the appearance unique, and remove the white spaces.

@Emandac
Copy link
Contributor Author

Emandac commented Mar 27, 2025

DisplayNation should be in it own file ?

@SomeTroglodyte
Copy link
Collaborator

The check you're failing is this unit test. You know you can debug them, right? But this one might be the first "Nope" I commented. Didn't really switch on brain, sorry. Or it may be related to the next point below, and to the fact that your constructor change is not guaranteed to always initialize the new field same as civName - deserialization uses the no-args constructor. So yes loading a save from a prior version pretty much guarantees trouble?

Idea: Initialize displayName as null. Gdx.Json will recognize the default and save space in the saved game unless it's actually set. Good for backwards compatibility too. Then, make the getter private too so all access will return displayName ?: civName instead. Now cloning is harder, so just make it a private field with explicit getter and setter... Can't explain well. Maybe as example:

Nice idea but needs sharp thinking because cloning would go through the getter and setter (but serialization/deserialization would not):

    var displayName: String? = null
        get() = field ?: civName
        set(value) { field = if (value == civName) null else value }

Safer:

    private var displayName: String? = null
    fun getDisplayName() = displayName ?: civName
    fun setDisplayName(value: String) { displayName = if (value == civName) null else value }

@SomeTroglodyte
Copy link
Collaborator

DisplayNation should be in it own file ?

Whut? Why? I imagined a new field in Civilization pretty much ticking the same way as displayName, not a new class.

@SomeTroglodyte
Copy link
Collaborator

The barest start to that DisplayNation idea would be:

Index: core/src/com/unciv/ui/screens/diplomacyscreen/LeaderIntroTable.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/src/com/unciv/ui/screens/diplomacyscreen/LeaderIntroTable.kt b/core/src/com/unciv/ui/screens/diplomacyscreen/LeaderIntroTable.kt
--- a/core/src/com/unciv/ui/screens/diplomacyscreen/LeaderIntroTable.kt	(revision b0f427a4469ca11a5f4e712d11cdde74bf0252a2)
+++ b/core/src/com/unciv/ui/screens/diplomacyscreen/LeaderIntroTable.kt	(date 1719508388471)
@@ -27,7 +27,7 @@
      */
     init {
         defaults().align(Align.center)
-        val nation = civInfo.nation
+        val nation = civInfo.getDisplayNation()
         val leaderPortraitFile = "LeaderIcons/" + nation.leaderName
         val leaderLabel = civInfo.getLeaderDisplayName().toLabel(fontSize = Constants.headingFontSize, hideIcons = true)
         val nationIndicator = ImageGetter.getNationPortrait(nation, 24f)
Index: core/src/com/unciv/ui/screens/worldscreen/topbar/WorldScreenTopBar.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/src/com/unciv/ui/screens/worldscreen/topbar/WorldScreenTopBar.kt b/core/src/com/unciv/ui/screens/worldscreen/topbar/WorldScreenTopBar.kt
--- a/core/src/com/unciv/ui/screens/worldscreen/topbar/WorldScreenTopBar.kt	(revision b0f427a4469ca11a5f4e712d11cdde74bf0252a2)
+++ b/core/src/com/unciv/ui/screens/worldscreen/topbar/WorldScreenTopBar.kt	(date 1734877708753)
@@ -235,7 +235,7 @@
             if (this.selectedCiv == newCiv) return
             this.selectedCiv = newCiv
 
-            selectedCivIcon = ImageGetter.getNationPortrait(worldScreen.selectedCiv.nation, 25f)
+            selectedCivIcon = ImageGetter.getNationPortrait(worldScreen.selectedCiv.getDisplayNation(), 25f)
             selectedCivIconCell.setActor(selectedCivIcon)
             selectedCivLabel.setText(newCiv.tr(hideIcons = true))
             invalidate()
Index: core/src/com/unciv/logic/civilization/Civilization.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/src/com/unciv/logic/civilization/Civilization.kt b/core/src/com/unciv/logic/civilization/Civilization.kt
--- a/core/src/com/unciv/logic/civilization/Civilization.kt	(revision b0f427a4469ca11a5f4e712d11cdde74bf0252a2)
+++ b/core/src/com/unciv/logic/civilization/Civilization.kt	(date 1743097917215)
@@ -157,6 +157,11 @@
     var civName = ""
         private set
 
+    private var displayNation: String? = null
+    fun getDisplayNationName() = displayNation ?: civName
+    fun getDisplayNation() = if (displayNation == null) nation else gameInfo.ruleset.nations[displayNation] ?: nation
+    fun setDisplayNation(value: String) { displayNation = if (value == civName) null else value }
+
     var tech = TechManager()
     var policies = PolicyManager()
     var civConstructions = CivConstructions()
@@ -305,6 +310,7 @@
         toReturn.hasMovedAutomatedUnits = hasMovedAutomatedUnits
         toReturn.statsHistory = statsHistory.clone()
         toReturn.resourceStockpiles = resourceStockpiles.clone()
+        toReturn.displayNation = displayNation
         return toReturn
     }

... You'd still need to find a ton of places where e.g. the nation colors are used - units on the map, city buttons,... Also, one would need to evaluate whether caching the getDisplayNation() result as transient would be advisable, if so the field's name isn't the best choice ...

Emandac added 9 commits March 28, 2025 19:43
 change setNationTransient from displayCivName to civName.
change NationTable back to WidgetGroup for getListModeNationActor.
remove white spaces.
And disable ChangeCivilizationNation because it's i will refactor it later.
To only change the color of a civ to a dummy civ
this function updates civ color to the unique if there is for that era
@Emandac
Copy link
Contributor Author

Emandac commented Apr 13, 2025

The only downside is that the modders have to create a dummy civ at the start era that has the default color of the civ.
to not get the other color era civ while loading up a old savefile

@Emandac
Copy link
Contributor Author

Emandac commented Apr 14, 2025

Nvm I fixed it

Copy link

This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days.

Copy link

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions github-actions bot removed the Stale label Jun 18, 2025
Copy link

github-actions bot commented Aug 2, 2025

This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days.

@github-actions github-actions bot added the Stale label Aug 2, 2025
Copy link

This PR was closed because it has been stalled for 10 days with no activity.

@github-actions github-actions bot closed this Aug 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants