Quellcode durchsuchen

[VendingMachine] [2.0.2.2] init

Zariteis vor 4 Jahren
Ursprung
Commit
c6d05ca9d5

BIN
VendingMachine/Assets/i900U1.png


+ 13 - 0
VendingMachine/Core.cs

@@ -0,0 +1,13 @@
+using GadgetCore;
+using GadgetCore.API;
+using System.Collections.Generic;
+
+namespace VendingMachine
+{
+  internal static class Core
+  {
+    public static List<ItemInfo> infoList;
+
+    public static GadgetLogger logger;
+  }
+}

+ 3 - 0
VendingMachine/Manifest.ini

@@ -0,0 +1,3 @@
+[Metadata]
+Name=Vending Machine
+Assembly=VendingMachine.dll

+ 1 - 0
VendingMachine/ModInfo.txt

@@ -0,0 +1 @@
+A mod that adds ultimate version of rings.

+ 22 - 0
VendingMachine/Patches/Patch_GameScript_GatherLoot.cs

@@ -0,0 +1,22 @@
+using HarmonyLib;
+using GadgetCore.API;
+using UnityEngine;
+using System.Collections;
+
+namespace VendingMachine.Patches
+{
+  [HarmonyPatch(typeof(GameScript))]
+  [HarmonyPatch("GatherLoot")]
+  [HarmonyGadget("VendingMachine")]
+  public static class Patch_GameScript_GatherLoot
+  {
+    [HarmonyPrefix]
+    public static bool Prefix(GameScript __instance)
+    {
+      return true;
+      int num2 = Random.Range(0, Core.infoList.Count);
+      __instance.AddItemGather(Core.infoList[num2].GetID());
+      return false;
+    }
+  }
+}

+ 34 - 0
VendingMachine/Patches/Patch_GameScript_RecipeDown.cs

@@ -0,0 +1,34 @@
+using HarmonyLib;
+using GadgetCore.API;
+using UnityEngine;
+using System.Collections;
+
+namespace VendingMachine.Patches
+{
+  [HarmonyPatch(typeof(GameScript))]
+  [HarmonyPatch("RecipeDown")]
+  [HarmonyGadget("VendingMachine")]
+  public static class Patch_GameScript_RecipeDown
+  {
+    [HarmonyPrefix]
+    public static bool Prefix(GameScript __instance, int ___craftType, ref int ___curRecipePage)
+    {
+      int pages = 1;
+      switch (___craftType)
+      {
+        case 0:
+          pages = 6;
+          break;
+        case 1:
+          pages = 2;
+          break;
+        case 2:
+          pages = 7;
+          break;
+      }
+      ___curRecipePage = (___curRecipePage + pages - 1) % pages;
+      __instance.RefreshRecipe();
+      return false;
+    }
+  }
+}

+ 34 - 0
VendingMachine/Patches/Patch_GameScript_RecipeUp.cs

@@ -0,0 +1,34 @@
+using HarmonyLib;
+using GadgetCore.API;
+using UnityEngine;
+using System.Collections;
+
+namespace VendingMachine.Patches
+{
+  [HarmonyPatch(typeof(GameScript))]
+  [HarmonyPatch("RecipeUp")]
+  [HarmonyGadget("VendingMachine")]
+  public static class Patch_GameScript_RecipeUp
+  {
+    [HarmonyPrefix]
+    public static bool Prefix(GameScript __instance, int ___craftType, ref int ___curRecipePage)
+    {
+      int pages = 1;
+      switch (___craftType)
+      {
+        case 0:
+          pages = 6;
+          break;
+        case 1:
+          pages = 2;
+          break;
+        case 2:
+          pages = 7;
+          break;
+      }
+      ___curRecipePage = (___curRecipePage + 1) % pages;
+      __instance.RefreshRecipe();
+      return false;
+    }
+  }
+}

+ 51 - 0
VendingMachine/Patches/Patch_GameScript_RefreshRecipe.cs

