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
3 changes: 2 additions & 1 deletion C7Engine/C7GameData/GameData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public class GameData {
public ExperienceLevel defaultExperienceLevel;
public Rules rules;
public TimeOptions timeOptions;
public Dictionary<string, List<HistTurnRecord>> history;

public BarbarianInfo barbarianInfo = new BarbarianInfo();

Expand Down Expand Up @@ -324,7 +325,7 @@ internal void RemoveUnit(MapUnit unit) {
}

internal void SpawnUnit(Player player, UnitPrototype proto, Tile tile) {
// TODO: consolidate unit spawning routines (here)
// TODO: consolidate unit spawning routines (here)

var defaultExpLevel = this.defaultExperienceLevel;
var barbExpLevel = this.experienceLevels.First(e => e.baseHitPoints == this.barbarianInfo.maxHitpoints);
Expand Down
9 changes: 9 additions & 0 deletions C7Engine/C7GameData/HistTurnRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace C7GameData;

public class HistTurnRecord {
public int Date { get; set; }
public int Power { get; set; }
public int Score { get; set; }
public int Culture { get; set; }
public int VP { get; set; }
}
40 changes: 40 additions & 0 deletions C7Engine/C7GameData/ImportCiv3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ private SaveGame importSav(string savePath, string defaultBicPath, Func<string,
ImportSavCities();
save.GameDifficulty = save.Difficulties[savData.Game.DifficultyID];

ImportSavHistory();

SetMapDimensions(savData, save);
SetWorldWrap(savData, save);

Expand Down Expand Up @@ -206,6 +208,44 @@ private SaveGame importSav(string savePath, string defaultBicPath, Func<string,
return save;
}

private void ImportSavHistory() {
Dictionary<int, ID> civPlayerMap = BuildCivIdPlayerMap();

foreach (ID player in civPlayerMap.Values) {
save.History[player.ToString()] = new List<HistTurnRecord>();
}

foreach (var turn in savData.HistTurn) {
var civs = savData.TurnCiv[turn.TurnNumber];
var powers = savData.TurnPower[turn.TurnNumber];
var scores = savData.TurnScore[turn.TurnNumber];
var cultures = savData.TurnCulture[turn.TurnNumber];
var vps = savData.TurnVP[turn.TurnNumber];
foreach ((int civ, int idx) in civs.Select((civ, idx) => (civ, idx))) {
var player = civPlayerMap[civ];
save.History[player.ToString()].Add(new HistTurnRecord {
Date = turn.Date,
Power = powers[idx],
Score = scores[idx],
Culture = cultures[idx],
VP = vps == null ? 0 : vps[idx]
});
}
}
}

private Dictionary<int, ID> BuildCivIdPlayerMap() {
var civ3CivIdToPlayerId = new Dictionary<int, ID>();
var civs = savData.TurnCiv[0];
foreach (int civ in civs) {
var raceId = savData.Lead[civ].RaceID;
var race = savData.Bic.Race[raceId];
var player = save.Players.First(p => p.civilization == race.Name);
civ3CivIdToPlayerId[civ] = player.id;
}
return civ3CivIdToPlayerId;
}

/**
* defaultBiqPath is used in case some sections (map, rules, player data) are not
* present.
Expand Down
35 changes: 35 additions & 0 deletions C7Engine/C7GameData/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1130,6 +1130,41 @@ public int ShieldCost(IProducible producible) {

return producible.ShieldCost(civilization.traits, costFactor);
}

public void UpdateHistory(GameData gameData) {
if (!gameData.history.ContainsKey(id.ToString()))
return;

int n = gameData.history[id.ToString()].Count;
HistTurnRecord lastTurn = gameData.history[id.ToString()].LastOrDefault();

// TODO: Make formulas moddable

// "Power is an amalgam of cities, gold, culture, advances, resources, military strength,
// nuclear weapons, and wonder."
// Exact formula is unknown, so we repeat the previous value.
// TODO: Figure out power formula
int power = (lastTurn?.Power ?? 100);

// Score is the _average_ of "turn scores".
// Here we calculate the cumulative moving average: S[n+1] = S[n] + (x[n+1] - S[N])/(n+1)
int lastScore = (lastTurn?.Score ?? 0);
// TODO: Victory scoring
// float turnScore = ScoreVictory.ComputeTurnScore(this, gameData);
// int score = (int) Math.Floor(lastScore + (turnScore - lastScore) / (1f * (n+1)));
int score = lastScore;

// Culture is "the sum of the cultural value of all your cities"
int totalCulture = cities.Sum(c => c.GetCulture());

gameData.history[id.ToString()].Add(new HistTurnRecord {
Date = gameData.timeOptions.GetRawNumber(gameData.turn),
Power = power,
Score = score,
Culture = totalCulture,
VP = 0 // TODO: victory points
});
}
}

}
14 changes: 14 additions & 0 deletions C7Engine/C7GameData/Save/SaveGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public static SaveGame FromGameData(GameData data) {
GameDifficulty = data.gameDifficulty,
Rules = data.rules,
TimeOptions = data.timeOptions,
History = data.history,
TerrainImprovements = data.terrainImprovements.ConvertAll(ti => ti.ToSaveTerrainImprovement()),
GameModeConfig = data.gameModeConfig,
};
Expand Down Expand Up @@ -138,6 +139,8 @@ public GameData ToGameData(BehaviorEngine behaviors) {
ConvertAlliances(data);
ConvertAllianceWars(data);

BeginHistory(data);

data.defaultExperienceLevelKey = DefaultExperienceLevel;
data.defaultExperienceLevel = data.experienceLevels.Find(el => el.key == DefaultExperienceLevel);

Expand All @@ -149,6 +152,15 @@ public GameData ToGameData(BehaviorEngine behaviors) {
return data;
}

private void BeginHistory(GameData data) {
foreach (var player in data.players) {
if (!player.isBarbarians) {
if (!data.history.ContainsKey(player.id.ToString()))
data.history[player.id.ToString()] = new List<HistTurnRecord>();
}
}
}

private void OnGameCreation() {
foreach (Player p in EngineStorage.gameData.players) {
// Backfill citizen assignments for scenarios that don't specify
Expand Down Expand Up @@ -193,6 +205,7 @@ private GameData InitializeGameData() {
experienceLevels = ExperienceLevels,
rules = Rules,
timeOptions = TimeOptions,
history = History,
GreatWondersBuilt = GreatWondersBuilt,
};

Expand Down Expand Up @@ -449,6 +462,7 @@ private void ConvertAllianceWars(GameData data) {
public List<SaveTerraform> TerraForms = new();
public List<Government> Governments = new();
public List<WorldSize> WorldSizes = new();
public Dictionary<string, List<HistTurnRecord>> History = new();

// The relative directory that can be used to find scenario-specific
// assets.
Expand Down
2 changes: 2 additions & 0 deletions C7Engine/EntryPoints/TurnHandling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ public static async Task AdvanceTurn() {
// unhappiness of a new citizen during their turn.
log.Information($"\n*** City growth/production for turn {gameData.turn}, player {player} ***");
player.HandleCityUpdates(gameData);

player.UpdateHistory(gameData);
}

// Now that the turn is ending, do all the bookkeeping for the
Expand Down
Loading