using Microsoft.Xna.Framework.Graphics;
using oldschoolcrafting.Content.Items;
using ReLogic.Content;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using Terraria;
using Terraria.GameContent;
using Terraria.GameContent.ItemDropRules;
using Terraria.ID;
using Terraria.Localization;
using Terraria.ModLoader;
namespace oldschoolcrafting
{
public class oldschoolcrafting : Mod
{
}
public class RecipieChanges : ModSystem
{
private record IngredientSpec(bool IsGroup, int Id, int Stack);
private static IngredientSpec Item(int itemId, int stack = 1) => new(false, itemId, stack);
private static IngredientSpec Group(int groupId, int stack = 1) => new(true, groupId, stack);
private record RecipeReplacement
{
public IngredientSpec[][] Variants { get; }
public int[] TileOverride { get; }
public RecipeReplacement(IngredientSpec[] ingredients, int[] tileOverride = null)
{
Variants = new[] { ingredients };
TileOverride = tileOverride;
}
public RecipeReplacement(IngredientSpec[][] variants, int[] tileOverride = null)
{
Variants = variants;
TileOverride = tileOverride;
}
}
private static int AdamantiteOrTitaniumHelmetMelee;
private static int AdamantiteOrTitaniumHelmetRanged;
private static int AdamantiteOrTitaniumHelmetMagic;
private static int AdamantiteOrTitaniumChest;
private static int AdamantiteOrTitaniumLegs;
private static int CobaltOrPalladiumAnyHelmet;
private static int MythrilOrOrichalcumAnyHelmet;
private static int AdamantiteOrTitaniumAnyHelmet;
private static int CobaltOrPalladiumHelmetMelee;
private static int CobaltOrPalladiumHelmetRanged;
private static int CobaltOrPalladiumHelmetMagic;
private static int CobaltOrPalladiumChest;
private static int CobaltOrPalladiumLegs;
private static int MythrilOrOrichalcumHelmetMelee;
private static int MythrilOrOrichalcumHelmetRanged;
private static int MythrilOrOrichalcumHelmetMagic;
private static int MythrilOrOrichalcumChest;
private static int MythrilOrOrichalcumLegs;
private static int CopperOrTinBar;
private static int SilverOrTungstenBar;
private static int GoldOrPlatinumBar;
private static int CobaltOrPalladiumBar;
private static int MythrilOrOrichalcumBar;
private static int AdamantiteOrTitaniumBar;
private static int CobaltOrPalladiumPickaxe;
private static int MythrilOrOrichalcumPickaxe;
private static int AdamantiteOrTitaniumPickaxe;
private static int CobaltOrPalladiumDrill;
private static int MythrilOrOrichalcumDrill;
private static int AdamantiteOrTitaniumDrill;
private static int CobaltOrPalladiumWaraxe;
private static int MythrilOrOrichalcumWaraxe;
private static int AdamantiteOrTitaniumWaraxe;
private static int CobaltOrPalladiumChainsaw;
private static int MythrilOrOrichalcumChainsaw;
private static int AdamantiteOrTitaniumChainsaw;
private static int CobaltOrPalladiumSword;
private static int MythrilOrOrichalcumSword;
private static int AdamantiteOrTitaniumSword;
private static int CobaltOrPalladiumRepeater;
private static int MythrilOrOrichalcumRepeater;
private static int AdamantiteOrTitaniumRepeater;
private static int CobaltOrPalladiumSpear;
private static int MythrilOrOrichalcumSpear;
private static int AdamantiteOrTitaniumSpear;
public override void AddRecipeGroups()
{
CopperOrTinBar = RegisterGroup(
"CopperOrTinBar",
new int[] {
ItemID.CopperBar, ItemID.TinBar
},
displayNameOverride: "Any Copper Bar");
/* RecipieGroupID already has IronBar for us, thanks 1.2! */
SilverOrTungstenBar = RegisterGroup(
"CopperOrTinBar",
new int[] {
ItemID.SilverBar, ItemID.TungstenBar
},
displayNameOverride: "Any Silver Bar");
GoldOrPlatinumBar = RegisterGroup(
"CopperOrTinBar",
new int[] {
ItemID.GoldBar, ItemID.PlatinumBar
},
displayNameOverride: "Any Gold Bar");
/* T1 to T3 HM Ore Bars */
CobaltOrPalladiumBar = RegisterGroup(
"CobaltOrPalladiumBar", ItemID.CobaltBar, ItemID.PalladiumBar);
MythrilOrOrichalcumBar = RegisterGroup(
"MythrilOrOrichalcumBar", ItemID.MythrilBar, ItemID.OrichalcumBar);
AdamantiteOrTitaniumBar = RegisterGroup(
"AdamantiteOrTitaniumBar", ItemID.AdamantiteBar, ItemID.TitaniumBar);
/* Cobalt */
CobaltOrPalladiumHelmetMelee = RegisterGroup(
"CobaltOrPalladiumHelmetMelee",
ItemID.CobaltHelmet, ItemID.PalladiumMask);
CobaltOrPalladiumHelmetRanged = RegisterGroup(
"CobaltOrPalladiumHelmetRanged",
ItemID.CobaltMask, ItemID.PalladiumHelmet);
CobaltOrPalladiumHelmetMagic = RegisterGroup(
"CobaltOrPalladiumHelmetMagic",
ItemID.CobaltHat, ItemID.PalladiumHeadgear);
CobaltOrPalladiumChest = RegisterGroup(
"CobaltOrPalladiumChest",
ItemID.CobaltBreastplate, ItemID.PalladiumBreastplate);
CobaltOrPalladiumLegs = RegisterGroup(
"CobaltOrPalladiumLegs",
ItemID.CobaltLeggings, ItemID.PalladiumLeggings);
/* Mythril */
MythrilOrOrichalcumHelmetMelee = RegisterGroup(
"MythrilOrOrichalcumHelmetMelee",
ItemID.MythrilHelmet, ItemID.OrichalcumMask);
MythrilOrOrichalcumHelmetRanged = RegisterGroup(
"MythrilOrOrichalcumHelmetRanged",
ItemID.MythrilHat, ItemID.OrichalcumHelmet);
MythrilOrOrichalcumHelmetMagic = RegisterGroup(
"MythrilOrOrichalcumHelmetMagic",
ItemID.MythrilHood, ItemID.OrichalcumHeadgear);
MythrilOrOrichalcumChest = RegisterGroup(
"MythrilOrOrichalcumChest",
ItemID.MythrilChainmail, ItemID.OrichalcumBreastplate);
MythrilOrOrichalcumLegs = RegisterGroup(
"MythrilOrOrichalcumLegs",
ItemID.MythrilGreaves, ItemID.OrichalcumLeggings);
/* Adamantite */
AdamantiteOrTitaniumHelmetMelee = RegisterGroup(
"AdamantiteOrTitaniumHelmetMelee", ItemID.AdamantiteHelmet, ItemID.TitaniumHelmet);
AdamantiteOrTitaniumHelmetRanged = RegisterGroup(
"AdamantiteOrTitaniumHelmetRanged", ItemID.AdamantiteMask, ItemID.TitaniumMask);
AdamantiteOrTitaniumHelmetMagic = RegisterGroup(
"AdamantiteOrTitaniumHelmetMagic", ItemID.AdamantiteHeadgear, ItemID.TitaniumHeadgear);
AdamantiteOrTitaniumChest = RegisterGroup(
"AdamantiteOrTitaniumChest", ItemID.AdamantiteBreastplate, ItemID.TitaniumBreastplate);
AdamantiteOrTitaniumLegs = RegisterGroup(
"AdamantiteOrTitaniumLegs", ItemID.AdamantiteLeggings, ItemID.TitaniumLeggings);
/* Any Helmet */
CobaltOrPalladiumAnyHelmet = RegisterGroup(
"CobaltOrPalladiumAnyHelmet",
new int[] {
ItemID.CobaltHelmet, ItemID.CobaltMask, ItemID.CobaltHat,
ItemID.PalladiumMask, ItemID.PalladiumHelmet, ItemID.PalladiumHeadgear,
},
displayNameOverride: "Any Cobalt or Palladium Helmets");
MythrilOrOrichalcumAnyHelmet = RegisterGroup(
"MythrilOrOrichalcumAnyHelmet",
new int[] {
ItemID.MythrilHelmet, ItemID.MythrilHat, ItemID.MythrilHood,
ItemID.OrichalcumMask, ItemID.OrichalcumHelmet, ItemID.OrichalcumHeadgear,
},
displayNameOverride: "Any Mythril or Orichalcum Helmets");
AdamantiteOrTitaniumAnyHelmet = RegisterGroup(
"AdamantiteOrTitaniumAnyHelmet",
new int[] {
ItemID.AdamantiteHelmet, ItemID.AdamantiteMask, ItemID.AdamantiteHeadgear,
ItemID.TitaniumHelmet, ItemID.TitaniumMask, ItemID.TitaniumHeadgear,
},
displayNameOverride: "Any Adamantite or Titanium Helmets");
CobaltOrPalladiumPickaxe = RegisterGroup(
"CobaltOrPalladiumPickaxe", ItemID.CobaltPickaxe, ItemID.PalladiumPickaxe);
MythrilOrOrichalcumPickaxe = RegisterGroup(
"MythrilOrOrichalcumPickaxe", ItemID.MythrilPickaxe, ItemID.OrichalcumPickaxe);
AdamantiteOrTitaniumPickaxe = RegisterGroup(
"AdamantiteOrTitaniumPickaxe", ItemID.AdamantitePickaxe, ItemID.TitaniumPickaxe);
CobaltOrPalladiumDrill = RegisterGroup(
"CobaltOrPalladiumDrill", ItemID.CobaltDrill, ItemID.PalladiumDrill);
MythrilOrOrichalcumDrill = RegisterGroup(
"MythrilOrOrichalcumDrill", ItemID.MythrilDrill, ItemID.OrichalcumDrill);
AdamantiteOrTitaniumDrill = RegisterGroup(
"AdamantiteOrTitaniumDrill", ItemID.AdamantiteDrill, ItemID.TitaniumDrill);
CobaltOrPalladiumWaraxe = RegisterGroup(
"CobaltOrPalladiumWaraxe", ItemID.CobaltWaraxe, ItemID.PalladiumWaraxe);
MythrilOrOrichalcumWaraxe = RegisterGroup(
"MythrilOrOrichalcumWaraxe", ItemID.MythrilWaraxe, ItemID.OrichalcumWaraxe);
AdamantiteOrTitaniumWaraxe = RegisterGroup(
"AdamantiteOrTitaniumWaraxe", ItemID.AdamantiteWaraxe, ItemID.TitaniumWaraxe);
CobaltOrPalladiumChainsaw = RegisterGroup(
"CobaltOrPalladiumChainsaw", ItemID.CobaltChainsaw, ItemID.PalladiumChainsaw);
MythrilOrOrichalcumChainsaw = RegisterGroup(
"MythrilOrOrichalcumChainsaw", ItemID.MythrilChainsaw, ItemID.OrichalcumChainsaw);
AdamantiteOrTitaniumChainsaw = RegisterGroup(
"AdamantiteOrTitaniumChainsaw", ItemID.AdamantiteChainsaw, ItemID.TitaniumChainsaw);
CobaltOrPalladiumSword = RegisterGroup(
"CobaltOrPalladiumSword", ItemID.CobaltSword, ItemID.PalladiumSword);
MythrilOrOrichalcumSword = RegisterGroup(
"MythrilOrOrichalcumSword", ItemID.MythrilSword, ItemID.OrichalcumSword);
AdamantiteOrTitaniumSword = RegisterGroup(
"AdamantiteOrTitaniumSword", ItemID.AdamantiteSword, ItemID.TitaniumSword);
CobaltOrPalladiumRepeater = RegisterGroup(
"CobaltOrPalladiumRepeater", ItemID.CobaltRepeater, ItemID.PalladiumRepeater);
MythrilOrOrichalcumRepeater = RegisterGroup(
"MythrilOrOrichalcumRepeater", ItemID.MythrilRepeater, ItemID.OrichalcumRepeater);
AdamantiteOrTitaniumRepeater = RegisterGroup(
"AdamantiteOrTitaniumRepeater", ItemID.AdamantiteRepeater, ItemID.TitaniumRepeater);
CobaltOrPalladiumSpear = RegisterGroup(
"CobaltOrPalladiumSpear", ItemID.CobaltNaginata, ItemID.PalladiumPike);
MythrilOrOrichalcumSpear = RegisterGroup(
"MythrilOrOrichalcumSpear", ItemID.MythrilHalberd, ItemID.OrichalcumHalberd);
AdamantiteOrTitaniumSpear = RegisterGroup(
"AdamantiteOrTitaniumSpear", ItemID.AdamantiteGlaive, ItemID.TitaniumTrident);
}
private static string FormatGroupName(int[] items, string displayNameOverride)
{
if (displayNameOverride != null)
return displayNameOverride;
var names = items.Select(Lang.GetItemNameValue).ToArray();
return names.Length switch
{
1 => names[0],
2 => $"{names[0]} or {names[1]}",
_ => string.Join(", ", names[..^1]) + $", or {names[^1]}"
};
}
private static int RegisterGroup(string name, int[] items, string displayNameOverride = null)
{
var group = new RecipeGroup(() => FormatGroupName(items, displayNameOverride), items);
return RecipeGroup.RegisterGroup($"oldschoolcrafting:{name}", group);
}
private static int RegisterGroup(string name, params int[] items) => RegisterGroup(name, items, displayNameOverride: null);
private static Dictionary<int, RecipeReplacement> BuildReplacements() => new()
{
/* Jungle Stuff */
#region Jungle Stuff
[ItemID.JungleHat] = new RecipeReplacement(new IngredientSpec[][]
{
new[] { Item(ItemID.SilverHelmet, 1), Item(ItemID.Sapphire, 1), Item(ItemID.Emerald, 1), Item(ItemID.JungleSpores, 15) },
new[] { Item(ItemID.TungstenHelmet, 1), Item(ItemID.Sapphire, 1), Item(ItemID.Emerald, 1), Item(ItemID.JungleSpores, 15) },
}),
[ItemID.JungleShirt] = new RecipeReplacement(new IngredientSpec[][]
{
new[] { Item(ItemID.SilverChainmail, 1), Item(ItemID.Ruby, 1), Item(ItemID.Diamond, 1), Item(ItemID.JungleSpores, 20), Item(ItemID.Stinger, 20) },
new[] { Item(ItemID.TungstenChainmail, 1), Item(ItemID.Ruby, 1), Item(ItemID.Diamond, 1), Item(ItemID.JungleSpores, 20), Item(ItemID.Stinger, 20) },
}),
[ItemID.JunglePants] = new RecipeReplacement(new IngredientSpec[][]
{
new[] { Item(ItemID.SilverGreaves, 1), Item(ItemID.Amethyst, 1), Item(ItemID.Topaz, 1), Item(ItemID.JungleSpores, 20), Item(ItemID.Vine, 2) },
new[] { Item(ItemID.TungstenGreaves, 1), Item(ItemID.Amethyst, 1), Item(ItemID.Topaz, 1), Item(ItemID.JungleSpores, 20), Item(ItemID.Vine, 2) },
}),
[ItemID.IvyWhip] = new RecipeReplacement(new[]
{
Item(ItemID.GrapplingHook, 1),
Item(ItemID.JungleSpores, 15),
Item(ItemID.Vine, 3),
}),
[ItemID.BladeofGrass] = new RecipeReplacement(new IngredientSpec[][]
{
new[] { Item(ItemID.SilverBroadsword, 1), Item(ItemID.JungleSpores, 20), Item(ItemID.Stinger, 20) },
new[] { Item(ItemID.TungstenBroadsword, 1), Item(ItemID.JungleSpores, 20), Item(ItemID.Stinger, 20) },
}),
[ItemID.ThornChakram] = new RecipeReplacement(new[]
{
Item(ItemID.JungleSpores, 15),
Item(ItemID.Stinger, 20)
}),
/* End Jungle Stuff */
#endregion
/* Hell Stuff */
#region Hell Stuff
[ItemID.Flamarang] = new RecipeReplacement(new[]
{
Item(ItemID.HellstoneBar, 15),
Item(ItemID.EnchantedBoomerang, 1)
}),
[ItemID.MoltenFury] = new RecipeReplacement(new[]
{
Item(ItemID.HellstoneBar, 25),
}),
[ItemID.FieryGreatsword] = new RecipeReplacement(new[]
{
Item(ItemID.HellstoneBar, 35),
}),
[ItemID.MoltenPickaxe] = new RecipeReplacement(new[]
{
Item(ItemID.HellstoneBar, 35),
}),
[ItemID.MoltenHamaxe] = new RecipeReplacement(new[]
{
Item(ItemID.HellstoneBar, 35),
}),
[ItemID.PhoenixBlaster] = new RecipeReplacement(new[]
{
Item(ItemID.HellstoneBar, 20),
Item(ItemID.Handgun, 1),
}),
[ItemID.MoltenHelmet] = new RecipeReplacement(new IngredientSpec[][]
{
new[] { Item(ItemID.GoldHelmet, 1), Item(ItemID.HellstoneBar, 30) },
new[] { Item(ItemID.PlatinumHelmet, 1), Item(ItemID.HellstoneBar, 30) },
}),
[ItemID.MoltenBreastplate] = new RecipeReplacement(new IngredientSpec[][]
{
new[] { Item(ItemID.GoldChainmail, 1), Item(ItemID.HellstoneBar, 40) },
new[] { Item(ItemID.PlatinumChainmail, 1), Item(ItemID.HellstoneBar, 40) },
}),
[ItemID.MoltenGreaves] = new RecipeReplacement(new IngredientSpec[][]
{
new[] { Item(ItemID.GoldGreaves, 1), Item(ItemID.HellstoneBar, 35) },
new[] { Item(ItemID.PlatinumGreaves, 1), Item(ItemID.HellstoneBar, 35) },
}),
/** Custom: 75% more expensive, using 35 -> 20 bars from the Fiery Greatsword (Volcano) as a baseline. **/
[ItemID.ImpStaff] = new RecipeReplacement(new[]
{
Item(ItemID.HellstoneBar, 30),
}),
/* End Hell */
#endregion
#region Ores
/* Ores */
[ItemID.AdamantiteBar] = new RecipeReplacement(new[]
{
Item(ItemID.AdamantiteOre, 5),
}),
[ItemID.TitaniumBar] = new RecipeReplacement(new[]
{
Item(ItemID.TitaniumOre, 5),
}),
[ItemID.ChlorophyteBar] = new RecipeReplacement(new[]
{
Item(ItemID.ChlorophyteOre, 6),
}),
[ItemID.DemoniteBar] = new RecipeReplacement(new[]
{
Item(ItemID.DemoniteOre, 4),
}),
[ItemID.CrimtaneBar] = new RecipeReplacement(new[]
{
Item(ItemID.CrimtaneOre, 4),
}),
/* Meteorite */
/** 1.1 Recipie **/
[ItemID.MeteoriteBar] = new RecipeReplacement(new[]
{
Item(ItemID.Meteorite, 4),
}),
#endregion
/* End Ores */
#region Meteorite
[ItemID.SpaceGun] = new RecipeReplacement(new[]
{
Item(ItemID.FlintlockPistol, 1),
Item(ItemID.MeteoriteBar, 30),
Item(ItemID.FallenStar, 10),
}),
[ItemID.MeteorHamaxe] = new RecipeReplacement(new[]
{
Item(ItemID.MeteoriteBar, 35),
}),
[ItemID.MeteorHamaxe] = new RecipeReplacement(new[]
{
Item(ItemID.MeteoriteBar, 35),
}),
[ItemID.MeteorHelmet] = new RecipeReplacement(new[]
{
Item(ItemID.MeteoriteBar, 20),
}),
[ItemID.MeteorSuit] = new RecipeReplacement(new[]
{
Item(ItemID.MeteoriteBar, 30),
}),
[ItemID.MeteorHelmet] = new RecipeReplacement(new[]
{
Item(ItemID.MeteoriteBar, 25),
}),
[ItemID.BluePhaseblade] = new RecipeReplacement(new[]
{
Item(ItemID.MeteoriteBar, 20),
Item(ItemID.Sapphire, 10),
}),
[ItemID.RedPhaseblade] = new RecipeReplacement(new[]
{
Item(ItemID.MeteoriteBar, 20),
Item(ItemID.Ruby, 10),
}),
[ItemID.GreenPhaseblade] = new RecipeReplacement(new[]
{
Item(ItemID.MeteoriteBar, 20),
Item(ItemID.Emerald, 10),
}),
[ItemID.PurplePhaseblade] = new RecipeReplacement(new[]
{
Item(ItemID.MeteoriteBar, 20),
Item(ItemID.Amethyst, 10),
}),
[ItemID.WhitePhaseblade] = new RecipeReplacement(new[]
{
Item(ItemID.MeteoriteBar, 20),
Item(ItemID.Diamond, 10),
}),
[ItemID.YellowPhaseblade] = new RecipeReplacement(new[]
{
Item(ItemID.MeteoriteBar, 20),
Item(ItemID.Topaz, 10),
}),
[ItemID.OrangePhaseblade] = new RecipeReplacement(new[]
{
Item(ItemID.MeteoriteBar, 20),
Item(ItemID.Amber, 10),
}),
/* Not in 1.4.4.9...
[ItemID.RainbowPhaseblade] = new RecipeReplacement(new[]
{
}),
*/
/* End Meteroite */
#endregion
/* Hallowed / 1.1 Era */
#region Hallowed / 1.1 Era
[ItemID.HallowedMask] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumHelmetMelee, 1),
Group(MythrilOrOrichalcumHelmetMelee, 1),
Group(AdamantiteOrTitaniumHelmetMelee, 1),
Item(ItemID.HallowedBar, 12),
Item(ItemID.SoulofSight, 20)
}),
[ItemID.HallowedHelmet] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumHelmetRanged, 1),
Group(MythrilOrOrichalcumHelmetRanged, 1),
Group(AdamantiteOrTitaniumHelmetRanged, 1),
Item(ItemID.HallowedBar, 12),
Item(ItemID.SoulofSight, 20)
}),
[ItemID.HallowedHeadgear] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumHelmetMagic, 1),
Group(MythrilOrOrichalcumHelmetMagic, 1),
Group(AdamantiteOrTitaniumHelmetMagic, 1),
Item(ItemID.HallowedBar, 12),
Item(ItemID.SoulofSight, 20)
}),
[ItemID.HallowedPlateMail] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumChest, 1),
Group(MythrilOrOrichalcumChest, 1),
Group(AdamantiteOrTitaniumChest, 1),
Item(ItemID.HallowedBar, 18),
Item(ItemID.SoulofMight, 20)
}),
[ItemID.HallowedGreaves] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumLegs, 1),
Group(MythrilOrOrichalcumLegs, 1),
Group(AdamantiteOrTitaniumLegs, 1),
Item(ItemID.HallowedBar, 15),
Item(ItemID.SoulofFright, 20)
}),
[ItemID.HallowedHood] = new RecipeReplacement(new IngredientSpec[][]
{
new [] {
Group(CobaltOrPalladiumAnyHelmet, 1),
Group(MythrilOrOrichalcumAnyHelmet, 1),
Group(AdamantiteOrTitaniumAnyHelmet, 1),
Item(ItemID.HallowedBar, 12),
Item(ItemID.SoulofSight, 20)
},
//new [] {
// Group(CobaltOrPalladiumBar, 12),
// Group(MythrilOrOrichalcumBar, 12),
// Group(AdamantiteOrTitaniumBar, 12),
//Item(ItemID.HallowedBar, 12),
//Item(ItemID.SoulofSight, 20) }
}),
/* Ancient Hallow */
[ItemID.AncientHallowedMask] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumHelmetMelee, 1),
Group(MythrilOrOrichalcumHelmetMelee, 1),
Group(AdamantiteOrTitaniumHelmetMelee, 1),
Item(ItemID.HallowedBar, 12),
Item(ItemID.SoulofSight, 20)
}),
[ItemID.AncientHallowedHelmet] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumHelmetRanged, 1),
Group(MythrilOrOrichalcumHelmetRanged, 1),
Group(AdamantiteOrTitaniumHelmetRanged, 1),
Item(ItemID.HallowedBar, 12),
Item(ItemID.SoulofSight, 20)
}),
[ItemID.AncientHallowedHeadgear] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumHelmetMagic, 1),
Group(MythrilOrOrichalcumHelmetMagic, 1),
Group(AdamantiteOrTitaniumHelmetMagic, 1),
Item(ItemID.HallowedBar, 12),
Item(ItemID.SoulofSight, 20)
}),
[ItemID.AncientHallowedPlateMail] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumChest, 1),
Group(MythrilOrOrichalcumChest, 1),
Group(AdamantiteOrTitaniumChest, 1),
Item(ItemID.HallowedBar, 18),
Item(ItemID.SoulofMight, 20)
}),
[ItemID.AncientHallowedGreaves] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumLegs, 1),
Group(MythrilOrOrichalcumLegs, 1),
Group(AdamantiteOrTitaniumLegs, 1),
Item(ItemID.HallowedBar, 15),
Item(ItemID.SoulofFright, 20)
}),
[ItemID.AncientHallowedHood] = new RecipeReplacement(new IngredientSpec[][]
{
new [] {
Group(CobaltOrPalladiumAnyHelmet, 1),
Group(MythrilOrOrichalcumAnyHelmet, 1),
Group(AdamantiteOrTitaniumAnyHelmet, 1),
Item(ItemID.HallowedBar, 12),
Item(ItemID.SoulofSight, 20)
},
//new [] {
// Group(CobaltOrPalladiumBar, 12),
// Group(MythrilOrOrichalcumBar, 12),
// Group(AdamantiteOrTitaniumBar, 12),
//Item(ItemID.HallowedBar, 12),
//Item(ItemID.SoulofSight, 20) }
}),
[ItemID.Flamethrower] = new RecipeReplacement(new IngredientSpec[][]
{
new [] {
Group(CopperOrTinBar, 20),
Group(RecipeGroupID.IronBar, 20),
Item(ItemID.IllegalGunParts),
Item(ItemID.CursedFlame, 35),
Item(ItemID.SoulofFright, 20)
},
new []
{
Group(CopperOrTinBar, 20),
Group(RecipeGroupID.IronBar, 20),
Item(ItemID.IllegalGunParts),
Item(ItemID.Ichor, 35),
Item(ItemID.SoulofFright, 20)
}
}),
[ItemID.MagicalHarp] = new RecipeReplacement(new[]
{
Item(ItemID.Harp),
Item(ItemID.CrystalShard, 25),
Item(ItemID.SoulofNight, 15),
Group(GoldOrPlatinumBar, 15),
Item(ItemID.SoulofSight, 20)
}),
[ItemID.FairyBell] = new RecipeReplacement(new[]
{
Item(ItemID.Bell),
Item(ItemID.PixieDust, 80),
Item(ItemID.SoulofLight, 15),
Group(GoldOrPlatinumBar, 15),
Item(ItemID.SoulofSight, 20)
}),
[ItemID.RainbowRod] = new RecipeReplacement(new[]
{
Item(ItemID.CrystalShard, 30),
Item(ItemID.UnicornHorn, 4),
Item(ItemID.PixieDust, 60),
Item(ItemID.SoulofLight, 10),
Item(ItemID.SoulofSight, 20)
}),
[ItemID.LightDisc] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumBar, 20),
Group(MythrilOrOrichalcumBar, 20),
Item(ItemID.SoulofLight, 15),
Item(ItemID.SoulofMight, 25)
}),
[ItemID.PickaxeAxe] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumPickaxe),
Group(MythrilOrOrichalcumPickaxe),
Group(AdamantiteOrTitaniumPickaxe),
Group(CobaltOrPalladiumWaraxe),
Group(MythrilOrOrichalcumWaraxe),
Group(AdamantiteOrTitaniumWaraxe),
Item(ItemID.HallowedBar, 18),
Item(ItemID.SoulofFright, 5),
Item(ItemID.SoulofMight, 5),
Item(ItemID.SoulofSight, 5)
}),
[ItemID.Drax] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumDrill),
Group(MythrilOrOrichalcumDrill),
Group(AdamantiteOrTitaniumDrill),
Group(CobaltOrPalladiumChainsaw),
Group(MythrilOrOrichalcumChainsaw),
Group(AdamantiteOrTitaniumChainsaw),
Item(ItemID.HallowedBar, 18),
Item(ItemID.SoulofFright, 5),
Item(ItemID.SoulofMight, 5),
Item(ItemID.SoulofSight, 5)
}),
[ItemID.HallowedRepeater] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumRepeater),
Group(MythrilOrOrichalcumRepeater),
Group(AdamantiteOrTitaniumRepeater),
Item(ItemID.HallowedBar, 12),
Item(ItemID.SoulofSight, 20)
}),
[ItemID.Excalibur] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumSword),
Group(MythrilOrOrichalcumSword),
Group(AdamantiteOrTitaniumSword),
Item(ItemID.HallowedBar, 12),
Item(ItemID.SoulofMight, 20)
}),
[ItemID.Gungnir] = new RecipeReplacement(new[]
{
Group(CobaltOrPalladiumSpear),
Group(MythrilOrOrichalcumSpear),
Group(AdamantiteOrTitaniumSpear),
Item(ItemID.HallowedBar, 12),
Item(ItemID.SoulofFright, 20)
}),
/** Custom **/
[ItemID.HallowJoustingLance] = new RecipeReplacement(new[]
{
Item(ItemID.JoustingLance),
Item(ItemID.HallowedBar, 12),
Item(ItemID.SoulofMight, 20)
}),
/** Custom **/
[ItemID.SwordWhip] = new RecipeReplacement(new[]
{
Item(ItemID.HallowedBar, 12),
Item(ItemID.SoulofFright, 20)
}),
[ItemID.CrystalStorm] = new RecipeReplacement(new[]
{
Item(ItemID.SpellTome, 1),
Item(ItemID.CrystalShard, 30),
Item(ItemID.SoulofLight, 20)
}),
[ItemID.CursedFlames] = new RecipeReplacement(new[]
{
Item(ItemID.SpellTome, 1),
Item(ItemID.CursedFlame, 30),
Item(ItemID.SoulofNight, 20)
}),
[ItemID.GoldenShower] = new RecipeReplacement(new[]
{
Item(ItemID.SpellTome, 1),
Item(ItemID.Ichor, 30),
Item(ItemID.SoulofNight, 20)
}),
/** Custom **/
[ItemID.MeteorStaff] = new RecipeReplacement(new[]
{
Item(ItemID.MeteoriteBar, 20),
Item(ItemID.PixieDust, 20),
Item(ItemID.SoulofLight, 15)
}),
/** Custom **/
[ItemID.Chik] = new RecipeReplacement(new[]
{
Item(ItemID.WoodYoyo, 1),
Item(ItemID.CrystalShard, 25),
Item(ItemID.SoulofLight, 15)
}),
/** Custom **/
[ItemID.OnyxBlaster] = new RecipeReplacement(new[]
{
Item(ItemID.Shotgun, 1),
Item(ItemID.DarkShard, 2),
Item(ItemID.SoulofNight, 25) /* lol */
}),
[ItemID.CoolWhip] = new RecipeReplacement(new[]
{
Item(ItemID.SoulofLight, 12),
Item(ItemID.SoulofNight, 12),
Item(ItemID.FrostCore, 1)
}),
[ItemID.NeptunesShell] = new RecipeReplacement(new[]
{
Item(ItemID.Coral, 15),
Item(ItemID.SharkFin, 5),
Item(ItemID.Goldfish, 15),
Item(ItemID.SoulofLight, 5),
Item(ItemID.SoulofNight, 5),
Item(ItemID.SoulofFright, 20),
},
tileOverride: new int[] { TileID.MythrilAnvil, }
),
/* End Hallow */
#endregion
/** Custom **/
[ItemID.TerraBlade] = new RecipeReplacement(new[]
{
Item(ItemID.TrueNightsEdge, 1),
Item(ItemID.Excalibur, 1),
Item(ItemID.BrokenHeroSword, 3) /* instead of 1 */
}),
[ItemID.DaoofPow] = new RecipeReplacement(new[]
{
Item(ItemID.DarkShard, 1),
Item(ItemID.LightShard, 1),
Item(ItemID.SoulofNight, 10),
Item(ItemID.SoulofLight, 10),
}),
[ItemID.MechanicalWorm] = new RecipeReplacement(new IngredientSpec[][]
{
new [] {
Item(ItemID.RottenChunk, 6),
Group(CopperOrTinBar, 5),
Group(RecipeGroupID.IronBar, 5),
Item(ItemID.SoulofNight, 7),
},
new [] {
Item(ItemID.Vertebrae, 6),
Group(CopperOrTinBar, 5),
Group(RecipeGroupID.IronBar, 5),
Item(ItemID.SoulofNight, 7),
},
}),
[ItemID.MechanicalEye] = new RecipeReplacement(new[]
{
Item(ItemID.Lens, 3),
Group(CopperOrTinBar, 5),
Group(RecipeGroupID.IronBar, 5),
Item(ItemID.SoulofLight, 7),
}),
[ItemID.MechanicalSkull] = new RecipeReplacement(new[]
{
Item(ItemID.Bone, 30),
Group(CopperOrTinBar, 5),
Group(RecipeGroupID.IronBar, 5),
Item(ItemID.SoulofLight, 5),
Item(ItemID.SoulofNight, 5),
}),
/** Custom **/
[ItemID.AvengerEmblem] = new RecipeReplacement(new[]
{
Item(ItemID.SorcererEmblem, 1),
Item(ItemID.WarriorEmblem, 1),
Item(ItemID.RangerEmblem, 1),
Item(ItemID.SummonerEmblem, 1),
Item(ItemID.SoulofMight, 5),
Item(ItemID.SoulofSight, 5),
Item(ItemID.SoulofFright, 5)
}),
/** Keymolds **/
#region Keymolds
[ItemID.JungleKey] = new RecipeReplacement(new[]
{
Item(ItemID.TempleKey, 1),
Item(ModContent.ItemType<JungleKeyMold>(), 1),
Item(ItemID.SoulofFright, 5),
Item(ItemID.SoulofMight, 5),
Item(ItemID.SoulofSight, 5),
}),
[ItemID.CorruptionKey] = new RecipeReplacement(new[]
{
Item(ItemID.TempleKey, 1),
Item(ModContent.ItemType<CorruptionKeyMold>(), 1),
Item(ItemID.SoulofFright, 5),
Item(ItemID.SoulofMight, 5),
Item(ItemID.SoulofSight, 5),
}),
[ItemID.CrimsonKey] = new RecipeReplacement(new[]
{
Item(ItemID.TempleKey, 1),
Item(ModContent.ItemType<CrimsonKeyMold>(), 1),
Item(ItemID.SoulofFright, 5),
Item(ItemID.SoulofMight, 5),
Item(ItemID.SoulofSight, 5),
}),
[ItemID.HallowedKey] = new RecipeReplacement(new[]
{
Item(ItemID.TempleKey, 1),
Item(ModContent.ItemType<HallowedKeyMold>(), 1),
Item(ItemID.SoulofFright, 5),
Item(ItemID.SoulofMight, 5),
Item(ItemID.SoulofSight, 5),
}),
[ItemID.FrozenKey] = new RecipeReplacement(new[]
{
Item(ItemID.TempleKey, 1),
Item(ModContent.ItemType<FrozenKeyMold>(), 1),
Item(ItemID.SoulofFright, 5),
Item(ItemID.SoulofMight, 5),
Item(ItemID.SoulofSight, 5),
}),
[ItemID.DungeonDesertKey] = new RecipeReplacement(new[]
{
Item(ItemID.TempleKey, 1),
Item(ModContent.ItemType<DesertKeyMold>(), 1),
Item(ItemID.SoulofFright, 5),
Item(ItemID.SoulofMight, 5),
Item(ItemID.SoulofSight, 5),
}),
/* End Keymolds */
#endregion
/* Watches & Goggles */
#region Watches & Goggles
/* As of 1.4.4.9 this is already how the recipies are, but 1.4.5
* will change this -- so in preparation for that the adjustments
* are made now.
*/
//[ItemID.Goggles] = new RecipeReplacement(new[]
//{
// Item(ItemID.Lens, 2),
//},
// tileOverride: new int[] { TileID.Tables, TileID.Chairs }
// ),
//[ItemID.CopperWatch] = new RecipeReplacement(new[]
//{
// Item(ItemID.CopperBar, 10),
// Item(ItemID.Chain, 1)
//},
// tileOverride: new int[] { TileID.Tables, TileID.Chairs }
// ),
//[ItemID.TinWatch] = new RecipeReplacement(new[]
//{
// Item(ItemID.TinBar, 10),
// Item(ItemID.Chain, 1)
//},
// tileOverride: new int[] { TileID.Tables, TileID.Chairs }
//),
// [ItemID.SilverWatch] = new RecipeReplacement(new[]
//{
// Item(ItemID.SilverBar, 10),
// Item(ItemID.Chain, 1)
//},
// tileOverride: new int[] { TileID.Tables, TileID.Chairs }
//),
// [ItemID.TungstenWatch] = new RecipeReplacement(new[]
//{
// Item(ItemID.TungstenBar, 10),
// Item(ItemID.Chain, 1)
//},
// tileOverride: new int[] { TileID.Tables, TileID.Chairs }
//),
// [ItemID.GoldWatch] = new RecipeReplacement(new[]
//{
// Item(ItemID.GoldBar, 10),
// Item(ItemID.Chain, 1)
//},
// tileOverride: new int[] { TileID.Tables, TileID.Chairs }
//),
// [ItemID.PlatinumWatch] = new RecipeReplacement(new[]
//{
// Item(ItemID.PlatinumBar, 10),
// Item(ItemID.Chain, 1)
//},
// tileOverride: new int[] { TileID.Tables, TileID.Chairs }
//),
#endregion
};
public override void PostAddRecipes()
{
var Replacements = BuildReplacements();
var byResult = new Dictionary<int, List<Recipe>>();
#if DEBUG
DateTime start = DateTime.UtcNow;
#endif
for (int i = 0; i < Recipe.numRecipes; i++)
{
Recipe recipe = Main.recipe[i];
int type = recipe.createItem.type;
if (!Replacements.ContainsKey(type))
{
continue;
}
if (!byResult.TryGetValue(type, out var list))
{
byResult[type] = list = new List<Recipe>();
}
list.Add(recipe);
}
foreach (var (itemType, replacement) in Replacements)
{
byResult.TryGetValue(itemType, out var matches);
if (matches != null && matches.Count > 1)
{
int replacementCount = replacement.Variants.Length;
if (replacementCount < matches.Count)
{
#if DEBUG
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Error.WriteLine(
$"[oldschoolcrafting] Warning: {ItemID.Search.GetName(itemType)} " +
$"({itemType}): found {matches.Count} existing recipes but only {replacementCount} replacement(s) defined.");
Console.ResetColor();
#endif
}
}
Recipe anchor = ((matches != null && matches.Count > 0) ? matches[0] : null);
#if DEBUG
if (anchor == null && replacement.TileOverride == null)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Error.WriteLine(
$"[oldschoolcrafting] No original recipe found for {ItemID.Search.GetName(itemType)} " +
$"({itemType}); new recipe(s) will require no crafting station unless overridden.");
Console.ResetColor();
}
#endif
foreach (var ingredients in replacement.Variants)
{
var newRecipe = Recipe.Create(itemType);
foreach (var spec in ingredients)
{
if (spec.IsGroup)
{
newRecipe.AddRecipeGroup(spec.Id, spec.Stack);
}
else
{
newRecipe.AddIngredient(spec.Id, spec.Stack);
}
}
if (replacement.TileOverride != null)
{
foreach (int tile in replacement.TileOverride)
{
newRecipe.AddTile(tile);
}
}
else if (anchor != null)
{
foreach (int tile in anchor.requiredTile)
{
newRecipe.AddTile(tile);
}
}
if (anchor != null)
{
newRecipe.SortBefore(anchor);
}
newRecipe.Register();
}
if (matches != null)
{
foreach (Recipe old in matches)
{
old.DisableRecipe();
}
}
}
#if DEBUG
DateTime end = DateTime.UtcNow;
TimeSpan total = end - start;
Console.Write($"Total MS: " + total.TotalMilliseconds);
Console.Write("\n");
/* all this logic takes about 1 to 10 ms per iteration; not worth parallelizing */
#endif
}
}
#region Keymold Logic
public class SpriteOverrides : ModSystem
{
public class KeyMoldDrops : GlobalNPC
{
public override void ModifyGlobalLoot(GlobalLoot globalLoot)
{
Replace(globalLoot, ItemID.JungleKey, ModContent.ItemType<JungleKeyMold>(), new Conditions.JungleKeyCondition());
Replace(globalLoot, ItemID.CorruptionKey, ModContent.ItemType<CorruptionKeyMold>(), new Conditions.CorruptKeyCondition());
Replace(globalLoot, ItemID.CrimsonKey, ModContent.ItemType<CrimsonKeyMold>(), new Conditions.CrimsonKeyCondition());
Replace(globalLoot, ItemID.HallowedKey, ModContent.ItemType<HallowedKeyMold>(), new Conditions.HallowKeyCondition());
Replace(globalLoot, ItemID.FrozenKey, ModContent.ItemType<FrozenKeyMold>(), new Conditions.FrozenKeyCondition());
Replace(globalLoot, ItemID.DungeonDesertKey, ModContent.ItemType<DesertKeyMold>(), new Conditions.DesertKeyCondition());
}
private static void Replace(GlobalLoot globalLoot, int oldItemId, int newItemId, IItemDropRuleCondition condition)
{
globalLoot.RemoveWhere(rule => rule is ItemDropWithConditionRule dropRule && dropRule.itemId == oldItemId);
/* rates were 1 in 4000 prior to 1.2.3, which made them 1 in 2500! */
globalLoot.Add(new ItemDropWithConditionRule(newItemId, 4000, 1, 1, condition, 1));
}
}
}
#endregion
#region Individual Enemy Drop Adjustments
public class NPCLootChanges : GlobalNPC
{
/* runs once per npc load */
public override void ModifyNPCLoot(NPC npc, NPCLoot npcLoot)
{
if (npc.type != NPCID.CreatureFromTheDeep)
{
return;
}
switch (npc.type)
{
case (NPCID.CreatureFromTheDeep):
{
/* Unfortunately since this item was craftable prior to 1.2, we can't just have it drop from enemies like fodder, so we must remove it */
npcLoot.RemoveWhere(rule => rule is DropBasedOnExpertMode wrapper && DropsItem(wrapper.ruleForNormalMode, ItemID.NeptunesShell));
/* potentially replacing it with something else so the enemy drops *something* at least */
// npcLoot.Add(new DropBasedOnExpertMode(
// ItemDropRule.Common(ItemID.Coral, 5, 1, 2),
// ItemDropRule.Common(ItemID.Coral, 5, 2, 4)
//));
break;
}
default:
return;
}
}
private static bool DropsItem(IItemDropRule rule, int itemId)
{
return rule is CommonDropWithRerolls drop && drop.itemId == itemId;
}
}
#endregion
}