using System; using XRL.UI; using XRL.World.Capabilities; using XRL.World.Parts; // this is 95% copy/pasted from decompiled vanilla HeightenedHearingEffect // only thing added was a reference to the implant because it has the part rather than the implantee namespace XRL.World.Effects { [Serializable] public class CyberneticHeightenedHearingEffect : Effect { public bool bIdentified; public int Level = 1; public GameObject Listener; public GameObject Implant; public CyberneticHeightenedHearingEffect() => Duration = 1; public CyberneticHeightenedHearingEffect(int Level, GameObject Listener) : this() { this.Level = Level; this.Listener = Listener; } public CyberneticHeightenedHearingEffect(int Level, GameObject Listener, GameObject Implant) : this() { this.Level = Level; this.Listener = Listener; this.Implant = Implant; } public override int GetEffectType() => 2048; public override bool SameAs(Effect e) => false; public override string GetDescription() => (string)null; private bool BadListener() { Listener = null; Object.RemoveEffect(this); return true; } public bool CheckListen() { if (!GameObject.validate(ref Listener) || !Listener.IsPlayer()) { return BadListener(); } if (!(Implant.GetPart("CyberneticsHearingAid") is CyberneticsHearingAid part)) { return BadListener(); } int num = Object.DistanceTo(Listener); if (num > part.Radius) { return BadListener(); } if (bIdentified) { CheckInterruptAutoExplore(); return true; } if (Object.CurrentCell == null) { return true; } if (((int)((100 + (10 * Level)) / Math.Pow(num + 9, 2.0) * 100.0)).in100()) { bIdentified = true; CheckInterruptAutoExplore(); } return false; } public void CheckInterruptAutoExplore() { if (!bIdentified || !GameObject.validate(ref Listener) || !Listener.IsPlayer() || !AutoAct.IsInterruptable() || AutoAct.IsGathering() || !Listener.IsRelevantHostile(Object)) return; AddPlayerMessage(Listener.GenerateSpotMessage(Object, verb: "hear")); AutoAct.Interrupt(null, null, Object); } public override bool Apply(GameObject Object) { if (Object.pBrain != null) Object.pBrain.Hibernating = false; CheckListen(); return true; } public override void Register(GameObject Object) { Object.RegisterEffectEvent(this, "EndTurn"); base.Register(Object); } public override void Unregister(GameObject Object) { Object.UnregisterEffectEvent(this, "EndTurn"); base.Unregister(Object); } public bool HeardAndNotSeen(GameObject obj) { if (obj == null) return false; if (!obj.IsVisible()) return true; Cell currentCell = obj.CurrentCell; return currentCell != null && (!currentCell.IsLit() || !currentCell.IsExplored()); } public override bool FinalRender(RenderEvent E, bool bAlt) { if (!HeardAndNotSeen(Object) || !Object.CanHypersensesDetect()) { return true; } if (bIdentified) { E.HighestLayer = 0; Object.Render(E); E.ColorString = "&K"; E.DetailColor = "K"; E.RenderString = Object.pRender.RenderString; E.Tile = !Options.UseTiles ? null : Object.pRender.Tile; E.CustomDraw = true; } else { E.RenderString = "&K?"; E.Tile = null; E.CustomDraw = true; } return false; } public override bool FireEvent(Event E) { if (E.ID == "EndTurn" && Object != null) CheckListen(); return base.FireEvent(E); } } }