@@ -0,0 +1,51 @@
+using HarmonyLib;
+using GadgetCore.API;
+using UnityEngine;
+using System.Collections;
+
+namespace VendingMachine.Patches
+{
+  [HarmonyPatch(typeof(GameScript))]
+  [HarmonyPatch("RefreshRecipe")]
+  [HarmonyGadget("VendingMachine")]
+  public static class Patch_GameScript_RefreshRecipe
+  {
+    [HarmonyPrefix]
+    public static bool Prefix(GameScript __instance, int ___craftType, int ___curRecipePage)
+    {
+      if (___craftType == 0)
+      {
+        __instance.txtRecipeName[0].text = string.Empty + __instance.GetRecipeName0(___curRecipePage);
+        __instance.txtRecipeUnlocked[0].text = "Page " + (___curRecipePage + 1) + "/6";
+      }
+      else if (___craftType == 1)
+      {
+        __instance.txtRecipeName[0].text = string.Empty + __instance.GetRecipeName1(___curRecipePage);
+        __instance.txtRecipeUnlocked[0].text = "Page " + (___curRecipePage + 1) + "/2";
+      }
+      else if (___craftType == 2)
+      {
+        __instance.txtRecipeName[0].text = string.Empty + __instance.GetRecipeName2(___curRecipePage);
+        __instance.txtRecipeUnlocked[0].text = "Page " + (___curRecipePage + 1) + "/7";
+      }
+      __instance.txtRecipeUnlocked[0].gameObject.GetComponent<Animation>().Play();
+      __instance.txtRecipeName[0].gameObject.GetComponent<Animation>().Play();
+      __instance.txtRecipeName[1].text = __instance.txtRecipeName[0].text;
+      __instance.txtRecipeUnlocked[1].text = __instance.txtRecipeUnlocked[0].text;
+      if (___craftType != 2 || ___curRecipePage <= 5)
+      {
+        __instance.menuRecipe.GetComponent<Renderer>().material = (Material)Resources.Load(string.Concat(new object[] { "mat/r", ___curRecipePage, "t", ___craftType }));
+      }
+      else
+      {
+        __instance.txtRecipeName[0].text = "Rings";
+        __instance.menuRecipe.GetComponent<Renderer>().material = new Material(Shader.Find("Unlit/Transparent"))
+        {
+          mainTexture = GadgetCoreAPI.LoadTexture2D("recipesEmpty.png")
+        };
+      }
+      __instance.RefreshRecipeUnlock();
+      return false;
+    }
+  }
+}

+ 40 - 0
VendingMachine/Patches/Patch_GameScript_RefreshRecipeUnlock.cs

@@ -0,0 +1,40 @@
+using HarmonyLib;
+using GadgetCore.API;
+using UnityEngine;
+using System.Collections;
+
+namespace VendingMachine.Patches
+{
+  [HarmonyPatch(typeof(GameScript))]
+  [HarmonyPatch("RefreshRecipeUnlock")]
+  [HarmonyGadget("VendingMachine")]
+  public static class Patch_GameScript_RefreshRecipeUnlock
+	{
+    [HarmonyPrefix]
+    public static bool Prefix(GameScript __instance, 
+			int ___craftType, 
+			int ___curRecipePage, 
+			GameObject ___ultLocksObj, 
+			GameObject ___recipeButtons,
+			GameObject[] ___recipeLock,
+			int[,] ___ultLocksUnlocked,
+			GameObject[] ___ultLocks)
+		{
+			if (___craftType == 2 && ___curRecipePage >= 6)
+			{
+				___ultLocksObj.SetActive(true);
+				___recipeButtons.SetActive(false);
+				for (int i = 0; i < 36; i++)
+				{
+					if (i < 12)
+					{
+						___recipeLock[i].SetActive(false);
+					}
+					___ultLocks[i].SetActive(false);
+				}
+				return false;
+			}
+			return true;
+		}
+  }
+}

+ 10 - 0
VendingMachine/Properties/AssemblyInfo.cs

