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

@@ -12,7 +12,10 @@ namespace Content.Shared._CP14.Religion.Components;
public sealed partial class CP14ReligionObserverComponent : Component
{
[DataField, AutoNetworkedField]
public Dictionary<ProtoId<CP14ReligionPrototype>, float> Observation = new(); //DAMNATION
public ProtoId<CP14ReligionPrototype>? Religion;
[DataField, AutoNetworkedField]
public float Radius = 5f;
[DataField, AutoNetworkedField]
public bool Active = true;

View File

@@ -11,8 +11,5 @@ public sealed partial class CP14ReligionPrototype : IPrototype
[IdDataField] public string ID { get; } = default!;
[DataField]
public float FollowerObservationRadius = 8f;
[DataField]
public float AltarObservationRadius = 25f;
public float FollowerObservationRadius = 10f;
}

View File

@@ -48,50 +48,6 @@ public abstract partial class CP14SharedReligionGodSystem
},
});
}
public bool TryConvertAltar(EntityUid target, ProtoId<CP14ReligionPrototype> religion)
{
if (!_proto.TryIndex(religion, out var indexedReligion))
return false;
EnsureComp<CP14ReligionAltarComponent>(target, out var altar);
if (!altar.CanBeConverted)
return false;
var oldReligion = altar.Religion;
altar.Religion = religion;
Dirty(target, altar);
EditObservation(target, religion, indexedReligion.AltarObservationRadius);
var ev = new CP14ReligionChangedEvent(oldReligion, religion);
RaiseLocalEvent(target, ev);
return true;
}
public void DeconvertAltar(EntityUid target)
{
if (!TryComp<CP14ReligionAltarComponent>(target, out var altar))
return;
if (altar.Religion is null)
return;
if (!_proto.TryIndex(altar.Religion, out var indexedReligion))
return;
EditObservation(target, altar.Religion.Value, -indexedReligion.AltarObservationRadius);
var oldReligion = altar.Religion;
altar.Religion = null;
var ev = new CP14ReligionChangedEvent(oldReligion, null);
RaiseLocalEvent(target, ev);
Dirty(target, altar);
}
}
[Serializable, NetSerializable]

View File

@@ -40,16 +40,30 @@ public abstract partial class CP14SharedReligionGodSystem
if (ent.Comp.Religion is null)
return;
EnsureComp<CP14ReligionObserverComponent>(ent, out var observer);
if (!_proto.TryIndex(observer.Religion, out var indexedReligion))
return;
var baseObservation = indexedReligion.FollowerObservationRadius;
switch (args.NewMobState)
{
case MobState.Alive:
observer.Radius = baseObservation;
break;
case MobState.Critical:
SendMessageToGods(ent.Comp.Religion.Value, Loc.GetString("cp14-critical-follower-message", ("name", MetaData(ent).EntityName)), ent);
observer.Radius = baseObservation * 0.25f;
break;
case MobState.Dead:
SendMessageToGods(ent.Comp.Religion.Value, Loc.GetString("cp14-dead-follower-message", ("name", MetaData(ent).EntityName)), ent);
observer.Radius = 0f;
break;
}
Dirty(ent.Owner, observer);
}
private void OnGetAltVerbs(EntityUid uid, CP14ReligionFollowerComponent component, GetVerbsEvent<AlternativeVerb> args)
@@ -152,12 +166,14 @@ public abstract partial class CP14SharedReligionGodSystem
return false;
EnsureComp<CP14ReligionFollowerComponent>(pending, out var follower);
EnsureComp<CP14ReligionObserverComponent>(pending, out var observer);
observer.Religion = indexedReligion;
observer.Radius = indexedReligion.FollowerObservationRadius;
var oldReligion = follower.Religion;
follower.Religion = pending.Comp.Religion;
Dirty(pending, follower);
EditObservation(pending, pending.Comp.Religion.Value, indexedReligion.FollowerObservationRadius);
Dirty(pending, observer);
var ev = new CP14ReligionChangedEvent(oldReligion, pending.Comp.Religion);
RaiseLocalEvent(pending, ev);
@@ -178,11 +194,9 @@ public abstract partial class CP14SharedReligionGodSystem
if (follower.Religion is null)
return;
if (!_proto.TryIndex(follower.Religion, out var indexedReligion))
return;
RemCompDeferred<CP14ReligionObserverComponent>(target);
SendMessageToGods(follower.Religion.Value, Loc.GetString("cp14-remove-follower-message", ("name", MetaData(target).EntityName)), target);
EditObservation(target, follower.Religion.Value, -indexedReligion.FollowerObservationRadius);
var oldReligion = follower.Religion;
follower.Religion = null;

View File

@@ -28,28 +28,6 @@ public abstract partial class CP14SharedReligionGodSystem
args.Visibility &= ~MenuVisibility.NoFov;
}
public void EditObservation(EntityUid target, ProtoId<CP14ReligionPrototype> religion, float range)
{
EnsureComp<CP14ReligionObserverComponent>(target, out var observer);
if (observer.Observation.ContainsKey(religion))
{
var newRange = Math.Clamp(observer.Observation[religion] + range, 0, float.MaxValue);
if (newRange <= 0)
observer.Observation.Remove(religion);
else
observer.Observation[religion] = newRange;
}
else
{
// Otherwise, add a new observation for the religion.
observer.Observation.Add(religion, range);
}
Dirty(target, observer);
}
public bool InVision(EntityUid target, Entity<CP14ReligionEntityComponent> user)
{
var position = Transform(target).Coordinates;
@@ -62,29 +40,27 @@ public abstract partial class CP14SharedReligionGodSystem
if (!HasComp<CP14ReligionVisionComponent>(user))
return true;
if (user.Comp.Religion is null)
return true;
var userXform = Transform(user);
var query = EntityQueryEnumerator<CP14ReligionObserverComponent, TransformComponent>();
while (query.MoveNext(out var uid, out var observer, out var xform))
{
if (!observer.Active)
if (!observer.Active || observer.Religion is null || observer.Radius <= 0f)
continue;
if (xform.MapID != userXform.MapID)
continue;
if (user.Comp.Religion is null)
if (observer.Religion.Value != user.Comp.Religion.Value)
continue;
if (!observer.Observation.ContainsKey(user.Comp.Religion.Value))
continue;
var obsPos = _transform.GetWorldPosition(uid);
var targetPos = coords.Position;
if (Vector2.Distance(obsPos, targetPos) <= observer.Observation[user.Comp.Religion.Value])
if (Vector2.Distance(obsPos, targetPos) <= observer.Radius)
{
// If the observer is within range of the target, they can see it.
return true;
return observer.Religion.Value == user.Comp.Religion.Value;
}
}