Skip to content

Commit

Permalink
Initialization / v1.0 Release
Browse files Browse the repository at this point in the history
  • Loading branch information
LexTheGreat committed Feb 27, 2024
0 parents commit bac75fa
Show file tree
Hide file tree
Showing 15 changed files with 664 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# EditorConfig is awesome: https://EditorConfig.org

[*.cs]
csharp_new_line_before_open_brace = none
csharp_new_line_before_else = false
csharp_new_line_before_catch = false
csharp_new_line_before_finally = false
csharp_new_line_before_members_in_object_initializers = false
csharp_new_line_before_members_in_anonymous_types = false
csharp_new_line_between_query_expression_clauses = false
56 changes: 56 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Windows image file caches
Thumbs.db
ehthumbs.db

# Folder config file
Desktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Windows Installer files
*.cab
*.msi
*.msm
*.msp

# Windows shortcuts
*.lnk

# =========================
# Operating System Files
# =========================

# OSX
# =========================

.DS_Store
.AppleDouble
.LSOverride

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

# Project
bin
obj
.vscode
build.bat
lib
releasesetup
TODO.MD
9 changes: 9 additions & 0 deletions AiDisabler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using UnityEngine;

namespace AiDisabler {
public class AiDisablerBehaviour : MonoBehaviour {
public void Start() {
Plugin.Log.LogInfo("AiDisabler.Start() called!");
}
}
}
38 changes: 38 additions & 0 deletions AiDisabler.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AssemblyName>AiDisabler</AssemblyName>
<Description>Disable specific AI spawns</Description>
<Version>1.0.0</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<RestoreAdditionalProjectSources>
https://api.nuget.org/v3/index.json;
https://nuget.bepinex.dev/v3/index.json;
https://nuget.samboy.dev/v3/index.json
</RestoreAdditionalProjectSources>
<RootNamespace>AiDisabler</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.*" IncludeAssets="compile" />
<PackageReference Include="BepInEx.PluginInfoProps" Version="2.*" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3"/>
<Reference Include="Il2Cppmscorlib">
<HintPath>lib\Il2Cppmscorlib.dll</HintPath>
</Reference>
<Reference Include="0Harmony">
<HintPath>lib\0Harmony.dll</HintPath>
</Reference>
<Reference Include="UnityEngine">
<HintPath>lib\UnityEngine.dll</HintPath>
</Reference>
<Reference Include="UnityEngineCoreModule">
<HintPath>lib\UnityEngine.CoreModule.dll</HintPath>
</Reference>
<Reference Include="SonsAiVail">
<HintPath>lib\Sons.Ai.Vail.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
25 changes: 25 additions & 0 deletions AiDisabler.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.002.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AiDisabler", "AiDisabler.csproj", "{6ADC66E0-D8AC-4C2D-A166-E8C6861579ED}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6ADC66E0-D8AC-4C2D-A166-E8C6861579ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6ADC66E0-D8AC-4C2D-A166-E8C6861579ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6ADC66E0-D8AC-4C2D-A166-E8C6861579ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6ADC66E0-D8AC-4C2D-A166-E8C6861579ED}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {03A45BA1-279E-4B09-96D9-BB065FA658DA}
EndGlobalSection
EndGlobal
52 changes: 52 additions & 0 deletions Config/AiConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using AiDisabler.Config.Types;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace AiDisabler.Config {
public class AiConverter : JsonCreationConverter<Ai> {
protected override Ai Create(Type objectType, JObject jObject) {
if (FieldExists("Children", jObject)) {
return new AiGroup();
} else {
return new Ai();
}
}

private bool FieldExists(string fieldName, JObject jObject) {
return jObject[fieldName] != null;
}
}

public abstract class JsonCreationConverter<T> : JsonConverter {
protected abstract T Create(Type objectType, JObject jObject);

public override bool CanConvert(Type objectType) {
return typeof(T).IsAssignableFrom(objectType);
}

public override bool CanWrite {
get { return false; }
}

public override object ReadJson(JsonReader reader,
Type objectType,
object existingValue,
JsonSerializer serializer) {
// Load JObject from stream
JObject jObject = JObject.Load(reader);

// Create target object based on JObject
T target = Create(objectType, jObject);

// Populate the object properties
serializer.Populate(jObject.CreateReader(), target);

return target;
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
throw new NotImplementedException();
}
}
}
148 changes: 148 additions & 0 deletions Config/DisablerConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.IO;
using AiDisabler.Config.Types;
using BepInEx;
using Newtonsoft.Json;

