Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
132 commits
Select commit Hold shift + click to select a range
69d0b75
Switch to Harmony2
bfennema Jun 21, 2020
6228450
Adding in comments to help understand where in the rendering code thi…
BardezAnAvatar Jun 25, 2020
f9568e6
Removing assembly references that are not needed
BardezAnAvatar Jun 26, 2020
f3b68be
Adding in empty test project
BardezAnAvatar Jun 26, 2020
b22394a
Moving RenderCheckbox to a new class handling UI methods
BardezAnAvatar Jun 26, 2020
75d54d0
Adding in an empty unit test class
BardezAnAvatar Jun 26, 2020
7e8c613
Moving RenderCustomNameField to UmmUiRenderer
BardezAnAvatar Jun 26, 2020
b003206
Flipping ref to a return value
BardezAnAvatar Jun 26, 2020
5fbc8b3
Moving RenderIntSlider into UmmUiRenderer
BardezAnAvatar Jun 26, 2020
d342690
Adding return values to XML comments
BardezAnAvatar Jun 26, 2020
d8947e5
Moving enum to public
BardezAnAvatar Jun 26, 2020
016da40
Moving RenderToggleSection over to UmmUiRenderer
BardezAnAvatar Jun 26, 2020
ed98f61
Making the Button call minorly more readable
BardezAnAvatar Jun 26, 2020
8c33824
Moving RenderLabel over to UmmUiRenderer
BardezAnAvatar Jun 26, 2020
104cdba
Needless clarity
BardezAnAvatar Jun 26, 2020
b77f935
Re-ordering params for consistency
BardezAnAvatar Jun 26, 2020
77c2227
Moving RenderSelection to UmmUiRenderer
BardezAnAvatar Jun 26, 2020
702ae90
Moving overlaoded RenderSelection to UmmUiRenderer
BardezAnAvatar Jun 26, 2020
7c76894
Add param for rendering a Label on its own horizontal
BardezAnAvatar Jun 29, 2020
c1f9cf4
Extracting the spell-based item creation from the render control into…
BardezAnAvatar Jun 29, 2020
7c76388
Extracting Settings into its own file
BardezAnAvatar Jun 29, 2020
b0150db
Moving RenderCheatsSection to UserInterfaceEventHandlingLogic
BardezAnAvatar Jun 30, 2020
933a8f0
Extracting an interface, implementation, and factory out for the batt…
BardezAnAvatar Jun 30, 2020
6fc88bb
Adding unit tests over BattleLogFactory
BardezAnAvatar Jun 30, 2020
2739ecb
Adding in a clarifying comment
BardezAnAvatar Jun 30, 2020
576ec6f
Adding in a rough implementation of the Cheat Section rendering code
BardezAnAvatar Jun 30, 2020
7b62c90
Refactoring the surrounding index logic out of the rendering code bac…
BardezAnAvatar Jul 1, 2020
fac9c6f
Refactoring the "on its own line" stuff for RenderLabel
BardezAnAvatar Jul 1, 2020
e984a29
Adding in a Float slider
BardezAnAvatar Jul 1, 2020
ac2ee6c
Refactoring all of the UI stuff for the Cheat section into an interfa…
BardezAnAvatar Jul 1, 2020
150e2cd
Moving UmmUiRenderer into UnityModManager namespace
BardezAnAvatar Jul 1, 2020
c8a0ec1
Adding in unit tests over CheatSectionRendererFactory
BardezAnAvatar Jul 1, 2020
15b2862
Adding in missing param XML comment
BardezAnAvatar Jul 1, 2020
66ddb5a
Adding in unit tests over RenderCheatsSectionAndUpdateSettings
BardezAnAvatar Jul 1, 2020
6f7a27c
Adding Button controls to the UmmUiRenderer
BardezAnAvatar Jul 2, 2020
126df0c
Adding a section renderer for feat reassignment
BardezAnAvatar Jul 2, 2020
892db87
Moving RenderFeatReassignmentSection into UserInterfaceEnventHandling…
BardezAnAvatar Jul 2, 2020
a193c45
Extracting an interface from FeatReassignmentSectionRenderer
BardezAnAvatar Jul 2, 2020
7dd6bde
Adding a factory for IFeatReassignmentSectionRenderer
BardezAnAvatar Jul 2, 2020
e88eb7e
Flipping over to interface instance and factory instantiation
BardezAnAvatar Jul 2, 2020
87f1b00
Adding in unit tests over FeatReassignmentSectionRendererFactory
BardezAnAvatar Jul 2, 2020
b2af0b5
Encapsulating tests by method being tested. collapsable, more readabl…
BardezAnAvatar Jul 2, 2020
7bddf9a
Extracting constants for item qualitoes into its own constants class
BardezAnAvatar Jul 2, 2020
e7fefec
Extracting specific enchantment unique identifiers into their own con…
BardezAnAvatar Jul 2, 2020
d3c28c3
Adding in a struct to replace/convert the `EnchantmentBlueprints.Item…
BardezAnAvatar Jul 2, 2020
245956d
Converting EnchantmentBlueprints.ItemEnchantmentGuids into a struct r…
BardezAnAvatar Jul 2, 2020
04d3cfa
Fix undersized and oversized can be used with two hands flag
bfennema Dec 12, 2020
cdae0ff
Extracting unique identifiers for classes and archetyes into their ow…
BardezAnAvatar Jul 3, 2020
32e2042
Extracting feat, ability, and feature GUIDs into constants class
BardezAnAvatar Jul 3, 2020
ce93e95
Extracting the area blueprint GUIDs to their own file
BardezAnAvatar Jul 15, 2020
ce2fad2
Extracting game mechanics Guids to their own class
BardezAnAvatar Jul 16, 2020
2a67066
Removing bonded item features from Main
BardezAnAvatar Jul 16, 2020
e463359
Moving the data into the empty Data dir already in the solution
BardezAnAvatar Jul 16, 2020
9035924
Today I learned that L10n being short for localization and is actuall…
BardezAnAvatar Jul 16, 2020
0c664da
Extracting item costs from Main into their own constants class
BardezAnAvatar Jul 16, 2020
d5fe71e
Adding in a comment about the cost for special materials
BardezAnAvatar Jul 16, 2020
eee6e4f
Adding mithral price per pound constant
BardezAnAvatar Jul 16, 2020
573fc35
Extracting the localized string constants into their own class (and a…
BardezAnAvatar Jul 16, 2020
17a1d37
Moving IkPatches (?) into their own constants, namespace, and file
BardezAnAvatar Jul 16, 2020
83a5322
Renaming _public_ fields in IkPatch
BardezAnAvatar Jul 16, 2020
8a21b33
Adding in a few unit tests to ensure that appropriate blueprints are …
BardezAnAvatar Jul 16, 2020
58ede23
Refactoring the returned IkPatch entities into something a bit better…
BardezAnAvatar Jul 16, 2020
fd4f9dd
Moving `PatchIk` out into its own class and be a bit clearer on what …
BardezAnAvatar Jul 16, 2020
5680b3e
Moving `CraftingPriceStrings` into UserInterfaceEventHandlingLogic
BardezAnAvatar Jul 16, 2020
8cdd04d
Extracting "selected" and "current" static variables out into an inst…
BardezAnAvatar Jul 17, 2020
57353ae
Moving the SelectionIndex getter and setter into the Selections class
BardezAnAvatar Jul 17, 2020
ca9beb5
Extracting the various dictionary data
BardezAnAvatar Jul 17, 2020
e579267
Moving a patcher over to the patching namespace
BardezAnAvatar Jul 17, 2020
e33a7d3
Moving loaded JSON data into the DictionaryData class (which needs to…
BardezAnAvatar Jul 17, 2020
298601e
Moving Localization (L10N) files into Localization namespace.
BardezAnAvatar Jul 17, 2020
c157e01
Moving L10NFormat into a helper class (and renaming (for clarity?))
BardezAnAvatar Jul 17, 2020
387fdd2
Extracting the Harmony patches from Main into their own files: MainMe…
BardezAnAvatar Dec 14, 2020
0312dfb
Extracting the Harmony patches from Main into their own files: TwoWea…
BardezAnAvatar Dec 14, 2020
4ca90ac
Extracting the Harmony patches from Main into their own files: Shield…
BardezAnAvatar Dec 14, 2020
2b1494c
Extracting the Harmony patches from Main into their own files: MainMe…
BardezAnAvatar Dec 14, 2020
c11bef8
Extracting the Harmony patches from Main into their own files: Action…
BardezAnAvatar Dec 14, 2020
b60c457
Extracting the Harmony patches from Main into their own files: Bluepr…
BardezAnAvatar Dec 14, 2020
d97980f
Extracting the Harmony patches from Main into their own files: Spellb…
BardezAnAvatar Dec 14, 2020
c01ac48
Extracting the Harmony patches from Main into their own files: Bluepr…
BardezAnAvatar Dec 14, 2020
71cd168
Extracting the Harmony patches from Main into their own files: LogIte…
BardezAnAvatar Dec 14, 2020
8dafd13
Extracting the Harmony patches from Main into their own files: Battle…
BardezAnAvatar Dec 14, 2020
40c4dce
Extracting the Harmony patches from Main into their own files: Capita…
BardezAnAvatar Dec 14, 2020
0ecdc4f
Extracting the Harmony patches from Main into their own files: RestCo…
BardezAnAvatar Dec 14, 2020
cd0dee0
Extracting the Harmony patches from Main into their own files: Player…
BardezAnAvatar Dec 14, 2020
de3b3a6
Extracting the Harmony patches from Main into their own files: GameOn…
BardezAnAvatar Dec 14, 2020
7121982
Extracting the Harmony patches from Main into their own files: Weapon…
BardezAnAvatar Dec 14, 2020
7abcc59
Extracting the Harmony patches from Main into their own files: Weapon…
BardezAnAvatar Dec 14, 2020
f397c6e
Extracting the Harmony patches from Main into their own files: Attack…
BardezAnAvatar Dec 14, 2020
3cfd727
Extracting the Harmony patches from Main into their own files: Damage…
BardezAnAvatar Dec 14, 2020
311ee05
Extracting the Harmony patches from Main into their own files: UIUtil…
BardezAnAvatar Dec 14, 2020
64fc8af
Extracting the Harmony patches from Main into their own files: UIUtil…
BardezAnAvatar Dec 14, 2020
670a3e4
Extracting the Harmony patches from Main into their own files: UIUtil…
BardezAnAvatar Dec 14, 2020
2710084
Extracting the Harmony patches from Main into their own files: UIUtil…
BardezAnAvatar Dec 14, 2020
ba9aed2
Extracting the Harmony patches from Main into their own files: ItemEn…
BardezAnAvatar Dec 14, 2020
1d16d93
Extracting the Harmony patches from Main into their own files: UnitUs…
BardezAnAvatar Dec 14, 2020
9c82ece
Extracting the Harmony patches from Main into their own files: Weapon…
BardezAnAvatar Dec 14, 2020
d30731a
Extracting the Harmony patches from Main into their own files: Weapon…
BardezAnAvatar Dec 14, 2020
dfcc393
Extracting the Harmony patches from Main into their own files: Weapon…
BardezAnAvatar Dec 14, 2020
68d5378
Extracting the Harmony patches from Main into their own files: Weapon…
BardezAnAvatar Dec 14, 2020
6ba7d3d
Extracting the Harmony patches from Main into their own files: Weapon…
BardezAnAvatar Dec 14, 2020
af41e73
Extracting the Harmony patches from Main into their own files: Weapon…
BardezAnAvatar Dec 14, 2020
a61648c
Extracting the Harmony patches from Main into their own files: Weapon…
BardezAnAvatar Dec 14, 2020
755ee4c
Extracting the Harmony patches from Main into their own files: Brilli…
BardezAnAvatar Dec 14, 2020
1241e49
Extracting the Harmony patches from Main into their own files: MissAg…
BardezAnAvatar Dec 14, 2020
aba81a5
Extracting the Harmony patches from Main into their own files: Weapon…
BardezAnAvatar Dec 14, 2020
e35a0e0
Extracting the Harmony patches from Main into their own files: AddIni…
BardezAnAvatar Dec 14, 2020
ad74cec
Extracting the Harmony patches from Main into their own files: RuleCa…
BardezAnAvatar Dec 14, 2020
3204d07
Extracting the Harmony patches from Main into their own files: ItemEn…
BardezAnAvatar Dec 14, 2020
f5937fe
Extracting the Harmony patches from Main into their own files: Descri…
BardezAnAvatar Dec 14, 2020
1d9ead2
Extracting the Harmony patches from Main into their own files: Descri…
BardezAnAvatar Dec 14, 2020
bb63664
Extracting the Harmony patches from Main into their own files: UnitVi…
BardezAnAvatar Dec 14, 2020
1d6f535
Extracting the Harmony patches from Main into their own files: Activa…
BardezAnAvatar Dec 14, 2020
389ebcf
Cleanup
BardezAnAvatar Dec 14, 2020
8944933
Extracting the harmony patching into its own class
BardezAnAvatar Jul 20, 2020
0bb53d2
Moving classes that only contain Harmony patches into that namespace
BardezAnAvatar Jul 20, 2020
218ae1b
Ctrl + K, D
BardezAnAvatar Jul 20, 2020
72a8b73
Moving UpgradeSave and AddToLootTables to PlayerPostLoadPatch due to …
BardezAnAvatar Jul 20, 2020
f0c9642
Moving ReverseEngineerEnchantmentCost into MainMenuStartPatch
BardezAnAvatar Jul 20, 2020
9aa5389
Moving BuildCustomRecipeItemDescription into CraftMagicItemsBlueprint…
BardezAnAvatar Jul 20, 2020
12bbb27
Moving AddRecipeForMaterial into MainMenuPatch, as it is the only cod…
BardezAnAvatar Jul 20, 2020
f25619a
Moving AddRecipeForEnchantment into ManiMenuStartPatch, as it is the …
BardezAnAvatar Jul 20, 2020
6a69602
Moving AddItemIdForEnchantment into MainMenuStartPatch
BardezAnAvatar Jul 20, 2020
d6b68b4
Moving AddItemForType into MainMenuStartPatch
BardezAnAvatar Jul 20, 2020
8312499
Extracting WorkOnProjects into a common class for crafting logic, sin…
BardezAnAvatar Jul 20, 2020
5bcff57
Moving CheckCrafterPrerequisites into CraftingLogic
BardezAnAvatar Jul 20, 2020
d80d91f
Moving the CheckFeatPrerequisites into CraftingLogic
BardezAnAvatar Jul 20, 2020
3754932
Moving CheckSpellPrerequisites methods into CraftingLogic
BardezAnAvatar Jul 20, 2020
1e6bed2
Moving GetMissingCrafterPrerequisites into CraftingLogic
BardezAnAvatar Jul 20, 2020
f1d6824
Moving FindCasterSpell into CraftingLogic
BardezAnAvatar Jul 20, 2020
e454ca3
Moving IsMundaneCraftingData into CraftingLogic
BardezAnAvatar Jul 20, 2020
c002da5
Moving CraftItem into CraftingLogic
BardezAnAvatar Jul 20, 2020
13cf6eb
Moving CheckForOppositionSchool into CraftingLogic
BardezAnAvatar Jul 20, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CraftMagicItems.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.30104.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CraftMagicItems", "CraftMagicItems\CraftMagicItems.csproj", "{9379C37F-B226-4F81-893D-372F0CCEAAE5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CraftMagicItemsTests", "CraftMagicItemsTests\CraftMagicItemsTests.csproj", "{FDC2E2FA-48A9-4F1B-9C9B-1B1D43628884}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug (2.1)|Any CPU = Debug (2.1)|Any CPU
Expand All @@ -22,6 +24,14 @@ Global
{9379C37F-B226-4F81-893D-372F0CCEAAE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9379C37F-B226-4F81-893D-372F0CCEAAE5}.Release|Any CPU.Build.0 = Release|Any CPU
{9379C37F-B226-4F81-893D-372F0CCEAAE5}.Release|Any CPU.Deploy.0 = Release|Any CPU
{FDC2E2FA-48A9-4F1B-9C9B-1B1D43628884}.Debug (2.1)|Any CPU.ActiveCfg = Debug (2.1)|Any CPU
{FDC2E2FA-48A9-4F1B-9C9B-1B1D43628884}.Debug (2.1)|Any CPU.Build.0 = Debug (2.1)|Any CPU
{FDC2E2FA-48A9-4F1B-9C9B-1B1D43628884}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FDC2E2FA-48A9-4F1B-9C9B-1B1D43628884}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FDC2E2FA-48A9-4F1B-9C9B-1B1D43628884}.Release (2.1)|Any CPU.ActiveCfg = Release|Any CPU
{FDC2E2FA-48A9-4F1B-9C9B-1B1D43628884}.Release (2.1)|Any CPU.Build.0 = Release|Any CPU
{FDC2E2FA-48A9-4F1B-9C9B-1B1D43628884}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FDC2E2FA-48A9-4F1B-9C9B-1B1D43628884}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
69 changes: 17 additions & 52 deletions CraftMagicItems/Accessors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,74 +37,39 @@ namespace CraftMagicItems {
public delegate TResult FastStaticInvoker<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);

public class Accessors {
public static Harmony12.AccessTools.FieldRef<TClass, TResult> CreateFieldRef<TClass, TResult>(string name) {
public static HarmonyLib.AccessTools.FieldRef<TClass, TResult> CreateFieldRef<TClass, TResult>(string name) {
var classType = typeof(TClass);
var resultType = typeof(TResult);
var fieldInfo = Harmony12.AccessTools.Field(classType, name);
var fieldInfo = HarmonyLib.AccessTools.Field(classType, name);
if (fieldInfo == null) {
throw new Exception($"{classType} does not contain field {name}");
}

if (!resultType.IsAssignableFrom(fieldInfo.FieldType)) {
if (!resultType.IsAssignableFrom(fieldInfo.FieldType) && (!fieldInfo.FieldType.IsEnum || resultType != typeof(int))) {
throw new InvalidCastException($"Cannot cast field type {resultType} as {fieldInfo.FieldType} for class {classType} field {name}");
}

var fieldRef = Harmony12.AccessTools.FieldRefAccess<TClass, TResult>(name);
var fieldRef = HarmonyLib.AccessTools.FieldRefAccess<TClass, TResult>(name);
return fieldRef;
}

public static FastGetter CreateGetter(Type classType, Type resultType, string name) {
var fieldInfo = Harmony12.AccessTools.Field(classType, name);
var propInfo = Harmony12.AccessTools.Property(classType, name);
if (fieldInfo == null && propInfo == null) {
throw new Exception($"{classType} does not contain field or property {name}");
}

bool isProp = propInfo != null;
Type memberType = isProp ? propInfo.PropertyType : fieldInfo.FieldType;
string memberTypeName = isProp ? "property" : "field";
if (!resultType.IsAssignableFrom(memberType)) {
throw new InvalidCastException($"Cannot cast field type {resultType} as {memberType} for class {classType} {memberTypeName} {name}");
}

var handler = isProp ? Harmony12.FastAccess.CreateGetterHandler(propInfo) : Harmony12.FastAccess.CreateGetterHandler(fieldInfo);
return new FastGetter(handler);
}

public static FastGetter<TClass, TResult> CreateGetter<TClass, TResult>(string name) {
public static FastSetter<TClass, TValue> CreateSetter<TClass, TValue>(string name) {
var classType = typeof(TClass);
var resultType = typeof(TResult);
var handler = CreateGetter(classType, resultType, name);
return instance => (TResult) handler.Invoke(instance);
}

public static FastSetter CreateSetter(Type classType, Type valueType, string name) {
var propertyInfo = Harmony12.AccessTools.Property(classType, name);
var fieldInfo = Harmony12.AccessTools.Field(classType, name);
if (propertyInfo == null && fieldInfo == null) {
var propertySetter = HarmonyLib.AccessTools.PropertySetter(classType, name);
if (propertySetter == null) {
throw new Exception($"{classType} does not contain a field or property {name}");
}

var isProperty = propertyInfo != null;
var memberType = isProperty ? propertyInfo.PropertyType : fieldInfo.FieldType;
var memberTypeName = isProperty ? "property" : "field";
var propertyInfo = HarmonyLib.AccessTools.Property(classType, name);
var memberType = propertyInfo.PropertyType;
var valueType = typeof(TValue);
if (!valueType.IsAssignableFrom(memberType) && (!memberType.IsEnum || valueType != typeof(int))) {
throw new Exception($"Cannot cast property type {valueType} as {memberType} for class {classType} {memberTypeName} {name}");
throw new Exception($"Cannot cast property type {valueType} as {memberType} for class {classType} property {name}");
}

var handler = isProperty ? Harmony12.FastAccess.CreateSetterHandler(propertyInfo) : Harmony12.FastAccess.CreateSetterHandler(fieldInfo);
return new FastSetter(handler);
}

public static FastSetter<TClass, TValue> CreateSetter<TClass, TValue>(string name) {
var classType = typeof(TClass);
var valueType = typeof(TValue);
var handler = CreateSetter(classType, valueType, name);
return (instance, value) => handler.Invoke(instance, value);
return new FastSetter<TClass, TValue>(HarmonyLib.AccessTools.MethodDelegate<Action<TClass, TValue>>(propertySetter));
}

private static MethodInfo GetMethodInfoValidated(Type classType, string name, Type resultType, Type[] args, Type[] typeArgs) {
var methodInfo = Harmony12.AccessTools.Method(classType, name, args, typeArgs);
var methodInfo = HarmonyLib.AccessTools.Method(classType, name, args, typeArgs);
if (methodInfo == null) {
var argString = string.Join(", ", args.Select(t => t.ToString()));
throw new Exception($"{classType} does not contain method {name} with arguments {argString}");
Expand All @@ -119,7 +84,7 @@ private static MethodInfo GetMethodInfoValidated(Type classType, string name, Ty

private static FastInvoker CreateInvoker(Type classType, string name, Type resultType, Type[] args, Type[] typeArgs = null) {
var methodInfo = GetMethodInfoValidated(classType, name, resultType, args, typeArgs);
return new FastInvoker(Harmony12.MethodInvoker.GetHandler(methodInfo));
return new FastInvoker(HarmonyLib.MethodInvoker.GetHandler(methodInfo));
}

public static FastInvoker<TClass, TResult> CreateInvoker<TClass, TResult>(string name) {
Expand Down Expand Up @@ -156,9 +121,9 @@ public static FastInvoker<TClass, T1, T2, T3, TResult> CreateInvoker<TClass, T1,

private class StaticFastInvokeHandler {
private readonly Type classType;
private readonly Harmony12.FastInvokeHandler invoker;
private readonly HarmonyLib.FastInvokeHandler invoker;

public StaticFastInvokeHandler(Type classType, Harmony12.FastInvokeHandler invoker) {
public StaticFastInvokeHandler(Type classType, HarmonyLib.FastInvokeHandler invoker) {
this.classType = classType;
this.invoker = invoker;
}
Expand All @@ -170,7 +135,7 @@ public object Invoke(params object[] args) {

private static FastStaticInvoker CreateStaticInvoker(Type classType, string name, Type resultType, Type[] args, Type[] typeArgs = null) {
var methodInfo = GetMethodInfoValidated(classType, name, resultType, args, typeArgs);
return new StaticFastInvokeHandler(classType, Harmony12.MethodInvoker.GetHandler(methodInfo)).Invoke;
return new StaticFastInvokeHandler(classType, HarmonyLib.MethodInvoker.GetHandler(methodInfo)).Invoke;
}

public static FastStaticInvoker<TResult> CreateStaticInvoker<TResult>(Type classType, string name) {
Expand Down
4 changes: 2 additions & 2 deletions CraftMagicItems/AfterBuild.bat
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ xcopy CraftMagicItems.dll CraftMagicItems || goto :error
xcopy ..\..\..\Info.json CraftMagicItems || goto :error
xcopy /E /I ..\..\..\L10n CraftMagicItems\L10n || goto :error
xcopy /E /I ..\..\..\Icons CraftMagicItems\Icons || goto :error
xcopy /E /I ..\..\..\Data CraftMagicItems\Data || goto :error
xcopy /E /I Data CraftMagicItems\Data || goto :error
"C:\Program Files\7-Zip\7z.exe" a CraftMagicItems.zip CraftMagicItems || goto :error

"C:\Program Files\7-Zip\7z.exe" a CraftMagicItems-Source.zip ..\..\*.cs ..\..\..\L10n ..\..\..\Icons ..\..\..\Data || goto :error
"C:\Program Files\7-Zip\7z.exe" a CraftMagicItems-Source.zip ..\..\*.cs ..\..\..\L10n ..\..\..\Icons Data || goto :error

goto :EOF

Expand Down
5 changes: 3 additions & 2 deletions CraftMagicItems/BondedItemComponent.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using CraftMagicItems.Localization;
using Kingmaker;
using Kingmaker.Items;
using Kingmaker.Items.Slots;
Expand Down Expand Up @@ -43,7 +44,7 @@ public void HandleEquipmentSlotUpdated(ItemSlot slot, ItemEntity previousItem) {
}

// If the owner of a bonded object casts a spell when not wielding it, they need to make a Concentration check or lose the spell.
[Harmony12.HarmonyPatch(typeof(UnitUseAbility), "MakeConcentrationCheckIfCastingIsDifficult")]
[HarmonyLib.HarmonyPatch(typeof(UnitUseAbility), "MakeConcentrationCheckIfCastingIsDifficult")]
// ReSharper disable once UnusedMember.Local
private static class UnitUseAbilityMakeConcentrationCheckIfCastingIsDifficultPatch {
// ReSharper disable once UnusedMember.Local
Expand All @@ -52,7 +53,7 @@ private static void Postfix(UnitUseAbility __instance) {
var bondedComponent = Main.GetBondedItemComponentForCaster(caster.Descriptor);
if (bondedComponent != null && bondedComponent.ownerItem != null && bondedComponent.ownerItem.Wielder != caster.Descriptor) {
Main.AddBattleLogMessage(
Main.L10NFormat(caster, "craftMagicItems-logMessage-not-wielding-bonded-item", bondedComponent.ownerItem.Name),
LocalizationHelper.FormatLocalizedString(caster, "craftMagicItems-logMessage-not-wielding-bonded-item", bondedComponent.ownerItem.Name),
new L10NString("craftMagicItems-bonded-item-glossary"));
// Concentration checks have no way of overriding the DC, so contrive some fake damage to give a DC of 20 + spell level.
var ruleDamage = new RuleDealDamage(caster, caster, null);
Expand Down
53 changes: 53 additions & 0 deletions CraftMagicItems/Config/DictionaryData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System.Collections.Generic;
using Kingmaker.Blueprints.Items;
using Kingmaker.Blueprints.Items.Equipment;
using Kingmaker.Enums.Damage;

namespace CraftMagicItems.Config
{
/// <summary>
/// Class containing all of the loaded dictionaries of data that are loaded
/// from config files or game resources
/// </summary>
public class DictionaryData
{
/// <summary>Collection of items that are related to spells</summary>
public readonly Dictionary<UsableItemType, Dictionary<string, List<BlueprintItemEquipment>>> SpellIdToItem;

/// <summary>Crafting data loaded fron JSON files and its hierarchy</summary>
public readonly Dictionary<string, List<ItemCraftingData>> SubCraftingData;

/// <summary>Collection of items matching type of blueprint (shield, armor, weapon)</summary>
public readonly Dictionary<string, BlueprintItem> TypeToItem;

/// <summary>Collection of various item blueprints, keyed on enchantment blueprint ID</summary>
public readonly Dictionary<string, List<BlueprintItemEquipment>> EnchantmentIdToItem;

/// <summary>Collection of various recipies, keyed on enchantment blueprint ID</summary>
public readonly Dictionary<string, List<RecipeData>> EnchantmentIdToRecipe;

/// <summary>Collection of various recipies, keyed on physical material</summary>
public readonly Dictionary<PhysicalDamageMaterial, List<RecipeData>> MaterialToRecipe;

/// <summary>Collection of various enchantment costs, keyed on enchantment blueprint ID</summary>
public readonly Dictionary<string, int> EnchantmentIdToCost;

/// <summary>Array of item crafting data read from JSON file</summary>
public ItemCraftingData[] ItemCraftingData;

/// <summary>Array of custom loot data read from JSON file</summary>
public CustomLootItem[] CustomLootItems;

/// <summary>Default constructor</summary>
public DictionaryData()
{
SpellIdToItem = new Dictionary<UsableItemType, Dictionary<string, List<BlueprintItemEquipment>>>();
SubCraftingData = new Dictionary<string, List<ItemCraftingData>>();
TypeToItem = new Dictionary<string, BlueprintItem>();
EnchantmentIdToItem = new Dictionary<string, List<BlueprintItemEquipment>>();
EnchantmentIdToRecipe = new Dictionary<string, List<RecipeData>>();
MaterialToRecipe = new Dictionary<PhysicalDamageMaterial, List<RecipeData>>();
EnchantmentIdToCost = new Dictionary<string, int>();
}
}
}
71 changes: 71 additions & 0 deletions CraftMagicItems/Config/Selections.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System.Collections.Generic;
using CraftMagicItems.UI;
using Kingmaker.Blueprints.Items;
using Kingmaker.Blueprints.Items.Equipment;
using Kingmaker.EntitySystem.Entities;

namespace CraftMagicItems.Config
{
/// <summary>Class containing the selections from the UI</summary>
public class Selections
{
/// <summary>Currently selected index for a given setting</summary>
/// <remarks>
/// TODO: This should probably be broken up for ease of maintenance
/// </remarks>
public readonly Dictionary<string, int> SelectedIndex = new Dictionary<string, int>();

/// <summary>
/// The currently-selected caster level with which to create an item (wand, scroll, potion, item effect, etc.)
/// i.e.: "cast {spell} as an Nth level caster"
/// </summary>
public int SelectedCasterLevel;

/// <summary>Flag indicating whether to ONLY display currently prepared/available spells</summary>
public bool SelectedShowPreparedSpells;

/// <summary>Is a double weapon's second side selected?</summary>
public bool SelectedDoubleWeaponSecondEnd;

/// <summary>Is a shield's weapon (bash, spikes, etc.) seleted?</summary>
public bool SelectedShieldWeapon;

/// <summary>Selected times that an item can cast a given spell per day</summary>
public int SelectedCastsPerDay;

/// <summary>Currently selected base item blueprint</summary>
public BlueprintItemEquipment SelectedBaseBlueprint;

/// <summary>User-entered custom name for the item</summary>
public string SelectedCustomName;

/// <summary>Has the user selected to bond with a new item</summary>
public bool SelectedBondWithNewObject;

/// <summary>Currently selected crafter/caster</summary>
public UnitEntityData CurrentCaster;

/// <summary>Currently-selected crafting section to render</summary>
public OpenSection CurrentSection = OpenSection.CraftMagicItemsSection;

/// <summary>Blueprint that is currently being upgraded</summary>
public BlueprintItem UpgradingBlueprint;


/// <summary>Retrieves the select index in <see cref="SelectedIndex" /> matching the key of <paramref name="label" /></summary>
/// <param name="label">Label used as a key to search on</param>
/// <returns>The selected index value, or 0 if <paramref name="label" /> cannot be found</returns>
public int GetSelectionIndex(string label)
{
return SelectedIndex.ContainsKey(label) ? SelectedIndex[label] : 0;
}

/// <summary>Sets the <see cref="SelectedIndex" /> matching the key of <paramref name="label" /></summary>
/// <param name="label">Label used as a key to search on</param>
/// <param name="value">Value to assign</param>
public void SetSelectionIndex(string label, int value)
{
SelectedIndex[label] = value;
}
}
}
24 changes: 24 additions & 0 deletions CraftMagicItems/Constants/Areas.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace CraftMagicItems.Constants
{
/// <summary>Class containing unique identifiers for area blueprints</summary>
public static class Areas
{
/// <summary>Collection of blueprint unique identifiers for "safe" areas</summary>
public static readonly string[] SafeBlueprintAreaGuids =
{
"141f6999dada5a842a46bb3f029c287a", // Dire Narlmarches village
"e0852647faf68a641a0a5ec5436fc0bf", // Dunsward village
"537acbd9039b6a04f915dfc21572affb", // Glenebon village
"3ddf191773e8c2f448d31289b8d654bf", // Kamelands village
"f1b76870cc69e6a479c767cbe3c8a8ca", // North Narlmarches village
"ea3788bcdf33d884baffc34440ff620f", // Outskirts village
"e7292eab463c4924c8f14548545e25b7", // Silverstep village
"7c4a954c65e8d7146a6edc00c498a582", // South Narlmarches village
"7d9616b3807840c47ba3b2ab380c55a0", // Tors of Levenies village
"653811192a3fcd148816384a9492bd08", // Secluded Lodge
"fd1b6fa9f788ca24e86bd922a10da080", // Tenebrous Depths start hub
"c49315fe499f0e5468af6f19242499a2", // Tenebrous Depths start hub (Roguelike)
// TODO: camp outside the capital?
};
}
}
15 changes: 15 additions & 0 deletions CraftMagicItems/Constants/ClassBlueprints.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace CraftMagicItems.Constants
{
/// <summary>Contains constants for class/archetype blueprint unique identifiers</summary>
public static class ClassBlueprints
{
/// <summary>Blueprint for Alchemist class progression</summary>
public const string AlchemistProgressionGuid = "efd55ff9be2fda34981f5b9c83afe4f1";

/// <summary>Blueprint for Alchemist Grenadier archetype</summary>
public const string AlchemistGrenadierArchetypeGuid = "6af888a7800b3e949a40f558ff204aae";

/// <summary>Blueprint for Wizard Scroll Savant archetype</summary>
public const string ScrollSavantArchetypeGuid = "f43c78692a4e10d43a38bd6aedf53c1b";
}
}
Loading