예제 #1
0
        public IChest PlaceChest(ushort tileType, int style, DPoint placeLocation)
        {
            Contract.Requires <ArgumentException>(tileType == TileID.Containers || tileType == TileID.Containers2 || tileType == TileID.Dressers);

            IChest chest;
            bool   isDresser   = (tileType == TileID.Dressers);
            int    chestIndex  = WorldGen.PlaceChest(placeLocation.X, placeLocation.Y, tileType, false, style);
            bool   isWorldFull = (chestIndex == -1 || chestIndex == ChestManager.DummyChestIndex);

            if (!isWorldFull)
            {
                chest = new ChestAdapter(chestIndex, Main.chest[chestIndex]);
            }
            else
            {
                lock (this.WorldMetadata.ProtectorChests) {
                    isWorldFull = (this.WorldMetadata.ProtectorChests.Count >= this.Config.MaxProtectorChests);
                    if (isWorldFull)
                    {
                        throw new LimitEnforcementException();
                    }

                    if (isDresser)
                    {
                        WorldGen.PlaceDresserDirect(placeLocation.X, placeLocation.Y, tileType, style, chestIndex);
                    }
                    else
                    {
                        WorldGen.PlaceChestDirect(placeLocation.X, placeLocation.Y, tileType, style, chestIndex);
                    }

                    DPoint chestLocation = TerrariaUtils.Tiles.MeasureObject(placeLocation).OriginTileLocation;
                    chest = new ProtectorChestData(chestLocation);
                    this.WorldMetadata.ProtectorChests.Add(chestLocation, (ProtectorChestData)chest);

                    chestIndex = ChestManager.DummyChestIndex;
                }
            }

            int storageType = 0;

            if (isDresser)
            {
                storageType = 2;
            }
            if (tileType == TileID.Containers2)
            {
                storageType = 4;
            }

            TSPlayer.All.SendData(PacketTypes.TileKill, string.Empty, storageType, placeLocation.X, placeLocation.Y, style, chestIndex);
            // The client will always show open / close animations for the latest chest index. But when there are multiple chests with id 999
            // this will look awkard, so instead tell the client about another 999 chest on a location where the animation will never be noticed by the player.
            if (chestIndex == ChestManager.DummyChestIndex)
            {
                TSPlayer.All.SendData(PacketTypes.TileKill, string.Empty, storageType, 0, 0, style, chestIndex);
            }

            return(chest);
        }
예제 #2
0
        public IChest CreateChestData(DPoint chestLocation)
        {
            int  chestIndex  = Chest.CreateChest(chestLocation.X, chestLocation.Y);
            bool isWorldFull = (chestIndex == -1 || chestIndex == ChestManager.DummyChestIndex);

            if (!isWorldFull)
            {
                return(new ChestAdapter(chestIndex, Main.chest[chestIndex]));
            }
            else
            {
                lock (this.WorldMetadata.ProtectorChests) {
                    isWorldFull = (this.WorldMetadata.ProtectorChests.Count >= this.Config.MaxProtectorChests);
                    if (isWorldFull)
                    {
                        throw new LimitEnforcementException();
                    }

                    IChest chest = new ProtectorChestData(chestLocation);
                    this.WorldMetadata.ProtectorChests.Add(chestLocation, (ProtectorChestData)chest);
                    return(chest);
                }
            }
        }
        public bool TrySwapChestData(TSPlayer player, DPoint anyChestTileLocation, out IChest newChest)
        {
            newChest = null;

              if (TerrariaUtils.Tiles[anyChestTileLocation].type != TileID.Containers && TerrariaUtils.Tiles[anyChestTileLocation].type != TileID.Dressers) {
            player.SendErrorMessage("The selected tile is not a chest or dresser.");
            return false;
              }

              DPoint chestLocation = TerrariaUtils.Tiles.MeasureObject(anyChestTileLocation).OriginTileLocation;
              IChest chest = this.ChestManager.ChestFromLocation(chestLocation, player);
              if (chest == null)
            return false;

              ItemData[] content = new ItemData[Chest.maxItems];
              for (int i = 0; i < Chest.maxItems; i++)
            content[i] = chest.Items[i];

              if (chest.IsWorldChest) {
            lock (this.WorldMetadata.ProtectorChests) {
              bool isChestAvailable = this.WorldMetadata.ProtectorChests.Count < this.Config.MaxProtectorChests;
              if (!isChestAvailable) {
            player?.SendErrorMessage("The maximum of possible Protector chests has been reached.");
            return false;
              }

              int playerUsingChestIndex = Chest.UsingChest(chest.Index);
              if (playerUsingChestIndex != -1)
            Main.player[playerUsingChestIndex].chest = -1;

              Main.chest[chest.Index] = null;
              newChest = new ProtectorChestData(chestLocation, content);

              this.WorldMetadata.ProtectorChests.Add(chestLocation, (ProtectorChestData)newChest);

              //TSPlayer.All.SendData(PacketTypes.ChestName, string.Empty, chest.Index, chestLocation.X, chestLocation.Y);

              // Tell the client to remove the chest with the given index from its own chest array.
              TSPlayer.All.SendData(PacketTypes.TileKill, string.Empty, 1, chestLocation.X, chestLocation.Y, 0, chest.Index);
              TSPlayer.All.SendTileSquare(chestLocation.X, chestLocation.Y, 2);
              player?.SendWarningMessage("This chest is now a Protector chest.");
            }
              } else {
            int availableUnnamedChestIndex = -1;
            int availableEmptyChestIndex = -1;
            for (int i = 0; i < Main.chest.Length; i++) {
              if (i == ChestManager.DummyChestIndex)
            continue;

              Chest tChest = Main.chest[i];
              if (tChest == null) {
            availableEmptyChestIndex = i;
            break;
              } else if (availableUnnamedChestIndex == -1 && string.IsNullOrWhiteSpace(tChest.name)) {
            availableUnnamedChestIndex = i;
              }
            }

            // Prefer unset chests over unnamed chests.
            int availableChestIndex = availableEmptyChestIndex;
            if (availableChestIndex == -1)
              availableChestIndex = availableUnnamedChestIndex;

            bool isChestAvailable = (availableChestIndex != -1);
            if (!isChestAvailable) {
              player?.SendErrorMessage("The maximum of possible world chests has been reached.");
              return false;
            }

            lock (this.WorldMetadata.ProtectorChests)
              this.WorldMetadata.ProtectorChests.Remove(chestLocation);

            Chest availableChest = Main.chest[availableChestIndex];
            bool isExistingButUnnamedChest = (availableChest != null);
            if (isExistingButUnnamedChest) {
              if (!this.TrySwapChestData(null, new DPoint(availableChest.x, availableChest.y), out newChest))
            return false;
            }

            availableChest = Main.chest[availableChestIndex] = new Chest();
            availableChest.x = chestLocation.X;
            availableChest.y = chestLocation.Y;
            availableChest.item = content.Select(i => i.ToItem()).ToArray();

            newChest = new ChestAdapter(availableChestIndex, availableChest);
            player?.SendWarningMessage("This chest is now a world chest.");
              }

              return true;
        }
