Skip to content

Commit

Permalink
Fixed various issues with planet generation
Browse files Browse the repository at this point in the history
- Fixed crashing when loading planet with missing factions.

- Fixed planet sometimes duping settlements and sites.

- Fixed planet sometimes not removing settlements correctly.

- Fixed planet sometimes removing maps with player pawns inside.
  • Loading branch information
Byte-Nova committed Sep 12, 2024
1 parent c90933f commit b0ad209
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 112 deletions.
72 changes: 47 additions & 25 deletions Source/Client/Managers/NPCSettlementManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static void ParsePacket(Packet packet)

switch (data._stepMode)
{
case SettlementStepMode.Add:
case SettlementStepMode.Add:
break;

case SettlementStepMode.Remove:
Expand All @@ -27,30 +27,32 @@ public static void ParsePacket(Packet packet)

public static void AddSettlements(PlanetNPCSettlement[] settlements)
{
if (settlements == null) return;

foreach(PlanetNPCSettlement settlement in NPCSettlementManagerHelper.tempNPCSettlements)
foreach(PlanetNPCSettlement settlement in settlements)
{
SpawnSettlement(settlement);
SpawnSingleSettlement(settlement);
}
}

public static void SpawnSettlement(PlanetNPCSettlement toAdd)
public static void SpawnSingleSettlement(PlanetNPCSettlement toAdd)
{
try
if (Find.WorldObjects.Settlements.FirstOrDefault(fetch => fetch.Tile == toAdd.tile) != null) return;
else
{
Settlement settlement = (Settlement)WorldObjectMaker.MakeWorldObject(WorldObjectDefOf.Settlement);
settlement.Tile = toAdd.tile;
settlement.Name = toAdd.name;

//TODO
//THIS FUNCTION WILL ALWAYS ASSIGN ALL SETTLEMENTS TO THE FIRST INSTANCE OF A FACTION IF THERE'S MORE OF ONE OF THE SAME TIME
//HAVING MULTIPLE GENTLE TRIBES WILL SYNC ALL THE SETTLEMENTS OF THE GENTLE TRIBES TO THE FIRST ONE. FIX!!
settlement.SetFaction(PlanetManagerHelper.GetNPCFactionFromDefName(toAdd.defName));

Find.WorldObjects.Add(settlement);
try
{
Settlement settlement = (Settlement)WorldObjectMaker.MakeWorldObject(WorldObjectDefOf.Settlement);
settlement.Tile = toAdd.tile;
settlement.Name = toAdd.name;

//TODO
//THIS FUNCTION WILL ALWAYS ASSIGN ALL SETTLEMENTS TO THE FIRST INSTANCE OF A FACTION IF THERE'S MORE OF ONE OF THE SAME TIME
//HAVING MULTIPLE GENTLE TRIBES WILL SYNC ALL THE SETTLEMENTS OF THE GENTLE TRIBES TO THE FIRST ONE. FIX!!
settlement.SetFaction(PlanetManagerHelper.GetNPCFactionFromDefName(toAdd.defName));

Find.WorldObjects.Add(settlement);
}
catch (Exception e) { Logger.Warning($"Failed to build NPC settlement at {toAdd.tile}. Reason: {e}"); }
}
catch (Exception e) { Logger.Error($"Failed to build NPC settlement at {toAdd.tile}. Reason: {e}"); }
}

public static void ClearAllSettlements()
Expand All @@ -60,15 +62,15 @@ public static void ClearAllSettlements()

foreach (Settlement settlement in settlements)
{
RemoveSettlement(settlement, null);
RemoveSingleSettlement(settlement, null);
}

DestroyedSettlement[] destroyedSettlements = Find.WorldObjects.DestroyedSettlements.Where(fetch => !FactionValues.playerFactions.Contains(fetch.Faction) &&
fetch.Faction != Faction.OfPlayer).ToArray();

foreach (DestroyedSettlement settlement in destroyedSettlements)
{
RemoveSettlement(null, settlement);
RemoveSingleSettlement(null, settlement);
}
}

Expand All @@ -77,17 +79,37 @@ public static void RemoveNPCSettlementFromPacket(PlanetNPCSettlement data)
Settlement toRemove = Find.World.worldObjects.Settlements.FirstOrDefault(fetch => fetch.Tile == data.tile &&
fetch.Faction != Faction.OfPlayer);

if (toRemove != null) RemoveSettlement(toRemove, null);
if (toRemove != null) RemoveSingleSettlement(toRemove, null);
}

