Skip to content

Commit fea9e64

Browse files
committed
Add AbilityManager
1 parent 63ffcf8 commit fea9e64

5 files changed

Lines changed: 229 additions & 3 deletions

File tree

.editorconfig

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
trim_trailing_whitespace = false
7+
insert_final_newline = false
8+
indent_style = space
9+
indent_size = 4
10+
11+
# Microsoft .NET properties
12+
csharp_new_line_before_members_in_object_initializers = false
13+
csharp_preferred_modifier_order = public, private, protected, internal, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async:none
14+
dotnet_naming_rule.constants_rule.import_to_resharper = as_predefined
15+
dotnet_naming_rule.constants_rule.severity = none
16+
dotnet_naming_rule.constants_rule.style = upper_camel_case_style
17+
dotnet_naming_rule.constants_rule.symbols = constants_symbols
18+
dotnet_naming_rule.public_fields_rule.import_to_resharper = as_predefined
19+
dotnet_naming_rule.public_fields_rule.severity = none
20+
dotnet_naming_rule.public_fields_rule.style = lower_camel_case_style
21+
dotnet_naming_rule.public_fields_rule.symbols = public_fields_symbols
22+
dotnet_naming_rule.static_readonly_rule.import_to_resharper = as_predefined
23+
dotnet_naming_rule.static_readonly_rule.severity = none
24+
dotnet_naming_rule.static_readonly_rule.style = upper_camel_case_style
25+
dotnet_naming_rule.static_readonly_rule.symbols = static_readonly_symbols
26+
dotnet_naming_rule.unity_serialized_field_rule.import_to_resharper = True
27+
dotnet_naming_rule.unity_serialized_field_rule.resharper_description = Unity serialized field
28+
dotnet_naming_rule.unity_serialized_field_rule.resharper_guid = 5f0fdb63-c892-4d2c-9324-15c80b22a7ef
29+
dotnet_naming_rule.unity_serialized_field_rule.severity = none
30+
dotnet_naming_rule.unity_serialized_field_rule.style = lower_camel_case_style
31+
dotnet_naming_rule.unity_serialized_field_rule.symbols = unity_serialized_field_symbols
32+
dotnet_naming_style.lower_camel_case_style.capitalization = camel_case
33+
dotnet_naming_style.upper_camel_case_style.capitalization = pascal_case
34+
dotnet_naming_symbols.constants_symbols.applicable_accessibilities = public,internal,protected,protected_internal,private_protected
35+
dotnet_naming_symbols.constants_symbols.applicable_kinds = field
36+
dotnet_naming_symbols.constants_symbols.required_modifiers = const
37+
dotnet_naming_symbols.public_fields_symbols.applicable_accessibilities = public,internal,protected,protected_internal,private_protected
38+
dotnet_naming_symbols.public_fields_symbols.applicable_kinds = field
39+
dotnet_naming_symbols.static_readonly_symbols.applicable_accessibilities = public,internal,protected,protected_internal,private_protected
40+
dotnet_naming_symbols.static_readonly_symbols.applicable_kinds = field
41+
dotnet_naming_symbols.static_readonly_symbols.required_modifiers = static,readonly
42+
dotnet_naming_symbols.unity_serialized_field_symbols.applicable_accessibilities = *
43+
dotnet_naming_symbols.unity_serialized_field_symbols.applicable_kinds =
44+
dotnet_naming_symbols.unity_serialized_field_symbols.resharper_applicable_kinds = unity_serialised_field
45+
dotnet_naming_symbols.unity_serialized_field_symbols.resharper_required_modifiers = instance
46+
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
47+
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none
48+
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
49+
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
50+
dotnet_style_predefined_type_for_member_access = true:suggestion
51+
dotnet_style_qualification_for_event = false:suggestion
52+
dotnet_style_qualification_for_field = false:suggestion
53+
dotnet_style_qualification_for_method = false:suggestion
54+
dotnet_style_qualification_for_property = false:suggestion
55+
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
56+
57+
# ReSharper properties
58+
resharper_align_multiline_binary_expressions_chain = false
59+
resharper_autodetect_indent_settings = true
60+
resharper_blank_lines_after_block_statements = 0
61+
resharper_blank_lines_around_property = 0
62+
resharper_blank_lines_around_single_line_type = 0
63+
resharper_csharp_blank_lines_around_invocable = 0
64+
resharper_csharp_empty_block_style = together_same_line
65+
resharper_csharp_insert_final_newline = true
66+
resharper_csharp_max_line_length = 201
67+
resharper_csharp_space_around_shift_op = false
68+
resharper_indent_preprocessor_directives = normal
69+
resharper_keep_existing_declaration_block_arrangement = true
70+
resharper_place_expr_accessor_on_single_line = true
71+
resharper_place_expr_property_on_single_line = true
72+
resharper_place_simple_accessor_on_single_line = false
73+
resharper_place_simple_anonymousmethod_on_single_line = false
74+
resharper_place_simple_embedded_statement_on_same_line = false
75+
resharper_remove_blank_lines_near_braces_in_code = false
76+
resharper_remove_blank_lines_near_braces_in_declarations = false
77+
resharper_use_indent_from_vs = false
78+
resharper_wrap_before_arrow_with_expressions = true
79+
80+
[*.{appxmanifest,asax,ascx,aspx,axaml,build,cg,cginc,compute,cs,cshtml,dtd,fs,fsi,fsscript,fsx,hlsl,hlsli,hlslinc,master,ml,mli,nuspec,paml,razor,resw,resx,shader,skin,usf,ush,vb,xaml,xamlx,xoml,xsd}]
81+
indent_style = space
82+
indent_size = 4
83+
tab_width = 4
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
using System.Collections.ObjectModel;
2+
using System.Diagnostics.CodeAnalysis;
3+
using DiskCardGame;
4+
using HarmonyLib;
5+
using UnityEngine;
6+
using UnityEngine.UI;
7+
8+
namespace InscryptionAPI.Abilities;
9+
10+
[HarmonyPatch]
11+
public static class AbilityManager
12+
{
13+
public class FullAbility
14+
{
15+
public Ability Id { get; internal set; }
16+
public AbilityInfo Info { get; internal set; }
17+
public Type AbilityBehavior { get; internal set; }
18+
public Texture Texture { get; internal set; }
19+
}
20+
21+
public readonly static ReadOnlyCollection<FullAbility> BaseGameAbilities = new(GenBaseGameAbilityList());
22+
private readonly static ObservableCollection<FullAbility> NewAbilities = new();
23+
24+
public static List<FullAbility> AllAbilities { get; private set; }
25+
public static List<AbilityInfo> AllAbilityInfos { get; private set; }
26+
27+
private static int _abilityCounter = (int)Ability.NUM_ABILITIES;
28+
29+
static AbilityManager()
30+
{
31+
NewAbilities.CollectionChanged += static (_, _) =>
32+
{
33+
AllAbilities = BaseGameAbilities.Concat(NewAbilities).ToList();
34+
AllAbilityInfos = AllAbilities.Select(x => x.Info).ToList();
35+
};
36+
}
37+
38+
private static List<FullAbility> GenBaseGameAbilityList()
39+
{
40+
List<FullAbility> baseGame = new();
41+
var gameAsm = typeof(AbilityInfo).Assembly;
42+
foreach (var ability in Resources.LoadAll<AbilityInfo>("Data/Abilities"))
43+
{
44+
var name = ability.ability.ToString();
45+
baseGame.Add(new FullAbility
46+
{
47+
Id = ability.ability,
48+
Info = ability,
49+
AbilityBehavior = gameAsm.GetType($"DiskCardGame.{name}"),
50+
Texture = AbilitiesUtil.LoadAbilityIcon(name)
51+
});
52+
}
53+
return baseGame;
54+
}
55+
56+
public static FullAbility Add(AbilityInfo info, Type behavior, Texture tex)
57+
{
58+
FullAbility full = new()
59+
{
60+
Info = info,
61+
AbilityBehavior = behavior,
62+
Texture = tex,
63+
Id = (Ability)Interlocked.Increment(ref _abilityCounter)
64+
};
65+
full.Info.ability = full.Id;
66+
NewAbilities.Add(full);
67+
return full;
68+
}
69+
70+
public static void Remove(Ability id) => NewAbilities.Remove(NewAbilities.FirstOrDefault(x => x.Id == id));
71+
public static void Remove(FullAbility ability) => NewAbilities.Remove(ability);
72+
73+
[HarmonyPrefix]
74+
[HarmonyPatch(typeof(ScriptableObjectLoader<UnityObject>), nameof(ScriptableObjectLoader<UnityObject>.LoadData))]
75+
[SuppressMessage("Member Access", "Publicizer001", Justification = "Need to set internal list of abilities")]
76+
private static void AbilityLoadPrefix()
77+
{
78+
ScriptableObjectLoader<AbilityInfo>.allData = AllAbilityInfos;
79+
}
80+
81+
[HarmonyPrefix]
82+
[HarmonyPatch(typeof(AbilitiesUtil), nameof(AbilitiesUtil.LoadAbilityIcon))]
83+
private static bool LoadAbilityIconReplacement(string abilityName, ref Texture __result)
84+
{
85+
if (int.TryParse(abilityName, out int abilityId))
86+
{
87+
__result = AllAbilities.FirstOrDefault(x => x.Id == (Ability)abilityId).Texture;
88+
}
89+
else
90+
{
91+
__result = AllAbilities.FirstOrDefault(x => x.Info.name == abilityName).Texture;
92+
}
93+
94+
return false;
95+
}
96+
97+
[HarmonyPrefix]
98+
[HarmonyPatch(typeof(AbilitiesUtil), nameof(AbilitiesUtil.GetLearnedAbilities))]
99+
private static bool GetLearnedAbilitesReplacement(bool opponentUsable, int minPower, int maxPower, AbilityMetaCategory categoryCriteria, ref List<Ability> __result)
100+
{
101+
__result = new();
102+
103+
foreach (var ability in AllAbilityInfos)
104+
{
105+
bool canUse = true;
106+
canUse &= !opponentUsable || ability.opponentUsable;
107+
canUse &= minPower <= ability.powerLevel && maxPower >= ability.powerLevel;
108+
canUse &= ability.metaCategories.Contains(categoryCriteria);
109+
canUse &= ProgressionData.LearnedAbility(ability.ability);
110+
111+
if (canUse)
112+
{
113+
__result.Add(ability.ability);
114+
}
115+
}
116+
117+
return false;
118+
}
119+
120+
[HarmonyPrefix]
121+
[HarmonyPatch(typeof(CardTriggerHandler), nameof(CardTriggerHandler.AddAbility), new[] { typeof(Ability) })]
122+
private static bool AddAbilityReplacement(CardTriggerHandler __instance, Ability ability)
123+
{
124+
var full = AllAbilities.FirstOrDefault(x => x.Id == ability);
125+
if (!__instance.triggeredAbilities.Exists(x => x.Item1 == ability) || full.Info.canStack && !full.Info.passive)
126+
{
127+
var reciever = (AbilityBehaviour)__instance.gameObject.GetComponent(full.AbilityBehavior);
128+
if (!reciever)
129+
{
130+
reciever = (AbilityBehaviour)__instance.gameObject.AddComponent(full.AbilityBehavior);
131+
}
132+
__instance.triggeredAbilities.Add(new Tuple<Ability, AbilityBehaviour>(ability, reciever));
133+
}
134+
135+
return false;
136+
}
137+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using DiskCardGame;
2+
3+
namespace InscryptionAPI.Card;
4+
5+
public static class CardExtensions
6+
{
7+
public static CardInfo CardByName(this List<CardInfo> cards, string name) => cards.FirstOrDefault(x => x.name == name);
8+
}

InscryptionAPI/Card/CardManager.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Diagnostics.CodeAnalysis;
33
using DiskCardGame;
44
using HarmonyLib;
5-
using Sirenix.Serialization.Utilities;
65
using UnityEngine;
76

87
namespace InscryptionAPI.Card;
@@ -19,7 +18,7 @@ static CardManager()
1918
{
2019
NewCards.CollectionChanged += static (_, _) =>
2120
{
22-
var cards = BaseGameCards.Append(NewCards).ToList();
21+
var cards = BaseGameCards.Concat(NewCards).Select(x => CardLoader.Clone(x)).ToList();
2322
AllCards = ModifyCardList?.Invoke(cards) ?? cards;
2423
};
2524
}

InscryptionAPI/InscryptionAPIPlugin.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ public class InscryptionAPIPlugin : BaseUnityPlugin
2121

2222
private static readonly (Type, string)[] ObjectLoaderTypes =
2323
{
24-
(typeof(AbilityInfo), "Abilities"),
2524
(typeof(AscensionChallengeInfo), "Ascension/Challenges"),
2625
(typeof(BoonData), "Boons"),
2726
(typeof(CommandLineTextSegment), ""),

0 commit comments

Comments
 (0)