예제 #1
0
        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
			};
		}
예제 #3
0
    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);
      }
    }
예제 #4
0
        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"));
        }
예제 #5
0
		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();
		}
예제 #6
0
        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 + ',');
            }
              }
        }
예제 #7
0
        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};
              };
        }
예제 #10
0
        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);
        }
예제 #11
0
        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];
              }
        }
예제 #12
0
        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];
        }
예제 #13
0
        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;
        }
예제 #15
0
    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.");
      }
    }
예제 #16
0
        public Item ToItem()
        {
            Item item = new Item();
              item.netDefaults((int)this.Type);
              item.Prefix((int)this.Prefix);
              item.stack = this.StackSize;

              return item;
        }
예제 #17
0
        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;
        }
예제 #18
0
        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];
        }
예제 #19
0
 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);
 }
예제 #20
0
 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();
     }
 }
예제 #21
0
        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];
              }
            }
              }
        }