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); }
public IChest ChestFromLocation(DPoint chestLocation, TSPlayer reportToPlayer = null) { Tile tile = TerrariaUtils.Tiles[chestLocation]; if (!tile.active() || (tile.type != (int)BlockType.Chest && tile.type != (int)BlockType.Dresser)) { reportToPlayer?.SendErrorMessage("There is no chest at this position."); return(null); } IChest chest = null; int chestIndex = Chest.FindChest(chestLocation.X, chestLocation.Y); bool isWorldDataChest = (chestIndex != -1 && chestIndex != ChestManager.DummyChestIndex); if (isWorldDataChest) { Chest tChest = Main.chest[chestIndex]; if (tChest != null) { chest = new ChestAdapter(chestIndex, Main.chest[chestIndex]); } else { reportToPlayer?.SendErrorMessage($"World data for this chest (id {chestIndex}) were expected, but was not present."); } } else { lock (this.WorldMetadata.ProtectorChests) { ProtectorChestData protectorChest; if (this.WorldMetadata.ProtectorChests.TryGetValue(chestLocation, out protectorChest)) { chest = protectorChest; } else { reportToPlayer?.SendErrorMessage("The data record of this chest is missing in both world data and Protector's data."); } } } return(chest); }