Ejemplo n.º 1
0
    public void LockChest(DPoint anyChestTileLocation) {
      ITile chestTile = TerrariaUtils.Tiles[anyChestTileLocation];
      if (!chestTile.active() || (chestTile.type != TileID.Containers && chestTile.type != TileID.Containers2))
        throw new ArgumentException("Tile is not a chest.", nameof(anyChestTileLocation));

      bool isLocked;
      ChestStyle chestStyle = this.GetChestStyle(chestTile, out isLocked);
      if (isLocked)
        throw new InvalidChestStyleException("Chest is already locked.", chestStyle);

      if (!this.IsChestStyleLockable(chestStyle))
        throw new InvalidChestStyleException("Chest has to be a lockable chest.", chestStyle);

      ObjectMeasureData measureData = this.MeasureObject(anyChestTileLocation);
      if (
        chestStyle == ChestStyle.JungleChest ||
        chestStyle == ChestStyle.CorruptionChest ||
        chestStyle == ChestStyle.CrimsonChest ||
        chestStyle == ChestStyle.HallowedChest ||
        chestStyle == ChestStyle.FrozenChest)
      {
        foreach (ITile tile in this.EnumerateObjectTiles(measureData))
          tile.frameX += 180;
      }
      else
      {
        foreach (ITile tile in this.EnumerateObjectTiles(measureData))
          tile.frameX += 36;
      }
      
      TSPlayer.All.SendTileSquare(anyChestTileLocation, 4);
    }
        public CircuitProcessor(PluginTrace pluginTrace, CircuitHandler circuitHandler, ObjectMeasureData senderMeasureData)
        {
            Contract.Requires<ArgumentNullException>(pluginTrace != null);
              Contract.Requires<ArgumentNullException>(circuitHandler != null);

              this.PluginTrace = pluginTrace;
              this.CircuitHandler = circuitHandler;
              this.SenderMeasureData = senderMeasureData;

              // Is sender directly wired?
              bool isSenderWired;
              if (this.SenderMeasureData.BlockType == BlockType.DoorOpened) {
            isSenderWired = false;
            for (int y = this.SenderMeasureData.OriginTileLocation.Y; y < this.SenderMeasureData.OriginTileLocation.Y + this.SenderMeasureData.Size.Y; y++) {
              if (TerrariaUtils.Tiles[this.SenderMeasureData.OriginTileLocation.X, y].HasWire()) {
            isSenderWired = true;
            break;
              }
            }
              } else {
            isSenderWired = TerrariaUtils.Tiles.IsObjectWired(this.SenderMeasureData);
              }

              this.result = new CircuitProcessingResult {
            IsAdvancedCircuit = !isSenderWired,
            SenderLocation = this.SenderMeasureData.OriginTileLocation
              };
        }
Ejemplo n.º 3
0
    public bool IsObjectWired(ObjectMeasureData measureData, WireColor wireColor, out DPoint firstWireLocation) {
      foreach (DPoint tileLocation in this.EnumerateObjectTileLocations(measureData)) {
        ITile tile = TerrariaUtils.Tiles[tileLocation];
        if (tile.HasWire(wireColor)) {
          firstWireLocation = tileLocation;
          return true;
        }
      }

      firstWireLocation = DPoint.Empty;
      return false;
    }
Ejemplo n.º 4
0
        public IEnumerable<DPoint> EnumerateObjectTileLocations(ObjectMeasureData measureData)
        {
            DPoint origin = measureData.OriginTileLocation;

              if (
            measureData.BlockType == BlockType.DoorOpened &&
            this.GetDoorDirection(measureData.OriginTileLocation) == Direction.Left
              ) {
            origin.Offset(-1, 0);
              }

              for (int x = origin.X; x < origin.X + measureData.Size.X; x++)
            for (int y = origin.Y; y < origin.Y + measureData.Size.Y; y++)
              yield return new DPoint(x, y);
        }
Ejemplo n.º 5
0
    public IEnumerable<DPoint> EnumerateObjectTileLocations(ObjectMeasureData measureData) {
      DPoint origin = measureData.OriginTileLocation;

      if (
        (measureData.BlockType == TileID.OpenDoor &&
        this.GetDoorDirection(measureData.OriginTileLocation) == Direction.Left) ||
        (measureData.BlockType == TileID.TrapdoorOpen &&
        this.GetDoorDirection(measureData.OriginTileLocation) == Direction.Down )
      ) {
        origin.Offset(-1, 0);
      }

      for (int x = origin.X; x < origin.X + measureData.Size.X; x++)
        for (int y = origin.Y; y < origin.Y + measureData.Size.Y; y++)
          yield return new DPoint(x, y);
    }
