-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathDoorBreachComponent.cs
More file actions
239 lines (204 loc) · 8.58 KB
/
Copy pathDoorBreachComponent.cs
File metadata and controls
239 lines (204 loc) · 8.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using BepInEx.Logging;
using Comfort.Common;
using DoorBreach;
using EFT;
using EFT.Interactive;
using Newtonsoft.Json;
using UnityEngine;
#pragma warning disable IDE0044 // Add readonly modifier
#pragma warning disable IDE0007 // Use implicit type
namespace BackdoorBandit
{
internal class DoorBreachComponent : MonoBehaviour
{
private static int doorCount = 0;
private static int invalidStateCount = 0;
private static int inoperableCount = 0;
private static int invalidLayerCount = 0;
private static int containerCount = 0;
private static int invalidContainers = 0;
private static int inoperatableContainers = 0;
private static int invalidContainerLayer = 0;
private static int trunkCount = 0;
private static int invalidCarTrunks = 0;
private static int inoperatableTrunks = 0;
private static int invalidTrunkLayer = 0;
internal static HashSet<string> GrenadeLaunchers;
internal static HashSet<string> MeleeWeapons;
internal static HashSet<string> ShotgunWeapons;
internal static HashSet<string> OtherWeapons;
internal static HashSet<string> ApplicableWeapons;
internal static ManualLogSource Logger
{
get; private set;
}
private DoorBreachComponent()
{
if (Logger == null)
{
Logger = BepInEx.Logging.Logger.CreateLogSource(nameof(DoorBreachComponent));
}
}
public void Awake()
{
doorCount = 0;
invalidStateCount = 0;
inoperableCount = 0;
invalidLayerCount = 0;
containerCount = 0;
invalidContainers = 0;
inoperatableContainers = 0;
invalidContainerLayer = 0;
trunkCount = 0;
invalidCarTrunks = 0;
inoperatableTrunks = 0;
invalidTrunkLayer = 0;
ApplicableWeapons = new HashSet<string>();
OtherWeapons = new HashSet<string>();
GrenadeLaunchers = new HashSet<string>();
MeleeWeapons = new HashSet<string>();
ShotgunWeapons = new HashSet<string>();
LoadHashSetFromJson(ref GrenadeLaunchers, "GrenadeLaunchers.json");
LoadHashSetFromJson(ref MeleeWeapons, "MeleeWeapons.json");
LoadHashSetFromJson(ref ShotgunWeapons, "ShotgunWeapons.json");
LoadHashSetFromJson(ref OtherWeapons, "OtherWeapons.json");
SetupApplicableWeapons();
ProcessObjectsOfType<Door>("Doors", DoorBreachPlugin.interactiveLayer);
ProcessObjectsOfType<LootableContainer>("Containers", DoorBreachPlugin.interactiveLayer);
ProcessObjectsOfType<Trunk>("Trunks", DoorBreachPlugin.interactiveLayer);
LogStatistics("Doors", doorCount, invalidStateCount, inoperableCount, invalidLayerCount);
LogStatistics("Containers", containerCount, invalidContainers, inoperatableContainers, invalidContainerLayer);
LogStatistics("Trunks", trunkCount, invalidCarTrunks, inoperatableTrunks, invalidTrunkLayer);
}
private void ProcessObjectsOfType<T>(string objectType, int interactiveLayer) where T : Component
{
int count = 0;
int invalidCount = 0;
int inoperableCount = 0;
int invalidLayerCount = 0;
FindObjectsOfType<T>().ExecuteForEach(obj =>
{
count++;
if (!IsValidObject(obj, ref invalidCount, ref inoperableCount, ref invalidLayerCount, interactiveLayer))
return;
var randHitPoints = UnityEngine.Random.Range(DoorBreachPlugin.MinHitPoints.Value, DoorBreachPlugin.MaxHitPoints.Value);
var hitpoints = obj.gameObject.GetOrAddComponent<Hitpoints>();
hitpoints.hitpoints = randHitPoints;
if (obj is Door door)
{
door.OnEnable();
}
else if (obj is LootableContainer container)
{
container.OnEnable();
}
else if (obj is Trunk trunk)
{
trunk.OnEnable();
}
});
LogStatistics(objectType, count, invalidCount, inoperableCount, invalidLayerCount);
}
private bool IsOperatable<T>(T obj) where T : Component
{
if (obj is Door door)
{
return door.Operatable;
}
else if (obj is LootableContainer container)
{
return container.Operatable;
}
else if (obj is Trunk trunk)
{
return trunk.Operatable;
}
// Default case: assume operatable if not one of the specific types
return true;
}
private bool IsValidObject<T>(T obj, ref int invalidCount, ref int inoperableCount, ref int invalidLayerCount, int interactiveLayer) where T : Component
{
if (obj is Door door && !IsValidDoorState(door))
{
invalidCount++;
return false;
}
if (obj is LootableContainer container && !IsValidContainerState(container))
{
invalidCount++;
return false;
}
if (obj is Trunk trunk && !IsValidTrunkState(trunk))
{
invalidCount++;
return false;
}
if (!IsOperatable(obj))
{
inoperableCount++;
return false;
}
if (!IsValidLayer(obj, interactiveLayer))
{
invalidLayerCount++;
return false;
}
return true;
}
private bool IsValidDoorState(Door door) =>
door.DoorState == EDoorState.Shut || door.DoorState == EDoorState.Locked || door.DoorState == EDoorState.Breaching || door.DoorState == EDoorState.Open;
private bool IsValidContainerState(LootableContainer container) =>
container.DoorState == EDoorState.Shut || container.DoorState == EDoorState.Locked || container.DoorState == EDoorState.Breaching;
private bool IsValidTrunkState(Trunk trunk) =>
trunk.DoorState == EDoorState.Shut || trunk.DoorState == EDoorState.Locked || trunk.DoorState == EDoorState.Breaching;
private bool IsValidLayer<T>(T obj, int interactiveLayer) where T : Component =>
obj.gameObject.layer == interactiveLayer;
private void LogStatistics(string objectType, int totalCount, int invalidStateCount, int inoperableCount, int invalidLayerCount)
{
Logger.LogInfo($"Total {objectType}: {totalCount}");
Logger.LogInfo($"Invalid State {objectType}: {invalidStateCount}");
Logger.LogInfo($"Inoperable {objectType}: {inoperableCount}");
Logger.LogInfo($"Invalid Layer {objectType}: {invalidLayerCount}");
}
public static void Enable()
{
if (Singleton<IBotGame>.Instantiated)
{
var gameWorld = Singleton<GameWorld>.Instance;
gameWorld.GetOrAddComponent<DoorBreachComponent>();
}
}
private void LoadHashSetFromJson(ref HashSet<string> hashSet, string jsonFileName)
{
string dllDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string jsonPath = Path.Combine(dllDirectory, jsonFileName);
if (File.Exists(jsonPath))
{
string jsonContent = File.ReadAllText(jsonPath);
hashSet = JsonConvert.DeserializeObject<HashSet<string>>(jsonContent);
}
else
{
Logger.LogError($"JSON file not found: {jsonFileName}");
}
}
internal static void SetupApplicableWeapons()
{
ApplicableWeapons.UnionWith(DoorBreachComponent.MeleeWeapons);
ApplicableWeapons.UnionWith(DoorBreachComponent.GrenadeLaunchers);
ApplicableWeapons.UnionWith(DoorBreachComponent.ShotgunWeapons);
ApplicableWeapons.UnionWith(DoorBreachComponent.OtherWeapons);
#if DEBUG
//print out applicable weapons hashes to console
Logger.LogInfo("Applicable Weapons:");
foreach (var weapon in ApplicableWeapons)
{
Logger.LogInfo(weapon);
}
#endif
}
}
}