Skip to content

Commit

Permalink
Merge branch 'C7-Game:Development' into kulkobsw/multiturn-irrigation
Browse files Browse the repository at this point in the history
  • Loading branch information
KulkoBSW authored Feb 15, 2025
2 parents 800f4fb + 82acab2 commit 4a8dfc1
Show file tree
Hide file tree
Showing 12 changed files with 365 additions and 12 deletions.
82 changes: 82 additions & 0 deletions C7/Text/c7-static-map-save.json
Original file line number Diff line number Diff line change
Expand Up @@ -64533,5 +64533,87 @@
"tech-44"
]
}
],
"citizenTypes": [
{
"id": "CitizenType-1",
"isDefaultCitizen": true,
"specialistIndex": 0,
"singularName": "Laborer",
"civilopediaEntry": "CTZN_Laborer",
"pluralName": "Laborers",
"luxuries": 0,
"research": 0,
"taxes": 0,
"corruption": 0,
"construction": 0
},
{
"id": "CitizenType-2",
"isDefaultCitizen": false,
"specialistIndex": 1,
"singularName": "Entertainer",
"civilopediaEntry": "CTZN_Entertainer",
"pluralName": "Entertainers",
"luxuries": 1,
"research": 0,
"taxes": 0,
"corruption": 0,
"construction": 0
},
{
"id": "CitizenType-3",
"isDefaultCitizen": false,
"specialistIndex": 2,
"singularName": "Tax Collector",
"civilopediaEntry": "CTZN_Tax_Collector",
"pluralName": "Tax Collectors",
"luxuries": 0,
"research": 0,
"taxes": 2,
"corruption": 0,
"construction": 0
},
{
"id": "CitizenType-4",
"isDefaultCitizen": false,
"specialistIndex": 3,
"singularName": "Scientist",
"civilopediaEntry": "CTZN_Scientist",
"pluralName": "Scientists",
"luxuries": 0,
"research": 3,
"taxes": 0,
"corruption": 0,
"construction": 0
},
{
"id": "CitizenType-5",
"isDefaultCitizen": false,
"specialistIndex": 4,
"singularName": "Policeman",
"civilopediaEntry": "CTZN_Laborer",
"pluralName": "Policemen",
"prerequisiteTech": "tech-44",
"luxuries": 0,
"research": 0,
"taxes": 0,
"corruption": 1,
"construction": 0
},
{
"id": "CitizenType-6",
"isDefaultCitizen": false,
"specialistIndex": 5,
"singularName": "Civil Engineer",
"civilopediaEntry": "CTZN_Laborer",
"pluralName": "Civil Engineers",
"prerequisiteTech": "tech-58",
"luxuries": 0,
"research": 0,
"taxes": 0,
"corruption": 0,
"construction": 2
}
]
}
97 changes: 94 additions & 3 deletions C7/UIElements/CityScreen/CityScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ public partial class CityScreen : CenterContainer {
private ILogger log = LogManager.ForContext<CityScreen>();
public TileAssignmentLayer tileAssignmentLayer;
public MapView mapView;
private TextureRect background;
private List<TextureButton> popHeads = new();

// Called when the node enters the scene tree for the first time.
public override void _Ready() {
TextureRect background = new() {
background = new() {
Texture = Util.LoadTextureFromPCX("Art/city screen/background.pcx")
};
AddChild(background);
Expand Down Expand Up @@ -48,15 +50,16 @@ public override void _UnhandledInput(InputEvent @event) {
using (UIGameDataAccess gameDataAccess = new()) {
Tile tile = mapView.tileOnScreenAt(gameDataAccess.gameData.map, eventMouseButton.Position);
if (tile != null) {
HandleReassignment(tile);
HandleReassignment(tile, gameDataAccess.gameData.citizenTypes);
RenderPopHeads(tileAssignmentLayer.city);
}
}
}
}
}
}