@@ -0,0 +1,10 @@
+using System.Reflection;
+using static VendingMachine.VendingMachine;
+
+[assembly: AssemblyProduct("VendingMachine")] //Set this to the full name of the mod including spaces.
+[assembly: AssemblyTitle("ScrapYard")] //This is only used when mousing over a dll file in Windows explorer.
+[assembly: AssemblyDescription("A mod that adds ultimate version of rings.")] //This is a short description for your mod's assembly.
+[assembly: AssemblyCompany("")] //Set this to your name/nickname and/or website
+[assembly: AssemblyCopyright("© 2021 Zariteis. All rights reserved.")] //Set this to your copyright name.
+[assembly: AssemblyVersion(MOD_VERSION)]
+[assembly: AssemblyFileVersion(MOD_VERSION)]

+ 8 - 0
VendingMachine/Properties/launchSettings.json

@@ -0,0 +1,8 @@
+{
+  "profiles": {
+    "VendingMachine": {
+      "commandName": "Executable",
+      "executablePath": "C:\\Program Files (x86)\\Steam\\steamapps\\common\\Roguelands\\Roguelands.exe"
+    }
+  }
+}

+ 15 - 0
VendingMachine/README.txt

@@ -0,0 +1,15 @@
+In addition to changing all references to "Template" this and that to a more appropriate name,
+you need to add a file called "GamePaths.xml" to the folder ABOVE where you put this template, with the following content:
+
+<?xml version="1.0" encoding="utf-8"?>
+<Project>
+  <PropertyGroup>
+    <!-- Set this full path to your game folder. Must contain a slash at the end. -->
+    <GamePath>C:\Program Files (x86)\Steam\steamapps\common\Roguelands\</GamePath>
+
+    <!-- Set this partial path to the game's Managed folder. Must contain a slash at the end. -->
+    <ManagedFolder>Roguelands_Data\Managed\</ManagedFolder>
+  </PropertyGroup>
+</Project>
+
+Note that `GamePath` may need to be changed, depending on the nature of your installation.

+ 164 - 0
VendingMachine/RecipePageRegistry/RecipePageInfo.cs

