Area of influence depends on followers MobState (#1439)
* simple anti-religion zone shader * observers refactor
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user