diff --git a/CardLoaderMod.csproj b/ExampleMod.csproj
similarity index 88%
rename from CardLoaderMod.csproj
rename to ExampleMod.csproj
index 8adce66..a00105e 100644
--- a/CardLoaderMod.csproj
+++ b/ExampleMod.csproj
@@ -2,9 +2,9 @@
netstandard2.0
- CardLoaderMod
- Loads a custom card, and modifies the wolf
- 1.0.0
+ ExampleMod
+ An example mod for Inscryption API
+ 1.6.0
true
9.0
diff --git a/Plugin.cs b/Plugin.cs
index 83e76e2..70a8c06 100644
--- a/Plugin.cs
+++ b/Plugin.cs
@@ -1,13 +1,8 @@
using BepInEx;
-using BepInEx.Logging;
-using System;
using System.Collections;
using System.Collections.Generic;
-using System.Reflection;
-using System.Linq;
using System.IO;
using DiskCardGame;
-using HarmonyLib;
using UnityEngine;
using APIPlugin;
@@ -17,9 +12,9 @@ namespace CardLoaderMod
[BepInDependency("cyantist.inscryption.api", BepInDependency.DependencyFlags.HardDependency)]
public class Plugin : BaseUnityPlugin
{
- private const string PluginGuid = "cyantist.inscryption.customcardexample";
- private const string PluginName = "CustomCardModExample";
- private const string PluginVersion = "1.0.0.0";
+ private const string PluginGuid = "cyantist.inscryption.examplemod";
+ private const string PluginName = "ExampleMod";
+ private const string PluginVersion = "1.6.0.0";
private void Awake()
{
@@ -28,92 +23,334 @@ private void Awake()
AddBears();
AddAbility();
ChangeWolf();
+ AddRegion();
}
private void AddBears()
{
- List metaCategories = new List();
- metaCategories.Add(CardMetaCategory.ChoiceNode);
- metaCategories.Add(CardMetaCategory.Rare);
+ // metaCategories determine the card pools
+ List metaCategories = new List
+ {
+ CardMetaCategory.ChoiceNode,
+ CardMetaCategory.Rare
+ };
- List appearanceBehaviour = new List();
- appearanceBehaviour.Add(CardAppearanceBehaviour.Appearance.RareCardBackground);
+ List appearanceBehaviour = new List
+ {
+ CardAppearanceBehaviour.Appearance.RareCardBackground,
+ CardAppearanceBehaviour.Appearance.AnimatedPortrait // Optional. If not provided for a talking card, it will be added automatically
+ };
- byte[] imgBytes = System.IO.File.ReadAllBytes(Path.Combine(this.Info.Location.Replace("CardLoaderMod.dll",""),"Artwork/eightfuckingbears.png"));
+ List specialAbilities = new List
+ {
+ SpecialTriggeredAbility.TalkingCardChooser // Required for talking cards!
+ };
+
+ // Load the image into a Texture2D object
+ byte[] imgBytes = File.ReadAllBytes(Path.Combine(this.Info.Location.Replace("ExampleMod.dll", ""),"Artwork/eightfuckingbears.png"));
Texture2D tex = new Texture2D(2,2);
tex.LoadImage(imgBytes);
- NewCard.Add("Eight_Bears", metaCategories, CardComplexity.Simple, CardTemple.Nature,"8 fucking bears!",32,48,description:"Kill this abomination please",cost:3,appearanceBehaviour:appearanceBehaviour, tex:tex);
+ // Add the card
+ NewCard.Add("Eight_Bears", "8 fucking bears!", 32, 48, metaCategories, CardComplexity.Simple, CardTemple.Nature, description: "Kill this abomination please",
+ bloodCost: 3, appearanceBehaviour: appearanceBehaviour, defaultTex: tex, specialAbilities: specialAbilities);
+
+ // Add the talking card behaviour. The name must be the same as the card name!
+ NewTalkingCard.Add("Eight_Bears", EightBearsTalkingCard.GetDictionary());
}
private NewAbility AddAbility()
- {
+ {
AbilityInfo info = ScriptableObject.CreateInstance();
info.powerLevel = 0;
info.rulebookName = "Example Ability";
info.rulebookDescription = "Example ability which adds a PiggyBank!";
- info.metaCategories = new List {AbilityMetaCategory.Part1Rulebook, AbilityMetaCategory.Part1Modular};
+ // metaCategories determine the pools
+ info.metaCategories = new List { AbilityMetaCategory.Part1Rulebook, AbilityMetaCategory.Part1Modular };
+
+ // Create the 'learned' dialogue
List lines = new List();
DialogueEvent.Line line = new DialogueEvent.Line();
line.text = "New abilities? I didn't authorise homebrew!";
lines.Add(line);
info.abilityLearnedDialogue = new DialogueEvent.LineSet(lines);
- byte[] imgBytes = System.IO.File.ReadAllBytes(Path.Combine(this.Info.Location.Replace("CardLoaderMod.dll",""),"Artwork/new.png"));
- Texture2D tex = new Texture2D(2,2);
+ // Load the image into a Texture2D object
+ byte[] imgBytes = File.ReadAllBytes(Path.Combine(this.Info.Location.Replace("ExampleMod.dll", ""), "Artwork/new.png"));
+ Texture2D tex = new Texture2D(2, 2);
tex.LoadImage(imgBytes);
- NewAbility ability = new NewAbility(info,typeof(NewTestAbility),tex,AbilityIdentifier.GetAbilityIdentifier(PluginGuid, info.rulebookName));
+ NewAbility ability = new NewAbility(info, typeof(NewTestAbility), tex, AbilityIdentifier.GetID(PluginGuid, info.rulebookName));
NewTestAbility.ability = ability.ability;
return ability;
- }
+ }
private void ChangeWolf()
{
- List abilities = new List {NewTestAbility.ability};
- new CustomCard("Wolf") {baseAttack=10, abilities=abilities};
+ List abilities = new List { NewTestAbility.ability };
+ new CustomCard("Wolf") { baseAttack = 10, abilities = abilities };
}
+ private void AddRegion()
+ {
+ // Load the default first region (NOTE: For Kaycee's Mod, use 'regions[0]')
+ RegionData regionData = ResourceBank.Get("Data/Map/RegionProgression").regions[0][0];
+
+ regionData.name = "Example_Region";
+
+ // Clear default encounters
+ regionData.encounters.Clear();
+
+ // Modify the colors to be red/green
+ regionData.boardLightColor = new Color(1f, 0f, 0f);
+ regionData.cardsLightColor = new Color(0f, 1f, 0f);
+
+ // Adds the region to tier 0
+ new NewRegion(regionData, 0);
+
+
+ // Add eight turns with four 'Eight_Bears' cards
+ List> turns = new List>();
+ for (int i = 0; i < 8; i++)
+ {
+ List turn = new List();
+ for (int j = 0; j < 4; j++)
+ {
+ turn.Add(new EncounterBlueprintData.CardBlueprint() {
+ // We have to get it directly from the new card list because it is not yet loaded into data - will be fixed in the future
+ card = NewCard.cards.Find(card => card.name == "Eight_Bears")
+ });
+ }
+ turns.Add(turn);
+ }
+ EncounterBlueprintData bearsBlueprint = ScriptableObject.CreateInstance();
+
+ // Which totem to use for totem battles (Bears are tribeless, so using squirrel here)
+ bearsBlueprint.dominantTribes = new List() { Tribe.Squirrel };
+ bearsBlueprint.turns = turns;
+
+ // Add the encounter as 'regular' encounter of the example region
+ // Usually it's better to add it to the encounters field instead, if you create the region in the same mod
+ new NewEncounter("Bear_Spam", bearsBlueprint, "Example_Region", true, false);
+ }
+
+
public class NewTestAbility : AbilityBehaviour
- {
- public override Ability Ability
- {
- get
- {
- return ability;
- }
- }
+ {
+ public override Ability Ability
+ {
+ get
+ {
+ return ability;
+ }
+ }
public static Ability ability;
- public override bool RespondsToResolveOnBoard()
- {
- return true;
- }
-
- public override IEnumerator OnResolveOnBoard()
- {
- yield return base.PreSuccessfulTriggerSequence();
- yield return new WaitForSeconds(0.2f);
- Singleton.Instance.SwitchToView(View.Default, false, false);
- yield return new WaitForSeconds(0.25f);
- if (RunState.Run.consumables.Count < 3)
- {
- RunState.Run.consumables.Add("PiggyBank");
- Singleton.Instance.UpdateItems(false);
- }
- else
- {
- base.Card.Anim.StrongNegationEffect();
- yield return new WaitForSeconds(0.2f);
- Singleton.Instance.ShakeConsumableSlots(0f);
- }
- yield return new WaitForSeconds(0.2f);
- yield return base.LearnAbility(0f);
- yield break;
- }
- }
+ public override bool RespondsToResolveOnBoard()
+ {
+ return true;
+ }
+
+ public override IEnumerator OnResolveOnBoard()
+ {
+ yield return base.PreSuccessfulTriggerSequence();
+ yield return new WaitForSeconds(0.2f);
+ Singleton.Instance.SwitchToView(View.Default, false, false);
+ yield return new WaitForSeconds(0.25f);
+ // Add piggy bank, only if there is room for it
+ if (RunState.Run.consumables.Count < 3)
+ {
+ RunState.Run.consumables.Add("PiggyBank");
+ Singleton.Instance.UpdateItems(false);
+ }
+ else
+ {
+ base.Card.Anim.StrongNegationEffect();
+ yield return new WaitForSeconds(0.2f);
+ Singleton.Instance.ShakeConsumableSlots(0f);
+ }
+ yield return new WaitForSeconds(0.2f);
+ yield return base.LearnAbility(0f);
+ yield break;
+ }
+ }
}
+ public class EightBearsTalkingCard : PaperTalkingCard
+ {
+ // Static method for easy access
+ public static DialogueEvent.Speaker Speaker => (DialogueEvent.Speaker) 100;
+
+ // Only important for multi-speaker dialogs
+ public override DialogueEvent.Speaker SpeakerType => Speaker;
+
+ // IDs should point to dictionary entries in GetDictionary().
+ // Required:
+
+ public override string OnDrawnDialogueId => "TalkingEightBearsDrawn";
+
+ public override string OnDrawnFallbackDialogueId => "TalkingEightBearsDrawn2";
+
+ public override string OnPlayFromHandDialogueId => "TalkingEightBearsPlayed";
+
+ public override string OnAttackedDialogueId => "TalkingEightBearsAttacked";
+
+ public override string OnBecomeSelectablePositiveDialogueId => "TalkingEightBearsPositiveSelectable";
+
+ public override string OnBecomeSelectableNegativeDialogueId => "TalkingEightBearsNegativeSelectable";
+
+ public override Dictionary OnDrawnSpecialOpponentDialogueIds => new Dictionary();
+
+ // Optional:
+
+ public override string OnSacrificedDialogueId => "TalkingEightBearsSacrificed";
+
+ public override string OnSelectedForCardMergeDialogueId => "TalkingEightBearsMerged";
+
+ public override string OnSelectedForCardRemoveDialogueId => "TalkingEightBearsRemoved";
+
+ public override string OnSelectedForDeckTrialDialogueId => "TalkingEightBearsDeckTrial";
+
+ public override string OnDiscoveredInExplorationDialogueId => "TalkingEightBearsDiscovered";
+
+ public static Dictionary GetDictionary()
+ {
+ Dictionary events = new Dictionary();
+ events.Add("TalkingEightBearsDrawn", new DialogueEvent()
+ {
+ id = "TalkingEightBearsDrawn",
+ speakers = new List() { Speaker },
+ mainLines = new DialogueEvent.LineSet()
+ {
+ lines = new List()
+ {
+ new DialogueEvent.Line { text = "*Bear Noises*" }
+ }
+ }
+ });
+ events.Add("TalkingEightBearsDrawn2", new DialogueEvent()
+ {
+ id = "TalkingEightBearsDrawn2",
+ speakers = new List() { Speaker },
+ mainLines = new DialogueEvent.LineSet()
+ {
+ lines = new List()
+ {
+ new DialogueEvent.Line { text = "*Bear Noises*" }
+ }
+ }
+ });
+ events.Add("TalkingEightBearsPlayed", new DialogueEvent()
+ {
+ id = "TalkingEightBearsPlayed",
+ speakers = new List() { Speaker },
+ mainLines = new DialogueEvent.LineSet()
+ {
+ lines = new List()
+ {
+ new DialogueEvent.Line { text = "*Bear Noises*" }
+ }
+ }
+ });
+ events.Add("TalkingEightBearsAttacked", new DialogueEvent()
+ {
+ id = "TalkingEightBearsAttacked",
+ speakers = new List() { Speaker },
+ mainLines = new DialogueEvent.LineSet()
+ {
+ lines = new List()
+ {
+ new DialogueEvent.Line { text = "*Bear Noises*" }
+ }
+ }
+ });
+ events.Add("TalkingEightBearsPositiveSelectable", new DialogueEvent()
+ {
+ id = "TalkingEightBearsPositiveSelectable",
+ speakers = new List() { Speaker },
+ mainLines = new DialogueEvent.LineSet()
+ {
+ lines = new List()
+ {
+ new DialogueEvent.Line { text = "*Bear Noises*" }
+ }
+ }
+ });
+ events.Add("TalkingEightBearsNegativeSelectable", new DialogueEvent()
+ {
+ id = "TalkingEightBearsNegativeSelectable",
+ speakers = new List() { Speaker },
+ mainLines = new DialogueEvent.LineSet()
+ {
+ lines = new List()
+ {
+ new DialogueEvent.Line { text = "*Bear Noises*" }
+ }
+ }
+ });
+ events.Add("TalkingEightBearsSacrificed", new DialogueEvent()
+ {
+ id = "TalkingEightBearsSacrificed",
+ speakers = new List() { Speaker },
+ mainLines = new DialogueEvent.LineSet()
+ {
+ lines = new List()
+ {
+ new DialogueEvent.Line { text = "*Bear Noises*" }
+ }
+ }
+ });
+ events.Add("TalkingEightBearsMerged", new DialogueEvent()
+ {
+ id = "TalkingEightBearsMerged",
+ speakers = new List() { Speaker },
+ mainLines = new DialogueEvent.LineSet()
+ {
+ lines = new List()
+ {
+ new DialogueEvent.Line { text = "*Bear Noises*" }
+ }
+ }
+ });
+ events.Add("TalkingEightBearsRemoved", new DialogueEvent()
+ {
+ id = "TalkingEightBearsRemoved",
+ speakers = new List() { Speaker },
+ mainLines = new DialogueEvent.LineSet()
+ {
+ lines = new List()
+ {
+ new DialogueEvent.Line { text = "*Bear Noises*" }
+ }
+ }
+ });
+ events.Add("TalkingEightBearsDeckTrial", new DialogueEvent()
+ {
+ id = "TalkingEightBearsDeckTrial",
+ speakers = new List() { Speaker },
+ mainLines = new DialogueEvent.LineSet()
+ {
+ lines = new List()
+ {
+ new DialogueEvent.Line { text = "*Bear Noises*" }
+ }
+ }
+ });
+ events.Add("TalkingEightBearsDiscovered", new DialogueEvent()
+ {
+ id = "TalkingEightBearsDiscovered",
+ speakers = new List() { Speaker },
+ mainLines = new DialogueEvent.LineSet()
+ {
+ lines = new List()
+ {
+ new DialogueEvent.Line { text = "*Bear Noises*" }
+ }
+ }
+ });
+ return events;
+ }
+ }
}
diff --git a/README.md b/README.md
index 701bd5c..dcc7a93 100644
--- a/README.md
+++ b/README.md
@@ -1,31 +1,27 @@
# ExampleMod
## Example mod for Inscryption API made by Cyantist
-This plugin is a BepInEx plugin made for Inscryption to create custom cards for the API by Cyantist.
-One example card is provided in the Plugin class with method name AddBears.
-One customised card is provided in the Plugin class with method name ChangeWolf.
+This plugin is a BepInEx plugin made for Inscryption to add content using the API by Cyantist.
+Examples for the following features are included in the Plugin class:
+- `AddBears()`: custom cards and talking cards
+- `AddAbility()`: custom abilities
+- `ChangeWolf()`: modifying existing cards
+- `AddRegion()`: custom regions and encounters
## Installation (automated)
This is the recommended way to install the API on the game.
- Download and install [Thunderstore Mod Manager](https://www.overwolf.com/app/Thunderstore-Thunderstore_Mod_Manager) or [r2modman](https://timberborn.thunderstore.io/package/ebkr/r2modman/)
-- Click Install with Mod Manager button on top of the [page](https://inscryption.thunderstore.io/package/Cyantist/ExampleMod/)
+- Click Install with Mod Manager button on top of the [page](https://inscryption.thunderstore.io/package/API_dev/ExampleMod/)
- Run the game via the mod manager
## Installation (manual)
To install this plugin first you need to install BepInEx as a mod loader for Inscryption. A guide to do this can be found [here](https://docs.bepinex.dev/articles/user_guide/installation/index.html#where-to-download-bepinex). Inscryption needs the 86x (32 bit) mono version.
-You will also need to install the [CardLoaderPlugin](https://github.com/ScottWilson0903/InscryptionAPI)
+You will also need to install the [API](https://github.com/ScottWilson0903/InscryptionAPI)
To install Inscryption API you simply need to copy **API.dll** from [releases](https://github.com/ScottWilson0903/InscryptionAPI/releases) to **Inscryption/BepInEx/plugins**.
-To install ExampleMod with just the default example card included "Eight Fucking Bears!" and example modified wolf, you simply need to copy **CardLoaderMod.dll** and the **Artwork** folder from the source code zip in [releases](https://github.com/ScottWilson0903/InscryptionExampleMod/releases) to a **Cyantist-ExampleMod** folder inside **Inscryption/BepInEx/plugins**.
-
-## Creating your own
-To generate your own cards, you will need to either pass in an already created **CardInfo** object to the **NewCard.Add** function, or you will need to pass all the required and optional parameters to the **NewCard** constructor as done in **Plugin.AddBears**. Any png files should be added to the **Artwork** folder and should be 114x94 pixels.
-To alter existing cards you will need to pass the card name and the values you want to change to the optional parameters in the **CustomCard** constructor, as done in **Plugin.ChangeWolf**.
-To add custom abilities you will need a class inheriting **AbilityBehaviour**, an **AbilityInfo** and a texture which should be 49x49 pixels and also placed in the **Artwork** folder.
-
-The newly compiled **CardLoaderMod.dll** should be installed exactly the same way as above.
+To install ExampleMod with just the default examples, you simply need to copy **ExampleMod.dll** and the **Artwork** folder from the source code zip in [releases](https://github.com/ScottWilson0903/InscryptionExampleMod/releases) to a **Cyantist-ExampleMod** folder inside **Inscryption/BepInEx/plugins**.
## Can I donate?
Donations are totally not needed, this is a passion project before anything else. If you do still want to donate though, you can buy me a coffee on [ko-fi](https://ko-fi.com/madcyantist).
diff --git a/lib/API.dll b/lib/API.dll
index 1d699bb..5c2207d 100644
Binary files a/lib/API.dll and b/lib/API.dll differ
diff --git a/lib/Assembly-CSharp.dll b/lib/Assembly-CSharp.dll
index 4fdb2e6..6bfcbba 100644
Binary files a/lib/Assembly-CSharp.dll and b/lib/Assembly-CSharp.dll differ
diff --git a/manifest.json b/manifest.json
index 280671b..5c4d57d 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,10 +1,10 @@
{
"name": "ExampleMod",
- "version_number": "1.5.0",
+ "version_number": "1.6.0",
"website_url": "https://github.com/ScottWilson0903/InscryptionExampleMod",
- "description": "This plugin is a BepInEx plugin made for Inscryption to create custom cards and abilities for the API by Cyantist.",
+ "description": "This plugin is a BepInEx plugin made for Inscryption to provide various examples for the API by Cyantist.",
"dependencies": [
"BepInEx-BepInExPack_Inscryption-5.4.1701",
- "API_dev-API-1.11.0"
+ "API_dev-API-1.13.0"
]
}