Skip to content

Commit 121d6cb

Browse files
Merge pull request #105 from zelzmiy/CustomTraits
Custom Traits
2 parents 1dfbcec + 036bfbb commit 121d6cb

File tree

4 files changed

+139
-0
lines changed

4 files changed

+139
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,5 +604,6 @@ FodyWeavers.xsd
604604

605605
!COTL_API/Debug/
606606
build/
607+
.idea
607608

608609
global.json
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using I2.Loc;
2+
using UnityEngine;
3+
4+
namespace FoodPlus.CustomTraits;
5+
6+
public abstract class CustomTrait
7+
{
8+
public abstract string InternalName { get; }
9+
10+
internal FollowerTrait.TraitType TraitType;
11+
internal string ModPrefix = "";
12+
13+
public virtual string LocalizedTitle() => LocalizationManager.GetTranslation($"Traits/{ModPrefix}.{InternalName}");
14+
15+
public virtual string LocalizedDescription() => LocalizationManager.GetTranslation($"Traits/{InternalName}.description");
16+
17+
public virtual bool IsTraitUnavailable() => false;
18+
19+
public virtual TraitFlags TraitFlags => TraitFlags.NONE;
20+
21+
public virtual List<FollowerTrait.TraitType> ExclusiveTraits => [];
22+
public virtual Sprite Icon => TextureHelper.CreateSpriteFromPath(PluginPaths.ResolveAssetPath("placeholder.png"));
23+
public virtual bool Positive => true;
24+
25+
}
26+
27+
[Flags]
28+
public enum TraitFlags
29+
{
30+
NONE = 0,
31+
STARTING_TRAIT = 1 << 0,
32+
FAITHFUL_TRAIT = 1 << 1,
33+
RARE_STARTING_TRAIT = 1 << 2,
34+
SINGLE_TRAIT = 1 << 3,
35+
EXCLUDE_FROM_MATING = 1 << 4,
36+
SIN_TRAIT = 1 << 5,
37+
PURE_BLOOD_TRAIT = 1 << 6,
38+
REQUIRES_ONBOARDING_COMPLETE = 1 << 7,
39+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System.Reflection;
2+
using COTL_API.Guid;
3+
4+
namespace FoodPlus.CustomTraits;
5+
6+
public static partial class CustomTraitManager
7+
{
8+
private static Dictionary<FollowerTrait.TraitType, CustomTrait> CustomTraitList { get; } = [];
9+
10+
public static FollowerTrait.TraitType Add(CustomTrait trait)
11+
{
12+
var guid = TypeManager.GetModIdFromCallstack(Assembly.GetCallingAssembly());
13+
14+
var traitType = GuidManager.GetEnumValue<FollowerTrait.TraitType>(guid, trait.InternalName);
15+
trait.TraitType = traitType;
16+
trait.ModPrefix = guid;
17+
18+
HandleTraitFlags(trait);
19+
foreach (var exclusive in trait.ExclusiveTraits)
20+
{
21+
FollowerTrait.ExclusiveTraits.Add(traitType, exclusive);
22+
}
23+
24+
CustomTraitList.Add(traitType, trait);
25+
26+
return traitType;
27+
}
28+
29+
private static void HandleTraitFlags(CustomTrait item)
30+
{
31+
var flagActions = new Dictionary<TraitFlags, Action>
32+
{
33+
{ TraitFlags.STARTING_TRAIT, () => FollowerTrait.StartingTraits.Add(item.TraitType) },
34+
{ TraitFlags.FAITHFUL_TRAIT, () => FollowerTrait.FaithfulTraits.Add(item.TraitType) },
35+
{ TraitFlags.RARE_STARTING_TRAIT, () => FollowerTrait.RareStartingTraits.Add(item.TraitType) },
36+
{ TraitFlags.SINGLE_TRAIT, () => FollowerTrait.SingleTraits.Add(item.TraitType) },
37+
{ TraitFlags.SIN_TRAIT, () => FollowerTrait.SinTraits.Add(item.TraitType) },
38+
{ TraitFlags.EXCLUDE_FROM_MATING, () => FollowerTrait.ExcludedFromMating.Add(item.TraitType) },
39+
{ TraitFlags.PURE_BLOOD_TRAIT, () => FollowerTrait.PureBloodTraits.Add(item.TraitType) },
40+
{ TraitFlags.REQUIRES_ONBOARDING_COMPLETE, () => FollowerTrait.RequiresOnboardingCompleted.Add(item.TraitType) }
41+
};
42+
43+
foreach (var flagAction in flagActions)
44+
{
45+
if (item.TraitFlags.HasFlag(flagAction.Key))
46+
{
47+
flagAction.Value();
48+
}
49+
}
50+
}
51+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using HarmonyLib;
2+
using UnityEngine;
3+
4+
namespace FoodPlus.CustomTraits;
5+
6+
[HarmonyPatch]
7+
public static partial class CustomTraitManager
8+
{
9+
[HarmonyPatch(typeof(FollowerTrait), nameof(FollowerTrait.GetIcon))]
10+
[HarmonyPostfix]
11+
private static void FollowerTrait_GetIcon(FollowerTrait.TraitType Type, ref Sprite __result)
12+
{
13+
if (!CustomTraitList.TryGetValue(Type, out var value)) return;
14+
__result = value.Icon;
15+
}
16+
17+
[HarmonyPatch(typeof(FollowerTrait), nameof(FollowerTrait.IsPositiveTrait))]
18+
[HarmonyPostfix]
19+
private static void FollowerTrait_IsPositiveTrait(FollowerTrait.TraitType traitType, ref bool __result)
20+
{
21+
if (!CustomTraitList.TryGetValue(traitType, out var value)) return;
22+
__result = value.Positive;
23+
}
24+
25+
[HarmonyPatch(typeof(FollowerTrait), nameof(FollowerTrait.GetLocalizedTitle))]
26+
[HarmonyPostfix]
27+
private static void FollowerTrait_GetLocalizedTitle(FollowerTrait.TraitType Type, ref string __result)
28+
{
29+
if (!CustomTraitList.TryGetValue(Type, out var value)) return;
30+
__result = value.LocalizedTitle();
31+
}
32+
33+
[HarmonyPatch(typeof(FollowerTrait), nameof(FollowerTrait.GetLocalizedDescription))]
34+
[HarmonyPostfix]
35+
private static void FollowerTrait_GetLocalizedDescription(FollowerTrait.TraitType Type, ref string __result)
36+
{
37+
if (!CustomTraitList.TryGetValue(Type, out var value)) return;
38+
__result = value.LocalizedDescription();
39+
}
40+
41+
[HarmonyPatch(typeof(FollowerTrait), nameof(FollowerTrait.IsTraitUnavailable))]
42+
[HarmonyPostfix]
43+
private static void FollowerTrait_IsTraitUnavailable(FollowerTrait.TraitType trait, ref bool __result)
44+
{
45+
if (!CustomTraitList.TryGetValue(trait, out var value)) return;
46+
__result = value.IsTraitUnavailable();
47+
}
48+
}

0 commit comments

Comments
 (0)