Ejemplo n.º 6
0
    public bool ObjectHasActiveState(ObjectMeasureData measureData) {
      ITile tile = TerrariaUtils.Tiles[measureData.OriginTileLocation];

      switch (measureData.BlockType) {
        case TileID.Switches:
          return (tile.frameY == 0);
        case TileID.Timers:
        case TileID.WaterFountain:
          return (tile.frameY != 0);
        case TileID.MusicBoxes:
          return (tile.frameX != 0);
        case TileID.Torches:
          return (tile.frameX < 66);
        case TileID.HolidayLights:
          return (tile.frameX < 54);
        default:
          return (tile.frameX == 0);
      }
    }
 public void RegisterUnregisterTimer(TSPlayer triggeringPlayer, ObjectMeasureData measureData, bool register) {
   bool alreadyRegistered = this.WorldMetadata.ActiveTimers.ContainsKey(measureData.OriginTileLocation);
   if (register) {
     if (!alreadyRegistered) {
       this.WorldMetadata.ActiveTimers.Add(
         measureData.OriginTileLocation, new ActiveTimerMetadata(AdvancedCircuits.MeasureTimerFrameTime(measureData.OriginTileLocation), triggeringPlayer.Name)
       );
     }
   } else if (alreadyRegistered) {
     this.WorldMetadata.ActiveTimers.Remove(measureData.OriginTileLocation);
   }
 }
Ejemplo n.º 8
0
        private IEnumerable<ProtectionEntry> EnumProtectionEntriesOnTopOfObject(ObjectMeasureData measureData)
        {
            for (int rx = 0; rx < measureData.Size.X; rx++) {
            DPoint absoluteLocation = measureData.OriginTileLocation.OffsetEx(rx, -1);

            Tile topTile = TerrariaUtils.Tiles[absoluteLocation];
            if (
              topTile.type == (int)BlockType.Bottle ||
              topTile.type == (int)BlockType.Chest ||
              topTile.type == (int)BlockType.Candle ||
              topTile.type == (int)BlockType.WaterCandle ||
              topTile.type == (int)BlockType.Book ||
              topTile.type == (int)BlockType.ClayPot ||
              topTile.type == (int)BlockType.Bed ||
              topTile.type == (int)BlockType.SkullLantern ||
              topTile.type == (int)BlockType.TrashCan_UNUSED ||
              topTile.type == (int)BlockType.Candelabra ||
              topTile.type == (int)BlockType.Bowl ||
              topTile.type == (int)BlockType.CrystalBall
            ) {
              lock (this.WorldMetadata.Protections) {
            ProtectionEntry protection;
            if (this.WorldMetadata.Protections.TryGetValue(absoluteLocation, out protection))
              yield return protection;
              }
            }
              }
        }
Ejemplo n.º 9
0
        public void SetObjectState(
            ObjectMeasureData measureData, bool activeState, bool sendTileSquare = true
            )
        {
            #if DEBUG
              if (this.ObjectHasActiveState(measureData) == activeState) {
            throw new ArgumentException(string.Format(
              "The object \"{0}\" does already have the state \"{1}\".", TerrariaUtils.Tiles.GetBlockTypeName(measureData.BlockType), activeState
            ));
              }
              #endif

              int originX = measureData.OriginTileLocation.X;
              int originY = measureData.OriginTileLocation.Y;
              int objectWidth = measureData.Size.X;
              int objectHeight = measureData.Size.Y;
              int newFrameXOffset = 0;
              int newFrameYOffset = 0;
              if (measureData.BlockType == BlockType.Torch || measureData.BlockType == BlockType.XMasLight)
            newFrameXOffset = measureData.TextureTileSize.X * 2;

              if (
            measureData.BlockType != BlockType.Switch &&
            measureData.BlockType != BlockType.XSecondTimer &&
            measureData.BlockType != BlockType.WaterFountain
              ) {
            int frameXOffset = (objectWidth * measureData.TextureTileSize.X) + newFrameXOffset;
            if (measureData.BlockType == BlockType.MusicBox)
              frameXOffset = -frameXOffset;

            if (activeState)
              newFrameXOffset = (short)-frameXOffset;
            else
              newFrameXOffset = (short)frameXOffset;

            if (measureData.BlockType == BlockType.BubbleMachine && !activeState)
              newFrameYOffset = -TerrariaUtils.Tiles[measureData.OriginTileLocation].frameY;
              } else {
            int frameYOffset = (objectHeight * measureData.TextureTileSize.Y);
            if (measureData.BlockType == BlockType.WaterFountain && !activeState) {
              newFrameYOffset = -TerrariaUtils.Tiles[measureData.OriginTileLocation].frameY;
            } else {
              if (
            measureData.BlockType == BlockType.XSecondTimer ||
            measureData.BlockType == BlockType.WaterFountain
              )
            activeState = !activeState;

              if (activeState)
            newFrameYOffset = (short)-frameYOffset;
              else
            newFrameYOffset = (short)frameYOffset;
            }
              }

              for (int tx = 0; tx < objectWidth; tx++) {
            for (int ty = 0; ty < objectHeight; ty++) {
              int absoluteX = originX + tx;
              int absoluteY = originY + ty;

              TerrariaUtils.Tiles[absoluteX, absoluteY].frameX += (short)newFrameXOffset;
              TerrariaUtils.Tiles[absoluteX, absoluteY].frameY += (short)newFrameYOffset;
            }
              }

              if (sendTileSquare)
            TSPlayer.All.SendTileSquareEx(originX, originY, Math.Max(objectWidth, objectHeight));
        }
Ejemplo n.º 10
0
        public bool ObjectHasActiveState(ObjectMeasureData measureData)
        {
            Tile tile = TerrariaUtils.Tiles[measureData.OriginTileLocation];

              switch (measureData.BlockType) {
            case BlockType.Switch:
              return (tile.frameY == 0);
            case BlockType.XSecondTimer:
            case BlockType.WaterFountain:
              return (tile.frameY != 0);
            case BlockType.MusicBox:
              return (tile.frameX != 0);
            case BlockType.Torch:
              return (tile.frameX < 66);
            case BlockType.XMasLight:
              return (tile.frameX < 54);
            default:
              return (tile.frameX == 0);
              }
        }