private void HandleReassignment(Tile tile) {
private void HandleReassignment(Tile tile, List<CitizenType> citizenTypes) {
City city = tileAssignmentLayer.city;

// We can't assign citizens to other cities.
Expand Down Expand Up @@ -99,6 +102,7 @@ private void HandleReassignment(Tile tile) {
worst.tileWorked.personWorkingTile = null;
worst.tileWorked = tile;
tile.personWorkingTile = worst;
worst.citizenType = citizenTypes.Find(x => x.IsDefaultCitizen);
return;
}

Expand All @@ -112,6 +116,7 @@ private void HandleReassignment(Tile tile) {

for (int i = 0; i < numResidents; ++i) {
CityResident newResident = new() {
citizenType = citizenTypes.Find(x => x.IsDefaultCitizen),
nationality = city.owner.civilization,
city = city
};
Expand All @@ -128,5 +133,91 @@ public void HideScreen() {
private void OnShowCityScreen(ParameterWrapper<City> city) {
this.Show();
tileAssignmentLayer.city = city.Value;
RenderPopHeads(city.Value);
}

private void RenderPopHeads(City city) {
// Reset any old heads.
foreach (TextureButton head in popHeads) {
background.RemoveChild(head);
head.QueueFree();
}
popHeads.Clear();

int eraNum = 0;
if (city.owner.eraCivilopediaName == "ERAS_Ancient_Times") {
eraNum = 0;
} else if (city.owner.eraCivilopediaName == "ERAS_Middle_Ages") {
eraNum = 1;
} else if (city.owner.eraCivilopediaName == "ERAS_Industrial_Age") {
eraNum = 2;
} else if (city.owner.eraCivilopediaName == "ERAS_Modern_Era") {
eraNum = 3;
}

// The pop head textures are 50 x 50, but have a 1px border on all sides
//
// The texture file has 16 rows of the default citizen, in groups of 4
// per era (content, happy, resisting, unhappy). There are 10 columns,
// the first 5 are male heads of different regions for civs, the other 5
// are female heads.
//
// After the 16 rows of default citizens there is one row per specialist
// type, and again 10 columns per row. This time they are
// (ancient, middle, industrial, modern, blank) for male and female heads
//
// TODO: handle citizen moods
// TODO: handle per-civ regions
// TODO: handle male/female citizens

// Start by splitting the default residents from the specialists, since
// they are spaced apart in the UI.
List<CityResident> defaultResidents = city.residents.FindAll(x => x.citizenType.IsDefaultCitizen);
List<CityResident> specialists = city.residents.FindAll(x => !x.citizenType.IsDefaultCitizen);

// Each head is 48px, so leave a 1 head gap if we have specialists.
int width = city.residents.Count * 48;
if (specialists.Count > 0) {
width += 48;
}

// Track the x position of each head so that we're centered in the screen
int xPos = background.Texture.GetWidth() / 2 + -width / 2;

// Add each of the default citizens. These are buttons with the idea that
// we can eventually support clicking on the heads to view details, such
// as the reason for unhappiness.
foreach (CityResident cr in defaultResidents) {
TextureButton tb = new();
tb.TextureNormal = Util.LoadTextureFromPCX("Art/SmallHeads/popHeads.pcx",
0 + 1, 200 * eraNum + 1, 48, 48);
tb.SetPosition(new Vector2(xPos, 440));
background.AddChild(tb);
popHeads.Add(tb);
xPos += 48;
}

// Add space before specialists.
xPos += 48;

// Add each of the specialists.
//
// TODO: When clicking a specialist, have it iterate through the types
// of specialists known to the player.
//
// TODO: Render the specialist effect (like a smiley for entertainers)
// in the corner of the head.
foreach (CityResident cr in specialists) {
TextureButton tb = new();
int textX = 50 * eraNum;
int numRowsOfLaborers = 16;
int textY = 50 * numRowsOfLaborers + 50 * (cr.citizenType.SpecialistIndex - 1);
tb.TextureNormal = Util.LoadTextureFromPCX("Art/SmallHeads/popHeads.pcx",
textX + 1, textY + 1, 48, 48);
tb.SetPosition(new Vector2(xPos, 440));
background.AddChild(tb);
popHeads.Add(tb);
xPos += 48;
}
}
}
1 change: 1 addition & 0 deletions C7Engine/EntryPoints/CityInteractions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public static City BuildCity(int X, int Y, ID playerID, string name) {
City newCity = new City(tileWithNewCity, owner, name, gameData.ids.CreateID("city"));
CityResident firstResident = new CityResident();
firstResident.city = newCity;
firstResident.citizenType = gameData.citizenTypes.Find(x => x.IsDefaultCitizen);
CityTileAssignmentAI.AssignNewCitizenToTile(firstResident);
newCity.SetItemBeingProduced(CityProductionAI.GetNextItemToBeProduced(newCity, null));
if (owner.cities.Count == 0) {
Expand Down
1 change: 1 addition & 0 deletions C7Engine/EntryPoints/TurnHandling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ private static void HandleCityResults(GameData gameData) {
CityResident newResident = new CityResident();
newResident.nationality = city.owner.civilization;
newResident.city = city;
newResident.citizenType = gameData.citizenTypes.Find(x => x.IsDefaultCitizen);
CityTileAssignmentAI.AssignNewCitizenToTile(newResident);
} else if (newSize < initialSize) {
int diff = initialSize - newSize;
Expand Down
45 changes: 45 additions & 0 deletions C7GameData/CitizenType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;
using System.Runtime.InteropServices;

namespace C7GameData {
public class CitizenType {
public ID Id;

// Should this citizen be the default?
public bool IsDefaultCitizen;

// If !IsDefaultCitizen, the index of this specialist, for looking up in
// popHeads.pcx. 0 is the first non-laborer row.
public int SpecialistIndex;

// Like "Laborer" or "Scientist"
public string SingularName;

public string CivilopediaEntry;

// Like "Laborers" or "Scientists"
public string PluralName;

// If non-null, the tech needed to use this citizen type.
public ID PrerequisiteTech;

// The contribution, in gold per turn, that this citizen makes towards
// luxuries/happiness.
public int Luxuries;

// The contribution, in beakers, that this citizen makes towards teching
public int Research;

// The contribution, in gold per turn, that this citizen makes towards
// the treasury.
public int Taxes;

// TODO: Figure out the details of how corruption is reduced by
// policemen.
public int Corruption;

// The contribution, in shields per turn, that this citizen makes
// towards production.
public int Construction;
}
}
4 changes: 3 additions & 1 deletion C7GameData/CityResident.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
namespace C7GameData {
public class CityResident {
//Specialist type
public CitizenType citizenType;

// Only relevant if citizenType.IsDefaultCitizen == true
public Tile tileWorked = Tile.NONE;
public Civilization nationality;
public City city;
Expand Down
1 change: 1 addition & 0 deletions C7GameData/GameData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class GameData {

public List<ExperienceLevel> experienceLevels = new List<ExperienceLevel>();
public List<Tech> techs = new();
public List<CitizenType> citizenTypes = new();
public string defaultExperienceLevelKey;
public ExperienceLevel defaultExperienceLevel;

Expand Down
Loading

0 comments on commit 4a8dfc1

Please sign in to comment.