@@ -16,104 +16,31 @@ namespace InscryptionAPI.Card;
1616[ HarmonyPatch ]
1717public static class TribeManager
1818{
19+ /// <summary>
20+ /// The internal object used to store all relevant info about a Tribe.
21+ /// guid - The mod GUID that added the Tribe.
22+ /// name - The internal name of the Tribe.
23+ /// tribe - The enum value corresponding to this Tribe.
24+ /// icon - The sprite displayed on cards with this Tribe.
25+ /// tribeChoice - Whether or not this Tribe can appear at card tribe choice nodes.
26+ /// cardBack - The texture displayed at card tribe choice nodes. If null, the API will create one using the icon Sprite.
27+ /// </summary>
28+ public class TribeInfo {
29+ public string guid ;
30+ public string name ;
31+ public Tribe tribe ;
32+ public Sprite icon ;
33+ public bool tribeChoice ;
34+ public Texture2D cardback ;
35+ }
36+
1937 private static readonly List < TribeInfo > tribes = new ( ) ;
2038 private static readonly List < Tribe > tribeTypes = new ( ) ;
2139 public static readonly ReadOnlyCollection < TribeInfo > NewTribes = new ( tribes ) ;
2240 public static readonly ReadOnlyCollection < Tribe > NewTribesTypes = new ( tribeTypes ) ;
2341
2442 private static readonly Texture2D TribeIconMissing = TextureHelper . GetImageAsTexture ( "tribeicon_none.png" , Assembly . GetExecutingAssembly ( ) ) ;
2543
26- [ HarmonyPatch ( typeof ( CardDisplayer3D ) , nameof ( CardDisplayer3D . UpdateTribeIcon ) ) ]
27- [ HarmonyPostfix ]
28- private static void UpdateTribeIcon ( CardDisplayer3D __instance , CardInfo info )
29- {
30- if ( info == null || __instance . tribeIconRenderers . Count == 0 )
31- return ;
32-
33- foreach ( TribeInfo tribeInfo in tribes )
34- {
35- if ( tribeInfo ? . icon == null || info . IsNotOfTribe ( tribeInfo . tribe ) )
36- continue ;
37-
38- bool foundSpriteRenderer = false ;
39- foreach ( SpriteRenderer spriteRenderer in __instance . tribeIconRenderers )
40- {
41- if ( spriteRenderer . sprite == null )
42- {
43- spriteRenderer . sprite = tribeInfo . icon ;
44- foundSpriteRenderer = true ;
45- break ;
46- }
47- }
48- if ( ! foundSpriteRenderer )
49- {
50- SpriteRenderer last = __instance . tribeIconRenderers . Last ( ) ;
51- SpriteRenderer spriteRenderer = UnityObject . Instantiate ( last ) ;
52- spriteRenderer . transform . parent = last . transform . parent ;
53- spriteRenderer . transform . localPosition = last . transform . localPosition + ( __instance . tribeIconRenderers [ 1 ] . transform . localPosition - __instance . tribeIconRenderers [ 0 ] . transform . localPosition ) ;
54- }
55- }
56- }
57-
58- [ HarmonyPatch ( typeof ( CardSingleChoicesSequencer ) , nameof ( CardSingleChoicesSequencer . GetCardbackTexture ) ) ]
59- [ HarmonyPostfix ]
60- private static void GetCardbackTexture ( ref Texture __result , CardChoice choice )
61- {
62- if ( choice != null && choice . tribe != Tribe . None && __result == null )
63- {
64- __result = tribes . Find ( x => x ? . tribe == choice . tribe ) ? . cardback ;
65- }
66- }
67-
68- [ HarmonyPatch ( typeof ( Part1CardChoiceGenerator ) , nameof ( Part1CardChoiceGenerator . GenerateTribeChoices ) ) ]
69- [ HarmonyPrefix ]
70- private static bool GenerateTribeChoices ( ref List < CardChoice > __result , int randomSeed )
71- {
72- // create list of chooseable vanilla tribes then add all chooseable custom tribes
73- List < Tribe > list = new ( )
74- {
75- Tribe . Bird ,
76- Tribe . Canine ,
77- Tribe . Hooved ,
78- Tribe . Insect ,
79- Tribe . Reptile
80- } ;
81- list . AddRange ( TribeManager . tribes . FindAll ( ( x ) => x != null && x . tribeChoice ) . ConvertAll ( ( x ) => x . tribe ) ) ;
82- // create a list of this region's dominant tribes
83- List < Tribe > tribes = new ( RunState . CurrentMapRegion . dominantTribes ) ;
84- // get a list of cards obtainable at choice nodes
85- List < CardInfo > obtainableCards = CardManager . AllCardsCopy . FindAll ( c => c . HasCardMetaCategory ( CardMetaCategory . ChoiceNode ) ) ;
86- // remove all non-chooseable tribes and all tribes with no cards
87- tribes . RemoveAll ( t => ( TribeManager . tribes . Exists ( ct => ct . tribe == t && ! ct . tribeChoice ) ) || ! obtainableCards . Exists ( c => c . IsOfTribe ( t ) ) ) ;
88- list . RemoveAll ( t => tribes . Contains ( t ) || ! obtainableCards . Exists ( c => c . IsOfTribe ( t ) ) ) ;
89- // if list is empty, add Insect as a fallback
90- if ( list . Count == 0 )
91- list . Add ( Tribe . Insect ) ;
92-
93- while ( tribes . Count < 3 )
94- {
95- Tribe item = list [ SeededRandom . Range ( 0 , list . Count , randomSeed ++ ) ] ;
96- tribes . Add ( item ) ;
97- if ( list . Count > 1 ) // prevents softlock
98- list . Remove ( item ) ;
99- }
100- while ( tribes . Count > 3 ) // if there are more than 3 tribes, reduce it to 3
101- tribes . RemoveAt ( SeededRandom . Range ( 0 , tribes . Count , randomSeed ++ ) ) ;
102-
103- // randomise the order the Tribes will be displayed
104- List < CardChoice > list2 = new ( ) ;
105- foreach ( Tribe tribe in tribes . Randomize ( ) )
106- {
107- list2 . Add ( new CardChoice
108- {
109- tribe = tribe
110- } ) ;
111- }
112-
113- __result = list2 ;
114- return false ;
115- }
116-
11744 /// <summary>
11845 /// Adds a new tribe to the game.
11946 /// </summary>
@@ -140,6 +67,62 @@ public static Tribe Add(string guid, string name, Texture2D tribeIcon = null, bo
14067 tribeTypes . Add ( tribe ) ;
14168 return tribe ;
14269 }
70+
71+ /// <summary>
72+ /// Adds a new tribe to the game
73+ /// </summary>
74+ /// <param name="guid">The guid of the mod adding the tribe.</param>
75+ /// <param name="name">The name of the tribe.</param>
76+ /// <param name="pathToTribeIcon">Path to the tribal icon that will appear as a watermark on all cards belonging to this tribe.</param>
77+ /// <param name="appearInTribeChoices">Indicates if the card should appear in tribal choice nodes.</param>
78+ /// <param name="pathToChoiceCardbackTexture">Path to the card back texture to display if the card should appear in tribal choice nodes.</param>
79+ /// <returns>The unique identifier for the new tribe.</returns>
80+ public static Tribe Add ( string guid , string name , string pathToTribeIcon = null , bool appearInTribeChoices = false , string pathToChoiceCardBackTexture = null ) {
81+ // Reason for 'is not null' is because if we pass 'null' to GetImageAsTexture, It will throw an exception.
82+ return Add ( guid , name , pathToTribeIcon is not null ? TextureHelper . GetImageAsTexture ( pathToTribeIcon ) : null , appearInTribeChoices , pathToChoiceCardBackTexture is not null ? TextureHelper . GetImageAsTexture ( pathToChoiceCardBackTexture ) : null ) ;
83+ }
84+
85+ public static bool IsCustomTribe ( Tribe tribe ) => tribeTypes . Contains ( tribe ) ;
86+
87+ /// <summary>
88+ /// Retrieves the TribeInfo object associated with the given Tribe enum value.
89+ /// </summary>
90+ /// <param name="tribe">Tribe to retrieve the TribeInfo of.</param>
91+ /// <remarks>Only custom Tribes have an associated TribeInfo; returns null for vanilla Tribes.</remarks>
92+ public static TribeInfo GetCustomTribeInfo ( Tribe tribe ) => tribes . Find ( x => x . tribe == tribe ) ;
93+
94+ /// <summary>
95+ /// Returns the icon texture associated with the given Tribe.
96+ /// </summary>
97+ /// <param name="tribe">Tribe to get the icon of.</param>
98+ /// <param name="useMissingIconIfNull">If true, return the missing icon texure when the checked Tribe has no icon texture.</param>
99+ public static Texture2D GetTribeIcon ( Tribe tribe , bool useMissingIconIfNull = true ) {
100+ Texture2D texture2D = null ;
101+ if ( IsCustomTribe ( tribe ) ) {
102+ foreach ( TribeInfo tribeInfo in NewTribes ) {
103+ if ( tribeInfo . tribe != tribe )
104+ continue ;
105+
106+ if ( tribeInfo . icon != null && tribeInfo . icon . texture != null )
107+ texture2D = tribeInfo . icon . texture ;
108+
109+ break ;
110+ }
111+ }
112+ else {
113+ // Vanilla tribe icon
114+ string str = "Art/Cards/TribeIcons/tribeicon_" + tribe . ToString ( ) . ToLowerInvariant ( ) ;
115+ Sprite sprite = ResourceBank . Get < Sprite > ( str ) ;
116+ if ( sprite != null )
117+ texture2D = sprite . texture ;
118+ }
119+
120+ if ( texture2D == null && useMissingIconIfNull )
121+ texture2D = TribeIconMissing ;
122+
123+ return texture2D ;
124+ }
125+
143126 private static Texture2D MakePlaceholderCardback ( Texture2D tribeIcon )
144127 {
145128 Texture2D emptyCardback = TextureHelper . GetImageAsTexture ( "empty_rewardCardBack.png" , InscryptionAPIPlugin . APIAssembly ) ;
@@ -174,70 +157,86 @@ private static Texture2D MakePlaceholderCardback(Texture2D tribeIcon)
174157 emptyCardback . Apply ( ) ;
175158 return emptyCardback ;
176159 }
177- /// <summary>
178- /// Adds a new tribe to the game
179- /// </summary>
180- /// <param name="guid">The guid of the mod adding the tribe.</param>
181- /// <param name="name">The name of the tribe.</param>
182- /// <param name="pathToTribeIcon">Path to the tribal icon that will appear as a watermark on all cards belonging to this tribe.</param>
183- /// <param name="appearInTribeChoices">Indicates if the card should appear in tribal choice nodes.</param>
184- /// <param name="pathToChoiceCardbackTexture">Path to the card back texture to display if the card should appear in tribal choice nodes.</param>
185- /// <returns>The unique identifier for the new tribe.</returns>
186- public static Tribe Add ( string guid , string name , string pathToTribeIcon = null , bool appearInTribeChoices = false , string pathToChoiceCardBackTexture = null )
187- {
188- // Reason for 'is not null' is because if we pass 'null' to GetImageAsTexture, It will thorw an exception.
189- return Add ( guid , name , pathToTribeIcon is not null ? TextureHelper . GetImageAsTexture ( pathToTribeIcon ) : null , appearInTribeChoices , pathToChoiceCardBackTexture is not null ? TextureHelper . GetImageAsTexture ( pathToChoiceCardBackTexture ) : null ) ;
190- }
191160
192- public static bool IsCustomTribe ( Tribe tribe ) => tribeTypes . Contains ( tribe ) ;
161+ [ HarmonyPatch ( typeof ( CardDisplayer3D ) , nameof ( CardDisplayer3D . UpdateTribeIcon ) ) ]
162+ [ HarmonyPostfix ]
163+ private static void UpdateTribeIcon ( CardDisplayer3D __instance , CardInfo info ) {
164+ if ( info == null || __instance . tribeIconRenderers . Count == 0 )
165+ return ;
193166
194- public static Texture2D GetTribeIcon ( Tribe tribe , bool useMissingIconIfNull = true )
195- {
196- Texture2D texture2D = null ;
197- if ( IsCustomTribe ( tribe ) )
198- {
199- foreach ( TribeInfo tribeInfo in NewTribes )
200- {
201- if ( tribeInfo . tribe != tribe )
202- continue ;
167+ foreach ( TribeInfo tribeInfo in tribes ) {
168+ if ( tribeInfo ? . icon == null || info . IsNotOfTribe ( tribeInfo . tribe ) )
169+ continue ;
203170
204- if ( tribeInfo . icon != null && tribeInfo . icon . texture != null )
205- texture2D = tribeInfo . icon . texture ;
171+ bool foundSpriteRenderer = false ;
172+ foreach ( SpriteRenderer spriteRenderer in __instance . tribeIconRenderers ) {
173+ if ( spriteRenderer . sprite == null ) {
174+ spriteRenderer . sprite = tribeInfo . icon ;
175+ foundSpriteRenderer = true ;
176+ break ;
177+ }
178+ }
206179
207- break ;
180+ // create new sprite renderer to hold custom tribe icon if all current renderers are full
181+ if ( ! foundSpriteRenderer ) {
182+ SpriteRenderer last = __instance . tribeIconRenderers . Last ( ) ;
183+ SpriteRenderer spriteRenderer = UnityObject . Instantiate ( last ) ;
184+ spriteRenderer . transform . parent = last . transform . parent ;
185+ spriteRenderer . transform . localPosition = last . transform . localPosition + ( __instance . tribeIconRenderers [ 1 ] . transform . localPosition - __instance . tribeIconRenderers [ 0 ] . transform . localPosition ) ;
208186 }
209187 }
210- else
211- {
212- // Vanilla tribe icon
213- string str = "Art/Cards/TribeIcons/tribeicon_" + tribe . ToString ( ) . ToLowerInvariant ( ) ;
214- Sprite sprite = ResourceBank . Get < Sprite > ( str ) ;
215- if ( sprite != null )
216- texture2D = sprite . texture ;
188+ }
189+
190+ [ HarmonyPatch ( typeof ( CardSingleChoicesSequencer ) , nameof ( CardSingleChoicesSequencer . GetCardbackTexture ) ) ]
191+ [ HarmonyPostfix ]
192+ private static void GetCardbackTexture ( ref Texture __result , CardChoice choice ) {
193+ if ( choice != null && choice . tribe != Tribe . None && __result == null ) {
194+ __result = tribes . Find ( x => x ? . tribe == choice . tribe ) ? . cardback ;
217195 }
196+ }
218197
219- if ( texture2D == null && useMissingIconIfNull )
220- texture2D = TribeIconMissing ;
198+ [ HarmonyPatch ( typeof ( Part1CardChoiceGenerator ) , nameof ( Part1CardChoiceGenerator . GenerateTribeChoices ) ) ]
199+ [ HarmonyPrefix ]
200+ private static bool GenerateTribeChoices ( ref List < CardChoice > __result , int randomSeed ) {
201+ // create list of chooseable vanilla tribes then add all chooseable custom tribes
202+ List < Tribe > list = new ( )
203+ {
204+ Tribe . Bird ,
205+ Tribe . Canine ,
206+ Tribe . Hooved ,
207+ Tribe . Insect ,
208+ Tribe . Reptile
209+ } ;
210+ list . AddRange ( TribeManager . tribes . FindAll ( ( x ) => x != null && x . tribeChoice ) . ConvertAll ( ( x ) => x . tribe ) ) ;
211+ // create a list of this region's dominant tribes
212+ List < Tribe > tribes = new ( RunState . CurrentMapRegion . dominantTribes ) ;
213+ // get a list of cards obtainable at choice nodes
214+ List < CardInfo > obtainableCards = CardManager . AllCardsCopy . FindAll ( c => c . HasCardMetaCategory ( CardMetaCategory . ChoiceNode ) ) ;
215+ // remove all non-chooseable tribes and all tribes with no cards
216+ tribes . RemoveAll ( t => ( TribeManager . tribes . Exists ( ct => ct . tribe == t && ! ct . tribeChoice ) ) || ! obtainableCards . Exists ( c => c . IsOfTribe ( t ) ) ) ;
217+ list . RemoveAll ( t => tribes . Contains ( t ) || ! obtainableCards . Exists ( c => c . IsOfTribe ( t ) ) ) ;
218+ // if list is empty, add Insect as a fallback
219+ if ( list . Count == 0 )
220+ list . Add ( Tribe . Insect ) ;
221221
222- return texture2D ;
223- }
222+ while ( tribes . Count < 3 ) {
223+ Tribe item = list [ SeededRandom . Range ( 0 , list . Count , randomSeed ++ ) ] ;
224+ tribes . Add ( item ) ;
225+ if ( list . Count > 1 ) // prevents softlock
226+ list . Remove ( item ) ;
227+ }
228+ while ( tribes . Count > 3 ) // if there are more than 3 tribes, reduce it to 3
229+ tribes . RemoveAt ( SeededRandom . Range ( 0 , tribes . Count , randomSeed ++ ) ) ;
224230
225- /// <summary>
226- /// The internal object used to store all relevant info about a Tribe.
227- /// guid - The mod GUID that added the Tribe.
228- /// name - The internal name of the Tribe.
229- /// tribe - The enum value corresponding to this Tribe.
230- /// icon - The sprite displayed on cards with this Tribe.
231- /// tribeChoice - Whether or not this Tribe can appear at card tribe choice nodes.
232- /// cardBack - The texture displayed at card tribe choice nodes. If null, the API will create one using the icon Sprite.
233- /// </summary>
234- public class TribeInfo
235- {
236- public string guid ;
237- public string name ;
238- public Tribe tribe ;
239- public Sprite icon ;
240- public bool tribeChoice ;
241- public Texture2D cardback ;
231+ // randomise the order the Tribes will be displayed
232+ List < CardChoice > list2 = new ( ) ;
233+ foreach ( Tribe tribe in tribes . Randomize ( ) ) {
234+ list2 . Add ( new CardChoice {
235+ tribe = tribe
236+ } ) ;
237+ }
238+
239+ __result = list2 ;
240+ return false ;
242241 }
243242}
0 commit comments