Skip to content

Commit 491e572

Browse files
jneb802claude
andcommitted
fix: sync ZoneLocation radii/ClearArea from prefab's Location component
LocationConfig.ExteriorRadius, InteriorRadius, and ClearArea are now nullable. GetZoneLocation falls back to the previous defaults (10f/0f/false) when null so existing callers are unaffected. CustomLocation now syncs these three fields from the prefab's Location component onto the ZoneLocation whenever the corresponding config field is unset (null). Applied in both constructors: - Non-SoftReference ctor: sync runs immediately after GetZoneLocation, using the component that was authored on (or added to) the prefab. - SoftReference ctor: sync runs inside OnLocationResolve once the prefab asset is actually loaded. The LocationConfig reference is stored so the callback can check which fields the caller left null. Before this change, ZoneLocation.m_exteriorRadius (used by world-gen terrain-delta sampling and spawn-time ClearArea/slope sampling) could diverge from Location.m_exteriorRadius authored in Unity Editor, leading to placements that failed terrain checks at a radius smaller than the authored footprint and vegetation clearing that stopped short. Semantics: config wins when set; otherwise prefab component wins; otherwise the original defaults apply. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5a84863 commit 491e572

2 files changed

Lines changed: 36 additions & 11 deletions

File tree

JotunnLib/Configs/LocationConfig.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ public class LocationConfig
4444

4545
/// <summary>
4646
/// Radius of the location. Terrain delta is calculated within this circle.
47+
/// If null, falls back to the prefab's <see cref="Location"/> component value when one exists.
4748
/// </summary>
48-
public float ExteriorRadius { get; set; } = 10f;
49+
public float? ExteriorRadius { get; set; }
4950

5051
/// <summary>
5152
/// Attempt to place in the central zone first
@@ -129,9 +130,10 @@ public class LocationConfig
129130
public bool HasInterior { get; set; }
130131

131132
/// <summary>
132-
/// Radius of the interior attached to the location
133+
/// Radius of the interior attached to the location.
134+
/// If null, falls back to the prefab's <see cref="Location"/> component value when one exists.
133135
/// </summary>
134-
public float InteriorRadius { get; set; }
136+
public float? InteriorRadius { get; set; }
135137

136138
/// <summary>
137139
/// Environment string used by the interior
@@ -159,9 +161,10 @@ public class LocationConfig
159161
public bool IconAlways { get; set; }
160162

161163
/// <summary>
162-
/// Enable to forbid Vegetation from spawning inside the circle defined by <see cref="ExteriorRadius"/>
164+
/// Enable to forbid Vegetation from spawning inside the circle defined by <see cref="ExteriorRadius"/>.
165+
/// If null, falls back to the prefab's <see cref="Location"/> component value when one exists.
163166
/// </summary>
164-
public bool ClearArea { get; set; }
167+
public bool? ClearArea { get; set; }
165168

166169
/// <summary>
167170
/// Create a new <see cref="LocationConfig"/>
@@ -218,9 +221,9 @@ public ZoneSystem.ZoneLocation GetZoneLocation()
218221
m_biomeArea = BiomeArea,
219222
m_quantity = Quantity,
220223
m_prioritized = Priotized,
221-
m_interiorRadius = InteriorRadius,
222-
m_exteriorRadius = ExteriorRadius,
223-
m_clearArea = ClearArea,
224+
m_interiorRadius = InteriorRadius ?? 0f,
225+
m_exteriorRadius = ExteriorRadius ?? 10f,
226+
m_clearArea = ClearArea ?? false,
224227
m_centerFirst = CenterFirst,
225228
m_forestTresholdMin = ForestTresholdMin,
226229
m_forestTresholdMax = ForestTrasholdMax,

JotunnLib/Entities/CustomLocation.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,18 +95,20 @@ public CustomLocation(GameObject exteriorPrefab, GameObject interiorPrefab, bool
9595
else
9696
{
9797
Location = exteriorPrefab.AddComponent<Location>();
98-
Location.m_clearArea = locationConfig.ClearArea;
99-
Location.m_exteriorRadius = locationConfig.ExteriorRadius;
98+
if (locationConfig.ClearArea.HasValue) Location.m_clearArea = locationConfig.ClearArea.Value;
99+
if (locationConfig.ExteriorRadius.HasValue) Location.m_exteriorRadius = locationConfig.ExteriorRadius.Value;
100100
Location.m_interiorPrefab = interiorPrefab;
101101
Location.m_hasInterior = locationConfig.HasInterior;
102-
Location.m_interiorRadius = locationConfig.InteriorRadius;
102+
if (locationConfig.InteriorRadius.HasValue) Location.m_interiorRadius = locationConfig.InteriorRadius.Value;
103103
Location.m_interiorEnvironment = locationConfig.InteriorEnvironment;
104104
}
105105

106106
ZoneLocation = locationConfig.GetZoneLocation();
107107
ZoneLocation.m_prefab = new SoftReference<GameObject>(AssetManager.Instance.AddAsset(exteriorPrefab));
108108
ZoneLocation.m_prefabName = exteriorPrefab.name;
109109

110+
SyncZoneLocationFromComponent(Location, locationConfig);
111+
110112
FixReference = fixReference;
111113
}
112114

@@ -124,6 +126,7 @@ public CustomLocation(SoftReference<GameObject> softReferencePrefab, bool fixRef
124126
return;
125127
}
126128

129+
_locationConfig = locationConfig;
127130
var parent = ZoneManager.Instance.LocationContainer.transform;
128131
AssetManager.Instance.ResolveMocksOnLoad(softReferencePrefab, parent, OnLocationResolve);
129132
Name = softReferencePrefab.Name;
@@ -134,14 +137,33 @@ public CustomLocation(SoftReference<GameObject> softReferencePrefab, bool fixRef
134137
SoftReference = true;
135138
}
136139

140+
private readonly LocationConfig _locationConfig;
141+
137142
private void OnLocationResolve(GameObject gameObject)
138143
{
144+
if (gameObject.TryGetComponent<Location>(out var location))
145+
{
146+
SyncZoneLocationFromComponent(location, _locationConfig);
147+
}
148+
139149
if (gameObject.TryGetComponent<ZoneSystem.ZoneLocation>(out var zoneLocation))
140150
{
141151
ZoneManager.Instance.PrepareLocation(zoneLocation, SourceMod);
142152
}
143153
}
144154

155+
private void SyncZoneLocationFromComponent(Location location, LocationConfig locationConfig)
156+
{
157+
if (location == null || ZoneLocation == null)
158+
{
159+
return;
160+
}
161+
162+
if (!locationConfig.ExteriorRadius.HasValue) ZoneLocation.m_exteriorRadius = location.m_exteriorRadius;
163+
if (!locationConfig.InteriorRadius.HasValue) ZoneLocation.m_interiorRadius = location.m_interiorRadius;
164+
if (!locationConfig.ClearArea.HasValue) ZoneLocation.m_clearArea = location.m_clearArea;
165+
}
166+
145167
/// <summary>
146168
/// Helper method to determine if a location prefab with a given name is a custom location created with Jötunn.
147169
/// </summary>

0 commit comments

Comments
 (0)