Skip to content

Commit 0b46da6

Browse files
committed
added null card and custom categories
1 parent 805a85a commit 0b46da6

6 files changed

Lines changed: 339 additions & 121 deletions

File tree

CardChoiceSpawnUniqueCardPatch.dll

4 KB
Binary file not shown.

CardChoiceSpawnUniqueCardPatch/CardChoiceSpawnUniqueCardPatch.cs

Lines changed: 61 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@
77
using System.Collections.Generic;
88
using System;
99
using System.Runtime.CompilerServices;
10+
using CardChoiceSpawnUniqueCardPatch.Utils;
11+
using UnboundLib; // requires unboundlib
12+
using UnboundLib.Cards;
1013
// requires Assembly-CSharp.dll
1114
// requires MMHOOK-Assembly-CSharp.dll
1215

1316
namespace CardChoiceSpawnUniqueCardPatch
1417
{
15-
[BepInPlugin(ModId, ModName, "0.0.0.0")]
18+
[BepInDependency("com.willis.rounds.unbound", BepInDependency.DependencyFlags.HardDependency)]
19+
[BepInPlugin(ModId, ModName, "0.0.1.0")]
1620
[BepInProcess("Rounds.exe")]
1721
public class CardChoiceSpawnUniqueCardPatch : BaseUnityPlugin
1822
{
@@ -22,104 +26,14 @@ private void Awake()
2226
}
2327
private void Start()
2428
{
25-
29+
CustomCard.BuildCard<NullCard>(cardInfo => CardChoiceSpawnUniqueCardPatch.NullCard = cardInfo);
2630
}
2731

2832
private const string ModId = "pykess.rounds.plugins.cardchoicespawnuniquecardpatch";
2933

3034
private const string ModName = "CardChoiceSpawnUniqueCardPatch";
31-
}
32-
// stolen from PCE
33-
public sealed class Cards
34-
{
35-
// singleton design
36-
public static readonly Cards instance = new Cards();
37-
private Cards()
38-
{
39-
Cards instance = this;
40-
}
41-
public bool CardIsUniqueFromCards(CardInfo card, CardInfo[] cards)
42-
{
43-
bool unique = true;
44-
45-
foreach (CardInfo otherCard in cards)
46-
{
47-
if (card.cardName == otherCard.cardName)
48-
{
49-
unique = false;
50-
}
51-
}
52-
53-
return unique;
54-
}
55-
56-
public bool CardDoesNotConflictWithCards(CardInfo card, CardInfo[] cards)
57-
{
58-
bool conflicts = false;
59-
60-
foreach (CardInfo otherCard in cards)
61-
{
62-
if (card.categories.Intersect(otherCard.blacklistedCategories).Any())
63-
{
64-
conflicts = true;
65-
}
66-
}
67-
68-
return conflicts;
69-
}
70-
71-
public bool PlayerIsAllowedCard(Player player, CardInfo card)
72-
{
73-
bool blacklisted = false;
74-
75-
foreach (CardInfo currentCard in player.data.currentCards)
76-
{
77-
if (card.categories.Intersect(currentCard.blacklistedCategories).Any())
78-
{
79-
blacklisted = true;
80-
}
81-
}
82-
83-
return !blacklisted && (card.allowMultiple || !player.data.currentCards.Where(cardinfo => cardinfo.name == card.name).Any());
84-
85-
}
86-
public CardInfo GetRandomCardWithCondition(CardChoice cardChoice, Player player, Func<CardInfo, Player, bool> condition, int maxattempts = 1000)
87-
{
88-
89-
CardInfo card = ((GameObject)typeof(CardChoice).InvokeMember("GetRanomCard",
90-
BindingFlags.Instance | BindingFlags.InvokeMethod |
91-
BindingFlags.NonPublic, null, cardChoice, new object[] { })).GetComponent<CardInfo>();
92-
93-
int i = 0;
94-
95-
// draw a random card until it's an uncommon or the maximum number of attempts was reached
96-
while (!condition(card, player) && i < maxattempts)
97-
{
98-
card = ((GameObject)typeof(CardChoice).InvokeMember("GetRanomCard",
99-
BindingFlags.Instance | BindingFlags.InvokeMethod |
100-
BindingFlags.NonPublic, null, cardChoice, new object[] { })).GetComponent<CardInfo>();
101-
i++;
102-
}
103-
104-
if (!condition(card, player))
105-
{
106-
return null;
107-
}
108-
else
109-
{
110-
return card;
111-
}
112-
113-
}
11435

115-
public int GetCardID(CardInfo card)
116-
{
117-
return Array.IndexOf(global::CardChoice.instance.cards, card);
118-
}
119-
public CardInfo GetCardWithID(int cardID)
120-
{
121-
return global::CardChoice.instance.cards[cardID];
122-
}
36+
internal static CardInfo NullCard;
12337
}
12438

