1+ // -----------------------------------------------------------------------
2+ // <copyright file="VisionInformationFix.cs" company="ExMod Team">
3+ // Copyright (c) ExMod Team. All rights reserved.
4+ // Licensed under the CC BY-SA 3.0 license.
5+ // </copyright>
6+ // -----------------------------------------------------------------------
7+ namespace Exiled . Events . Patches . Fixes
8+ {
9+ using System . Collections . Generic ;
10+ using System . Reflection . Emit ;
11+
12+ using API . Features . Pools ;
13+
14+ using CustomPlayerEffects ;
15+
16+ using HarmonyLib ;
17+
18+ using PlayerRoles . PlayableScps ;
19+
20+ using static HarmonyLib . AccessTools ;
21+
22+ /// <summary>
23+ /// Patches <see cref="VisionInformation.CheckIsInDarkness"/>.
24+ /// Fix for effects that blind the player are not perceived as blindness.
25+ /// Bug reported to NW (https://git.scpslgame.com/northwood-qa/scpsl-bug-reporting/-/issues/3125).
26+ /// </summary>
27+ [ HarmonyPatch ( typeof ( VisionInformation ) , nameof ( VisionInformation . CheckIsInDarkness ) ) ]
28+ internal class VisionInformationFix
29+ {
30+ private static IEnumerable < CodeInstruction > Transpiler ( IEnumerable < CodeInstruction > instructions , ILGenerator generator )
31+ {
32+ List < CodeInstruction > newInstructions = ListPool < CodeInstruction > . Pool . Get ( instructions ) ;
33+
34+ LocalBuilder effectsController = generator . DeclareLocal ( typeof ( PlayerEffectsController ) ) ;
35+
36+ Label retTrue = generator . DefineLabel ( ) ;
37+ Label @continue = generator . DefineLabel ( ) ;
38+
39+ newInstructions [ 0 ] . labels . Add ( @continue ) ;
40+
41+ newInstructions . InsertRange ( 0 , new CodeInstruction [ ]
42+ {
43+ // effectsController = hub.playerEffectsController;
44+ new ( OpCodes . Ldarg_0 ) ,
45+ new ( OpCodes . Ldfld , Field ( typeof ( ReferenceHub ) , nameof ( ReferenceHub . playerEffectsController ) ) ) ,
46+ new ( OpCodes . Dup ) ,
47+ new ( OpCodes . Stloc_S , effectsController ) ,
48+
49+ // if (effectsController.GetEffect<Flashed>().IsEnabled)
50+ // return true;
51+ new ( OpCodes . Callvirt , Method ( typeof ( PlayerEffectsController ) , nameof ( PlayerEffectsController . GetEffect ) ) . MakeGenericMethod ( typeof ( Flashed ) ) ) ,
52+ new ( OpCodes . Callvirt , PropertyGetter ( typeof ( Flashed ) , nameof ( Flashed . IsEnabled ) ) ) ,
53+ new ( OpCodes . Brtrue_S , retTrue ) ,
54+
55+ // if (effectsController.GetEffect<SeveredEyes>().IsEnabled)
56+ // return true;
57+ new ( OpCodes . Ldloc_S , effectsController ) ,
58+ new ( OpCodes . Callvirt , Method ( typeof ( PlayerEffectsController ) , nameof ( PlayerEffectsController . GetEffect ) ) . MakeGenericMethod ( typeof ( SeveredEyes ) ) ) ,
59+ new ( OpCodes . Callvirt , PropertyGetter ( typeof ( SeveredEyes ) , nameof ( SeveredEyes . IsEnabled ) ) ) ,
60+ new ( OpCodes . Brtrue_S , retTrue ) ,
61+
62+ // if (effectsController.GetEffect<Blindness>().Intensity >= Blindness.MaxHealableIntensity)
63+ // return true;
64+ new ( OpCodes . Ldloc_S , effectsController ) ,
65+ new ( OpCodes . Callvirt , Method ( typeof ( PlayerEffectsController ) , nameof ( PlayerEffectsController . GetEffect ) ) . MakeGenericMethod ( typeof ( Blindness ) ) ) ,
66+ new ( OpCodes . Callvirt , PropertyGetter ( typeof ( Blindness ) , nameof ( Blindness . Intensity ) ) ) ,
67+ new ( OpCodes . Ldc_I4 , ( int ) Blindness . MaxHealableIntensity ) ,
68+ new ( OpCodes . Bge_S , retTrue ) ,
69+
70+ new ( OpCodes . Br_S , @continue ) ,
71+ new CodeInstruction ( OpCodes . Ldc_I4_1 ) . WithLabels ( retTrue ) ,
72+ new ( OpCodes . Ret ) ,
73+ } ) ;
74+
75+ for ( int z = 0 ; z < newInstructions . Count ; z ++ )
76+ yield return newInstructions [ z ] ;
77+
78+ ListPool < CodeInstruction > . Pool . Return ( newInstructions ) ;
79+ }
80+ }
81+ }
0 commit comments