Ejemplo n.º 11
0
 public IEnumerable<ITile> EnumerateObjectTiles(ObjectMeasureData measureData) {
   foreach (DPoint tileLocation in this.EnumerateObjectTileLocations(measureData))
     yield return TerrariaUtils.Tiles[tileLocation];
 }
 public static bool IsComponentWiredByPort(ObjectMeasureData measureData)
 {
     return AdvancedCircuits.IsComponentWiredByPort(measureData.OriginTileLocation, measureData.Size);
 }
        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;
        }
        private bool SignalPortDefiningComponent(RootBranchProcessData rootBranch, ObjectMeasureData measureData, DPoint portLocation, bool signal)
        {
            if (!this.IsAdvancedCircuit)
            throw new InvalidOperationException("This is no advanced circuit.");

              Tile portTile = TerrariaUtils.Tiles[portLocation];
              Tile componentTile = TerrariaUtils.Tiles[measureData.OriginTileLocation];
              if (!portTile.HasWire(rootBranch.WireColor) || componentTile.HasWire())
            return false;

              if (portTile.active() && portTile.type == (int)AdvancedCircuits.BlockType_NOTGate && measureData.BlockType != AdvancedCircuits.BlockType_NOTGate)
            signal = !signal;
              else if (portTile.active() && portTile.type == (int)AdvancedCircuits.BlockType_XORGate && measureData.BlockType != AdvancedCircuits.BlockType_XORGate)
            signal = false;

              List<DPoint> componentPorts = null;
              bool outputSignal = signal;
              DPoint componentLocation = measureData.OriginTileLocation;
              PaintColor componentPaint = (PaintColor)TerrariaUtils.Tiles[measureData.OriginTileLocation].color();

              BlockActivatorMetadata blockActivatorToRegister = null;
              DPoint blockActivatorLocationToRegister = DPoint.Empty;
              BlockActivatorMode blockActivatorModeToRegister = BlockActivatorMode.Default;

              switch (measureData.BlockType) {
            case BlockType.DoorOpened:
            case BlockType.DoorClosed: {
              for (int y = measureData.OriginTileLocation.Y; y < measureData.OriginTileLocation.Y + measureData.Size.Y; y++)
            if (TerrariaUtils.Tiles[measureData.OriginTileLocation.X, y].HasWire())
              return false;

              if (measureData.BlockType == BlockType.DoorOpened) {
            // Extra check needed if a port of the door is really hit. This is because doors define ports differently than
            // other components if they are opened.
            componentPorts = new List<DPoint>(AdvancedCircuits.EnumerateComponentPortLocations(measureData));
            if (!componentPorts.Contains(portLocation))
              return false;
              }

              this.OpenDoor(measureData, AdvancedCircuits.BoolToSignal(signal));
              break;
            }
            case BlockType.XSecondTimer: {
              if (!portTile.active() || portTile.type != (int)AdvancedCircuits.BlockType_InputPort)
            return false;

              bool currentState = (TerrariaUtils.Tiles.ObjectHasActiveState(measureData));
              if (currentState != signal)
            TerrariaUtils.Tiles.SetObjectState(measureData, signal);

              if (currentState != signal)
            this.CircuitHandler.RegisterUnregisterTimer(this.TriggeringPlayer, measureData, signal);
              else if (signal)
            this.CircuitHandler.ResetTimer(measureData);

              return true;
            }
            case BlockType.Switch:
            case BlockType.Lever: {
              if (measureData.BlockType == BlockType.Lever && TerrariaUtils.Tiles.IsObjectWired(measureData))
            return false;

              bool isInputPort = (portTile.active() && portTile.type == (int)AdvancedCircuits.BlockType_InputPort);
              bool currentState = (TerrariaUtils.Tiles.ObjectHasActiveState(measureData));
              if (isInputPort) {
            if (currentState != signal)
              TerrariaUtils.Tiles.SetObjectState(measureData, signal);

            return true;
              } else {
            switch (componentPaint) {
              default:
                if (currentState == signal)
                  return true;

                TerrariaUtils.Tiles.SetObjectState(measureData, signal);
                break;
              case AdvancedCircuits.Paint_Switch_ToggleAndForward:
                if (currentState != signal)
                  TerrariaUtils.Tiles.SetObjectState(measureData, signal);

                break;
              case AdvancedCircuits.Paint_Switch_ForwardIfEqual:
                if (currentState != signal)
                  return true;

                break;
              case AdvancedCircuits.Paint_Switch_ForwardIfEqualByChance:
                if (currentState != signal)
                  return true;

                if (CircuitProcessor.Random.Next(0, 2) == 0)
                  outputSignal = !signal;

                break;
              case AdvancedCircuits.Paint_Switch_ForwardByChance:
                if (CircuitProcessor.Random.Next(0, 2) == 0)
                  return true;

                break;
            }

            if (componentPaint != AdvancedCircuits.Paint_Switch_ToggleAndForward) {
              blockActivatorToRegister = rootBranch.BlockActivator;
              blockActivatorLocationToRegister = rootBranch.BlockActivatorLocation;
              blockActivatorModeToRegister = rootBranch.BlockActivatorMode;
            }
              }

              break;
            }
            case AdvancedCircuits.BlockType_NOTGate: {
              if (!portTile.active() || portTile.type != (int)AdvancedCircuits.BlockType_InputPort)
            return false;

              outputSignal = !signal;

              blockActivatorToRegister = rootBranch.BlockActivator;
              blockActivatorLocationToRegister = rootBranch.BlockActivatorLocation;
              blockActivatorModeToRegister = rootBranch.BlockActivatorMode;

              break;
            }
            case AdvancedCircuits.BlockType_ANDGate:
            case AdvancedCircuits.BlockType_ORGate:
            case AdvancedCircuits.BlockType_XORGate: {
              if (!portTile.active() || portTile.type != (int)AdvancedCircuits.BlockType_InputPort)
            return false;

              GateStateMetadata metadata;
              switch (componentPaint) {
            default:
              if (!this.CircuitHandler.WorldMetadata.GateStates.TryGetValue(componentLocation, out metadata)) {
                metadata = new GateStateMetadata();
                this.CircuitHandler.WorldMetadata.GateStates.Add(componentLocation, metadata);
              }
              break;
            case AdvancedCircuits.Paint_Gate_TemporaryState:
              if (!temporaryGateStates.TryGetValue(componentLocation, out metadata)) {
                metadata = new GateStateMetadata();
                temporaryGateStates.Add(componentLocation, metadata);
              }
              break;
              }

              componentPorts = new List<DPoint>(AdvancedCircuits.EnumerateComponentPortLocations(measureData));
              int inputPorts = 0;
              int signaledPorts = 0;
              bool isInvalid = false;
              for (int i = 0; i < componentPorts.Count; i++) {
            DPoint port = componentPorts[i];
            portTile = TerrariaUtils.Tiles[port];
            if (portTile.HasWire() && portTile.active() && portTile.type == (int)AdvancedCircuits.BlockType_InputPort) {
              inputPorts++;

              if (port == portLocation)
                metadata.PortStates[i] = outputSignal;

              if (metadata.PortStates[i] == null)
                isInvalid = true;
            }

            if (metadata.PortStates[i] != null && metadata.PortStates[i].Value)
              signaledPorts++;
              }

              // Gates will not operate as long as the input port states are not clear.
              if (isInvalid)
            return false;

              switch ((BlockType)componentTile.type) {
            case AdvancedCircuits.BlockType_ANDGate:
              outputSignal = (inputPorts == signaledPorts);
              break;
            case AdvancedCircuits.BlockType_ORGate:
              outputSignal = (signaledPorts > 0);
              break;
            case AdvancedCircuits.BlockType_XORGate:
              outputSignal = (signaledPorts != 0 && signaledPorts < inputPorts);
              break;
              }

              blockActivatorToRegister = rootBranch.BlockActivator;
              blockActivatorLocationToRegister = rootBranch.BlockActivatorLocation;
              blockActivatorModeToRegister = rootBranch.BlockActivatorMode;

              break;
            }
            case AdvancedCircuits.BlockType_Swapper: {
              if (!signal)
            return false;

              int swapperCounterValue;
              if (!this.CircuitHandler.WorldMetadata.Swappers.TryGetValue(componentLocation, out swapperCounterValue)) {
            this.CircuitHandler.WorldMetadata.Swappers.Add(componentLocation, 1);

            if (componentPaint == PaintColor.None)
              outputSignal = false;
            else
              return true;
              } else {
            swapperCounterValue++;

            bool sendSignal = true;
            int swapperCounterMax = AdvancedCircuits.SwapperPaintToCount(componentPaint);
            if (swapperCounterValue == swapperCounterMax) {
              outputSignal = false;
            } else if (swapperCounterValue >= swapperCounterMax * 2) {
              outputSignal = true;
              swapperCounterValue = 0;
            } else {
              sendSignal = false;
            }

            this.CircuitHandler.WorldMetadata.Swappers[componentLocation] = swapperCounterValue;
            if (!sendSignal)
              return true;
              }

              blockActivatorToRegister = rootBranch.BlockActivator;
              blockActivatorLocationToRegister = rootBranch.BlockActivatorLocation;
              blockActivatorModeToRegister = rootBranch.BlockActivatorMode;

              break;
            }
            case AdvancedCircuits.BlockType_CrossoverBridge: {
              switch (AdvancedCircuits.DirectionFromTileLocations(componentLocation, portLocation)) {
            case Direction.Left:
              componentPorts = new List<DPoint> { new DPoint(componentLocation.X + 1, componentLocation.Y) };
              break;
            case Direction.Up:
              componentPorts = new List<DPoint> { new DPoint(componentLocation.X, componentLocation.Y + 1) };
              break;
            case Direction.Right:
              componentPorts = new List<DPoint> { new DPoint(componentLocation.X - 1, componentLocation.Y) };
              break;
            case Direction.Down:
              componentPorts = new List<DPoint> { new DPoint(componentLocation.X, componentLocation.Y - 1) };
              break;
            default:
              throw new ArgumentOutOfRangeException();
              }

              blockActivatorToRegister = rootBranch.BlockActivator;
              blockActivatorLocationToRegister = rootBranch.BlockActivatorLocation;
              blockActivatorModeToRegister = rootBranch.BlockActivatorMode;

              break;
            }
            case AdvancedCircuits.BlockType_BlockActivator: {
              if (!portTile.active() || portTile.type != (int)AdvancedCircuits.BlockType_InputPort)
            return false;
              if (
            this.CircuitHandler.Config.BlockActivatorConfig.Cooldown > 0 &&
            !WorldGen.checkMech(componentLocation.X, componentLocation.Y, this.CircuitHandler.Config.BlockActivatorConfig.Cooldown
              ))
            return false;

              if (
            this.TriggeringPlayer != TSPlayer.Server &&
            !this.TriggeringPlayer.Group.HasPermission(AdvancedCircuitsPlugin.TriggerBlockActivator_Permission)
              ) {
            this.Result.WarnReason = CircuitWarnReason.InsufficientPermissionToSignalComponent;
            this.Result.WarnRelatedComponentType = AdvancedCircuits.BlockType_BlockActivator;
            return true;
              }

              BlockActivatorMetadata blockActivator;
              this.CircuitHandler.WorldMetadata.BlockActivators.TryGetValue(componentLocation, out blockActivator);

              if (signal) {
            if (blockActivator == null || blockActivator.IsActivated)
              return true;
              } else {
            if (blockActivator == null) {
              blockActivator = new BlockActivatorMetadata();
              this.CircuitHandler.WorldMetadata.BlockActivators.Add(componentLocation, blockActivator);
            } else {
              // Will do nothing if already deactivated.
              if (!blockActivator.IsActivated)
                return true;

              blockActivator.RegisteredInactiveBlocks.Clear();
            }
              }

              blockActivator.IsActivated = signal;
              if (signal && blockActivator.RegisteredInactiveBlocks.Count == 0)
            return true;

              blockActivatorToRegister = blockActivator;
              blockActivatorLocationToRegister = componentLocation;
              if (componentPaint == AdvancedCircuits.Paint_BlockActivator_Replace)
            blockActivatorModeToRegister = BlockActivatorMode.ReplaceBlocks;

              break;
            }
            case AdvancedCircuits.BlockType_WirelessTransmitter: {
              if (!portTile.active() || portTile.type != (int)AdvancedCircuits.BlockType_InputPort)
            return false;

              WirelessTransmitterConfig transmitterConfig;
              if (
            (
              this.CircuitHandler.Config.WirelessTransmitterConfigs.TryGetValue(componentPaint, out transmitterConfig) ||
              this.CircuitHandler.Config.WirelessTransmitterConfigs.TryGetValue(PaintColor.None, out transmitterConfig)
            ) && (
              transmitterConfig.Cooldown == 0 ||
              WorldGen.checkMech(componentLocation.X, componentLocation.Y, transmitterConfig.Cooldown)
            )
              ) {
            if (
              transmitterConfig.TriggerPermission != null &&
              this.TriggeringPlayer != TSPlayer.Server &&
              !this.TriggeringPlayer.Group.HasPermission(transmitterConfig.TriggerPermission)
            ) {
              this.Result.WarnReason = CircuitWarnReason.InsufficientPermissionToSignalComponent;
              this.Result.WarnRelatedComponentType = AdvancedCircuits.BlockType_WirelessTransmitter;
              return true;
            }

            string sendingTransmitterOwner;
            if (!this.CircuitHandler.WorldMetadata.WirelessTransmitters.TryGetValue(componentLocation, out sendingTransmitterOwner))
              return false;

            bool isBroadcasting = (transmitterConfig.Network == 0);
            double sendingSquareRange = 0;
            if (transmitterConfig.Range > 0)
              sendingSquareRange = Math.Pow(transmitterConfig.Range + 1, 2);

            DPoint portOffset = new DPoint(portLocation.X - componentLocation.X, portLocation.Y - componentLocation.Y);
            foreach (KeyValuePair<DPoint,string> pair in this.CircuitHandler.WorldMetadata.WirelessTransmitters) {
              DPoint receivingTransmitterLocation = pair.Key;
              if (receivingTransmitterLocation == componentLocation)
                continue;

              string receivingTransmitterOwner = pair.Value;
              if (receivingTransmitterOwner != sendingTransmitterOwner)
                continue;

              Tile transmitterTile = TerrariaUtils.Tiles[receivingTransmitterLocation];
              if (!transmitterTile.active() || transmitterTile.type != (int)AdvancedCircuits.BlockType_WirelessTransmitter || transmitterTile.HasWire())
                continue;

              if (
                sendingSquareRange > 0 &&
                sendingSquareRange <= (
                  Math.Pow(receivingTransmitterLocation.X - componentLocation.X, 2) +
                  Math.Pow(receivingTransmitterLocation.Y - componentLocation.Y, 2)
                )
              )
                continue;

              DPoint outputPortLocation = receivingTransmitterLocation.OffsetEx(portOffset.X, portOffset.Y);
              Tile outputPortTile = TerrariaUtils.Tiles[outputPortLocation];
              if (!outputPortTile.HasWire() || (outputPortTile.active() && outputPortTile.type == (int)AdvancedCircuits.BlockType_InputPort))
                continue;

              if (!isBroadcasting) {
                PaintColor receiverPaint = (PaintColor)TerrariaUtils.Tiles[receivingTransmitterLocation].color();
                WirelessTransmitterConfig receiverConfig;
                if (!this.CircuitHandler.Config.WirelessTransmitterConfigs.TryGetValue(receiverPaint, out receiverConfig))
                  receiverConfig = this.CircuitHandler.Config.WirelessTransmitterConfigs[PaintColor.None];

                if (receiverConfig.Network != 0 && receiverConfig.Network != transmitterConfig.Network)
                  continue;
              }

              bool portOutputSignal = outputSignal;
              if (outputPortTile.active() && outputPortTile.type == (int)AdvancedCircuits.BlockType_NOTGate)
                portOutputSignal = !portOutputSignal;
              else if (outputPortTile.active() && outputPortTile.type == (int)AdvancedCircuits.BlockType_XORGate)
                portOutputSignal = false;

              foreach (WireColor wireColor in AdvancedCircuits.EnumerateWireColors()) {
                if (!outputPortTile.HasWire(wireColor))
                  continue;

                this.QueuedRootBranches.Add(new RootBranchProcessData(receivingTransmitterLocation, outputPortLocation, AdvancedCircuits.BoolToSignal(portOutputSignal), wireColor) {
                  BlockActivator = rootBranch.BlockActivator,
                  BlockActivatorLocation = rootBranch.BlockActivatorLocation,
                  BlockActivatorMode = rootBranch.BlockActivatorMode,
                  TeleporterLocation = rootBranch.TeleporterLocation
                });
              }
            }

            return true;
              }

              break;
            }
            default:
              return false;
              }

              if (componentPorts == null)
            componentPorts = new List<DPoint>(AdvancedCircuits.EnumerateComponentPortLocations(measureData));

              for (int i = 0; i < componentPorts.Count; i++) {
            DPoint port = componentPorts[i];
            // A component shouldn't send a signal through a port where it just received one.
            if (port == portLocation) {
              componentPorts.RemoveAt(i--);
              continue;
            }

            portTile = TerrariaUtils.Tiles[port];
            if (!portTile.HasWire() || (portTile.active() && portTile.type == (int)AdvancedCircuits.BlockType_InputPort))
              componentPorts.RemoveAt(i--);
              }

              foreach (DPoint port in componentPorts) {
            portTile = TerrariaUtils.Tiles[port];
            bool portOutputSignal = outputSignal;
            if (
              portTile.active() && portTile.type == (int)AdvancedCircuits.BlockType_NOTGate &&
              measureData.BlockType != AdvancedCircuits.BlockType_NOTGate
            ) {
              portOutputSignal = !portOutputSignal;
            } else if (
              portTile.active() && portTile.type == (int)AdvancedCircuits.BlockType_XORGate &&
              measureData.BlockType != AdvancedCircuits.BlockType_XORGate
            ) {
              portOutputSignal = false;
            }

            foreach (WireColor wireColor in AdvancedCircuits.EnumerateWireColors()) {
              if (!portTile.HasWire(wireColor))
            continue;

              RootBranchProcessData newRootBranch = new RootBranchProcessData(
            componentLocation, port, AdvancedCircuits.BoolToSignal(portOutputSignal), wireColor
              );
              if (blockActivatorToRegister != null) {
            newRootBranch.BlockActivator = blockActivatorToRegister;
            newRootBranch.BlockActivatorLocation = blockActivatorLocationToRegister;
            newRootBranch.BlockActivatorMode = blockActivatorModeToRegister;
              }
              newRootBranch.TeleporterLocation = rootBranch.TeleporterLocation;

              this.QueuedRootBranches.Add(newRootBranch);
            }
              }

              return true;
        }
 public void ResetTimer(ObjectMeasureData measureData) {
   ActiveTimerMetadata activeTimer;
   if (this.WorldMetadata.ActiveTimers.TryGetValue(measureData.OriginTileLocation, out activeTimer))
     activeTimer.FramesLeft = AdvancedCircuits.MeasureTimerFrameTime(measureData.OriginTileLocation);
 }