12539
[Serializable]
@@ -154,35 +68,13 @@ private static bool Prefix(ref GameObject __result, CardChoice __instance, Vecto
15468
{
15569
// there are no valid cards left - this is an extremely unlikely scenario, only achievable if most of the cards have been disabled
15670

157-
// if any valid cards were found, just return one of those, even though its a duplicate
158-
159-
160-
List<GameObject> spawnedCards = (List<GameObject>)Traverse.Create(__instance).Field("spawnedCards").GetValue();
161-
162-
GameObject card;
163-
164-
if (spawnedCards.Count > 0)
165-
{
166-
CardInfo cardInfo = Cards.instance.GetCardWithID(Cards.instance.GetCardID(spawnedCards[0].GetComponent<CardInfo>().sourceCard));
167-
card = cardInfo.gameObject;
168-
}
169-
170-
// if no valid cards could be found, then just get any card at all because that's better than crashing the game
171-
else
172-
{
173-
card = ((GameObject)typeof(CardChoice).InvokeMember("GetRanomCard",
174-
BindingFlags.Instance | BindingFlags.InvokeMethod |
175-
BindingFlags.NonPublic, null, __instance, new object[] { }));
176-
}
71+
// return a blank card
17772
GameObject gameObject = (GameObject)typeof(CardChoice).InvokeMember("Spawn",
178-
BindingFlags.Instance | BindingFlags.InvokeMethod |
179-
BindingFlags.NonPublic, null, __instance, new object[] { card.gameObject, pos, rot });
180-
gameObject.GetComponent<CardInfo>().sourceCard = card.GetComponent<CardInfo>();
73+
BindingFlags.Instance | BindingFlags.InvokeMethod |
74+
BindingFlags.NonPublic, null, __instance, new object[] { CardChoiceSpawnUniqueCardPatch.NullCard.gameObject, pos, rot });
75+
gameObject.GetComponent<CardInfo>().sourceCard = CardChoiceSpawnUniqueCardPatch.NullCard.GetComponent<CardInfo>();
18176
gameObject.GetComponentInChildren<DamagableEvent>().GetComponent<Collider2D>().enabled = false;
182-
183-
18477
__result = gameObject;
185-
18678
}
18779