namespace AiDisabler.Config {
public class DisablerConfig {
public string configPath = Path.Combine(Paths.ConfigPath, "AiDisabler.json");
public AiGroup rootGroup;
public bool GlobalDisabled = false;
public bool GlobalKilled = false;
private List<Ai> CachedDisabled = new List<Ai>();
private List<Ai> CachedKilled = new List<Ai>();
public DisablerConfig() {
LoadConfig();
CacheConfig(rootGroup, true);
if (Plugin.configPrintAi.Value) {
Plugin.Log.LogInfo("=================CachedDisabled=================");
foreach (Ai ai in CachedDisabled) {
Plugin.Log.LogInfo($"CachedDisabled: (ID:{ai.ID} NAM:{ai.Name} TID:{ai.TypeId} CID:{ai.ClassId}) -> {ai.IsDisabled}");
}
Plugin.Log.LogInfo("=================CachedKilled===================");
foreach (Ai ai in CachedKilled) {
Plugin.Log.LogInfo($"CachedKilled: (ID:{ai.ID} NAM:{ai.Name} TID:{ai.TypeId} CID:{ai.ClassId}) -> {ai.IsKilled}");
}
Plugin.Log.LogInfo("=================MatchTest======================");
List<Ai> testList = new List<Ai>() {
new Ai() { TypeId = "egal", ClassId = "Animal" },
new Ai() { TypeId = "mrpuffton", ClassId = "Creepy" },
new Ai() { TypeId = "twins", ClassId = "Creepy", Name = "Twins" }
};

foreach (Ai ai in testList) {
Plugin.Log.LogInfo($"{ai.TypeId}? -> {CachedDisabled.Contains(ai)} {CachedKilled.Contains(ai)}");
bool one = this.CheckDisabled(ai, out string Disabler);
bool two = this.CheckKilled(ai, out string Killer);
Plugin.Log.LogInfo($"{ai.TypeId}?? -> {Disabler} {Killer}");
}
Plugin.Log.LogInfo("=================EndTest========================");
}
}

private void LoadConfig() {
rootGroup = new AiGroup();
Plugin.Log.LogInfo($"Plugin {MyPluginInfo.PLUGIN_GUID} is doing config.");
if (File.Exists(configPath)) {
try {
rootGroup = JsonConvert.DeserializeObject<AiGroup>(File.ReadAllText(configPath), new AiConverter());
Plugin.Log.LogInfo("AiDisabler.json loaded.");
} catch (Exception e) {
Plugin.Log.LogError($"Delete AiDisabler.json and restart the game to fix this issue! Or fix your json errors.");
Plugin.Log.LogError($"Error loading AiDisabler.json: {e}");
}
} else {
Plugin.Log.LogError("AiDisabler.json not found. Please copy over the AiDisabler.json from the zip file to the BepInEx/config folder.");
return;
}
Plugin.Log.LogInfo($"Plugin {MyPluginInfo.PLUGIN_GUID} is done doing config!");
}

private void CacheConfig(AiGroup aiGroup, bool isRoot = false) {
if (isRoot) {
Plugin.Log.LogDebug($"===Cache'n Root -> ID:{aiGroup.ID} NAM:{aiGroup.Name} TID:{aiGroup.TypeId} CID:{aiGroup.ClassId} IDS:{aiGroup.IsDisabled} IKL:{aiGroup.IsKilled}");
if (aiGroup.IsDisabled != null)
CachedDisabled.Add(aiGroup);
if (aiGroup.IsKilled != null)
CachedKilled.Add(aiGroup);
}

foreach (Ai child in aiGroup.Children) {
if ((aiGroup.ID != null || aiGroup.ID != "") && (child.ID == null || child.ID == "")) {
child.ID = $"{aiGroup.ID}.|{child.Name}-{child.TypeId}-{child.ClassId}|";
Plugin.Log.LogDebug($"-^Parrent {aiGroup.ID} has override'n Child's ID to {child.ID} due to missing ID!");
}


Plugin.Log.LogDebug($"+Cache'n AI: ID:{child.ID} NAM:{child.Name} TID:{child.TypeId} CID:{child.ClassId} IDS:{child.IsDisabled} IKL:{child.IsKilled}");

if (CachedDisabled.Contains(child)) {
Plugin.Log.LogDebug($"-^CachedDisabled of ID:{child.ID} NAM:{child.Name} TID:{child.TypeId} CID:{child.ClassId} IDS:{child.IsDisabled} IKL:{child.IsKilled} existing, overriding...");
CachedDisabled.Remove(child);
}
if (CachedKilled.Contains(child)) {
Plugin.Log.LogDebug($"-^CachedKilled of ID:{child.ID} NAM:{child.Name} TID:{child.TypeId} CID:{child.ClassId} IDS:{child.IsDisabled} IKL:{child.IsKilled} existing, overriding...");
CachedKilled.Remove(child);
}

if (aiGroup.IsDisabled != null && child.IsDisabled == null) {
child.IsDisabled = aiGroup.IsDisabled;
CachedDisabled.Add(child);
Plugin.Log.LogDebug($"-^Parrent {aiGroup.ID} has override'n Child's IsDisabled to {child.IsDisabled}");
} else {
if (child is AiGroup) {
if (child.Name != null || child.TypeId != null || child.ClassId != null)
CachedDisabled.Add(child);
} else {
Plugin.Log.LogDebug($"+ Added CachedDisabled (ID:{child.ID} NAM:{child.Name} TID:{child.TypeId} CID:{child.ClassId}) -> {child.IsKilled}");
CachedDisabled.Add(child);
}
}
if (aiGroup.IsKilled != null && child.IsKilled == null) {
child.IsKilled = aiGroup.IsKilled;
CachedKilled.Add(child);
Plugin.Log.LogDebug($"-^Parrent {aiGroup.ID} has override'n Child's IsKilled to {child.IsKilled}");
} else {
if (child is AiGroup) {
if (child.Name != null || child.TypeId != null || child.ClassId != null)
CachedKilled.Add(child);
} else {
Plugin.Log.LogDebug($"+ Added CachedKilled (ID:{child.ID} NAM:{child.Name} TID:{child.TypeId} CID:{child.ClassId}) -> {child.IsKilled}");
CachedKilled.Add(child);
}
}

if (child is AiGroup) {
Plugin.Log.LogDebug($"+==Cache'n AiGroup -> ID:{child.ID} NAM:{child.Name} TID:{child.TypeId} CID:{child.ClassId} IDS:{child.IsDisabled} IKL:{child.IsKilled}");
CacheConfig((AiGroup)child);
Plugin.Log.LogDebug($"+==Cache'n AiGroup: {child.ID} finished!");
}
Plugin.Log.LogDebug($"===Cache'n Root with id {aiGroup.ID}, finished!");
}
}

public bool CheckDisabled(Ai ai, out string idOfDisabler) {
for (int i = CachedDisabled.ToArray().Length; i-- > 0;) {
if (CachedDisabled[i].Equals(ai)) {
idOfDisabler = CachedDisabled[i].ID;
return (bool)CachedDisabled[i].IsDisabled;
}
}
idOfDisabler = "";
return false;
}

public bool CheckKilled(Ai ai, out string idOfKiller) {
for (int i = CachedKilled.ToArray().Length; i-- > 0;) {
if (CachedKilled[i].Equals(ai)) {
idOfKiller = CachedKilled[i].ID;
return (bool)CachedDisabled[i].IsKilled;
}
}
idOfKiller = "";
return false;
}
}
}
38 changes: 38 additions & 0 deletions Config/Types/Ai.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Collections.Generic;