public static void RemoveSettlement(Settlement settlement, DestroyedSettlement destroyedSettlement)
public static void RemoveSingleSettlement(Settlement settlement, DestroyedSettlement destroyedSettlement)
{
if (settlement != null)
{
NPCSettlementManagerHelper.lastRemovedSettlement = settlement;
Find.WorldObjects.Remove(settlement);
try
{
if (!RimworldManager.CheckIfMapHasPlayerPawns(settlement.Map))
{
NPCSettlementManagerHelper.lastRemovedSettlement = settlement;
Find.WorldObjects.Remove(settlement);
}
else Logger.Warning($"Ignored removal of settlement at {settlement.Tile} because player was inside");
}
catch (Exception e) { Logger.Warning($"Failed to remove NPC settlement at {settlement.Tile}. Reason: {e}"); }
}

else if (destroyedSettlement != null)
{
try
{
if (!RimworldManager.CheckIfMapHasPlayerPawns(destroyedSettlement.Map))
{
Find.WorldObjects.Remove(destroyedSettlement);
}
else Logger.Warning($"Ignored removal of settlement at {destroyedSettlement.Tile} because player was inside");
}
catch (Exception e) { Logger.Warning($"Failed to remove NPC settlement at {destroyedSettlement.Tile}. Reason: {e}"); }
}
else if (destroyedSettlement != null) Find.WorldObjects.Remove(destroyedSettlement);
}

public static void RequestSettlementRemoval(Settlement settlement)
Expand Down
22 changes: 11 additions & 11 deletions Source/Client/Managers/PlanetGeneratorManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public static void SetPlanetFeatures()

Find.WorldFeatures.features.Add(worldFeature);
}
catch (Exception e) { Logger.Error($"Failed set planet feature from def '{planetFeature.defName}'. Reason: {e}"); }
catch (Exception e) { Logger.Warning($"Failed set planet feature from def '{planetFeature.defName}'. Reason: {e}"); }
}

Find.WorldFeatures.textsCreated = false;
Expand All @@ -203,11 +203,11 @@ public static void SetPlanetFactions()

for (int i = 0; i < cachedWorldValues.NPCFactions.Length; i++)
{
PlanetNPCFaction faction = cachedWorldValues.NPCFactions[i];

try
{
Faction toModify = planetFactions[i];
PlanetNPCFaction faction = cachedWorldValues.NPCFactions[i];

Faction toModify = planetFactions.First(fetch => fetch.def.defName == cachedWorldValues.NPCFactions[i].defName);

toModify.Name = faction.name;

Expand All @@ -216,7 +216,7 @@ public static void SetPlanetFactions()
faction.color[2],
faction.color[3]);
}
catch (Exception e) { Logger.Error($"Failed set planet faction from def '{faction.defName}'. Reason: {e}"); }
catch (Exception e) { Logger.Warning($"Failed set planet faction from def '{cachedWorldValues.NPCFactions[i].defName}'. Reason: {e}"); }
}
}
}
Expand Down Expand Up @@ -245,7 +245,7 @@ public static PlanetNPCFaction[] GetNPCFactionsFromDef(FactionDef[] factionDefs)
toCreate.defName = faction.defName;
npcFactions.Add(toCreate);
}
catch (Exception e) { Logger.Error($"Failed transform faction '{faction.defName}' from game. Reason: {e}"); }
catch (Exception e) { Logger.Warning($"Failed to get faction '{faction.defName}' from game. Reason: {e}"); }
}
return npcFactions.ToArray();
}
Expand All @@ -255,8 +255,8 @@ public static FactionDef[] GetFactionDefsFromNPCFaction(PlanetNPCFaction[] facti
List<FactionDef> defList = new List<FactionDef>();
foreach (PlanetNPCFaction faction in factions)
{
try { defList.Add(DefDatabase<FactionDef>.AllDefs.FirstOrDefault(fetch => fetch.defName == faction.defName)); }
catch (Exception e) { Logger.Error($"Failed get FactionDef '{faction.defName}' from server. Reason: {e}"); }
try { defList.Add(DefDatabase<FactionDef>.AllDefs.First(fetch => fetch.defName == faction.defName)); }
catch (Exception e) { Logger.Warning($"Failed to get FactionDef '{faction.defName}' from server. Reason: {e}"); }
}
return defList.ToArray();
}
Expand All @@ -281,7 +281,7 @@ public static PlanetNPCFaction[] GetPlanetNPCFactions()
planetFactions.Add(planetFaction);
}
}
catch (Exception e) { Logger.Error($"Failed get NPC faction '{faction.def.defName}' to populate. Reason: {e}"); }
catch (Exception e) { Logger.Warning($"Failed to get NPC faction '{faction.def.defName}' to populate. Reason: {e}"); }
}

return planetFactions.ToArray();
Expand All @@ -307,7 +307,7 @@ public static PlanetNPCSettlement[] GetPlanetNPCSettlements()