18880
return false; // do not run the original method (BAD IDEA)
@@ -243,4 +135,54 @@ private static Func<CardInfo, Player, bool> BaseCondition(CardChoice instance)
243135
};
244136
}
245137
}
138+
public class NullCard : CustomCard
139+
{
140+
141+
public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers)
142+
{
143+
}
144+
public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
145+
{
146+
147+
}
148+
public override void OnRemoveCard()
149+
{
150+
}
151+
152+
protected override string GetTitle()
153+
{
154+
return " ";
155+
}
156+
protected override string GetDescription()
157+
{
158+
return "";
159+
}
160+
161+
protected override GameObject GetCardArt()
162+
{
163+
return null;
164+
}
165+
166+
protected override CardInfo.Rarity GetRarity()
167+
{
168+
return CardInfo.Rarity.Common;
169+
}
170+
171+
protected override CardInfoStat[] GetStats()
172+
{
173+
return null;
174+
}
175+
protected override CardThemeColor.CardThemeColorType GetTheme()
176+
{
177+
return CardThemeColor.CardThemeColorType.TechWhite;
178+
}
179+
public override bool GetEnabled()
180+
{
181+
return false;
182+
}
183+
public override string GetModName()
184+
{
185+
return "Patch";
186+
}
187+
}
246188
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
using BepInEx; // requires BepInEx.dll and BepInEx.Harmony.dll
2+
using UnityEngine; // requires UnityEngine.dll, UnityEngine.CoreModule.dll, and UnityEngine.AssetBundleModule.dll
3+
using HarmonyLib; // requires 0Harmony.dll
4+
using System.Collections;
5+
using System.Reflection;
6+
using System.Linq;
7+
using System.Collections.Generic;
8+
using System;
9+
using System.Runtime.CompilerServices;
10+
// requires Assembly-CSharp.dll
11+
// requires MMHOOK-Assembly-CSharp.dll
12+
13+
namespace CardChoiceSpawnUniqueCardPatch.Utils
14+
{
15+
// stolen from PCE
16+
public sealed class Cards
17+
{
18+
// singleton design
19+
public static readonly Cards instance = new Cards();
20+
private Cards()
21+
{
22+
Cards instance = this;
23+
}
24+
public bool CardIsUniqueFromCards(CardInfo card, CardInfo[] cards)
25+
{
26+
bool unique = true;
27+
28+
foreach (CardInfo otherCard in cards)
29+
{
30+
if (card.cardName == otherCard.cardName)
31+
{
32+
unique = false;
33+
}
34+
}
35+
36+
return unique;
37+
}
38+
39+
public bool CardDoesNotConflictWithCards(CardInfo card, CardInfo[] cards)
40+
{
41+
bool conflicts = false;
42+
43+
foreach (CardInfo otherCard in cards)
44+
{
45+
if (card.categories.Intersect(otherCard.blacklistedCategories).Any())
46+
{
47+
conflicts = true;
48+
}
49+
}
50+
51+
return conflicts;
52+
}
53+
54+
public bool PlayerIsAllowedCard(Player player, CardInfo card)
55+
{
56+
bool blacklisted = false;
57+
58+
foreach (CardInfo currentCard in player.data.currentCards)
59+
{
60+
if (card.categories.Intersect(currentCard.blacklistedCategories).Any())
61+
{
62+
blacklisted = true;
63+
}
64+
}
65+
66+
return !blacklisted && (card.allowMultiple || !player.data.currentCards.Where(cardinfo => cardinfo.name == card.name).Any());
67+
68+
}
69+
public CardInfo GetRandomCardWithCondition(CardChoice cardChoice, Player player, Func<CardInfo, Player, bool> condition, int maxattempts = 1000)
70+
{
71+
72+
CardInfo card = ((GameObject)typeof(CardChoice).InvokeMember("GetRanomCard",
73+
BindingFlags.Instance | BindingFlags.InvokeMethod |
74+
BindingFlags.NonPublic, null, cardChoice, new object[] { })).GetComponent<CardInfo>();
75+
76+
int i = 0;
77+
78+
// draw a random card until it's an uncommon or the maximum number of attempts was reached
79+
while (!condition(card, player) && i < maxattempts)
80+
{
81+
card = ((GameObject)typeof(CardChoice).InvokeMember("GetRanomCard",
82+
BindingFlags.Instance | BindingFlags.InvokeMethod |
83+
BindingFlags.NonPublic, null, cardChoice, new object[] { })).GetComponent<CardInfo>();
84+
i++;
85+
}
86+
87+
if (!condition(card, player))
88+
{
89+
return null;
90+
}
91+
else
92+
{
93+
return card;
94+
}
95+
96+
}
97+
98+
public CardInfo[] GetAllCardsWithCondition(CardChoice cardChoice, Player player, Func<CardInfo,Player,bool> condition)
99+
{
100+
List<CardInfo> validCards = new List<CardInfo>() { };
101+
102+
foreach (CardInfo card in cardChoice.cards)
103+
{
104+
if (condition(card,player))
105+
{
106+
validCards.Add(card);
107+
}
108+
}
109+
110+
return validCards.ToArray();
111+
}
112+
113+
public CardInfo[] GetAllCardsWithCondition(CardInfo[] cards, Player player, Func<CardInfo, Player, bool> condition)
114+
{
115+
List<CardInfo> validCards = new List<CardInfo>() { };
116+
117+
foreach (CardInfo card in cards)
118+
{
119+
if (condition(card, player))
120+
{
121+
validCards.Add(card);
122+
}
123+
}
124+
125+
return validCards.ToArray();
126+
}
127+
128+
public int GetCardID(CardInfo card)
129+
{
130+
return Array.IndexOf(global::CardChoice.instance.cards, card);
131+
}
132+
public CardInfo GetCardWithID(int cardID)
133+
{
134+
return global::CardChoice.instance.cards[cardID];
135+
}
136+
}
137+
138+
}

0 commit comments

Comments
 (0)