@@ -0,0 +1,164 @@
+using GadgetCore.API;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using UnityEngine;
+
+namespace VendingMachine.RecipePageRegistry
+{
+  /// <summary>
+  /// Defines a custom Chip. Make sure to call Register on it to register your Chip.
+  /// </summary>
+  public class RecipePageInfo : RegistryEntry<RecipePageInfo, RecipePageType>
+  {
+    /// <summary>
+    /// The ChipType of this Chip
+    /// </summary>
+    public readonly RecipePageType Type;
+    /// <summary>
+    /// The name of this Chip
+    /// </summary>
+    public readonly string Title;
+
+    /// <summary>
+    /// The Texture associated with this Chip. May be null.
+    /// </summary>
+    public virtual Texture Tex { get; protected set; }
+    /// <summary>
+    /// The Material associated with this Chip. May be null.
+    /// </summary>
+    public virtual Material Mat { get; protected set; }
+
+    /// <summary>
+    /// Use to create a new ChipInfo. Make sure to call Register on it to register your Chip.
+    /// </summary>
+    public RecipePageInfo(RecipePageType Type, string Title, Texture Tex)
+    {
+      this.Type = Type;
+      this.Title = Title;
+      this.Tex = Tex;
+    }
+
+    /// <summary>
+    /// Use to create a new ChipInfo. Make sure to call Register on it to register your Chip.
+    /// </summary>
+    public RecipePageInfo(RecipePageType Type, string Title, Material Mat)
+    {
+      this.Type = Type;
+      this.Title = Title;
+      this.Mat = Mat;
+    }
+
+    /// <summary>
+    /// Registers this ChipInfo to the ChipRegistry.
+    /// </summary>
+    /// <param name="name">The registry name to use.</param>
+    /// <param name="preferredID">If specified, will use this registry ID.</param>
+    /// <param name="overrideExisting">If false, will not register if the preferred ID is already used. Ignored if no preferred ID is specified.</param>
+    public virtual RecipePageInfo Register(string name)
+    {
+      return RegisterInternal(name) as RecipePageInfo;
+    }
+
+    /// <summary>
+    /// Called after this Registry Entry has been registered to its Registry. You should never call this yourself.
+    /// </summary>
+    protected override void PostRegister()
+    {
+      if (Mat == null)
+      {
+        Mat = new Material(Shader.Find("Unlit/Transparent"))
+        {
+          mainTexture = Tex
+        };
+      }
+      else
+      {
+        Tex = Mat.mainTexture;
+      }
+    }
+
+    /// <summary>
+    /// Returns the Registry Entry's Type enum. Used in the registration process, although it is safe to check this yourself by directly accessing the <see cref="Type"/> property.
+    /// </summary>
+    public override RecipePageType GetEntryType()
+    {
+      return Type;
+    }
+
+    /// <summary>
+    /// Returns the singleton of the registry used for storing this type of Registry Entry.
+    /// </summary>
+    public override Registry<RecipePageInfo, RecipePageType> GetRegistry()
+    {
+      return RecipePageRegistry.Singleton;
+    }
+
+    /// <summary>
+    /// Returns whether the specified ID is valid for this Registry Entry's Type.
+    /// </summary>
+    public override bool IsValidIDForType(int id)
+    {
+      return id > 0;
+    }
+
+    /// <summary>
+    /// Returns the next valid ID for this Registry Entry's Type, after the provided lastValidID. Should skip the vanilla ID range.
+    /// </summary>
+    public override int GetNextIDForType(int lastValidID)
+    {
+      if (lastValidID < GetRegistry().GetIDStart() - 1) lastValidID = GetRegistry().GetIDStart() - 1;
+      return ++lastValidID;
+    }
+
+    /// <summary>
+    /// Checks if the chip should be considered to currently be in use, and should not be allowed to be activated again. Override to add custom behavior - by default, always returns false.
+    /// </summary>
+    public virtual bool IsChipActive(int slot) { return false; }
+
+    /// <summary>
+    /// Invoked whenever this chip is activated. Will never be invoked if the ChipType is not ACTIVE. The int parameter is the slot the chip is in.
+    /// </summary>
+    public event Action<int> OnUse;
+    /// <summary>
+    /// Invoked whenever this chip is equipped. The int parameter is the slot the chip is being equipped to. This is invoked immediately after the chip is placed into the slot.
+    /// </summary>
+    public event Action<int> OnEquip;
+    /// <summary>
+    /// Invoked whenever this chip is dequipped. The int parameter is the slot the chip is being dequipped from. This is invoked immediately before the chip is removed from the slot.
+    /// </summary>
+    public event Action<int> OnDequip;
+
+    internal void InvokeOnUse(int slot) { OnUse?.Invoke(slot); }
+    internal void InvokeOnEquip(int slot) { OnEquip?.Invoke(slot); }
+    internal void InvokeOnDequip(int slot) { OnDequip?.Invoke(slot); }
+
+    /// <summary>
+    /// This indicates what should the active chip's cost represent.
+    /// </summary>
+    public enum ChipCostType
+    {
+      /// <summary>
+      /// The cost represents a number of points of mana, as normal chips do.
+      /// </summary>
+      MANA,
+      /// <summary>
+      /// The cost represents a number of points of stamina.
+      /// </summary>
+      ENERGY,
+      /// <summary>
+      /// The cost represents a number of points of health, although activating the chip will be unable to kill the player, and if it would the activation fails.
+      /// </summary>
+      HEALTH_SAFE,
+      /// <summary>
+      /// The cost represents a number of points of health, and activating the chip is able to kill the player if they have less than or equal to the number of points of health that the cost requires. If the player dies from attempting to activate this chip, then the effect does not get activated.
+      /// </summary>
+      HEALTH_LETHAL,
+      /// <summary>
+      /// The cost represents a number of points of health, and activating the chip is able to kill the player if they have less than or equal to the number of points of health that the cost requires. If the player dies from attempting to activate this chip, then the effect still activates. Note that at the moment of invocation, the player well have 0 or less health, and will be flagged as dead (GameScript.dead == true) but the death screen will not have opened yet, and the death will be canceled if the chip restores the player's health.
+      /// </summary>
+      HEALTH_LETHAL_POSTMORTEM
+    }
+  }
+}

+ 68 - 0
VendingMachine/RecipePageRegistry/RecipePageRegistry.cs

