Skip to content

Commit 257f67d

Browse files
Added boss managers and updated docs
1 parent 90f125b commit 257f67d

6 files changed

Lines changed: 362 additions & 10 deletions

File tree

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System.Collections.ObjectModel;
2+
using DiskCardGame;
3+
using HarmonyLib;
4+
using InscryptionAPI.Guid;
5+
6+
namespace InscryptionAPI.Encounters;
7+
8+
[HarmonyPatch]
9+
public static class AIManager
10+
{
11+
public class FullAI
12+
{
13+
public readonly string Id;
14+
public readonly Type AI;
15+
16+
public FullAI(string id, Type aiType)
17+
{
18+
Id = id;
19+
AI = aiType;
20+
21+
TypeManager.Add(Id.ToString(), AI);
22+
}
23+
}
24+
25+
public readonly static ReadOnlyCollection<FullAI> BaseGameAIs = new(GenBaseGameAIsList());
26+
private readonly static ObservableCollection<FullAI> NewAIs = new();
27+
28+
public static List<FullAI> AllAIs { get; private set; } = BaseGameAIs.ToList();
29+
30+
static AIManager()
31+
{
32+
NewAIs.CollectionChanged += static (_, _) =>
33+
{
34+
AllAIs = BaseGameAIs.Concat(NewAIs).ToList();
35+
};
36+
}
37+
38+
private static List<FullAI> GenBaseGameAIsList()
39+
{
40+
List<FullAI> baseGame = new();
41+
var gameAsm = typeof(AI).Assembly;
42+
foreach (Type aiType in gameAsm.GetTypes().Where(type => type.IsSubclassOf(typeof(AI))))
43+
{
44+
baseGame.Add(new(aiType.Name, aiType));
45+
}
46+
return baseGame;
47+
}
48+
49+
public static FullAI Add(string guid, string aiName, Type sequencer)
50+
{
51+
FullAI full = new("AI_" + GuidManager.GetFullyQualifiedName(guid, aiName), sequencer);
52+
NewAIs.Add(full);
53+
return full;
54+
}
55+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
using System.Collections.ObjectModel;
2+
using System.Diagnostics.CodeAnalysis;
3+
using System.Runtime.CompilerServices;
4+
using DiskCardGame;
5+
using HarmonyLib;
6+
using InscryptionAPI.Guid;
7+
using UnityEngine;
8+
9+
namespace InscryptionAPI.Encounters;
10+
11+
[HarmonyPatch]
12+
public static class OpponentManager
13+
{
14+
public class FullOpponent
15+
{
16+
public readonly Opponent.Type Id;
17+
public Type Opponent;
18+
public string SpecialSequencerId;
19+
20+
public FullOpponent(Opponent.Type id, Type opponent, string specialSequencerId)
21+
{
22+
Id = id;
23+
SpecialSequencerId = specialSequencerId;
24+
Opponent = opponent;
25+
}
26+
}
27+
28+
public static readonly ReadOnlyCollection<FullOpponent> BaseGameOpponents = new(GenBaseGameOpponents());
29+
private static readonly ObservableCollection<FullOpponent> NewOpponents = new();
30+
31+
private static List<FullOpponent> GenBaseGameOpponents()
32+
{
33+
bool useReversePatch = true;
34+
try
35+
{
36+
OriginalGetSequencerIdForBoss(Opponent.Type.ProspectorBoss);
37+
}
38+
catch (NotImplementedException)
39+
{
40+
useReversePatch = false;
41+
}
42+
43+
List<FullOpponent> baseGame = new();
44+
var gameAsm = typeof(Opponent).Assembly;
45+
foreach (Opponent.Type opponent in Enum.GetValues(typeof(Opponent.Type)))
46+
{
47+
string specialSequencerId = useReversePatch ? OriginalGetSequencerIdForBoss(opponent) : BossBattleSequencer.GetSequencerIdForBoss(opponent);
48+
Type opponentType = gameAsm.GetType($"DiskCardGame.{opponent.ToString()}Opponent");
49+
50+
baseGame.Add(new FullOpponent(opponent, opponentType, specialSequencerId));
51+
}
52+
return baseGame;
53+
}
54+
55+
static OpponentManager()
56+
{
57+
NewOpponents.CollectionChanged += static (_, _) =>
58+
{
59+
AllOpponents = BaseGameOpponents.Concat(NewOpponents).ToList();
60+
};
61+
}
62+
63+
public static List<FullOpponent> AllOpponents { get; private set; } = BaseGameOpponents.ToList();
64+
65+
public static FullOpponent Add(string guid, string opponentName, string sequencerID, Type opponentType)
66+
{
67+
Opponent.Type opponentId = GuidManager.GetEnumValue<Opponent.Type>(guid, opponentName);
68+
FullOpponent opp = new (opponentId, opponentType, sequencerID);
69+
NewOpponents.Add(opp);
70+
return opp;
71+
}
72+
73+
[HarmonyPatch(typeof(Opponent), nameof(Opponent.SpawnOpponent))]
74+
[HarmonyPrefix]
75+
public static bool ReplaceSpawnOpponent(EncounterData encounterData, ref Opponent __result)
76+
{
77+
if (encounterData.opponentType == Opponent.Type.Default || !ProgressionData.LearnedMechanic(MechanicsConcept.OpponentQueue))
78+
return true; // For default opponents or if we're in the tutorial, just let the base game logic flow
79+
80+
// This mostly just follows the logic of the base game, other than the fact that the
81+
// opponent gets instantiated by looking up the type from the list
82+
83+
GameObject gameObject = new GameObject();
84+
gameObject.name = "Opponent";
85+
86+
__result = gameObject.AddComponent(AllOpponents.First(o => o.Id == encounterData.opponentType).Opponent) as Opponent;
87+
88+
__result.AI = Activator.CreateInstance(CustomType.GetType("DiskCardGame", encounterData.aiId ?? "AI")) as AI;
89+
__result.NumLives = __result.StartingLives;
90+
__result.OpponentType = encounterData.opponentType;
91+
__result.TurnPlan = __result.ModifyTurnPlan(encounterData.opponentTurnPlan);
92+
__result.Blueprint = encounterData.Blueprint;
93+
__result.Difficulty = encounterData.Difficulty;
94+
__result.ExtraTurnsToSurrender = SeededRandom.Range(0, 3, SaveManager.SaveFile.GetCurrentRandomSeed());
95+
return false;
96+
}
97+
98+
[HarmonyReversePatch(HarmonyReversePatchType.Original)]
99+
[HarmonyPatch(typeof(BossBattleSequencer), nameof(BossBattleSequencer.GetSequencerIdForBoss))]
100+
[MethodImpl(MethodImplOptions.NoInlining)]
101+
public static string OriginalGetSequencerIdForBoss(Opponent.Type bossType) { throw new NotImplementedException(); }
102+
103+
[HarmonyPatch(typeof(BossBattleSequencer), nameof(BossBattleSequencer.GetSequencerIdForBoss))]
104+
[HarmonyPrefix]
105+
public static bool ReplaceGetSequencerId(Opponent.Type bossType, ref string __result)
106+
{
107+
__result = AllOpponents.First(o => o.Id == bossType).SpecialSequencerId;
108+
return false;
109+
}
110+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using DiskCardGame;
2+
3+
namespace InscryptionAPI.Encounters;
4+
5+
public static class EncounterExtensions
6+
{
7+
public static OpponentManager.FullOpponent OpponentById(this IEnumerable<OpponentManager.FullOpponent> opponents, Opponent.Type id)
8+
{
9+
return opponents.FirstOrDefault(o => o.Id == id);
10+
}
11+
12+
public static OpponentManager.FullOpponent SetOpponent(this OpponentManager.FullOpponent opp, Type opponentType)
13+
{
14+
opp.Opponent = opponentType;
15+
return opp;
16+
}
17+
18+
public static OpponentManager.FullOpponent SetSequencer(this OpponentManager.FullOpponent opp, string sequenceId)
19+
{
20+
opp.SpecialSequencerId = sequenceId;
21+
return opp;
22+
}
23+
24+
public static OpponentManager.FullOpponent SetNewSequencer(this OpponentManager.FullOpponent opp, string pluginGuid, string sequencerName, Type sequencerType)
25+
{
26+
var newSequencer = SpecialSequenceManager.Add(pluginGuid, sequencerName, sequencerType);
27+
opp.SpecialSequencerId = newSequencer.Id;
28+
return opp;
29+
}
30+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using System.Collections.ObjectModel;
2+
using DiskCardGame;
3+
using HarmonyLib;
4+
using InscryptionAPI.Guid;
5+
6+
namespace InscryptionAPI.Encounters;
7+
8+
[HarmonyPatch]
9+
public static class SpecialSequenceManager
10+
{
11+
public class FullSpecialSequencer
12+
{
13+
public readonly string Id;
14+
15+
private Type _specialSequencer;
16+
public Type SpecialSequencer { get; private set; }
17+
18+
public FullSpecialSequencer(string id, Type specialSequencer)
19+
{
20+
Id = id;
21+
SpecialSequencer = specialSequencer;
22+
23+
TypeManager.Add(Id.ToString(), specialSequencer); // This is the magic that makes the patches work
24+
}
25+
}
26+
27+
public readonly static ReadOnlyCollection<FullSpecialSequencer> BaseGameSpecialSequencers = new(GenBaseGameSpecialSequencersList());
28+
private readonly static ObservableCollection<FullSpecialSequencer> NewSpecialSequencers = new();
29+
30+
public static List<FullSpecialSequencer> AllSpecialSequencers { get; private set; } = BaseGameSpecialSequencers.ToList();
31+
32+
static SpecialSequenceManager()
33+
{
34+
NewSpecialSequencers.CollectionChanged += static (_, _) =>
35+
{
36+
AllSpecialSequencers = BaseGameSpecialSequencers.Concat(NewSpecialSequencers).ToList();
37+
};
38+
}
39+
40+
private static List<FullSpecialSequencer> GenBaseGameSpecialSequencersList()
41+
{
42+
List<FullSpecialSequencer> baseGame = new();
43+
var gameAsm = typeof(SpecialBattleSequencer).Assembly;
44+
foreach (Type sequencer in gameAsm.GetTypes().Where(type => type.IsSubclassOf(typeof(SpecialBattleSequencer))))
45+
{
46+
baseGame.Add(new(sequencer.Name, sequencer));
47+
}
48+
return baseGame;
49+
}
50+
51+
public static FullSpecialSequencer Add(string guid, string sequencerName, Type sequencer)
52+
{
53+
FullSpecialSequencer full = new("SpecialSequencer_" + GuidManager.GetFullyQualifiedName(guid, sequencerName), sequencer);
54+
NewSpecialSequencers.Add(full);
55+
return full;
56+
}
57+
}

InscryptionAPI/Guid/CustomTypePatches.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ internal static void Add(string key, Type value)
1818
TypeCache.Add(key, value);
1919
}
2020

21+
internal static void Replace(string key, Type value)
22+
{
23+
if (TypeCache.ContainsKey(key))
24+
TypeCache.Remove(key);
25+
26+
Add(key, value);
27+
}
28+
2129

2230
[HarmonyReversePatch(HarmonyReversePatchType.Original)]
2331
[HarmonyPatch(typeof(CustomType), nameof(CustomType.GetType), new Type[] { typeof(string), typeof(string) } )]
@@ -28,7 +36,7 @@ internal static void Add(string key, Type value)
2836
[HarmonyPrefix]
2937
public static bool GetCustomType(string nameSpace, string typeName, ref Type __result)
3038
{
31-
InscryptionAPIPlugin.Logger.LogInfo($"Trying to get type for {nameSpace}.{typeName}");
39+
//InscryptionAPIPlugin.Logger.LogInfo($"Trying to get type for {nameSpace}.{typeName}");
3240

3341
if (TypeCache.ContainsKey(typeName))
3442
{
@@ -39,7 +47,7 @@ public static bool GetCustomType(string nameSpace, string typeName, ref Type __r
3947
int enumValue;
4048
if (int.TryParse(typeName, out enumValue))
4149
{
42-
InscryptionAPIPlugin.Logger.LogInfo($"This appears to be a custom type");
50+
//InscryptionAPIPlugin.Logger.LogInfo($"This appears to be a custom type");
4351
Type enumType = GuidManager.GetEnumType(enumValue);
4452

4553
if (enumType == typeof(Ability))

0 commit comments

Comments
 (0)