From 4e651b074c017745844e32f66bc63c49291149ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lilian=20J=C3=B3nsd=C3=B3ttir?= Date: Mon, 18 Dec 2023 22:26:05 -0800 Subject: [PATCH] CyberneticHearingAid 1.0.0 --- .../CyberneticHeightenedHearingEffect.cs | 157 ++++++++++++++++++ CyberneticHearingAid/CyberneticsHearingAid.cs | 50 ++++++ CyberneticHearingAid/ObjectBlueprints.xml | 11 ++ .../Textures/Items/hearingaid.png | Bin 0 -> 726 bytes CyberneticHearingAid/manifest.json | 8 + CyberneticHearingAid/preview.png | Bin 0 -> 11983 bytes CyberneticHearingAid/workshop.json | 8 + 7 files changed, 234 insertions(+) create mode 100755 CyberneticHearingAid/CyberneticHeightenedHearingEffect.cs create mode 100755 CyberneticHearingAid/CyberneticsHearingAid.cs create mode 100755 CyberneticHearingAid/ObjectBlueprints.xml create mode 100755 CyberneticHearingAid/Textures/Items/hearingaid.png create mode 100755 CyberneticHearingAid/manifest.json create mode 100755 CyberneticHearingAid/preview.png create mode 100755 CyberneticHearingAid/workshop.json diff --git a/CyberneticHearingAid/CyberneticHeightenedHearingEffect.cs b/CyberneticHearingAid/CyberneticHeightenedHearingEffect.cs new file mode 100755 index 0000000..ece16ad --- /dev/null +++ b/CyberneticHearingAid/CyberneticHeightenedHearingEffect.cs @@ -0,0 +1,157 @@ +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); + } + } +} + diff --git a/CyberneticHearingAid/CyberneticsHearingAid.cs b/CyberneticHearingAid/CyberneticsHearingAid.cs new file mode 100755 index 0000000..1b76aec --- /dev/null +++ b/CyberneticHearingAid/CyberneticsHearingAid.cs @@ -0,0 +1,50 @@ +using System; + +using XRL.World.Effects; + +namespace XRL.World.Parts +{ + [Serializable] + public class CyberneticsHearingAid : IPart + { + public int Radius + { + get { return GetAvailableComputePowerEvent.GetFor(ParentObject.Implantee) + 20; } + } + public int Level + { + get { return GetAvailableComputePowerEvent.GetFor(ParentObject.Implantee) + 1; } + } + + public override bool SameAs(IPart p) => false; + + public override bool WantEvent(int ID, int cascade) => base.WantEvent(ID, cascade) || ID == EndTurnEvent.ID || ID == GetShortDescriptionEvent.ID; + + public override bool HandleEvent(EndTurnEvent E) + { + GameObject implantee = ParentObject.Implantee; + if (implantee?.IsPlayer() == true && !IsBroken() && !IsRusted() && !IsEMPed()) + { + Cell currentCell = implantee.CurrentCell; + if (currentCell?.OnWorldMap() == false) + { + foreach (var thing in currentCell.ParentZone.FastSquareSearch(currentCell.X, currentCell.Y, Radius, "Combat")) + { + if (implantee.DistanceTo(thing) <= Radius && !thing.HasEffect("CyberneticHeightenedHearingEffect")) + { + thing.ApplyEffect(new CyberneticHeightenedHearingEffect(Level, implantee, ParentObject)); + } + } + } + } + return base.HandleEvent(E); + } + + public override bool HandleEvent(GetShortDescriptionEvent E) + { + E.Postfix.AppendRules("Compute power on the local lattice increases this item's range."); + return base.HandleEvent(E); + } + public override bool AllowStaticRegistration() => false; + } +} diff --git a/CyberneticHearingAid/ObjectBlueprints.xml b/CyberneticHearingAid/ObjectBlueprints.xml new file mode 100755 index 0000000..77332b1 --- /dev/null +++ b/CyberneticHearingAid/ObjectBlueprints.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/CyberneticHearingAid/Textures/Items/hearingaid.png b/CyberneticHearingAid/Textures/Items/hearingaid.png new file mode 100755 index 0000000000000000000000000000000000000000..f7194430e94fa28ef8c37235d124d7c4991970a0 GIT binary patch literal 726 zcmV;{0xA88P)EX>4Tx04R}tkvmAkP!xv$rb4rtTK|Hf* z>74h8!>lAJ#OK801`SC3$aUG}H_kQ4kWK#3QVPdh^!Ey()lA#h$6Gs$Pqy9qH zWrgz=XSGsetvUG%gL!Qw&2`FQ#Ib|~k`N)IhB7L!5T#Qi#YBqkV;=q?$DbsZOs+B* zITlcb3d!+<|H1FwnuV!Jw^J|%bidg4#|RME1)6o+{yw(t<_X|`2ClTWzuEw1KS{5* zwa5|BzYSbmw>5bWxZD8-pLEHP9LY~96bium8GTa@7`O#`*WA6e?s576WN25*H^9Lm zFj}PE>mKj!>D=4DHLd;q07ad0m7--d3jhEB24YJ`L;wH)0002_L%V+f000SaNLh0L z01FcU01FcV0GgZ_00007bV*G`2j&3~0w)$sCI3nQ000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}00023Nkl#Te*+~|MjrYBnCT%_#`mEzJ^ z%mp&X8TPkr-mBIf^_L8sK4Fyth?vh?>pze<+>m*&&=F2bI<)eDQ|+bHC4z+8At&D0Ga9)MO^>@ z7kh~dAST2ArRqgjB7&IM*v~;WPfjqgCtuF%J#Gz*LIkbP zwb7ZTZE%_{WUkKaY#i*qS6S6El@>K6@(*JwSY>KoubyaI2s`t(pmc*@@+SB0fvl&L z_Mz9op-ZyUWLLJ*zV{Rz@9u+y1iYPES*fl{^NuBV65FKFbwexZlgGy!d&4UiPqf@H z_^a;~Gm2N|%ACq@G*5yYo{C1#j1cs@#_lFGug!j_r6=F}kXi8DS4mxC`=XXdSo9Hf zUYo=w3kbZ+v)bLUzP$Z@p*5fkZ*^IEje zO+WIujH-KI-3rzQyEP7`f#?Oi1wp7o_*Z4Q?w=NMW{31d|b*O7b0 z8B?vw+7hL!$uYcA)XUnI;Ml`4%GQDtm)snw#-BdaDaCg^|8A9|e4a+!?OK9Cb9GSJ zfHjv_f&^pZ%FY|JZ9?q3Q7HkI3J8-(*mD=5V)91dqUvcwQS=tQWlXOG97_B=MxB=$+tIep%&JK}M zdF`~23HP=l<<++&Gkgm2_Ne@*xhzDkU2Do=ukK#01fN$~krO=gJJsD=vp{d65uHu}a~qN4=SS!D163|j)U_{MbC10(KAI_fa<}gM zgSP#!z@e29uF*)Qf#7b2aS@@bH6*l&~ee~8#?!u?X zfkC?onrn2>-s|0scN&8{USsP4guI^L2PO+3B_b*^ZGJhNbU z-G>@uE*!lfHA=Y0y2K*Q)hx0_pi?7$RsLbEZacFonKK48GFSoWfi83fOqTOC2y-)h~JcAZp>dh}74IHfJGx8%< zss@TEmaF+55$~9k1sd+;H}O4p-0}9*8HyG3XT8Kg#e>oq#LZ8Q-aJ-QbAD9nlBS5$ zPadaLDx5E#Z=%3O(0C=Zn3Lv$<+Vkoeg+TSW-w?E2b2D8c*!W?dG=fH=*^Czd4owA%sC zS!*Vyu5uVN^HkK+R0=+J<(WygrOo6vLe5`0VN%~brMYl_FEO2jI0CCuSO z`bFXsI&ErAGE~ZH?tM=F3-`TwOZXWoz@YA$hyK&s`cqH4jJ^&%p7BxyzfxDB_>5<^ zBi%}6zA&{SxQ$|#l=ViizX*L=UQk8vUr(V|A=6zgYTaKUAN<9E@v?8DT}W=`ZI3?x zGiMIDmTx?*#1zc0XFQnDI!C_z;(>5>nOvwXo}2DS4}_F`VVUc?fTG_?WzC08+c1cP zC@#8`2hdU&0`7mf1x4>P?d>!w6q&F;d&dky;EPdJ2+_HQZc(_wq*y2KyUJgXR$MND z4vUeb%qe8E?g+eaEDi>@=R$_YBQB+}%X@cqYazfet4wRVGwB-EcHav(XD4omX zdxY*6%dKI=`v$TPjPCP%5wb1JoQe@5>W;fZtT0pXg|PB@Vv9DLOl5u_L6r

sq#A{5h2$)d-$KB@sqMRT5s=uOGz>WFl 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 literal 0 HcmV?d00001 diff --git a/CyberneticHearingAid/workshop.json b/CyberneticHearingAid/workshop.json new file mode 100755 index 0000000..e1def31 --- /dev/null +++ b/CyberneticHearingAid/workshop.json @@ -0,0 +1,8 @@ +{ + "WorkshopId": 2721172552, + "Title": "Cybernetic Hearing Aid", + "Description": "Like the Enhanced Hearing mutation, but a cybernetic.", + "Tags": "Script,Cybernetic", + "Visibility": "0", + "ImagePath": "preview.png" +} \ No newline at end of file