private void SendGatePortStatesInfo(TSPlayer player, GateStateMetadata gateState) { player.SendMessage("Top Port: " + this.GatePortStateToString(gateState.PortStates[0]), Color.LightGray); player.SendMessage("Left Port: " + this.GatePortStateToString(gateState.PortStates[2]), Color.LightGray); player.SendMessage("Bottom Port: " + this.GatePortStateToString(gateState.PortStates[1]), Color.LightGray); player.SendMessage("Right Port: " + this.GatePortStateToString(gateState.PortStates[3]), Color.LightGray); }
private bool TryExecuteSubCommand(string commandNameLC, CommandArgs args) { switch (commandNameLC) { case "commands": case "cmds": args.Player.SendMessage("Available Sub-Commands:", Color.White); args.Player.SendMessage("/ac blocks", Color.Yellow); args.Player.SendMessage("/ac toggle|switch", Color.Yellow); if (args.Player.Group.HasPermission(AdvancedCircuitsPlugin.ReloadCfg_Permission)) { args.Player.SendMessage("/ac reloadcfg", Color.Yellow); } return(true); case "reloadcfg": if (args.Player.Group.HasPermission(AdvancedCircuitsPlugin.ReloadCfg_Permission)) { this.PluginTrace.WriteLineInfo("Reloading configuration file."); try { this.ReloadConfigurationCallback(); this.PluginTrace.WriteLineInfo("Configuration file successfully reloaded."); if (args.Player != TSPlayer.Server) { args.Player.SendMessage("Configuration file successfully reloaded.", Color.Yellow); } } catch (Exception ex) { this.PluginTrace.WriteLineError( "Reloading the configuration file failed. Keeping old configuration. Exception details:\n{0}", ex ); } } else { args.Player.SendErrorMessage("You do not have the necessary permission to do that."); } return(true); case "blocks": case "ores": case "tiles": int pageNumber; if (!PaginationTools.TryParsePageNumber(args.Parameters, 1, args.Player, out pageNumber)) { return(true); } PaginationTools.SendPage( args.Player, pageNumber, new List <string>() { "Copper Ore - OR-Gate", "Silver Ore - AND-Gate", "Gold Ore - XOR-Gate / XOR-Port", "Obsidian - NOT-Gate / NOT-Port", "Iron Ore - Swapper", "Spike - Crossover Bridge", "Glass - Input Port", "Active Stone - Active Stone and Block Activator", "Adamantite Ore - Wireless Transmitter" }, new PaginationTools.Settings { HeaderFormat = "Advanced Circuits Special Blocks (Page {0} of {1})", HeaderTextColor = Color.Lime, LineTextColor = Color.LightGray, MaxLinesPerPage = 4, } ); return(true); case "toggle": case "switch": args.Player.SendInfoMessage("Place or destroy a wire on the component you want to toggle."); if (args.Parameters.Count > 3) { args.Player.SendErrorMessage("Proper syntax: /ac switch [state] [+p]"); args.Player.SendInfoMessage("Type /ac switch help to get more help to this command."); return(true); } bool persistentMode = false; bool?newState = null; if (args.Parameters.Count > 1) { int newStateRaw; if (int.TryParse(args.Parameters[1], out newStateRaw)) { newState = (newStateRaw == 1); } persistentMode = args.ContainsParameter("+p", StringComparison.InvariantCultureIgnoreCase); } CommandInteraction interaction = this.StartOrResetCommandInteraction(args.Player); interaction.DoesNeverComplete = persistentMode; interaction.TileEditCallback = (player, editType, blockType, location, blockStyle) => { if ( editType != TileEditType.PlaceTile || editType != TileEditType.PlaceWall || editType != TileEditType.DestroyWall || editType != TileEditType.PlaceActuator ) { CommandInteractionResult result = new CommandInteractionResult { IsHandled = true, IsInteractionCompleted = true }; ITile tile = TerrariaUtils.Tiles[location]; if ( !args.Player.HasBuildPermission(location.X, location.Y) || ( this.PluginCooperationHandler.IsProtectorAvailable && this.PluginCooperationHandler.Protector_CheckProtected(args.Player, location, false) )) { player.SendErrorMessage("This object is protected."); player.SendTileSquare(location, 1); return(result); } int hitBlockType = tile.type; if (tile.active() && hitBlockType == TileID.ActiveStoneBlock) { if (newState == null || newState == false) { TerrariaUtils.Tiles.SetBlock(location, TileID.InactiveStoneBlock); } else { args.Player.SendTileSquare(location); } } else if (hitBlockType == TileID.InactiveStoneBlock) { if (tile.active() && newState == null || newState == true) { TerrariaUtils.Tiles.SetBlock(location, TileID.ActiveStoneBlock); } else { args.Player.SendTileSquare(location); } } else if (tile.active() && TerrariaUtils.Tiles.IsMultistateObject(hitBlockType)) { ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(location); bool currentState = TerrariaUtils.Tiles.ObjectHasActiveState(measureData); if (newState == null) { newState = !TerrariaUtils.Tiles.ObjectHasActiveState(measureData); } if (currentState != newState.Value) { TerrariaUtils.Tiles.SetObjectState(measureData, newState.Value); } else { args.Player.SendTileSquare(location); } } else if ( hitBlockType == AdvancedCircuits.BlockType_ORGate || hitBlockType == AdvancedCircuits.BlockType_ANDGate || hitBlockType == AdvancedCircuits.BlockType_XORGate ) { if ( !args.Player.HasBuildPermission(location.X, location.Y) || ( this.PluginCooperationHandler.IsProtectorAvailable && this.PluginCooperationHandler.Protector_CheckProtected(args.Player, location, false) )) { player.SendErrorMessage("This gate is protected."); player.SendTileSquare(location); return(result); } PaintColor paint = (PaintColor)TerrariaUtils.Tiles[location].color(); if (paint == AdvancedCircuits.Paint_Gate_TemporaryState) { player.SendErrorMessage("The gate is painted {0}, there's no point in initializing it.", AdvancedCircuits.Paint_Gate_TemporaryState); args.Player.SendTileSquare(location); return(result); } GateStateMetadata gateState; if (!this.WorldMetadata.GateStates.TryGetValue(location, out gateState)) { gateState = new GateStateMetadata(); this.WorldMetadata.GateStates.Add(location, gateState); } List <DPoint> gatePortLocations = new List <DPoint>(AdvancedCircuits.EnumerateComponentPortLocations(location, new DPoint(1, 1))); for (int i = 0; i < 4; i++) { ITile gatePort = TerrariaUtils.Tiles[gatePortLocations[i]]; if (!gatePort.active() || gatePort.type != (int)AdvancedCircuits.BlockType_InputPort) { continue; } if (newState == null) { if (gateState.PortStates[i] == null) { gateState.PortStates[i] = true; } else { gateState.PortStates[i] = !gateState.PortStates[i]; } } else { gateState.PortStates[i] = newState.Value; } } player.SendSuccessMessage("The states of this gate's ports are now:"); this.SendGatePortStatesInfo(args.Player, gateState); args.Player.SendTileSquare(location); } else if (tile.active() && tile.type == (int)AdvancedCircuits.BlockType_InputPort) { foreach (DPoint adjacentTileLocation in AdvancedCircuits.EnumerateComponentPortLocations(location, new DPoint(1, 1))) { ITile adjacentTile = TerrariaUtils.Tiles[adjacentTileLocation]; if (!adjacentTile.active() || !AdvancedCircuits.IsLogicalGate(adjacentTile.type)) { continue; } if ( !args.Player.HasBuildPermission(adjacentTileLocation.X, adjacentTileLocation.Y) || ( this.PluginCooperationHandler.IsProtectorAvailable && this.PluginCooperationHandler.Protector_CheckProtected(args.Player, adjacentTileLocation, false) )) { player.SendErrorMessage("This gate is protected."); player.SendTileSquare(location); return(result); } PaintColor paint = (PaintColor)TerrariaUtils.Tiles[location].color(); if (paint == AdvancedCircuits.Paint_Gate_TemporaryState) { player.SendErrorMessage("The gate is painted {0}, there's no point in initializing it.", AdvancedCircuits.Paint_Gate_TemporaryState); args.Player.SendTileSquare(location); return(result); } GateStateMetadata gateState; if (!this.WorldMetadata.GateStates.TryGetValue(adjacentTileLocation, out gateState)) { gateState = new GateStateMetadata(); this.WorldMetadata.GateStates.Add(adjacentTileLocation, gateState); } int portIndex; switch (AdvancedCircuits.DirectionFromTileLocations(adjacentTileLocation, location)) { case Direction.Up: portIndex = 0; break; case Direction.Down: portIndex = 1; break; case Direction.Left: portIndex = 2; break; case Direction.Right: portIndex = 3; break; default: return(result); } if (newState == null) { if (gateState.PortStates[portIndex] == null) { gateState.PortStates[portIndex] = true; } else { gateState.PortStates[portIndex] = !gateState.PortStates[portIndex]; } } else { gateState.PortStates[portIndex] = newState.Value; } player.SendSuccessMessage("The states of this gate's ports are now:"); this.SendGatePortStatesInfo(args.Player, gateState); args.Player.SendTileSquare(location); return(result); } player.SendErrorMessage($"The state of \"{TerrariaUtils.Tiles.GetBlockTypeName(hitBlockType, 0)}\" can not be changed."); player.SendTileSquare(location); } return(result); } return(new CommandInteractionResult { IsHandled = false, IsInteractionCompleted = false }); }; interaction.TimeExpiredCallback = (player) => { player.SendErrorMessage("Waited too long, no component will be toggled."); }; args.Player.SendSuccessMessage("Hit an object to change its state."); return(true); } return(false); }
private bool TryExecuteSubCommand(string commandNameLC, CommandArgs args) { switch (commandNameLC) { case "commands": case "cmds": args.Player.SendMessage("Available Sub-Commands:", Color.White); args.Player.SendMessage("/ac blocks", Color.Yellow); args.Player.SendMessage("/ac toggle|switch", Color.Yellow); if (args.Player.Group.HasPermission(AdvancedCircuitsPlugin.ReloadCfg_Permission)) args.Player.SendMessage("/ac reloadcfg", Color.Yellow); return true; case "reloadcfg": if (args.Player.Group.HasPermission(AdvancedCircuitsPlugin.ReloadCfg_Permission)) { this.PluginTrace.WriteLineInfo("Reloading configuration file."); try { this.ReloadConfigurationCallback(); this.PluginTrace.WriteLineInfo("Configuration file successfully reloaded."); if (args.Player != TSPlayer.Server) args.Player.SendMessage("Configuration file successfully reloaded.", Color.Yellow); } catch (Exception ex) { this.PluginTrace.WriteLineError( "Reloading the configuration file failed. Keeping old configuration. Exception details:\n{0}", ex ); } } else { args.Player.SendErrorMessage("You do not have the necessary permission to do that."); } return true; case "blocks": case "ores": case "tiles": int pageNumber; if (!PaginationUtil.TryParsePageNumber(args.Parameters, 1, args.Player, out pageNumber)) return true; PaginationUtil.SendPage( args.Player, pageNumber, new List<string>() { "Copper Ore - OR-Gate", "Silver Ore - AND-Gate", "Gold Ore - XOR-Gate / XOR-Port", "Obsidian - NOT-Gate / NOT-Port", "Iron Ore - Swapper", "Spike - Crossover Bridge", "Glass - Input Port", "Active Stone - Active Stone and Block Activator", "Adamantite Ore - Wireless Transmitter" }, new PaginationUtil.Settings { HeaderFormat = "Advanced Circuits Special Blocks (Page {0} of {1})", HeaderTextColor = Color.Lime, LineTextColor = Color.LightGray, MaxLinesPerPage = 4, } ); return true; case "toggle": case "switch": args.Player.SendInfoMessage("Place or destroy a wire on the component you want to toggle."); if (args.Parameters.Count > 3) { args.Player.SendErrorMessage("Proper syntax: /ac switch [state] [+p]"); args.Player.SendInfoMessage("Type /ac switch help to get more help to this command."); return true; } bool persistentMode = false; bool? newState = null; if (args.Parameters.Count > 1) { int newStateRaw; if (int.TryParse(args.Parameters[1], out newStateRaw)) newState = (newStateRaw == 1); persistentMode = args.ContainsParameter("+p", StringComparison.InvariantCultureIgnoreCase); } CommandInteraction interaction = this.StartOrResetCommandInteraction(args.Player); interaction.DoesNeverComplete = persistentMode; interaction.TileEditCallback = (player, editType, blockType, location, blockStyle) => { if ( editType != TileEditType.PlaceTile || editType != TileEditType.PlaceWall || editType != TileEditType.DestroyWall || editType != TileEditType.PlaceActuator ) { CommandInteractionResult result = new CommandInteractionResult { IsHandled = true, IsInteractionCompleted = true }; Tile tile = TerrariaUtils.Tiles[location]; if ( TShock.CheckTilePermission(args.Player, location.X, location.Y) || ( this.PluginCooperationHandler.IsProtectorAvailable && this.PluginCooperationHandler.Protector_CheckProtected(args.Player, location, false) ) ) { player.SendErrorMessage("This object is protected."); player.SendTileSquare(location, 1); return result; } BlockType hitBlockType = (BlockType)tile.type; if (tile.active() && hitBlockType == BlockType.ActiveStone) { if (newState == null || newState == false) TerrariaUtils.Tiles.SetBlock(location, BlockType.InactiveStone); else args.Player.SendTileSquare(location); } else if (hitBlockType == BlockType.InactiveStone) { if (tile.active() && newState == null || newState == true) TerrariaUtils.Tiles.SetBlock(location, BlockType.ActiveStone); else args.Player.SendTileSquare(location); } else if (tile.active() && TerrariaUtils.Tiles.IsMultistateObject(hitBlockType)) { ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(location); bool currentState = TerrariaUtils.Tiles.ObjectHasActiveState(measureData); if (newState == null) newState = !TerrariaUtils.Tiles.ObjectHasActiveState(measureData); if (currentState != newState.Value) TerrariaUtils.Tiles.SetObjectState(measureData, newState.Value); else args.Player.SendTileSquare(location); } else if ( hitBlockType == AdvancedCircuits.BlockType_ORGate || hitBlockType == AdvancedCircuits.BlockType_ANDGate || hitBlockType == AdvancedCircuits.BlockType_XORGate ) { if ( TShock.CheckTilePermission(args.Player, location.X, location.Y) || ( this.PluginCooperationHandler.IsProtectorAvailable && this.PluginCooperationHandler.Protector_CheckProtected(args.Player, location, false) )) { player.SendErrorMessage("This gate is protected."); player.SendTileSquare(location); return result; } PaintColor paint = (PaintColor)TerrariaUtils.Tiles[location].color(); if (paint == AdvancedCircuits.Paint_Gate_TemporaryState) { player.SendErrorMessage("The gate is painted {0}, there's no point in initializing it.", AdvancedCircuits.Paint_Gate_TemporaryState); args.Player.SendTileSquare(location); return result; } GateStateMetadata gateState; if (!this.WorldMetadata.GateStates.TryGetValue(location, out gateState)) { gateState = new GateStateMetadata(); this.WorldMetadata.GateStates.Add(location, gateState); } List<DPoint> gatePortLocations = new List<DPoint>(AdvancedCircuits.EnumerateComponentPortLocations(location, new DPoint(1, 1))); for (int i = 0; i < 4; i++) { Tile gatePort = TerrariaUtils.Tiles[gatePortLocations[i]]; if (!gatePort.active() || gatePort.type != (int)AdvancedCircuits.BlockType_InputPort) continue; if (newState == null) { if (gateState.PortStates[i] == null) gateState.PortStates[i] = true; else gateState.PortStates[i] = !gateState.PortStates[i]; } else { gateState.PortStates[i] = newState.Value; } } player.SendSuccessMessage("The states of this gate's ports are now:"); this.SendGatePortStatesInfo(args.Player, gateState); args.Player.SendTileSquare(location); } else if (tile.active() && tile.type == (int)AdvancedCircuits.BlockType_InputPort) { foreach (DPoint adjacentTileLocation in AdvancedCircuits.EnumerateComponentPortLocations(location, new DPoint(1, 1))) { Tile adjacentTile = TerrariaUtils.Tiles[adjacentTileLocation]; if (!adjacentTile.active() || !AdvancedCircuits.IsLogicalGate((BlockType)adjacentTile.type)) continue; if ( TShock.CheckTilePermission(args.Player, adjacentTileLocation.X, adjacentTileLocation.Y) || ( this.PluginCooperationHandler.IsProtectorAvailable && this.PluginCooperationHandler.Protector_CheckProtected(args.Player, adjacentTileLocation, false) ) ) { player.SendErrorMessage("This gate is protected."); player.SendTileSquare(location); return result; } PaintColor paint = (PaintColor)TerrariaUtils.Tiles[location].color(); if (paint == AdvancedCircuits.Paint_Gate_TemporaryState) { player.SendErrorMessage("The gate is painted {0}, there's no point in initializing it.", AdvancedCircuits.Paint_Gate_TemporaryState); args.Player.SendTileSquare(location); return result; } GateStateMetadata gateState; if (!this.WorldMetadata.GateStates.TryGetValue(adjacentTileLocation, out gateState)) { gateState = new GateStateMetadata(); this.WorldMetadata.GateStates.Add(adjacentTileLocation, gateState); } int portIndex; switch (AdvancedCircuits.DirectionFromTileLocations(adjacentTileLocation, location)) { case Direction.Up: portIndex = 0; break; case Direction.Down: portIndex = 1; break; case Direction.Left: portIndex = 2; break; case Direction.Right: portIndex = 3; break; default: return result; } if (newState == null) { if (gateState.PortStates[portIndex] == null) gateState.PortStates[portIndex] = true; else gateState.PortStates[portIndex] = !gateState.PortStates[portIndex]; } else { gateState.PortStates[portIndex] = newState.Value; } player.SendSuccessMessage("The states of this gate's ports are now:"); this.SendGatePortStatesInfo(args.Player, gateState); args.Player.SendTileSquare(location); return result; } player.SendErrorMessage(string.Format( "The state of \"{0}\" can not be changed.", TerrariaUtils.Tiles.GetBlockTypeName(hitBlockType) )); player.SendTileSquare(location); } return result; } return new CommandInteractionResult { IsHandled = false, IsInteractionCompleted = false }; }; interaction.TimeExpiredCallback = (player) => { player.SendErrorMessage("Waited too long, no component will be toggled."); }; args.Player.SendSuccessMessage("Hit an object to change its state."); 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; }
private void SendGatePortStatesInfo(TSPlayer player, GateStateMetadata gateState) { player.SendMessage("Top Port: " + this.GatePortStateToString(gateState.PortStates[0]), Color.LightGray); player.SendMessage("Left Port: " + this.GatePortStateToString(gateState.PortStates[2]), Color.LightGray); player.SendMessage("Bottom Port: " + this.GatePortStateToString(gateState.PortStates[1]), Color.LightGray); player.SendMessage("Right Port: " + this.GatePortStateToString(gateState.PortStates[3]), Color.LightGray); }