- Updated the code for handling Census - Town NPC Checklist support to use the more modern APIs
ItemTypeOrderedSet
is now more stable and can properly remember previously-unloaded items (Thanks to@buzzers
on Discord)- Fixed the tooltip for the Advanced Portable Remote Crafting Access not displaying the correct ranges due to a copy/paste oversight
- Fixed the Spanish tooltips for the Portable Remote Access items to use the correct noun pies (feet) instead of bloques (blocks)
- Fixed a bug where storage-pylon logic wouldn't recognize world changes from special seeds like getfixedboi
- Fixed the tooltip of the Display new items/recipes config option not showing the correct text
- World data will no longer leak between the main world and subworlds when using Subworld Library
- Fixed an oversight where a Storage Heart without a tile entity could still have its location saved to a Locator, Locator Disk or Portable Remote Access
- Fixed an oversight where a Storage Crafting Interface without a tile entity could still have its location saved to a Portable Remote Crafting Access
- Reworked the system responsible for encrypting certain character strings to fix a bug that would generate invalid Unicode characters
- Fixed an oversight that caused some logic responsible for preventing item slot interactions from working properly
- Fixed a bug where the Use Journey Mode Infinite Items module for the Storage Configuration Interface would only update when fully researching an item and wouldn't properly reset when changing players
- Fixed a bug caused by
TEStorageComponent.SearchAndRefreshNetwork()
missing anull
check - Fixed some oversights that caused some of the recipe groups ("Any X") to miss some items
- Fixed a bug where ingredients using recipe groups ("Any X") would sometimes not be satisifed
- This was caused by the system trying to completely satisfy the ingredient requirement with one item in the group at a time
- E.g. if a recipe called for Any Iron Bar (6), 2 Iron Bars and 4 Lead Bars would not fulfill the requirement
- Fixed a bug which caused special recipe conditions like "Near water" to be never satisfied
RecipeLoader.OnCraft()
— and its subsequent callsModItem.OnCreate()
andGlobalItem.OnCreate()
— is no longer called during crafting simulations- If you were using this behavior to drop extra items when using certain recipes, check the new API for adding "extra craft drops" mentioned further down in this document
- Fixed a bug where crafted items would not get random prefixes
ModItem.OnCreate()
andGlobalItem.OnCreate()
are now called with the actual crafted item rather than a temporary clone- Ingredient blocking now respects the prefixes of items being blocked (previously only tracked the ID)
- Fixed some concurrency issues where player "zone information" could be incorrect when evaluating recipes
- Now triggers achievements related to crafting items
- Fixed an issue with the Delete Unloaded Mod Data control which, when used, would cause the items it modified to end up in an unstable state and sometimes be unable to save
- Rewrote the backend for item slots to be more stable on higher-frequency monitors
- Handled by the v1.0.6 update of absoluteAquarian Utilities
- Fixed a bug where item slots would sometimes have the wrong background when refreshing the UI
- The Required Objects lines of text in the Crafting UI will now shrink horizontally if they end up being too long
- Fixed an oversight where the Required Objects in the Crafing UI text was recalculated every update tick
- Fixed a bug where the recipe result item slot in the Crafting UI could not be used to deposit items
- Fixed an oversight where the Ingredients item slots area in the Crafing UI would have an extra row if the amount of required ingredients was a multiple of 7
- Fixed a bug where the Default Sorting sorting option used the coin value of Summoner weapons instead of their damage
- Fixed inconistencies and removed false positives in the filters for weapons:
- Non-consumable Throwing weapons were considered the same as Melee weapons
- Any items whose name ended with coating were considered Throwing weapons
- Magic weapons with no mana cost were not considered Magic weapons
- Fixed an oversight where weapons with a max stack of 1 would be sorted last when using the Default Sorting sorting option
- Fixed several bugs in the item/recipe sorting logic which caused some entries to be in reverse order or in the wrong location
- Fixed a bug where the Filter New Recently Added Items filter option would always show nothing for multiplayer clients
- Multiplayer clients will now occasionally force a full refresh of the Storage UI to mitigate phantom/fake/missing items
- Storage components now remember where their connected Storage Heart or Remote Access is located and vice versa
- Previously, attempting to retrieve the Storage Heart for a storage component would always perform a search of the entire network
- The
MagicStorage.MagicCache::InitRecursiveTrees
step during mod loading is now parallelized- The step now also mentions its progress
- Fixed a massive memory leak caused by
MagicCache
data being captured by compiler-generated classes - Rewrote the backend for IME handling in the search bars to be more performant
- Handled by the v1.0.6 update of absoluteAquarian Utilities
- Added another layer of data compression to make Storage Unit data take up as few bytes as possible for netcode packets
- A Storage Heart now only remembers the most recent 130 unique items inserted into its storage
- This was a massive issue since the entire deposit history — which would end up being thousands of bytes — was sent in netcode packets and only ~100 entries were actually needed
- Clients considered the host for a server (either via Host&Play or via the
start-tModLoaderServer
script) can now be automatically given the Server Admin status on join- This is locked behind a config option in the Magic Storage Server Config
- Added a new multiplayer-exclusive help tip for the Automaton which mentions how the Server Operator and Server Admin statuses work
- Removed the message about Item Deletion Mode that was printed on world join
- Reduced the width of the Automaton's collision box
- The Server Operator Key is now also printed to the
server.log
logging file- The client message also now mentions that the key can be found in the server log
- Entering the correct key now mentions that the Server Administrator status is also granted
- Fixed the prices and "adjacent tile" information for the Combined Stations items being incorrect
- Added a safeguard when loading item data to mitigrate crashes and load failures when entering a world
- Added localizations for Portuguese (thanks to
@Suh
on Discord) - The Radiant Jewel now follows a "pity drops" system where the more drop attempts fail — either from the Moon Lord himself or his Treasure Bag — the more likely it is to drop
- All of the recipe groups that Magic Storage creates (
MagicStorage:AnyX
) are now mirrored to standard recipe groups"MagicStorage:AnyChest"
⇔nameof(ItemID.Chest)
"MagicStorage:AnySnowBiomeBlock"
⇔nameof(ItemID.SnowBlock)
"MagicStorage:AnyDiamond"
⇔nameof(ItemID.Diamond)
"MagicStorage:AnyChest"
⇔nameof(ItemID.Chest)
"MagicStorage:AnyWorkBench"
⇔nameof(ItemID.WorkBench)
"MagicStorage:AnyPreHmAnvil"
⇔nameof(ItemID.IronAnvil)
"MagicStorage:AnyBottle"
⇔nameof(ItemID.Bottle)
"MagicStorage:AnySink"
⇔nameof(ItemID.MetalSink)
"MagicStorage:AnyTable"
⇔nameof(ItemID.WoodenTable)
"MagicStorage:AnyCookingPot"
⇔nameof(ItemID.CookingPot)
"MagicStorage:AnyHmAnvil"
⇔nameof(ItemID.MythrilAnvil)
"MagicStorage:AnyHmFurnace"
⇔nameof(ItemID.AdamantiteForge)
"MagicStorage:AnyBookcase"
⇔nameof(ItemID.Bookcase)
"MagicStorage:AnyTombstone"
⇔nameof(ItemID.Tombstone)
"MagicStorage:AnyCampfire"
⇔nameof(ItemID.Campfire)
"MagicStorage:AnySilverBar"
⇔nameof(ItemID.SilverBar)
"MagicStorage:AnyMythrilBar"
⇔nameof(ItemID.MythrilBar)
"MagicStorage:AnyDemoniteBar"
⇔nameof(ItemID.DemoniteBar)
- Added a new API for defining custom Storage Unit tiers (see: New APIs further down in the document)
- The Storage Crafting Interface can now be detected by the Smart Interact cursor
- Upgraded Storage Unit tiles can now be stood on
- The Use Player Inventory Items and Use Non-Favorited Player Inventory Items modules from the Storage Configuration Interface will now also read from the player's Void Vault / Void Bag if the player's main inventory has an Open Void Bag
- Items considered infinite by the Storage Crafting Interface — e.g. from the Creative Storage Unit — are now skipped when checking for ingredient requirements and consuming ingredients
- Massively overhauled the server auditing system
- Storage actions — item depositing, item withdrawing and many more — are now added to a new
.ms.audit
file next to the world file- This file has a custom, disk space efficient, binary format
- A more human-readable audit log can be generated by using the
/msaudit
command- Requires entering in the server console (
msaudit
) or the Server Administrator status - Generated file will be an
.ms.audit.txt
file
- Requires entering in the server console (
- The audit log can be cleared via the
/msauditclear
command- Also requires entering in the server console (
msauditclear
) or the Server Administrator status
- Also requires entering in the server console (
- Selecting a recipe already present in the Crafting UI's Recipe History will no longer clear other recipe entries in the history after it
- The panel for the Crafting UI's Recipe History is now fully opaque
- Added a new "global" whitelist and blacklist for recipes that carries over between characters (Thanks to
@buzzers
on Discord)- To add or remove a recipe, use
Ctrl + Shift + Left Click
- To add or remove a recipe, use
- Fixed a very old oversight where holding
Shift
over an inventory item slot while viewing the Storage or Crafting UI would show the "trash can" cursor instead of the "item to chest" cursor - The Ingredients item slots area now has a scroll bar and a maximum row count of 3 to 8 depending on the game's window height and UI Scale
- The layout of the UIs will try to be forced to Modern Paged if there isn't enough vertical space to properly display them
- If doing so allowed the UI to display properly, a new error is printed to the chat
- Otherwise, the existing "UI panel was too short" error is printed
- Empty item slots (aka "air items") in storage are no longer displayed to the user
- Improved the appearance of some of the scroll bars
- Accessing a Storage Access or Storage Crafting Interface or Storage Configuration Interface no longer requires a connected Storage heart
- An error is still printed to the chat
- Enabling Item Deletion Mode will now automatically forces the Storage UI to go to its Storage page
- Changing recipes in the Crafting UI will now reset the bulk crafting amount to 1
- A Storage Heart and its connected storage components can be assigned a name via the Controls tab of the Storage UI
- Storage Aether Interface
- Obtained by dropping a Storage Crafting Interface into Shimmer
- Contains a new UI for handling shimmering actions: decrafting items, transmuting items, sacrificing coins for Coin Luck and spawning NPCs from items
- The Automaton has new help tips for:
- Describing some of the new content
- Entering the Aether biome for the first time
- Useful hotkeys for easier usage of the text prompts
- The Automaton's happiness can now affect the value of items sold via Item Selling Mode
- Worse happiness = less value
- This can be disabled via an option in the Magic Storage Server Config
- New filter option: Filter Misc Gameplay Items
- Boss summons, magic mirrors and other "gameplay" items
- New filter option: Filter Fishing Items
- Fishing rods, bait and any vanilla Terraria items that affect fishing power or do things when fishing
- Filter options can now be classified as "general filters"
- Acts as a whitelist rather than a blacklist
- Multiple general filters can be selected at once
- E.g. Filter Ranged Weapons + Filter Stackables + Filter Not Fully Researched
- Reimplemented previously-removed filter options Filter Stackables and Filter Unstackables as general filters
- Massive overhaul of the previous Sell Duplicates submenu in the Controls page of the Storage UI
- Select an item to set the quantity of the item to sell
- Click the Sell button to sell the selected items and exist Item Selling Mode
- The "core" of a Storage Unit can be extracted by the new Storage Core Wrench
- The Storage Unit is then turned into an Empty Storage Unit
- Right clicking an Empty Storage Unit with an extracted Storage Unit Core will insert it
- Each storage tier has its own unique Storage Unit Core
- A Storage Unit Core contains the item data for a Storage Unit, allowing for mass relocation of storage even between worlds
- A Storage Heart can be assigned to a "security network" via the new Storage Security Wand
- Left click a Storage Heart with a Storage Security Wand to open the new Security UI
- Create new networks, destroy existing networks, or modify them
- Only the creator of a network can modify it
- Double click a network in the network list to assign it to the Storage Heart that was used to open the Security UI
- Not having access to a security network and attempting to access storage components of a Storage Heart assigned to the network will require a password
- The creator of the network and Server Administrators can always access it, however
- The icons for many of the filter icons are now properly centered
- The text in the mod search buttons (located under the text search prompts) in the UIs is now vertically centered
- Updated the Automaton's help tip for the Storage Configuration Interface to be actually helpful and mention its recipe
- The Server Operator commands now specify that they are for Magic Storage purposes only
- The Storage Access now has a tile entity
- Worlds created before the v0.7 update will attempt to spawn entities for Storage Access tiles on first load
- If this fails, just destroy and re-place the Storage Access
- If Fargo's Mutants Mod is enabled, the recipe for the Combined Stations (Final Tier) item now requires a Golden Dipping Vat
- It will also count as a Golden Dipping Vat for crafting purposes
- The Filter Summons filter option has been renamed to Filter Summon Weapons and no longer filters "gameplay" items, pets, mounts and minecarts
- The Filter Equipment and Filter Armor and Equipment filter options now filter pets, mounts and minecarts
- The Filter Tools filter option now filter fishing poles when the Display extra sorting icons config option is disabled
- The Filter Fully Researched and Filter Not Fully Researched filter options are now general filters
- Replaced all mentions of a Crafting Access in the English localizations with the proper name Crafting Interface
- Added game tips during world creation and loading that explain features for Magic Storage
- Updated the error message that's thrown when detecting invalid recipes during mod loading
- Renamed some commands:
/reqop
⇒/msreqop
/op
⇒/msop
/deop
⇒/msdeop
- Constructor was made hidden to encourage modders to use
CraftingGUI.GetCurrentInventory()
instead
- Now obsolete, replaced by
MagicStorage.CrossMod.StorageAggregator
static bool SimulatingCrafts { get; }
virtual IEnumerable<int> GetInfiniteItems(EnvironmentSandbox sandbox)
MagicStorage.Common.Systems.HiddenRecipes
- Contains a list of recipes that should never appear in the Storage Crafting Interface
bool HideRecipe(Recipe recipe)
bool HideRecipeResult(int resultItem)
bool IsHidden(Recipe recipe)
- Contains a set of item IDs that should never be consumed when crafting in a Storage Crafting Interface
static bool AddInfiniteIngredient(int type)
static bool IsConsideredInfinite(int type)
HashSet<int> GetInfiniteItems()
static void BlockRecipeRecursionFor(Recipe recipe)
virtual bool GetGlowmask(int x, int y, int type, int frameX, int frameY, out Asset<Texture2D> asset, out Color drawColor)
- Handles adding extra items when crafting certain recipes
static void RegisterDrop(Recipe recipe, IItemDropRule rule)
static void RegisterDrop(Func<Recipe, bool> condition, IItemDropRule rule)
static List<Item> GetSimulatedDrops(Recipe recipe)
virtual bool IsGeneralFilter { get; }
- Enables finer control over whether storage systems can combine stacks of items
int Type { get; }
virtual bool AppliesToItem(Item item)
virtual bool? CanAggregateItems(Item destination, Item checking)
virtual void SelectData(ModItem item, TagCompound tag)
virtual void SelectGlobalData(GlobalItem item, TagCompound tag)
static bool CanCombineItems(Item destination, Item checking, bool checkPrefix = true)
static bool CanCombineItems(Item destination, Item checking, bool checkPrefix, bool strict, ConditionalWeakTable<Item, byte[]> savedItemTagIO)
- The base class for defining custom Storage Unit tiers
- An example implementation of this can be found here
int Type { get; }
abstract int UpgradeItemType { get; }
abstract int CoreItemType { get; }
abstract int Capacity { get; }
abstract int StorageUnitItemType { get; }
abstract int StorageUnitTileType { get; }
virtual int ItemPlaceStyle { get; }
IReadOnlyList<StorageUnitTier> NextTiers { get; }
bool CanUpgradeTo(StorageUnitTier other)
void SetUpgradeableTo(StorageUnitTier nextTier)
void SetUpgradeableFrom(StorageUnitTier previousTier)
void RemoveConnections(StorageUnitTier adjacentTier)
void RemoveAllConnections()
abstract bool IsValidTile(int frameX, int frameY)
abstract void Frame(StorageUnitFullness fullness, bool active, out int frameX, out int frameY)
abstract void GetState(int frameX, int frameY, out StorageUnitFullness fullness, out bool active)
static StorageUnitTier Basic { get; }
static StorageUnitTier Demonite { get; }
static StorageUnitTier Crimtane { get; }
static StorageUnitTier Hellstone { get; }
static StorageUnitTier Hallowed { get; }
static StorageUnitTier BlueChlorophyte { get; }
static StorageUnitTier Luminite { get; }
static StorageUnitTier Terra { get; }
static StorageUnitTier Empty { get; }
- An
enum
containing states for the fullness of a Storage Unit Empty
,PartiallyFull
,Full
- The loader class for
StorageUnitTier
static int Count { get; }
static StorageUnitTier Get(int type)
static StorageUnitTier FindFromCoreItem(BaseStorageCore core)
static StorageUnitTier FindFromUpgradeItem(BaseStorageUpgradeItem upgradeItem)
static StorageUnitTier FindFromTile(int x, int y)
static StorageUnitTier FindFromTileFrame(int type, int frameX, int frameY)
- A modifier for
StorageUnitTier
instances int Type { get; }
virtual void ModifyUpgradeConnections(StorageUnitTier tier)
- The loader class for
StorageTierModifier
static int Count { get; }
static StorageTierModifier Get(int type)
- Contains constant IDs for each help tip that the Automaton has
static string GetHelpKey(int id)
static string GetHelpText(int id)
static int GetHelpItem(int id)
static bool IsOptionAvailable(int id)
Call("Add Extra Craft Drop", Recipe recipe, IItemDropRule rule)
Call("Add Extra Craft Drop", Func<Recipe, bool> condition, IItemDropRule rule)
Call("Block Recursion", Recipe recipe)
Call("Add Infinite Ingredient", int itemID)
Call("Create Aggregator", Mod mod, string name, Func<Item, bool> appliesToItem, Func<Item, Item, bool?> canAggregateItems = null, Action<ModItem, TagCompound> selectData = null, Action<GlobalItem, TagCompound> selectGlobalData = null)
Call("Hide Recipe", Recipe recipe)
Call("Hide Recipe Result", int resultItem)
Call("Is Ingredient Infinite", int itemID)
Call("Is Recipe Hidden", Recipe recipe)
Call("Simulating Crafts")