public bool Equals(TrapConfigKey other)
 {
     return(
         this.TrapStyle == other.TrapStyle &&
         this.Paint == other.Paint
         );
 }
        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)
            {
                ITile tile = TerrariaUtils.Tiles[tileToCheck];
                if (!tile.active())
                {
                    continue;
                }
                if (tileToCheck != location && tile.type != AdvancedCircuits.BlockType_WirelessTransmitter)
                {
                    continue;
                }

                bool hasPermission               = true;
                ObjectMeasureData measureData    = TerrariaUtils.Tiles.MeasureObject(tileToCheck);
                PaintColor        componentPaint = (PaintColor)TerrariaUtils.Tiles[measureData.OriginTileLocation].color();
                switch (tile.type)
                {
                case TileID.Statues: {
                    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);

                        return(true);
                    }
                    break;
                }

                case TileID.Traps: {
                    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 TileID.Boulder: {
                    hasPermission = player.Group.HasPermission(AdvancedCircuitsPlugin.WireBoulder_Permission);
                    break;
                }

                case TileID.Signs: {
                    hasPermission = player.Group.HasPermission(AdvancedCircuitsPlugin.WireSign_Permission);
                    break;
                }

                case TileID.InletPump:
                case TileID.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 TileID.Teleporter: {
                    hasPermission = player.Group.HasPermission(AdvancedCircuitsPlugin.WireTeleporter_Permission);
                    break;
                }
                }

                if (!hasPermission)
                {
                    this.TellMissingComponentWiringPermission(player, tile.type);

                    player.SendTileSquare(location, 1);
                    return(true);
                }
            }

            return(false);
        }
        private bool CheckTilePermission(TSPlayer player, DPoint location, int blockType, int objectStyle, PaintColor paint, bool dropItem = false)
        {
            switch (blockType)
            {
            case TileID.Statues: {
                DPoint originTileLocation = new DPoint(location.X - 1, location.Y - 2);
                if (!TerrariaUtils.Tiles.IsObjectWired(originTileLocation, new DPoint(2, 3)))
                {
                    break;
                }
                StatueStyle  statueStyle = TerrariaUtils.Tiles.GetStatueStyle(objectStyle);
                StatueConfig statueConfig;
                if (!this.Config.StatueConfigs.TryGetValue(statueStyle, out statueConfig) || statueConfig == null)
                {
                    break;
                }

                if (!player.Group.HasPermission(statueConfig.WirePermission))
                {
                    player.SendTileSquareEx(location, 10);

                    if (dropItem)
                    {
                        int itemTypeToDrop;
                        itemTypeToDrop = TerrariaUtils.Tiles.GetItemTypeFromStatueStyle(statueStyle);

                        Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, itemTypeToDrop);
                    }

                    this.TellNoStatueWiringPermission(player, statueStyle);
                    return(false);
                }

                break;
            }

            case TileID.Traps: {
                ITile destTile = TerrariaUtils.Tiles[location];
                if (!destTile.HasWire())
                {
                    break;
                }
                TrapConfig trapConfig;
                TrapStyle  trapStyle = TerrariaUtils.Tiles.GetTrapStyle(destTile.frameY / 18);

                TrapConfigKey configKey = new TrapConfigKey(trapStyle, paint);
                if (!this.Config.TrapConfigs.TryGetValue(configKey, out trapConfig))
                {
                    break;
                }

                if (!player.Group.HasPermission(trapConfig.WirePermission))
                {
                    player.SendTileSquareEx(location, 10);

                    if (dropItem)
                    {
                        int itemTypeToDrop = TerrariaUtils.Tiles.GetItemTypeFromTrapStyle(trapStyle);
                        Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, itemTypeToDrop);
                    }

                    this.TellMissingComponentWiringPermission(player, blockType);
                    return(false);
                }

                break;
            }

            case TileID.Boulder: {
                DPoint originTileLocation = new DPoint(location.X - 1, location.Y - 1);
                if (!TerrariaUtils.Tiles.IsObjectWired(originTileLocation, new DPoint(2, 2)))
                {
                    break;
                }

                if (!player.Group.HasPermission(AdvancedCircuitsPlugin.WireBoulder_Permission))
                {
                    player.SendTileSquareEx(location, 10);

                    if (dropItem)
                    {
                        Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, ItemID.Boulder);
                    }

                    this.TellMissingComponentWiringPermission(player, blockType);
                    return(false);
                }

                break;
            }

            case TileID.Signs: {
                if (!TerrariaUtils.Tiles.IsObjectWired(location, new DPoint(2, 2)))
                {
                    break;
                }

                if (!player.Group.HasPermission(AdvancedCircuitsPlugin.WireSign_Permission))
                {
                    player.SendTileSquareEx(location, 10);

                    if (dropItem)
                    {
                        Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, ItemID.Sign);
                    }

                    this.TellMissingComponentWiringPermission(player, blockType);
                    return(false);
                }

                break;
            }

            case TileID.InletPump:
            case TileID.OutletPump: {
                DPoint originTileLocation = new DPoint(location.X - 1, location.Y - 1);
                if (!TerrariaUtils.Tiles.IsObjectWired(originTileLocation, new DPoint(2, 2)))
                {
                    break;
                }
                PumpConfig pumpConfig;
                if (!this.Config.PumpConfigs.TryGetValue(paint, out pumpConfig))
                {
                    break;
                }
                if (string.IsNullOrEmpty(pumpConfig.WirePermission))
                {
                    break;
                }

                if (!player.Group.HasPermission(pumpConfig.WirePermission))
                {
                    player.SendTileSquareEx(location, 10);

                    if (dropItem)
                    {
                        int itemTypeToDrop = ItemID.OutletPump;
                        if (blockType == ItemID.InletPump)
                        {
                            itemTypeToDrop = ItemID.InletPump;
                        }

                        Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, itemTypeToDrop);
                    }

                    this.TellMissingComponentWiringPermission(player, blockType);
                    return(false);
                }

                break;
            }

            case AdvancedCircuits.BlockType_WirelessTransmitter: {
                if (!AdvancedCircuits.IsComponentWiredByPort(location, new DPoint(1, 1)))
                {
                    break;
                }
                WirelessTransmitterConfig transmitterConfig;
                if (!this.Config.WirelessTransmitterConfigs.TryGetValue(paint, out transmitterConfig))
                {
                    break;
                }

                if (!player.Group.HasPermission(transmitterConfig.WirePermission))
                {
                    player.SendTileSquareEx(location, 1);

                    if (dropItem)
                    {
                        Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, ItemID.AdamantiteOre);
                    }

                    this.TellMissingComponentWiringPermission(player, blockType);
                    return(false);
                }

                break;
            }

            case ItemID.Teleporter: {
                DPoint originTileLocation = new DPoint(location.X - 1, location.Y - 1);
                if (!TerrariaUtils.Tiles.IsObjectWired(originTileLocation, new DPoint(3, 1)))
                {
                    break;
                }

                if (!player.Group.HasPermission(AdvancedCircuitsPlugin.WireTeleporter_Permission))
                {
                    player.SendTileSquareEx(location, 10);

                    if (dropItem)
                    {
                        Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, ItemID.Teleporter);
                    }

                    this.TellMissingComponentWiringPermission(player, blockType);
                    return(false);
                }

                break;
            }
            }

            return(true);
        }
        protected bool SignalComponent(ref ObjectMeasureData measureData, RootBranchProcessData rootBranch, SignalType signal, bool localOnly = false)
        {
            int originX = measureData.OriginTileLocation.X;
              int originY = measureData.OriginTileLocation.Y;

              switch (measureData.BlockType) {
            case BlockType.Torch:
            case BlockType.XMasLight:
            case BlockType.Candle:
            case BlockType.PlatinumCandle:
            case BlockType.ChainLantern:
            case BlockType.ChineseLantern:
            case BlockType.Candelabra:
            case BlockType.PlatinumCandelabra:
            case BlockType.DiscoBall:
            case BlockType.TikiTorch:
            case BlockType.CopperChandelier:
            case BlockType.SilverChandelier:
            case BlockType.GoldChandelier:
            case BlockType.PlatinumChandelier:
            case BlockType.LampPost:
            case BlockType.MusicBox:
            case BlockType.XSecondTimer:
            case BlockType.WaterFountain:
            case BlockType.BubbleMachine: {
              bool currentState = TerrariaUtils.Tiles.ObjectHasActiveState(measureData);
              bool newState;
              if (signal == SignalType.Swap)
            newState = !currentState;
              else
            newState = AdvancedCircuits.SignalToBool(signal).Value;

              if (measureData.BlockType == BlockType.XSecondTimer) {
            // Directly wired Timers in an Advanced Circuit are not meant to be switched.
            if (this.IsAdvancedCircuit)
              return false;

            if (newState != currentState)
              this.CircuitHandler.RegisterUnregisterTimer(this.TriggeringPlayer, measureData, newState);
              }

              if (newState != currentState)
            TerrariaUtils.Tiles.SetObjectState(measureData, newState, !localOnly);

              return true;
            }
            case BlockType.ActiveStone:
            case BlockType.InactiveStone: {
              bool currentState = (measureData.BlockType == BlockType.ActiveStone);
              bool newState;
              if (signal == SignalType.Swap)
            newState = !currentState;
              else
            newState = AdvancedCircuits.SignalToBool(signal).Value;

              if (newState != currentState) {
            BlockType newBlockType;
            if (newState)
              newBlockType = BlockType.ActiveStone;
            else
              newBlockType = BlockType.InactiveStone;

            TerrariaUtils.Tiles[measureData.OriginTileLocation].type = (byte)newBlockType;
            WorldGen.SquareTileFrame(originX, originY);
            TSPlayer.All.SendTileSquareEx(originX, originY, 1);
              }

              return true;
            }
            case BlockType.DoorClosed:
            case BlockType.DoorOpened: {
              if (this.IsAdvancedCircuit)
            return false;

              this.OpenDoor(measureData, signal);
              return true;
            }
            case BlockType.InletPump:
            case BlockType.OutletPump: {
              if (signal == SignalType.Off)
            return false;

              PumpConfig pumpConfig;
              PaintColor componentPaint = (PaintColor)TerrariaUtils.Tiles[measureData.OriginTileLocation].color();
              if (
            (
              this.CircuitHandler.Config.PumpConfigs.TryGetValue(componentPaint, out pumpConfig) ||
              this.CircuitHandler.Config.PumpConfigs.TryGetValue(PaintColor.None, out pumpConfig)
            ) &&
              pumpConfig.Cooldown == 0 ||
              WorldGen.checkMech(originX, originY, pumpConfig.Cooldown
            )
              ) {
            if (this.Result.SignaledPumps > this.CircuitHandler.Config.MaxPumpsPerCircuit) {
              this.Result.WarnReason = CircuitWarnReason.SignalesTooManyPumps;
              return true;
            }
            if (
              pumpConfig.TriggerPermission != null &&
              this.TriggeringPlayer != TSPlayer.Server &&
              !this.TriggeringPlayer.Group.HasPermission(pumpConfig.TriggerPermission)
            ) {
              this.Result.WarnReason = CircuitWarnReason.InsufficientPermissionToSignalComponent;
              this.Result.WarnRelatedComponentType = measureData.BlockType;
              return true;
            }

            if (measureData.BlockType == BlockType.InletPump)
              this.SignaledInletPumps.Add(new DPoint(originX, originY));
            else
              this.SignaledOutletPumps.Add(new DPoint(originX, originY));

            this.Result.SignaledPumps++;
              }

              return true;
            }
            case BlockType.DartTrap: {
              if (signal == SignalType.Off)
            return false;

              TrapConfig trapConfig;
              Tile componentTile = TerrariaUtils.Tiles[measureData.OriginTileLocation];
              PaintColor componentPaint = (PaintColor)componentTile.color();
              TrapStyle trapStyle = TerrariaUtils.Tiles.GetTrapStyle(componentTile.frameY / 18);
              TrapConfigKey configKey = new TrapConfigKey(trapStyle, componentPaint);
              TrapConfigKey defaultKey = new TrapConfigKey(trapStyle, PaintColor.None);
              if (
            (
              this.CircuitHandler.Config.TrapConfigs.TryGetValue(configKey, out trapConfig) ||
              this.CircuitHandler.Config.TrapConfigs.TryGetValue(defaultKey, out trapConfig)
            ) &&
              trapConfig.Cooldown == 0 ||
              WorldGen.checkMech(originX, originY, trapConfig.Cooldown
            )
              ) {
            if (this.Result.SignaledTraps > this.CircuitHandler.Config.MaxTrapsPerCircuit) {
              this.Result.WarnReason = CircuitWarnReason.SignalesTooManyTraps;
              return true;
            }
            if (
              trapConfig.TriggerPermission != null &&
              this.TriggeringPlayer != TSPlayer.Server &&
              !this.TriggeringPlayer.Group.HasPermission(trapConfig.TriggerPermission)
            ) {
              this.Result.WarnReason = CircuitWarnReason.InsufficientPermissionToSignalComponent;
              this.Result.WarnRelatedComponentType = BlockType.DartTrap;
              return true;
            }

            int projectileIndex = 1000;
            for (int i = 0; i < 1000; ++i) {
              if (!Main.projectile[i].active) {
                projectileIndex = i;
                break;
              }
            }
            if (projectileIndex == 1000)
              return true;

            bool isFacingLeft = (TerrariaUtils.Tiles[originX, originY].frameX == 0);
            float projectileAngle = trapConfig.ProjectileAngle;
            if (isFacingLeft)
              projectileAngle += 180f;

            projectileAngle += CircuitProcessor.Random.Next(-(int)trapConfig.ProjectileAngleVariance, (int)trapConfig.ProjectileAngleVariance + 1);

            Vector2 normalizedPolarOffset = new Vector2(
              (float)Math.Cos(Math.PI * projectileAngle / 180f),
              (float)Math.Sin(Math.PI * projectileAngle / 180f)
            );
            Projectile projectile = Main.projectile[projectileIndex];
            projectile.SetDefaults(trapConfig.ProjectileType);
            Vector2 projectileSpawn = new Vector2(
              (originX * TerrariaUtils.TileSize + (trapConfig.ProjectileOffset * normalizedPolarOffset.X)),
              (originY * TerrariaUtils.TileSize + (trapConfig.ProjectileOffset * normalizedPolarOffset.Y))
            );
            projectileSpawn = projectileSpawn.Add(new Vector2(
              TerrariaUtils.TileSize / 2 - projectile.width / 2,
              TerrariaUtils.TileSize / 2 - projectile.height / 2
            ));
            projectile.position.X = projectileSpawn.X;
            projectile.position.Y = projectileSpawn.Y;
            projectile.owner = Main.myPlayer;
            projectile.velocity.X = (trapConfig.ProjectileSpeed * normalizedPolarOffset.X);
            projectile.velocity.Y = (trapConfig.ProjectileSpeed * normalizedPolarOffset.Y);
            projectile.damage = trapConfig.ProjectileDamage;
            projectile.knockBack = trapConfig.ProjectileKnockback;
            projectile.identity = projectileIndex;
            projectile.timeLeft = trapConfig.ProjectileLifeTime;
            projectile.wet = Collision.WetCollision(projectile.position, projectile.width, projectile.height);
            TSPlayer.All.SendData(PacketTypes.ProjectileNew, string.Empty, projectileIndex);

            this.Result.SignaledTraps++;
              }

              return true;
            }
            case BlockType.Explosives: {
              if (signal == SignalType.Off)
            return false;

              WorldGen.KillTile(originX, originY, false, false, true);
              TSPlayer.All.SendTileSquareEx(originX, originY, 1);
              Projectile.NewProjectile((originX * 16 + 8), (originY * 16 + 8), 0f, 0f, 108, 250, 10f, Main.myPlayer);

              return true;
            }
            case BlockType.Statue: {
              if (signal == SignalType.Off)
            return false;

              StatueStyle statueStyle = TerrariaUtils.Tiles.GetStatueStyle(TerrariaUtils.Tiles[measureData.OriginTileLocation]);
              StatueConfig statueConfig;
              if (
            this.CircuitHandler.Config.StatueConfigs.TryGetValue(statueStyle, out statueConfig) &&
            statueConfig.Actions.Count > 0 && (
              statueConfig.Cooldown == 0 ||
              WorldGen.checkMech(originX, originY, statueConfig.Cooldown)
            )
              ) {
            if (this.Result.SignaledStatues > this.CircuitHandler.Config.MaxStatuesPerCircuit) {
              this.Result.WarnReason = CircuitWarnReason.SignalesTooManyStatues;
              return true;
            }
            if (
              statueConfig.TriggerPermission != null &&
              this.TriggeringPlayer != TSPlayer.Server &&
              !this.TriggeringPlayer.Group.HasPermission(statueConfig.TriggerPermission)
            ) {
              this.Result.WarnReason = CircuitWarnReason.InsufficientPermissionToSignalComponent;
              this.Result.WarnRelatedComponentType = BlockType.Statue;
              return true;
            }

            if (statueConfig.PlayerCheckRange > 0) {
              bool isPlayerInRange = false;
              foreach (TSPlayer player in TShock.Players) {
                if (player == null || !player.Active)
                  continue;
                if (Math.Sqrt(Math.Pow(player.TileX - originX, 2) + Math.Pow(player.TileY - originY, 2)) <= statueConfig.PlayerCheckRange) {
                  isPlayerInRange = true;
                  break;
                }
              }
              if (!isPlayerInRange)
                return true;
            }

            if (statueConfig.ActionsProcessingMethod == ActionListProcessingMethod.ExecuteAll) {
              foreach (NullStatueAction action in statueConfig.Actions)
                this.ExecuteStatueAction(measureData.OriginTileLocation, action);
            } else {
              NullStatueAction randomAction = statueConfig.Actions[CircuitProcessor.Random.Next(0, statueConfig.Actions.Count)];
              this.ExecuteStatueAction(measureData.OriginTileLocation, randomAction);
            }

            this.Result.SignaledStatues++;
              }

              return true;
            }
            case BlockType.Sign: {
              if (!this.IsAdvancedCircuit || signal == SignalType.Off || this.TriggeringPlayer == TSPlayer.Server)
            return false;

              if (this.IsTriggeredPassively && !this.TriggeringPlayer.Group.HasPermission(AdvancedCircuitsPlugin.PassiveTriggerSign_Permission)) {
            this.Result.WarnReason = CircuitWarnReason.InsufficientPermissionToSignalComponent;
            this.Result.WarnRelatedComponentType = BlockType.Sign;
            return false;
              }

              string signText = Main.sign[Sign.ReadSign(originX, originY)].text;
              if (signText == null)
            return false;

              if (
            this.CircuitHandler.PluginCooperationHandler.IsSignCommandsAvailable &&
            this.CircuitHandler.PluginCooperationHandler.SignCommands_CheckIsSignCommand(signText)
              ) {
            if (!this.TriggeringPlayer.Group.HasPermission(AdvancedCircuitsPlugin.TriggerSignCommand_Permission)) {
              this.Result.WarnReason = CircuitWarnReason.InsufficientPermissionToSignalComponent;
              this.Result.WarnRelatedComponentType = BlockType.Sign;
              return false;
            }

            this.CircuitHandler.PluginCooperationHandler.SignCommands_ExecuteSignCommand(
              this.TriggeringPlayer, measureData.OriginTileLocation, signText
            );
            return true;
              }

              if (!WorldGen.checkMech(originX, originY, 300))
            return true;

              string fullText = this.CircuitHandler.Config.SignConfig.ReadPrefix + signText;
              int lineStartIndex = 0;
              int lineLength = 0;
              for (int i = 0; i < fullText.Length; i++) {
            if (lineLength == 60 || fullText[i] == '\n' || (i == fullText.Length - 1 && lineLength > 0)) {
              if (fullText[i] == '\n') {
                if (lineLength > 0)
                  this.TriggeringPlayer.SendInfoMessage(fullText.Substring(lineStartIndex, i - lineStartIndex));
                else
                  this.TriggeringPlayer.SendInfoMessage(string.Empty);

                lineStartIndex = i + 1;
              } else if (i == fullText.Length - 1) {
                this.TriggeringPlayer.SendInfoMessage(fullText.Substring(lineStartIndex, i - lineStartIndex + 1));
                lineStartIndex = i;
              } else {
                this.TriggeringPlayer.SendInfoMessage(fullText.Substring(lineStartIndex, i - lineStartIndex));
                lineStartIndex = i;
              }

              lineLength = 0;
              continue;
            }

            lineLength++;
              }

              return true;
            }
            case BlockType.Boulder: {
              if (!this.IsAdvancedCircuit || signal == SignalType.Off)
            return false;

              WorldGen.KillTile(originX, originY, false, false, true);
              TSPlayer.All.SendTileSquareEx(originX, originY, 2);
              return true;
            }
            case BlockType.LandMine: {
              if (signal == SignalType.Off)
            return false;

              WorldGen.ExplodeMine(originX, originY);
              return true;
            }
            case BlockType.Rocket: {
              if (signal == SignalType.Off)
            return false;

              WorldGen.LaunchRocket(originX, originY);
              return true;
            }
            case BlockType.Teleporter: {
              if (signal == SignalType.Off)
            return false;
              if (TerrariaUtils.Tiles[measureData.OriginTileLocation].wall == (int)WallType.LihzahrdBrickWall && !(originY <= Main.worldSurface || NPC.downedPlantBoss))
            return true;
              if (this.TriggeringPlayer != TSPlayer.Server && !this.TriggeringPlayer.Group.HasPermission(AdvancedCircuitsPlugin.TriggerTeleporter_Permission)) {
            this.Result.WarnReason = CircuitWarnReason.InsufficientPermissionToSignalComponent;
            this.Result.WarnRelatedComponentType = BlockType.Teleporter;
            return false;
              }

              if (rootBranch.TeleporterLocation == DPoint.Empty) {
            rootBranch.TeleporterLocation = measureData.OriginTileLocation;
              } else {
            WorldGen.teleport[0] = rootBranch.TeleporterLocation.ToXnaVector2();
            WorldGen.teleport[1] = measureData.OriginTileLocation.ToXnaVector2();
            WorldGen.Teleport();
            WorldGen.teleport[0] = WorldGen.teleport[1] = new Vector2(-1f, -1f);

            rootBranch.TeleporterLocation = DPoint.Empty;
              }
              return true;
            }
              }

              return false;
        }
 public bool Equals(TrapConfigKey other) {
   return (
     this.TrapStyle == other.TrapStyle &&
     this.Paint == other.Paint
   );
 }
        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;
        }
        private bool CheckTilePermission(TSPlayer player, DPoint location, BlockType blockType, int objectStyle, PaintColor paint, bool dropItem = false)
        {
            switch (blockType) {
            case BlockType.Statue: {
              DPoint originTileLocation = new DPoint(location.X, location.Y - 2);
              if (!TerrariaUtils.Tiles.IsObjectWired(originTileLocation, new DPoint(2, 3)))
            break;
              StatueStyle statueStyle = TerrariaUtils.Tiles.GetStatueStyle(objectStyle);
              StatueConfig statueConfig;
              if (!this.Config.StatueConfigs.TryGetValue(statueStyle, out statueConfig) || statueConfig == null)
            break;

              if (!player.Group.HasPermission(statueConfig.WirePermission)) {
            player.SendTileSquareEx(location, 10);

            if (dropItem) {
              ItemType itemTypeToDrop;
              itemTypeToDrop = TerrariaUtils.Tiles.GetItemTypeFromStatueStyle(statueStyle);

              Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, (int)itemTypeToDrop);
            }

            this.TellNoStatueWiringPermission(player, statueStyle);
            return false;
              }

              break;
            }
            case BlockType.DartTrap: {
              Tile destTile = TerrariaUtils.Tiles[location];
              if (!destTile.HasWire())
            break;
              TrapConfig trapConfig;
              TrapStyle trapStyle = TerrariaUtils.Tiles.GetTrapStyle(destTile.frameY / 18);
              TrapConfigKey configKey = new TrapConfigKey(trapStyle, paint);
              if (!this.Config.TrapConfigs.TryGetValue(configKey, out trapConfig))
            break;

              if (!player.Group.HasPermission(trapConfig.WirePermission)) {
            player.SendTileSquareEx(location, 10);

            if (dropItem) {
              ItemType itemTypeToDrop = TerrariaUtils.Tiles.GetItemTypeFromTrapStyle(trapStyle);
              Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, (int)itemTypeToDrop);
            }

            this.TellMissingComponentWiringPermission(player, blockType);
            return false;
              }

              break;
            }
            case BlockType.Boulder: {
              DPoint originTileLocation = new DPoint(location.X - 1, location.Y - 1);
              if (!TerrariaUtils.Tiles.IsObjectWired(originTileLocation, new DPoint(2, 2)))
            break;

              if (!player.Group.HasPermission(AdvancedCircuitsPlugin.WireBoulder_Permission)) {
            player.SendTileSquareEx(location, 10);

            if (dropItem)
              Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, (int)ItemType.Boulder);

            this.TellMissingComponentWiringPermission(player, blockType);
            return false;
              }

              break;
            }
            case BlockType.Sign: {
              if (!TerrariaUtils.Tiles.IsObjectWired(location, new DPoint(2, 2)))
            break;

              if (!player.Group.HasPermission(AdvancedCircuitsPlugin.WireSign_Permission)) {
            player.SendTileSquareEx(location, 10);

            if (dropItem)
              Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, (int)ItemType.Sign);

            this.TellMissingComponentWiringPermission(player, blockType);
            return false;
              }

              break;
            }
            case BlockType.InletPump:
            case BlockType.OutletPump: {
              DPoint originTileLocation = new DPoint(location.X - 1, location.Y - 1);
              if (!TerrariaUtils.Tiles.IsObjectWired(originTileLocation, new DPoint(2, 2)))
            break;
              PumpConfig pumpConfig;
              if (!this.Config.PumpConfigs.TryGetValue(paint, out pumpConfig))
            break;
              if (string.IsNullOrEmpty(pumpConfig.WirePermission))
            break;

              if (!player.Group.HasPermission(pumpConfig.WirePermission)) {
            player.SendTileSquareEx(location, 10);

            if (dropItem) {
              ItemType itemTypeToDrop = ItemType.OutletPump;
              if (blockType == BlockType.InletPump)
                itemTypeToDrop = ItemType.InletPump;

              Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, (int)itemTypeToDrop);
            }

            this.TellMissingComponentWiringPermission(player, blockType);
            return false;
              }

              break;
            }
            case AdvancedCircuits.BlockType_WirelessTransmitter: {
              if (!AdvancedCircuits.IsComponentWiredByPort(location, new DPoint(1, 1)))
            break;
              WirelessTransmitterConfig transmitterConfig;
              if (!this.Config.WirelessTransmitterConfigs.TryGetValue(paint, out transmitterConfig))
            break;

              if (!player.Group.HasPermission(transmitterConfig.WirePermission)) {
            player.SendTileSquareEx(location, 1);

            if (dropItem)
              Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, (int)ItemType.AdamantiteOre);

            this.TellMissingComponentWiringPermission(player, blockType);
            return false;
              }

              break;
            }
            case BlockType.Teleporter: {
              DPoint originTileLocation = new DPoint(location.X - 1, location.Y - 1);
              if (!TerrariaUtils.Tiles.IsObjectWired(originTileLocation, new DPoint(3, 1)))
            break;

              if (!player.Group.HasPermission(AdvancedCircuitsPlugin.WireTeleporter_Permission)) {
            player.SendTileSquareEx(location, 10);

            if (dropItem)
              Item.NewItem(location.X * TerrariaUtils.TileSize, location.Y * TerrariaUtils.TileSize, 0, 0, (int)ItemType.Teleporter);

            this.TellMissingComponentWiringPermission(player, blockType);
            return false;
              }

              break;
            }
              }

              return true;
        }