public static void LoadLegacy(Item item, BinaryReader reader, bool readStack = false, bool readFavorite = false) { string modName = reader.ReadString(); bool hasGlobalSaving = false; if (modName.Length == 0) { hasGlobalSaving = true; modName = reader.ReadString(); } if (modName == "Terraria") { item.netDefaults(reader.ReadInt32()); LoadLegacyModData(item, LegacyModData(item.type, reader, hasGlobalSaving), hasGlobalSaving); } else { string itemName = reader.ReadString(); int type = ModLoader.GetMod(modName)?.ItemType(itemName) ?? 0; byte[] data = LegacyModData(type == 0 ? int.MaxValue : type, reader, hasGlobalSaving); if (type != 0) { item.netDefaults(type); LoadLegacyModData(item, data, hasGlobalSaving); } else { item.netDefaults(ModLoader.GetMod("ModLoader").ItemType("MysteryItem")); var tag = new TagCompound { ["mod"] = modName, ["name"] = itemName, ["hasGlobalSaving"] = hasGlobalSaving, ["legacyData"] = data }; ((MysteryItem)item.modItem).Setup(tag); } } item.Prefix(reader.ReadByte()); if (readStack) item.stack = reader.ReadInt32(); if (readFavorite) item.favorited = reader.ReadBoolean(); }
TextSnippet ITagHandler.Parse(string text, Color baseColor, string options) { Item item = new Item(); int type; if (int.TryParse(text, out type)) { item.netDefaults(type); } else { item.SetDefaults(text); } if (item.type <= 0) { return new TextSnippet(text); } item.stack = 1; if (options != null) { string[] array = options.Split(new char[] { ',' }); for (int i = 0; i < array.Length; i++) { if (array[i].Length != 0) { char c = array[i][0]; int value2; if (c != 'p') { int value; if ((c == 's' || c == 'x') && int.TryParse(array[i].Substring(1), out value)) { item.stack = Utils.Clamp<int>(value, 1, item.maxStack); } } else if (int.TryParse(array[i].Substring(1), out value2)) { item.Prefix((int)((byte)Utils.Clamp<int>(value2, 0, 84))); } } } } string str = ""; if (item.stack > 1) { str = " (" + item.stack + ")"; } return new ItemTagHandler.ItemSnippet(item) { Text = "[" + item.AffixName() + str + "]", CheckForHover = true, DeleteWhole = true }; }
public void Add(ItemData?[] updates, int itemType, int stack, int prefixType = -1) { Contract.Requires<ArgumentNullException>(updates != null); Contract.Requires<ArgumentOutOfRangeException>(updates.Length == this.Items.Count); Contract.Requires<ArgumentException>(stack > 0); Item itemInfo = new Item(); itemInfo.netDefaults(itemType); if (stack > itemInfo.maxStack) throw new ArgumentException("Stack size can not be greater than the maximum."); // would never need more than one empty slot var emptySlotIndex = -1; bool isStackable = itemInfo.maxStack != 1; // except platinum coins because there is no special stacking with them bool isCoin = TerrariaUtils.Items.IsCoinType((ItemType)itemType) && itemType != ItemID.PlatinumCoin; // this variable is just to measure whether the item fits at all int remainingStack = stack; for (int i = 0; i < this.Items.Count; i++) { ItemData invItem = updates[i] ?? this.Items[i]; // the slot is either marked to be removed by the updates or is currently empty and not going to be filled by the updates if (invItem == ItemData.None) { bool isPreferred = false; var itemsAdapter = this.Items as ItemsAdapter; if (itemsAdapter != null) isPreferred = itemsAdapter.PreferredSlotIndexes(invItem.Type).Contains(i); emptySlotIndex = (isPreferred || emptySlotIndex == -1) ? i : emptySlotIndex; if (!isStackable) break; } else if (isStackable && (int)invItem.Type == itemType) { int newStack = Math.Min(invItem.StackSize + remainingStack, itemInfo.maxStack); int stackToAdd = newStack - invItem.StackSize; remainingStack -= stackToAdd; // a special case are coins if a stack is full if (isCoin && newStack == itemInfo.maxStack) updates[i] = new ItemData((ItemType)TerrariaUtils.Items.GetHigherTierCoinType(itemType)); else updates[i] = new ItemData(invItem.Type, newStack); Contract.Assert(remainingStack >= 0); if (remainingStack == 0 && !isCoin) return; } } if (remainingStack > 0) { if (emptySlotIndex == -1) throw new InvalidOperationException("Inventory is full."); updates[emptySlotIndex] = new ItemData((ItemPrefix)prefixType, (ItemType)itemType, remainingStack); } }
public static void Load(Item item, TagCompound tag) { if (tag.Count == 0) { item.netDefaults(0); return; } string modName = tag.GetString("mod"); if (modName == "Terraria") { item.netDefaults(tag.GetInt("id")); if (tag.HasTag("legacyData")) LoadLegacyModData(item, tag.GetByteArray("legacyData"), tag.GetBool("hasGlobalSaving")); } else { int type = ModLoader.GetMod(modName)?.ItemType(tag.GetString("name")) ?? 0; if (type > 0) { item.netDefaults(type); if (tag.HasTag("legacyData")) LoadLegacyModData(item, tag.GetByteArray("legacyData"), tag.GetBool("hasGlobalSaving")); else item.modItem.Load(tag.GetCompound("data")); } else { item.netDefaults(ModLoader.GetMod("ModLoader").ItemType("MysteryItem")); ((MysteryItem)item.modItem).Setup(tag); } } item.Prefix(tag.GetByte("prefix")); item.stack = tag.GetTag<int?>("stack") ?? 1; item.favorited = tag.GetBool("fav"); if (!(item.modItem is MysteryItem)) LoadGlobals(item, tag.GetList<TagCompound>("globalData")); }
public static void ReadItem(Item item, BinaryReader reader, bool readStack = false, bool readFavorite = false) { string modName = reader.ReadString(); bool hasGlobalSaving = false; if (modName.Length == 0) { hasGlobalSaving = true; modName = reader.ReadString(); } if (modName == "Terraria") { item.netDefaults(reader.ReadInt32()); ReadCustomData(item, GetCustomData(item.type, reader, hasGlobalSaving), hasGlobalSaving); } else { string itemName = reader.ReadString(); int type = ModLoader.GetMod(modName)?.ItemType(itemName) ?? 0; byte[] data = GetCustomData(type == 0 ? Int32.MaxValue : type, reader, hasGlobalSaving); if (type != 0) { item.netDefaults(type); ReadCustomData(item, data, hasGlobalSaving); } else { item.netDefaults(ModLoader.GetMod("ModLoader").ItemType("MysteryItem")); ((MysteryItem)item.modItem).Setup(modName, itemName, data, hasGlobalSaving); } } item.Prefix(reader.ReadByte()); if (readStack) item.stack = reader.ReadInt32(); if (readFavorite) item.favorited = reader.ReadBoolean(); }
public void DebugPrintCreatedWallIdList() { for (int i = TerrariaUtils.ItemType_Min; i < TerrariaUtils.ItemType_Max + 1; i++) { Item dummyItem = new Item(); dummyItem.netDefaults(i); if (!string.IsNullOrEmpty(dummyItem.name) && dummyItem.createWall != -1) { string itemName = dummyItem.name; itemName = itemName.Replace(" ", ""); itemName = itemName.Replace("'", ""); itemName = itemName.Replace("´", ""); itemName = itemName.Replace("`", ""); Debug.Print(itemName + " = " + dummyItem.createWall + ','); } } }
public void DebugPrintItemIdList() { for (int i = TerrariaUtils.ItemType_Min; i < TerrariaUtils.ItemType_Max + 1; i++) { Item dummyItem = new Item(); dummyItem.netDefaults(i); string itemName; if (string.IsNullOrEmpty(dummyItem.name)) { itemName = "NullOrEmpty"; } else { itemName = dummyItem.name; itemName = itemName.Replace(" ", ""); itemName = itemName.Replace("'", ""); itemName = itemName.Replace("´", ""); itemName = itemName.Replace("`", ""); } Debug.Print(itemName + " = " + i + ','); } }
public bool HandleChestGetContents(TSPlayer player, DPoint location, bool skipInteractions) { if (this.IsDisposed) return false; if (!skipInteractions && base.HandleChestGetContents(player, location)) return true; bool isDummyChest = (location.X == 0); if (isDummyChest) return true; if (!TerrariaUtils.Tiles[location].active()) return true; if (this.Config.LoginRequiredForChestUsage && !player.IsLoggedIn) { player.SendErrorMessage("You have to be logged in to make use of chests."); return true; } if (this.Config.DungeonChestProtection && !NPC.downedBoss3 && !player.Group.HasPermission(ProtectorPlugin.ProtectionMaster_Permission)) { ChestKind kind = TerrariaUtils.Tiles.GuessChestKind(location); if (kind == ChestKind.DungeonChest || kind == ChestKind.HardmodeDungeonChest) { player.SendErrorMessage("Skeletron has not been defeated yet."); return true; } } ProtectionEntry protection = null; // Only need the first enumerated entry as we don't need the protections of adjacent blocks. foreach (ProtectionEntry enumProtection in this.ProtectionManager.EnumerateProtectionEntries(location)) { protection = enumProtection; break; } DPoint chestLocation = TerrariaUtils.Tiles.MeasureObject(location).OriginTileLocation; IChest chest = this.ChestManager.ChestFromLocation(chestLocation, player); if (chest == null) return true; if (this.IsChestInUse(player, chest)) { player.SendErrorMessage("Another player is already viewing the content of this chest."); return true; } if (protection != null) { bool isTradeChest = (protection.TradeChestData != null); if (!this.ProtectionManager.CheckProtectionAccess(protection, player)) { if (isTradeChest) this.InitTrade(player, chest, protection); else player.SendErrorMessage("This chest is protected."); return true; } if (isTradeChest) { Item sellItem = new Item(); sellItem.netDefaults(protection.TradeChestData.ItemToSellId); sellItem.stack = protection.TradeChestData.ItemToSellAmount; Item payItem = new Item(); payItem.netDefaults(protection.TradeChestData.ItemToPayId); payItem.stack = protection.TradeChestData.ItemToPayAmount; player.SendMessage($"This is a trade chest selling {TShock.Utils.ItemTag(sellItem)} for {TShock.Utils.ItemTag(payItem)}", Color.OrangeRed); player.SendMessage("You have access to it, so you can modify it any time.", Color.LightGray); } if (protection.RefillChestData != null) { RefillChestMetadata refillChest = protection.RefillChestData; if (this.CheckRefillChestLootability(refillChest, player)) { if (refillChest.OneLootPerPlayer) player.SendMessage("You can loot this chest a single time only.", Color.OrangeRed); } else { return true; } if (refillChest.RefillTime != TimeSpan.Zero) { lock (this.ChestManager.RefillTimers) { if (this.ChestManager.RefillTimers.IsTimerRunning(refillChest.RefillTimer)) { TimeSpan timeLeft = (refillChest.RefillStartTime + refillChest.RefillTime) - DateTime.Now; player.SendMessage($"This chest will refill in {timeLeft.ToLongString()}.", Color.OrangeRed); } else { player.SendMessage("This chest will refill its content.", Color.OrangeRed); } } } else { player.SendMessage("This chest will refill its content.", Color.OrangeRed); } } } lock (ChestManager.DummyChest) { Main.chest[ChestManager.DummyChestIndex] = ChestManager.DummyChest; if (chest.IsWorldChest) { ChestManager.DummyChest.name = chest.Name; player.TPlayer.chest = chest.Index; } else { player.TPlayer.chest = -1; } for (int i = 0; i < Chest.maxItems; i++) { ChestManager.DummyChest.item[i] = chest.Items[i].ToItem(); player.SendData(PacketTypes.ChestItem, string.Empty, ChestManager.DummyChestIndex, i); } ChestManager.DummyChest.x = chestLocation.X; ChestManager.DummyChest.y = chestLocation.Y; player.SendData(PacketTypes.ChestOpen, string.Empty, ChestManager.DummyChestIndex); ChestManager.DummyChest.x = 0; } DPoint oldChestLocation; if (this.PlayerIndexChestDictionary.TryGetValue(player.Index, out oldChestLocation)) { this.PlayerIndexChestDictionary.Remove(player.Index); this.ChestPlayerIndexDictionary.Remove(oldChestLocation); } if (!chest.IsWorldChest) { this.PlayerIndexChestDictionary[player.Index] = chestLocation; this.ChestPlayerIndexDictionary[chestLocation] = player.Index; } return false; }
private void InitTrade(TSPlayer player, IChest chest, ProtectionEntry protection) { TradeChestMetadata tradeChestData = protection.TradeChestData; Item sellItem = new Item(); sellItem.netDefaults(tradeChestData.ItemToSellId); sellItem.stack = tradeChestData.ItemToSellAmount; Item payItem = new Item(); payItem.netDefaults(tradeChestData.ItemToPayId); payItem.stack = tradeChestData.ItemToPayAmount; player.SendMessage($"This is a trade chest owned by {TShock.Utils.ColorTag(GetUserName(protection.Owner), Color.Red)}.", Color.LightGray); Inventory chestInventory = new Inventory(chest.Items, specificPrefixes: false); int stock = chestInventory.Amount(sellItem.netID); if (stock < sellItem.stack) { player.SendMessage($"It was trading {TShock.Utils.ItemTag(sellItem)} for {TShock.Utils.ItemTag(payItem)} but it is out of stock.", Color.LightGray); return; } player.SendMessage($"Click again to purchase {TShock.Utils.ItemTag(sellItem)} for {TShock.Utils.ItemTag(payItem)}", Color.LightGray); CommandInteraction interaction = this.StartOrResetCommandInteraction(player); interaction.ChestOpenCallback += (playerLocal, chestLocation) => { bool complete; bool wasThisChestHit = (chestLocation == chest.Location); if (wasThisChestHit) { // this is important to check, otherwise players could use trade chests to easily duplicate items if (!this.IsChestInUse(playerLocal, chest)) this.PerformTrade(player, protection, chestInventory, sellItem, payItem); else player.SendErrorMessage("Another player is currently viewing the content of this chest."); complete = false; } else { this.HandleChestGetContents(playerLocal, chestLocation, skipInteractions: true); complete = true; } playerLocal.SendTileSquare(chest.Location); return new CommandInteractionResult {IsHandled = true, IsInteractionCompleted = complete}; }; }
public bool IsWeaponType(ItemType itemType) { if ((int)itemType < TerrariaUtils.ItemType_Min || (int)itemType > TerrariaUtils.ItemType_Max) throw new ArgumentException(string.Format("The given item type {0} is invalid.", itemType), "itemType"); if (TerrariaItems.weaponTypes == null) { TerrariaItems.weaponTypes = new List<ItemType>(20); for (int i = TerrariaUtils.ItemType_Min; i < TerrariaUtils.ItemType_Max + 1; i++) { Item dummyItem = new Item(); dummyItem.netDefaults(i); if (!string.IsNullOrEmpty(dummyItem.name) && dummyItem.damage > 0 && dummyItem.ammo == 0) TerrariaItems.weaponTypes.Add((ItemType)i); } } return TerrariaItems.weaponTypes.Contains(itemType); }
public bool IsEquipableType(ItemType itemType) { if ((int)itemType < TerrariaUtils.ItemType_Min || (int)itemType > TerrariaUtils.ItemType_Max) throw new ArgumentException(string.Format("The given item type {0} is invalid.", itemType), "itemType"); if (TerrariaItems.equipableItemTypes == null) { TerrariaItems.equipableItemTypes = new bool[TerrariaUtils.ItemType_Max + 1 + Math.Abs(TerrariaUtils.ItemType_Min)]; for (int i = TerrariaUtils.ItemType_Min; i < TerrariaUtils.ItemType_Max + 1; i++) { Item dummyItem = new Item(); dummyItem.netDefaults(i); if ( !string.IsNullOrEmpty(dummyItem.name) && !dummyItem.vanity && ( dummyItem.headSlot != -1 || dummyItem.bodySlot != -1 || dummyItem.legSlot != -1 || dummyItem.accessory ) ) { int index = i; if (index < 0) index += TerrariaUtils.ItemType_Max; TerrariaItems.equipableItemTypes[index] = true; } } } { int index = (int)itemType; if (index < 0) index += TerrariaUtils.ItemType_Max; return TerrariaItems.equipableItemTypes[index]; } }
public ItemType GetItemTypeFromWallType(WallType wallType) { if ((int)wallType < TerrariaUtils.WallType_Min || (int)wallType > TerrariaUtils.WallType_Max) throw new ArgumentException(string.Format("The given item type {0} is invalid.", wallType), "wallType"); if (TerrariaItems.wallTypesItemTypes == null) { TerrariaItems.wallTypesItemTypes = new ItemType[TerrariaUtils.WallType_Max + 1]; for (int i = TerrariaUtils.ItemType_Min; i < TerrariaUtils.WallType_Max + 1; i++) { Item dummyItem = new Item(); dummyItem.netDefaults(i); if (!string.IsNullOrEmpty(dummyItem.name) && dummyItem.createWall != -1) TerrariaItems.wallTypesItemTypes[dummyItem.createWall] = (ItemType)i; } } return TerrariaItems.wallTypesItemTypes[(int)wallType]; }
public void SetUpTradeChest(TSPlayer player, DPoint tileLocation, int sellAmount, int sellItemId, int payAmount, int payItemId, int lootLimit = 0, bool checkPermissions = false) { Contract.Requires<ArgumentNullException>(player != null); Contract.Requires<ArgumentException>(TerrariaUtils.Tiles[tileLocation] != null, "tileLocation"); Contract.Requires<ArgumentException>(TerrariaUtils.Tiles[tileLocation].active(), "tileLocation"); Contract.Requires<ArgumentOutOfRangeException>(sellAmount > 0, "sellAmount"); Contract.Requires<ArgumentOutOfRangeException>(payAmount > 0, "payAmount"); Item itemInfo = new Item(); itemInfo.netDefaults(sellItemId); if (sellAmount > itemInfo.maxStack) throw new ArgumentOutOfRangeException("sellAmount"); itemInfo.netDefaults(payItemId); if (payAmount > itemInfo.maxStack) throw new ArgumentOutOfRangeException("payAmount"); Tile tile = TerrariaUtils.Tiles[tileLocation]; BlockType blockType = (BlockType)tile.type; if (blockType != BlockType.Chest && blockType != BlockType.Dresser) throw new InvalidBlockTypeException(blockType); if (checkPermissions && !player.Group.HasPermission(ProtectorPlugin.SetTradeChests_Permission)) throw new MissingPermissionException(ProtectorPlugin.SetTradeChests_Permission); DPoint chestLocation = TerrariaUtils.Tiles.MeasureObject(tileLocation).OriginTileLocation; ProtectionEntry protection; lock (this.WorldMetadata.Protections) if (!this.WorldMetadata.Protections.TryGetValue(chestLocation, out protection)) throw new NoProtectionException(chestLocation); if (protection.BankChestKey != BankChestDataKey.Invalid) throw new ChestIncompatibilityException(); IChest chest = this.ChestFromLocation(chestLocation); if (chest == null) throw new NoChestDataException(chestLocation); bool isNewTradeChest = (protection.TradeChestData == null); if (isNewTradeChest && checkPermissions && this.CooperationHandler.IsSeconomyAvailable && !player.Group.HasPermission(ProtectorPlugin.FreeTradeChests_Permision)) { if (this.CooperationHandler.Seconomy_GetBalance(player.Name) < this.Config.TradeChestPayment) throw new PaymentException(this.Config.TradeChestPayment); this.CooperationHandler.Seconomy_TransferToWorld(player.Name, this.Config.TradeChestPayment, "Trade Chest", "Setup Price"); } protection.TradeChestData = protection.TradeChestData ?? new TradeChestMetadata(); protection.TradeChestData.ItemToSellAmount = sellAmount; if (protection.TradeChestData.ItemToSellId != sellItemId) protection.TradeChestData.LootersTable.Clear(); protection.TradeChestData.ItemToSellId = sellItemId; protection.TradeChestData.ItemToPayAmount = payAmount; protection.TradeChestData.ItemToPayId = payItemId; protection.TradeChestData.LootLimitPerPlayer = lootLimit; this.PluginTrace.WriteLineVerbose($"{player.Name} just setup a trade chest selling {sellAmount}x {sellItemId} for {payAmount}x {payItemId} with a limit of {lootLimit} at {tileLocation}"); }
private bool TryGetProtectionInfo(TSPlayer player, DPoint tileLocation, bool sendFailureMessages = true) { Tile tile = TerrariaUtils.Tiles[tileLocation]; if (!tile.active()) return false; ProtectionEntry protection = null; // Only need the first enumerated entry as we don't need the protections of adjacent blocks. foreach (ProtectionEntry enumProtection in this.ProtectionManager.EnumerateProtectionEntries(tileLocation)) { protection = enumProtection; break; } BlockType blockType = (BlockType)TerrariaUtils.Tiles[tileLocation].type; if (protection == null) { if (sendFailureMessages) player.SendErrorMessage($"This {TerrariaUtils.Tiles.GetBlockTypeName(blockType)} is not protected by Protector at all."); return false; } bool canViewExtendedInfo = ( player.Group.HasPermission(ProtectorPlugin.ViewAllProtections_Permission) || protection.Owner == player.User.ID || protection.IsSharedWithPlayer(player) ); if (!canViewExtendedInfo) { player.SendMessage($"This {TerrariaUtils.Tiles.GetBlockTypeName(blockType)} is protected and not shared with you.", Color.LightGray); player.SendWarningMessage("You are not permitted to get more information about this protection."); return true; } string ownerName; if (protection.Owner == -1) ownerName = "{Server}"; else ownerName = GetUserName(protection.Owner); player.SendMessage($"This {TerrariaUtils.Tiles.GetBlockTypeName(blockType)} is protected. The owner is {TShock.Utils.ColorTag(ownerName, Color.Red)}.", Color.LightGray); string creationTimeFormat = "unknown"; if (protection.TimeOfCreation != DateTime.MinValue) creationTimeFormat = "{0:MM/dd/yy, h:mm tt} UTC ({1} ago)"; player.SendMessage( string.Format( CultureInfo.InvariantCulture, "Protection created On: " + creationTimeFormat, protection.TimeOfCreation, (DateTime.UtcNow - protection.TimeOfCreation).ToLongString() ), Color.LightGray ); if (blockType == BlockType.Chest || blockType == BlockType.Dresser) { if (protection.RefillChestData != null) { RefillChestMetadata refillChest = protection.RefillChestData; if (refillChest.RefillTime != TimeSpan.Zero) player.SendMessage($"This is a refill chest with a timer set to {TShock.Utils.ColorTag(refillChest.RefillTime.ToLongString(), Color.Red)}.", Color.LightGray); else player.SendMessage("This is a refill chest without a timer.", Color.LightGray); if (refillChest.OneLootPerPlayer || refillChest.RemainingLoots != -1) { StringBuilder messageBuilder = new StringBuilder(); messageBuilder.Append("It can only be looted "); if (refillChest.OneLootPerPlayer) messageBuilder.Append("one time by each player"); if (refillChest.RemainingLoots != -1) { if (messageBuilder.Length > 0) messageBuilder.Append(" and "); messageBuilder.Append(TShock.Utils.ColorTag(refillChest.RemainingLoots.ToString(), Color.Red)); messageBuilder.Append(" more times in total"); } if (refillChest.Looters != null) { messageBuilder.Append(" and was looted "); messageBuilder.Append(TShock.Utils.ColorTag(refillChest.Looters.Count.ToString(), Color.Red)); messageBuilder.Append(" times until now"); } messageBuilder.Append('.'); player.SendMessage(messageBuilder.ToString(), Color.LightGray); } } else if (protection.BankChestKey != BankChestDataKey.Invalid) { BankChestDataKey bankChestKey = protection.BankChestKey; player.SendMessage($"This is a bank chest instance with the number {bankChestKey.BankChestIndex}.", Color.LightGray); } else if (protection.TradeChestData != null) { Item sellItem = new Item(); sellItem.netDefaults(protection.TradeChestData.ItemToSellId); sellItem.stack = protection.TradeChestData.ItemToSellAmount; Item payItem = new Item(); payItem.netDefaults(protection.TradeChestData.ItemToPayId); payItem.stack = protection.TradeChestData.ItemToPayAmount; player.SendMessage($"This is a trade chest. It's selling {TShock.Utils.ItemTag(sellItem)} for {TShock.Utils.ItemTag(payItem)}", Color.LightGray); } IChest chest = this.ChestManager.ChestFromLocation(protection.TileLocation); if (chest.IsWorldChest) player.SendMessage($"It is stored as part of the world data (id: {TShock.Utils.ColorTag(chest.Index.ToString(), Color.Red)}).", Color.LightGray); else player.SendMessage($"It is {TShock.Utils.ColorTag("not", Color.Red)} stored as part of the world data.", Color.LightGray); } if (ProtectionManager.IsShareableBlockType(blockType)) { if (protection.IsSharedWithEveryone) { player.SendMessage("Protection is shared with everyone.", Color.LightGray); } else { StringBuilder sharedListBuilder = new StringBuilder(); if (protection.SharedUsers != null) { for (int i = 0; i < protection.SharedUsers.Count; i++) { if (i > 0) sharedListBuilder.Append(", "); TShockAPI.DB.User tsUser = TShock.Users.GetUserByID(protection.SharedUsers[i]); if (tsUser != null) sharedListBuilder.Append(tsUser.Name); } } if (sharedListBuilder.Length == 0 && protection.SharedGroups == null) { player.SendMessage($"Protection is {TShock.Utils.ColorTag("not", Color.Red)} shared with users or groups.", Color.LightGray); } else { if (sharedListBuilder.Length > 0) player.SendMessage($"Shared with users: {TShock.Utils.ColorTag(sharedListBuilder.ToString(), Color.Red)}", Color.LightGray); else player.SendMessage($"Protection is {TShock.Utils.ColorTag("not", Color.Red)} shared with users.", Color.LightGray); if (protection.SharedGroups != null) player.SendMessage($"Shared with groups: {TShock.Utils.ColorTag(protection.SharedGroups.ToString(), Color.Red)}", Color.LightGray); else player.SendMessage($"Protection is {TShock.Utils.ColorTag("not", Color.Red)} shared with groups.", Color.LightGray); } } } if (protection.TradeChestData != null && protection.TradeChestData.TransactionJournal.Count > 0) { player.SendMessage($"Trade Chest Journal (Last {protection.TradeChestData.TransactionJournal.Count} Transactions)", Color.LightYellow); protection.TradeChestData.TransactionJournal.ForEach(entry => { string entryText = entry.Item1; DateTime entryTime = entry.Item2; TimeSpan timeSpan = DateTime.UtcNow - entryTime; player.SendMessage($"{entryText} {timeSpan.ToLongString()} ago.", Color.LightGray); }); } return true; }
public void Remove(ItemData?[] updates, int itemType, int stack, int prefixType = 0) { Contract.Requires<ArgumentNullException>(updates != null); Contract.Requires<ArgumentOutOfRangeException>(updates.Length == this.Items.Count); Contract.Requires<ArgumentException>(stack > 0); Item itemInfo = new Item(); itemInfo.netDefaults(itemType); // would never need more than one empty slot var emptySlotIndex = -1; int higherTierCoinSlotIndex = -1; // except platinum coins because it is already the highest tier bool isCoin = TerrariaUtils.Items.IsCoinType((ItemType)itemType) && itemType != ItemID.PlatinumCoin; int higherTierCoinType = TerrariaUtils.Items.GetHigherTierCoinType(itemType); int remainingStack = stack; for (int i = 0; i < this.Items.Count; i++) { ItemData invItem = updates[i] ?? this.Items[i]; // the slot is either marked to be removed by the updates or is currently empty and not going to be filled by the updates if (invItem == ItemData.None) { bool isPreferred = false; var itemsAdapter = this.Items as ItemsAdapter; if (itemsAdapter != null) isPreferred = itemsAdapter.PreferredSlotIndexes(invItem.Type).Contains(i); emptySlotIndex = (isPreferred || emptySlotIndex == -1) ? i : emptySlotIndex; // in case we are working with coins here, we might need one stack of the next higher tier coin type later } else if (isCoin && (int)invItem.Type == higherTierCoinType) { higherTierCoinSlotIndex = higherTierCoinSlotIndex != -1 ? higherTierCoinSlotIndex : i; } else if ((int)invItem.Type == itemType && (!specificPrefixes || (int)invItem.Prefix == prefixType)) { int stackReduce = Math.Min(remainingStack, invItem.StackSize); if (stackReduce == invItem.StackSize) emptySlotIndex = i; // prefer the slots which would be emptied over already empty slots invItem.StackSize -= stackReduce; updates[i] = invItem; remainingStack -= stackReduce; Contract.Assert(remainingStack >= 0); if (remainingStack == 0 && !isCoin) break; } } if (remainingStack > 0) { // special handling for coins, e.g. if there's 30 silver left after decrementing all existing silver stacks, then // try to decrement a gold coin stack by one and add the remaining silver as a new stack if (isCoin && higherTierCoinSlotIndex != -1 && emptySlotIndex != -1) { ItemData higherTierItem = updates[higherTierCoinSlotIndex] ?? this.Items[higherTierCoinSlotIndex]; updates[higherTierCoinSlotIndex] = new ItemData(higherTierItem.Type, higherTierItem.StackSize - 1); updates[emptySlotIndex] = new ItemData((ItemType)itemType, 100 - remainingStack); return; } throw new InvalidOperationException("The inventory doesn't contain enough items to remove."); } }
public Item ToItem() { Item item = new Item(); item.netDefaults((int)this.Type); item.Prefix((int)this.Prefix); item.stack = this.StackSize; return item; }
public Item ToItem() { Item item = new Item(); if (this.StackSize > 0) { item.netDefaults((int)this.Type); item.Prefix((int)this.Prefix); item.stack = this.StackSize; } else { item.netDefaults(0); } return item; }
public string GetItemName(ItemData itemData, bool includePrefix = false) { if ((itemData.Prefix != ItemPrefix.None && includePrefix) || itemData.Type < 0) { Item dummyItem = new Item(); dummyItem.netDefaults((int)itemData.Type); dummyItem.prefix = (byte)itemData.Prefix; return dummyItem.AffixName(); } return Main.itemName[(int)itemData.Type]; }
public static void Receive(Item item, BinaryReader reader, bool readStack = false, bool readFavorite = false) { item.netDefaults(reader.ReadInt16()); item.Prefix(reader.ReadByte()); if (readStack) item.stack = reader.ReadInt16(); if (readFavorite) item.favorited = reader.ReadBoolean(); ReceiveModData(item, reader); }
private static void LoadChests(BinaryReader reader) { int num = (int)reader.ReadInt16(); int num2 = (int)reader.ReadInt16(); int num3; int num4; if (num2 < 40) { num3 = num2; num4 = 0; } else { num3 = 40; num4 = num2 - 40; } int i; for (i = 0; i < num; i++) { Chest chest = new Chest(false); chest.x = reader.ReadInt32(); chest.y = reader.ReadInt32(); chest.name = reader.ReadString(); for (int j = 0; j < num3; j++) { short num5 = reader.ReadInt16(); Item item = new Item(); if (num5 > 0) { item.netDefaults(reader.ReadInt32()); item.stack = (int)num5; item.Prefix((int)reader.ReadByte()); } else if (num5 < 0) { item.netDefaults(reader.ReadInt32()); item.Prefix((int)reader.ReadByte()); item.stack = 1; } chest.item[j] = item; } for (int j = 0; j < num4; j++) { short num5 = reader.ReadInt16(); if (num5 > 0) { reader.ReadInt32(); reader.ReadByte(); } } Main.chest[i] = chest; } List<Point16> list = new List<Point16>(); for (int k = 0; k < i; k++) { if (Main.chest[k] != null) { Point16 item2 = new Point16(Main.chest[k].x, Main.chest[k].y); if (list.Contains(item2)) { Main.chest[k] = null; } else { list.Add(item2); } } } while (i < 1000) { Main.chest[i] = null; i++; } if (WorldFile.versionNumber < 115) { WorldFile.FixDresserChests(); } }
public ItemType GetItemTypeFromBlockType(BlockType blockType, int objectStyle = 0) { if ((int)blockType < TerrariaUtils.BlockType_Min || (int)blockType > TerrariaUtils.BlockType_Max) throw new ArgumentException(string.Format("The given block type {0} is invalid.", blockType), "blockType"); if (TerrariaItems.blockTypesItemTypes == null) { TerrariaItems.blockTypesItemTypes = new ItemType[TerrariaUtils.ItemType_Max + 1][]; for (int i = TerrariaUtils.ItemType_Min; i < TerrariaUtils.ItemType_Max + 1; i++) { Item dummyItem = new Item(); dummyItem.netDefaults(i); if (!string.IsNullOrEmpty(dummyItem.name) && dummyItem.createTile != -1) { ItemType[] styleArray = TerrariaItems.blockTypesItemTypes[dummyItem.createTile]; ItemType[] newStyleArray; if (styleArray != null) { newStyleArray = new ItemType[Math.Max(dummyItem.placeStyle + 1, styleArray.Length)]; styleArray.CopyTo(newStyleArray, 0); } else { newStyleArray = new ItemType[dummyItem.placeStyle + 1]; } newStyleArray[dummyItem.placeStyle] = (ItemType)i; TerrariaItems.blockTypesItemTypes[dummyItem.createTile] = newStyleArray; } } } { switch (blockType) { case BlockType.Mannequin: return ItemType.Mannequin; case BlockType.DartTrap: return ItemType.DartTrap; case BlockType.IceBlock: return ItemType.None; default: { ItemType[] styleArray = TerrariaItems.blockTypesItemTypes[(int)blockType]; Contract.Assert(styleArray != null, "BlockType: " + blockType.ToString()); if (objectStyle >= styleArray.Length) throw new ArgumentException(string.Format("There is no item type for block \"{0}\" with object style {1}", blockType, objectStyle)); return styleArray[objectStyle]; } } } }