@@ -0,0 +1,68 @@
+using GadgetCore.API;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace VendingMachine.RecipePageRegistry
+{
+  /// <summary>
+  /// This registry is filled with ChipInfos, and is used for registering custom chips to the game.
+  /// </summary>
+  public class RecipePageRegistry : Registry<RecipePageRegistry, RecipePageInfo, RecipePageType>
+  {
+    private static Dictionary<string, int> chipIDsByName;
+    private static Dictionary<string, int> chipIDsByRegistryName;
+
+    /// <summary>
+    /// The name of this registry.
+    /// </summary>
+    public const string REGISTRY_NAME = "RecipePage";
+
+    /// <summary>
+    /// Gets the name of this registry. Must be constant. Returns <see cref="REGISTRY_NAME"/>.
+    /// </summary>
+    public override string GetRegistryName()
+    {
+      return REGISTRY_NAME;
+    }
+
+    /// <summary>
+    /// Called after the specified Registry Entry has been registered. You should never call this yourself. Note that this is called before <see cref="RegistryEntry{E, T}.PostRegister"/>
+    /// </summary>
+    protected override void PostRegistration(RecipePageInfo entry)
+    {
+      //chipIDsByRegistryName[entry.RegistryName] = entry.ID;
+    }
+
+    /// <summary>
+    /// Called just before an entry is removed from the registry by <see cref="Registry.UnregisterGadget(GadgetInfo)"/>
+    /// </summary>
+    protected override void OnUnregister(RecipePageInfo entry)
+    {
+      //chipIDsByName.Remove(entry.Name);
+      //chipIDsByRegistryName.Remove(entry.RegistryName);
+    }
+  }
+
+  /// <summary>
+  /// Specifies what type of recipe this is.
+  /// </summary>
+  public enum RecipePageType
+  {
+    /// <summary>
+    /// This recipe is avalible at the Gear Forge.
+    /// </summary>
+    GearForge,
+
+    /// <summary>
+    /// This recipe is avalible at the Alchemy Station.
+    /// </summary>
+    AlchemyStation,
+
+    /// <summary>
+    /// This recipe is avalible at the Ultimate Forge.
+    /// </summary>
+    UltimateForge
+  }
+}

+ 95 - 0
VendingMachine/VendingMachine.cs

