44using MiraAPI . GameOptions ;
55using NewMod . Components . ScreenEffects ;
66using NewMod . Options . Roles . ShadeOptions ;
7+ using NewMod . Roles . NeutralRoles ;
8+ using NewMod . Utilities ;
9+ using Reactor . Networking . Attributes ;
10+ using Reactor . Utilities ;
711using Reactor . Utilities . Attributes ;
812using UnityEngine ;
913
@@ -15,67 +19,95 @@ public class ShadowZone(IntPtr ptr) : MonoBehaviour(ptr)
1519 public byte shadeId ;
1620 public float radius ;
1721 public float duration ;
18- public float _t ;
19- public bool _on ;
20- public static List < ShadowZone > zones = new ( ) ;
22+ private float timer ;
23+ private bool active ;
24+ public static readonly List < ShadowZone > zones = new ( ) ;
2125
2226 public void Awake ( )
2327 {
24- if ( ! zones . Contains ( this ) ) zones . Add ( this ) ;
28+ if ( ! zones . Contains ( this ) )
29+ zones . Add ( this ) ;
2530 }
2631
2732 public void OnDestroy ( )
2833 {
2934 zones . Remove ( this ) ;
3035 }
3136
32- public bool Contains ( Vector2 pos )
37+ private bool Contains ( Vector2 pos )
3338 {
3439 return Vector2 . Distance ( pos , ( Vector2 ) transform . position ) <= radius ;
3540 }
3641
3742 public void Update ( )
3843 {
39- _t += Time . deltaTime ;
40- if ( _t >= duration )
44+ timer += Time . deltaTime ;
45+ if ( timer >= duration )
4146 {
47+ Coroutines . Start ( CoroutinesHelper . RemoveCameraEffect ( Camera . main , 0f ) ) ;
48+ active = false ;
4249 Destroy ( gameObject ) ;
4350 return ;
4451 }
4552
4653 var lp = PlayerControl . LocalPlayer ;
47- if ( ! lp || lp . PlayerId == shadeId ) return ;
54+ var hud = HudManager . Instance ;
55+ var killButton = hud . KillButton ;
4856
4957 bool inside = Contains ( lp . GetTruePosition ( ) ) ;
50- var cam = Camera . main ;
51- var fx = cam . GetComponent < ShadowCrawlEffect > ( ) ;
52-
5358 var mode = OptionGroupSingleton < ShadeOptions > . Instance . Behavior ;
59+ var cam = Camera . main ;
5460
55- if ( inside && ! _on )
61+ if ( inside && ! active )
5662 {
57- if ( cam && fx == null ) cam . gameObject . AddComponent < ShadowCrawlEffect > ( ) ;
58-
59- if ( mode is ShadeOptions . ShadowMode . Invisible or ShadeOptions . ShadowMode . Both )
63+ cam . gameObject . AddComponent < ShadowFluxEffect > ( ) ;
64+ if ( lp . PlayerId == shadeId && lp . Data . Role is Shade )
6065 {
61- lp . SetInvisibility ( true ) ;
66+ if ( mode is ShadeOptions . ShadowMode . Invisible or ShadeOptions . ShadowMode . Both )
67+ {
68+ lp . cosmetics . SetPhantomRoleAlpha ( 0 ) ;
69+ lp . cosmetics . nameText . gameObject . SetActive ( false ) ;
70+ }
71+
72+ killButton . gameObject . SetActive ( true ) ;
73+ killButton . currentTarget = null ;
6274 }
75+ active = true ;
76+ }
6377
78+ if ( inside && active && lp . PlayerId == shadeId && lp . Data . Role is Shade )
79+ {
6480 if ( mode is ShadeOptions . ShadowMode . KillEnabled or ShadeOptions . ShadowMode . Both )
6581 {
66- lp . Data . Role . CanUseKillButton = true ;
67- }
82+ var list = new Il2CppSystem . Collections . Generic . List < PlayerControl > ( ) ;
83+ lp . Data . Role . GetPlayersInAbilityRangeSorted ( list ) ;
84+ var players = list . ToArray ( ) . Where ( p => p . PlayerId != lp . PlayerId && ! p . Data . IsDead ) . ToList ( ) ;
85+ var closest = players . Count > 0 ? players [ 0 ] : null ;
86+
87+ if ( killButton . currentTarget && killButton . currentTarget != closest )
88+ killButton . currentTarget . ToggleHighlight ( false , RoleTeamTypes . Impostor ) ;
6889
69- _on = true ;
90+ killButton . currentTarget = closest ;
91+ if ( closest != null )
92+ closest . ToggleHighlight ( true , RoleTeamTypes . Impostor ) ;
93+ }
7094 }
71- else if ( ! inside && _on )
95+ else if ( ! inside && active )
7296 {
73- if ( fx ) Destroy ( fx ) ;
74-
75- lp . SetInvisibility ( false ) ;
76- lp . Data . Role . CanUseKillButton = false ;
97+ Coroutines . Start ( CoroutinesHelper . RemoveCameraEffect ( cam , 0f ) ) ;
98+ if ( lp . PlayerId == shadeId )
99+ {
100+ lp . cosmetics . SetPhantomRoleAlpha ( 1 ) ;
101+ lp . cosmetics . nameText . gameObject . SetActive ( true ) ;
77102
78- _on = false ;
103+ if ( killButton . currentTarget )
104+ {
105+ killButton . currentTarget . ToggleHighlight ( false , RoleTeamTypes . Impostor ) ;
106+ killButton . currentTarget = null ;
107+ }
108+ killButton . gameObject . SetActive ( false ) ;
109+ }
110+ active = false ;
79111 }
80112 }
81113
@@ -89,9 +121,16 @@ public static ShadowZone Create(byte id, Vector2 pos, float r, float dur)
89121 go . transform . position = pos ;
90122 return z ;
91123 }
124+
125+ [ MethodRpc ( ( uint ) CustomRPC . DeployZone ) ]
126+ public static void RpcDeployZone ( PlayerControl source , Vector2 pos , float radius , float duration )
127+ {
128+ Create ( source . PlayerId , pos , radius , duration ) ;
129+ }
130+
92131 public static bool IsInsideAny ( Vector2 pos )
93132 {
94- return zones . Any ( a => a && a . Contains ( pos ) ) ;
133+ return zones . Any ( z => z && z . Contains ( pos ) ) ;
95134 }
96135 }
97136}
0 commit comments