Area of influence depends on followers MobState (#1439)

* simple anti-religion zone shader

* observers refactor
This commit is contained in:
Red
2025-06-18 21:46:58 +03:00
committed by GitHub
parent 54307574c3
commit 3a4bbcb289
11 changed files with 179 additions and 156 deletions

View File

@@ -25,12 +25,15 @@ public sealed class CP14ReligionVisionOverlay : Overlay
public override bool RequestScreenTexture => true;
public override OverlaySpace Space => OverlaySpace.WorldSpace;
private readonly ProtoId<CP14ReligionPrototype>? _religion = null;
private readonly ProtoId<CP14ReligionPrototype>? _religion;
private readonly ShaderInstance _religionShader;
private readonly Vector2[] _positions = new Vector2[MaxCount];
private readonly float[] _radii = new float[MaxCount];
private int _count = 0;
private int _count;
private readonly Vector2[] _antiPositions = new Vector2[MaxCount];
private readonly float[] _antiRadii = new float[MaxCount];
private int _antiCount;
public CP14ReligionVisionOverlay()
{
@@ -49,20 +52,21 @@ public sealed class CP14ReligionVisionOverlay : Overlay
if (args.Viewport.Eye == null)
return false;
_count = 0;
var clusters = new List<Cluster>();
var antiClusters = new List<Cluster>();
var religionQuery = _entManager.AllEntityQueryEnumerator<CP14ReligionObserverComponent, TransformComponent>();
while (religionQuery.MoveNext(out var uid, out var rel, out var xform))
while (religionQuery.MoveNext(out var uid, out var observer, out var xform))
{
if (_religion is null)
continue;
var observation = rel.Observation;
if (!observation.ContainsKey(_religion.Value))
if (observer.Religion is null)
continue;
if (!rel.Active || xform.MapID != args.MapId)
if (observer.Radius <= 0f)
continue;
if (!observer.Active || xform.MapID != args.MapId)
continue;
var mapPos = _transform.GetWorldPosition(uid);
@@ -72,23 +76,40 @@ public sealed class CP14ReligionVisionOverlay : Overlay
var tempCoords = args.Viewport.WorldToLocal(mapPos);
tempCoords.Y = args.Viewport.Size.Y - tempCoords.Y; // Local space to fragment space.
// try find cluster to merge with
bool merged = false;
foreach (var cluster in clusters)
if (observer.Religion.Value == _religion.Value)
{
if ((cluster.Position - tempCoords).Length() < 150f)
// try find cluster to merge with
bool merged = false;
foreach (var cluster in clusters)
{
cluster.Add(tempCoords, rel.Observation[_religion.Value]);
merged = true;
break;
if ((cluster.Position - tempCoords).Length() < 150f)
{
cluster.Add(tempCoords, observer.Radius);
merged = true;
break;
}
}
if (!merged && clusters.Count < MaxCount)
clusters.Add(new Cluster(tempCoords, observer.Radius));
}
else
{
// try find cluster to merge with
bool merged = false;
foreach (var antiCluster in antiClusters)
{
if ((antiCluster.Position - tempCoords).Length() < 150f)
{
antiCluster.Add(tempCoords, observer.Radius);
merged = true;
break;
}
}
if (!merged)
clusters.Add(new Cluster(tempCoords, rel.Observation[_religion.Value]));
if (clusters.Count >= MaxCount)
break;
if (!merged && antiClusters.Count < MaxCount)
antiClusters.Add(new Cluster(tempCoords, observer.Radius));
}
}
_count = 0;
@@ -99,6 +120,14 @@ public sealed class CP14ReligionVisionOverlay : Overlay
_count++;
}
_antiCount = 0;
foreach (var antiCluster in antiClusters)
{
_antiPositions[_antiCount] = antiCluster.Position;
_antiRadii[_antiCount] = antiCluster.Radius;
_antiCount++;
}
return true;
}
@@ -112,9 +141,15 @@ public sealed class CP14ReligionVisionOverlay : Overlay
_religionShader?.SetParameter("shaderColor", visionComponent.ShaderColor);
_religionShader?.SetParameter("renderScale", args.Viewport.RenderScale * args.Viewport.Eye.Scale);
_religionShader?.SetParameter("count", _count);
_religionShader?.SetParameter("position", _positions);
_religionShader?.SetParameter("radius", _radii);
_religionShader?.SetParameter("anticount", _antiCount);
_religionShader?.SetParameter("antiposition", _antiPositions);
_religionShader?.SetParameter("antiradius", _antiRadii);
_religionShader?.SetParameter("SCREEN_TEXTURE", ScreenTexture);
var worldHandle = args.WorldHandle;