public bool HandleHitSwitch(TSPlayer player, DPoint tileLocation) { ITile tile = TerrariaUtils.Tiles[tileLocation]; if ( tile.type == TileID.PressurePlates && TerrariaUtils.Tiles.GetPressurePlateKind(tile.frameY / 18) == PressurePlateKind.TriggeredByNpcsEnemies ) { return(true); } if (tile.type == TileID.Timers) { ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(tileLocation); bool isActive = TerrariaUtils.Tiles.ObjectHasActiveState(measureData); this.RegisterUnregisterTimer(player, measureData, !isActive); TerrariaUtils.Tiles.SetObjectState(measureData, !isActive, false); } else { try { this.ProcessCircuit(player, tileLocation); } catch (Exception ex) { this.PluginTrace.WriteLineError( "HitSwitch for \"{0}\" at {1} failed. See inner exception for details.\n{2}", TerrariaUtils.Tiles.GetBlockTypeName(TerrariaUtils.Tiles[tileLocation]), tileLocation, ex.ToString() ); } } NetMessage.SendData((int)PacketTypes.HitSwitch, -1, player.Index, NetworkText.Empty, tileLocation.X, tileLocation.Y); return(true); }
public CircuitHandler(PluginTrace pluginTrace, Configuration config, WorldMetadata worldMetadata, PluginCooperationHandler pluginCooperationHandler) { Contract.Requires <ArgumentNullException>(pluginTrace != null); Contract.Requires <ArgumentNullException>(config != null); Contract.Requires <ArgumentNullException>(worldMetadata != null); Contract.Requires <ArgumentNullException>(pluginCooperationHandler != null); this.PluginTrace = pluginTrace; this.Config = config; this.WorldMetadata = worldMetadata; this.PluginCooperationHandler = pluginCooperationHandler; this.isDayTime = Main.dayTime; this.isDaylight = (Main.dayTime && Main.time >= 7200 && Main.time <= 46800); // Timers are always inactive when a map is loaded, so switch them into their active state. foreach (DPoint activeTimerLocation in this.WorldMetadata.ActiveTimers.Keys) { ObjectMeasureData timerMeasureData = TerrariaUtils.Tiles.MeasureObject(activeTimerLocation); if (!TerrariaUtils.Tiles.ObjectHasActiveState(timerMeasureData)) { TerrariaUtils.Tiles.SetObjectState(timerMeasureData, true); } } }
public static DPoint GetPortAdjacentComponentTileLocation(ObjectMeasureData measureData, DPoint portLocation) { DPoint origin = measureData.OriginTileLocation; DPoint size = measureData.Size; if (measureData.BlockType == TileID.OpenDoor) { size = new DPoint(1, 3); } else if (measureData.BlockType == TileID.TrapdoorOpen) { size = new DPoint(2, 2); } 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"); }
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); } } } } }
protected override IMetadataFile InitMetadata() { WorldMetadata metadata = new WorldMetadata(); this.PluginTrace.WriteLineInfo("Starting one time metadata initialization..."); for (int x = 0; x < Main.maxTilesX - 1; x++) { for (int y = 0; y < Main.maxTilesY - 1; y++) { if (!TerrariaUtils.Tiles[x, y].active()) { continue; } DPoint tileLocation = new DPoint(x, y); switch (TerrariaUtils.Tiles[x, y].type) { case TileID.Timers: { // Is active timer? if (TerrariaUtils.Tiles[x, y].frameY > 0) { if (!metadata.ActiveTimers.ContainsKey(tileLocation)) { metadata.ActiveTimers.Add(tileLocation, new ActiveTimerMetadata()); } } break; } case TileID.GrandfatherClocks: { ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(tileLocation); if (!metadata.Clocks.ContainsKey(measureData.OriginTileLocation)) { metadata.Clocks.Add(measureData.OriginTileLocation, new GrandfatherClockMetadata(null)); } break; } case AdvancedCircuits.BlockType_WirelessTransmitter: { foreach (DPoint portLocation in AdvancedCircuits.EnumerateComponentPortLocations(tileLocation, new DPoint(1, 1))) { if (TerrariaUtils.Tiles[portLocation].HasWire() && !metadata.WirelessTransmitters.ContainsKey(tileLocation)) { metadata.WirelessTransmitters.Add(tileLocation, "{Server}"); } } break; } } } } this.PluginTrace.WriteLineInfo("Metadata initialization complete."); return(metadata); }
public void ResetTimer(ObjectMeasureData measureData) { ActiveTimerMetadata activeTimer; if (this.WorldMetadata.ActiveTimers.TryGetValue(measureData.OriginTileLocation, out activeTimer)) { activeTimer.FramesLeft = AdvancedCircuits.MeasureTimerFrameTime(measureData.OriginTileLocation); } }
public static IEnumerable <DPoint> EnumerateComponentPortLocations(ObjectMeasureData measureData) { DPoint componentOriginLocation = measureData.OriginTileLocation; DPoint componentSize = measureData.Size; if (measureData.BlockType == TileID.OpenDoor) { componentSize = new DPoint(1, 3); } return(AdvancedCircuits.EnumerateComponentPortLocations(componentOriginLocation, componentSize)); }
public override bool HandleTileEdit(TSPlayer player, TileEditType editType, int blockType, DPoint location, int objectStyle) { if (this.IsDisposed) { return(false); } if (base.HandleTileEdit(player, editType, blockType, location, objectStyle)) { return(true); } if (editType == TileEditType.PlaceTile) { return(this.HandleTilePlace(player, blockType, location, objectStyle)); } if (editType == TileEditType.TileKill || editType == TileEditType.TileKillNoItem) { return(this.HandleTileDestruction(player, location)); } if (editType == TileEditType.PlaceWire || editType == TileEditType.PlaceWireBlue || editType == TileEditType.PlaceWireGreen || editType == TileEditType.PlaceWireYellow) { return(this.HandleWirePlace(player, location)); } #if DEBUG || Testrun if (editType == TileEditType.DestroyWire) { player.SendMessage(location.ToString(), Color.Aqua); if (!TerrariaUtils.Tiles[location].active()) { return(false); } ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(location); player.SendInfoMessage(string.Format( "X: {0}, Y: {1}, FrameX: {2}, FrameY: {3}, Origin X: {4}, Origin Y: {5}, Active State: {6} Paint:{7}", location.X, location.Y, TerrariaUtils.Tiles[location].frameX, TerrariaUtils.Tiles[location].frameY, measureData.OriginTileLocation.X, measureData.OriginTileLocation.Y, TerrariaUtils.Tiles.ObjectHasActiveState(measureData), TerrariaUtils.Tiles[location].color() )); } #endif return(false); }
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); } }
public static void IsObjectActive(int x, int y, bool expectedState) { Tile tile = TerrariaUtils.Tiles[x, y]; if (!tile.active()) { throw new AssertException( string.Format("Assert failed. There is no tile at [{0},{1}].", x, y) ); } ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(new DPoint(x, y)); bool isActive = TerrariaUtils.Tiles.ObjectHasActiveState(measureData); if (isActive != expectedState) { string actualStateString; if (isActive) { actualStateString = "active"; } else { actualStateString = "inactive"; } string expectedStateString; if (expectedState) { expectedStateString = "Active"; } else { expectedStateString = "Inactive"; } throw new AssertException(string.Format( "Assert failed. {0} frame for object \"{1}\" at [{2},{3}] was expected, but it is {4}.", expectedStateString, TerrariaUtils.Tiles.GetBlockTypeName((BlockType)tile.type), x, y, actualStateString )); } }
private IEnumerable <ProtectionEntry> EnumProtectionEntriesOnTopOfObject(ObjectMeasureData measureData) { for (int rx = 0; rx < measureData.Size.X; rx++) { DPoint absoluteLocation = measureData.OriginTileLocation.OffsetEx(rx, -1); ITile 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); } } } } }
public void HandleGameUpdate() { this.frameCounter++; if (this.frameCounter % CircuitHandler.TimerUpdateFrameRate == 0) { List <DPoint> timersToDelete = null; List <KeyValuePair <DPoint, ActiveTimerMetadata> > timersToProcess = null; foreach (KeyValuePair <DPoint, ActiveTimerMetadata> activeTimer in this.WorldMetadata.ActiveTimers) { DPoint timerLocation = activeTimer.Key; ActiveTimerMetadata timerMetadata = activeTimer.Value; ITile timerTile = TerrariaUtils.Tiles[timerLocation]; if (timerMetadata == null || !timerTile.active() || timerTile.type != TileID.Timers) { if (timersToDelete == null) { timersToDelete = new List <DPoint>(); } timersToDelete.Add(timerLocation); continue; } if (timerMetadata.FramesLeft <= 0) { if (timersToProcess == null) { timersToProcess = new List <KeyValuePair <DPoint, ActiveTimerMetadata> >(); } timersToProcess.Add(activeTimer); timerMetadata.FramesLeft = AdvancedCircuits.MeasureTimerFrameTime(timerLocation); continue; } timerMetadata.FramesLeft -= CircuitHandler.TimerUpdateFrameRate; } if (timersToProcess != null) { DateTime now = DateTime.UtcNow; foreach (KeyValuePair <DPoint, ActiveTimerMetadata> activeTimer in timersToProcess) { SignalType signalType; // Is Advanced Circuit? if (!TerrariaUtils.Tiles[activeTimer.Key].HasWire()) { signalType = SignalType.On; } else { signalType = SignalType.Swap; } try { CircuitProcessingResult result = this.ProcessCircuit(null, activeTimer.Key, signalType, false); // If the circuit had errors or if it reached its max activity time, deactivate the timer. if ( result.CancellationReason != CircuitCancellationReason.None || ( this.Config.MaxTimerActivityTime != TimeSpan.Zero && (now - activeTimer.Value.TimeOfRegistration) >= this.Config.MaxTimerActivityTime ) ) { ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(activeTimer.Key); this.RegisterUnregisterTimer(result.TriggeringPlayer, measureData, false); TerrariaUtils.Tiles.SetObjectState(measureData, false); } } catch (Exception ex) { this.PluginTrace.WriteLineError("Circuit processing for a Timer at {0} failed. See inner exception for details.\n{1}", activeTimer.Key, ex.ToString()); } } } if (timersToDelete != null) { foreach (DPoint timerLocation in timersToDelete) { this.WorldMetadata.ActiveTimers.Remove(timerLocation); } } } if (this.frameCounter % CircuitHandler.ClockUpdateFrameRate == 0) { bool isDaylight = (Main.dayTime && Main.time >= 7200 && Main.time <= 46800); bool dayTimeChanged = (Main.dayTime != this.isDayTime); bool daylightChanged = (this.isDaylight != isDaylight); if (dayTimeChanged || daylightChanged) { List <DPoint> clocksToRemove = null; foreach (KeyValuePair <DPoint, GrandfatherClockMetadata> clock in this.WorldMetadata.Clocks) { DPoint clockLocation = clock.Key; ITile clockTile = TerrariaUtils.Tiles[clockLocation]; if (!clockTile.active() || clockTile.type != TileID.GrandfatherClocks) { if (clocksToRemove == null) { clocksToRemove = new List <DPoint>(); } clocksToRemove.Add(clock.Key); continue; } bool signal; switch ((PaintColor)TerrariaUtils.Tiles[clockLocation].color()) { case AdvancedCircuits.Paint_Clock_ByDaylight: if (!daylightChanged) { continue; } signal = !isDaylight; break; case AdvancedCircuits.Paint_Clock_ByNighttimeAndBloodmoon: if (!dayTimeChanged) { continue; } signal = !Main.dayTime && Main.bloodMoon; break; case AdvancedCircuits.Paint_Clock_ByNighttimeAndFullmoon: if (!dayTimeChanged) { continue; } signal = !Main.dayTime && Main.moonPhase == 0; break; default: if (!dayTimeChanged) { continue; } signal = !Main.dayTime; break; } try { TSPlayer triggeringPlayer = null; if (clock.Value.TriggeringPlayerName != null) { triggeringPlayer = TShockEx.GetPlayerByName(clock.Value.TriggeringPlayerName); } if (triggeringPlayer == null) { triggeringPlayer = TSPlayer.Server; } this.ProcessCircuit(triggeringPlayer, clockLocation, AdvancedCircuits.BoolToSignal(signal), false); } catch (Exception ex) { this.PluginTrace.WriteLineError( "Circuit processing for a Grandfather Clock at {0} failed. See inner exception for details.\n{1}", clockLocation, ex.ToString() ); } } if (clocksToRemove != null) { foreach (DPoint clockLocation in clocksToRemove) { this.WorldMetadata.Clocks.Remove(clockLocation); } } if (dayTimeChanged) { this.isDayTime = Main.dayTime; } if (daylightChanged) { this.isDaylight = isDaylight; } } if (this.frameCounter >= 100000) { this.frameCounter = 0; } } }
public IEnumerable <ProtectionEntry> EnumerateProtectionEntries(DPoint tileLocation) { ITile tile = TerrariaUtils.Tiles[tileLocation]; if (!tile.active()) { yield break; } lock (this.WorldMetadata.Protections) { ProtectionEntry protection; if (TerrariaUtils.Tiles.IsSolidBlockType(tile.type, true) || tile.type == TileID.WoodenBeam) { if (this.WorldMetadata.Protections.TryGetValue(tileLocation, out protection)) { yield return(protection); } // ** Enumerate Adjacent Object Protections ** DPoint topTileLocation = new DPoint(tileLocation.X, tileLocation.Y - 1); DPoint leftTileLocation = new DPoint(tileLocation.X - 1, tileLocation.Y); DPoint rightTileLocation = new DPoint(tileLocation.X + 1, tileLocation.Y); DPoint bottomTileLocation = new DPoint(tileLocation.X, tileLocation.Y + 1); ITile topTile = TerrariaUtils.Tiles[topTileLocation]; ITile leftTile = TerrariaUtils.Tiles[leftTileLocation]; ITile rightTile = TerrariaUtils.Tiles[rightTileLocation]; ITile bottomTile = TerrariaUtils.Tiles[bottomTileLocation]; TileObjectData topTileData = TileObjectData.GetTileData(topTile); TileObjectData leftTileData = TileObjectData.GetTileData(leftTile); TileObjectData rightTileData = TileObjectData.GetTileData(rightTile); TileObjectData bottomTileData = TileObjectData.GetTileData(bottomTile); // Top tile is object and is object placed on top of this tile? if (topTileData != null && topTileData.AnchorBottom.type != AnchorType.None && topTile.type != TileID.Containers && topTile.type != TileID.Containers2 && topTile.type != TileID.Dressers) { ObjectMeasureData topObjectMeasureData = TerrariaUtils.Tiles.MeasureObject(topTileLocation); bool isObjectAllowingWallPlacement = ( topTile.type == TileID.Signs || topTile.type == TileID.Switches || topTile.type == TileID.Lever ); bool isProtected = this.WorldMetadata.Protections.TryGetValue(topObjectMeasureData.OriginTileLocation, out protection); if (isProtected) { bool hasWallsBehind = false; if (isObjectAllowingWallPlacement) { hasWallsBehind = TerrariaUtils.Tiles.EnumerateObjectTiles(topObjectMeasureData).All((t) => t.wall != 0); } if (!isObjectAllowingWallPlacement || !hasWallsBehind) { yield return(protection); } } // There may also be protected objects on top of the object. foreach (ProtectionEntry topProtection in this.EnumProtectionEntriesOnTopOfObject(topObjectMeasureData)) { yield return(topProtection); } } // Left tile is object and is object placed on the left edge of this tile? if (leftTileData != null && leftTileData.AnchorRight.type != AnchorType.None) { ObjectMeasureData leftObjectMeasureData = TerrariaUtils.Tiles.MeasureObject(leftTileLocation); bool isObjectAllowingWallPlacement = ( leftTile.type == TileID.Signs || leftTile.type == TileID.Switches ); bool isProtected = this.WorldMetadata.Protections.TryGetValue(leftObjectMeasureData.OriginTileLocation, out protection); if (isProtected) { bool hasWallsBehind = false; if (isObjectAllowingWallPlacement) { hasWallsBehind = TerrariaUtils.Tiles.EnumerateObjectTiles(leftObjectMeasureData).All((t) => t.wall != 0); } if (!isObjectAllowingWallPlacement || !hasWallsBehind) { yield return(protection); } } } // Right tile is object and is object placed on the right edge of this tile? if (rightTileData != null && rightTileData.AnchorLeft.type != AnchorType.None) { ObjectMeasureData rightObjectMeasureData = TerrariaUtils.Tiles.MeasureObject(rightTileLocation); bool isObjectAllowingWallPlacement = ( rightTile.type == TileID.Signs || rightTile.type == TileID.Switches ); bool isProtected = this.WorldMetadata.Protections.TryGetValue(rightObjectMeasureData.OriginTileLocation, out protection); if (isProtected) { bool hasWallsBehind = false; if (isObjectAllowingWallPlacement) { hasWallsBehind = TerrariaUtils.Tiles.EnumerateObjectTiles(rightObjectMeasureData).All((t) => t.wall != 0); } if (!isObjectAllowingWallPlacement || !hasWallsBehind) { yield return(protection); } } } // Bottom tile is object and is object placed on the bottom edge of this tile? if (bottomTileData != null && bottomTileData.AnchorTop.type != AnchorType.None) { ObjectMeasureData bottomObjectMeasureData = TerrariaUtils.Tiles.MeasureObject(bottomTileLocation); bool isObjectAllowingWallPlacement = ( bottomTile.type == TileID.Signs ); bool isProtected = this.WorldMetadata.Protections.TryGetValue(bottomObjectMeasureData.OriginTileLocation, out protection); if (isProtected) { bool hasWallsBehind = false; if (isObjectAllowingWallPlacement) { hasWallsBehind = TerrariaUtils.Tiles.EnumerateObjectTiles(bottomObjectMeasureData).All((t) => t.wall != 0); } if (!isObjectAllowingWallPlacement || !hasWallsBehind) { yield return(protection); } } } } else { // This tile represents a sprite, no solid block. ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(tileLocation); tileLocation = measureData.OriginTileLocation; if (this.WorldMetadata.Protections.TryGetValue(tileLocation, out protection)) { yield return(protection); } if (tile.type >= TileID.ImmatureHerbs && tile.type <= TileID.BloomingHerbs) { // Clay Pots and their plants have a special handling - the plant should not be removable if the pot is protected. ITile tileBeneath = TerrariaUtils.Tiles[tileLocation.X, tileLocation.Y + 1]; if ( tileBeneath.type == TileID.ClayPot && this.WorldMetadata.Protections.TryGetValue(new DPoint(tileLocation.X, tileLocation.Y + 1), out protection) ) { yield return(protection); } } else { // Check all tiles above the sprite, in case a protected sprite is placed upon it (like on a table). foreach (ProtectionEntry protectionOnTop in this.EnumProtectionEntriesOnTopOfObject(measureData)) { yield return(protectionOnTop); } } } } }
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 HandleWirePlace(TSPlayer player, DPoint location) { if (this.IsDisposed) { return(false); } DPoint[] tilesToCheck = new[] { location, new DPoint(location.X - 1, location.Y), new DPoint(location.X + 1, location.Y), new DPoint(location.X, location.Y - 1), new DPoint(location.X, location.Y + 1), }; foreach (DPoint tileToCheck in tilesToCheck) { ITile tile = TerrariaUtils.Tiles[tileToCheck]; if (!tile.active()) { continue; } if (tileToCheck != location && tile.type != AdvancedCircuits.BlockType_WirelessTransmitter) { continue; } bool hasPermission = true; ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(tileToCheck); PaintColor componentPaint = (PaintColor)TerrariaUtils.Tiles[measureData.OriginTileLocation].color(); switch (tile.type) { case TileID.Statues: { StatueStyle statueStyle = TerrariaUtils.Tiles.GetStatueStyle(tile); StatueConfig statueConfig; if (!this.Config.StatueConfigs.TryGetValue(statueStyle, out statueConfig)) { return(false); } if (string.IsNullOrEmpty(statueConfig.WirePermission)) { return(false); } hasPermission = player.Group.HasPermission(statueConfig.WirePermission); if (!hasPermission) { this.TellNoStatueWiringPermission(player, statueStyle); player.SendTileSquare(location, 1); return(true); } break; } case TileID.Traps: { TrapConfig trapConfig; TrapConfigKey configKey = new TrapConfigKey(TerrariaUtils.Tiles.GetTrapStyle(TerrariaUtils.Tiles[location].frameY / 18), componentPaint); if (!this.Config.TrapConfigs.TryGetValue(configKey, out trapConfig)) { break; } if (string.IsNullOrEmpty(trapConfig.WirePermission)) { break; } hasPermission = player.Group.HasPermission(trapConfig.WirePermission); break; } case TileID.Boulder: { hasPermission = player.Group.HasPermission(AdvancedCircuitsPlugin.WireBoulder_Permission); break; } case TileID.Signs: { hasPermission = player.Group.HasPermission(AdvancedCircuitsPlugin.WireSign_Permission); break; } case TileID.InletPump: case TileID.OutletPump: { PumpConfig pumpConfig; if (!this.Config.PumpConfigs.TryGetValue(componentPaint, out pumpConfig)) { break; } hasPermission = player.Group.HasPermission(pumpConfig.WirePermission); break; } case AdvancedCircuits.BlockType_WirelessTransmitter: { WirelessTransmitterConfig transmitterConfig; if (!this.Config.WirelessTransmitterConfigs.TryGetValue(componentPaint, out transmitterConfig)) { break; } hasPermission = player.Group.HasPermission(transmitterConfig.WirePermission); break; } case TileID.Teleporter: { hasPermission = player.Group.HasPermission(AdvancedCircuitsPlugin.WireTeleporter_Permission); break; } } if (!hasPermission) { this.TellMissingComponentWiringPermission(player, tile.type); player.SendTileSquare(location, 1); return(true); } } return(false); }
public static bool IsComponentWiredByPort(ObjectMeasureData measureData) { return(AdvancedCircuits.IsComponentWiredByPort(measureData.OriginTileLocation, measureData.Size)); }
public IEnumerable <ProtectionEntry> EnumerateProtectionEntries(DPoint tileLocation) { Tile tile = TerrariaUtils.Tiles[tileLocation]; if (!tile.active()) { yield break; } lock (this.WorldMetadata.Protections) { ProtectionEntry protection; if (TerrariaUtils.Tiles.IsSolidBlockType((BlockType)tile.type, true) || tile.type == (int)BlockType.WoodenBeam) { if (this.WorldMetadata.Protections.TryGetValue(tileLocation, out protection)) { yield return(protection); } // Check for adjacent sprites. DPoint topTileLocation = new DPoint(tileLocation.X, tileLocation.Y - 1); Tile topTile = TerrariaUtils.Tiles[topTileLocation]; if ( topTile.active() && !TerrariaUtils.Tiles.IsSolidBlockType((BlockType)topTile.type, true, true) ) { if ( topTile.type == (int)BlockType.CrystalShard || topTile.type == (int)BlockType.Torch || topTile.type == (int)BlockType.Sign || topTile.type == (int)BlockType.Switch ) { if ( TerrariaUtils.Tiles.GetObjectOrientation(topTile) == Direction.Up && this.WorldMetadata.Protections.TryGetValue(TerrariaUtils.Tiles.MeasureObject(topTileLocation).OriginTileLocation, out protection) ) { yield return(protection); } } else if ( topTile.type != (int)BlockType.Vine && topTile.type != (int)BlockType.JungleVine && topTile.type != (int)BlockType.HallowedVine && !(topTile.type >= (int)BlockType.CopperChandelier && topTile.type == (int)BlockType.GoldChandelier) && topTile.type != (int)BlockType.Banner && topTile.type != (int)BlockType.ChainLantern && topTile.type != (int)BlockType.ChineseLantern && topTile.type != (int)BlockType.DiscoBall && topTile.type != (int)BlockType.XMasLight ) { ObjectMeasureData topObjectMeasureData = TerrariaUtils.Tiles.MeasureObject(topTileLocation); if (this.WorldMetadata.Protections.TryGetValue(topObjectMeasureData.OriginTileLocation, out protection)) { yield return(protection); } foreach (ProtectionEntry protectionOnTop in this.EnumProtectionEntriesOnTopOfObject(topObjectMeasureData)) { yield return(protectionOnTop); } } } DPoint leftTileLocation = new DPoint(tileLocation.X - 1, tileLocation.Y); Tile leftTile = TerrariaUtils.Tiles[leftTileLocation]; if ( leftTile.active() && ( leftTile.type == (int)BlockType.CrystalShard || leftTile.type == (int)BlockType.Torch || leftTile.type == (int)BlockType.Sign || leftTile.type == (int)BlockType.Switch ) && TerrariaUtils.Tiles.GetObjectOrientation(leftTile) == Direction.Left ) { if (this.WorldMetadata.Protections.TryGetValue(TerrariaUtils.Tiles.MeasureObject(leftTileLocation).OriginTileLocation, out protection)) { yield return(protection); } } DPoint rightTileLocation = new DPoint(tileLocation.X + 1, tileLocation.Y); Tile rightTile = TerrariaUtils.Tiles[rightTileLocation]; if ( rightTile.active() && ( rightTile.type == (int)BlockType.CrystalShard || rightTile.type == (int)BlockType.Torch || rightTile.type == (int)BlockType.Sign || rightTile.type == (int)BlockType.Switch ) && TerrariaUtils.Tiles.GetObjectOrientation(rightTile) == Direction.Right ) { if (this.WorldMetadata.Protections.TryGetValue(TerrariaUtils.Tiles.MeasureObject(rightTileLocation).OriginTileLocation, out protection)) { yield return(protection); } } DPoint bottomTileLocation = new DPoint(tileLocation.X, tileLocation.Y + 1); Tile bottomTile = TerrariaUtils.Tiles[bottomTileLocation]; if ( bottomTile.active() && ( bottomTile.type == (int)BlockType.Vine || bottomTile.type == (int)BlockType.JungleVine || bottomTile.type == (int)BlockType.HallowedVine || (bottomTile.type >= (int)BlockType.CopperChandelier && bottomTile.type == (int)BlockType.GoldChandelier) || bottomTile.type == (int)BlockType.Banner || bottomTile.type == (int)BlockType.ChainLantern || bottomTile.type == (int)BlockType.ChineseLantern || bottomTile.type == (int)BlockType.DiscoBall || bottomTile.type == (int)BlockType.XMasLight || ( (bottomTile.type == (int)BlockType.CrystalShard || bottomTile.type == (int)BlockType.Sign) && TerrariaUtils.Tiles.GetObjectOrientation(bottomTile) == Direction.Down ) ) ) { if (this.WorldMetadata.Protections.TryGetValue(TerrariaUtils.Tiles.MeasureObject(bottomTileLocation).OriginTileLocation, out protection)) { yield return(protection); } } } else { // This tile represents a sprite, no solid block. ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(tileLocation); tileLocation = measureData.OriginTileLocation; if (this.WorldMetadata.Protections.TryGetValue(tileLocation, out protection)) { yield return(protection); } if (tile.type >= (int)BlockType.HerbGrowing && tile.type <= (int)BlockType.HerbBlooming) { // Clay Pots and their plants have a special handling - the plant should not be removable if the pot is protected. Tile tileBeneath = TerrariaUtils.Tiles[tileLocation.X, tileLocation.Y + 1]; if ( tileBeneath.type == (int)BlockType.ClayPot && this.WorldMetadata.Protections.TryGetValue(new DPoint(tileLocation.X, tileLocation.Y + 1), out protection) ) { yield return(protection); } } else { // Check all tiles above the sprite, in case a protected sprite is placed upon it (like on a table). foreach (ProtectionEntry protectionOnTop in this.EnumProtectionEntriesOnTopOfObject(measureData)) { yield return(protectionOnTop); } } } } }
public bool HandleTileEdit(TSPlayer player, TileEditType editType, int blockType, DPoint location, int objectStyle) { switch (editType) { case TileEditType.PlaceTile: { switch (blockType) { case AdvancedCircuits.BlockType_WirelessTransmitter: if ( AdvancedCircuits.IsComponentWiredByPort(location, new DPoint(1, 1)) && !this.Metadata.WirelessTransmitters.ContainsKey(location) ) { this.Metadata.WirelessTransmitters.Add(location, player.Name); } break; } break; } case TileEditType.PlaceWire: case TileEditType.PlaceWireBlue: case TileEditType.PlaceWireGreen: { // Check if we just wired an unregistered component's port. foreach (DPoint adjacentTileLocation in AdvancedCircuits.EnumerateComponentPortLocations(location, new DPoint(1, 1))) { ITile tile = TerrariaUtils.Tiles[adjacentTileLocation]; if (tile.active() && tile.type == AdvancedCircuits.BlockType_WirelessTransmitter) { if (!this.Metadata.WirelessTransmitters.ContainsKey(adjacentTileLocation)) { this.Metadata.WirelessTransmitters.Add(adjacentTileLocation, player.Name); } } } break; } case TileEditType.TileKill: case TileEditType.TileKillNoItem: { if (!TerrariaUtils.Tiles[location].active()) { break; } switch (TerrariaUtils.Tiles[location].type) { case TileID.Timers: { if (this.Metadata.ActiveTimers.ContainsKey(location)) { this.Metadata.ActiveTimers.Remove(location); } break; } case TileID.GrandfatherClocks: { ObjectMeasureData measureData = TerrariaUtils.Tiles.MeasureObject(location); if (this.Metadata.Clocks.ContainsKey(measureData.OriginTileLocation)) { this.Metadata.Clocks.Remove(measureData.OriginTileLocation); } break; } case AdvancedCircuits.BlockType_Swapper: { if (this.Metadata.Swappers.ContainsKey(location)) { this.Metadata.Swappers.Remove(location); } break; } case AdvancedCircuits.BlockType_ANDGate: case AdvancedCircuits.BlockType_ORGate: case AdvancedCircuits.BlockType_XORGate: { if (this.Metadata.GateStates.ContainsKey(location)) { this.Metadata.GateStates.Remove(location); } break; } case AdvancedCircuits.BlockType_BlockActivator: { if (this.Metadata.BlockActivators.ContainsKey(location)) { this.Metadata.BlockActivators.Remove(location); } break; } case AdvancedCircuits.BlockType_WirelessTransmitter: { if (this.Metadata.WirelessTransmitters.ContainsKey(location)) { this.Metadata.WirelessTransmitters.Remove(location); } break; } } break; } } return(false); }