-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPlugin.cs
207 lines (168 loc) · 11.1 KB
/
Plugin.cs
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
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using LocalizationManager;
using PieceManager;
using ServerSync;
using UnityEngine;
namespace PieceManagerModTemplate
{
[BepInPlugin(ModGUID, ModName, ModVersion)]
public class PieceManagerModTemplatePlugin : BaseUnityPlugin
{
internal const string ModName = "PieceManagerModTemplate";
internal const string ModVersion = "1.0.0";
internal const string Author = "{azumatt}";
private const string ModGUID = Author + "." + ModName;
private static string ConfigFileName = ModGUID + ".cfg";
private static string ConfigFileFullPath = Paths.ConfigPath + Path.DirectorySeparatorChar + ConfigFileName;
internal static string ConnectionError = "";
private readonly Harmony _harmony = new(ModGUID);
public static readonly ManualLogSource PieceManagerModTemplateLogger = BepInEx.Logging.Logger.CreateLogSource(ModName);
private static readonly ConfigSync ConfigSync = new(ModGUID) { DisplayName = ModName, CurrentVersion = ModVersion, MinimumRequiredVersion = ModVersion };
public enum Toggle
{
On = 1,
Off = 0
}
public void Awake()
{
// Uncomment the line below to use the LocalizationManager for localizing your mod.
//Localizer.Load(); // Use this to initialize the LocalizationManager (for more information on LocalizationManager, see the LocalizationManager documentation https://github.com/blaxxun-boop/LocalizationManager#example-project).
_serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only.");
_ = ConfigSync.AddLockingConfigEntry(_serverConfigLocked);
// Globally turn off configuration options for your pieces, omit if you don't want to do this.
BuildPiece.ConfigurationEnabled = false;
// Format: new("AssetBundleName", "PrefabName", "FolderName");
BuildPiece examplePiece1 = new("funward_bundle", "funward", "FunWard_BundleFolder");
examplePiece1.Name.English("Fun Ward"); // Localize the name and description for the building piece for a language.
examplePiece1.Description.English("Ward For testing the Piece Manager");
examplePiece1.RequiredItems.Add("FineWood", 20, false); // Set the required items to build. Format: ("PrefabName", Amount, Recoverable)
examplePiece1.RequiredItems.Add("SurtlingCore", 20, false);
examplePiece1.Category.Set(PieceManager.BuildPieceCategory.Misc);
examplePiece1.Crafting.Set(PieceManager.CraftingTable.ArtisanTable); // Set a crafting station requirement for the piece.
//examplePiece1.Extension.Set(CraftingTable.Forge, 2); // Makes this piece a station extension, can change the max station distance by changing the second value. Use strings for custom tables.
// Or you can do it for a custom table (### Default maxStationDistance is 5. I used 2 as an example here.)
//examplePiece1.Extension.Set("MYCUSTOMTABLE", 2); // Makes this piece a station extension, can change the max station distance by changing the second value. Use strings for custom tables.
//examplePiece1.Crafting.Set("CUSTOMTABLE"); // If you have a custom table you're adding to the game. Just set it like this.
//examplePiece1.SpecialProperties.NoConfig = true; // Do not generate a config for this piece, omit this line of code if you want to generate a config.
examplePiece1.SpecialProperties = new SpecialProperties() { AdminOnly = true, NoConfig = true }; // You can declare multiple properties in one line
BuildPiece examplePiece2 = new("bamboo", "Bamboo_Wall"); // Note: If you wish to use the default "assets" folder for your assets, you can omit it!
examplePiece2.Name.English("Bamboo Wall");
examplePiece2.Description.English("A wall made of bamboo!");
examplePiece2.RequiredItems.Add("BambooLog", 20, false);
examplePiece2.Category.Set(PieceManager.BuildPieceCategory.BuildingWorkbench);
examplePiece2.Crafting.Set("CUSTOMTABLE"); // If you have a custom table you're adding to the game. Just set it like this.
examplePiece2.SpecialProperties.AdminOnly = true; // You can declare these one at a time as well!.
// If you want to add your item to the cultivator or another hammer with vanilla categories
// Format: (AssetBundle, "PrefabName", addToCustom, "Item that has a piecetable")
BuildPiece examplePiece3 = new("bamboo", "Bamboo_Sapling");
examplePiece3.Name.English("Bamboo Sapling");
examplePiece3.Description.English("A young bamboo tree, called a sapling");
examplePiece3.RequiredItems.Add("BambooSeed", 20, false);
examplePiece3.Tool.Add("Cultivator"); // Format: ("Item that has a piecetable")
examplePiece3.SpecialProperties.NoConfig = true;
// If you don't want to make an icon inside unity, but want the PieceManager to snag one for you, simply add .Snapshot() to your piece.
examplePiece3.Snapshot(); // Optionally, you can use the lightIntensity parameter to set the light intensity of the snapshot. Default is 1.3 or the cameraRotation parameter to set the rotation of the camera. Default is null.
// If you want a more custom piece, below is an example. Including custom category and custom crafting station. Also adding to a custom hammer.
BuildPiece examplePiece4 = new("bamboo", "Bamboo_Beam_Light");
examplePiece4.Name.English("Bamboo Beam Light");
examplePiece4.Description.English("A light made of bamboo!");
examplePiece4.RequiredItems.Add("BambooLog", 20, false);
examplePiece4.Category.Set("Custom Category");
examplePiece4.Crafting.Set("CUSTOMTABLE");
examplePiece4.Tool.Add("Custom Hammer");
examplePiece4.SpecialProperties.NoConfig = true;
examplePiece4.Snapshot(); // Optionally, you can use the lightIntensity parameter to set the light intensity of the snapshot. Default is 1.3 or the cameraRotation parameter to set the rotation of the camera. Default is null.
// Need to add something to ZNetScene but not the hammer, cultivator or other?
PiecePrefabManager.RegisterPrefab("bamboo", "Bamboo_Beam_Light");
// Does your model need to swap materials with a vanilla material? Format: (GameObject, isJotunnMock)
MaterialReplacer.RegisterGameObjectForMatSwap(examplePiece3.Prefab, false);
// Does your model use a shader from the game like Custom/Creature or Custom/Piece in unity? Need it to "just work"?
//MaterialReplacer.RegisterGameObjectForShaderSwap(examplePiece3.Prefab, MaterialReplacer.ShaderType.UseUnityShader);
// What if you want to use a custom shader from the game (like Custom/Piece that allows snow!!!) but your unity shader isn't set to Custom/Piece? Format: (GameObject, MaterialReplacer.ShaderType.)
//MaterialReplacer.RegisterGameObjectForShaderSwap(examplePiece3.Prefab, MaterialReplacer.ShaderType.PieceShader);
// Detailed instructions on how to use the MaterialReplacer can be found on the current PieceManager Wiki. https://github.com/AzumattDev/PieceManager/wiki
Assembly assembly = Assembly.GetExecutingAssembly();
_harmony.PatchAll(assembly);
SetupWatcher();
}
private void OnDestroy()
{
Config.Save();
}
private void SetupWatcher()
{
FileSystemWatcher watcher = new(Paths.ConfigPath, ConfigFileName);
watcher.Changed += ReadConfigValues;
watcher.Created += ReadConfigValues;
watcher.Renamed += ReadConfigValues;
watcher.IncludeSubdirectories = true;
watcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
watcher.EnableRaisingEvents = true;
}
private void ReadConfigValues(object sender, FileSystemEventArgs e)
{
if (!File.Exists(ConfigFileFullPath)) return;
try
{
PieceManagerModTemplateLogger.LogDebug("ReadConfigValues called");
Config.Reload();
}
catch
{
PieceManagerModTemplateLogger.LogError($"There was an issue loading your {ConfigFileName}");
PieceManagerModTemplateLogger.LogError("Please check your config entries for spelling and format!");
}
}
#region ConfigOptions
private static ConfigEntry<Toggle> _serverConfigLocked = null!;
private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
{
ConfigDescription extendedDescription = new(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags);
ConfigEntry<T> configEntry = Config.Bind(group, name, value, extendedDescription);
//var configEntry = Config.Bind(group, name, value, description);
SyncedConfigEntry<T> syncedConfigEntry = ConfigSync.AddConfigEntry(configEntry);
syncedConfigEntry.SynchronizedConfig = synchronizedSetting;
return configEntry;
}
private ConfigEntry<T> config<T>(string group, string name, T value, string description, bool synchronizedSetting = true)
{
return config(group, name, value, new ConfigDescription(description), synchronizedSetting);
}
private class ConfigurationManagerAttributes
{
[UsedImplicitly] public int? Order = null!;
[UsedImplicitly] public bool? Browsable = null!;
[UsedImplicitly] public string? Category = null!;
[UsedImplicitly] public Action<ConfigEntryBase>? CustomDrawer = null!;
}
class AcceptableShortcuts : AcceptableValueBase
{
public AcceptableShortcuts() : base(typeof(KeyboardShortcut))
{
}
public override object Clamp(object value) => value;
public override bool IsValid(object value) => true;
public override string ToDescriptionString() => "# Acceptable values: " + string.Join(", ", UnityInput.Current.SupportedKeyCodes);
}
#endregion
}
public static class KeyboardExtensions
{
public static bool IsKeyDown(this KeyboardShortcut shortcut)
{
return shortcut.MainKey != KeyCode.None && Input.GetKeyDown(shortcut.MainKey) && shortcut.Modifiers.All(Input.GetKey);
}
public static bool IsKeyHeld(this KeyboardShortcut shortcut)
{
return shortcut.MainKey != KeyCode.None && Input.GetKey(shortcut.MainKey) && shortcut.Modifiers.All(Input.GetKey);
}
}
}