World Project - Niilo007/RimWorld-NQoL GitHub Wiki
---
title: Capture Relation Effects
---
stateDiagram-v2
[*] --> SettlementCaptured
SettlementCaptured --> [*] : Is Our Settlement
SettlementCaptured --> DecreaseRelationWithAttacker_1 : Settlement Of Ally
SettlementCaptured --> DecreaseRelationWithAttacker_1 : Settlement Of Neutral
SettlementCaptured --> IncreaseRelationWithAttacker_1 : Settlement Of Enemy
DecreaseRelationWithAttacker_1 --> SettlementIdeo
SettlementIdeo --> DecreaseRelationWithAttacker_2 : Same As Our Ideo
SettlementIdeo --> DecreaseRelationWithAttacker_2 : Our Ideo Is Minor Ideo
DecreaseRelationWithAttacker_2 --> SettlementCulture
IncreaseRelationWithAttacker_1 --> SettlementIdeo
SettlementIdeo --> IncreaseRelationWithAttacker_2 : Incompatible With Ours
IncreaseRelationWithAttacker_2 --> SettlementCulture
SettlementIdeo --> SettlementCulture : null
SettlementIdeo --> AttackerIdeo : Different From Ours
AttackerIdeo --> IncreaseRelationWithAttacker_3 : Same As Ours
IncreaseRelationWithAttacker_3 --> SettlementCulture
SettlementCulture --> AttackerCulture_1 : Same As Ours
SettlementCulture --> AttackerCulture_2 : Different From Ours
AttackerCulture_1 --> DecreaseRelationWithAttacker_4 : Different From Ours
AttackerCulture_1 --> [*] : Same As Ours
AttackerCulture_2 --> IncreaseRelationWithAttacker_4 : Same As Ours
AttackerCulture_2 --> [*] : Different From Ours
IncreaseRelationWithAttacker_4 --> [*]
DecreaseRelationWithAttacker_4 --> [*]
SettlementCulture --> [*] : null
<li Class="NQualityOfLife.World.FactionExtensions" Inherit="False" MayRequireAnyOf="Niilo007.NiilosQoL,Niilo007.NiilosQoL.Dev">
<allowDiplomacy>true</allowDiplomacy>
</li>
flowchart TB
LocalExpansionDesire --Increases--> AttackDesire
ExpansionDesire --Increases--> AttackDesire
LocalPopDensity --Increases--> AttackDesire
SettlementCount --Decreases--> TruceDesire
SettlementCount --Decreases--> ExpansionDesire
LocalPopDensity --Increases--> LocalExpansionDesire
private void UpdateLocalExpansionDesire()
{
if (localTilePopulationCapCached <= 0f)
{
Utils.Log.Error($"'{nameof(localTilePopulationCapCached)}' was: '{localTilePopulationCapCached.OrNull()}'! - Should have been set by now! Setting it now... - '{this.parent.OrNull()}'");
localTilePopulationCapCached = GetPopulationCapForTile(myTileId, populationSoftCap, populationHardCap, myTile);
}
if (population <= 0f || localTilePopulationCapCached <= 0f) { localExpansionDesireCached = 0f; populationDensityRatio = 0f; return; }
if (population > localTilePopulationCapCached)
{
populationDensityRatio = 1;
}
else
{
populationDensityRatio = population / localTilePopulationCapCached;
}
localExpansionDesireCached = populationDensityRatio;
}
/// <summary>Calculate a faction's desire to expand it's settlement count</summary>
/// <param name="faction">The faction who's expansion desire we are calculating</param>
/// <param name="strongest">Strongest faction on the map</param>
/// <param name="weakest">weakest faction on the map</param>
/// <returns>float in a range of 0f-1f</returns>
public static Ratio CalculateFactionExpansionDesire(this Faction faction, Faction strongest, Faction weakest)
{
if (faction == null || strongest == null || weakest == null)
{
Utils.Log.Error_Null(nameof(faction), nameof(strongest), nameof(weakest), $"({faction.AsParam(nameof(faction))}, {strongest.AsParam(nameof(strongest))}, {weakest.AsParam(nameof(weakest))})");
return 0;
}
(int bases, int population, int popCap) = faction.GetSettlementCountAndTotalPopulation();
float desire = (float)((float)population / popCap);
if (faction == strongest) { desire *= 0.5f; }
else if (faction == weakest) { desire *= 1.5f; }
desire -= bases * 0.01f;
return desire.ClampRatio();
}
/// <summary>Calculate a faction's general desire to make peace with other factions</summary>
/// <param name="faction">The faction who's truce desire we are calculating</param>
/// <param name="strongest">Strongest faction on the map</param>
/// <param name="weakest">weakest faction on the map</param>
/// <returns>float in a range of 0f-1f</returns>
public static Ratio CalculateTruceDesire(this Faction faction, Faction strongest, Faction weakest)
{
if (faction == null || strongest == null || weakest == null)
{
Utils.Log.Error_Null(nameof(faction), nameof(strongest), nameof(weakest), $"({faction.AsParam(nameof(faction))}, {strongest.AsParam(nameof(strongest))}, {weakest.AsParam(nameof(weakest))})");
return 0;
}
if (faction.def.GetModExtension<FactionExtensions>()?.allowDiplomacy != true)
{
Utils.Log.ErrorOnce($"'{faction.OrNull()}' does not allow diplomacy but: '{nameof(CalculateTruceDesire)}' was called -> will always return '{Ratio.Zero}'!");
return Ratio.Zero;
}
ushort ourSettlementCount = faction.SettlementCount();
float desire = World.NQoL_WorldComp.AllSettlementsCount / (float)(ourSettlementCount * ourSettlementCount);
if (faction == weakest) { desire *= 2f; }
else if (faction == strongest) { desire *= 0.25f; }
if (faction != strongest && faction.RelationWith(strongest).kind == FactionRelationKind.Hostile) { desire *= 2f; }
desire *= 0.01f;
return desire.ClampRatio();
}
Truce can happen if both factions have a desire for a truce and are hostile to each other. A successful truce makes the 2 factions unconditionally neutral to each other.
flowchart TB
SharedCulture --Increases--> TruceWillingness
SharedIdeo --Increases--> TruceWillingness
If a faction is desperate enough for peace, they may surrender to a hostile faction.
---
title: Peace Deal
---
stateDiagram-v2
[*] --> TryToMakePeaceWithNextFaction
TryToMakePeaceWithNextFaction --> [*] : Iterated All
TryToMakePeaceWithNextFaction --> SurrenderOutcomePartialChange
SurrenderOutcomePartialChange --> PeaceWithFaction : Accepted
SurrenderOutcomePartialChange--> SurrenderOutcomePartialConversion : Rejected
SurrenderOutcomePartialConversion --> PeaceWithFaction : Accepted
SurrenderOutcomePartialConversion --> SurrenderOutcomeMajorChange : Rejected
SurrenderOutcomeMajorChange --> PeaceWithFaction : Accepted
SurrenderOutcomeMajorChange --> SurrenderOutcomeTotalConversion : Rejected
SurrenderOutcomeTotalConversion --> TryToMakePeaceWithNextFaction : Rejected
SurrenderOutcomeTotalConversion --> PeaceWithFaction : Accepted
PeaceWithFaction --> TryToMakePeaceWithNextFaction
public static float GetCurrentPopulationGrowthRatePerDay(float localStaticGrowthRate, float biomePopulationCap, float currentPopulation, Factor localFertility, Ratio populationDensityRatio)
{
float logisticGrowth = biomePopulationCap * currentPopulation * (1f - populationDensityRatio);
return localStaticGrowthRate * logisticGrowth * localFertility;
}
- Food is produced by Farm files and consumed by the Population. Lack of food causes population stagnation or loss.
- Foo resources can be transferred with roads.
private Factor UpdateCachedFertility()
{
localFertilityCached = myTileId.LocalFertility(Session.Instance.World!.grid) * 0.14285f;
return localFertilityCached;
}
public static Factor LocalFertility(this int tile, WorldGrid? worldGrid = null, int radius = 6)
{
if (tile < 0) { Utils.Log.Error_InvalidInput_WithReason(nameof(tile), $"({tile.AsParam(nameof(tile))}, {worldGrid.AsParam()})", "has an invalid tile id!"); return Factor.Invalid; }
else { if (Session.Instance?.World == null || TileCount <= -1 || (worldGrid != null && Session.Instance!.World!.grid != worldGrid)) { Session.NewSession.World = Find.World; } }
List<int> relevantTiles = Tile_.GetTilesInRadius(tile, radius, out int count, Session.Instance!.World!.grid); //RelevantTiles(tile, radius, out int count); // new List<int>(); //tile.NeighbouringTiles(WorldGrid);
//int nC = n.Count;
Factor totalFertility = 0f; // tile.TileFertilityFactor(WorldGrid);
for (int i = 0; i < count; i++)
{
totalFertility += relevantTiles[i].TileFertilityFactor(Session.Instance!.World!.grid);
}
return Utils.Math.Clamp(totalFertility, 1f, 999f);
}
public static Factor TileFertilityFactor(this int tile, WorldGrid? worldGrid = null)
{
if (tile < 0) { Utils.Log.Error_InvalidInput_WithReason(tile.AsParam(nameof(tile)), $"({tile.AsParam(nameof(tile))}, {worldGrid.AsParam(nameof(worldGrid))})", "has an invalid tile id!"); return Factor.Invalid; }
else { if (Session.Instance?.World == null || TileCount <= -1) { Session.NewSession.World = Find.World; } }
return Session.Instance!.World!.grid.tiles[tile].TileFertilityFactor(tile);
}
bool attackerVictory = DoBattleSim
(
attackers: population * 0.5f,
attackerTechLevel: myFaction!.def.techLevel,
attackerCasualties: out float attackerCasualties,
battleGoal: out battleGoal,
defenders: theirComp!.population,
defenderTechLevel: theirFaction.def.techLevel,
defenderCasualties: out float defenderCasualties,
hilliness: battleFieldTile.hilliness,
attackSuccessChance: out _,
attackerFaction: myFaction,
defenderFaction: theirFaction,
biome: battleFieldTile.biome,
defenderComp: theirComp
);
Tiles can become war torn when the settlement is attacked.
public static bool MakeWarTornAround(this Tile tile, int tileId, WorldGrid? worldGrid = null)
{
}
- Implemented Tiles:
- Urban
- Farm land
- Planned:
- Mining tile / site
- Urban tiles increase the population capacity of the settlement.
- See:
NQualityOfLife.World.NQoL_World_Object_Comp.GetPopulationCapForTile()
- See:
- Urban tiles provide defense buffs in battle.
- See:
NQualityOfLife.World.NQoL_World_Object_Comp.DoBattleSim()
- See:
- Urban tiles are less fertile than natural terrain or farm land
- See:
NQualityOfLife.World.Utils_.Tile_.TileFertilityFactor()
- See:
<li Class="NQualityOfLife.World.FactionExtensions" Inherit="False" MayRequireAnyOf="Niilo007.NiilosQoL,Niilo007.NiilosQoL.Dev">
<canDevelop>true</canDevelop>
<canUrbanize>true</canUrbanize>
</li>
- Farm tiles have high fertility.
<li Class="NQualityOfLife.World.FactionExtensions" Inherit="False" MayRequireAnyOf="Niilo007.NiilosQoL,Niilo007.NiilosQoL.Dev">
<canDevelop>true</canDevelop>
<canFarm>true</canFarm>
</li>
- Settlements can transfer resources and population to connected settlements.
- Settlements can build new roads to connect to nearby settlements, and upgrade existing roads.
- Planned:
- The tier of the road affects transfer efficiency.
<li Class="NQualityOfLife.World.FactionExtensions" Inherit="False" MayRequireAnyOf="Niilo007.NiilosQoL,Niilo007.NiilosQoL.Dev">
<canDevelop>true</canDevelop>
<canBuildRoads>true</canBuildRoads>
</li>
- Existing settlements can establish new settlements if they have the resources and population to do so.
<li Class="NQualityOfLife.World.FactionExtensions" Inherit="False" MayRequireAnyOf="Niilo007.NiilosQoL,Niilo007.NiilosQoL.Dev">
<canDevelop>true</canDevelop>
<specialFactionModifiers>CanBuildNewSettlements</specialFactionModifiers>
</li>
mindmap
root((World Project))
Resource System
Trade
Road Building
Population System
Population
War Stuff
Battle Sim
flowchart TB
FoodResource --Consumed By--> Population
Population --Produces--> RawMaterials
RawMaterials --Produced By--> Population
RawMaterials --Used To Build--> Roads
RawMaterials --Used To Build--> UrbanTiles
UrbanTiles --Increases--> PopCap
PopCap --Used To Calculate--> PopDensity
Population --Used To Calculate--> PopDensity
PopGrowth --Increased By--> Population
PopGrowth --Increased By--> PopCap
PopGrowth --Decreased By--> PopDensity
PopDensity --Calculated From--> PopCap
PopDensity --Calculated From--> Population
FarmTiles --Produces--> FoodResource
Population --Consumes--> FoodResource