namespace AiDisabler.Config.Types {
public class Ai {
public string ID { get; set; }
public string Name { get; set; }
public string ClassId { get; set; }
public string TypeId { get; set; }
public bool? IsDisabled { get; set; }
public bool? IsKilled { get; set; }

public override bool Equals(object obj) {
if (obj == null || !(obj is Ai))
return false;
Ai objectTest = (Ai)obj;

bool hasmatch = false;
if (objectTest.ID != null && this.ID != null)
if (objectTest.ID.ToLower() == this.ID.ToLower())
hasmatch = true;
if (objectTest.Name != null && this.Name != null)
if (objectTest.Name.ToLower() == this.Name.ToLower())
hasmatch = true;
if (objectTest.ClassId != null && this.ClassId != null)
if (objectTest.ClassId.ToLower() == this.ClassId.ToLower())
hasmatch = true;
if (objectTest.TypeId != null && this.TypeId != null)
if (objectTest.TypeId.ToLower() == this.TypeId.ToLower())
hasmatch = true;

return hasmatch;
}

public override int GetHashCode() {
return ID.ToLower().GetHashCode() ^ Name.ToLower().GetHashCode() ^ ClassId.ToLower().GetHashCode() ^ TypeId.ToLower().GetHashCode() ^ IsDisabled.GetHashCode() ^ IsKilled.GetHashCode();
}
}
}
Loading

0 comments on commit bac75fa

Please sign in to comment.