@@ -0,0 +1,95 @@
+using GadgetCore.API;
+using GadgetCore.API.ConfigMenu;
+using GadgetCore.Util;
+using System.Collections.Generic;
+
+namespace VendingMachine
+{
+
+  [Gadget("VendingMachine")]
+  public class VendingMachine : Gadget<VendingMachine>
+  {
+    public const string MOD_VERSION = "1.0"; // Set this to the version of your mod.
+    public const string CONFIG_VERSION = "1.0"; // Increment this whenever you change your mod's config file.
+
+    protected override void LoadConfig()
+    {
+      Config.Load();
+
+      string fileVersion = Config.ReadString("ConfigVersion", CONFIG_VERSION, comments: "The Config Version (not to be confused with mod version)");
+
+      if (fileVersion != CONFIG_VERSION)
+      {
+        Config.Reset();
+        Config.WriteString("ConfigVersion", CONFIG_VERSION, comments: "The Config Version (not to be confused with mod version)");
+      }
+
+      Config.Reset();
+      Config.Save();
+    }
+    public override IGadgetConfigMenu GetConfigMenu() { return null; }
+
+    public override string GetModDescription()
+    {
+      return "A mod that adds ultimate version of rings.";
+    }
+
+    protected override void Initialize()
+    {
+      Logger.Log("Vending Machine v" + Info.Mod.Version);
+      Core.logger = Logger;
+      List<ItemInfo> infoList = new List<ItemInfo>();
+
+      infoList.Add(new ItemInfo(ItemType.RING, "Fit Ring", "", GadgetCoreAPI.LoadTexture2D("i900U1.png"), Stats: new EquipStats(1, 3, 2, 0, 0, 0)).Register("ring900U1"));
+      infoList.Add(new ItemInfo(ItemType.RING, "Gear Ring", "", GadgetCoreAPI.LoadTexture2D("i900U2.png"), Stats: new EquipStats(1, 2, 1, 3, 0, 0)).Register("ring900U2"));
+      infoList.Add(new ItemInfo(ItemType.RING, "Heart Ring", "", GadgetCoreAPI.LoadTexture2D("i900U3.png"), Stats: new EquipStats(5, 1, 1, 0, 0, 0)).Register("ring900U3"));
+
+      infoList.Add(new ItemInfo(ItemType.RING, "Shattered Ring", "", GadgetCoreAPI.LoadTexture2D("i901U1.png"), Stats: new EquipStats(1, 1, 1, 1, 1, 1)).Register("ring901U1"));
+      infoList.Add(new ItemInfo(ItemType.RING, "Dragon Egg Ring", "", GadgetCoreAPI.LoadTexture2D("i901U2.png"), Stats: new EquipStats(0, 0, 0, 0, 4, 3)).Register("ring901U2"));
+      infoList.Add(new ItemInfo(ItemType.RING, "Space Ring", "", GadgetCoreAPI.LoadTexture2D("i901U3.png"), Stats: new EquipStats(2, 0, 0, 4, 2, 1)).Register("ring901U3"));
+
+      infoList.Add(new ItemInfo(ItemType.RING, "Shine Ring", "", GadgetCoreAPI.LoadTexture2D("i902U1.png"), Stats: new EquipStats(2, 0, 0, 0, 3, 3)).Register("ring902U1"));
+      infoList.Add(new ItemInfo(ItemType.RING, "Obsidian Ring", "", GadgetCoreAPI.LoadTexture2D("i902U2.png"), Stats: new EquipStats(4, 0, 0, 0, 1, 2)).Register("ring902U2"));
+      infoList.Add(new ItemInfo(ItemType.RING, "Wing Ring", "", GadgetCoreAPI.LoadTexture2D("i902U3.png"), Stats: new EquipStats(3, 0, 0, 0, 2, 2)).Register("ring902U3"));
+
+      infoList.Add(new ItemInfo(ItemType.RING, "Lucky 4 Ring", "", GadgetCoreAPI.LoadTexture2D("i903U1.png"), Stats: new EquipStats(0, 0, 0, 0, 0, 0)).Register("ring903U1"));
+      infoList.Add(new ItemInfo(ItemType.RING, "Bomb Ring", "", GadgetCoreAPI.LoadTexture2D("i903U2.png"), Stats: new EquipStats(0, 2, 2, 4, 0, 0)).Register("ring903U2"));
+      infoList.Add(new ItemInfo(ItemType.RING, "Banana Ring", "", GadgetCoreAPI.LoadTexture2D("i903U3.png"), Stats: new EquipStats(0, 3, 3, 2, 0, 0)).Register("ring903U3"));
+
+      infoList.Add(new ItemInfo(ItemType.RING, "Gem Ring", "", GadgetCoreAPI.LoadTexture2D("i904U1.png"), Stats: new EquipStats(0, 2, 2, 0, 2, 2)).Register("ring904U1"));
+      infoList.Add(new ItemInfo(ItemType.RING, "Void Ring", "", GadgetCoreAPI.LoadTexture2D("i904U2.png"), Stats: new EquipStats(2, 0, 2, 1, 0, 0)).Register("ring904U2"));
+      infoList.Add(new ItemInfo(ItemType.RING, "Resonance Ring", "", GadgetCoreAPI.LoadTexture2D("i904U3.png"), Stats: new EquipStats(2, 0, 2, 1, 0, 0)).Register("ring904U3"));
+
+      infoList.Add(new ItemInfo(ItemType.RING, "Forrest Ring", "", GadgetCoreAPI.LoadTexture2D("i905U1.png"), Stats: new EquipStats(0, 5, 2, 0, 0, 0)).Register("ring905U1"));
+      infoList.Add(new ItemInfo(ItemType.RING, "Emptiness Ring", "", GadgetCoreAPI.LoadTexture2D("i905U2.png"), Stats: new EquipStats(0, 8, 0, 0, 0, 0)).Register("ring905U2"));
+      infoList.Add(new ItemInfo(ItemType.RING, "Fresh Ring", "", GadgetCoreAPI.LoadTexture2D("i905U3.png"), Stats: new EquipStats(0, 5, 2, 0, 0, 0)).Register("ring905U3"));
+
+      Core.infoList = infoList;
+
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(900, 89), Core.infoList[0].GetID());
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(900, 90), Core.infoList[1].GetID());
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(900, 91), Core.infoList[2].GetID());
+
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(901, 89), Core.infoList[3].GetID());
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(901, 90), Core.infoList[4].GetID());
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(901, 91), Core.infoList[5].GetID());
+
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(902, 89), Core.infoList[6].GetID());
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(902, 90), Core.infoList[7].GetID());
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(902, 91), Core.infoList[8].GetID());
+
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(903, 89), Core.infoList[9].GetID());
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(903, 90), Core.infoList[10].GetID());
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(903, 91), Core.infoList[11].GetID());
+
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(904, 89), Core.infoList[12].GetID());
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(904, 90), Core.infoList[13].GetID());
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(904, 91), Core.infoList[14].GetID());
+
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(905, 89), Core.infoList[15].GetID());
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(905, 90), Core.infoList[16].GetID());
+      GadgetCoreAPI.AddUltimateForgeRecipe(new Tuple<int, int>(905, 91), Core.infoList[17].GetID());
+
+    }
+  }
+}