Ejemplo n.º 16
0
 public bool IsObjectWired(ObjectMeasureData measureData, WireColor wireColor = WireColor.None) {
   DPoint dummy;
   return this.IsObjectWired(measureData, wireColor, out dummy);
 }
Ejemplo n.º 17
0
    public void SetObjectState(
      ObjectMeasureData measureData, bool activeState, bool sendTileSquare = true
    ) {
      #if DEBUG
      if (this.ObjectHasActiveState(measureData) == activeState) {
        throw new ArgumentException(
          $"The object \"{TerrariaUtils.Tiles.GetBlockTypeName(measureData.BlockType, 0)}\" does already have the state \"{activeState}\"."
        );
      }
      #endif

      int originX = measureData.OriginTileLocation.X;
      int originY = measureData.OriginTileLocation.Y;
      int objectWidth = measureData.Size.X;
      int objectHeight = measureData.Size.Y;
      int newFrameXOffset = 0;
      int newFrameYOffset = 0;
      if (measureData.BlockType == TileID.Torches || measureData.BlockType == TileID.HolidayLights)
        newFrameXOffset = measureData.TextureTileSize.X * 2;

      if (
        measureData.BlockType != TileID.Switches && 
        measureData.BlockType != TileID.Timers &&
        measureData.BlockType != TileID.WaterFountain
      ) {
        int frameXOffset = (objectWidth * measureData.TextureTileSize.X) + newFrameXOffset;
        if (measureData.BlockType == TileID.MusicBoxes)
          frameXOffset = -frameXOffset;

        if (activeState)
          newFrameXOffset = (short)-frameXOffset;
        else
          newFrameXOffset = (short)frameXOffset;

        if (measureData.BlockType == TileID.BubbleMachine && !activeState)
          newFrameYOffset = -TerrariaUtils.Tiles[measureData.OriginTileLocation].frameY;
      } else {
        int frameYOffset = (objectHeight * measureData.TextureTileSize.Y);
        if (measureData.BlockType == TileID.WaterFountain && !activeState) {
          newFrameYOffset = -TerrariaUtils.Tiles[measureData.OriginTileLocation].frameY;
        } else {
          if (
            measureData.BlockType == TileID.Timers ||
            measureData.BlockType == TileID.WaterFountain
          )
            activeState = !activeState;

          if (activeState)
            newFrameYOffset = (short)-frameYOffset;
          else
            newFrameYOffset = (short)frameYOffset;
        }
      }
        
      for (int tx = 0; tx < objectWidth; tx++) {
        for (int ty = 0; ty < objectHeight; ty++) {
          int absoluteX = originX + tx;
          int absoluteY = originY + ty;

          TerrariaUtils.Tiles[absoluteX, absoluteY].frameX += (short)newFrameXOffset;
          TerrariaUtils.Tiles[absoluteX, absoluteY].frameY += (short)newFrameYOffset;
        }
      }
            
      if (sendTileSquare)
        TSPlayer.All.SendTileSquareEx(originX, originY, Math.Max(objectWidth, objectHeight));
    }
        private void OpenDoor(ObjectMeasureData measureData, SignalType signal)
        {
            bool currentState = (measureData.BlockType == BlockType.DoorOpened);
              bool newState;
              if (signal == SignalType.Swap)
            newState = !currentState;
              else
            newState = AdvancedCircuits.SignalToBool(signal).Value;

              if (newState != currentState) {
            int doorX = measureData.OriginTileLocation.X;
            int doorY = measureData.OriginTileLocation.Y;

            if (newState) {
              // A door will always try to open to the opposite site of the sender's location that triggered the circuit first.
              int direction = 1;
              if (doorX < this.SenderMeasureData.OriginTileLocation.X)
            direction = -1;

              // If opening it towards one direction doesn't work, try the other.
              currentState = WorldGen.OpenDoor(doorX, doorY, direction);
              if (!currentState) {
            direction *= -1;
            currentState = WorldGen.OpenDoor(doorX, doorY, direction);
              }

              if (currentState) {
            TSPlayer.All.SendData(PacketTypes.DoorUse, string.Empty, 0, doorX, doorY, direction);
            // Because the door changed its sprite, we have to re-measure it now.
            measureData = TerrariaUtils.Tiles.MeasureObject(measureData.OriginTileLocation);
              }
            } else {
              if (WorldGen.CloseDoor(doorX, doorY, true))
            TSPlayer.All.SendData(PacketTypes.DoorUse, string.Empty, 1, doorX, doorY);
            }

            WorldGen.numWire = 0;
            WorldGen.numNoWire = 0;
              }
        }
        private void OpenDoor(ObjectMeasureData measureData, SignalType signal)
        {
            bool currentState = false;
              DoorAction action = DoorAction.Invalid;
              switch (measureData.BlockType) {
            case BlockType.DoorClosed:
              currentState = false;
              action = DoorAction.OpenDoor;
              break;
            case BlockType.DoorOpened:
              currentState = true;
              action = DoorAction.CloseDoor;
              break;
            case BlockType.TallGateClosed:
              currentState = false;
              action = DoorAction.OpenTallGate;
              break;
            case BlockType.TallGateOpen:
              currentState = true;
              action = DoorAction.CloseTallGate;
              break;
            case BlockType.TrapdoorClosed:
              currentState = false;
              action = DoorAction.OpenTrapdoor;
              break;
            case BlockType.TrapdoorOpen:
              currentState = true;
              action = DoorAction.CloseTrapdoor;
              break;
              }

              bool newState;
              if (signal == SignalType.Swap)
            newState = !currentState;
              else
            newState = AdvancedCircuits.SignalToBool(signal).Value;

              if (newState != currentState) {
            int doorX = measureData.OriginTileLocation.X;
            int doorY = measureData.OriginTileLocation.Y;
            int direction = 1;

            // Tall gates dont care direction
            if (action == DoorAction.OpenTallGate || action == DoorAction.CloseTallGate) {
              if(WorldGen.ShiftTallGate(doorX, doorY, action == DoorAction.CloseTallGate))
            TSPlayer.All.SendData(PacketTypes.DoorUse, string.Empty, (int)action, doorX, doorY);
            }

            if (action == DoorAction.OpenDoor) {
              // A door will always try to open to the opposite site of the sender's location that triggered the circuit first.
              if (doorX < this.SenderMeasureData.OriginTileLocation.X)
            direction = -1;

              // If opening it towards one direction doesn't work, try the other.
              currentState = WorldGen.OpenDoor(doorX, doorY, direction);
              if (!currentState) {
            direction *= -1;
            currentState = WorldGen.OpenDoor(doorX, doorY, direction);
              }
              if (currentState) {
            TSPlayer.All.SendData(PacketTypes.DoorUse, string.Empty, (int)action, doorX, doorY, direction);
              }
            }
            else if (action == DoorAction.CloseDoor) {
              if (WorldGen.CloseDoor(doorX, doorY, true)) {
            TSPlayer.All.SendData(PacketTypes.DoorUse, string.Empty, (int)action, doorX, doorY, direction);
            // Because the door changed its sprite, we have to re-measure it now.
            measureData = TerrariaUtils.Tiles.MeasureObject(measureData.OriginTileLocation);
              }
            }
            else if (action == DoorAction.OpenTrapdoor) {
              // A trapdoor will always try to open to the opposite site of the sender's location that triggered the circuit first.
              // direction: 1 is up, -1 is down;
              if (doorY < this.SenderMeasureData.OriginTileLocation.Y)
            direction = -1;

              // If opening it towards one direction doesn't work, try the other.
              currentState = WorldGen.ShiftTrapdoor(doorX, doorY, direction == -1);
              if (!currentState) {
            direction *= -1;
            currentState = WorldGen.ShiftTrapdoor(doorX, doorY, direction == -1);
              }

              if (currentState) {
            TSPlayer.All.SendData(PacketTypes.DoorUse, string.Empty, (int)action, doorX, doorY, direction);
            // Because the door changed its sprite, we have to re-measure it now.
            measureData = TerrariaUtils.Tiles.MeasureObject(measureData.OriginTileLocation);
              }
            }
            else if (action == DoorAction.CloseTrapdoor) {
              if (doorY < this.SenderMeasureData.OriginTileLocation.Y)
            direction = -1;
              if (WorldGen.ShiftTrapdoor(doorX, doorY, direction == -1)) {
            direction *= -1;
            TSPlayer.All.SendData(PacketTypes.DoorUse, string.Empty, (int)action, doorX, doorY, direction);
            // Because the door changed its sprite, we have to re-measure it now.
            measureData = TerrariaUtils.Tiles.MeasureObject(measureData.OriginTileLocation);
              }
            }
              }
        }