npcSettlements.Add(PlanetNPCSettlement);
}
catch (Exception e) { Logger.Error($"Failed get NPC settlement '{settlement.Tile}' to populate. Reason: {e}"); }
catch (Exception e) { Logger.Warning($"Failed to get NPC settlement '{settlement.Tile}' to populate. Reason: {e}"); }
}
return npcSettlements.ToArray();
}
Expand All @@ -328,7 +328,7 @@ public static PlanetFeature[] GetPlanetFeatures()

planetFeatures.Add(planetFeature);
}
catch (Exception e) { Logger.Error($"Failed get feature '{worldFeature.def.defName}' to populate. Reason: {e}"); }
catch (Exception e) { Logger.Warning($"Failed to get feature '{worldFeature.def.defName}' to populate. Reason: {e}"); }
}

return planetFeatures.ToArray();
Expand Down
60 changes: 25 additions & 35 deletions Source/Client/Managers/PlayerSettlementManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,76 +20,66 @@ public static void ParsePacket(Packet packet)
switch (settlementData._stepMode)
{
case SettlementStepMode.Add:
SpawnSingleSettlement(settlementData);
SpawnSingleSettlement(settlementData._settlementData);
break;

case SettlementStepMode.Remove:
RemoveSingleSettlement(settlementData);
RemoveSingleSettlement(settlementData._settlementData);
break;
}
}

public static void AddSettlements(SettlementFile[] toAdd)
public static void AddSettlements(SettlementFile[] settlements)
{
if (toAdd == null) return;

for (int i = 0; i < PlayerSettlementManagerHelper.tempSettlements.Count(); i++)
foreach (SettlementFile toAdd in settlements)
{
SettlementFile settlementFile = PlayerSettlementManagerHelper.tempSettlements[i];

try
{
Settlement settlement = (Settlement)WorldObjectMaker.MakeWorldObject(WorldObjectDefOf.Settlement);
settlement.Tile = settlementFile.Tile;
settlement.Name = $"{settlementFile.Owner}'s settlement";
settlement.SetFaction(PlanetManagerHelper.GetPlayerFactionFromGoodwill(settlementFile.Goodwill));

playerSettlements.Add(settlement);
Find.WorldObjects.Add(settlement);
}
catch (Exception e) { Logger.Error($"Failed to build settlement at {settlementFile.Tile}. Reason: {e}"); }
SpawnSingleSettlement(toAdd);
}
}

public static void ClearAllSettlements()
{
playerSettlements.Clear();

Settlement[] settlements = Find.WorldObjects.Settlements.Where(fetch => FactionValues.playerFactions.Contains(fetch.Faction)).ToArray();
foreach (Settlement settlement in settlements) Find.WorldObjects.Remove(settlement);
foreach (Settlement settlement in settlements)
{
SettlementFile toRemove = new SettlementFile();
toRemove.Tile = settlement.Tile;
RemoveSingleSettlement(toRemove);
}
}

public static void SpawnSingleSettlement(PlayerSettlementData toAdd)
public static void SpawnSingleSettlement(SettlementFile toAdd)
{
if (ClientValues.isReadyToPlay)
if (Find.WorldObjects.Settlements.FirstOrDefault(fetch => fetch.Tile == toAdd.Tile) != null) return;
else
{
try
{
Settlement settlement = (Settlement)WorldObjectMaker.MakeWorldObject(WorldObjectDefOf.Settlement);
settlement.Tile = toAdd._settlementData.Tile;
settlement.Name = $"{toAdd._settlementData.Owner}'s settlement";
settlement.SetFaction(PlanetManagerHelper.GetPlayerFactionFromGoodwill(toAdd._settlementData.Goodwill));
settlement.Tile = toAdd.Tile;
settlement.Name = $"{toAdd.Owner}'s settlement";
settlement.SetFaction(PlanetManagerHelper.GetPlayerFactionFromGoodwill(toAdd.Goodwill));

playerSettlements.Add(settlement);
Find.WorldObjects.Add(settlement);
}
catch (Exception e) { Logger.Error($"Failed to spawn settlement at {toAdd._settlementData.Tile}. Reason: {e}"); }
catch (Exception e) { Logger.Error($"Failed to spawn settlement at {toAdd.Tile}. Reason: {e}"); }
}
}

public static void RemoveSingleSettlement(PlayerSettlementData toRemove)
public static void RemoveSingleSettlement(SettlementFile toRemove)
{
if (ClientValues.isReadyToPlay)
try
{
try
Settlement toGet = Find.WorldObjects.Settlements.Find(fetch => fetch.Tile == toRemove.Tile && FactionValues.playerFactions.Contains(fetch.Faction));
if (!RimworldManager.CheckIfMapHasPlayerPawns(toGet.Map))
{
Settlement toGet = playerSettlements.Find(x => x.Tile == toRemove._settlementData.Tile);

playerSettlements.Remove(toGet);
if (playerSettlements.Contains(toGet)) playerSettlements.Remove(toGet);
Find.WorldObjects.Remove(toGet);
}
catch (Exception e) { Logger.Error($"Failed to remove settlement at {toRemove._settlementData.Tile}. Reason: {e}"); }
else Logger.Warning($"Ignored removal of settlement at {toGet.Tile} because player was inside");
}
catch (Exception e) { Logger.Error($"Failed to remove settlement at {toRemove.Tile}. Reason: {e}"); }
}
}

