public override bool HandleHitSwitch(TSPlayer player, DPoint location) { if (this.IsDisposed) return false; if (base.HandleHitSwitch(player, location)) return true; if (this.CheckProtected(player, location, false)) { player.SendTileSquare(location, 3); return true; } return false; }
public override bool HandleTileEdit( TSPlayer player, TileEditType editType, BlockType blockType, DPoint location, int objectStyle ) { if (this.IsDisposed) return false; if (base.HandleTileEdit(player, editType, blockType, location, objectStyle)) return true; switch (editType) { case TileEditType.PlaceTile: { Tile tile = TerrariaUtils.Tiles[location]; if (tile == null) Main.tile[location.X, location.Y] = tile = new Tile(); WorldGen.PlaceTile(location.X, location.Y, (int)blockType, false, true, -1, objectStyle); NetMessage.SendData((int)PacketTypes.Tile, -1, player.Index, string.Empty, 1, location.X, location.Y, (int)blockType, objectStyle); if (this.Config.AutoProtectedTiles[(int)blockType]) this.TryCreateAutoProtection(player, location); return true; } case TileEditType.TileKill: case TileEditType.TileKillNoItem: { // Is the tile really going to be destroyed or just being hit? //if (blockType != 0) // break; Tile tile = TerrariaUtils.Tiles[location]; bool isChest = (tile.type == TileID.Containers || tile.type == TileID.Dressers); foreach (ProtectionEntry protection in this.ProtectionManager.EnumerateProtectionEntries(location)) { // If the protection is invalid, just remove it. if (!TerrariaUtils.Tiles.IsValidCoord(protection.TileLocation)) { this.ProtectionManager.RemoveProtection(TSPlayer.Server, protection.TileLocation, false); continue; } Tile protectedTile = TerrariaUtils.Tiles[protection.TileLocation]; // If the protection is invalid, just remove it. if (!protectedTile.active() || protectedTile.type != (int)protection.BlockType) { this.ProtectionManager.RemoveProtection(TSPlayer.Server, protection.TileLocation, false); continue; } string tileName = TerrariaUtils.Tiles.GetBlockTypeName((BlockType)protectedTile.type); if ( protection.Owner == player.User.ID || ( this.Config.AutoDeprotectEverythingOnDestruction && player.Group.HasPermission(ProtectorPlugin.ProtectionMaster_Permission) ) ) { if (isChest) { bool isBankChest = (protection.BankChestKey != BankChestDataKey.Invalid); ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(protection.TileLocation); DPoint chestLocation = measureData.OriginTileLocation; IChest chest = this.ChestManager.ChestFromLocation(chestLocation); if (chest == null) return true; if (isBankChest) { this.DestroyBlockOrObject(chestLocation); } else { for (int i = 0; i < Chest.maxItems; i++) { if (chest.Items[i].StackSize > 0) return true; } } } this.ProtectionManager.RemoveProtection(player, protection.TileLocation, false); if (this.Config.NotifyAutoDeprotections) player.SendWarningMessage($"The {tileName} is not protected anymore."); } else { player.SendErrorMessage($"The {tileName} is protected."); if (protection.TradeChestData != null) player.SendWarningMessage("If you want to trade with this chest, right click it first."); player.SendTileSquare(location); return true; } } if (isChest) { ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(location); DPoint chestLocation = measureData.OriginTileLocation; IChest chest = this.ChestManager.ChestFromLocation(chestLocation); if (chest != null) { // Don't allow removing of non empty chests. for (int i = 0; i < Chest.maxItems; i++) { if (chest.Items[i].StackSize > 0) return true; } this.DestroyBlockOrObject(chestLocation); return true; } } break; } case TileEditType.PlaceWire: case TileEditType.PlaceWireBlue: case TileEditType.PlaceWireGreen: case TileEditType.PlaceWireYellow: case TileEditType.PlaceActuator: case TileEditType.DestroyWire: case TileEditType.DestroyWireBlue: case TileEditType.DestroyWireGreen: case TileEditType.DestroyWireYellow: case TileEditType.DestroyActuator: if (this.Config.AllowWiringProtectedBlocks) break; if (this.CheckProtected(player, location, false)) { player.SendTileSquare(location); return true; } break; case TileEditType.PokeLogicGate: case TileEditType.Actuate: if (this.CheckProtected(player, location, false)) { player.SendTileSquare(location); return true; } break; } return false; }
public virtual bool HandleChestUnlock(TSPlayer player, DPoint chestLocation) { if (this.IsDisposed) 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(chestLocation)) { protection = enumProtection; break; } if (protection == null) return false; bool undoUnlock = false; if (!this.ProtectionManager.CheckProtectionAccess(protection, player, false)) { player.SendErrorMessage("This chest is protected, you can't unlock it."); undoUnlock = true; } if (protection.RefillChestData != null && !this.CheckRefillChestLootability(protection.RefillChestData, player)) undoUnlock = true; if (undoUnlock) { bool dummy; if (TerrariaUtils.Tiles.GetChestStyle(TerrariaUtils.Tiles[chestLocation], out dummy) == ChestStyle.GoldChest) { int itemIndex = Item.NewItem( chestLocation.X * TerrariaUtils.TileSize, chestLocation.Y * TerrariaUtils.TileSize, 0, 0, (int)ItemType.GoldenKey ); player.SendData(PacketTypes.ItemDrop, string.Empty, itemIndex); } player.SendTileSquare(chestLocation, 3); return true; } return false; }
public virtual bool HandleDoorUse(TSPlayer player, DPoint location, bool isOpening, Direction direction) { if (this.IsDisposed) return false; if (this.CheckProtected(player, location, false)) { player.SendTileSquare(location, 5); return true; } return false; }
public override bool HandleTileEdit( TSPlayer player, TileEditType editType, BlockType blockType, DPoint location, int objectStyle ) { if (this.IsDisposed) return false; if (base.HandleTileEdit(player, editType, blockType, location, objectStyle)) return true; switch (editType) { case TileEditType.TileKill: case TileEditType.TileKillNoItem: { // Is the tile really going to be destroyed or just being hit? //if (blockType != 0) // break; foreach (ProtectionEntry protection in this.ProtectionManager.EnumerateProtectionEntries(location)) { // If the protection is invalid, just remove it. if (!TerrariaUtils.Tiles.IsValidCoord(protection.TileLocation)) { this.ProtectionManager.RemoveProtection(TSPlayer.Server, protection.TileLocation, false); continue; } Tile protectedTile = TerrariaUtils.Tiles[protection.TileLocation]; // If the protection is invalid, just remove it. if ( !protectedTile.active() || protectedTile.type != (int)protection.BlockType ) { this.ProtectionManager.RemoveProtection(TSPlayer.Server, protection.TileLocation, false); continue; } string tileName = TerrariaUtils.Tiles.GetBlockTypeName((BlockType)protectedTile.type); if ( protection.Owner == player.User.ID || ( this.Config.AutoDeprotectEverythingOnDestruction && player.Group.HasPermission(ProtectorPlugin.ProtectionMaster_Permission) ) ) { bool isChest = (protectedTile.type == TileID.Containers || protectedTile.type == TileID.Dressers); if (isChest) { ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(protection.TileLocation); DPoint chestLocation = measureData.OriginTileLocation; int chestId = Chest.FindChest(chestLocation.X, chestLocation.Y); if (chestId != -1) { bool isBankChest = (protection.BankChestKey != BankChestDataKey.Invalid); if (isBankChest) { Chest.DestroyChestDirect(chestLocation.X, chestLocation.Y, chestId); WorldGen.KillTile(location.X, location.Y); TSPlayer.All.SendData(PacketTypes.TileKill, string.Empty, 3, chestLocation.X, chestLocation.Y, 0f, chestId); } else { Chest tChest = Main.chest[chestId]; bool isFilled = tChest.item.Any(i => i != null && i.stack > 0); if (isFilled) break; // Do not remove protections of filled chests. } } } this.ProtectionManager.RemoveProtection(player, protection.TileLocation, false); if (this.Config.NotifyAutoDeprotections) { player.SendWarningMessage(string.Format("The {0} is not protected anymore.", tileName)); } } else { player.SendErrorMessage(string.Format("The {0} is protected.", tileName)); player.SendTileSquare(location); return true; } } break; } case TileEditType.PlaceWire: case TileEditType.DestroyWire: if (this.Config.AllowWiringProtectedBlocks) break; if (this.CheckProtected(player, location, false)) { player.SendTileSquare(location); return true; } break; case TileEditType.PlaceTile: // As of Terraria 1.2.3, this packet should never be sent for chests. // Fix: We do not allow chests to be placed on active stone to prevent players from using the chest duplication bugs. // Fix2: Don't allow on ice blocks either, you never know. /*if (blockType == BlockType.Chest) { for (int x = 0; x < 2; x++) { DPoint tileBeneathLocation = location.OffsetEx(x, 1); if ( TerrariaUtils.Tiles[tileBeneathLocation].active() && ( TerrariaUtils.Tiles[tileBeneathLocation].type == (int)BlockType.ActiveStone || TerrariaUtils.Tiles[tileBeneathLocation].type == (int)BlockType.IceRodBlock ) ) { TSPlayer.All.SendData(PacketTypes.Tile, string.Empty, 0, location.X, location.Y); bool dummy; ChestStyle chestStyle = TerrariaUtils.Tiles.GetChestStyle(objectStyle, out dummy); int itemType = (int)TerrariaUtils.Tiles.GetItemTypeFromChestType(chestStyle); Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 32, 32, itemType); player.SendErrorMessage("Chests can not be placed on active stone or ice blocks."); return true; } } }*/ break; } return false; }
public virtual bool HandleChestPlace(TSPlayer player, DPoint location, int storageType, int storageStyle) { if (this.IsDisposed) return false; ushort tileToPlace = TileID.Containers; bool isDresser = (storageType == 2); if (isDresser) tileToPlace = TileID.Dressers; try { this.ChestManager.PlaceChest(tileToPlace, storageStyle, location); } catch (LimitEnforcementException ex) { player.SendTileSquare(location.X, location.Y, 2); player.SendErrorMessage("The limit of maximum possible chests has been reached. Please report this to a server administrator."); this.PluginTrace.WriteLineWarning($"Chest limit of {Main.chest.Length + this.Config.MaxProtectorChests - 1} has been reached!"); } if (this.Config.AutoProtectedTiles[tileToPlace]) this.TryCreateAutoProtection(player, location); return true; }
private void SendFakeTileWire(TSPlayer player, DPoint tileLocation) { Tile tile = TerrariaUtils.Tiles[tileLocation]; if (tile.wire2()) return; try { tile.wire2(true); player.SendTileSquare(tileLocation, 1); } finally { tile.wire2(false); } }
private void SendAreaDottedFakeWires(TSPlayer player, Rectangle area, bool setOrUnset = true) { foreach (Point boundaryPoint in TShock.Utils.EnumerateRegionBoundaries(area)) if ((boundaryPoint.X + boundaryPoint.Y & 1) == 0) if (setOrUnset) this.SendFakeTileWire(player, new DPoint(boundaryPoint.X, boundaryPoint.Y)); else player.SendTileSquare(boundaryPoint.X, boundaryPoint.Y, 1); }
public override bool HandleTileEdit( TSPlayer player, TileEditType editType, BlockType blockType, DPoint location, int objectStyle ) { if (this.IsDisposed) return false; if (base.HandleTileEdit(player, editType, blockType, location, objectStyle)) return true; switch (editType) { case TileEditType.TileKill: case TileEditType.TileKillNoItem: { // Is the tile really going to be destroyed or just being hit? //if (blockType != 0) // break; foreach (ProtectionEntry protection in this.ProtectionManager.EnumerateProtectionEntries(location)) { // If the protection is invalid, just remove it. if (!TerrariaUtils.Tiles.IsValidCoord(protection.TileLocation)) { this.ProtectionManager.RemoveProtection(TSPlayer.Server, protection.TileLocation, false); continue; } Tile protectedTile = TerrariaUtils.Tiles[protection.TileLocation]; // If the protection is invalid, just remove it. if (!protectedTile.active() || protectedTile.type != (int)protection.BlockType) { this.ProtectionManager.RemoveProtection(TSPlayer.Server, protection.TileLocation, false); continue; } string tileName = TerrariaUtils.Tiles.GetBlockTypeName((BlockType)protectedTile.type); if ( protection.Owner == player.User.ID || ( this.Config.AutoDeprotectEverythingOnDestruction && player.Group.HasPermission(ProtectorPlugin.ProtectionMaster_Permission) ) ) { bool isChest = (protectedTile.type == TileID.Containers || protectedTile.type == TileID.Dressers); if (isChest) { ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(protection.TileLocation); DPoint chestLocation = measureData.OriginTileLocation; int chestId = Chest.FindChest(chestLocation.X, chestLocation.Y); if (chestId != -1) { bool isBankChest = (protection.BankChestKey != BankChestDataKey.Invalid); if (isBankChest) { Chest.DestroyChestDirect(chestLocation.X, chestLocation.Y, chestId); WorldGen.KillTile(location.X, location.Y); TSPlayer.All.SendData(PacketTypes.TileKill, string.Empty, 3, chestLocation.X, chestLocation.Y, 0f, chestId); } else { Chest tChest = Main.chest[chestId]; bool isFilled = tChest.item.Any(i => i != null && i.stack > 0); if (isFilled) break; // Do not remove protections of filled chests. } } } this.ProtectionManager.RemoveProtection(player, protection.TileLocation, false); if (this.Config.NotifyAutoDeprotections) player.SendWarningMessage(string.Format("The {0} is not protected anymore.", tileName)); } else { player.SendErrorMessage(string.Format("The {0} is protected.", tileName)); player.SendTileSquare(location); return true; } } break; } case TileEditType.PlaceWire: case TileEditType.DestroyWire: if (this.Config.AllowWiringProtectedBlocks) break; if (this.CheckProtected(player, location, false)) { player.SendTileSquare(location); return true; } break; } return false; }
public override bool HandleTileEdit( TSPlayer player, TileEditType editType, BlockType blockType, DPoint location, int objectStyle ) { if (this.IsDisposed) return false; if (base.HandleTileEdit(player, editType, blockType, location, objectStyle)) return true; switch (editType) { case TileEditType.TileKill: case TileEditType.TileKillNoItem: { // Is the tile really going to be destroyed or just being hit? if (blockType != 0) break; // Because Terraria is dumb-assed, TileKill which is usually only sent on a chest being removed, is also sent // when the chest is filled but was hit enought times to be removed, thus we have to work around this by checking // if there's content in the chest. if (TerrariaUtils.Tiles[location].active() && TerrariaUtils.Tiles[location].type == (int)BlockType.Chest) { DPoint chestLocation = TerrariaUtils.Tiles.MeasureObject(location).OriginTileLocation; int chestIndex = Chest.FindChest(chestLocation.X, chestLocation.Y); // Non existing chests are considered empty. if (chestIndex != -1) { Chest tChest = Main.chest[chestIndex]; bool isFilled = tChest.item.Any(i => i != null && i.stack > 0); if (isFilled) { lock (this.WorldMetadata.Protections) { ProtectionEntry protection; if ( !this.WorldMetadata.Protections.TryGetValue(chestLocation, out protection) || protection.BankChestKey == BankChestDataKey.Invalid ) { break; } } } } } Tile protectedTile = null; foreach (ProtectionEntry protection in this.ProtectionManager.EnumerateProtectionEntries(location)) { if (!TerrariaUtils.Tiles.IsValidCoord(protection.TileLocation)) { this.ProtectionManager.RemoveProtection(TSPlayer.Server, protection.TileLocation, false); protectedTile = null; continue; } protectedTile = TerrariaUtils.Tiles[protection.TileLocation]; // If the protection is invalid, just remove it. if (!protectedTile.active() || protectedTile.type != (int)protection.BlockType) { this.ProtectionManager.RemoveProtection(TSPlayer.Server, protection.TileLocation, false); protectedTile = null; continue; } if ( protection.Owner == player.UserID || ( this.Config.AutoDeprotectEverythingOnDestruction && player.Group.HasPermission(ProtectorPlugin.ProtectionMaster_Permission) ) ) { this.ProtectionManager.RemoveProtection(player, protection.TileLocation, false); if (this.Config.NotifyAutoDeprotections) { player.SendWarningMessage(string.Format( "The {0} is not protected anymore.", TerrariaUtils.Tiles.GetBlockTypeName((BlockType)protectedTile.type) )); } protectedTile = null; continue; } } if (protectedTile != null) { player.SendErrorMessage(string.Format( "The {0} is protected.", TerrariaUtils.Tiles.GetBlockTypeName((BlockType)protectedTile.type) )); player.SendTileSquare(location); return true; } break; } case TileEditType.PlaceWire: case TileEditType.DestroyWire: if (this.Config.AllowWiringProtectedBlocks) break; if (this.CheckProtected(player, location, false)) { player.SendTileSquare(location); return true; } break; case TileEditType.PlaceTile: // As of Terraria 1.2.3, this packet should never be sent for chests. // Fix: We do not allow chests to be placed on active stone to prevent players from using the chest duplication bugs. // Fix2: Don't allow on ice blocks either, you never know. /*if (blockType == BlockType.Chest) { for (int x = 0; x < 2; x++) { DPoint tileBeneathLocation = location.OffsetEx(x, 1); if ( TerrariaUtils.Tiles[tileBeneathLocation].active() && ( TerrariaUtils.Tiles[tileBeneathLocation].type == (int)BlockType.ActiveStone || TerrariaUtils.Tiles[tileBeneathLocation].type == (int)BlockType.IceRodBlock ) ) { TSPlayer.All.SendData(PacketTypes.Tile, string.Empty, 0, location.X, location.Y); bool dummy; ChestStyle chestStyle = TerrariaUtils.Tiles.GetChestStyle(objectStyle, out dummy); int itemType = (int)TerrariaUtils.Tiles.GetItemTypeFromChestType(chestStyle); Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 32, 32, itemType); player.SendErrorMessage("Chests can not be placed on active stone or ice blocks."); return true; } } }*/ break; } return false; }
private bool HandleWirePlace(TSPlayer player, DPoint location) { if (this.IsDisposed) return false; DPoint[] tilesToCheck = new[] { location, new DPoint(location.X - 1, location.Y), new DPoint(location.X + 1, location.Y), new DPoint(location.X, location.Y - 1), new DPoint(location.X, location.Y + 1), }; foreach (DPoint tileToCheck in tilesToCheck) { Tile tile = TerrariaUtils.Tiles[tileToCheck]; if (!tile.active()) continue; if (tileToCheck != location && tile.type != (int)AdvancedCircuits.BlockType_WirelessTransmitter) continue; bool hasPermission = true; ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(tileToCheck); PaintColor componentPaint = (PaintColor)TerrariaUtils.Tiles[measureData.OriginTileLocation].color(); switch ((BlockType)tile.type) { case BlockType.Statue: { StatueStyle statueStyle = TerrariaUtils.Tiles.GetStatueStyle(tile); StatueConfig statueConfig; if (!this.Config.StatueConfigs.TryGetValue(statueStyle, out statueConfig)) return false; if (string.IsNullOrEmpty(statueConfig.WirePermission)) return false; hasPermission = player.Group.HasPermission(statueConfig.WirePermission); if (!hasPermission) { this.TellNoStatueWiringPermission(player, statueStyle); player.SendTileSquare(location, 1); Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, (int)ItemType.Wire); return true; } break; } case BlockType.DartTrap: { TrapConfig trapConfig; TrapConfigKey configKey = new TrapConfigKey(TerrariaUtils.Tiles.GetTrapStyle(TerrariaUtils.Tiles[location].frameY / 18), componentPaint); if (!this.Config.TrapConfigs.TryGetValue(configKey, out trapConfig)) break; if (string.IsNullOrEmpty(trapConfig.WirePermission)) break; hasPermission = player.Group.HasPermission(trapConfig.WirePermission); break; } case BlockType.Boulder: { hasPermission = player.Group.HasPermission(AdvancedCircuitsPlugin.WireBoulder_Permission); break; } case BlockType.Sign: { hasPermission = player.Group.HasPermission(AdvancedCircuitsPlugin.WireSign_Permission); break; } case BlockType.InletPump: case BlockType.OutletPump: { PumpConfig pumpConfig; if (!this.Config.PumpConfigs.TryGetValue(componentPaint, out pumpConfig)) break; hasPermission = player.Group.HasPermission(pumpConfig.WirePermission); break; } case AdvancedCircuits.BlockType_WirelessTransmitter: { WirelessTransmitterConfig transmitterConfig; if (!this.Config.WirelessTransmitterConfigs.TryGetValue(componentPaint, out transmitterConfig)) break; hasPermission = player.Group.HasPermission(transmitterConfig.WirePermission); break; } case BlockType.Teleporter: { hasPermission = player.Group.HasPermission(AdvancedCircuitsPlugin.WireTeleporter_Permission); break; } } if (!hasPermission) { this.TellMissingComponentWiringPermission(player, (BlockType)tile.type); player.SendTileSquare(location, 1); Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, (int)ItemType.Wire); return true; } } return false; }