Ejemplo n.º 20
0
 public IEnumerable<Tile> EnumerateObjectTiles(ObjectMeasureData measureData)
 {
     foreach (DPoint tileLocation in this.EnumerateObjectTileLocations(measureData))
     yield return TerrariaUtils.Tiles[tileLocation];
 }
Ejemplo n.º 21
0
        public bool IsObjectWired(ObjectMeasureData measureData, WireColor wireColor, out DPoint firstWireLocation)
        {
            foreach (DPoint tileLocation in this.EnumerateObjectTileLocations(measureData)) {
            Tile tile = TerrariaUtils.Tiles[tileLocation];
            if (tile.HasWire(wireColor)) {
              firstWireLocation = tileLocation;
              return true;
            }
              }

              firstWireLocation = DPoint.Empty;
              return false;
        }
        public static DPoint GetPortAdjacentComponentTileLocation(ObjectMeasureData measureData, DPoint portLocation)
        {
            DPoint origin = measureData.OriginTileLocation;
              DPoint size = measureData.Size;
              if (measureData.BlockType == BlockType.DoorOpened)
            size = new DPoint(1, 3);

              if (portLocation.X < origin.X)
            return new DPoint(origin.X, portLocation.Y);
              if (portLocation.Y < origin.Y)
            return new DPoint(portLocation.X, origin.Y);
              if (portLocation.X >= origin.X + size.X)
            return new DPoint(origin.X + size.X - 1, portLocation.Y);
              if (portLocation.Y >= origin.Y + size.Y)
            return new DPoint(portLocation.X, origin.Y + size.Y - 1);

              throw new ArgumentException("The given port location referes to no port of this component at all.", "portLocation");
        }