Expand Down
60 changes: 24 additions & 36 deletions Source/Client/Managers/PlayerSiteManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,70 +14,58 @@ public static class PlayerSiteManager

public static void AddSites(SiteFile[] sites)
{
if (sites == null) return;

for (int i = 0; i < PlayerSiteManagerHelper.tempSites.Count(); i++)
foreach (SiteFile toAdd in sites)
{
SiteFile siteFile = PlayerSiteManagerHelper.tempSites[i];

try
{
SitePartDef siteDef = SiteManager.GetDefForNewSite(siteFile.Type, siteFile.FactionFile != null);
Site site = SiteMaker.MakeSite(sitePart: siteDef,
tile: siteFile.Tile,
threatPoints: 1000,
faction: PlanetManagerHelper.GetPlayerFactionFromGoodwill(siteFile.Goodwill));

playerSites.Add(site);
Find.WorldObjects.Add(site);
}
catch (Exception e) { Logger.Error($"Failed to spawn site at {siteFile.Tile}. Reason: {e}"); }
SpawnSingleSite(toAdd);
}
}

public static void ClearAllSites()
{
playerSites.Clear();
Site[] sites = Find.WorldObjects.Sites.Where(fetch => FactionValues.playerFactions.Contains(fetch.Faction) ||
fetch.Faction == Faction.OfPlayer).ToArray();

Site[] sites = Find.WorldObjects.Sites.Where(fetch => FactionValues.playerFactions.Contains(fetch.Faction)).ToArray();
foreach (Site site in sites) Find.WorldObjects.Remove(site);

sites = Find.WorldObjects.Sites.Where(fetch => fetch.Faction == Faction.OfPlayer).ToArray();
foreach (Site site in sites) Find.WorldObjects.Remove(site);
foreach (Site toRemove in sites)
{
SiteFile siteFile = new SiteFile();
siteFile.Tile = toRemove.Tile;
RemoveSingleSite(siteFile);
}
}

public static void SpawnSingleSite(SiteData siteData)
public static void SpawnSingleSite(SiteFile toAdd)
{
if (ClientValues.isReadyToPlay)
if (Find.WorldObjects.Sites.FirstOrDefault(fetch => fetch.Tile == toAdd.Tile) != null) return;
else
{
try
{
SitePartDef siteDef = SiteManager.GetDefForNewSite(siteData._siteFile.Type, siteData._siteFile.FactionFile != null);
SitePartDef siteDef = SiteManager.GetDefForNewSite(toAdd.Type, toAdd.FactionFile != null);
Site site = SiteMaker.MakeSite(sitePart: siteDef,
tile: siteData._siteFile.Tile,
tile: toAdd.Tile,
threatPoints: 1000,
faction: PlanetManagerHelper.GetPlayerFactionFromGoodwill(siteData._goodwill));
faction: PlanetManagerHelper.GetPlayerFactionFromGoodwill(toAdd.Goodwill));

playerSites.Add(site);
Find.WorldObjects.Add(site);
}
catch (Exception e) { Logger.Error($"Failed to spawn site at {siteData._siteFile.Tile}. Reason: {e}"); }
catch (Exception e) { Logger.Error($"Failed to spawn site at {toAdd.Tile}. Reason: {e}"); }
}
}

public static void RemoveSingleSite(SiteData siteData)
public static void RemoveSingleSite(SiteFile toRemove)
{
if (ClientValues.isReadyToPlay)
try
{
try
Site toGet = Find.WorldObjects.Sites.Find(fetch => fetch.Tile == toRemove.Tile && FactionValues.playerFactions.Contains(fetch.Faction));
if (!RimworldManager.CheckIfMapHasPlayerPawns(toGet.Map))
{
Site toGet = playerSites.Find(x => x.Tile == siteData._siteFile.Tile);

playerSites.Remove(toGet);
if (playerSites.Contains(toGet)) playerSites.Remove(toGet);
Find.WorldObjects.Remove(toGet);
}
catch (Exception e) { Logger.Message($"Failed to remove site at {siteData._siteFile.Tile}. Reason: {e}"); }
else Logger.Warning($"Ignored removal of site at {toGet.Tile} because player was inside");
}
catch (Exception e) { Logger.Error($"Failed to remove site at {toRemove.Tile}. Reason: {e}"); }
}
}

Expand Down
Loading

0 comments on commit b0ad209

Please sign in to comment.