├── .gitattributes ├── .gitignore ├── Assets ├── FilterAll.png ├── FilterAmmo.png ├── FilterArmor.png ├── FilterAxe.png ├── FilterEquips.png ├── FilterHammer.png ├── FilterMagic.png ├── FilterMelee.png ├── FilterMisc.png ├── FilterOtherWeapon.png ├── FilterPickaxe.png ├── FilterPotion.png ├── FilterRanged.png ├── FilterSummon.png ├── FilterThrowing.png ├── FilterTile.png ├── FilterVanity.png ├── RecipeAll.png ├── RecipeAvailable.png ├── SearchBar.png ├── SortButtonBackground.png ├── SortButtonBackgroundActive.png ├── SortID.png ├── SortName.png ├── SortNumber.png └── SortValue.png ├── BlockRecipes.cs ├── Components ├── CraftingAccess.cs ├── CraftingAccess.png ├── CraftingAccess_Glow.png ├── CreativeStorageUnit.cs ├── CreativeStorageUnit.png ├── CreativeStorageUnit_Glow.png ├── RemoteAccess.cs ├── RemoteAccess.png ├── RemoteAccess_Glow.png ├── StorageAccess.cs ├── StorageAccess.png ├── StorageAccess_Glow.png ├── StorageComponent.cs ├── StorageComponent.png ├── StorageComponent_Highlight.png ├── StorageConnector.cs ├── StorageConnector.png ├── StorageHeart.cs ├── StorageHeart.png ├── StorageHeart_Glow.png ├── StorageUnit.cs ├── StorageUnit.png ├── StorageUnit_Glow.png ├── TEAbstractStorageUnit.cs ├── TECraftingAccess.cs ├── TECreativeStorageUnit.cs ├── TERemoteAccess.cs ├── TEStorageCenter.cs ├── TEStorageComponent.cs ├── TEStorageHeart.cs ├── TEStoragePoint.cs └── TEStorageUnit.cs ├── CraftingGUI.cs ├── DpsTooltips.cs ├── Edits ├── Detours │ └── Vanilla.NetMessage.cs └── EditsLoader.cs ├── GUIHelpers.cs ├── InterfaceHelper.cs ├── ItemData.cs ├── ItemSaveLoadHook.cs ├── ItemTypeOrderedSet.cs ├── Items ├── CraftingAccess.cs ├── CraftingAccess.png ├── CreativeStorageUnit.cs ├── CreativeStorageUnit.png ├── Locator.cs ├── Locator.png ├── LocatorDisk.cs ├── LocatorDisk.png ├── PortableAccess.cs ├── PortableAccess.png ├── RadiantJewel.cs ├── RadiantJewel.png ├── RadiantJewelBag.cs ├── RadiantJewelDrop.cs ├── RemoteAccess.cs ├── RemoteAccess.png ├── ShadowDiamond.cs ├── ShadowDiamond.png ├── ShadowDiamondDrop.cs ├── SnowBiomeEmulator.cs ├── SnowBiomeEmulator.png ├── StorageAccess.cs ├── StorageAccess.png ├── StorageComponent.cs ├── StorageComponent.png ├── StorageConnector.cs ├── StorageConnector.png ├── StorageDeactivator.cs ├── StorageDeactivator.png ├── StorageHeart.cs ├── StorageHeart.png ├── StorageItem.cs ├── StorageUnit.cs ├── StorageUnit.png ├── StorageUnitBlueChlorophyte.cs ├── StorageUnitBlueChlorophyte.png ├── StorageUnitCrimtane.cs ├── StorageUnitCrimtane.png ├── StorageUnitDemonite.cs ├── StorageUnitDemonite.png ├── StorageUnitHallowed.cs ├── StorageUnitHallowed.png ├── StorageUnitHellstone.cs ├── StorageUnitHellstone.png ├── StorageUnitLuminite.cs ├── StorageUnitLuminite.png ├── StorageUnitTerra.cs ├── StorageUnitTerra.png ├── StorageUnitTiny.cs ├── StorageUnitTiny.png ├── UpgradeBlueChlorophyte.cs ├── UpgradeBlueChlorophyte.png ├── UpgradeCrimtane.cs ├── UpgradeCrimtane.png ├── UpgradeDemonite.cs ├── UpgradeDemonite.png ├── UpgradeHallowed.cs ├── UpgradeHallowed.png ├── UpgradeHellstone.cs ├── UpgradeHellstone.png ├── UpgradeLuminite.cs ├── UpgradeLuminite.png ├── UpgradeTerra.cs └── UpgradeTerra.png ├── LICENSE ├── MagicStorageConfig.cs ├── MagicStorageExtra.RecipeGroups.cs ├── MagicStorageExtra.Translations.cs ├── MagicStorageExtra.cs ├── MagicStorageExtra.csproj ├── MagicStorageExtra.sln ├── ModSearchBox.cs ├── NetHelper.cs ├── OldArt ├── Components │ ├── CraftingAccess.png │ ├── CraftingAccess_Glow.png │ ├── CreativeStorageUnit.png │ ├── RemoteAccess.png │ ├── RemoteAccess_Glow.png │ ├── StorageAccess.png │ ├── StorageAccess_Glow.png │ ├── StorageComponent.png │ ├── StorageHeart.png │ ├── StorageHeart_Glow.png │ ├── StorageUnit.png │ └── StorageUnit_Glow.png ├── Items │ ├── CreativeStorageUnit.png │ ├── Locator.png │ ├── LocatorDisk.png │ ├── RadiantJewel.png │ ├── RemoteAccess.png │ ├── SnowBiomeEmulator.png │ ├── StorageAccess.png │ ├── StorageComponent.png │ ├── StorageHeart.png │ ├── StorageUnit.png │ ├── StorageUnitBlueChlorophyte.png │ ├── StorageUnitCrimtane.png │ ├── StorageUnitDemonite.png │ ├── StorageUnitHallowed.png │ ├── StorageUnitHellstone.png │ ├── StorageUnitLuminite.png │ ├── StorageUnitTerra.png │ ├── UpgradeBlueChlorophyte.png │ ├── UpgradeCrimtane.png │ ├── UpgradeDemonite.png │ ├── UpgradeHallowed.png │ ├── UpgradeHellstone.png │ ├── UpgradeLuminite.png │ └── UpgradeTerra.png ├── OldOldArt │ ├── CraftingAccess.png │ ├── RemoteAccess.png │ ├── StorageAccess.png │ ├── StorageComponent.png │ ├── StorageHeart.png │ └── StorageUnit.png ├── SortButtonBackground.png ├── SortButtonBackgroundActive.png ├── SortID.png ├── SortName.png └── SortNumber.png ├── Properties └── launchSettings.json ├── Readme.md ├── RecursiveCraftIntegration.cs ├── Sorting ├── CompareFunction.cs ├── DefaultSorting.cs ├── FilterMode.cs ├── ItemFilter.cs ├── ItemSorter.cs └── SortMode.cs ├── StorageGUI.cs ├── StoragePlayer.cs ├── StorageWorld.cs ├── UI ├── UIButtonChoice.cs ├── UISearchBar.cs ├── UISlotZone.cs └── UIToggleButton.cs ├── build.txt ├── description.txt ├── icon.png └── lib └── RecursiveCraft_v1.6.1.dll /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files you want to always be normalized and converted 5 | # to native line endings on checkout. 6 | *.c text 7 | *.h text 8 | *.cs text 9 | 10 | # Declare files that will always have CRLF line endings on checkout. 11 | *.sln text eol=crlf 12 | 13 | # Denote all files that are truly binary and should not be modified. 14 | *.png binary 15 | *.jpg binary 16 | -------------------------------------------------------------------------------- /Assets/FilterAll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterAll.png -------------------------------------------------------------------------------- /Assets/FilterAmmo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterAmmo.png -------------------------------------------------------------------------------- /Assets/FilterArmor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterArmor.png -------------------------------------------------------------------------------- /Assets/FilterAxe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterAxe.png -------------------------------------------------------------------------------- /Assets/FilterEquips.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterEquips.png -------------------------------------------------------------------------------- /Assets/FilterHammer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterHammer.png -------------------------------------------------------------------------------- /Assets/FilterMagic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterMagic.png -------------------------------------------------------------------------------- /Assets/FilterMelee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterMelee.png -------------------------------------------------------------------------------- /Assets/FilterMisc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterMisc.png -------------------------------------------------------------------------------- /Assets/FilterOtherWeapon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterOtherWeapon.png -------------------------------------------------------------------------------- /Assets/FilterPickaxe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterPickaxe.png -------------------------------------------------------------------------------- /Assets/FilterPotion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterPotion.png -------------------------------------------------------------------------------- /Assets/FilterRanged.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterRanged.png -------------------------------------------------------------------------------- /Assets/FilterSummon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterSummon.png -------------------------------------------------------------------------------- /Assets/FilterThrowing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterThrowing.png -------------------------------------------------------------------------------- /Assets/FilterTile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterTile.png -------------------------------------------------------------------------------- /Assets/FilterVanity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/FilterVanity.png -------------------------------------------------------------------------------- /Assets/RecipeAll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/RecipeAll.png -------------------------------------------------------------------------------- /Assets/RecipeAvailable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/RecipeAvailable.png -------------------------------------------------------------------------------- /Assets/SearchBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/SearchBar.png -------------------------------------------------------------------------------- /Assets/SortButtonBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/SortButtonBackground.png -------------------------------------------------------------------------------- /Assets/SortButtonBackgroundActive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/SortButtonBackgroundActive.png -------------------------------------------------------------------------------- /Assets/SortID.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/SortID.png -------------------------------------------------------------------------------- /Assets/SortName.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/SortName.png -------------------------------------------------------------------------------- /Assets/SortNumber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/SortNumber.png -------------------------------------------------------------------------------- /Assets/SortValue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Assets/SortValue.png -------------------------------------------------------------------------------- /BlockRecipes.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.DataStructures; 3 | using Terraria.ModLoader; 4 | 5 | namespace MagicStorageExtra 6 | { 7 | public class BlockRecipes : GlobalRecipe 8 | { 9 | public static bool active = true; 10 | public static object activeLock = new object(); 11 | 12 | public override bool RecipeAvailable(Recipe recipe) 13 | { 14 | if (!active) 15 | return true; 16 | try 17 | { 18 | Player player = Main.LocalPlayer; 19 | var modPlayer = player.GetModPlayer(); 20 | Point16 storageAccess = modPlayer.ViewingStorage(); 21 | return storageAccess.X < 0 || storageAccess.Y < 0; 22 | } 23 | catch 24 | { 25 | return true; 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Components/CraftingAccess.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.DataStructures; 3 | using Terraria.ModLoader; 4 | 5 | namespace MagicStorageExtra.Components 6 | { 7 | public class CraftingAccess : StorageAccess 8 | { 9 | public override ModTileEntity GetTileEntity() => mod.GetTileEntity("TECraftingAccess"); 10 | 11 | public override int ItemType(int frameX, int frameY) => ModContent.ItemType(); 12 | 13 | public override bool HasSmartInteract() => true; 14 | 15 | public override TEStorageHeart GetHeart(int i, int j) 16 | { 17 | Point16 point = TEStorageComponent.FindStorageCenter(new Point16(i, j)); 18 | if (point.X < 0 || point.Y < 0 || !TileEntity.ByPosition.ContainsKey(point)) 19 | return null; 20 | TileEntity heart = TileEntity.ByPosition[point]; 21 | if (!(heart is TEStorageCenter center)) 22 | return null; 23 | return center.GetHeart(); 24 | } 25 | 26 | public override void KillTile(int i, int j, ref bool fail, ref bool effectOnly, ref bool noItem) 27 | { 28 | if (Main.tile[i, j].frameX > 0) 29 | i--; 30 | if (Main.tile[i, j].frameY > 0) 31 | j--; 32 | var pos = new Point16(i, j); 33 | if (!TileEntity.ByPosition.ContainsKey(pos)) 34 | return; 35 | if (TileEntity.ByPosition[new Point16(i, j)] is TECraftingAccess access) 36 | foreach (Item item in access.stations) 37 | if (!item.IsAir) 38 | { 39 | fail = true; 40 | break; 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Components/CraftingAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Components/CraftingAccess.png -------------------------------------------------------------------------------- /Components/CraftingAccess_Glow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Components/CraftingAccess_Glow.png -------------------------------------------------------------------------------- /Components/CreativeStorageUnit.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using Terraria; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Components 7 | { 8 | public class CreativeStorageUnit : StorageComponent 9 | { 10 | public override ModTileEntity GetTileEntity() => mod.GetTileEntity("TECreativeStorageUnit"); 11 | 12 | public override int ItemType(int frameX, int frameY) => ModContent.ItemType(); 13 | 14 | public override void PostDraw(int i, int j, SpriteBatch spriteBatch) 15 | { 16 | Tile tile = Main.tile[i, j]; 17 | Vector2 zero = Main.drawToScreen ? Vector2.Zero : new Vector2(Main.offScreenRange); 18 | Vector2 drawPos = zero + 16f * new Vector2(i, j) - Main.screenPosition; 19 | var frame = new Rectangle(tile.frameX, tile.frameY, 16, 16); 20 | Color lightColor = Lighting.GetColor(i, j, Color.White); 21 | Color color = Color.Lerp(Color.White, lightColor, 0.5f); 22 | spriteBatch.Draw(mod.GetTexture("Components/CreativeStorageUnit_Glow"), drawPos, frame, color); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Components/CreativeStorageUnit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Components/CreativeStorageUnit.png -------------------------------------------------------------------------------- /Components/CreativeStorageUnit_Glow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Components/CreativeStorageUnit_Glow.png -------------------------------------------------------------------------------- /Components/RemoteAccess.cs: -------------------------------------------------------------------------------- 1 | using MagicStorageExtra.Items; 2 | using Terraria; 3 | using Terraria.DataStructures; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Components 7 | { 8 | public class RemoteAccess : StorageAccess 9 | { 10 | public override ModTileEntity GetTileEntity() => mod.GetTileEntity("TERemoteAccess"); 11 | 12 | public override int ItemType(int frameX, int frameY) => ModContent.ItemType(); 13 | 14 | public override bool HasSmartInteract() => true; 15 | 16 | public override TEStorageHeart GetHeart(int i, int j) 17 | { 18 | TileEntity ent = TileEntity.ByPosition[new Point16(i, j)]; 19 | return ((TERemoteAccess) ent).GetHeart(); 20 | } 21 | 22 | public override bool NewRightClick(int i, int j) 23 | { 24 | Player player = Main.LocalPlayer; 25 | Item item = player.inventory[player.selectedItem]; 26 | if (item.type == ModContent.ItemType() || item.type == ModContent.ItemType()) 27 | { 28 | if (Main.tile[i, j].frameX % 36 == 18) 29 | i--; 30 | if (Main.tile[i, j].frameY % 36 == 18) 31 | j--; 32 | var ent = (TERemoteAccess) TileEntity.ByPosition[new Point16(i, j)]; 33 | var locator = (Locator) item.modItem; 34 | if (ent.TryLocate(locator.location, out string message)) 35 | { 36 | if (item.type == ModContent.ItemType()) 37 | locator.location = new Point16(-1, -1); 38 | else 39 | item.SetDefaults(); 40 | } 41 | 42 | if (player.selectedItem == 58) 43 | Main.mouseItem = item.Clone(); 44 | Main.NewText(message); 45 | return true; 46 | } 47 | 48 | return base.NewRightClick(i, j); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Components/RemoteAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Components/RemoteAccess.png -------------------------------------------------------------------------------- /Components/RemoteAccess_Glow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Components/RemoteAccess_Glow.png -------------------------------------------------------------------------------- /Components/StorageAccess.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using Terraria; 4 | using Terraria.DataStructures; 5 | using Terraria.GameInput; 6 | using Terraria.ID; 7 | using Terraria.Localization; 8 | using Terraria.ModLoader; 9 | 10 | namespace MagicStorageExtra.Components 11 | { 12 | public class StorageAccess : StorageComponent 13 | { 14 | public override int ItemType(int frameX, int frameY) => ModContent.ItemType(); 15 | 16 | public override bool HasSmartInteract() => true; 17 | 18 | public virtual TEStorageHeart GetHeart(int i, int j) 19 | { 20 | Point16 point = TEStorageComponent.FindStorageCenter(new Point16(i, j)); 21 | if (point.X < 0 || point.Y < 0 || !TileEntity.ByPosition.ContainsKey(point)) 22 | return null; 23 | TileEntity heart = TileEntity.ByPosition[point]; 24 | if (!(heart is TEStorageCenter center)) 25 | return null; 26 | return center.GetHeart(); 27 | } 28 | 29 | public override void MouseOver(int i, int j) 30 | { 31 | Player player = Main.LocalPlayer; 32 | Tile tile = Main.tile[i, j]; 33 | player.showItemIcon = true; 34 | player.showItemIcon2 = ItemType(tile.frameX, tile.frameY); 35 | player.noThrow = 2; 36 | } 37 | 38 | public override bool NewRightClick(int i, int j) 39 | { 40 | if (Main.tile[i, j].frameX % 36 == 18) 41 | i--; 42 | if (Main.tile[i, j].frameY % 36 == 18) 43 | j--; 44 | 45 | string text = "This access is not connected to a Storage Heart!"; 46 | if (TileEntity.ByPosition.TryGetValue(new Point16(i, j), out TileEntity tileEntity)) 47 | if (tileEntity is TERemoteAccess remoteAccess && !remoteAccess.Loaded) 48 | text = "Storage Heart area not loaded! Try again."; 49 | 50 | if (GetHeart(i, j) == null) 51 | { 52 | Main.NewText(text); 53 | return true; 54 | } 55 | 56 | Player player = Main.LocalPlayer; 57 | var modPlayer = player.GetModPlayer(); 58 | Main.mouseRightRelease = false; 59 | if (player.sign > -1) 60 | { 61 | Main.PlaySound(SoundID.MenuClose); 62 | player.sign = -1; 63 | Main.editSign = false; 64 | Main.npcChatText = string.Empty; 65 | } 66 | 67 | if (Main.editChest) 68 | { 69 | Main.PlaySound(SoundID.MenuTick); 70 | Main.editChest = false; 71 | Main.npcChatText = string.Empty; 72 | } 73 | 74 | if (player.editedChestName) 75 | { 76 | NetMessage.SendData(MessageID.SyncPlayerChest, -1, -1, NetworkText.FromLiteral(Main.chest[player.chest].name), player.chest, 1f); 77 | player.editedChestName = false; 78 | } 79 | 80 | if (player.talkNPC > -1) 81 | { 82 | player.talkNPC = -1; 83 | Main.npcChatCornerItem = 0; 84 | Main.npcChatText = string.Empty; 85 | } 86 | 87 | bool hadChestOpen = player.chest != -1; 88 | player.chest = -1; 89 | Main.stackSplit = 600; 90 | var toOpen = new Point16(i, j); 91 | Point16 prevOpen = modPlayer.ViewingStorage(); 92 | if (prevOpen == toOpen) 93 | { 94 | modPlayer.CloseStorage(); 95 | Main.PlaySound(SoundID.MenuClose); 96 | lock (BlockRecipes.activeLock) 97 | { 98 | Recipe.FindRecipes(); 99 | } 100 | } 101 | else 102 | { 103 | bool hadOtherOpen = prevOpen.X >= 0 && prevOpen.Y >= 0; 104 | modPlayer.OpenStorage(toOpen); 105 | modPlayer.timeSinceOpen = 0; 106 | if (PlayerInput.GrappleAndInteractAreShared) 107 | PlayerInput.Triggers.JustPressed.Grapple = false; 108 | Main.recBigList = false; 109 | Main.PlaySound(hadChestOpen || hadOtherOpen ? SoundID.MenuTick : SoundID.MenuOpen); 110 | lock (BlockRecipes.activeLock) 111 | { 112 | Recipe.FindRecipes(); 113 | } 114 | } 115 | 116 | return true; 117 | } 118 | 119 | public override void PostDraw(int i, int j, SpriteBatch spriteBatch) 120 | { 121 | Tile tile = Main.tile[i, j]; 122 | Vector2 zero = Main.drawToScreen ? Vector2.Zero : new Vector2(Main.offScreenRange); 123 | Vector2 drawPos = zero + 16f * new Vector2(i, j) - Main.screenPosition; 124 | var frame = new Rectangle(tile.frameX, tile.frameY, 16, 16); 125 | Color lightColor = Lighting.GetColor(i, j, Color.White); 126 | Color color = Color.Lerp(lightColor, Color.White, Main.essScale); 127 | spriteBatch.Draw(mod.GetTexture("Components/" + Name + "_Glow"), drawPos, frame, color); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /Components/StorageAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Components/StorageAccess.png -------------------------------------------------------------------------------- /Components/StorageAccess_Glow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Components/StorageAccess_Glow.png -------------------------------------------------------------------------------- /Components/StorageComponent.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Microsoft.Xna.Framework; 3 | using Terraria; 4 | using Terraria.DataStructures; 5 | using Terraria.Enums; 6 | using Terraria.ID; 7 | using Terraria.ModLoader; 8 | using Terraria.ObjectData; 9 | 10 | namespace MagicStorageExtra.Components 11 | { 12 | public class StorageComponent : ModTile 13 | { 14 | public static Point16 killTile = new Point16(-1, -1); 15 | 16 | // Use StorageComponent_Highlight as the default highlight mask for subclasses 17 | public override string HighlightTexture => typeof(StorageComponent).FullName.Replace('.', '/') + "_Highlight"; 18 | 19 | public override void SetDefaults() 20 | { 21 | Main.tileSolidTop[Type] = true; 22 | Main.tileFrameImportant[Type] = true; 23 | 24 | TileObjectData.newTile.CopyFrom(TileObjectData.Style2x2); 25 | TileObjectData.newTile.Origin = new Point16(1, 1); 26 | TileObjectData.newTile.LavaDeath = false; 27 | TileObjectData.newTile.HookCheck = new PlacementHook(CanPlace, -1, 0, true); 28 | ModifyObjectData(); 29 | ModTileEntity tileEntity = GetTileEntity(); 30 | if (tileEntity != null) 31 | TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(tileEntity.Hook_AfterPlacement, -1, 0, false); 32 | else 33 | TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(TEStorageComponent.Hook_AfterPlacement_NoEntity, -1, 0, false); 34 | 35 | TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile); 36 | TileObjectData.newAlternate.AnchorBottom = AnchorData.Empty; 37 | TileObjectData.addAlternate(0); 38 | 39 | TileObjectData.addTile(Type); 40 | 41 | ModTranslation text = CreateMapEntryName(); 42 | text.SetDefault("Magic Storage"); 43 | AddMapEntry(new Color(153, 107, 61), text); 44 | dustType = 7; 45 | disableSmartCursor = true; 46 | TileID.Sets.HasOutlines[Type] = HasSmartInteract(); 47 | } 48 | 49 | public virtual void ModifyObjectData() 50 | { 51 | } 52 | 53 | public virtual ModTileEntity GetTileEntity() => null; 54 | 55 | public virtual int ItemType(int frameX, int frameY) => ModContent.ItemType(); 56 | 57 | public static bool IsStorageComponent(Point16 point) 58 | { 59 | Tile tile = Main.tile[point.X, point.Y]; 60 | return tile.active() && TileLoader.GetTile(tile.type) is StorageComponent; 61 | } 62 | 63 | public int CanPlace(int i, int j, int type, int style, int direction) 64 | { 65 | int count = 0; 66 | if (GetTileEntity() != null && GetTileEntity() is TEStorageCenter) 67 | count++; 68 | 69 | var startSearch = new Point16(i - 1, j - 1); 70 | var explored = new HashSet {startSearch}; 71 | var toExplore = new Queue(); 72 | foreach (Point16 point in TEStorageComponent.AdjacentComponents(startSearch)) 73 | toExplore.Enqueue(point); 74 | 75 | while (toExplore.Count > 0) 76 | { 77 | Point16 explore = toExplore.Dequeue(); 78 | if (!explored.Contains(explore) && explore != killTile) 79 | { 80 | explored.Add(explore); 81 | if (TEStorageCenter.IsStorageCenter(explore)) 82 | { 83 | count++; 84 | if (count >= 2) 85 | return -1; 86 | } 87 | 88 | foreach (Point16 point in TEStorageComponent.AdjacentComponents(explore)) 89 | toExplore.Enqueue(point); 90 | } 91 | } 92 | 93 | return count; 94 | } 95 | 96 | public override void KillMultiTile(int i, int j, int frameX, int frameY) 97 | { 98 | Item.NewItem(i * 16, j * 16, 32, 32, ItemType(frameX, frameY)); 99 | killTile = new Point16(i, j); 100 | ModTileEntity tileEntity = GetTileEntity(); 101 | if (tileEntity != null) 102 | { 103 | tileEntity.Kill(i, j); 104 | } 105 | else 106 | { 107 | if (Main.netMode == NetmodeID.MultiplayerClient) 108 | NetHelper.SendSearchAndRefresh(killTile.X, killTile.Y); 109 | else 110 | TEStorageComponent.SearchAndRefreshNetwork(killTile); 111 | } 112 | 113 | killTile = new Point16(-1, -1); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Components/StorageComponent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Components/StorageComponent.png -------------------------------------------------------------------------------- /Components/StorageComponent_Highlight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Components/StorageComponent_Highlight.png -------------------------------------------------------------------------------- /Components/StorageConnector.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Microsoft.Xna.Framework; 3 | using Terraria; 4 | using Terraria.DataStructures; 5 | using Terraria.Enums; 6 | using Terraria.ID; 7 | using Terraria.ModLoader; 8 | using Terraria.ObjectData; 9 | 10 | namespace MagicStorageExtra.Components 11 | { 12 | public class StorageConnector : ModTile 13 | { 14 | public override void SetDefaults() 15 | { 16 | Main.tileSolid[Type] = false; 17 | TileObjectData.newTile.Width = 1; 18 | TileObjectData.newTile.Height = 1; 19 | TileObjectData.newTile.Origin = new Point16(0, 0); 20 | TileObjectData.newTile.CoordinateHeights = new[] { 16 }; 21 | TileObjectData.newTile.CoordinateWidth = 16; 22 | TileObjectData.newTile.CoordinatePadding = 2; 23 | TileObjectData.newTile.HookCheck = new PlacementHook(CanPlace, -1, 0, true); 24 | TileObjectData.newTile.UsesCustomCanPlace = true; 25 | TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(Hook_AfterPlacement, -1, 0, false); 26 | TileObjectData.addTile(Type); 27 | ModTranslation text = CreateMapEntryName(); 28 | text.SetDefault("Magic Storage"); 29 | AddMapEntry(new Color(153, 107, 61), text); 30 | dustType = 7; 31 | drop = ModContent.ItemType(); 32 | } 33 | 34 | public static int CanPlace(int i, int j, int type, int style, int direction) 35 | { 36 | int count = 0; 37 | 38 | var startSearch = new Point16(i, j); 39 | var explored = new HashSet {startSearch}; 40 | var toExplore = new Queue(); 41 | foreach (Point16 point in TEStorageComponent.AdjacentComponents(startSearch)) 42 | toExplore.Enqueue(point); 43 | 44 | while (toExplore.Count > 0) 45 | { 46 | Point16 explore = toExplore.Dequeue(); 47 | if (!explored.Contains(explore) && explore != StorageComponent.killTile) 48 | { 49 | explored.Add(explore); 50 | if (TEStorageCenter.IsStorageCenter(explore)) 51 | { 52 | count++; 53 | if (count >= 2) 54 | return -1; 55 | } 56 | 57 | foreach (Point16 point in TEStorageComponent.AdjacentComponents(explore)) 58 | toExplore.Enqueue(point); 59 | } 60 | } 61 | 62 | return count; 63 | } 64 | 65 | public static int Hook_AfterPlacement(int i, int j, int type, int style, int direction) 66 | { 67 | if (Main.netMode == NetmodeID.MultiplayerClient) 68 | { 69 | NetMessage.SendTileRange(Main.myPlayer, i, j, 1, 1); 70 | NetHelper.SendSearchAndRefresh(i, j); 71 | return 0; 72 | } 73 | 74 | TEStorageComponent.SearchAndRefreshNetwork(new Point16(i, j)); 75 | return 0; 76 | } 77 | 78 | public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) 79 | { 80 | int frameX = 0; 81 | int frameY = 0; 82 | if (WorldGen.InWorld(i - 1, j) && Main.tile[i - 1, j].active() && Main.tile[i - 1, j].type == Type) 83 | frameX += 18; 84 | if (WorldGen.InWorld(i + 1, j) && Main.tile[i + 1, j].active() && Main.tile[i + 1, j].type == Type) 85 | frameX += 36; 86 | if (WorldGen.InWorld(i, j - 1) && Main.tile[i, j - 1].active() && Main.tile[i, j - 1].type == Type) 87 | frameY += 18; 88 | if (WorldGen.InWorld(i, j + 1) && Main.tile[i, j + 1].active() && Main.tile[i, j + 1].type == Type) 89 | frameY += 36; 90 | Main.tile[i, j].frameX = (short) frameX; 91 | Main.tile[i, j].frameY = (short) frameY; 92 | return false; 93 | } 94 | 95 | public override void KillTile(int i, int j, ref bool fail, ref bool effectOnly, ref bool noItem) 96 | { 97 | if (fail || effectOnly) 98 | return; 99 | StorageComponent.killTile = new Point16(i, j); 100 | if (Main.netMode == NetmodeID.MultiplayerClient) 101 | NetHelper.SendSearchAndRefresh(StorageComponent.killTile.X, StorageComponent.killTile.Y); 102 | else 103 | TEStorageComponent.SearchAndRefreshNetwork(StorageComponent.killTile); 104 | StorageComponent.killTile = new Point16(-1, -1); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Components/StorageConnector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Components/StorageConnector.png -------------------------------------------------------------------------------- /Components/StorageHeart.cs: -------------------------------------------------------------------------------- 1 | using MagicStorageExtra.Items; 2 | using Terraria; 3 | using Terraria.DataStructures; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Components 7 | { 8 | public class StorageHeart : StorageAccess 9 | { 10 | public override ModTileEntity GetTileEntity() => mod.GetTileEntity("TEStorageHeart"); 11 | 12 | public override int ItemType(int frameX, int frameY) => ModContent.ItemType(); 13 | 14 | public override bool HasSmartInteract() => true; 15 | 16 | public override TEStorageHeart GetHeart(int i, int j) 17 | { 18 | //return (TEStorageHeart) TileEntity.ByPosition[new Point16(i, j)]; 19 | if (TileEntity.ByPosition.TryGetValue(new Point16(i, j), out TileEntity tileEntity)) 20 | return (TEStorageHeart) tileEntity; 21 | return null; 22 | } 23 | 24 | public override bool NewRightClick(int i, int j) 25 | { 26 | Player player = Main.LocalPlayer; 27 | Item item = player.inventory[player.selectedItem]; 28 | if (item.type == ModContent.ItemType() || item.type == ModContent.ItemType() || item.type == ModContent.ItemType()) 29 | { 30 | if (Main.tile[i, j].frameX % 36 == 18) 31 | i--; 32 | if (Main.tile[i, j].frameY % 36 == 18) 33 | j--; 34 | var locator = (Locator) item.modItem; 35 | locator.location = new Point16(i, j); 36 | if (player.selectedItem == 58) 37 | Main.mouseItem = item.Clone(); 38 | Main.NewText("Locator successfully set to: X=" + i + ", Y=" + j); 39 | return true; 40 | } 41 | 42 | return base.NewRightClick(i, j); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Components/StorageHeart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Components/StorageHeart.png -------------------------------------------------------------------------------- /Components/StorageHeart_Glow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Components/StorageHeart_Glow.png -------------------------------------------------------------------------------- /Components/StorageUnit.cs: -------------------------------------------------------------------------------- 1 | using MagicStorageExtra.Items; 2 | using Microsoft.Xna.Framework; 3 | using Microsoft.Xna.Framework.Graphics; 4 | using Terraria; 5 | using Terraria.DataStructures; 6 | using Terraria.ID; 7 | using Terraria.ModLoader; 8 | using Terraria.ObjectData; 9 | 10 | namespace MagicStorageExtra.Components 11 | { 12 | public class StorageUnit : StorageComponent 13 | { 14 | public override void ModifyObjectData() 15 | { 16 | TileObjectData.newTile.StyleHorizontal = true; 17 | TileObjectData.newTile.StyleMultiplier = 6; 18 | TileObjectData.newTile.StyleWrapLimit = 6; 19 | } 20 | 21 | public override ModTileEntity GetTileEntity() => mod.GetTileEntity("TEStorageUnit"); 22 | 23 | public override void MouseOver(int i, int j) 24 | { 25 | Main.LocalPlayer.noThrow = 2; 26 | } 27 | 28 | public override int ItemType(int frameX, int frameY) 29 | { 30 | int style = frameY / 36; 31 | int type; 32 | switch (style) 33 | { 34 | case 1: 35 | type = ModContent.ItemType(); 36 | break; 37 | case 2: 38 | type = ModContent.ItemType(); 39 | break; 40 | case 3: 41 | type = ModContent.ItemType(); 42 | break; 43 | case 4: 44 | type = ModContent.ItemType(); 45 | break; 46 | case 5: 47 | type = ModContent.ItemType(); 48 | break; 49 | case 6: 50 | type = ModContent.ItemType(); 51 | break; 52 | case 7: 53 | type = ModContent.ItemType(); 54 | break; 55 | case 8: 56 | type = ModContent.ItemType(); 57 | break; 58 | default: 59 | type = ModContent.ItemType(); 60 | break; 61 | } 62 | 63 | return type; 64 | } 65 | 66 | public override bool CanKillTile(int i, int j, ref bool blockDamage) => Main.tile[i, j].frameX / 36 % 3 == 0; 67 | 68 | public override void KillTile(int i, int j, ref bool fail, ref bool effectOnly, ref bool noItem) 69 | { 70 | if (Main.tile[i, j].frameX / 36 % 3 != 0) 71 | fail = true; 72 | } 73 | 74 | public override bool NewRightClick(int i, int j) 75 | { 76 | if (Main.tile[i, j].frameX % 36 == 18) 77 | i--; 78 | if (Main.tile[i, j].frameY % 36 == 18) 79 | j--; 80 | if (TryUpgrade(i, j)) 81 | return true; 82 | var storageUnit = (TEStorageUnit) TileEntity.ByPosition[new Point16(i, j)]; 83 | Main.LocalPlayer.tileInteractionHappened = true; 84 | string activeString = storageUnit.Inactive ? "Inactive" : "Active"; 85 | string fullnessString = storageUnit.NumItems + " / " + storageUnit.Capacity + " Items"; 86 | Main.NewText(activeString + ", " + fullnessString); 87 | return base.NewRightClick(i, j); 88 | } 89 | 90 | private bool TryUpgrade(int i, int j) 91 | { 92 | Player player = Main.LocalPlayer; 93 | Item item = player.inventory[player.selectedItem]; 94 | int style = Main.tile[i, j].frameY / 36; 95 | bool success = false; 96 | switch (style) 97 | { 98 | case 0 when item.type == ModContent.ItemType(): 99 | SetStyle(i, j, 1); 100 | success = true; 101 | break; 102 | case 0 when item.type == ModContent.ItemType(): 103 | SetStyle(i, j, 2); 104 | success = true; 105 | break; 106 | case 1 when item.type == ModContent.ItemType(): 107 | SetStyle(i, j, 3); 108 | success = true; 109 | break; 110 | case 2 when item.type == ModContent.ItemType(): 111 | SetStyle(i, j, 3); 112 | success = true; 113 | break; 114 | case 3 when item.type == ModContent.ItemType(): 115 | SetStyle(i, j, 4); 116 | success = true; 117 | break; 118 | case 4 when item.type == ModContent.ItemType(): 119 | SetStyle(i, j, 5); 120 | success = true; 121 | break; 122 | case 5 when item.type == ModContent.ItemType(): 123 | SetStyle(i, j, 6); 124 | success = true; 125 | break; 126 | case 6 when item.type == ModContent.ItemType(): 127 | SetStyle(i, j, 7); 128 | success = true; 129 | break; 130 | } 131 | 132 | if (success) 133 | { 134 | var storageUnit = (TEStorageUnit) TileEntity.ByPosition[new Point16(i, j)]; 135 | storageUnit.UpdateTileFrame(); 136 | NetMessage.SendTileRange(Main.myPlayer, i, j, 2, 2); 137 | TEStorageHeart heart = storageUnit.GetHeart(); 138 | if (heart != null) 139 | { 140 | if (Main.netMode == NetmodeID.SinglePlayer) 141 | heart.ResetCompactStage(); 142 | else if (Main.netMode == NetmodeID.MultiplayerClient) 143 | NetHelper.SendResetCompactStage(heart.ID); 144 | } 145 | 146 | item.stack--; 147 | if (item.stack <= 0) 148 | item.SetDefaults(); 149 | if (player.selectedItem == 58) 150 | Main.mouseItem = item.Clone(); 151 | } 152 | 153 | return success; 154 | } 155 | 156 | private void SetStyle(int i, int j, int style) 157 | { 158 | Main.tile[i, j].frameY = (short) (36 * style); 159 | Main.tile[i + 1, j].frameY = (short) (36 * style); 160 | Main.tile[i, j + 1].frameY = (short) (36 * style + 18); 161 | Main.tile[i + 1, j + 1].frameY = (short) (36 * style + 18); 162 | } 163 | 164 | public override void PostDraw(int i, int j, SpriteBatch spriteBatch) 165 | { 166 | Tile tile = Main.tile[i, j]; 167 | Vector2 zero = Main.drawToScreen ? Vector2.Zero : new Vector2(Main.offScreenRange); 168 | Vector2 drawPos = zero + 16f * new Vector2(i, j) - Main.screenPosition; 169 | var frame = new Rectangle(tile.frameX, tile.frameY, 16, 16); 170 | Color lightColor = Lighting.GetColor(i, j, Color.White); 171 | Color color = Color.Lerp(Color.White, lightColor, 0.5f); 172 | spriteBatch.Draw(mod.GetTexture("Components/StorageUnit_Glow"), drawPos, frame, color); 173 | } 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /Components/StorageUnit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Components/StorageUnit.png -------------------------------------------------------------------------------- /Components/StorageUnit_Glow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Components/StorageUnit_Glow.png -------------------------------------------------------------------------------- /Components/TEAbstractStorageUnit.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using Terraria; 4 | using Terraria.DataStructures; 5 | using Terraria.ModLoader.IO; 6 | 7 | namespace MagicStorageExtra.Components 8 | { 9 | public abstract class TEAbstractStorageUnit : TEStorageComponent 10 | { 11 | private Point16 center; 12 | 13 | public bool Inactive { get; set; } 14 | 15 | public abstract bool IsFull { get; } 16 | 17 | public bool Link(Point16 pos) 18 | { 19 | bool changed = pos != center; 20 | center = pos; 21 | return changed; 22 | } 23 | 24 | public bool Unlink() => Link(new Point16(-1, -1)); 25 | 26 | public TEStorageHeart GetHeart() 27 | { 28 | if (center != new Point16(-1, -1) && ByPosition.ContainsKey(center) && ByPosition[center] is TEStorageCenter) 29 | return ((TEStorageCenter) ByPosition[center]).GetHeart(); 30 | return null; 31 | } 32 | 33 | public abstract bool HasSpaceInStackFor(Item check, bool locked = false); 34 | 35 | public abstract bool HasItem(Item check, bool locked = false, bool ignorePrefix = false); 36 | 37 | public abstract IEnumerable GetItems(); 38 | 39 | public abstract void DepositItem(Item toDeposit, bool locked = false); 40 | 41 | public abstract Item TryWithdraw(Item lookFor, bool locked = false, bool keepOneIfFavorite = false); 42 | 43 | public override TagCompound Save() 44 | { 45 | var tag = new TagCompound(); 46 | tag.Set("Inactive", Inactive); 47 | var tagCenter = new TagCompound(); 48 | tagCenter.Set("X", center.X); 49 | tagCenter.Set("Y", center.Y); 50 | tag.Set("Center", tagCenter); 51 | return tag; 52 | } 53 | 54 | public override void Load(TagCompound tag) 55 | { 56 | Inactive = tag.GetBool("Inactive"); 57 | TagCompound tagCenter = tag.GetCompound("Center"); 58 | center = new Point16(tagCenter.GetShort("X"), tagCenter.GetShort("Y")); 59 | } 60 | 61 | public override void NetSend(BinaryWriter writer, bool lightSend) 62 | { 63 | writer.Write(Inactive); 64 | writer.Write(center.X); 65 | writer.Write(center.Y); 66 | } 67 | 68 | public override void NetReceive(BinaryReader reader, bool lightReceive) 69 | { 70 | Inactive = reader.ReadBoolean(); 71 | center = new Point16(reader.ReadInt16(), reader.ReadInt16()); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Components/TECraftingAccess.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Linq; 4 | using Terraria; 5 | using Terraria.ID; 6 | using Terraria.ModLoader; 7 | using Terraria.ModLoader.IO; 8 | 9 | namespace MagicStorageExtra.Components 10 | { 11 | public class TECraftingAccess : TEStorageComponent 12 | { 13 | public const int Rows = 3; 14 | public const int Columns = 15; 15 | public const int ItemsTotal = Rows * Columns; 16 | 17 | public Item[] stations = new Item[ItemsTotal]; 18 | 19 | public TECraftingAccess() 20 | { 21 | for (int k = 0; k < ItemsTotal; k++) 22 | stations[k] = new Item(); 23 | } 24 | 25 | public override bool ValidTile(Tile tile) => tile.type == ModContent.TileType() && tile.frameX == 0 && tile.frameY == 0; 26 | 27 | public void TryDepositStation(Item item) 28 | { 29 | if (Main.netMode == NetmodeID.MultiplayerClient) 30 | return; 31 | foreach (Item station in stations) 32 | if (station.type == item.type) 33 | return; 34 | for (int k = 0; k < stations.Length; k++) 35 | if (stations[k].IsAir) 36 | { 37 | stations[k] = item.Clone(); 38 | stations[k].stack = 1; 39 | item.stack--; 40 | if (item.stack <= 0) 41 | item.SetDefaults(); 42 | NetHelper.SendTEUpdate(ID, Position); 43 | return; 44 | } 45 | } 46 | 47 | public Item TryWithdrawStation(int slot) 48 | { 49 | if (Main.netMode == NetmodeID.MultiplayerClient) 50 | return new Item(); 51 | if (!stations[slot].IsAir) 52 | { 53 | Item item = stations[slot]; 54 | stations[slot] = new Item(); 55 | NetHelper.SendTEUpdate(ID, Position); 56 | return item; 57 | } 58 | 59 | return new Item(); 60 | } 61 | 62 | public Item DoStationSwap(Item item, int slot) 63 | { 64 | if (Main.netMode == NetmodeID.MultiplayerClient) 65 | return new Item(); 66 | if (!item.IsAir) 67 | for (int k = 0; k < stations.Length; k++) 68 | if (k != slot && stations[k].type == item.type) 69 | return item; 70 | if ((item.IsAir || item.stack == 1) && !stations[slot].IsAir) 71 | { 72 | Item temp = item; 73 | item = stations[slot]; 74 | stations[slot] = temp; 75 | NetHelper.SendTEUpdate(ID, Position); 76 | return item; 77 | } 78 | 79 | if (!item.IsAir && stations[slot].IsAir) 80 | { 81 | stations[slot] = item.Clone(); 82 | stations[slot].stack = 1; 83 | item.stack--; 84 | if (item.stack <= 0) 85 | item.SetDefaults(); 86 | NetHelper.SendTEUpdate(ID, Position); 87 | return item; 88 | } 89 | 90 | return item; 91 | } 92 | 93 | public override TagCompound Save() 94 | { 95 | var tag = new TagCompound 96 | { 97 | ["Stations"] = stations.Select(ItemIO.Save).ToList() 98 | }; 99 | return tag; 100 | } 101 | 102 | public override void Load(TagCompound tag) 103 | { 104 | IList listStations = tag.GetList("Stations"); 105 | if (listStations != null && listStations.Count > 0) 106 | for (int k = 0; k < stations.Length; k++) 107 | if (k < listStations.Count) 108 | stations[k] = ItemIO.Load(listStations[k]); 109 | else 110 | stations[k] = new Item(); 111 | } 112 | 113 | public override void NetSend(BinaryWriter writer, bool lightSend) 114 | { 115 | foreach (Item item in stations) 116 | ItemIO.Send(item, writer, true, true); 117 | } 118 | 119 | public override void NetReceive(BinaryReader reader, bool lightReceive) 120 | { 121 | for (int k = 0; k < stations.Length; k++) 122 | stations[k] = ItemIO.Receive(reader, true, true); 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /Components/TECreativeStorageUnit.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using Terraria; 4 | using Terraria.ID; 5 | using Terraria.ModLoader; 6 | 7 | namespace MagicStorageExtra.Components 8 | { 9 | public class TECreativeStorageUnit : TEAbstractStorageUnit 10 | { 11 | public override bool IsFull => true; 12 | 13 | public override bool ValidTile(Tile tile) => tile.type == ModContent.TileType() && tile.frameX == 0 && tile.frameY == 0; 14 | 15 | public override bool HasSpaceInStackFor(Item check, bool locked = false) => false; 16 | 17 | public override bool HasItem(Item check, bool locked = false, bool ignorePrefix = false) => !Inactive; 18 | 19 | public override IEnumerable GetItems() => new CreativeEnumerable(Inactive); 20 | 21 | public override void DepositItem(Item toDeposit, bool locked = false) 22 | { 23 | } 24 | 25 | public override Item TryWithdraw(Item lookFor, bool locked = false, bool keepOneIfFavorite = false) 26 | { 27 | if (Inactive) 28 | return new Item(); 29 | return lookFor.Clone(); 30 | } 31 | } 32 | 33 | internal class CreativeEnumerable : IEnumerable 34 | { 35 | private readonly bool inactive; 36 | 37 | internal CreativeEnumerable(bool inactive) 38 | { 39 | this.inactive = inactive; 40 | } 41 | 42 | public IEnumerator GetEnumerator() => new CreativeEnumerator(inactive); 43 | 44 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 45 | } 46 | 47 | internal class CreativeEnumerator : IEnumerator 48 | { 49 | private readonly bool inactive; 50 | private int id; 51 | 52 | internal CreativeEnumerator(bool inactive) 53 | { 54 | this.inactive = inactive; 55 | } 56 | 57 | public Item Current 58 | { 59 | get 60 | { 61 | var item = new Item(); 62 | item.SetDefaults(id, true); 63 | item.stack = item.maxStack; 64 | return item; 65 | } 66 | } 67 | 68 | object IEnumerator.Current => Current; 69 | 70 | public bool MoveNext() 71 | { 72 | if (inactive) 73 | return false; 74 | do 75 | { 76 | id++; 77 | } while (id < ItemID.Sets.Deprecated.Length && ItemID.Sets.Deprecated[id]); 78 | 79 | return id < ItemID.Sets.Deprecated.Length; 80 | } 81 | 82 | public void Reset() 83 | { 84 | id = 0; 85 | } 86 | 87 | public void Dispose() 88 | { 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Components/TERemoteAccess.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using Terraria; 3 | using Terraria.DataStructures; 4 | using Terraria.ModLoader; 5 | using Terraria.ModLoader.IO; 6 | 7 | namespace MagicStorageExtra.Components 8 | { 9 | public class TERemoteAccess : TEStorageCenter 10 | { 11 | private bool _loaded; 12 | private Point16 locator = new Point16(-1, -1); 13 | 14 | internal bool Loaded 15 | { 16 | get => locator.X < 0 || locator.Y < 0 || _loaded; 17 | private set => _loaded = value; 18 | } 19 | 20 | public override bool ValidTile(Tile tile) => tile.type == ModContent.TileType() && tile.frameX == 0 && tile.frameY == 0; 21 | 22 | public override TEStorageHeart GetHeart() 23 | { 24 | if (locator.X < 0 || locator.Y < 0) 25 | return null; 26 | if (!ByPosition.ContainsKey(locator)) 27 | { 28 | Load(); 29 | return null; 30 | } 31 | 32 | return ByPosition[locator] as TEStorageHeart; 33 | } 34 | 35 | private void Load() 36 | { 37 | if (!Loaded) 38 | { 39 | Loaded = true; 40 | NetHelper.ClientRequestSection(locator); 41 | } 42 | } 43 | 44 | public bool TryLocate(Point16 toLocate, out string message) 45 | { 46 | if (locator.X >= 0 && locator.Y >= 0) 47 | { 48 | message = "This Access already has a locator, please mine then replace to reset it"; 49 | return false; 50 | } 51 | 52 | if (toLocate.X < 0 || toLocate.Y < 0) 53 | { 54 | message = "The locator has not been set to a destination"; 55 | return false; 56 | } 57 | 58 | message = "Success!"; 59 | locator = toLocate; 60 | NetHelper.ClientSendTEUpdate(ID); 61 | return true; 62 | } 63 | 64 | public override void Update() 65 | { 66 | TEStorageHeart heart = GetHeart(); 67 | if (heart != null && !heart.remoteAccesses.Contains(Position)) 68 | heart.remoteAccesses.Add(Position); 69 | } 70 | 71 | public override TagCompound Save() 72 | { 73 | TagCompound tag = base.Save(); 74 | var tagLocator = new TagCompound(); 75 | tagLocator.Set("X", locator.X); 76 | tagLocator.Set("Y", locator.Y); 77 | tag.Set("Locator", tagLocator); 78 | return tag; 79 | } 80 | 81 | public override void Load(TagCompound tag) 82 | { 83 | base.Load(tag); 84 | TagCompound tagLocator = tag.GetCompound("Locator"); 85 | locator = new Point16(tagLocator.GetShort("X"), tagLocator.GetShort("Y")); 86 | } 87 | 88 | public override void NetSend(BinaryWriter writer, bool lightSend) 89 | { 90 | base.NetSend(writer, lightSend); 91 | writer.Write(locator.X); 92 | writer.Write(locator.Y); 93 | } 94 | 95 | public override void NetReceive(BinaryReader reader, bool lightReceive) 96 | { 97 | base.NetReceive(reader, lightReceive); 98 | locator = new Point16(reader.ReadInt16(), reader.ReadInt16()); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Components/TEStorageCenter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using Terraria.DataStructures; 4 | using Terraria.ModLoader.IO; 5 | 6 | namespace MagicStorageExtra.Components 7 | { 8 | public abstract class TEStorageCenter : TEStorageComponent 9 | { 10 | public List storageUnits = new List(); 11 | 12 | public void ResetAndSearch() 13 | { 14 | var oldStorageUnits = new List(storageUnits); 15 | storageUnits.Clear(); 16 | var hashStorageUnits = new HashSet(); 17 | var explored = new HashSet {Position}; 18 | var toExplore = new Queue(); 19 | foreach (Point16 point in AdjacentComponents()) 20 | toExplore.Enqueue(point); 21 | bool changed = false; 22 | 23 | while (toExplore.Count > 0) 24 | { 25 | Point16 explore = toExplore.Dequeue(); 26 | if (!explored.Contains(explore) && explore != StorageComponent.killTile) 27 | { 28 | explored.Add(explore); 29 | if (ByPosition.ContainsKey(explore) && ByPosition[explore] is TEAbstractStorageUnit) 30 | { 31 | var storageUnit = (TEAbstractStorageUnit) ByPosition[explore]; 32 | if (storageUnit.Link(Position)) 33 | { 34 | NetHelper.SendTEUpdate(storageUnit.ID, storageUnit.Position); 35 | changed = true; 36 | } 37 | 38 | storageUnits.Add(explore); 39 | hashStorageUnits.Add(explore); 40 | } 41 | 42 | foreach (Point16 point in AdjacentComponents(explore)) 43 | toExplore.Enqueue(point); 44 | } 45 | } 46 | 47 | foreach (Point16 oldStorageUnit in oldStorageUnits) 48 | if (!hashStorageUnits.Contains(oldStorageUnit)) 49 | { 50 | if (ByPosition.ContainsKey(oldStorageUnit) && ByPosition[oldStorageUnit] is TEAbstractStorageUnit) 51 | { 52 | TileEntity storageUnit = ByPosition[oldStorageUnit]; 53 | ((TEAbstractStorageUnit) storageUnit).Unlink(); 54 | NetHelper.SendTEUpdate(storageUnit.ID, storageUnit.Position); 55 | } 56 | 57 | changed = true; 58 | } 59 | 60 | if (changed) 61 | { 62 | TEStorageHeart heart = GetHeart(); 63 | heart?.ResetCompactStage(); 64 | NetHelper.SendTEUpdate(ID, Position); 65 | } 66 | } 67 | 68 | public override void OnPlace() 69 | { 70 | ResetAndSearch(); 71 | } 72 | 73 | public override void OnKill() 74 | { 75 | foreach (Point16 storageUnit in storageUnits) 76 | { 77 | var unit = (TEAbstractStorageUnit) ByPosition[storageUnit]; 78 | unit.Unlink(); 79 | NetHelper.SendTEUpdate(unit.ID, unit.Position); 80 | } 81 | } 82 | 83 | public abstract TEStorageHeart GetHeart(); 84 | 85 | public static bool IsStorageCenter(Point16 point) => ByPosition.ContainsKey(point) && ByPosition[point] is TEStorageCenter; 86 | 87 | public override TagCompound Save() 88 | { 89 | var tag = new TagCompound(); 90 | var tagUnits = new List(); 91 | foreach (Point16 storageUnit in storageUnits) 92 | { 93 | var tagUnit = new TagCompound(); 94 | tagUnit.Set("X", storageUnit.X); 95 | tagUnit.Set("Y", storageUnit.Y); 96 | tagUnits.Add(tagUnit); 97 | } 98 | 99 | tag.Set("StorageUnits", tagUnits); 100 | return tag; 101 | } 102 | 103 | public override void Load(TagCompound tag) 104 | { 105 | foreach (TagCompound tagUnit in tag.GetList("StorageUnits")) 106 | storageUnits.Add(new Point16(tagUnit.GetShort("X"), tagUnit.GetShort("Y"))); 107 | } 108 | 109 | public override void NetSend(BinaryWriter writer, bool lightSend) 110 | { 111 | writer.Write((short) storageUnits.Count); 112 | foreach (Point16 storageUnit in storageUnits) 113 | { 114 | writer.Write(storageUnit.X); 115 | writer.Write(storageUnit.Y); 116 | } 117 | } 118 | 119 | public override void NetReceive(BinaryReader reader, bool lightReceive) 120 | { 121 | int count = reader.ReadInt16(); 122 | for (int k = 0; k < count; k++) 123 | storageUnits.Add(new Point16(reader.ReadInt16(), reader.ReadInt16())); 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /Components/TEStorageComponent.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Terraria; 3 | using Terraria.DataStructures; 4 | using Terraria.ID; 5 | using Terraria.ModLoader; 6 | 7 | namespace MagicStorageExtra.Components 8 | { 9 | public abstract class TEStorageComponent : ModTileEntity 10 | { 11 | private static readonly IEnumerable checkNeighbors = new[] 12 | { 13 | new Point16(-1, 0), 14 | new Point16(0, -1), 15 | new Point16(1, -1), 16 | new Point16(2, 0), 17 | new Point16(2, 1), 18 | new Point16(1, 2), 19 | new Point16(0, 2), 20 | new Point16(-1, 1) 21 | }; 22 | 23 | private static readonly IEnumerable checkNeighbors1x1 = new[] 24 | { 25 | new Point16(-1, 0), 26 | new Point16(0, -1), 27 | new Point16(1, 0), 28 | new Point16(0, 1) 29 | }; 30 | 31 | public override bool ValidTile(int i, int j) 32 | { 33 | Tile tile = Main.tile[i, j]; 34 | return tile.active() && ValidTile(tile); 35 | } 36 | 37 | public abstract bool ValidTile(Tile tile); 38 | 39 | public override int Hook_AfterPlacement(int i, int j, int type, int style, int direction) 40 | { 41 | if (Main.netMode == NetmodeID.MultiplayerClient) 42 | { 43 | NetHelper.SendComponentPlace(i - 1, j - 1, Type); 44 | return -1; 45 | } 46 | 47 | int id = Place(i - 1, j - 1); 48 | ((TEStorageComponent) ByID[id]).OnPlace(); 49 | return id; 50 | } 51 | 52 | public static int Hook_AfterPlacement_NoEntity(int i, int j, int type, int style, int direction) 53 | { 54 | if (Main.netMode == NetmodeID.MultiplayerClient) 55 | { 56 | NetMessage.SendTileRange(Main.myPlayer, i - 1, j - 1, 2, 2); 57 | NetHelper.SendSearchAndRefresh(i - 1, j - 1); 58 | return 0; 59 | } 60 | 61 | SearchAndRefreshNetwork(new Point16(i - 1, j - 1)); 62 | return 0; 63 | } 64 | 65 | public virtual void OnPlace() 66 | { 67 | SearchAndRefreshNetwork(Position); 68 | } 69 | 70 | public override void OnKill() 71 | { 72 | if (Main.netMode == NetmodeID.MultiplayerClient) 73 | NetHelper.SendSearchAndRefresh(Position.X, Position.Y); 74 | else 75 | SearchAndRefreshNetwork(Position); 76 | } 77 | 78 | public IEnumerable AdjacentComponents() => AdjacentComponents(Position); 79 | 80 | public static IEnumerable AdjacentComponents(Point16 point) 81 | { 82 | var points = new List(); 83 | bool isConnector = Main.tile[point.X, point.Y].type == ModContent.TileType(); 84 | foreach (Point16 add in isConnector ? checkNeighbors1x1 : checkNeighbors) 85 | { 86 | int checkX = point.X + add.X; 87 | int checkY = point.Y + add.Y; 88 | Tile tile = Main.tile[checkX, checkY]; 89 | if (!tile.active()) 90 | continue; 91 | if (TileLoader.GetTile(tile.type) is StorageComponent) 92 | { 93 | if (tile.frameX % 36 == 18) 94 | checkX--; 95 | if (tile.frameY % 36 == 18) 96 | checkY--; 97 | var check = new Point16(checkX, checkY); 98 | if (!points.Contains(check)) 99 | points.Add(check); 100 | } 101 | else if (tile.type == ModContent.TileType()) 102 | { 103 | var check = new Point16(checkX, checkY); 104 | if (!points.Contains(check)) 105 | points.Add(check); 106 | } 107 | } 108 | 109 | return points; 110 | } 111 | 112 | public static Point16 FindStorageCenter(Point16 startSearch) 113 | { 114 | var explored = new HashSet {startSearch}; 115 | var toExplore = new Queue(); 116 | foreach (Point16 point in AdjacentComponents(startSearch)) 117 | toExplore.Enqueue(point); 118 | 119 | while (toExplore.Count > 0) 120 | { 121 | Point16 explore = toExplore.Dequeue(); 122 | if (!explored.Contains(explore) && explore != StorageComponent.killTile) 123 | { 124 | explored.Add(explore); 125 | if (TEStorageCenter.IsStorageCenter(explore)) 126 | return explore; 127 | foreach (Point16 point in AdjacentComponents(explore)) 128 | toExplore.Enqueue(point); 129 | } 130 | } 131 | 132 | return new Point16(-1, -1); 133 | } 134 | 135 | public override void OnNetPlace() 136 | { 137 | OnPlace(); 138 | NetHelper.SendTEUpdate(ID, Position); 139 | } 140 | 141 | public static void SearchAndRefreshNetwork(Point16 position) 142 | { 143 | Point16 center = FindStorageCenter(position); 144 | if (center.X >= 0 && center.Y >= 0) 145 | { 146 | var centerEnt = (TEStorageCenter) ByPosition[center]; 147 | centerEnt.ResetAndSearch(); 148 | } 149 | } 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /Components/TEStoragePoint.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using Terraria.DataStructures; 4 | using Terraria.ModLoader.IO; 5 | 6 | namespace MagicStorageExtra.Components 7 | { 8 | public abstract class TEStoragePoint : TEStorageComponent 9 | { 10 | private Point16 center; 11 | 12 | public void ResetAndSearch() 13 | { 14 | Point16 oldCenter = center; 15 | center = new Point16(-1, -1); 16 | 17 | var explored = new HashSet {Position}; 18 | var toExplore = new Queue(); 19 | foreach (Point16 point in AdjacentComponents()) 20 | toExplore.Enqueue(point); 21 | 22 | while (toExplore.Count > 0) 23 | { 24 | Point16 explore = toExplore.Dequeue(); 25 | if (!explored.Contains(explore) && explore != StorageComponent.killTile) 26 | { 27 | explored.Add(explore); 28 | if (TEStorageCenter.IsStorageCenter(explore)) 29 | { 30 | center = explore; 31 | break; 32 | } 33 | 34 | foreach (Point16 point in AdjacentComponents(explore)) 35 | toExplore.Enqueue(point); 36 | } 37 | } 38 | 39 | if (center != oldCenter) 40 | NetHelper.SendTEUpdate(ID, Position); 41 | } 42 | 43 | public override void OnPlace() 44 | { 45 | ResetAndSearch(); 46 | } 47 | 48 | public bool Link(Point16 pos) 49 | { 50 | bool changed = pos != center; 51 | center = pos; 52 | return changed; 53 | } 54 | 55 | public bool Unlink() => Link(new Point16(-1, -1)); 56 | 57 | public TEStorageHeart GetHeart() 58 | { 59 | if (center != new Point16(-1, -1)) 60 | return ((TEStorageCenter) ByPosition[center]).GetHeart(); 61 | return null; 62 | } 63 | 64 | public static bool IsStoragePoint(Point16 point) => ByPosition.ContainsKey(point) && ByPosition[point] is TEStoragePoint; 65 | 66 | public override TagCompound Save() 67 | { 68 | var tag = new TagCompound(); 69 | var tagCenter = new TagCompound(); 70 | tagCenter.Set("X", center.X); 71 | tagCenter.Set("Y", center.Y); 72 | tag.Set("Center", tagCenter); 73 | return tag; 74 | } 75 | 76 | public override void Load(TagCompound tag) 77 | { 78 | TagCompound tagCenter = tag.GetCompound("Center"); 79 | center = new Point16(tagCenter.GetShort("X"), tagCenter.GetShort("Y")); 80 | } 81 | 82 | public override void NetSend(BinaryWriter writer, bool lightSend) 83 | { 84 | writer.Write(center.X); 85 | writer.Write(center.Y); 86 | } 87 | 88 | public override void NetReceive(BinaryReader reader, bool lightReceive) 89 | { 90 | center = new Point16(reader.ReadInt16(), reader.ReadInt16()); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /DpsTooltips.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using MagicStorageExtra.Sorting; 3 | using Terraria; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra 7 | { 8 | public class DpsTooltips : GlobalItem 9 | { 10 | public override void ModifyTooltips(Item item, List tooltips) 11 | { 12 | if (!MagicStorageConfig.ShowItemDps) 13 | return; 14 | 15 | double dps = CompareDps.GetDps(item); 16 | if (dps > 1f) 17 | tooltips.Add(new TooltipLine(MagicStorageExtra.Instance, "DPS", dps.ToString("F") + " DPS")); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Edits/Detours/Vanilla.NetMessage.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using On.Terraria; 4 | using Terraria.DataStructures; 5 | using Terraria.ID; 6 | using Terraria.Localization; 7 | using Terraria.ModLoader; 8 | 9 | namespace MagicStorageExtra.Edits.Detours 10 | { 11 | internal static class Vanilla 12 | { 13 | internal static void NetMessage_SendData(NetMessage.orig_SendData orig, int msgType, int remoteClient, int ignoreClient, NetworkText text, int number, float number2, float number3, float number4, int number5, int number6, int number7) 14 | { 15 | //TileSection (10) doesn't set "networkSend" to true in TileEntity.Write, so this needs to be kept track of manually 16 | //Keeping track of this simplifies the workaround code somewhat 17 | EditsLoader.MessageTileEntitySyncing = msgType == MessageID.TileSection; 18 | 19 | orig(msgType, remoteClient, ignoreClient, text, number, number2, number3, number4, number5, number6, number7); 20 | 21 | EditsLoader.MessageTileEntitySyncing = false; 22 | 23 | //Catch any uses of IDs TileSection (10) and send the ModPacket message 24 | //This is to circumvent the 65535 shorts' worth of data per-message limit and, hopefully, prevent world sections from suddenly disappearing for no reason 25 | if (msgType == MessageID.TileSection) 26 | { 27 | ModPacket packet = MagicStorageExtra.Instance.GetPacket(); 28 | 29 | //Get the entities in the section. Keep writing until the next entity written would make the size go over 65535 30 | int startX = number; 31 | int startY = (int) number2; 32 | short width = (short) number3; 33 | short height = (short) number4; 34 | 35 | var ids = new Queue(); 36 | 37 | //Only process tile entities from Magic Storage 38 | foreach (KeyValuePair item in TileEntity.ByPosition) 39 | { 40 | Point16 pos = item.Key; 41 | if (pos.X >= startX && pos.X < startX + width && pos.Y >= startY && pos.Y < startY + height) 42 | if (ModTileEntity.GetTileEntity(item.Value.type)?.mod == MagicStorageExtra.Instance) 43 | ids.Enqueue(item.Value.ID); 44 | } 45 | 46 | var ms = new MemoryStream(); 47 | var ms2 = new MemoryStream(); 48 | var msWriter = new BinaryWriter(ms); 49 | var msWriter2 = new BinaryWriter(ms2); 50 | int written = 0, total = 0, packetCount = 1; 51 | 52 | while (ids.Count > 0) 53 | WriteNetWorkaround(msWriter, ms, msWriter2, ms2, ids, ref written, ref total, ref packetCount, ref packet, remoteClient, ignoreClient, false); 54 | 55 | if (written > 0) 56 | //Write the remaining information 57 | WriteNetWorkaround(msWriter, ms, msWriter2, ms2, ids, ref written, ref total, ref packetCount, ref packet, remoteClient, ignoreClient, true); 58 | 59 | /* 60 | if (Main.netMode == NetmodeID.Server && total > 0) 61 | Console.WriteLine($"Magic Storage: Wrote {packetCount} packets for {total} entities, {(packetCount - 1) * 65535 + ms.Position} bytes written"); 62 | */ 63 | 64 | msWriter.Flush(); 65 | msWriter.Close(); 66 | msWriter.Dispose(); 67 | 68 | msWriter2.Flush(); 69 | msWriter2.Close(); 70 | msWriter2.Dispose(); 71 | } 72 | } 73 | 74 | private static void WriteNetWorkaround(BinaryWriter msWriter, MemoryStream ms, BinaryWriter msWriter2, MemoryStream ms2, Queue ids, ref int written, ref int total, ref int packetCount, ref ModPacket packet, int remoteClient, int ignoreClient, bool lastSend) 75 | { 76 | long start = msWriter.BaseStream.Position, end = start; 77 | 78 | // TODO: why does the last entity in the packet have a bad ID??? also, fix the "read underflow" issues from the other packet types 79 | 80 | if (!lastSend) 81 | { 82 | //The last send won't be getting another tile, so just ignore this section 83 | TileEntity.Write(msWriter2, TileEntity.ByID[ids.Dequeue()]); 84 | written++; 85 | total++; 86 | 87 | msWriter2.Flush(); 88 | 89 | end += msWriter2.BaseStream.Position; 90 | } 91 | 92 | byte[] newBytes = ms2.GetBuffer(); 93 | 94 | if (end > 65535 || lastSend && written > 0) 95 | { 96 | //Too much data for one net message 97 | // TODO: handle when ONE entity sends too much data, since this assumes that at least 2 would have to be split up across messages 98 | msWriter.Flush(); 99 | 100 | byte[] bytes = ms.GetBuffer(); 101 | 102 | //Write the data before the "overflow" 103 | //If this isn't the last packet, then the actual amount of entities written is "written - 1" 104 | packet.Write((byte) MessageType.NetWorkaround); 105 | packet.Write((ushort) (lastSend ? written : written - 1)); 106 | packet.Write(bytes, 0, (int) start); 107 | 108 | packet.Send(remoteClient, ignoreClient); 109 | 110 | //Debugging purposes 111 | /* 112 | if (Main.netMode == NetmodeID.Server) 113 | { 114 | string path = Path.Combine(Main.SavePath, "MagicStorage Logging"); 115 | Directory.CreateDirectory(path); 116 | 117 | path = Path.Combine(path, $"packet - {DateTime.Now.Ticks}t - {start}b.dat"); 118 | 119 | using (BinaryWriter fileWriter = new BinaryWriter(File.Open(path, FileMode.Create))) 120 | fileWriter.Write(bytes, 0, (int)start); 121 | } 122 | 123 | if (Main.netMode == NetmodeID.Server) 124 | Console.WriteLine($" [written: {written}, total: {total}, packets: {packetCount}, length: {start}]"); 125 | */ 126 | 127 | written = 0; 128 | 129 | if (!lastSend) 130 | { 131 | //Reset the packet 132 | packet = MagicStorageExtra.Instance.GetPacket(); 133 | 134 | packetCount++; 135 | 136 | //Reset the stream 137 | ms.Position = 0; 138 | ms.SetLength(0); 139 | ms.Capacity = 0; 140 | 141 | //Still need to write data for one more entity 142 | written = 1; 143 | } 144 | } 145 | 146 | if (!lastSend) 147 | { 148 | //Copy over the new bytes 149 | msWriter.Write(newBytes, 0, (int) (end - start)); 150 | 151 | ms2.Position = 0; 152 | ms2.SetLength(0); 153 | ms2.Capacity = 0; 154 | } 155 | } 156 | 157 | internal static void MessageBuffer_GetData(MessageBuffer.orig_GetData orig, Terraria.MessageBuffer self, int start, int length, out int messageType) 158 | { 159 | orig(self, start, length, out messageType); 160 | 161 | //Set to true in Mod.HijackGetData if the message ID is TileSection (10) 162 | EditsLoader.MessageTileEntitySyncing = false; 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /Edits/EditsLoader.cs: -------------------------------------------------------------------------------- 1 | using MagicStorageExtra.Edits.Detours; 2 | using On.Terraria; 3 | 4 | namespace MagicStorageExtra.Edits 5 | { 6 | //Handles loading/unloading any method detours and IL edits 7 | internal static class EditsLoader 8 | { 9 | internal static bool MessageTileEntitySyncing; 10 | 11 | public static void Load() 12 | { 13 | NetMessage.SendData += Vanilla.NetMessage_SendData; 14 | 15 | MessageBuffer.GetData += Vanilla.MessageBuffer_GetData; 16 | } 17 | 18 | public static void Unload() 19 | { 20 | NetMessage.SendData -= Vanilla.NetMessage_SendData; 21 | 22 | MessageBuffer.GetData -= Vanilla.MessageBuffer_GetData; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /GUIHelpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using MagicStorageExtra.UI; 4 | using Microsoft.Xna.Framework.Graphics; 5 | using Terraria; 6 | using Terraria.Localization; 7 | 8 | namespace MagicStorageExtra 9 | { 10 | public class GUIHelpers 11 | { 12 | public static UIButtonChoice MakeSortButtons(Action onChanged) 13 | { 14 | return new UIButtonChoice(onChanged, new[] 15 | { 16 | Main.inventorySortTexture[0], 17 | MagicStorageExtra.Instance.GetTexture("Assets/SortID"), 18 | MagicStorageExtra.Instance.GetTexture("Assets/SortName"), 19 | MagicStorageExtra.Instance.GetTexture("Assets/SortNumber"), 20 | MagicStorageExtra.Instance.GetTexture("Assets/SortNumber") 21 | }, new[] 22 | { 23 | Language.GetText("Mods.MagicStorageExtra.SortDefault"), 24 | Language.GetText("Mods.MagicStorageExtra.SortID"), 25 | Language.GetText("Mods.MagicStorageExtra.SortName"), 26 | Language.GetText("Mods.MagicStorageExtra.SortValue"), 27 | Language.GetText("Mods.MagicStorageExtra.SortDps") 28 | }); 29 | } 30 | 31 | public static UIButtonChoice MakeFilterButtons(bool withHistory, Action onChanged) 32 | { 33 | var textures = new List 34 | { 35 | MagicStorageExtra.Instance.GetTexture("Assets/FilterAll"), 36 | MagicStorageExtra.Instance.GetTexture("Assets/FilterMelee"), 37 | MagicStorageExtra.Instance.GetTexture("Assets/FilterRanged"), 38 | MagicStorageExtra.Instance.GetTexture("Assets/FilterMagic"), 39 | MagicStorageExtra.Instance.GetTexture("Assets/FilterSummon"), 40 | MagicStorageExtra.Instance.GetTexture("Assets/FilterThrowing"), 41 | MagicStorageExtra.Instance.GetTexture("Assets/FilterAmmo"), 42 | MagicStorageExtra.Instance.GetTexture("Assets/FilterPickaxe"), 43 | MagicStorageExtra.Instance.GetTexture("Assets/FilterArmor"), 44 | MagicStorageExtra.Instance.GetTexture("Assets/FilterEquips"), 45 | MagicStorageExtra.Instance.GetTexture("Assets/FilterVanity"), 46 | MagicStorageExtra.Instance.GetTexture("Assets/FilterPotion"), 47 | MagicStorageExtra.Instance.GetTexture("Assets/FilterTile"), 48 | MagicStorageExtra.Instance.GetTexture("Assets/FilterMisc") 49 | }; 50 | var texts = new List 51 | { 52 | Language.GetText("Mods.MagicStorageExtra.FilterAll"), 53 | Language.GetText("Mods.MagicStorageExtra.FilterWeaponsMelee"), 54 | Language.GetText("Mods.MagicStorageExtra.FilterWeaponsRanged"), 55 | Language.GetText("Mods.MagicStorageExtra.FilterWeaponsMagic"), 56 | Language.GetText("Mods.MagicStorageExtra.FilterWeaponsSummon"), 57 | Language.GetText("Mods.MagicStorageExtra.FilterWeaponsThrown"), 58 | Language.GetText("Mods.MagicStorageExtra.FilterAmmo"), 59 | Language.GetText("Mods.MagicStorageExtra.FilterTools"), 60 | Language.GetText("Mods.MagicStorageExtra.FilterArmor"), 61 | Language.GetText("Mods.MagicStorageExtra.FilterEquips"), 62 | Language.GetText("Mods.MagicStorageExtra.FilterVanity"), 63 | Language.GetText("Mods.MagicStorageExtra.FilterPotions"), 64 | Language.GetText("Mods.MagicStorageExtra.FilterTiles"), 65 | Language.GetText("Mods.MagicStorageExtra.FilterMisc") 66 | }; 67 | if (withHistory) 68 | { 69 | textures.Add(MagicStorageExtra.Instance.GetTexture("Assets/FilterAll")); 70 | texts.Add(Language.GetText("Mods.MagicStorageExtra.FilterRecent")); 71 | } 72 | 73 | return new UIButtonChoice(onChanged, textures.ToArray(), texts.ToArray()); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /InterfaceHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Reflection; 3 | using MagicStorageExtra.Components; 4 | using Microsoft.Xna.Framework; 5 | using Terraria; 6 | using Terraria.DataStructures; 7 | using Terraria.ModLoader; 8 | using Terraria.UI; 9 | 10 | namespace MagicStorageExtra 11 | { 12 | public static class InterfaceHelper 13 | { 14 | private static FieldInfo _itemIconCacheTimeInfo; 15 | 16 | public static void Initialize() 17 | { 18 | _itemIconCacheTimeInfo = typeof(Main).GetField("_itemIconCacheTime", BindingFlags.NonPublic | BindingFlags.Static); 19 | } 20 | 21 | public static void ModifyInterfaceLayers(List layers) 22 | { 23 | if (!Main.instance.IsActive) 24 | return; 25 | for (int k = 0; k < layers.Count; k++) 26 | if (layers[k].Name == "Vanilla: Inventory") 27 | { 28 | layers.Insert(k + 1, new LegacyGameInterfaceLayer("MagicStorageExtra: StorageAccess", DrawStorageGUI, InterfaceScaleType.UI)); 29 | k++; 30 | } 31 | } 32 | 33 | public static bool DrawStorageGUI() 34 | { 35 | Player player = Main.LocalPlayer; 36 | var modPlayer = player.GetModPlayer(); 37 | Point16 storageAccess = modPlayer.ViewingStorage(); 38 | if (Main.playerInventory && storageAccess.X >= 0 && storageAccess.Y >= 0) 39 | { 40 | ModTile modTile = TileLoader.GetTile(Main.tile[storageAccess.X, storageAccess.Y].type); 41 | if (modTile is StorageAccess access) 42 | { 43 | TEStorageHeart heart = access.GetHeart(storageAccess.X, storageAccess.Y); 44 | if (heart != null) 45 | { 46 | if (access is CraftingAccess) 47 | CraftingGUI.Draw(heart); 48 | else 49 | StorageGUI.Draw(heart); 50 | } 51 | } 52 | } 53 | 54 | return true; 55 | } 56 | 57 | public static void HideItemIconCache() 58 | { 59 | _itemIconCacheTimeInfo.SetValue(null, 0); 60 | } 61 | 62 | public static Rectangle GetFullRectangle(UIElement element) 63 | { 64 | var vector = new Vector2(element.GetDimensions().X, element.GetDimensions().Y); 65 | Vector2 position = new Vector2(element.GetDimensions().Width, element.GetDimensions().Height) + vector; 66 | vector = Vector2.Transform(vector, Main.UIScaleMatrix); 67 | position = Vector2.Transform(position, Main.UIScaleMatrix); 68 | var result = new Rectangle((int) vector.X, (int) vector.Y, (int) (position.X - vector.X), (int) (position.Y - vector.Y)); 69 | int width = Main.spriteBatch.GraphicsDevice.Viewport.Width; 70 | int height = Main.spriteBatch.GraphicsDevice.Viewport.Height; 71 | result.X = Utils.Clamp(result.X, 0, width); 72 | result.Y = Utils.Clamp(result.Y, 0, height); 73 | result.Width = Utils.Clamp(result.Width, 0, width - result.X); 74 | result.Height = Utils.Clamp(result.Height, 0, height - result.Y); 75 | return result; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /ItemData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Terraria; 3 | 4 | namespace MagicStorageExtra 5 | { 6 | public struct ItemData : IComparable 7 | { 8 | public readonly int Type; 9 | public readonly int Prefix; 10 | 11 | public ItemData(int type, int prefix = 0) 12 | { 13 | Type = type; 14 | Prefix = prefix; 15 | } 16 | 17 | public ItemData(Item item) 18 | { 19 | Type = item.type; 20 | Prefix = item.prefix; 21 | } 22 | 23 | public bool Equals(ItemData other) => Type == other.Type && Prefix == other.Prefix; 24 | 25 | public override bool Equals(object obj) => obj is ItemData other && Equals(other); 26 | 27 | public override int GetHashCode() => Type * 397 + Prefix; 28 | 29 | public static bool operator ==(ItemData left, ItemData right) => left.Equals(right); 30 | 31 | public static bool operator !=(ItemData left, ItemData right) => !left.Equals(right); 32 | 33 | public static bool Matches(Item item1, Item item2) => new ItemData(item1) == new ItemData(item2); 34 | 35 | public int CompareTo(ItemData other) 36 | { 37 | int typeComparison = Type.CompareTo(other.Type); 38 | if (typeComparison != 0) 39 | return typeComparison; 40 | return Prefix.CompareTo(other.Prefix); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ItemSaveLoadHook.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ModLoader; 3 | using Terraria.ModLoader.IO; 4 | 5 | namespace MagicStorageExtra 6 | { 7 | public class ItemSaveLoadHook : GlobalItem 8 | { 9 | public override TagCompound Save(Item item) 10 | { 11 | if (CraftingGUI.IsTestItem(item)) 12 | return new TagCompound {{"TestItem", true}}; 13 | 14 | return null; 15 | } 16 | 17 | public override void Load(Item item, TagCompound tag) 18 | { 19 | if (tag != null && tag.ContainsKey("TestItem")) 20 | CraftingGUI.MarkAsTestItem(item); 21 | 22 | base.Load(item, tag); 23 | } 24 | 25 | public override bool NeedsSaving(Item item) => CraftingGUI.IsTestItem(item); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ItemTypeOrderedSet.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Terraria; 4 | using Terraria.ModLoader; 5 | using Terraria.ModLoader.IO; 6 | 7 | namespace MagicStorageExtra 8 | { 9 | public class ItemTypeOrderedSet 10 | { 11 | private const string Suffix = "~v2"; 12 | private readonly string _name; 13 | private List _items = new List(); 14 | private HashSet _set = new HashSet(); 15 | 16 | public ItemTypeOrderedSet(string name) 17 | { 18 | _name = name; 19 | } 20 | 21 | public int Count => _items.Count; 22 | 23 | public IEnumerable Items => _items; 24 | 25 | public bool Add(Item item) => Add(item.type); 26 | 27 | public bool Add(int type) 28 | { 29 | var item = new Item(); 30 | item.SetDefaults(type); 31 | if (_set.Add(item.type)) 32 | { 33 | _items.Add(item); 34 | return true; 35 | } 36 | 37 | return false; 38 | } 39 | 40 | public bool Contains(int type) => _set.Contains(type); 41 | 42 | public bool Contains(Item item) => _set.Contains(item.type); 43 | 44 | public bool Remove(Item item) 45 | { 46 | int type = item.type; 47 | return Remove(type); 48 | } 49 | 50 | public bool Remove(int type) 51 | { 52 | if (_set.Remove(type)) 53 | { 54 | _items.RemoveAll(x => x.type == type); 55 | return true; 56 | } 57 | 58 | return false; 59 | } 60 | 61 | public void Clear() 62 | { 63 | _set.Clear(); 64 | _items.Clear(); 65 | } 66 | 67 | public bool RemoveAt(int index) 68 | { 69 | Item item = _items[index]; 70 | if (_set.Remove(item.type)) 71 | { 72 | _items.RemoveAt(index); 73 | return true; 74 | } 75 | 76 | return false; 77 | } 78 | 79 | public void Save(TagCompound c) 80 | { 81 | c.Add(_name + Suffix, _items.Select(x => x.type).ToList()); 82 | } 83 | 84 | public void Load(TagCompound tag) 85 | { 86 | IList list = tag.GetList(_name); 87 | if (list != null && list.Count > 0) 88 | { 89 | _items = list.Select(ItemIO.Load).ToList(); 90 | } 91 | else 92 | { 93 | IList listV2 = tag.GetList(_name + Suffix); 94 | if (listV2 != null) 95 | _items = listV2.Select(x => 96 | { 97 | if (x >= ItemLoader.ItemCount && ItemLoader.GetItem(x) == null) 98 | return null; 99 | var item = new Item(); 100 | item.SetDefaults(x); 101 | item.type = x; 102 | return item; 103 | }).Where(x => x != null).ToList(); 104 | else 105 | _items = new List(); 106 | } 107 | 108 | _set = new HashSet(_items.Select(x => x.type)); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /Items/CraftingAccess.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class CraftingAccess : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Storage Crafting Interface"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Модуль Создания Предметов"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Interfejs Rzemieślniczy Magazynu"); 15 | DisplayName.AddTranslation(GameCulture.French, "Interface de Stockage Artisanat"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Interfaz de Elaboración de almacenamiento"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "制作存储单元"); 18 | } 19 | 20 | public override void SetDefaults() 21 | { 22 | item.width = 26; 23 | item.height = 26; 24 | item.maxStack = 99; 25 | item.useTurn = true; 26 | item.autoReuse = true; 27 | item.useAnimation = 15; 28 | item.useTime = 10; 29 | item.useStyle = ItemUseStyleID.SwingThrow; 30 | item.consumable = true; 31 | item.rare = ItemRarityID.Blue; 32 | item.value = Item.sellPrice(0, 1, 16, 25); 33 | item.createTile = ModContent.TileType(); 34 | } 35 | 36 | public override void AddRecipe(ModItem result) 37 | { 38 | var recipe = new ModRecipe(mod); 39 | recipe.AddRecipeGroup("MagicStorageExtra:AnyStorageComponent"); 40 | recipe.AddRecipeGroup("MagicStorageExtra:AnyDiamond"); 41 | if (MagicStorageExtra.legendMod is null) 42 | recipe.AddIngredient(ItemID.Sapphire, 3); 43 | else 44 | recipe.AddRecipeGroup("MagicStorageExtra:AnySapphire", 5); 45 | recipe.AddTile(TileID.WorkBenches); 46 | recipe.SetResult(result); 47 | recipe.AddRecipe(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Items/CraftingAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/CraftingAccess.png -------------------------------------------------------------------------------- /Items/CreativeStorageUnit.cs: -------------------------------------------------------------------------------- 1 | using Terraria.ID; 2 | using Terraria.Localization; 3 | using Terraria.ModLoader; 4 | 5 | namespace MagicStorageExtra.Items 6 | { 7 | public class CreativeStorageUnit : StorageItem 8 | { 9 | public override void SetStaticDefaults() 10 | { 11 | DisplayName.AddTranslation(GameCulture.Russian, "Креативная Ячейка Хранилища"); 12 | DisplayName.AddTranslation(GameCulture.Polish, "Kreatywna Jednostka Magazynująca"); 13 | DisplayName.AddTranslation(GameCulture.French, "Unité de Stockage Créatif"); 14 | DisplayName.AddTranslation(GameCulture.Spanish, "Unidad de Almacenamiento Creativa"); 15 | DisplayName.AddTranslation(GameCulture.Chinese, "创造储存单元"); 16 | } 17 | 18 | public override void SetDefaults() 19 | { 20 | item.width = 26; 21 | item.height = 26; 22 | item.maxStack = 99; 23 | item.useTurn = true; 24 | item.autoReuse = true; 25 | item.useAnimation = 15; 26 | item.useTime = 10; 27 | item.useStyle = ItemUseStyleID.SwingThrow; 28 | item.consumable = true; 29 | item.rare = ItemRarityID.White; 30 | item.createTile = ModContent.TileType(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Items/CreativeStorageUnit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/CreativeStorageUnit.png -------------------------------------------------------------------------------- /Items/Locator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using Terraria; 4 | using Terraria.DataStructures; 5 | using Terraria.ID; 6 | using Terraria.Localization; 7 | using Terraria.ModLoader; 8 | using Terraria.ModLoader.IO; 9 | 10 | namespace MagicStorageExtra.Items 11 | { 12 | public class Locator : StorageItem 13 | { 14 | public Point16 location = new Point16(-1, -1); 15 | 16 | public override bool CloneNewInstances => true; 17 | 18 | public override void SetStaticDefaults() 19 | { 20 | DisplayName.AddTranslation(GameCulture.Russian, "Локатор"); 21 | DisplayName.AddTranslation(GameCulture.Polish, "Lokalizator"); 22 | DisplayName.AddTranslation(GameCulture.French, "Localisateur"); 23 | DisplayName.AddTranslation(GameCulture.Spanish, "Locador"); 24 | DisplayName.AddTranslation(GameCulture.Chinese, "定位器"); 25 | 26 | Tooltip.SetDefault(" Storage Heart to store location" + "\n Remote Storage Access to set it"); 27 | Tooltip.AddTranslation(GameCulture.Russian, " по Cердцу Хранилища чтобы запомнить его местоположение" + "\n на Модуль Удаленного Доступа к Хранилищу чтобы привязать его к Сердцу Хранилища"); 28 | Tooltip.AddTranslation(GameCulture.Polish, " na serce jednostki magazynującej, aby zapisać jej lokalizację" + "\n na bezprzewodowe okno dostępu aby je ustawić"); 29 | Tooltip.AddTranslation(GameCulture.French, " le Cœur de Stockage pour enregistrer son emplacement" + "\n le Stockage Éloigné pour le mettre en place"); 30 | Tooltip.AddTranslation(GameCulture.Spanish, " el Corazón de Almacenamiento para registrar su ubicación" + "\n el Acceso de Almacenamiento Remoto para establecerlo" + "\n Stockage Éloigné pour le mettre en place"); 31 | Tooltip.AddTranslation(GameCulture.Chinese, "存储核心可储存其定位点" + "\n远程存储装置以设置其定位点"); 32 | } 33 | 34 | public override void SetDefaults() 35 | { 36 | item.width = 28; 37 | item.height = 28; 38 | item.maxStack = 1; 39 | item.rare = ItemRarityID.Blue; 40 | item.value = Item.sellPrice(0, 1); 41 | } 42 | 43 | public override void ModifyTooltips(List lines) 44 | { 45 | bool isSet = location.X >= 0 && location.Y >= 0; 46 | for (int k = 0; k < lines.Count; k++) 47 | if (isSet && lines[k].mod == "Terraria" && lines[k].Name == "Tooltip0") 48 | { 49 | lines[k].text = Language.GetTextValue("Mods.MagicStorageExtra.SetTo", location.X, location.Y); 50 | } 51 | else if (!isSet && lines[k].mod == "Terraria" && lines[k].Name == "Tooltip1") 52 | { 53 | lines.RemoveAt(k); 54 | k--; 55 | } 56 | } 57 | 58 | public override void AddRecipe(ModItem result) 59 | { 60 | var recipe = new ModRecipe(mod); 61 | recipe.AddIngredient(ItemID.MeteoriteBar, 10); 62 | recipe.AddIngredient(ItemID.Amber, 2); 63 | recipe.AddTile(TileID.Anvils); 64 | recipe.SetResult(result); 65 | recipe.AddRecipe(); 66 | } 67 | 68 | public override TagCompound Save() 69 | { 70 | var tag = new TagCompound(); 71 | tag.Set("X", location.X); 72 | tag.Set("Y", location.Y); 73 | return tag; 74 | } 75 | 76 | public override void Load(TagCompound tag) 77 | { 78 | location = new Point16(tag.GetShort("X"), tag.GetShort("Y")); 79 | } 80 | 81 | public override void NetSend(BinaryWriter writer) 82 | { 83 | writer.Write(location.X); 84 | writer.Write(location.Y); 85 | } 86 | 87 | public override void NetRecieve(BinaryReader reader) 88 | { 89 | location = new Point16(reader.ReadInt16(), reader.ReadInt16()); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Items/Locator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/Locator.png -------------------------------------------------------------------------------- /Items/LocatorDisk.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class LocatorDisk : Locator 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Locator Drive"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Локатор с CD Приводом"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Dysk lokalizatora"); 15 | DisplayName.AddTranslation(GameCulture.French, "Disque Localisateur"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Disco Locador"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "定位器驱动"); 18 | 19 | Tooltip.SetDefault(" Storage Heart to store location" + "\n Remote Storage Access to set it" + "\nDoes not get destroyed upon use"); 20 | Tooltip.AddTranslation(GameCulture.Russian, " по Cердцу Хранилища чтобы запомнить его местоположение" + "\n на Модуль Удаленного Доступа к Хранилищу чтобы привязать его к Сердцу Хранилища" + "\nНе пропадает при использовании"); 21 | Tooltip.AddTranslation(GameCulture.Polish, " na serce jednostki magazynującej, aby zapisać jej lokalizację" + "\n na bezprzewodowe okno dostępu aby je ustawić" + "\nNie niszczy się po użyciu"); 22 | Tooltip.AddTranslation(GameCulture.French, " Cœur du Stockage pour enregistrer son emplacement" + "\n Stockage Éloigné pour le mettre en place" + "\nN'est pas détruit lors de son utilisation"); 23 | Tooltip.AddTranslation(GameCulture.Spanish, " el Corazón de Almacenamiento para registrar su ubicación" + "\n el Acceso de Almacenamiento Remoto para establecerlo" + "\nNo se destruye cuando se usa"); 24 | Tooltip.AddTranslation(GameCulture.Chinese, "存储核心可储存其定位点" + "\n远程存储装置以设置其定位点" + "\n使用后不再损坏"); 25 | } 26 | 27 | public override void SetDefaults() 28 | { 29 | item.width = 28; 30 | item.height = 28; 31 | item.maxStack = 1; 32 | item.rare = ItemRarityID.Red; 33 | item.value = Item.sellPrice(0, 5); 34 | } 35 | 36 | public override void AddRecipe(ModItem result) 37 | { 38 | var recipe = new ModRecipe(mod); 39 | recipe.AddIngredient(ItemID.MartianConduitPlating, 25); 40 | recipe.AddIngredient(ItemID.LunarBar, 2); 41 | recipe.AddTile(TileID.LunarCraftingStation); 42 | recipe.SetResult(result); 43 | recipe.AddRecipe(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Items/LocatorDisk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/LocatorDisk.png -------------------------------------------------------------------------------- /Items/PortableAccess.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Terraria; 3 | using Terraria.DataStructures; 4 | using Terraria.ID; 5 | using Terraria.Localization; 6 | using Terraria.ModLoader; 7 | 8 | namespace MagicStorageExtra.Items 9 | { 10 | public class PortableAccess : Locator 11 | { 12 | public override void SetStaticDefaults() 13 | { 14 | DisplayName.SetDefault("Portable Remote Storage Access"); 15 | DisplayName.AddTranslation(GameCulture.Russian, "Портативный Модуль Удаленного Доступа к Хранилищу"); 16 | DisplayName.AddTranslation(GameCulture.Chinese, "便携式远程存储装置"); 17 | 18 | Tooltip.SetDefault(" Storage Heart to store location" + "\nCurrently not set to any location" + "\nUse item to access your storage"); 19 | Tooltip.AddTranslation(GameCulture.Russian, " по Cердцу Хранилища чтобы запомнить его местоположение" + "\nВ данный момент Сердце Хранилища не привязанно" + "\nИспользуйте что бы получить доступ к вашему Хранилищу"); 20 | Tooltip.AddTranslation(GameCulture.Chinese, "存储核心可储存其定位点" + "\n目前未设置为任何位置" + "\n使用可直接访问你的存储"); 21 | } 22 | 23 | public override void SetDefaults() 24 | { 25 | item.width = 28; 26 | item.height = 28; 27 | item.maxStack = 1; 28 | item.rare = ItemRarityID.Purple; 29 | item.useStyle = ItemUseStyleID.SwingThrow; 30 | item.useAnimation = 28; 31 | item.useTime = 28; 32 | item.value = Item.sellPrice(0, 10); 33 | } 34 | 35 | public override bool UseItem(Player player) 36 | { 37 | if (player.whoAmI == Main.myPlayer) 38 | { 39 | if (location.X >= 0 && location.Y >= 0) 40 | { 41 | Tile tile = Main.tile[location.X, location.Y]; 42 | if (!tile.active() || tile.type != ModContent.TileType() || tile.frameX != 0 || tile.frameY != 0) 43 | Main.NewText("Storage Heart is missing!"); 44 | else 45 | OpenStorage(player); 46 | } 47 | else 48 | { 49 | Main.NewText("Locator is not set to any Storage Heart"); 50 | } 51 | } 52 | 53 | return true; 54 | } 55 | 56 | private void OpenStorage(Player player) 57 | { 58 | var modPlayer = player.GetModPlayer(); 59 | if (player.sign > -1) 60 | { 61 | Main.PlaySound(SoundID.MenuClose); 62 | player.sign = -1; 63 | Main.editSign = false; 64 | Main.npcChatText = string.Empty; 65 | } 66 | 67 | if (Main.editChest) 68 | { 69 | Main.PlaySound(SoundID.MenuTick); 70 | Main.editChest = false; 71 | Main.npcChatText = string.Empty; 72 | } 73 | 74 | if (player.editedChestName) 75 | { 76 | NetMessage.SendData(MessageID.SyncPlayerChest, -1, -1, NetworkText.FromLiteral(Main.chest[player.chest].name), player.chest, 1f); 77 | player.editedChestName = false; 78 | } 79 | 80 | if (player.talkNPC > -1) 81 | { 82 | player.talkNPC = -1; 83 | Main.npcChatCornerItem = 0; 84 | Main.npcChatText = string.Empty; 85 | } 86 | 87 | bool hadChestOpen = player.chest != -1; 88 | player.chest = -1; 89 | Main.stackSplit = 600; 90 | Point16 toOpen = location; 91 | Point16 prevOpen = modPlayer.ViewingStorage(); 92 | if (prevOpen == toOpen) 93 | { 94 | modPlayer.CloseStorage(); 95 | Main.PlaySound(SoundID.MenuClose); 96 | lock (BlockRecipes.activeLock) 97 | { 98 | Recipe.FindRecipes(); 99 | } 100 | } 101 | else 102 | { 103 | bool hadOtherOpen = prevOpen.X >= 0 && prevOpen.Y >= 0; 104 | modPlayer.OpenStorage(toOpen, true); 105 | modPlayer.timeSinceOpen = 0; 106 | Main.playerInventory = true; 107 | Main.recBigList = false; 108 | Main.PlaySound(hadChestOpen || hadOtherOpen ? 12 : 10); 109 | lock (BlockRecipes.activeLock) 110 | { 111 | Recipe.FindRecipes(); 112 | } 113 | } 114 | } 115 | 116 | public override void ModifyTooltips(List lines) 117 | { 118 | bool isSet = location.X >= 0 && location.Y >= 0; 119 | for (int k = 0; k < lines.Count; k++) 120 | if (isSet && lines[k].mod == "Terraria" && lines[k].Name == "Tooltip1") 121 | { 122 | lines[k].text = Language.GetTextValue("Mods.MagicStorageExtra.SetTo", location.X, location.Y); 123 | } 124 | else if (!isSet && lines[k].mod == "Terraria" && lines[k].Name == "Tooltip2") 125 | { 126 | lines.RemoveAt(k); 127 | k--; 128 | } 129 | } 130 | 131 | public override void AddRecipe(ModItem result) 132 | { 133 | var recipe = new ModRecipe(mod); 134 | recipe.AddRecipeGroup("MagicStorageExtra:AnyLocatorDisk"); 135 | recipe.AddRecipeGroup("MagicStorageExtra:AnyRadiantJewel"); 136 | recipe.AddRecipeGroup("MagicStorageExtra:AnyDiamond", 3); 137 | recipe.AddIngredient(ItemID.Ruby, 7); 138 | recipe.AddTile(TileID.LunarCraftingStation); 139 | recipe.SetResult(result); 140 | recipe.AddRecipe(); 141 | 142 | Mod otherMod = MagicStorageExtra.bluemagicMod; 143 | if (otherMod != null) 144 | { 145 | recipe = new ModRecipe(mod); 146 | recipe.AddRecipeGroup("MagicStorageExtra:AnyLocatorDisk"); 147 | recipe.AddIngredient(otherMod, "InfinityCrystal"); 148 | recipe.AddRecipeGroup("MagicStorageExtra:AnyDiamond", 3); 149 | recipe.AddIngredient(ItemID.Ruby, 7); 150 | recipe.AddTile(otherMod, "PuriumAnvil"); 151 | recipe.SetResult(result); 152 | recipe.AddRecipe(); 153 | } 154 | 155 | otherMod = ModLoader.GetMod("CalamityMod"); 156 | if (otherMod != null) 157 | { 158 | recipe = new ModRecipe(mod); 159 | recipe.AddRecipeGroup("MagicStorageExtra:AnyLocatorDisk"); 160 | recipe.AddIngredient(otherMod, "CosmiliteBar", 20); 161 | recipe.AddRecipeGroup("MagicStorageExtra:AnyDiamond", 3); 162 | recipe.AddIngredient(ItemID.Ruby, 7); 163 | recipe.AddTile(TileID.LunarCraftingStation); 164 | recipe.SetResult(result); 165 | recipe.AddRecipe(); 166 | } 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /Items/PortableAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/PortableAccess.png -------------------------------------------------------------------------------- /Items/RadiantJewel.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Terraria; 3 | using Terraria.ID; 4 | using Terraria.Localization; 5 | using Terraria.ModLoader; 6 | 7 | namespace MagicStorageExtra.Items 8 | { 9 | public class RadiantJewel : StorageItem 10 | { 11 | public override void SetStaticDefaults() 12 | { 13 | DisplayName.AddTranslation(GameCulture.Russian, "Сияющая Драгоценность"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Promieniejący klejnot"); 15 | DisplayName.AddTranslation(GameCulture.French, "Bijou Rayonnant"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Joya Radiante"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "光芒四射的宝石"); 18 | 19 | Tooltip.SetDefault("'Shines with a dazzling light'"); 20 | Tooltip.AddTranslation(GameCulture.Russian, "'Блестит ослепительным светом'"); 21 | Tooltip.AddTranslation(GameCulture.Polish, "'Świeci oślepiającym światłem'"); 22 | Tooltip.AddTranslation(GameCulture.French, "'Il brille avec une lumière aveuglante'"); 23 | Tooltip.AddTranslation(GameCulture.Spanish, "'Brilla con una luz deslumbrante'"); 24 | Tooltip.AddTranslation(GameCulture.Chinese, "'闪耀着耀眼的光芒'"); 25 | } 26 | 27 | public override void SetDefaults() 28 | { 29 | item.width = 14; 30 | item.height = 14; 31 | item.maxStack = 99; 32 | item.rare = ItemRarityID.Purple; 33 | item.value = Item.sellPrice(0, 10); 34 | } 35 | 36 | public override Color? GetAlpha(Color lightColor) => Color.White; 37 | 38 | public override void PostUpdate() 39 | { 40 | Lighting.AddLight(item.position, 1f, 1f, 1f); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Items/RadiantJewel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/RadiantJewel.png -------------------------------------------------------------------------------- /Items/RadiantJewelBag.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.ModLoader; 4 | 5 | namespace MagicStorageExtra.Items 6 | { 7 | public class RadiantJewelBag : GlobalItem 8 | { 9 | public override void OpenVanillaBag(string context, Player player, int arg) 10 | { 11 | if (MagicStorageExtra.MagicStorage != null) 12 | return; 13 | 14 | if (context == "bossBag" && arg == ItemID.MoonLordBossBag && Main.rand.Next(10) == 0) 15 | player.QuickSpawnItem(ModContent.ItemType()); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Items/RadiantJewelDrop.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.ModLoader; 4 | 5 | namespace MagicStorageExtra.Items 6 | { 7 | public class RadiantJewelDrop : GlobalNPC 8 | { 9 | public override void NPCLoot(NPC npc) 10 | { 11 | if (MagicStorageExtra.MagicStorage != null) 12 | return; 13 | 14 | if (npc.type == NPCID.MoonLordCore && !Main.expertMode && Main.rand.Next(20) == 0) 15 | Item.NewItem((int) npc.position.X, (int) npc.position.Y, npc.width, npc.height, ModContent.ItemType()); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Items/RemoteAccess.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class RemoteAccess : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Remote Storage Access"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Модуль Удаленного Доступа к Хранилищу"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Zdalna Jednostka Dostępu"); 15 | DisplayName.AddTranslation(GameCulture.French, "Fenêtre d'accès éloigné"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Acceso a Almacenamiento Remoto"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "远程存储装置"); 18 | } 19 | 20 | public override void SetDefaults() 21 | { 22 | item.width = 26; 23 | item.height = 26; 24 | item.maxStack = 99; 25 | item.useTurn = true; 26 | item.autoReuse = true; 27 | item.useAnimation = 15; 28 | item.useTime = 10; 29 | item.useStyle = ItemUseStyleID.SwingThrow; 30 | item.consumable = true; 31 | item.rare = ItemRarityID.Blue; 32 | item.value = Item.sellPrice(0, 1, 72, 50); 33 | item.createTile = ModContent.TileType(); 34 | } 35 | 36 | public override void AddRecipe(ModItem result) 37 | { 38 | var recipe = new ModRecipe(mod); 39 | recipe.AddRecipeGroup("MagicStorageExtra:AnyStorageComponent"); 40 | recipe.AddRecipeGroup("MagicStorageExtra:AnyDiamond", 3); 41 | if (MagicStorageExtra.legendMod is null) 42 | recipe.AddIngredient(ItemID.Ruby, 3); 43 | else 44 | recipe.AddRecipeGroup("MagicStorageExtra:AnyRuby", 3); 45 | recipe.AddTile(TileID.WorkBenches); 46 | recipe.SetResult(result); 47 | recipe.AddRecipe(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Items/RemoteAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/RemoteAccess.png -------------------------------------------------------------------------------- /Items/ShadowDiamond.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Terraria; 3 | using Terraria.ID; 4 | using Terraria.Localization; 5 | using Terraria.ModLoader; 6 | 7 | namespace MagicStorageExtra.Items 8 | { 9 | public class ShadowDiamond : StorageItem 10 | { 11 | public override void SetStaticDefaults() 12 | { 13 | DisplayName.AddTranslation(GameCulture.Russian, "Теневой Алмаз"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Mroczny Diament"); 15 | DisplayName.AddTranslation(GameCulture.French, "Diamant sombre"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Diamante sombreado"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "暗影钻石"); 18 | 19 | Tooltip.SetDefault("Traces of light still linger inside"); 20 | Tooltip.AddTranslation(GameCulture.Russian, "Следы света все еще мелькают внутри"); 21 | Tooltip.AddTranslation(GameCulture.Polish, "Ślady światła wciąż pozostają w środku"); 22 | Tooltip.AddTranslation(GameCulture.French, "Des traces de lumière s'attarde encore à l'intérieur"); 23 | Tooltip.AddTranslation(GameCulture.Spanish, "Sigue habiendo huellas de luz en el interior"); 24 | Tooltip.AddTranslation(GameCulture.Chinese, "那道光所余留的痕迹依旧"); 25 | } 26 | 27 | public override void SetDefaults() 28 | { 29 | item.width = 16; 30 | item.height = 16; 31 | item.maxStack = 99; 32 | item.rare = ItemRarityID.Blue; 33 | item.value = Item.sellPrice(0, 1); 34 | } 35 | 36 | public override Color? GetAlpha(Color lightColor) => Color.White; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Items/ShadowDiamond.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/ShadowDiamond.png -------------------------------------------------------------------------------- /Items/ShadowDiamondDrop.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.ModLoader; 4 | 5 | namespace MagicStorageExtra.Items 6 | { 7 | public class ShadowDiamondDrop : GlobalNPC 8 | { 9 | public override void NPCLoot(NPC npc) 10 | { 11 | if (MagicStorageExtra.MagicStorage != null) 12 | return; 13 | 14 | switch (npc.type) 15 | { 16 | case NPCID.KingSlime when !StorageWorld.kingSlimeDiamond: 17 | DropDiamond(npc, 1); 18 | StorageWorld.kingSlimeDiamond = true; 19 | break; 20 | case NPCID.EyeofCthulhu when !StorageWorld.boss1Diamond: 21 | DropDiamond(npc, Main.expertMode ? 2 : 1); 22 | StorageWorld.boss1Diamond = true; 23 | break; 24 | case NPCID.EaterofWorldsHead: 25 | case NPCID.EaterofWorldsBody: 26 | case NPCID.EaterofWorldsTail: 27 | case NPCID.BrainofCthulhu: 28 | if (!StorageWorld.boss2Diamond) 29 | { 30 | DropDiamond(npc, 1); 31 | StorageWorld.boss2Diamond = true; 32 | } 33 | 34 | break; 35 | case NPCID.SkeletronHead when !StorageWorld.boss3Diamond: 36 | DropDiamond(npc, 1); 37 | StorageWorld.boss3Diamond = true; 38 | break; 39 | case NPCID.QueenBee when !StorageWorld.queenBeeDiamond: 40 | DropDiamond(npc, 1); 41 | StorageWorld.queenBeeDiamond = true; 42 | break; 43 | case NPCID.WallofFlesh when !StorageWorld.hardmodeDiamond: 44 | DropDiamond(npc, 2); 45 | StorageWorld.hardmodeDiamond = true; 46 | break; 47 | case NPCID.TheDestroyer when !StorageWorld.mechBoss1Diamond: 48 | DropDiamond(npc, 1); 49 | StorageWorld.mechBoss1Diamond = true; 50 | break; 51 | case NPCID.Retinazer: 52 | case NPCID.Spazmatism: 53 | if (!StorageWorld.mechBoss2Diamond) 54 | { 55 | DropDiamond(npc, 1); 56 | StorageWorld.mechBoss2Diamond = true; 57 | } 58 | 59 | break; 60 | case NPCID.SkeletronPrime when !StorageWorld.mechBoss3Diamond: 61 | DropDiamond(npc, 1); 62 | StorageWorld.mechBoss3Diamond = true; 63 | break; 64 | case NPCID.Plantera when !StorageWorld.plantBossDiamond: 65 | DropDiamond(npc, Main.expertMode ? 2 : 1); 66 | StorageWorld.plantBossDiamond = true; 67 | break; 68 | case NPCID.Golem when !StorageWorld.golemBossDiamond: 69 | DropDiamond(npc, 1); 70 | StorageWorld.golemBossDiamond = true; 71 | break; 72 | case NPCID.DukeFishron when !StorageWorld.fishronDiamond: 73 | DropDiamond(npc, 1); 74 | StorageWorld.fishronDiamond = true; 75 | break; 76 | case NPCID.CultistBoss when !StorageWorld.ancientCultistDiamond: 77 | DropDiamond(npc, 1); 78 | StorageWorld.ancientCultistDiamond = true; 79 | break; 80 | case NPCID.MoonLordCore when !StorageWorld.moonlordDiamond: 81 | DropDiamond(npc, Main.expertMode ? 3 : 2); 82 | StorageWorld.moonlordDiamond = true; 83 | break; 84 | } 85 | } 86 | 87 | private void DropDiamond(NPC npc, int stack) 88 | { 89 | Item.NewItem(npc.position, npc.width, npc.height, ModContent.ItemType(), stack); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Items/SnowBiomeEmulator.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.DataStructures; 3 | using Terraria.ID; 4 | using Terraria.Localization; 5 | using Terraria.ModLoader; 6 | 7 | namespace MagicStorageExtra.Items 8 | { 9 | public class SnowBiomeEmulator : StorageItem 10 | { 11 | public override void SetStaticDefaults() 12 | { 13 | DisplayName.SetDefault("Broken Snowglobe"); 14 | DisplayName.AddTranslation(GameCulture.Russian, "Сломанная Снежная Сфера"); 15 | DisplayName.AddTranslation(GameCulture.Polish, "Emulator Śnieżnego Biomu"); 16 | DisplayName.AddTranslation(GameCulture.French, "Emulateur de biome de neige"); 17 | DisplayName.AddTranslation(GameCulture.Spanish, "Emulador de bioma de la nieve"); 18 | DisplayName.AddTranslation(GameCulture.Chinese, "雪地环境模拟器"); 19 | 20 | Tooltip.SetDefault("Allows the Storage Crafting Interface to craft snow biome recipes"); 21 | Tooltip.AddTranslation(GameCulture.Russian, "Позволяет Модулю Создания Предметов создавать предметы требующие нахождения игрока в снежном биоме"); 22 | Tooltip.AddTranslation(GameCulture.Polish, "Dodaje funkcje do Interfejsu Rzemieślniczego, pozwalającą na wytwarzanie przedmiotów dostępnych jedynie w Śnieżnym Biomie"); 23 | Tooltip.AddTranslation(GameCulture.French, "Permet à L'interface de Stockage Artisanat de créer des recettes de biome de neige"); 24 | Tooltip.AddTranslation(GameCulture.Spanish, "Permite la Interfaz de Elaboración de almacenamiento a hacer de recetas de bioma de la nieve"); 25 | Tooltip.AddTranslation(GameCulture.Chinese, "允许制作存储单元拥有雪地环境"); 26 | 27 | Main.RegisterItemAnimation(item.type, new DrawAnimationVertical(8, 8)); 28 | } 29 | 30 | public override void SetDefaults() 31 | { 32 | item.width = 30; 33 | item.height = 30; 34 | item.rare = ItemRarityID.Blue; 35 | } 36 | 37 | public override void AddRecipe(ModItem result) 38 | { 39 | var recipe = new ModRecipe(mod); 40 | recipe.AddRecipeGroup("MagicStorageExtra:AnySnowBiomeBlock", 300); 41 | recipe.AddTile(null, "CraftingAccess"); 42 | recipe.SetResult(result); 43 | recipe.AddRecipe(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Items/SnowBiomeEmulator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/SnowBiomeEmulator.png -------------------------------------------------------------------------------- /Items/StorageAccess.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class StorageAccess : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.AddTranslation(GameCulture.Russian, "Модуль Доступа к Хранилищу"); 13 | DisplayName.AddTranslation(GameCulture.Polish, "Okno dostępu do magazynu"); 14 | DisplayName.AddTranslation(GameCulture.French, "Access de Stockage"); 15 | DisplayName.AddTranslation(GameCulture.Spanish, "Acceso de Almacenamiento"); 16 | DisplayName.AddTranslation(GameCulture.Chinese, "存储装置"); 17 | } 18 | 19 | public override void SetDefaults() 20 | { 21 | item.width = 26; 22 | item.height = 26; 23 | item.maxStack = 99; 24 | item.useTurn = true; 25 | item.autoReuse = true; 26 | item.useAnimation = 15; 27 | item.useTime = 10; 28 | item.useStyle = ItemUseStyleID.SwingThrow; 29 | item.consumable = true; 30 | item.rare = ItemRarityID.Blue; 31 | item.value = Item.sellPrice(0, 0, 67, 50); 32 | item.createTile = ModContent.TileType(); 33 | } 34 | 35 | public override void AddRecipe(ModItem result) 36 | { 37 | var recipe = new ModRecipe(mod); 38 | recipe.AddRecipeGroup("MagicStorageExtra:AnyStorageComponent"); 39 | recipe.AddRecipeGroup("MagicStorageExtra:AnyDiamond", 3); 40 | if (MagicStorageExtra.legendMod is null) 41 | recipe.AddIngredient(ItemID.Topaz, 3); 42 | else 43 | recipe.AddRecipeGroup("MagicStorageExtra:AnyTopaz", 3); 44 | recipe.AddTile(TileID.WorkBenches); 45 | recipe.SetResult(result); 46 | recipe.AddRecipe(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Items/StorageAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/StorageAccess.png -------------------------------------------------------------------------------- /Items/StorageComponent.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class StorageComponent : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.AddTranslation(GameCulture.Russian, "Компонент Хранилища"); 13 | DisplayName.AddTranslation(GameCulture.Polish, "Komponent Magazynu"); 14 | DisplayName.AddTranslation(GameCulture.French, "Composant de Stockage"); 15 | DisplayName.AddTranslation(GameCulture.Spanish, "Componente de Almacenamiento"); 16 | DisplayName.AddTranslation(GameCulture.Chinese, "存储组件"); 17 | } 18 | 19 | public override void SetDefaults() 20 | { 21 | item.width = 26; 22 | item.height = 26; 23 | item.maxStack = 99; 24 | item.useTurn = true; 25 | item.autoReuse = true; 26 | item.useAnimation = 15; 27 | item.useTime = 10; 28 | item.useStyle = ItemUseStyleID.SwingThrow; 29 | item.consumable = true; 30 | item.rare = ItemRarityID.White; 31 | item.value = Item.sellPrice(0, 0, 1); 32 | item.createTile = ModContent.TileType(); 33 | } 34 | 35 | public override void AddRecipe(ModItem result) 36 | { 37 | var recipe = new ModRecipe(mod); 38 | recipe.AddIngredient(ItemID.Wood, 10); 39 | recipe.AddIngredient(ItemID.IronBar, 2); 40 | recipe.anyWood = true; 41 | recipe.anyIronBar = true; 42 | recipe.AddTile(TileID.WorkBenches); 43 | recipe.SetResult(result); 44 | recipe.AddRecipe(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Items/StorageComponent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/StorageComponent.png -------------------------------------------------------------------------------- /Items/StorageConnector.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class StorageConnector : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.AddTranslation(GameCulture.Russian, "Соединитель Ячеек Хранилища"); 13 | DisplayName.AddTranslation(GameCulture.Polish, "Łącznik"); 14 | DisplayName.AddTranslation(GameCulture.French, "Connecteur de Stockage"); 15 | DisplayName.AddTranslation(GameCulture.Spanish, "Conector de Almacenamiento"); 16 | DisplayName.AddTranslation(GameCulture.Chinese, "存储连接器"); 17 | } 18 | 19 | public override void SetDefaults() 20 | { 21 | item.width = 12; 22 | item.height = 12; 23 | item.maxStack = 999; 24 | item.useTurn = true; 25 | item.autoReuse = true; 26 | item.useAnimation = 15; 27 | item.useTime = 10; 28 | item.useStyle = ItemUseStyleID.SwingThrow; 29 | item.consumable = true; 30 | item.rare = ItemRarityID.White; 31 | item.value = Item.sellPrice(0, 0, 0, 10); 32 | item.createTile = ModContent.TileType(); 33 | } 34 | 35 | public override void AddRecipe(ModItem result) 36 | { 37 | var recipe = new ModRecipe(mod); 38 | recipe.AddIngredient(ItemID.Wood, 16); 39 | recipe.AddIngredient(ItemID.IronBar); 40 | recipe.anyWood = true; 41 | recipe.anyIronBar = true; 42 | recipe.AddTile(TileID.WorkBenches); 43 | recipe.SetResult(result, 16); 44 | recipe.AddRecipe(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Items/StorageConnector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/StorageConnector.png -------------------------------------------------------------------------------- /Items/StorageDeactivator.cs: -------------------------------------------------------------------------------- 1 | using MagicStorageExtra.Components; 2 | using Terraria; 3 | using Terraria.DataStructures; 4 | using Terraria.ID; 5 | using Terraria.Localization; 6 | using Terraria.ModLoader; 7 | 8 | namespace MagicStorageExtra.Items 9 | { 10 | public class StorageDeactivator : StorageItem 11 | { 12 | public override void SetStaticDefaults() 13 | { 14 | DisplayName.SetDefault("Storage Unit Wand"); 15 | DisplayName.AddTranslation(GameCulture.Russian, "Жезл Ячейки Хранилища"); 16 | DisplayName.AddTranslation(GameCulture.Polish, "Różdżka jednostki magazynującej"); 17 | DisplayName.AddTranslation(GameCulture.French, "Baguette d'unité de stockage"); 18 | DisplayName.AddTranslation(GameCulture.Spanish, "Varita de unidad de almacenamiento"); 19 | DisplayName.AddTranslation(GameCulture.French, "Baguetter d'unité de stockage"); 20 | DisplayName.AddTranslation(GameCulture.Chinese, "存储单元魔杖"); 21 | 22 | Tooltip.SetDefault(" Storage Unit to toggle between Active/Inactive"); 23 | Tooltip.AddTranslation(GameCulture.Russian, " на Ячейке Хранилища что бы активировать/деактивировать ее"); 24 | Tooltip.AddTranslation(GameCulture.Polish, " aby przełączyć Jednostkę Magazynującą (wł./wył.)"); 25 | Tooltip.AddTranslation(GameCulture.French, " pour changer l'unité de stockage actif/inactif"); 26 | Tooltip.AddTranslation(GameCulture.Spanish, " para cambiar el unidad de almacenamiento activo/inactivo"); 27 | Tooltip.AddTranslation(GameCulture.Chinese, "存储单元使其切换启用/禁用"); 28 | } 29 | 30 | public override void SetDefaults() 31 | { 32 | item.width = 24; 33 | item.height = 28; 34 | item.useTurn = true; 35 | item.autoReuse = true; 36 | item.useAnimation = 15; 37 | item.useTime = 15; 38 | item.useStyle = ItemUseStyleID.SwingThrow; 39 | item.tileBoost = 20; 40 | item.rare = ItemRarityID.Blue; 41 | item.value = Item.sellPrice(0, 0, 40); 42 | } 43 | 44 | public override bool UseItem(Player player) 45 | { 46 | if (player.whoAmI == Main.myPlayer && player.itemAnimation > 0 && player.itemTime == 0 && player.controlUseItem) 47 | { 48 | int i = Player.tileTargetX; 49 | int j = Player.tileTargetY; 50 | if (Main.tile[i, j].frameX % 36 == 18) 51 | i--; 52 | if (Main.tile[i, j].frameY % 36 == 18) 53 | j--; 54 | var point = new Point16(i, j); 55 | if (TileEntity.ByPosition.ContainsKey(point) && TileEntity.ByPosition[point] is TEAbstractStorageUnit storageUnit) 56 | { 57 | storageUnit.Inactive = !storageUnit.Inactive; 58 | string activeText = storageUnit.Inactive ? "Deactivated" : "Activated"; 59 | Main.NewText("Storage Unit has been " + activeText); 60 | NetHelper.ClientSendTEUpdate(storageUnit.ID); 61 | if (storageUnit is TEStorageUnit unit) 62 | { 63 | unit.UpdateTileFrameWithNetSend(); 64 | if (Main.netMode == NetmodeID.SinglePlayer) 65 | unit.GetHeart().ResetCompactStage(); 66 | } 67 | } 68 | } 69 | 70 | return true; 71 | } 72 | 73 | public override void AddRecipe(ModItem result) 74 | { 75 | var recipe = new ModRecipe(mod); 76 | recipe.AddIngredient(ItemID.ActuationRod); 77 | recipe.AddRecipeGroup("MagicStorageExtra:AnyStorageComponent"); 78 | recipe.AddTile(TileID.Anvils); 79 | recipe.SetResult(result); 80 | recipe.AddRecipe(); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Items/StorageDeactivator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/StorageDeactivator.png -------------------------------------------------------------------------------- /Items/StorageHeart.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class StorageHeart : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.AddTranslation(GameCulture.Russian, "Сердце Хранилища"); 13 | DisplayName.AddTranslation(GameCulture.Polish, "Serce Jednostki Magazynującej"); 14 | DisplayName.AddTranslation(GameCulture.French, "Cœur de Stockage"); 15 | DisplayName.AddTranslation(GameCulture.Spanish, "Corazón de Almacenamiento"); 16 | DisplayName.AddTranslation(GameCulture.Chinese, "存储核心"); 17 | } 18 | 19 | public override void SetDefaults() 20 | { 21 | item.width = 26; 22 | item.height = 26; 23 | item.maxStack = 99; 24 | item.useTurn = true; 25 | item.autoReuse = true; 26 | item.useAnimation = 15; 27 | item.useTime = 10; 28 | item.useStyle = ItemUseStyleID.SwingThrow; 29 | item.consumable = true; 30 | item.rare = ItemRarityID.Blue; 31 | item.value = Item.sellPrice(0, 1, 35); 32 | item.createTile = ModContent.TileType(); 33 | } 34 | 35 | public override void AddRecipe(ModItem result) 36 | { 37 | var recipe = new ModRecipe(mod); 38 | recipe.AddRecipeGroup("MagicStorageExtra:AnyStorageComponent"); 39 | recipe.AddRecipeGroup("MagicStorageExtra:AnyDiamond", 2); 40 | if (MagicStorageExtra.legendMod is null) 41 | recipe.AddIngredient(ItemID.Emerald, 3); 42 | else 43 | recipe.AddRecipeGroup("MagicStorageExtra:AnyEmerald", 5); 44 | recipe.AddTile(TileID.WorkBenches); 45 | recipe.SetResult(result); 46 | recipe.AddRecipe(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Items/StorageHeart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/StorageHeart.png -------------------------------------------------------------------------------- /Items/StorageItem.cs: -------------------------------------------------------------------------------- 1 | using Terraria.ModLoader; 2 | 3 | namespace MagicStorageExtra.Items 4 | { 5 | public abstract class StorageItem : ModItem 6 | { 7 | public sealed override void AddRecipes() 8 | { 9 | AddRecipe(this); 10 | if (MagicStorageExtra.MagicStorage != null) 11 | { 12 | ModItem modItem = MagicStorageExtra.MagicStorage.GetItem(Name); 13 | AddRecipe(modItem); 14 | AddReverseRecipes(modItem); 15 | } 16 | } 17 | 18 | public void AddReverseRecipes(ModItem other) 19 | { 20 | ModRecipe recipe = new ModRecipe(mod); 21 | recipe.AddIngredient(this); 22 | recipe.SetResult(other); 23 | recipe.AddRecipe(); 24 | 25 | recipe = new ModRecipe(mod); 26 | recipe.AddIngredient(other); 27 | recipe.SetResult(this); 28 | recipe.AddRecipe(); 29 | } 30 | 31 | public virtual void AddRecipe(ModItem result) 32 | { 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Items/StorageUnit.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class StorageUnit : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.AddTranslation(GameCulture.Russian, "Ячейка Хранилища"); 13 | DisplayName.AddTranslation(GameCulture.Polish, "Jednostka magazynująca"); 14 | DisplayName.AddTranslation(GameCulture.French, "Unité de stockage"); 15 | DisplayName.AddTranslation(GameCulture.Spanish, "Unidad de Almacenamiento"); 16 | DisplayName.AddTranslation(GameCulture.Chinese, "存储单元"); 17 | } 18 | 19 | public override void SetDefaults() 20 | { 21 | item.width = 26; 22 | item.height = 26; 23 | item.maxStack = 99; 24 | item.useTurn = true; 25 | item.autoReuse = true; 26 | item.useAnimation = 15; 27 | item.useTime = 10; 28 | item.useStyle = ItemUseStyleID.SwingThrow; 29 | item.consumable = true; 30 | item.rare = ItemRarityID.White; 31 | item.value = Item.sellPrice(0, 0, 6); 32 | item.createTile = ModContent.TileType(); 33 | } 34 | 35 | public override void AddRecipe(ModItem result) 36 | { 37 | var recipe = new ModRecipe(mod); 38 | recipe.AddRecipeGroup("MagicStorageExtra:AnyStorageComponent"); 39 | recipe.AddRecipeGroup("MagicStorageExtra:AnyChest"); 40 | recipe.AddIngredient(ItemID.SilverBar, 10); 41 | recipe.AddTile(TileID.WorkBenches); 42 | recipe.SetResult(result); 43 | recipe.AddRecipe(); 44 | 45 | recipe = new ModRecipe(mod); 46 | recipe.AddRecipeGroup("MagicStorageExtra:AnyStorageComponent"); 47 | recipe.AddRecipeGroup("MagicStorageExtra:AnyChest"); 48 | recipe.AddIngredient(ItemID.TungstenBar, 10); 49 | recipe.AddTile(TileID.WorkBenches); 50 | recipe.SetResult(result); 51 | recipe.AddRecipe(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Items/StorageUnit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/StorageUnit.png -------------------------------------------------------------------------------- /Items/StorageUnitBlueChlorophyte.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class StorageUnitBlueChlorophyte : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Blue Chlorophyte Storage Unit"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Синяя Хлорофитовая Ячейка Хранилища"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Jednostka magazynująca (Niebieski Chlorofit)"); 15 | DisplayName.AddTranslation(GameCulture.French, "Unité de stockage (Chlorophylle Bleu)"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Unidad de Almacenamiento (Clorofita Azul)"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "存储单元(蓝色叶绿)"); 18 | } 19 | 20 | public override void SetDefaults() 21 | { 22 | item.width = 26; 23 | item.height = 26; 24 | item.maxStack = 99; 25 | item.useTurn = true; 26 | item.autoReuse = true; 27 | item.useAnimation = 15; 28 | item.useTime = 10; 29 | item.useStyle = ItemUseStyleID.SwingThrow; 30 | item.consumable = true; 31 | item.rare = ItemRarityID.Lime; 32 | item.value = Item.sellPrice(0, 1, 60); 33 | item.createTile = ModContent.TileType(); 34 | item.placeStyle = 5; 35 | } 36 | 37 | public override void AddRecipe(ModItem result) 38 | { 39 | var recipe = new ModRecipe(mod); 40 | recipe.AddRecipeGroup("MagicStorageExtra:AnyStorageUnitHallowed"); 41 | recipe.AddRecipeGroup("MagicStorageExtra:AnyUpgradeBlueChlorophyte"); 42 | recipe.SetResult(result); 43 | recipe.AddRecipe(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Items/StorageUnitBlueChlorophyte.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/StorageUnitBlueChlorophyte.png -------------------------------------------------------------------------------- /Items/StorageUnitCrimtane.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class StorageUnitCrimtane : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Crimtane Storage Unit"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Кримтановая Ячейка Хранилища"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Jednostka magazynująca (Karmazynium)"); 15 | DisplayName.AddTranslation(GameCulture.French, "Unité de stockage (Carmitane)"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Unidad de Almacenamiento (Carmesí)"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "存储单元(血腥)"); 18 | } 19 | 20 | public override void SetDefaults() 21 | { 22 | item.width = 26; 23 | item.height = 26; 24 | item.maxStack = 99; 25 | item.useTurn = true; 26 | item.autoReuse = true; 27 | item.useAnimation = 15; 28 | item.useTime = 10; 29 | item.useStyle = ItemUseStyleID.SwingThrow; 30 | item.consumable = true; 31 | item.rare = ItemRarityID.Blue; 32 | item.value = Item.sellPrice(0, 0, 32); 33 | item.createTile = ModContent.TileType(); 34 | item.placeStyle = 2; 35 | } 36 | 37 | public override void AddRecipe(ModItem result) 38 | { 39 | var recipe = new ModRecipe(mod); 40 | recipe.AddRecipeGroup("MagicStorageExtra:AnyStorageUnit"); 41 | recipe.AddRecipeGroup("MagicStorageExtra:AnyUpgradeCrimtane"); 42 | recipe.SetResult(result); 43 | recipe.AddRecipe(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Items/StorageUnitCrimtane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/StorageUnitCrimtane.png -------------------------------------------------------------------------------- /Items/StorageUnitDemonite.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class StorageUnitDemonite : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Demonite Storage Unit"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Демонитовая Ячейка Хранилища"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Jednostka magazynująca (Demonit)"); 15 | DisplayName.AddTranslation(GameCulture.French, "Unité de stockage (Démonite)"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Unidad de Almacenamiento (Endemoniado)"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "存储单元(魔金)"); 18 | } 19 | 20 | public override void SetDefaults() 21 | { 22 | item.width = 26; 23 | item.height = 26; 24 | item.maxStack = 99; 25 | item.useTurn = true; 26 | item.autoReuse = true; 27 | item.useAnimation = 15; 28 | item.useTime = 10; 29 | item.useStyle = ItemUseStyleID.SwingThrow; 30 | item.consumable = true; 31 | item.rare = ItemRarityID.Blue; 32 | item.value = Item.sellPrice(0, 0, 32); 33 | item.createTile = ModContent.TileType(); 34 | item.placeStyle = 1; 35 | } 36 | 37 | public override void AddRecipe(ModItem result) 38 | { 39 | var recipe = new ModRecipe(mod); 40 | recipe.AddRecipeGroup("MagicStorageExtra:AnyStorageUnit"); 41 | recipe.AddRecipeGroup("MagicStorageExtra:AnyUpgradeDemonite"); 42 | recipe.SetResult(result); 43 | recipe.AddRecipe(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Items/StorageUnitDemonite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/StorageUnitDemonite.png -------------------------------------------------------------------------------- /Items/StorageUnitHallowed.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class StorageUnitHallowed : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Hallowed Storage Unit"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Святая Ячейка Хранилища"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Jednostka magazynująca (Święcona)"); 15 | DisplayName.AddTranslation(GameCulture.French, "Unité de stockage (Sacré)"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Unidad de Almacenamiento (Sagrado)"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "存储单元(神圣)"); 18 | } 19 | 20 | public override void SetDefaults() 21 | { 22 | item.width = 26; 23 | item.height = 26; 24 | item.maxStack = 99; 25 | item.useTurn = true; 26 | item.autoReuse = true; 27 | item.useAnimation = 15; 28 | item.useTime = 10; 29 | item.useStyle = ItemUseStyleID.SwingThrow; 30 | item.consumable = true; 31 | item.rare = ItemRarityID.LightRed; 32 | item.value = Item.sellPrice(0, 1); 33 | item.createTile = ModContent.TileType(); 34 | item.placeStyle = 4; 35 | } 36 | 37 | public override void AddRecipe(ModItem result) 38 | { 39 | var recipe = new ModRecipe(mod); 40 | recipe.AddRecipeGroup("MagicStorageExtra:AnyStorageUnitHellstone"); 41 | recipe.AddRecipeGroup("MagicStorageExtra:AnyUpgradeHallowed"); 42 | recipe.SetResult(result); 43 | recipe.AddRecipe(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Items/StorageUnitHallowed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/StorageUnitHallowed.png -------------------------------------------------------------------------------- /Items/StorageUnitHellstone.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class StorageUnitHellstone : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Hellstone Storage Unit"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Адская Ячейка Хранилища"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Jednostka magazynująca (Piekielny kamień)"); 15 | DisplayName.AddTranslation(GameCulture.French, "Unité de stockage (Infernale)"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Unidad de Almacenamiento (Piedra Infernal)"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "存储单元(狱岩)"); 18 | } 19 | 20 | public override void SetDefaults() 21 | { 22 | item.width = 26; 23 | item.height = 26; 24 | item.maxStack = 99; 25 | item.useTurn = true; 26 | item.autoReuse = true; 27 | item.useAnimation = 15; 28 | item.useTime = 10; 29 | item.useStyle = ItemUseStyleID.SwingThrow; 30 | item.consumable = true; 31 | item.rare = ItemRarityID.Green; 32 | item.value = Item.sellPrice(0, 0, 50); 33 | item.createTile = ModContent.TileType(); 34 | item.placeStyle = 3; 35 | } 36 | 37 | public override void AddRecipe(ModItem result) 38 | { 39 | var recipe = new ModRecipe(mod); 40 | recipe.AddRecipeGroup("MagicStorageExtra:AnyStorageUnitDemonite"); 41 | recipe.AddRecipeGroup("MagicStorageExtra:AnyUpgradeHellstone"); 42 | recipe.SetResult(result); 43 | recipe.AddRecipe(); 44 | 45 | recipe = new ModRecipe(mod); 46 | recipe.AddRecipeGroup("MagicStorageExtra:AnyStorageUnitCrimtane"); 47 | recipe.AddRecipeGroup("MagicStorageExtra:AnyUpgradeHellstone"); 48 | recipe.SetResult(result); 49 | recipe.AddRecipe(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Items/StorageUnitHellstone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/StorageUnitHellstone.png -------------------------------------------------------------------------------- /Items/StorageUnitLuminite.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class StorageUnitLuminite : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Luminite Storage Unit"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Люминитовая Ячейка Хранилища"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Jednostka magazynująca (Luminowana)"); 15 | DisplayName.AddTranslation(GameCulture.French, "Unité de stockage (Luminite)"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Unidad de Almacenamiento (Luminita)"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "存储单元(夜明)"); 18 | } 19 | 20 | public override void SetDefaults() 21 | { 22 | item.width = 26; 23 | item.height = 26; 24 | item.maxStack = 99; 25 | item.useTurn = true; 26 | item.autoReuse = true; 27 | item.useAnimation = 15; 28 | item.useTime = 10; 29 | item.useStyle = ItemUseStyleID.SwingThrow; 30 | item.consumable = true; 31 | item.rare = ItemRarityID.Red; 32 | item.value = Item.sellPrice(0, 2, 50); 33 | item.createTile = ModContent.TileType(); 34 | item.placeStyle = 6; 35 | } 36 | 37 | public override void AddRecipe(ModItem result) 38 | { 39 | var recipe = new ModRecipe(mod); 40 | recipe.AddRecipeGroup("MagicStorageExtra:AnyStorageUnitBlueChlorophyte"); 41 | recipe.AddRecipeGroup("MagicStorageExtra:AnyUpgradeLuminite"); 42 | recipe.SetResult(result); 43 | recipe.AddRecipe(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Items/StorageUnitLuminite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/StorageUnitLuminite.png -------------------------------------------------------------------------------- /Items/StorageUnitTerra.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class StorageUnitTerra : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Terra Storage Unit"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Терра Ячейка Хранилища"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Jednostka magazynująca (Terra)"); 15 | DisplayName.AddTranslation(GameCulture.French, "Unité de stockage (Terra)"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Unidad de Almacenamiento (Tierra)"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "存储单元(泰拉)"); 18 | } 19 | 20 | public override void SetDefaults() 21 | { 22 | item.width = 26; 23 | item.height = 26; 24 | item.maxStack = 99; 25 | item.useTurn = true; 26 | item.autoReuse = true; 27 | item.useAnimation = 15; 28 | item.useTime = 10; 29 | item.useStyle = ItemUseStyleID.SwingThrow; 30 | item.consumable = true; 31 | item.rare = ItemRarityID.Purple; 32 | item.value = Item.sellPrice(0, 0, 12); 33 | item.createTile = ModContent.TileType(); 34 | item.placeStyle = 7; 35 | } 36 | 37 | public override void AddRecipe(ModItem result) 38 | { 39 | var recipe = new ModRecipe(mod); 40 | recipe.AddRecipeGroup("MagicStorageExtra:AnyStorageUnitLuminite"); 41 | recipe.AddRecipeGroup("MagicStorageExtra:AnyUpgradeTerra"); 42 | recipe.SetResult(result); 43 | recipe.AddRecipe(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Items/StorageUnitTerra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/StorageUnitTerra.png -------------------------------------------------------------------------------- /Items/StorageUnitTiny.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class StorageUnitTiny : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Tiny Storage Unit"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Малая Ячейка Хранилища"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Mała jednostka magazynująca"); 15 | DisplayName.AddTranslation(GameCulture.French, "Unité de Stockage Miniscule"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Unidad de Almacenamiento Minúsculo"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "存储单元(小)"); 18 | } 19 | 20 | public override void SetDefaults() 21 | { 22 | item.width = 26; 23 | item.height = 26; 24 | item.maxStack = 99; 25 | item.useTurn = true; 26 | item.autoReuse = true; 27 | item.useAnimation = 15; 28 | item.useTime = 10; 29 | item.useStyle = ItemUseStyleID.SwingThrow; 30 | item.consumable = true; 31 | item.rare = ItemRarityID.White; 32 | item.value = Item.sellPrice(0, 0, 6); 33 | item.createTile = ModContent.TileType(); 34 | item.placeStyle = 8; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Items/StorageUnitTiny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/StorageUnitTiny.png -------------------------------------------------------------------------------- /Items/UpgradeBlueChlorophyte.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class UpgradeBlueChlorophyte : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Blue Chlorophyte Storage Upgrade"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Синее Хлорофитовое Улучшение Ячейки"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Ulepszenie jednostki magazynującej (Niebieski Chlorofit)"); 15 | DisplayName.AddTranslation(GameCulture.French, "Amélioration d'Unité de stockage (Chlorophylle Bleu)"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Actualización de Unidad de Almacenamiento (Clorofita Azul)"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "存储升级珠(蓝色叶绿)"); 18 | 19 | Tooltip.SetDefault("Upgrades Storage Unit to 240 capacity" + "\n a Hallowed Storage Unit to use"); 20 | Tooltip.AddTranslation(GameCulture.Russian, "Увеличивает количество слотов в Ячейке Хранилища до 240" + "\n на Святой Ячейке Хранилища для улучшения"); 21 | Tooltip.AddTranslation(GameCulture.Polish, "Ulepsza jednostkę magazynującą do 240 miejsc" + "\n na Jednostkę magazynującą (Święconą), aby użyć"); 22 | Tooltip.AddTranslation(GameCulture.French, "améliore la capacité de unité de stockage à 240" + "\n l'unité de stockage (Sacré) pour utiliser"); 23 | Tooltip.AddTranslation(GameCulture.Spanish, "Capacidad de unidad de almacenamiento mejorada a 240" + "\n en la unidad de almacenamiento (Sagrado) para utilizar"); 24 | Tooltip.AddTranslation(GameCulture.Chinese, "将存储单元升级至240容量" + "\n一个存储单元(神圣)可镶嵌"); 25 | } 26 | 27 | public override void SetDefaults() 28 | { 29 | item.width = 12; 30 | item.height = 12; 31 | item.maxStack = 99; 32 | item.rare = ItemRarityID.Lime; 33 | item.value = Item.sellPrice(0, 1); 34 | } 35 | 36 | public override void AddRecipe(ModItem result) 37 | { 38 | var recipe = new ModRecipe(mod); 39 | recipe.AddIngredient(ItemID.ShroomiteBar, 5); 40 | recipe.AddIngredient(ItemID.SpectreBar, 5); 41 | recipe.AddIngredient(ItemID.BeetleHusk, 2); 42 | if (MagicStorageExtra.legendMod is null) 43 | recipe.AddIngredient(ItemID.Emerald); 44 | else 45 | recipe.AddRecipeGroup("MagicStorageExtra:AnyEmerald"); 46 | recipe.AddTile(TileID.MythrilAnvil); 47 | recipe.SetResult(result); 48 | recipe.AddRecipe(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Items/UpgradeBlueChlorophyte.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/UpgradeBlueChlorophyte.png -------------------------------------------------------------------------------- /Items/UpgradeCrimtane.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class UpgradeCrimtane : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Crimtane Storage Upgrade"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Кримтановое Улучшение Ячейки Хранилища"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Ulepszenie jednostki magazynującej (Karmazynit)"); 15 | DisplayName.AddTranslation(GameCulture.French, "Amélioration d'Unité de stockage (Carmitane)"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Actualización de Unidad de Almacenamiento (Carmesí)"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "存储升级珠(血腥))"); 18 | 19 | Tooltip.SetDefault("Upgrades Storage Unit to 80 capacity" + "\n a Storage Unit to use"); 20 | Tooltip.AddTranslation(GameCulture.Russian, "Увеличивает количество слотов в Ячейке Хранилища до 80" + "\n на Ячейке Хранилища для улучшения"); 21 | Tooltip.AddTranslation(GameCulture.Polish, "Ulepsza jednostkę magazynującą do 80 miejsc" + "\n na Jednostkę magazynującą (Standardową), aby użyć"); 22 | Tooltip.AddTranslation(GameCulture.French, "améliore la capacité de unité de stockage à 80" + "\n l'unité de stockage pour utiliser"); 23 | Tooltip.AddTranslation(GameCulture.Spanish, "Capacidad de unidad de almacenamiento mejorada a 80" + "\n en la unidad de almacenamiento para utilizar"); 24 | Tooltip.AddTranslation(GameCulture.Chinese, "将存储单元升级至80容量" + "\n一个存储单元(血腥)可镶嵌"); 25 | } 26 | 27 | public override void SetDefaults() 28 | { 29 | item.width = 12; 30 | item.height = 12; 31 | item.maxStack = 99; 32 | item.rare = ItemRarityID.Blue; 33 | item.value = Item.sellPrice(0, 0, 32); 34 | } 35 | 36 | public override void AddRecipe(ModItem result) 37 | { 38 | var recipe = new ModRecipe(mod); 39 | recipe.AddIngredient(ItemID.CrimtaneBar, 10); 40 | if (MagicStorageExtra.legendMod is null) 41 | recipe.AddIngredient(ItemID.Amethyst); 42 | else 43 | recipe.AddRecipeGroup("MagicStorageExtra:AnyAmethyst"); 44 | recipe.AddTile(TileID.Anvils); 45 | recipe.SetResult(result); 46 | recipe.AddRecipe(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Items/UpgradeCrimtane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/UpgradeCrimtane.png -------------------------------------------------------------------------------- /Items/UpgradeDemonite.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class UpgradeDemonite : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Demonite Storage Upgrade"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Демонитовое Улучшение Ячейки Хранилища"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Ulepszenie jednostki magazynującej (Demonit)"); 15 | DisplayName.AddTranslation(GameCulture.French, "Amélioration d'Unité de stockage (Démonite)"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Actualización de Unidad de Almacenamiento (Endemoniado)"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "存储升级珠(魔金)"); 18 | 19 | Tooltip.SetDefault("Upgrades Storage Unit to 80 capacity" + "\n a Storage Unit to use"); 20 | Tooltip.AddTranslation(GameCulture.Russian, "Увеличивает количество слотов в Ячейке Хранилища до 80" + "\n на Ячейке Хранилища для улучшения"); 21 | Tooltip.AddTranslation(GameCulture.Polish, "Ulepsza jednostkę magazynującą do 80 miejsc" + "\n na Jednostkę magazynującą (Standardową), aby użyć"); 22 | Tooltip.AddTranslation(GameCulture.French, "améliore la capacité de unité de stockage à 80" + "\n l'unité de stockage pour utiliser"); 23 | Tooltip.AddTranslation(GameCulture.Spanish, "Capacidad de unidad de almacenamiento mejorada a 80" + "\n en la unidad de almacenamiento para utilizar"); 24 | Tooltip.AddTranslation(GameCulture.Chinese, "将存储单元升级至80容量" + "\n一个存储单元(魔金)可镶嵌"); 25 | } 26 | 27 | public override void SetDefaults() 28 | { 29 | item.width = 12; 30 | item.height = 12; 31 | item.maxStack = 99; 32 | item.rare = ItemRarityID.Blue; 33 | item.value = Item.sellPrice(0, 0, 32); 34 | } 35 | 36 | public override void AddRecipe(ModItem result) 37 | { 38 | var recipe = new ModRecipe(mod); 39 | recipe.AddIngredient(ItemID.DemoniteBar, 10); 40 | if (MagicStorageExtra.legendMod is null) 41 | recipe.AddIngredient(ItemID.Amethyst); 42 | else 43 | recipe.AddRecipeGroup("MagicStorageExtra:AnyAmethyst"); 44 | recipe.AddTile(TileID.Anvils); 45 | recipe.SetResult(result); 46 | recipe.AddRecipe(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Items/UpgradeDemonite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/UpgradeDemonite.png -------------------------------------------------------------------------------- /Items/UpgradeHallowed.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class UpgradeHallowed : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Hallowed Storage Upgrade"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Святое Улучшение Ячейки Хранилища"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Ulepszenie jednostki magazynującej (Święcone)"); 15 | DisplayName.AddTranslation(GameCulture.French, "Amélioration d'Unité de stockage (Sacré)"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Actualización de Unidad de Almacenamiento (Sagrado)"); 17 | 18 | Tooltip.SetDefault("Upgrades Storage Unit to 160 capacity" + "\n a Hellstone Storage Unit to use"); 19 | Tooltip.AddTranslation(GameCulture.Russian, "Увеличивает количество слотов в Ячейке Хранилища до 160" + "\n на Адской Ячейке Хранилища для улучшения"); 20 | Tooltip.AddTranslation(GameCulture.Polish, "Ulepsza jednostkę magazynującą do 160 miejsc" + "\n na Jednostkę magazynującą (Piekielny kamień), aby użyć"); 21 | Tooltip.AddTranslation(GameCulture.French, "améliore la capacité de unité de stockage à 160" + "\n l'unité de stockage (Infernale) pour utiliser"); 22 | Tooltip.AddTranslation(GameCulture.Spanish, "Capacidad de unidad de almacenamiento mejorada a 160" + "\n en la unidad de almacenamiento (Piedra Infernal) para utilizar"); 23 | Tooltip.AddTranslation(GameCulture.Chinese, "将存储单元升级至160容量" + "\n一个存储单元(神圣)可镶嵌"); 24 | } 25 | 26 | public override void SetDefaults() 27 | { 28 | item.width = 12; 29 | item.height = 12; 30 | item.maxStack = 99; 31 | item.rare = ItemRarityID.LightRed; 32 | item.value = Item.sellPrice(0, 0, 40); 33 | } 34 | 35 | public override void AddRecipe(ModItem result) 36 | { 37 | var recipe = new ModRecipe(mod); 38 | recipe.AddIngredient(ItemID.HallowedBar, 10); 39 | recipe.AddIngredient(ItemID.SoulofFright); 40 | recipe.AddIngredient(ItemID.SoulofMight); 41 | recipe.AddIngredient(ItemID.SoulofSight); 42 | if (MagicStorageExtra.legendMod is null) 43 | recipe.AddIngredient(ItemID.Sapphire); 44 | else 45 | recipe.AddRecipeGroup("MagicStorageExtra:AnySapphire"); 46 | recipe.AddTile(TileID.MythrilAnvil); 47 | recipe.SetResult(result); 48 | recipe.AddRecipe(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Items/UpgradeHallowed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/UpgradeHallowed.png -------------------------------------------------------------------------------- /Items/UpgradeHellstone.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class UpgradeHellstone : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Hellstone Storage Upgrade"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Адское Улучшение Ячейки Хранилища"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Ulepszenie jednostki magazynującej (Piekielny kamień)"); 15 | DisplayName.AddTranslation(GameCulture.French, "Amélioration d'Unité de stockage (Infernale)"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Actualización de Unidad de Almacenamiento (Piedra Infernal)"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "存储升级珠(狱岩)"); 18 | 19 | Tooltip.SetDefault("Upgrades Storage Unit to 120 capacity" + "\n a Demonite/Crimtane Storage Unit to use"); 20 | Tooltip.AddTranslation(GameCulture.Russian, "Увеличивает количество слотов в Ячейке Хранилища до 120" + "\n на Демонитовой/Кримтановой Ячейке Хранилища для улучшения"); 21 | Tooltip.AddTranslation(GameCulture.Polish, "Ulepsza jednostkę magazynującą do 120 miejsc" + "\n na Jednostkę magazynującą (Karmazynit/Demonit), aby użyć"); 22 | Tooltip.AddTranslation(GameCulture.French, "améliore la capacité de unité de stockage à 120" + "\n l'unité de stockage (Démonite/Carmitane) pour utiliser"); 23 | Tooltip.AddTranslation(GameCulture.Spanish, "Capacidad de unidad de almacenamiento mejorada a 120" + "\n en la unidad de almacenamiento (Endemoniado/Carmesí) para utilizar"); 24 | Tooltip.AddTranslation(GameCulture.Chinese, "将存储单元升级至120容量" + "\n一个存储单元(血腥/魔金)可镶嵌"); 25 | } 26 | 27 | public override void SetDefaults() 28 | { 29 | item.width = 12; 30 | item.height = 12; 31 | item.maxStack = 99; 32 | item.rare = ItemRarityID.Green; 33 | item.value = Item.sellPrice(0, 0, 40); 34 | } 35 | 36 | public override void AddRecipe(ModItem result) 37 | { 38 | var recipe = new ModRecipe(mod); 39 | recipe.AddIngredient(ItemID.HellstoneBar, 10); 40 | if (MagicStorageExtra.legendMod is null) 41 | recipe.AddIngredient(ItemID.Topaz); 42 | else 43 | recipe.AddRecipeGroup("MagicStorageExtra:AnyTopaz"); 44 | recipe.AddTile(TileID.Anvils); 45 | recipe.SetResult(result); 46 | recipe.AddRecipe(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Items/UpgradeHellstone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/UpgradeHellstone.png -------------------------------------------------------------------------------- /Items/UpgradeLuminite.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class UpgradeLuminite : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Luminite Storage Upgrade"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Люминитовое Улучшение Ячейки Хранилища"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Ulepszenie jednostki magazynującej (Luminowany)"); 15 | DisplayName.AddTranslation(GameCulture.French, "Amélioration d'Unité de stockage (Luminite)"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Actualización de Unidad de Almacenamiento (Luminita)"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "存储升级珠(夜明)"); 18 | 19 | Tooltip.SetDefault("Upgrades Storage Unit to 320 capacity" + "\n a Blue Chlorophyte Storage Unit to use"); 20 | Tooltip.AddTranslation(GameCulture.Russian, "Увеличивает количество слотов в Ячейке Хранилища до 320" + "\n на Синей Хлорофитовой Ячейке Хранилища для улучшения"); 21 | Tooltip.AddTranslation(GameCulture.Polish, "Ulepsza jednostkę magazynującą do 320 miejsc" + "\n na Jednostkę magazynującą (Niebieski Chlorofit), aby użyć"); 22 | Tooltip.AddTranslation(GameCulture.French, "améliore la capacité de unité de stockage à 320" + "\n l'unité de stockage (Chlorophylle Bleu) pour utiliser"); 23 | Tooltip.AddTranslation(GameCulture.Spanish, "Capacidad de unidad de almacenamiento mejorada a 320" + "\n en la unidad de almacenamiento (Clorofita Azul) para utilizar"); 24 | Tooltip.AddTranslation(GameCulture.Chinese, "将存储单元升级至320容量" + "\n一个存储单元(夜明)可镶嵌"); 25 | } 26 | 27 | public override void SetDefaults() 28 | { 29 | item.width = 12; 30 | item.height = 12; 31 | item.maxStack = 99; 32 | item.rare = ItemRarityID.Red; 33 | item.value = Item.sellPrice(0, 1, 50); 34 | } 35 | 36 | public override void AddRecipe(ModItem result) 37 | { 38 | var recipe = new ModRecipe(mod); 39 | recipe.AddIngredient(ItemID.LunarBar, 10); 40 | recipe.AddIngredient(ItemID.FragmentSolar, 5); 41 | recipe.AddIngredient(ItemID.FragmentVortex, 5); 42 | recipe.AddIngredient(ItemID.FragmentNebula, 5); 43 | recipe.AddIngredient(ItemID.FragmentStardust, 5); 44 | if (MagicStorageExtra.legendMod is null) 45 | recipe.AddIngredient(ItemID.Ruby); 46 | else 47 | recipe.AddRecipeGroup("MagicStorageExtra:AnyRuby"); 48 | recipe.AddTile(TileID.LunarCraftingStation); 49 | recipe.SetResult(result); 50 | recipe.AddRecipe(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Items/UpgradeLuminite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/UpgradeLuminite.png -------------------------------------------------------------------------------- /Items/UpgradeTerra.cs: -------------------------------------------------------------------------------- 1 | using Terraria; 2 | using Terraria.ID; 3 | using Terraria.Localization; 4 | using Terraria.ModLoader; 5 | 6 | namespace MagicStorageExtra.Items 7 | { 8 | public class UpgradeTerra : StorageItem 9 | { 10 | public override void SetStaticDefaults() 11 | { 12 | DisplayName.SetDefault("Terra Storage Upgrade"); 13 | DisplayName.AddTranslation(GameCulture.Russian, "Терра Улучшение Ячейки Хранилища"); 14 | DisplayName.AddTranslation(GameCulture.Polish, "Ulepszenie jednostki magazynującej (Terra)"); 15 | DisplayName.AddTranslation(GameCulture.French, "Amélioration d'Unité de stockage (Terra)"); 16 | DisplayName.AddTranslation(GameCulture.Spanish, "Actualización de Unidad de Almacenamiento (Tierra)"); 17 | DisplayName.AddTranslation(GameCulture.Chinese, "存储升级珠(泰拉)"); 18 | 19 | Tooltip.SetDefault("Upgrades Storage Unit to 640 capacity" + "\n a Luminite Storage Unit to use"); 20 | Tooltip.AddTranslation(GameCulture.Russian, "Увеличивает количество слотов в Ячейке Хранилища до 640" + "\n на Люминитовой Ячейке Хранилища для улучшения"); 21 | Tooltip.AddTranslation(GameCulture.Polish, "Ulepsza jednostkę magazynującą do 640 miejsc" + "\n na Jednostkę magazynującą (Luminowaną), aby użyć"); 22 | Tooltip.AddTranslation(GameCulture.French, "améliore la capacité de unité de stockage à 640" + "\n l'unité de stockage (Luminite) pour utiliser"); 23 | Tooltip.AddTranslation(GameCulture.Spanish, "Capacidad de unidad de almacenamiento mejorada a 640" + "\n en la unidad de almacenamiento (Luminita) para utilizar"); 24 | Tooltip.AddTranslation(GameCulture.Chinese, "将存储单元升级至640容量" + "\n一个存储单元(泰拉)可镶嵌"); 25 | } 26 | 27 | public override void SetDefaults() 28 | { 29 | item.width = 12; 30 | item.height = 12; 31 | item.maxStack = 99; 32 | item.rare = ItemRarityID.Purple; 33 | item.value = Item.sellPrice(0, 10); 34 | } 35 | 36 | public override void AddRecipe(ModItem result) 37 | { 38 | var recipe = new ModRecipe(mod); 39 | recipe.AddIngredient(null, "RadiantJewel"); 40 | recipe.AddRecipeGroup("MagicStorageExtra:AnyDiamond"); 41 | recipe.AddTile(TileID.LunarCraftingStation); 42 | recipe.SetResult(result); 43 | recipe.AddRecipe(); 44 | 45 | Mod otherMod = MagicStorageExtra.bluemagicMod; 46 | if (otherMod != null) 47 | { 48 | recipe = new ModRecipe(mod); 49 | recipe.AddIngredient(otherMod, "InfinityCrystal"); 50 | recipe.AddRecipeGroup("MagicStorageExtra:AnyDiamond"); 51 | recipe.AddTile(otherMod, "PuriumAnvil"); 52 | recipe.SetResult(result); 53 | recipe.AddRecipe(); 54 | } 55 | 56 | otherMod = ModLoader.GetMod("CalamityMod"); 57 | if (otherMod != null) 58 | { 59 | recipe = new ModRecipe(mod); 60 | recipe.AddIngredient(otherMod, "CosmiliteBar", 20); 61 | recipe.AddRecipeGroup("MagicStorageExtra:AnyDiamond"); 62 | recipe.AddTile(TileID.LunarCraftingStation); 63 | recipe.SetResult(result); 64 | recipe.AddRecipe(); 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Items/UpgradeTerra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/Items/UpgradeTerra.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Kaylee Minsuh Kim 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /MagicStorageConfig.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using Newtonsoft.Json; 3 | using Terraria.ModLoader; 4 | using Terraria.ModLoader.Config; 5 | 6 | // ReSharper disable MemberCanBePrivate.Global 7 | // ReSharper disable UnassignedField.Global 8 | 9 | namespace MagicStorageExtra 10 | { 11 | public class MagicStorageConfig : ModConfig 12 | { 13 | [Label("Display new items/recipes")] 14 | [Tooltip("Toggles whether new items in the storage will glow to indicate they're new")] 15 | [DefaultValue(true)] 16 | public bool glowNewItems; 17 | 18 | [Label("Use default filter")] 19 | [Tooltip("Enable to use the filter below, disable to remember last filter selected in game(filter is still used on first open after mod load)")] 20 | [DefaultValue(true)] 21 | public bool useConfigFilter; 22 | 23 | [Label("Default recipe filter")] 24 | [Tooltip("Enable to default to all recipes, disable to default to available recipes")] 25 | [DefaultValue(true)] 26 | public bool showAllRecipes; 27 | 28 | [Label("Quick stack deposit mode")] 29 | [Tooltip("Enable to quick stack with control(ctrl) pressed, disable to quick stack with control(ctrl) released")] 30 | [DefaultValue(false)] 31 | public bool quickStackDepositMode; 32 | 33 | [Label("Clear search text")] 34 | [Tooltip("Enable to clear the search text when opening the UI")] 35 | [DefaultValue(false)] 36 | public bool clearSearchText; 37 | 38 | [Label("Show estimated item dps")] 39 | [Tooltip("Enable to show the estimated dps of the item as a tooltip")] 40 | [DefaultValue(true)] 41 | public bool showItemDps; 42 | 43 | public static MagicStorageConfig Instance => ModContent.GetInstance(); 44 | 45 | [JsonIgnore] public static bool GlowNewItems => Instance.glowNewItems; 46 | 47 | [JsonIgnore] public static bool UseConfigFilter => Instance.useConfigFilter; 48 | 49 | [JsonIgnore] public static bool ShowAllRecipes => Instance.showAllRecipes; 50 | 51 | [JsonIgnore] public static bool QuickStackDepositMode => Instance.quickStackDepositMode; 52 | 53 | [JsonIgnore] public static bool ClearSearchText => Instance.clearSearchText; 54 | 55 | [JsonIgnore] public static bool ShowItemDps => Instance.showItemDps; 56 | 57 | public override ConfigScope Mode => ConfigScope.ClientSide; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /MagicStorageExtra.RecipeGroups.cs: -------------------------------------------------------------------------------- 1 | using MagicStorageExtra.Items; 2 | using Terraria; 3 | using Terraria.ID; 4 | using Terraria.Localization; 5 | using Terraria.ModLoader; 6 | 7 | namespace MagicStorageExtra 8 | { 9 | public partial class MagicStorageExtra 10 | { 11 | public override void AddRecipeGroups() 12 | { 13 | RecipeGroup group = new RecipeGroup(() => Language.GetText("LegacyMisc.37") + " Chest", ItemID.Chest, ItemID.GoldChest, ItemID.ShadowChest, 14 | ItemID.EbonwoodChest, ItemID.RichMahoganyChest, ItemID.PearlwoodChest, ItemID.IvyChest, ItemID.IceChest, ItemID.LivingWoodChest, 15 | ItemID.SkywareChest, ItemID.ShadewoodChest, ItemID.WebCoveredChest, ItemID.LihzahrdChest, ItemID.WaterChest, ItemID.JungleChest, 16 | ItemID.CorruptionChest, ItemID.CrimsonChest, ItemID.HallowedChest, ItemID.FrozenChest, ItemID.DynastyChest, ItemID.HoneyChest, 17 | ItemID.SteampunkChest, ItemID.PalmWoodChest, ItemID.MushroomChest, ItemID.BorealWoodChest, ItemID.SlimeChest, ItemID.GreenDungeonChest, 18 | ItemID.PinkDungeonChest, ItemID.BlueDungeonChest, ItemID.BoneChest, ItemID.CactusChest, ItemID.FleshChest, ItemID.ObsidianChest, 19 | ItemID.PumpkinChest, ItemID.SpookyChest, ItemID.GlassChest, ItemID.MartianChest, ItemID.GraniteChest, ItemID.MeteoriteChest, 20 | ItemID.MarbleChest); 21 | RecipeGroup.RegisterGroup("MagicStorageExtra:AnyChest", group); 22 | 23 | group = new RecipeGroup(() => Language.GetText("LegacyMisc.37").Value + " " + Language.GetTextValue("Mods.MagicStorageExtra.SnowBiomeBlock"), 24 | ItemID.SnowBlock, ItemID.IceBlock, ItemID.PurpleIceBlock, ItemID.PinkIceBlock); 25 | if (bluemagicMod != null) 26 | group.ValidItems.Add(bluemagicMod.ItemType("DarkBlueIce")); 27 | RecipeGroup.RegisterGroup("MagicStorageExtra:AnySnowBiomeBlock", group); 28 | 29 | group = new RecipeGroup(() => Language.GetText("LegacyMisc.37").Value + " " + Lang.GetItemNameValue(ItemID.Diamond), ItemID.Diamond, 30 | ItemType("ShadowDiamond")); 31 | if (legendMod != null) 32 | { 33 | group.ValidItems.Add(legendMod.ItemType("GemChrysoberyl")); 34 | group.ValidItems.Add(legendMod.ItemType("GemAlexandrite")); 35 | } 36 | 37 | RecipeGroup.RegisterGroup("MagicStorageExtra:AnyDiamond", group); 38 | if (legendMod != null) 39 | { 40 | group = new RecipeGroup(() => Language.GetText("LegacyMisc.37").Value + " " + Lang.GetItemNameValue(ItemID.Amethyst), ItemID.Amethyst, 41 | legendMod.ItemType("GemOnyx"), legendMod.ItemType("GemSpinel")); 42 | RecipeGroup.RegisterGroup("MagicStorageExtra:AnyAmethyst", group); 43 | 44 | group = new RecipeGroup(() => Language.GetText("LegacyMisc.37").Value + " " + Lang.GetItemNameValue(ItemID.Topaz), ItemID.Topaz, 45 | legendMod.ItemType("GemGarnet")); 46 | RecipeGroup.RegisterGroup("MagicStorageExtra:AnyTopaz", group); 47 | 48 | group = new RecipeGroup(() => Language.GetText("LegacyMisc.37").Value + " " + Lang.GetItemNameValue(ItemID.Sapphire), ItemID.Sapphire, 49 | legendMod.ItemType("GemCharoite")); 50 | RecipeGroup.RegisterGroup("MagicStorageExtra:AnySapphire", group); 51 | 52 | group = new RecipeGroup(() => Language.GetText("LegacyMisc.37").Value + " " + Lang.GetItemNameValue(ItemID.Emerald), 53 | legendMod.ItemType("GemPeridot")); 54 | RecipeGroup.RegisterGroup("MagicStorageExtra:AnyEmerald", group); 55 | 56 | group = new RecipeGroup(() => Language.GetText("LegacyMisc.37").Value + " " + Lang.GetItemNameValue(ItemID.Ruby), ItemID.Ruby, 57 | legendMod.ItemType("GemOpal")); 58 | RecipeGroup.RegisterGroup("MagicStorageExtra:AnyRuby", group); 59 | } 60 | 61 | AddCompatibilityRecipeGroups(); 62 | } 63 | 64 | private static void AddCompatibilityRecipeGroups() 65 | { 66 | AddCompatibilityRecipeGroup(); 67 | AddCompatibilityRecipeGroup(); 68 | AddCompatibilityRecipeGroup(); 69 | 70 | AddCompatibilityRecipeGroup(); 71 | AddCompatibilityRecipeGroup(); 72 | 73 | AddCompatibilityRecipeGroup(); 74 | AddCompatibilityRecipeGroup(); 75 | AddCompatibilityRecipeGroup(); 76 | AddCompatibilityRecipeGroup(); 77 | AddCompatibilityRecipeGroup(); 78 | AddCompatibilityRecipeGroup(); 79 | AddCompatibilityRecipeGroup(); 80 | 81 | AddCompatibilityRecipeGroup(); 82 | AddCompatibilityRecipeGroup(); 83 | AddCompatibilityRecipeGroup(); 84 | AddCompatibilityRecipeGroup(); 85 | AddCompatibilityRecipeGroup(); 86 | AddCompatibilityRecipeGroup(); 87 | AddCompatibilityRecipeGroup(); 88 | } 89 | 90 | private static void AddCompatibilityRecipeGroup() where TModItem : ModItem 91 | { 92 | ModItem item = ModContent.GetInstance(); 93 | RecipeGroup group = new RecipeGroup(() => item.DisplayName.GetTranslation(Language.ActiveCulture), item.item.type); 94 | 95 | if (MagicStorage != null) 96 | group.ValidItems.Add(MagicStorage.ItemType(item.Name)); 97 | 98 | RecipeGroup.RegisterGroup($"MagicStorageExtra:Any{item.Name}", group); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /MagicStorageExtra.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Reflection; 6 | using MagicStorageExtra.Edits; 7 | using Terraria; 8 | using Terraria.ID; 9 | using Terraria.ModLoader; 10 | using Terraria.UI; 11 | 12 | namespace MagicStorageExtra 13 | { 14 | public partial class MagicStorageExtra : Mod 15 | { 16 | public static MagicStorageExtra Instance; 17 | public static Mod bluemagicMod; 18 | public static Mod legendMod; 19 | public static Mod MagicStorage; 20 | public static Mod ItemChecklist; 21 | 22 | public static string GithubUserName => "ExterminatorX99"; 23 | public static string GithubProjectName => "MagicStorageExtra"; 24 | 25 | public static ModHotKey IsItemKnownHotKey { get; private set; } 26 | 27 | public Mod[] AllMods { get; private set; } 28 | 29 | public override void Load() 30 | { 31 | //if (ModLoader.GetMod("MagicStorage") != null) 32 | // throw new Exception("\"Magic Storage - Extra\" and \"Magic Storage\" are not compatible"); 33 | Instance = this; 34 | InterfaceHelper.Initialize(); 35 | legendMod = ModLoader.GetMod("LegendOfTerraria3"); 36 | bluemagicMod = ModLoader.GetMod("Bluemagic"); 37 | MagicStorage = ModLoader.GetMod("MagicStorage"); 38 | ItemChecklist = ModLoader.GetMod("ItemChecklist"); 39 | AddTranslations(); 40 | AddGlobalItem("MagicStorageExtraItemSaveLoadHook", new ItemSaveLoadHook()); 41 | IsItemKnownHotKey = RegisterHotKey("Is This Item Known?", ""); 42 | RecursiveCraftIntegration.Load(); 43 | EditsLoader.Load(); 44 | } 45 | 46 | public override void PostAddRecipes() 47 | { 48 | RecursiveCraftIntegration.InitRecipes(); 49 | } 50 | 51 | public override void Unload() 52 | { 53 | Instance = null; 54 | bluemagicMod = null; 55 | legendMod = null; 56 | MagicStorage = null; 57 | IsItemKnownHotKey = null; 58 | StorageGUI.Unload(); 59 | CraftingGUI.Unload(); 60 | RecursiveCraftIntegration.Unload(); 61 | EditsLoader.Unload(); 62 | } 63 | 64 | public override void PostSetupContent() 65 | { 66 | Type type = Assembly.GetAssembly(typeof(Mod)).GetType("Terraria.ModLoader.Mod"); 67 | FieldInfo loadModsField = type.GetField("items", BindingFlags.Instance | BindingFlags.NonPublic); 68 | 69 | AllMods = ModLoader.Mods.Where(x => !x.Name.EndsWith("Library", StringComparison.OrdinalIgnoreCase)) 70 | .Where(x => x.Name != "ModLoader") 71 | .Where(x => ((IDictionary)loadModsField.GetValue(x)).Count > 0) 72 | .ToArray(); 73 | } 74 | 75 | public override void HandlePacket(BinaryReader reader, int whoAmI) 76 | { 77 | NetHelper.HandlePacket(reader, whoAmI); 78 | } 79 | 80 | public override bool HijackGetData(ref byte messageType, ref BinaryReader reader, int playerNumber) 81 | { 82 | EditsLoader.MessageTileEntitySyncing = messageType == MessageID.TileSection; 83 | 84 | return false; 85 | } 86 | 87 | public override void ModifyInterfaceLayers(List layers) 88 | { 89 | InterfaceHelper.ModifyInterfaceLayers(layers); 90 | } 91 | 92 | public override void PostUpdateInput() 93 | { 94 | if (!Main.instance.IsActive) 95 | return; 96 | StorageGUI.Update(null); 97 | CraftingGUI.Update(null); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /MagicStorageExtra.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | MagicStorageExtra 6 | net45 7 | x86 8 | 7.3 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | lib\RecursiveCraft_v1.6.1.dll 19 | 20 | 21 | -------------------------------------------------------------------------------- /MagicStorageExtra.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30523.141 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MagicStorageExtra", "MagicStorageExtra.csproj", "{389B7639-2D67-407E-8203-1EB6E59FD03C}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {389B7639-2D67-407E-8203-1EB6E59FD03C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {389B7639-2D67-407E-8203-1EB6E59FD03C}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {389B7639-2D67-407E-8203-1EB6E59FD03C}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {389B7639-2D67-407E-8203-1EB6E59FD03C}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {31DA8F5B-F094-43AB-A2B8-1C82BC49884F} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ModSearchBox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework; 3 | using Microsoft.Xna.Framework.Input; 4 | using Terraria.GameContent.UI.Elements; 5 | using Terraria.ModLoader; 6 | 7 | namespace MagicStorageExtra 8 | { 9 | public class ModSearchBox 10 | { 11 | public const int ModIndexBaseGame = -1; 12 | public const int ModIndexAll = -2; 13 | private UITextPanel _modButton; 14 | public Action OnChanged; 15 | 16 | public ModSearchBox(Action onChanged) 17 | { 18 | OnChanged = onChanged; 19 | } 20 | 21 | public int ModIndex { get; private set; } = ModIndexAll; 22 | 23 | public string ModName { get; private set; } 24 | 25 | public UIPanel Button => _modButton; 26 | 27 | public void InitLangStuff() 28 | { 29 | if (_modButton == null) 30 | _modButton = new UITextPanel(MakeModButtonText(), 0.8f); 31 | } 32 | 33 | private void SetSearchMod(int index, bool silent) 34 | { 35 | if (ModIndex == index) 36 | return; 37 | ModIndex = index; 38 | _modButton?.SetText(MakeModButtonText()); 39 | ModName = ""; 40 | if (index > -1) 41 | ModName = MagicStorageExtra.Instance.AllMods[index].Name; 42 | if (!silent) 43 | OnChanged?.Invoke(); 44 | } 45 | 46 | public void Reset(bool silent) 47 | { 48 | SetSearchMod(ModIndexAll, silent); 49 | } 50 | 51 | private string MakeModButtonText() 52 | { 53 | switch (ModIndex) 54 | { 55 | case ModIndexAll: 56 | return "All mods"; 57 | case ModIndexBaseGame: 58 | return "Terraria"; 59 | default: 60 | return MagicStorageExtra.Instance.AllMods[ModIndex].Name; 61 | } 62 | } 63 | 64 | public void Update(MouseState curMouse, MouseState oldMouse) 65 | { 66 | Rectangle dim = InterfaceHelper.GetFullRectangle(_modButton); 67 | if (curMouse.X > dim.X && curMouse.X < dim.X + dim.Width && curMouse.Y > dim.Y && curMouse.Y < dim.Y + dim.Height) 68 | { 69 | _modButton.BackgroundColor = new Color(73, 94, 171); 70 | Mod[] allMods = MagicStorageExtra.Instance.AllMods; 71 | int index = ModIndex; 72 | if (curMouse.LeftButton == ButtonState.Pressed && oldMouse.LeftButton == ButtonState.Released) 73 | { 74 | index++; 75 | if (index >= allMods.Length) 76 | index = ModIndexAll; 77 | } 78 | else if (curMouse.RightButton == ButtonState.Pressed && oldMouse.RightButton == ButtonState.Released) 79 | { 80 | index--; 81 | if (index < -2) 82 | index = allMods.Length - 1; 83 | } 84 | 85 | SetSearchMod(index, false); 86 | } 87 | else 88 | { 89 | _modButton.BackgroundColor = new Color(63, 82, 151) * 0.7f; 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /OldArt/Components/CraftingAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Components/CraftingAccess.png -------------------------------------------------------------------------------- /OldArt/Components/CraftingAccess_Glow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Components/CraftingAccess_Glow.png -------------------------------------------------------------------------------- /OldArt/Components/CreativeStorageUnit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Components/CreativeStorageUnit.png -------------------------------------------------------------------------------- /OldArt/Components/RemoteAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Components/RemoteAccess.png -------------------------------------------------------------------------------- /OldArt/Components/RemoteAccess_Glow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Components/RemoteAccess_Glow.png -------------------------------------------------------------------------------- /OldArt/Components/StorageAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Components/StorageAccess.png -------------------------------------------------------------------------------- /OldArt/Components/StorageAccess_Glow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Components/StorageAccess_Glow.png -------------------------------------------------------------------------------- /OldArt/Components/StorageComponent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Components/StorageComponent.png -------------------------------------------------------------------------------- /OldArt/Components/StorageHeart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Components/StorageHeart.png -------------------------------------------------------------------------------- /OldArt/Components/StorageHeart_Glow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Components/StorageHeart_Glow.png -------------------------------------------------------------------------------- /OldArt/Components/StorageUnit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Components/StorageUnit.png -------------------------------------------------------------------------------- /OldArt/Components/StorageUnit_Glow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Components/StorageUnit_Glow.png -------------------------------------------------------------------------------- /OldArt/Items/CreativeStorageUnit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/CreativeStorageUnit.png -------------------------------------------------------------------------------- /OldArt/Items/Locator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/Locator.png -------------------------------------------------------------------------------- /OldArt/Items/LocatorDisk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/LocatorDisk.png -------------------------------------------------------------------------------- /OldArt/Items/RadiantJewel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/RadiantJewel.png -------------------------------------------------------------------------------- /OldArt/Items/RemoteAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/RemoteAccess.png -------------------------------------------------------------------------------- /OldArt/Items/SnowBiomeEmulator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/SnowBiomeEmulator.png -------------------------------------------------------------------------------- /OldArt/Items/StorageAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/StorageAccess.png -------------------------------------------------------------------------------- /OldArt/Items/StorageComponent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/StorageComponent.png -------------------------------------------------------------------------------- /OldArt/Items/StorageHeart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/StorageHeart.png -------------------------------------------------------------------------------- /OldArt/Items/StorageUnit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/StorageUnit.png -------------------------------------------------------------------------------- /OldArt/Items/StorageUnitBlueChlorophyte.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/StorageUnitBlueChlorophyte.png -------------------------------------------------------------------------------- /OldArt/Items/StorageUnitCrimtane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/StorageUnitCrimtane.png -------------------------------------------------------------------------------- /OldArt/Items/StorageUnitDemonite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/StorageUnitDemonite.png -------------------------------------------------------------------------------- /OldArt/Items/StorageUnitHallowed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/StorageUnitHallowed.png -------------------------------------------------------------------------------- /OldArt/Items/StorageUnitHellstone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/StorageUnitHellstone.png -------------------------------------------------------------------------------- /OldArt/Items/StorageUnitLuminite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/StorageUnitLuminite.png -------------------------------------------------------------------------------- /OldArt/Items/StorageUnitTerra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/StorageUnitTerra.png -------------------------------------------------------------------------------- /OldArt/Items/UpgradeBlueChlorophyte.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/UpgradeBlueChlorophyte.png -------------------------------------------------------------------------------- /OldArt/Items/UpgradeCrimtane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/UpgradeCrimtane.png -------------------------------------------------------------------------------- /OldArt/Items/UpgradeDemonite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/UpgradeDemonite.png -------------------------------------------------------------------------------- /OldArt/Items/UpgradeHallowed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/UpgradeHallowed.png -------------------------------------------------------------------------------- /OldArt/Items/UpgradeHellstone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/UpgradeHellstone.png -------------------------------------------------------------------------------- /OldArt/Items/UpgradeLuminite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/UpgradeLuminite.png -------------------------------------------------------------------------------- /OldArt/Items/UpgradeTerra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/Items/UpgradeTerra.png -------------------------------------------------------------------------------- /OldArt/OldOldArt/CraftingAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/OldOldArt/CraftingAccess.png -------------------------------------------------------------------------------- /OldArt/OldOldArt/RemoteAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/OldOldArt/RemoteAccess.png -------------------------------------------------------------------------------- /OldArt/OldOldArt/StorageAccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/OldOldArt/StorageAccess.png -------------------------------------------------------------------------------- /OldArt/OldOldArt/StorageComponent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/OldOldArt/StorageComponent.png -------------------------------------------------------------------------------- /OldArt/OldOldArt/StorageHeart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/OldOldArt/StorageHeart.png -------------------------------------------------------------------------------- /OldArt/OldOldArt/StorageUnit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/OldOldArt/StorageUnit.png -------------------------------------------------------------------------------- /OldArt/SortButtonBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/SortButtonBackground.png -------------------------------------------------------------------------------- /OldArt/SortButtonBackgroundActive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/SortButtonBackgroundActive.png -------------------------------------------------------------------------------- /OldArt/SortID.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/SortID.png -------------------------------------------------------------------------------- /OldArt/SortName.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/SortName.png -------------------------------------------------------------------------------- /OldArt/SortNumber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/OldArt/SortNumber.png -------------------------------------------------------------------------------- /Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Terraria": { 4 | "commandName": "Executable", 5 | "executablePath": "$(tMLPath)", 6 | "workingDirectory": "$(TerrariaSteamPath)" 7 | }, 8 | "TerrariaServer": { 9 | "commandName": "Executable", 10 | "executablePath": "$(tMLServerPath)", 11 | "workingDirectory": "$(TerrariaSteamPath)" 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Magic Storage 2 | 3 | Are you tired of having a mess of chests in your base? Never remember where you put your items, and have to run across your entire house to get from chest to chest? This mod will solve all of your problems! 4 | 5 | This mod offers a solution to storage problems once and for all. It allows you to construct a central network to store all your items, that you can access from one single block. If desired, you can even set up multiple access points to use your storage from anywhere in the world. You can search your storage for items with a certain name, filter by item types, etc. The magic storage can even craft items for you! 6 | 7 | The magic storage scales as you progress in your playthrough. It is accessible very early in the game, but with limited power. As you defeat bosses and earn more materials, you will be able to upgrade your storage to perform more functions and more easily expand the storage capacity. 8 | 9 | ## Description and discussion 10 | A full description and discussion concerning this mod can be found at the [Terraria forum thread](https://forums.terraria.org/index.php?threads/magic-storage.56294/) 11 | 12 | ## Credits 13 | * [@AdipemDragon](https://forums.terraria.org/index.php?members/adipemdragon.2930/) - Spriting 14 | 15 | ## TODO 16 | * Crafting Interface 17 | * Money Compactor 18 | * Wait for bug reports 19 | -------------------------------------------------------------------------------- /Sorting/CompareFunction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Terraria; 4 | 5 | namespace MagicStorageExtra.Sorting 6 | { 7 | public abstract class CompareFunction : IComparer 8 | { 9 | public abstract int Compare(Item item1, Item item2); 10 | 11 | public int Compare(object object1, object object2) 12 | { 13 | if (object1 is Item item1 && object2 is Item item2) 14 | return Compare(item1, item2); 15 | if (object1 is Recipe recipe1 && object2 is Recipe recipe2) 16 | return Compare(recipe1.createItem, recipe2.createItem); 17 | return 0; 18 | } 19 | } 20 | 21 | public class CompareID : CompareFunction 22 | { 23 | public override int Compare(Item item1, Item item2) => item1.type - item2.type; 24 | } 25 | 26 | public class CompareName : CompareFunction 27 | { 28 | public override int Compare(Item item1, Item item2) => string.Compare(item1.Name, item2.Name, StringComparison.OrdinalIgnoreCase); 29 | } 30 | 31 | public class CompareQuantity : CompareFunction 32 | { 33 | public override int Compare(Item item1, Item item2) => 34 | (int) Math.Ceiling(item2.stack / (float) item2.maxStack) - (int) Math.Ceiling(item1.stack / (float) item1.maxStack); 35 | } 36 | 37 | public class CompareValue : CompareFunction 38 | { 39 | public override int Compare(Item item1, Item item2) => item2.value - item1.value; 40 | } 41 | 42 | public class CompareDps : CompareFunction 43 | { 44 | public override int Compare(Item item1, Item item2) => (int) ((GetDps(item2) - GetDps(item1)) * 100); 45 | 46 | public static double GetDps(Item item) 47 | { 48 | if (item.damage <= 0) 49 | return 0d; 50 | 51 | int defence; 52 | if (NPC.downedMoonlord) 53 | defence = 50; 54 | else if (NPC.downedAncientCultist) 55 | defence = 43; 56 | else if (NPC.downedGolemBoss) 57 | defence = 38; 58 | else if (NPC.downedPlantBoss) 59 | defence = 32; 60 | else if (NPC.downedMechBossAny) 61 | defence = 26; 62 | else if (Main.hardMode) 63 | defence = 22; 64 | else if (NPC.downedBoss3) 65 | defence = 16; 66 | else if (NPC.downedBoss2) 67 | defence = 14; 68 | else if (NPC.downedBoss1) 69 | defence = 10; 70 | else 71 | defence = 8; 72 | 73 | return Math.Max(item.damage - defence * 0.5d, 1) / Math.Max((item.useTime + item.reuseDelay) / 60d, 0.001d) * (1d + item.crit / 100d); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Sorting/FilterMode.cs: -------------------------------------------------------------------------------- 1 | namespace MagicStorageExtra.Sorting 2 | { 3 | public enum FilterMode 4 | { 5 | All = 0, 6 | WeaponsMelee, 7 | WeaponsRanged, 8 | WeaponsMagic, 9 | WeaponsSummon, 10 | WeaponsThrown, 11 | Ammo, 12 | Tools, 13 | Armor, 14 | Equipment, 15 | Vanity, 16 | Potions, 17 | Placeables, 18 | Misc, 19 | Recent 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Sorting/ItemFilter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Terraria; 4 | using Terraria.ID; 5 | 6 | namespace MagicStorageExtra.Sorting 7 | { 8 | public abstract class ItemFilter 9 | { 10 | public abstract bool Passes(Item item); 11 | 12 | public bool Passes(object obj) 13 | { 14 | switch (obj) 15 | { 16 | case Item item: 17 | return Passes(item); 18 | case Recipe recipe: 19 | return Passes(recipe.createItem); 20 | default: 21 | return false; 22 | } 23 | } 24 | } 25 | 26 | public class FilterAll : ItemFilter 27 | { 28 | public override bool Passes(Item item) => true; 29 | } 30 | 31 | public class FilterWeaponMelee : ItemFilter 32 | { 33 | public override bool Passes(Item item) => (item.melee || item.thrown && !item.consumable) && item.pick == 0 && item.axe == 0 && item.hammer == 0 && item.damage > 0; 34 | } 35 | 36 | public class FilterWeaponRanged : ItemFilter 37 | { 38 | private readonly FilterWeaponThrown _thrown = new FilterWeaponThrown(); 39 | 40 | public override bool Passes(Item item) => item.ranged && item.damage > 0 && item.ammo <= 0 && !_thrown.Passes(item); 41 | } 42 | 43 | public class FilterWeaponMagic : ItemFilter 44 | { 45 | public override bool Passes(Item item) => (item.magic || item.mana > 0) && !item.summon && !item.consumable; 46 | } 47 | 48 | public class FilterWeaponSummon : ItemFilter 49 | { 50 | public override bool Passes(Item item) 51 | { 52 | switch (item.type) 53 | { 54 | case ItemID.LifeCrystal: 55 | case ItemID.ManaCrystal: 56 | case ItemID.CellPhone: 57 | case ItemID.PDA: 58 | case ItemID.MagicMirror: 59 | case ItemID.IceMirror: 60 | return false; 61 | } 62 | 63 | return item.summon || SortClassList.BossSpawn(item) || SortClassList.Cart(item) || SortClassList.LightPet(item) || SortClassList.Mount(item) || item.sentry; 64 | } 65 | } 66 | 67 | public class FilterWeaponThrown : ItemFilter 68 | { 69 | public override bool Passes(Item item) 70 | { 71 | switch (item.type) 72 | { 73 | case ItemID.Dynamite: 74 | case ItemID.StickyDynamite: 75 | case ItemID.BouncyDynamite: 76 | case ItemID.Bomb: 77 | case ItemID.StickyBomb: 78 | case ItemID.BouncyBomb: 79 | return true; 80 | } 81 | 82 | return item.thrown && item.damage > 0 || item.consumable && item.Name.ToLowerInvariant().EndsWith(" coating"); 83 | } 84 | } 85 | 86 | public class FilterAmmo : ItemFilter 87 | { 88 | public override bool Passes(Item item) => item.ammo > 0 && item.damage > 0 && item.ammo != AmmoID.Coin; 89 | } 90 | 91 | public class FilterVanity : ItemFilter 92 | { 93 | public override bool Passes(Item item) => 94 | item.vanity || SortClassList.Dye(item) || SortClassList.HairDye(item) || SortClassList.VanityPet(item); 95 | } 96 | 97 | public class FilterOtherWeapon : ItemFilter 98 | { 99 | public override bool Passes(Item item) => !item.melee && !item.ranged && !item.magic && !item.summon && !item.thrown && item.damage > 0; 100 | } 101 | 102 | public class FilterWeapon : ItemFilter 103 | { 104 | public override bool Passes(Item item) => !(item.consumable && item.thrown) && (item.damage > 0 || item.magic && item.healLife > 0 && item.mana > 0) && item.pick == 0 && item.axe == 0 && item.hammer == 0; 105 | } 106 | 107 | public class FilterPickaxe : ItemFilter 108 | { 109 | public override bool Passes(Item item) => item.pick > 0; 110 | } 111 | 112 | public class FilterAxe : ItemFilter 113 | { 114 | public override bool Passes(Item item) => item.axe > 0; 115 | } 116 | 117 | public class FilterHammer : ItemFilter 118 | { 119 | public override bool Passes(Item item) => item.hammer > 0; 120 | } 121 | 122 | public class FilterTool : ItemFilter 123 | { 124 | public override bool Passes(Item item) => item.pick > 0 || item.axe > 0 || item.hammer > 0; 125 | } 126 | 127 | public class FilterArmor : ItemFilter 128 | { 129 | public override bool Passes(Item item) => !item.vanity && (item.headSlot >= 0 || item.bodySlot >= 0 || item.legSlot >= 0); 130 | } 131 | 132 | public class FilterEquipment : ItemFilter 133 | { 134 | public override bool Passes(Item item) => !item.vanity && (item.accessory || Main.projHook[item.shoot] || item.mountType >= 0 || item.buffType > 0 && (Main.lightPet[item.buffType] || Main.vanityPet[item.buffType])); 135 | } 136 | 137 | public class FilterPotion : ItemFilter 138 | { 139 | public override bool Passes(Item item) => item.consumable && (item.healLife > 0 || item.healMana > 0 || item.buffType > 0 || item.potion || item.Name.ToLowerInvariant().Contains("potion") || item.Name.ToLowerInvariant().Contains("elixir")); 140 | } 141 | 142 | public class FilterPlaceable : ItemFilter 143 | { 144 | public override bool Passes(Item item) => item.createTile >= TileID.Dirt || item.createWall > 0; 145 | } 146 | 147 | public class FilterMisc : ItemFilter 148 | { 149 | private static readonly List blacklist = new List 150 | { 151 | new FilterWeaponMelee(), 152 | new FilterWeaponRanged(), 153 | new FilterWeaponMagic(), 154 | new FilterWeaponSummon(), 155 | new FilterWeaponThrown(), 156 | new FilterAmmo(), 157 | new FilterWeaponThrown(), 158 | new FilterVanity(), 159 | new FilterTool(), 160 | new FilterArmor(), 161 | new FilterEquipment(), 162 | new FilterPotion(), 163 | new FilterPlaceable() 164 | }; 165 | 166 | public override bool Passes(Item item) 167 | { 168 | return blacklist.All(filter => !filter.Passes(item)); 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /Sorting/ItemSorter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Terraria; 5 | using Terraria.ModLoader; 6 | 7 | namespace MagicStorageExtra.Sorting 8 | { 9 | public static class ItemSorter 10 | { 11 | public static IEnumerable SortAndFilter(IEnumerable items, SortMode sortMode, FilterMode filterMode, int modFilterIndex, string nameFilter, int? takeCount = null) 12 | { 13 | ItemFilter filter = MakeFilter(filterMode); 14 | IEnumerable filteredItems = items.Where(item => filter.Passes(item) && FilterName(item, nameFilter) && FilterMod(item, modFilterIndex)); 15 | if (takeCount != null) 16 | filteredItems = filteredItems.Take(takeCount.Value); 17 | 18 | filteredItems = Aggregate(filteredItems); 19 | 20 | CompareFunction func = MakeSortFunction(sortMode); 21 | return func is null ? filteredItems : filteredItems.OrderBy(x => x, func).ThenBy(x => x.type).ThenBy(x => x.value); 22 | } 23 | 24 | public static IEnumerable Aggregate(IEnumerable items) 25 | { 26 | var aggregateX = new Dictionary(); 27 | foreach (Item item in items) 28 | { 29 | ItemData itemData = new ItemData(item); 30 | if (aggregateX.TryGetValue(itemData, out Item i)) 31 | i.stack += item.stack; 32 | else 33 | aggregateX.Add(itemData, item.Clone()); 34 | } 35 | 36 | return aggregateX.Values; 37 | } 38 | 39 | public static IEnumerable GetRecipes(SortMode sortMode, FilterMode filterMode, int modFilterIndex, string nameFilter) 40 | { 41 | ItemFilter filter = MakeFilter(filterMode); 42 | IEnumerable filteredRecipes = Main.recipe.Take(Recipe.numRecipes) 43 | .Where(recipe => filter.Passes(recipe) && FilterName(recipe.createItem, nameFilter) && FilterMod(recipe.createItem, modFilterIndex)); 44 | 45 | CompareFunction func = MakeSortFunction(sortMode); 46 | return func is null 47 | ? filteredRecipes 48 | : filteredRecipes.OrderBy(x => x.createItem, func).ThenBy(x => x.createItem.type).ThenBy(x => x.createItem.value); 49 | } 50 | 51 | private static CompareFunction MakeSortFunction(SortMode sortMode) 52 | { 53 | CompareFunction func; 54 | switch (sortMode) 55 | { 56 | case SortMode.Default: 57 | func = new CompareDefault(); 58 | break; 59 | case SortMode.Id: 60 | func = new CompareID(); 61 | break; 62 | case SortMode.Name: 63 | func = new CompareName(); 64 | break; 65 | case SortMode.Value: 66 | func = new CompareValue(); 67 | break; 68 | case SortMode.Dps: 69 | func = new CompareDps(); 70 | break; 71 | default: 72 | func = null; 73 | break; 74 | } 75 | 76 | return func; 77 | } 78 | 79 | private static ItemFilter MakeFilter(FilterMode filterMode) 80 | { 81 | ItemFilter filter; 82 | switch (filterMode) 83 | { 84 | case FilterMode.All: 85 | filter = new FilterAll(); 86 | break; 87 | case FilterMode.WeaponsMelee: 88 | filter = new FilterWeaponMelee(); 89 | break; 90 | case FilterMode.WeaponsRanged: 91 | filter = new FilterWeaponRanged(); 92 | break; 93 | case FilterMode.WeaponsMagic: 94 | filter = new FilterWeaponMagic(); 95 | break; 96 | case FilterMode.WeaponsSummon: 97 | filter = new FilterWeaponSummon(); 98 | break; 99 | case FilterMode.Ammo: 100 | filter = new FilterAmmo(); 101 | break; 102 | case FilterMode.WeaponsThrown: 103 | filter = new FilterWeaponThrown(); 104 | break; 105 | case FilterMode.Tools: 106 | filter = new FilterTool(); 107 | break; 108 | case FilterMode.Armor: 109 | filter = new FilterArmor(); 110 | break; 111 | case FilterMode.Vanity: 112 | filter = new FilterVanity(); 113 | break; 114 | case FilterMode.Equipment: 115 | filter = new FilterEquipment(); 116 | break; 117 | case FilterMode.Potions: 118 | filter = new FilterPotion(); 119 | break; 120 | case FilterMode.Placeables: 121 | filter = new FilterPlaceable(); 122 | break; 123 | case FilterMode.Misc: 124 | filter = new FilterMisc(); 125 | break; 126 | case FilterMode.Recent: 127 | throw new NotSupportedException(); 128 | default: 129 | filter = new FilterAll(); 130 | break; 131 | } 132 | 133 | return filter; 134 | } 135 | 136 | private static bool FilterName(Item item, string filter) 137 | { 138 | if (filter.Trim().Length == 0) 139 | filter = string.Empty; 140 | return item.Name.ToLowerInvariant().IndexOf(filter.Trim().ToLowerInvariant(), StringComparison.Ordinal) >= 0; 141 | } 142 | 143 | private static bool FilterMod(Item item, int modFilterIndex) 144 | { 145 | if (modFilterIndex == ModSearchBox.ModIndexAll) 146 | return true; 147 | Mod[] allMods = MagicStorageExtra.Instance.AllMods; 148 | int index = ModSearchBox.ModIndexBaseGame; 149 | if (item.modItem != null) 150 | index = Array.IndexOf(allMods, item.modItem.mod); 151 | return index == modFilterIndex; 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /Sorting/SortMode.cs: -------------------------------------------------------------------------------- 1 | namespace MagicStorageExtra.Sorting 2 | { 3 | public enum SortMode 4 | { 5 | Default, 6 | Id, 7 | Name, 8 | Value, 9 | Dps, 10 | AsIs 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /StorageWorld.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Threading; 4 | using Terraria; 5 | using Terraria.ID; 6 | using Terraria.ModLoader; 7 | using Terraria.ModLoader.IO; 8 | 9 | namespace MagicStorageExtra 10 | { 11 | public class StorageWorld : ModWorld 12 | { 13 | private const int saveVersion = 0; 14 | public static bool kingSlimeDiamond; 15 | public static bool boss1Diamond; 16 | public static bool boss2Diamond; 17 | public static bool boss3Diamond; 18 | public static bool queenBeeDiamond; 19 | public static bool hardmodeDiamond; 20 | public static bool mechBoss1Diamond; 21 | public static bool mechBoss2Diamond; 22 | public static bool mechBoss3Diamond; 23 | public static bool plantBossDiamond; 24 | public static bool golemBossDiamond; 25 | public static bool fishronDiamond; 26 | public static bool ancientCultistDiamond; 27 | public static bool moonlordDiamond; 28 | public static Dictionary> TileToCreatingItem = new Dictionary>(); 29 | 30 | public override void Initialize() 31 | { 32 | kingSlimeDiamond = false; 33 | boss1Diamond = false; 34 | boss2Diamond = false; 35 | boss3Diamond = false; 36 | queenBeeDiamond = false; 37 | hardmodeDiamond = false; 38 | mechBoss1Diamond = false; 39 | mechBoss2Diamond = false; 40 | mechBoss3Diamond = false; 41 | plantBossDiamond = false; 42 | golemBossDiamond = false; 43 | fishronDiamond = false; 44 | ancientCultistDiamond = false; 45 | moonlordDiamond = false; 46 | } 47 | 48 | public override TagCompound Save() 49 | { 50 | var tag = new TagCompound 51 | { 52 | ["saveVersion"] = saveVersion, 53 | ["kingSlimeDiamond"] = kingSlimeDiamond, 54 | ["boss1Diamond"] = boss1Diamond, 55 | ["boss2Diamond"] = boss2Diamond, 56 | ["boss3Diamond"] = boss3Diamond, 57 | ["queenBeeDiamond"] = queenBeeDiamond, 58 | ["hardmodeDiamond"] = hardmodeDiamond, 59 | ["mechBoss1Diamond"] = mechBoss1Diamond, 60 | ["mechBoss2Diamond"] = mechBoss2Diamond, 61 | ["mechBoss3Diamond"] = mechBoss3Diamond, 62 | ["plantBossDiamond"] = plantBossDiamond, 63 | ["golemBossDiamond"] = golemBossDiamond, 64 | ["fishronDiamond"] = fishronDiamond, 65 | ["ancientCultistDiamond"] = ancientCultistDiamond, 66 | ["moonlordDiamond"] = moonlordDiamond 67 | }; 68 | return tag; 69 | } 70 | 71 | public override void Load(TagCompound tag) 72 | { 73 | kingSlimeDiamond = tag.GetBool("kingSlimeDiamond"); 74 | boss1Diamond = tag.GetBool("boss1Diamond"); 75 | boss2Diamond = tag.GetBool("boss2Diamond"); 76 | boss3Diamond = tag.GetBool("boss3Diamond"); 77 | queenBeeDiamond = tag.GetBool("queenBeeDiamond"); 78 | hardmodeDiamond = tag.GetBool("hardmodeDiamond"); 79 | mechBoss1Diamond = tag.GetBool("mechBoss1Diamond"); 80 | mechBoss2Diamond = tag.GetBool("mechBoss2Diamond"); 81 | mechBoss3Diamond = tag.GetBool("mechBoss3Diamond"); 82 | plantBossDiamond = tag.GetBool("plantBossDiamond"); 83 | golemBossDiamond = tag.GetBool("golemBossDiamond"); 84 | fishronDiamond = tag.GetBool("fishronDiamond"); 85 | ancientCultistDiamond = tag.GetBool("ancientCultistDiamond"); 86 | moonlordDiamond = tag.GetBool("moonlordDiamond"); 87 | 88 | Volatile.Write(ref TileToCreatingItem, new Dictionary>()); // used from threaded RefreshRecipes 89 | } 90 | 91 | public override void PostUpdate() 92 | { 93 | if (TileToCreatingItem.Count == 0) 94 | { 95 | #region Initialize TileToCreatingItem 96 | 97 | Dictionary> tileToCreatingItem = Enumerable.Range(0, ItemLoader.ItemCount).Select((x, i) => 98 | { 99 | var item = new Item(); 100 | // provide items 101 | try 102 | { 103 | item.SetDefaults(i, true); 104 | } 105 | catch 106 | { 107 | return null; 108 | } 109 | 110 | return item; 111 | }).Where(x => x?.type > 0 && x.createTile >= TileID.Dirt).Select(x => 112 | { 113 | // provide item and its tiles 114 | var tiles = new List {x.createTile}; 115 | switch (x.createTile) 116 | { 117 | case TileID.GlassKiln: 118 | case TileID.Hellforge: 119 | tiles.Add(TileID.Furnaces); 120 | break; 121 | case TileID.AdamantiteForge: 122 | tiles.Add(TileID.Furnaces); 123 | tiles.Add(TileID.Hellforge); 124 | break; 125 | case TileID.MythrilAnvil: 126 | tiles.Add(TileID.Anvils); 127 | break; 128 | case TileID.BewitchingTable: 129 | case TileID.Tables2: 130 | tiles.Add(TileID.Tables); 131 | break; 132 | case TileID.AlchemyTable: 133 | tiles.Add(TileID.Bottles); 134 | tiles.Add(TileID.Tables); 135 | break; 136 | } 137 | 138 | return new 139 | { 140 | item = x, 141 | tiles 142 | }; 143 | }) 144 | // flatten - tile, item 145 | .SelectMany(x => x.tiles.Select(t => new {tile = t, x.item})).GroupBy(x => x.tile).ToDictionary(x => x.Key, x => x.Select(y => y.item.type).ToList()); 146 | 147 | Volatile.Write(ref TileToCreatingItem, tileToCreatingItem); 148 | 149 | #endregion 150 | } 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /UI/UIButtonChoice.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework; 3 | using Microsoft.Xna.Framework.Graphics; 4 | using Terraria; 5 | using Terraria.Localization; 6 | using Terraria.UI; 7 | 8 | namespace MagicStorageExtra.UI 9 | { 10 | public class UIButtonChoice : UIElement 11 | { 12 | private readonly Action _onChanged; 13 | private readonly int buttonPadding; 14 | 15 | private readonly Texture2D[] buttons; 16 | private readonly int buttonSize; 17 | 18 | private readonly LocalizedText[] names; 19 | 20 | public UIButtonChoice(Action onChanged, Texture2D[] buttons, LocalizedText[] names, int buttonSize = 21, int buttonPadding = 1) 21 | { 22 | if (buttons.Length != names.Length || buttons.Length == 0) 23 | throw new ArgumentException(); 24 | 25 | _onChanged = onChanged; 26 | this.buttonSize = buttonSize; 27 | this.buttonPadding = buttonPadding; 28 | this.buttons = buttons; 29 | this.names = names; 30 | int width = buttonSize * buttons.Length + buttonPadding * (buttons.Length - 1); 31 | Width.Set(width, 0f); 32 | MinWidth.Set(width, 0f); 33 | Height.Set(buttonSize, 0f); 34 | MinHeight.Set(buttonSize, 0f); 35 | } 36 | 37 | public int Choice { get; set; } 38 | 39 | public override void Update(GameTime gameTime) 40 | { 41 | int oldChoice = Choice; 42 | if (StorageGUI.MouseClicked && Parent != null) 43 | for (int k = 0; k < buttons.Length; k++) 44 | if (MouseOverButton(StorageGUI.curMouse.X, StorageGUI.curMouse.Y, k)) 45 | { 46 | Choice = k; 47 | break; 48 | } 49 | 50 | if (oldChoice != Choice) 51 | _onChanged?.Invoke(); 52 | } 53 | 54 | private bool MouseOverButton(int mouseX, int mouseY, int button) 55 | { 56 | Rectangle dim = InterfaceHelper.GetFullRectangle(this); 57 | float left = dim.X + button * (buttonSize + buttonPadding) * Main.UIScale; 58 | float right = left + buttonSize * Main.UIScale; 59 | float top = dim.Y; 60 | float bottom = top + buttonSize * Main.UIScale; 61 | return mouseX > left && mouseX < right && mouseY > top && mouseY < bottom; 62 | } 63 | 64 | protected override void DrawSelf(SpriteBatch spriteBatch) 65 | { 66 | Texture2D backTexture = MagicStorageExtra.Instance.GetTexture("Assets/SortButtonBackground"); 67 | Texture2D backTextureActive = MagicStorageExtra.Instance.GetTexture("Assets/SortButtonBackgroundActive"); 68 | CalculatedStyle dim = GetDimensions(); 69 | for (int k = 0; k < buttons.Length; k++) 70 | { 71 | Texture2D texture = k == Choice ? backTextureActive : backTexture; 72 | var drawPos = new Vector2(dim.X + k * (buttonSize + buttonPadding), dim.Y); 73 | Color color = MouseOverButton(StorageGUI.curMouse.X, StorageGUI.curMouse.Y, k) ? Color.Silver : Color.White; 74 | Main.spriteBatch.Draw(texture, new Rectangle((int) drawPos.X, (int) drawPos.Y, buttonSize, buttonSize), color); 75 | Main.spriteBatch.Draw(buttons[k], new Rectangle((int) drawPos.X + 1, (int) drawPos.Y + 1, buttonSize - 1, buttonSize - 1), Color.White); 76 | } 77 | } 78 | 79 | public void DrawText() 80 | { 81 | for (int k = 0; k < buttons.Length; k++) 82 | if (MouseOverButton(StorageGUI.curMouse.X, StorageGUI.curMouse.Y, k)) 83 | Main.instance.MouseText(names[k].Value); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /UI/UISlotZone.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using Microsoft.Xna.Framework.Input; 4 | using Terraria; 5 | using Terraria.UI; 6 | 7 | namespace MagicStorageExtra.UI 8 | { 9 | public class UISlotZone : UIElement 10 | { 11 | public delegate Item GetItem(int slot, ref int context); 12 | 13 | public delegate void HoverItemSlot(int slot, ref int hoverSlot); 14 | 15 | private const int padding = 4; 16 | 17 | private readonly GetItem getItem; 18 | private readonly float inventoryScale; 19 | private readonly HoverItemSlot onHover; 20 | private int hoverSlot = -1; 21 | private int numColumns = 10; 22 | private int numRows = 4; 23 | 24 | public UISlotZone(HoverItemSlot onHover, GetItem getItem, float scale) 25 | { 26 | this.onHover = onHover; 27 | this.getItem = getItem; 28 | inventoryScale = scale; 29 | } 30 | 31 | public void SetDimensions(int columns, int rows) 32 | { 33 | numColumns = columns; 34 | numRows = rows; 35 | } 36 | 37 | public override void Update(GameTime gameTime) 38 | { 39 | hoverSlot = -1; 40 | Vector2 origin = InterfaceHelper.GetFullRectangle(this).TopLeft(); 41 | MouseState curMouse = StorageGUI.curMouse; 42 | if (curMouse.X <= origin.X || curMouse.Y <= origin.Y) 43 | return; 44 | int slotWidth = (int) (Main.inventoryBackTexture.Width * inventoryScale * Main.UIScale); 45 | int slotHeight = (int) (Main.inventoryBackTexture.Height * inventoryScale * Main.UIScale); 46 | int slotX = (curMouse.X - (int) origin.X) / (slotWidth + padding); 47 | int slotY = (curMouse.Y - (int) origin.Y) / (slotHeight + padding); 48 | if (slotX < 0 || slotX >= numColumns || slotY < 0 || slotY >= numRows) 49 | return; 50 | Vector2 slotPos = origin + new Vector2(slotX * (slotWidth + padding * Main.UIScale), slotY * (slotHeight + padding * Main.UIScale)); 51 | if (curMouse.X > slotPos.X && curMouse.X < slotPos.X + slotWidth && curMouse.Y > slotPos.Y && curMouse.Y < slotPos.Y + slotHeight) 52 | onHover(slotX + numColumns * slotY, ref hoverSlot); 53 | } 54 | 55 | protected override void DrawSelf(SpriteBatch spriteBatch) 56 | { 57 | float slotWidth = Main.inventoryBackTexture.Width * inventoryScale; 58 | float slotHeight = Main.inventoryBackTexture.Height * inventoryScale; 59 | Vector2 origin = GetDimensions().Position(); 60 | float oldScale = Main.inventoryScale; 61 | Main.inventoryScale = inventoryScale; 62 | var temp = new Item[11]; 63 | for (int k = 0; k < numColumns * numRows; k++) 64 | { 65 | int context = 0; 66 | Item item = getItem(k, ref context); 67 | Vector2 drawPos = origin + new Vector2((slotWidth + padding) * (k % numColumns), (slotHeight + padding) * (k / numColumns)); 68 | temp[10] = item; 69 | ItemSlot.Draw(Main.spriteBatch, temp, context, 10, drawPos); 70 | } 71 | 72 | Main.inventoryScale = oldScale; 73 | } 74 | 75 | public void DrawText() 76 | { 77 | if (hoverSlot >= 0) 78 | { 79 | int context = 0; 80 | Item hoverItem = getItem(hoverSlot, ref context); 81 | if (!hoverItem.IsAir) 82 | { 83 | Main.HoverItem = hoverItem.Clone(); 84 | Main.instance.MouseText(string.Empty); 85 | } 86 | } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /UI/UIToggleButton.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework; 3 | using Microsoft.Xna.Framework.Graphics; 4 | using Terraria; 5 | using Terraria.Localization; 6 | using Terraria.UI; 7 | 8 | namespace MagicStorageExtra.UI 9 | { 10 | public class UIToggleButton : UIElement 11 | { 12 | private readonly Texture2D _button; 13 | private readonly LocalizedText _name; 14 | private readonly int buttonSize; 15 | private readonly Action onChanged; 16 | 17 | public UIToggleButton(Action onChanged, Texture2D button, LocalizedText name, int buttonSize = 21) 18 | { 19 | this.buttonSize = buttonSize; 20 | this.onChanged = onChanged; 21 | _button = button; 22 | _name = name; 23 | Width.Set(buttonSize, 0f); 24 | MinWidth.Set(buttonSize, 0f); 25 | Height.Set(buttonSize, 0f); 26 | MinHeight.Set(buttonSize, 0f); 27 | } 28 | 29 | public bool Value { get; set; } 30 | 31 | public override void Update(GameTime gameTime) 32 | { 33 | bool oldValue = Value; 34 | if (StorageGUI.MouseClicked && Parent != null) 35 | if (MouseOverButton(StorageGUI.curMouse.X, StorageGUI.curMouse.Y)) 36 | Value = !Value; 37 | 38 | if (oldValue != Value) 39 | onChanged?.Invoke(); 40 | } 41 | 42 | private bool MouseOverButton(int mouseX, int mouseY) 43 | { 44 | Rectangle dim = InterfaceHelper.GetFullRectangle(this); 45 | float left = dim.X; 46 | float right = left + buttonSize * Main.UIScale; 47 | float top = dim.Y; 48 | float bottom = top + buttonSize * Main.UIScale; 49 | return mouseX > left && mouseX < right && mouseY > top && mouseY < bottom; 50 | } 51 | 52 | protected override void DrawSelf(SpriteBatch spriteBatch) 53 | { 54 | Texture2D backTexture = MagicStorageExtra.Instance.GetTexture("Assets/SortButtonBackground"); 55 | Texture2D backTextureActive = MagicStorageExtra.Instance.GetTexture("Assets/SortButtonBackgroundActive"); 56 | CalculatedStyle dim = GetDimensions(); 57 | Texture2D texture = Value ? backTextureActive : backTexture; 58 | var drawPos = new Vector2(dim.X, dim.Y); 59 | Color color = MouseOverButton(StorageGUI.curMouse.X, StorageGUI.curMouse.Y) ? Color.Silver : Color.White; 60 | Main.spriteBatch.Draw(texture, new Rectangle((int) drawPos.X, (int) drawPos.Y, buttonSize, buttonSize), color); 61 | Main.spriteBatch.Draw(_button, new Rectangle((int) drawPos.X + 1, (int) drawPos.Y + 1, buttonSize - 1, buttonSize - 1), Color.White); 62 | } 63 | 64 | public void DrawText() 65 | { 66 | if (MouseOverButton(StorageGUI.curMouse.X, StorageGUI.curMouse.Y)) 67 | Main.instance.MouseText(_name.Value); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /build.txt: -------------------------------------------------------------------------------- 1 | author = blushiemagic and wvlad and exterminator 2 | version = 0.5.5.10 3 | displayName = Magic Storage - Extra 4 | homepage = https://github.com/ExterminatorX99/MagicStorageExtra 5 | hideCode = false 6 | hideResources = false 7 | includeSource = true 8 | includePDB = true 9 | buildIgnore = OldArt\*, .git\* 10 | weakReferences = RecursiveCraft@1.6.1 -------------------------------------------------------------------------------- /description.txt: -------------------------------------------------------------------------------- 1 | Are you tired of having a mess of chests in your base? Never remember where you put your items, and have to run across your entire house to get from chest to chest? This mod will solve all of your problems! 2 | 3 | This mod offers a solution to storage problems once and for all. It allows you to construct a central network to store all your items, that you can access from one single block. If desired, you can even set up multiple access points to use your storage from anywhere in the world. You can search your storage for items with a certain name, filter by item types, etc. The magic storage can even craft items for you! 4 | 5 | The magic storage scales as you progress in your playthrough. It is accessible very early in the game, but with limited power. As you defeat bosses and earn more materials, you will be able to upgrade your storage to perform more functions and more easily expand the storage capacity. 6 | 7 | Changes from original: 8 | Added more station slots to the crafting interface. 9 | Added more sort options. 10 | Added RecursiveCraft support 11 | Added quick stack and restock to Storage Heart deposit button (Read tooltip) 12 | Added weapon DPS calculation (Not 100% accurate) 13 | 14 | TODO: 15 | Money Compactor 16 | Blacklist/Whitelist for specific accesses 17 | Wait for bug reports 18 | 19 | Changelog: 20 | 0.5.5.10: 21 | Fix Linux issues - fuck Mono 22 | 0.5.5.9: 23 | Add config option to toggle the dps tooltip 24 | 0.5.5.8: 25 | Fix bug that prevented the placement of Storage Connector above blocks 26 | 0.5.5.7: 27 | - Fix bug that prevented placing storage tiles onto blocks 28 | 0.5.5.6: 29 | - Fix Storage Unit placement bug 30 | 0.5.5.5: 31 | - Items of same type and prefix stack together 32 | - Bug fix 33 | 0.5.5.3: 34 | - Added config to clear search text 35 | 0.5.4.1: 36 | Add config for storage deposit quick stack behaviour 37 | - Due to some config changes, all your config settings have been reset 38 | 0.5.4.0: 39 | Fixed world sections not loading due to storage systems having too many items 40 | Fixed bad netcode causing "read underflows" 41 | Fixed the crafting GUI sometimes throwing exceptions 42 | Fixes done by absoluteAquarian 43 | 0.5.3.6: 44 | Update RecursiveCraft reference 45 | 0.5.3.5: 46 | Fix storage access 47 | 0.5.3.4: 48 | Fix reach extending items not working 49 | 0.5.3.3: 50 | Show that ingredient is craftable in ingredient list 51 | 0.5.3.2: 52 | Fix logic error 53 | 0.5.3.1: 54 | Fix storage heart not being loaded when far away in multiplayer 55 | 0.5.3.0: 56 | Update for new RecursiveCraft version 57 | 0.5.2.13: 58 | Fix issue with recipe staying selected after reload 59 | 0.5.2.12: 60 | Fix bug introduced in 0.5.2.9 and add Mod Helpers bug reporting feature 61 | 0.5.2.11: 62 | Some more optimizations 63 | 0.5.2.10: 64 | Fix right click only working on result once 65 | 0.5.2.9: 66 | Fix pulling wrong item from storage 67 | 0.5.2.8: 68 | Optimizations and modular ingredient UI 69 | 0.5.2.7: 70 | Added config for default recipe filter 71 | 0.5.2.6: 72 | Fixed extracting items from first instead of last stack 73 | 0.5.2.5: 74 | Functional RecursiveCraft support 75 | 0.5.2.4: 76 | Fix vanilla recipe groups not being processed 77 | 0.5.2.2: 78 | Temporarily disable integration with RecursiveCraft due to bugs 79 | 0.5.2.1: 80 | Fix search bug 81 | 0.5.2.0: 82 | Added integration with the RecursiveCraft mod -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/icon.png -------------------------------------------------------------------------------- /lib/RecursiveCraft_v1.6.1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExterminatorX99/MagicStorageExtra/5eb6a76a6c94f3f514538d16d84309d026d84c44/lib/RecursiveCraft_v1.6.1.dll --------------------------------------------------------------------------------