+ 407 - 0
VendingMachine/VendingMachine.csproj

@@ -0,0 +1,407 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project Sdk="Microsoft.NET.Sdk">
+  <ImportGroup>
+    <Import Project="../GamePaths.xml" />
+  </ImportGroup>
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProjectGuid>{91AB81DE-EAEE-47D1-93DD-541179208219}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>VendingMachine</RootNamespace>
+    <AssemblyName>VendingMachine</AssemblyName>
+    <TargetFrameworks>net35</TargetFrameworks>
+    <FileAlignment>512</FileAlignment>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+    <Configurations>Release</Configurations>
+    <Authors>Zariteis</Authors>
+    <ApplicationIcon />
+    <StartupObject />
+    <Platforms>x86</Platforms>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net35|x86'">
+    <NoWarn>1701;1702</NoWarn>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="0Harmony">
+      <HintPath>$(GamePath)$(ManagedFolder)0Harmony.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="Assembly-CSharp">
+      <HintPath>$(GamePath)$(ManagedFolder)Assembly-CSharp.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="GadgetCore">
+      <HintPath>$(GamePath)$(ManagedFolder)GadgetCore.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="UnityEngine">
+      <HintPath>$(GamePath)$(ManagedFolder)UnityEngine.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="WindowsBase" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="ModInfo.txt">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+  <UsingTask TaskName="GetFileVersion" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
+    <ParameterGroup>
+      <AssemblyPath ParameterType="System.String" Required="true" />
+      <Version ParameterType="System.String" Output="true" />
+      <TrimmedVersion ParameterType="System.String" Output="true" />
+    </ParameterGroup>
+    <Task>
+      <Using Namespace="System.Diagnostics" />
+      <Using Namespace="System.Text" />
+      <Using Namespace="System.Linq" />
+      <Code Type="Fragment" Language="cs">
+        <![CDATA[
+      this.Version = FileVersionInfo.GetVersionInfo(this.AssemblyPath).FileVersion;  
+      this.TrimmedVersion = this.Version.Split('.').TakeWhile(x => !x.Equals("0")).Aggregate(new StringBuilder(), (a, b) => { if (a.Length > 0) a.Append("."); a.Append(b); return a; }).ToString();
+      if (this.TrimmedVersion.IndexOf('.') == -1) this.TrimmedVersion += ".0";
+    ]]>
+      </Code>
+    </Task>
+  </UsingTask>
+  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
+    <GetFileVersion AssemblyPath="$(TargetPath)">
+      <Output TaskParameter="Version" PropertyName="ModFullVersion" />
+      <Output TaskParameter="TrimmedVersion" PropertyName="AssemblyFileVersion" />
+    </GetFileVersion>
+    <ItemGroup>
+      <OldZip Include="$(TargetDir)$(AssemblyName)_v*.zip" />
+      <OldZip Include="$(GamePath)GadgetCore\Mods\$(AssemblyName)_v*.zip" />
+    </ItemGroup>
+    <Delete Files="@(OldZip)" />
+    <MakeDir Directories="$(TargetDir)..\BuildCache\" />
+    <ZipDirectory SourceDirectory="$(TargetDir)" DestinationFile="$(TargetDir)..\BuildCache\$(AssemblyName)_v$(AssemblyFileVersion).zip" />
+    <Copy SourceFiles="$(TargetDir)..\BuildCache\$(AssemblyName)_v$(AssemblyFileVersion).zip" DestinationFiles="$(TargetDir)$(AssemblyName)_v$(AssemblyFileVersion).zip" />
+    <RemoveDir Directories="$(TargetDir)..\BuildCache\" />
+    <MakeDir Directories="$(GamePath)GadgetCore\Mods\" />
+    <Copy SourceFiles="$(TargetDir)$(AssemblyName)_v$(AssemblyFileVersion).zip" DestinationFiles="$(GamePath)GadgetCore\Mods\$(AssemblyName)_v$(AssemblyFileVersion).zip" />
+    <Message Importance="High" Text="Mod Exported to $(GamePath)GadgetCore\Mods\$(AssemblyName)_v$(AssemblyFileVersion).zip" />
+  </Target>
+  <ItemGroup>
+    <None Update="Assets\ancientCrystal.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\ancientCrystalCM.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\bgScrapYard.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\bgSpace.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\bScrapYardbg0.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\bScrapYardbg1.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\bScrapYardbg2.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\bScrapYardbg3.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\bSpacebg0.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\bSpacebg1.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\bSpacebg2.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\bSpacebg3.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\bugspotBig.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\cGreenLamp.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\charBG.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\cOrangeLamp.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\cPlatform.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\cPurpleLamp.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\cWhiteLamp.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\cYellowLamp.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\entranceScrapYard.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\entranceSpace.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\First\one">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\frozenWisp.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\goldenShroom.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i900U1.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i900U2.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i900U3.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i901U1.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i901U2.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i901U3.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i902U1.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i902U2.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i902U3.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i903U1.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i903U2.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i903U3.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i904U1.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i904U2.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i904U3.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i905U1.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i905U2.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\i905U3.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\iAirCore.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\iCore.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\iEarthCore.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\iFireCore.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\iGreenLamp.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\iOrangeLamp.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\iPlatform.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\iPurpleLamp.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\iWaterCore.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\iWhiteLamp.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\iYellowLamp.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\meteor1.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\meteor2.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\meteor3.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\meteor4.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\midCoverChunk0.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\midHiddenChunk0.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\midScrapYardChunk0.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\midScrapYardChunk1.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\midSpaceChunk0.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\midSpaceChunk1.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\one">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\plagueBall.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\plagueNest.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\planetScrapYard.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\planetSpace.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\planetSpacePrev.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\recipesEmpty.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\sideBigScrapYard.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\sideBigSpace.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\sidesmallScrapYard.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\sideSmallSpace.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\signScrapYard - Kopie.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\signScrapYard.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\signSpace.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\spaceOre.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\spaceOreBig.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\spiderEgg.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\spiderEggCM.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\spiderEggCM2.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\spikePlant.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\spikePlantCM.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\stars.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\tx1.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Assets\tx2.png">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="Manifest.ini">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Update="System">
+      <Private>false</Private>
+      <SpecificVersion>true</SpecificVersion>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Update="System.Data">
+      <EmbedInteropTypes>false</EmbedInteropTypes>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Update="System.Drawing">
+      <EmbedInteropTypes>false</EmbedInteropTypes>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Update="System.IO.Compression.FileSystem">
+      <EmbedInteropTypes>false</EmbedInteropTypes>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Update="System.Numerics">
+      <EmbedInteropTypes>false</EmbedInteropTypes>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Update="System.Runtime.Serialization">
+      <EmbedInteropTypes>false</EmbedInteropTypes>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Update="System.Xml">
+      <EmbedInteropTypes>false</EmbedInteropTypes>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Update="System.Xml.Linq">
+      <EmbedInteropTypes>false</EmbedInteropTypes>
+    </Reference>
+  </ItemGroup>
+</Project>