예제 #4
0
        public IChest PlaceChest(ushort tileType, int style, DPoint placeLocation)
        {
            Contract.Requires<ArgumentException>(tileType == TileID.Containers || tileType == TileID.Dressers);

              IChest chest;
              bool isDresser = (tileType == TileID.Dressers);
              int chestIndex = WorldGen.PlaceChest(placeLocation.X, placeLocation.Y, tileType, false, style);
              bool isWorldFull = (chestIndex == -1 || chestIndex == ChestManager.DummyChestIndex);

              if (!isWorldFull) {
            chest = new ChestAdapter(chestIndex, Main.chest[chestIndex]);
              } else {
            lock (this.WorldMetadata.ProtectorChests) {
              isWorldFull = (this.WorldMetadata.ProtectorChests.Count >= this.Config.MaxProtectorChests);
              if (isWorldFull)
            throw new LimitEnforcementException();

              if (isDresser)
            WorldGen.PlaceDresserDirect(placeLocation.X, placeLocation.Y, tileType, style, chestIndex);
              else
            WorldGen.PlaceChestDirect(placeLocation.X, placeLocation.Y, tileType, style, chestIndex);

              DPoint chestLocation = TerrariaUtils.Tiles.MeasureObject(placeLocation).OriginTileLocation;
              chest = new ProtectorChestData(chestLocation);
              this.WorldMetadata.ProtectorChests.Add(chestLocation, (ProtectorChestData)chest);

              chestIndex = ChestManager.DummyChestIndex;
            }
              }

              int storageType = 0;
              if (isDresser)
            storageType = 2;

              TSPlayer.All.SendData(PacketTypes.TileKill, string.Empty, storageType, placeLocation.X, placeLocation.Y, style, chestIndex);
              // The client will always show open / close animations for the latest chest index. But when there are multiple chests with id 999
              // this will look awkard, so instead tell the client about another 999 chest on a location where the animation will never be noticed by the player.
              if (chestIndex == ChestManager.DummyChestIndex)
            TSPlayer.All.SendData(PacketTypes.TileKill, string.Empty, storageType, 0, 0, style, chestIndex);

              return chest;
        }
예제 #5
0
        public IChest CreateChestData(DPoint chestLocation)
        {
            int chestIndex = Chest.CreateChest(chestLocation.X, chestLocation.Y);
              bool isWorldFull = (chestIndex == -1 || chestIndex == ChestManager.DummyChestIndex);

              if (!isWorldFull) {
            return new ChestAdapter(chestIndex, Main.chest[chestIndex]);
              } else {
            lock (this.WorldMetadata.ProtectorChests) {
              isWorldFull = (this.WorldMetadata.ProtectorChests.Count >= this.Config.MaxProtectorChests);
              if (isWorldFull)
            throw new LimitEnforcementException();

              IChest chest = new ProtectorChestData(chestLocation);
              this.WorldMetadata.ProtectorChests.Add(chestLocation, (ProtectorChestData)chest);
              return chest;
            }
              }
        }