Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions C7/UIElements/NewGame/ScenarioSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ public override void _Ready() {

// Set up buttons for the civs the player can play as.
civilizations = save.Civilizations;
playerListContainer.Columns = (int)Math.Ceiling(save.Civilizations.Count / 12.0);
string initiallySelectedCiv = save.Civilizations[1].name;
foreach (Civilization civ in save.Civilizations) {
if (civ.isBarbarian) {
continue;
}
playerListContainer.Columns = (int)Math.Ceiling(civilizations.Count / 12.0);

List<SavePlayer> pickablePlayers = save.Players.Where(p => p.canBePicked).ToList();
string initiallySelectedCiv = pickablePlayers.First(p => p.canBePicked).civilization;

foreach (SavePlayer player in pickablePlayers) {
Civilization civ = civilizations.Find(c => c.name == player.civilization);

Civ3MenuButton button = new() {
Text = civ.name,
Expand Down
2 changes: 1 addition & 1 deletion C7Engine/AI/PlayerAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class PlayerAI {
public static readonly int MAX_WATER_EXPLORERS = 4;

public static async Task PlayTurn(Player player, GameData gameData) {
if (player.isHuman || player.isBarbarians) {
if (player.isHuman || player.isBarbarians || !player.isIncludedInGame) {
return;
}
List<Tech> techs = gameData.techs;
Expand Down
2 changes: 1 addition & 1 deletion C7Engine/C7GameData/GameData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class GameData {

public List<City> cities = new List<City>();

internal List<Civilization> civilizations = new List<Civilization>();
public List<Civilization> civilizations { get; internal set; } = new List<Civilization>();

public List<ExperienceLevel> experienceLevels = new List<ExperienceLevel>();
public List<Tech> techs = new();
Expand Down
57 changes: 47 additions & 10 deletions C7Engine/C7GameData/ImportCiv3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ private SaveGame importSav(string savePath, string defaultBicPath, Func<string,
baseTerrain = save.TerrainTypes[civ3Tile.BaseTerrain].Key,
overlayTerrain = save.TerrainTypes[civ3Tile.OverlayTerrain].Key,
};
if (civ3Tile.BarbarianCamp >= 0) {
tile.features.Add("barbarianCamp");
}
if (civ3Tile.BonusShield) {
tile.features.Add("bonusShield");
}
Expand Down Expand Up @@ -183,6 +186,10 @@ private SaveGame importSav(string savePath, string defaultBicPath, Func<string,
}
i++;
}

// make barbarians unpickable
save.Players.Where(p => p.isBarbarian).ToList().ForEach(p => p.canBePicked = false);

return save;
}

Expand Down Expand Up @@ -226,6 +233,9 @@ private SaveGame importBiq(string biqPath, string defaultBiqPath, Func<string, s
baseTerrain = save.TerrainTypes[civ3Tile.BaseTerrain].Key,
overlayTerrain = save.TerrainTypes[civ3Tile.OverlayTerrain].Key,
};
if (civ3Tile.BarbarianCamp) {
tile.features.Add("barbarianCamp");
}
if (civ3Tile.BonusGrassland) {
tile.features.Add("bonusShield");
}
Expand Down Expand Up @@ -315,6 +325,18 @@ private SaveGame importBiq(string biqPath, string defaultBiqPath, Func<string, s
}
}

// Remove any unplayable Players, except Barbarians,
// ex. Mongols in `4 Middle Ages.biq` scenario.
// We only need to do this in the .biq files, not the .sav,
// because .sav files already contain just the playable Players + Barbarians.
// It's easier to do it like this, otherwise we need to manipulate the biq arrays,
// to check for playable players, offset array indexes by the difference, etc,
// as we are parsing the file, which is 10 times the hassle compared to this approach
save.Players = save.Players.Where(p => p.isBarbarian || p.isIncludedInGame).ToList();

// make barbarians unpickable
save.Players.Where(p => p.isBarbarian).ToList().ForEach(p => p.canBePicked = false);

return save;
}

Expand Down Expand Up @@ -407,10 +429,16 @@ private void ImportBicLeaders() {

// Make a player for each civ. The barbarians are always civ 0.
for (int i = 0; i < save.Civilizations.Count; ++i) {
save.Players.Add(MakeSavePlayerFromCiv(save.Civilizations[i],
isBarbarian: i == 0,
Civilization civ = save.Civilizations[i];

// GameCiv[0] does not contain the barbarians,
// but we want to include them in the gameplay
bool isIncluded = theBiq.GameCiv[0].Contains(i) || civ.isBarbarian;

save.Players.Add(MakeSavePlayerFromCiv(civ,
isHuman: false,
era: ""));
era: "",
isIncluded));

// Set a government for players not associated with LEAD.
// Usually, this applies only to barbarians, but in some scenarios
Expand All @@ -425,6 +453,8 @@ private void ImportBicLeaders() {
foreach (LEAD lead in theBiq.Lead) {
SavePlayer player = save.Players[lead.Civ];

player.canBePicked = lead.HumanPlayer == 1;

// Put the player in the correct starting era.
player.eraCivilopediaName = theBiq.Eras[lead.InitialEra].CivilopediaEntry;

Expand Down Expand Up @@ -469,9 +499,11 @@ private void ImportSavLeaders() {
}
Civilization civ = save.Civilizations[leader.RaceID];
SavePlayer player = MakeSavePlayerFromCiv(civ,
isBarbarian: i == 0,
isHuman: i == 1,
era: theBiq.Eras[leader.Era].CivilopediaEntry);
era: theBiq.Eras[leader.Era].CivilopediaEntry,
// by default if the player is in the .sav file, well, it's included in the game
// in contrast to a .biq file where it can have a player/civ that is not included in the final gameplay
true);

// Record what the player is currently researching.
if (leader.Researching > -1) {
Expand Down Expand Up @@ -499,6 +531,7 @@ private void ImportSavLeaders() {
player.taxRate = leader.TaxRate;
player.governmentId = save.Governments[leader.Government].id;
player.inAnarchyUntilTurn = save.TurnNumber + leader.AnarchyTurnsLeft;
player.primaryColorIndex = leader.Color;

save.Players.Add(player);
i++;
Expand Down Expand Up @@ -777,17 +810,17 @@ private void ImportSavLeaders() {
}
}

private SavePlayer MakeSavePlayerFromCiv(Civilization civ, bool isBarbarian, bool isHuman, string era) {
private SavePlayer MakeSavePlayerFromCiv(Civilization civ, bool isHuman, string era, bool isIncludedInGame = true) {
return new SavePlayer {
id = ids.CreateID("player"),
primaryColorIndex = civ.primaryColorIndex,
secondaryColorIndex = civ.secondaryColorIndex,
human = isHuman,
civilization = civ.name,

isIncludedInGame = isIncludedInGame,
// Never let barbarians play before a real player.
hasPlayedCurrentTurn = isBarbarian,

hasPlayedCurrentTurn = civ.isBarbarian,
isBarbarian = civ.isBarbarian,
eraCivilopediaName = era,
};
}
Expand Down Expand Up @@ -853,7 +886,11 @@ private void ImportBicUnits() {

// The owner index is into the list of civs, and we have a 1:1
// mapping of players and civs.
SavePlayer player = save.Players[unit.Owner];
// The exception to this are barbarian units (unit.OwnerType == 1),
// where the owner points to the tribe (city name in other civs), rather than the player/civ
// TODO: implement tribes for barbarians
int owner = unit.OwnerType == 1 ? 0 : unit.Owner;
SavePlayer player = save.Players[owner];
ExperienceLevel experience = save.ExperienceLevels[unit.ExperienceLevel];
save.Units.Add(createUnitAtLocation(player, unit.Name, unit.UnitType, experience.key, experience.baseHitPoints, unit.X, unit.Y));
}
Expand Down
10 changes: 10 additions & 0 deletions C7Engine/C7GameData/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ public class Player {

public Civilization civilization;

// Answers if this player-civ is simply included in the game.
// Some .biq scenarios contain players/civs in their data
// that are not a part of the gameplay.
// ex. Mongols in `4 Middle Ages.biq` scenario.
public bool isIncludedInGame = true;

// Answers if the human player can pick and play as this player-civ
// or is it only an AI player
public bool canBePicked = true;

public List<MapUnit> units = new List<MapUnit>();
public List<City> cities = new List<City>();
public TileKnowledge tileKnowledge { get; private set; }
Expand Down
4 changes: 1 addition & 3 deletions C7Engine/C7GameData/Save/SaveGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,7 @@ private void ConvertUnits(GameData data) {
proto.requiredTech = techDict[saveProto.requiredTech];
}

if (saveProto.unique != null) {
Civilization civ = civDict[saveProto.unique.civilization];

if (saveProto.unique != null && civDict.TryGetValue(saveProto.unique.civilization, out var civ)) {
proto.unique = new() {
civilization = civ
};
Expand Down
16 changes: 16 additions & 0 deletions C7Engine/C7GameData/Save/SavePlayer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;

namespace C7GameData.Save {

Expand All @@ -10,6 +11,8 @@ public class SavePlayer {
public bool human = false;
public bool hasPlayedCurrentTurn = false;
public bool defeated = false;
public bool isIncludedInGame = true;
public bool canBePicked = true;

public string civilization;

Expand Down Expand Up @@ -60,10 +63,17 @@ public class SavePlayer {
// The current government of the player.
public ID governmentId;

// Used when importing from .biq, to make it easier to distinguish barbarians from other players.
// It's not meant to be saved in the json.
[JsonIgnore]
public bool isBarbarian { get; init; }

public Player ToPlayer(GameMap map, List<Civilization> civilizations, List<Government> governments, List<Tech> techs, Rules rules) {
Player player = new Player{
id = id,
isHuman = human,
isIncludedInGame = isIncludedInGame,
canBePicked = canBePicked,
hasPlayedThisTurn = hasPlayedCurrentTurn,
defeated = defeated,
primaryColorIndex = primaryColorIndex,
Expand Down Expand Up @@ -104,13 +114,19 @@ public Player ToPlayer(GameMap map, List<Civilization> civilizations, List<Gover
player.AddTechItemToResearchQueue(tech);
}

if (player.civilization.isBarbarian) {
player.canBePicked = false;
}

return player;
}

public SavePlayer() { }

public SavePlayer(Player player) {
id = player.id;
isIncludedInGame = player.isIncludedInGame;
canBePicked = player.canBePicked;
primaryColorIndex = player.primaryColorIndex;
secondaryColorIndex = player.secondaryColorIndex;
human = player.isHuman;
Expand Down
1 change: 1 addition & 0 deletions C7Engine/GameSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ private void AddPlayer(SaveGame save, Civilization civ, bool isHuman) {
save.Players.Add(player);

if (civ.isBarbarian) {
player.canBePicked = false;
return;
}

Expand Down
Loading
Loading