Ejemplo n.º 23
0
 public bool IsObjectWired(ObjectMeasureData measureData, WireColor wireColor = WireColor.None)
 {
     DPoint dummy;
       return this.IsObjectWired(measureData, wireColor, out dummy);
 }
        public static IEnumerable<DPoint> EnumerateComponentPortLocations(ObjectMeasureData measureData)
        {
            DPoint componentOriginLocation = measureData.OriginTileLocation;
              DPoint componentSize = measureData.Size;
              if (measureData.BlockType == BlockType.DoorOpened)
            componentSize = new DPoint(1, 3);

              return AdvancedCircuits.EnumerateComponentPortLocations(componentOriginLocation, componentSize);
        }
Ejemplo n.º 25
0
        private IEnumerable<ProtectionEntry> EnumProtectionEntriesOnTopOfObject(ObjectMeasureData measureData)
        {
            for (int rx = 0; rx < measureData.Size.X; rx++) {
            DPoint absoluteLocation = measureData.OriginTileLocation.OffsetEx(rx, -1);

            Tile topTile = TerrariaUtils.Tiles[absoluteLocation];
            TileObjectData topData = TileObjectData.GetTileData(topTile);
            if (topData != null && (topData.AnchorBottom.type & AnchorType.Table) != 0) {
              lock (this.WorldMetadata.Protections) {
            ProtectionEntry protection;
            if (this.WorldMetadata.Protections.TryGetValue(absoluteLocation, out protection))
              yield return protection;
              }
            }
              }
        }