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 }; }
private CircuitProcessingResult ProcessCircuit(TSPlayer triggerer, DPoint tileLocation, SignalType?overrideSignal = null, bool switchSender = true) { CircuitProcessor processor = new CircuitProcessor(this.PluginTrace, this, tileLocation); CircuitProcessingResult result = processor.ProcessCircuit(triggerer, overrideSignal, switchSender); this.NotifyPlayer(result); return(result); }
protected void NotifyPlayer(CircuitProcessingResult result) { TSPlayer player = result.TriggeringPlayer; if (player == TSPlayer.Server) return; switch (result.WarnReason) { case CircuitWarnReason.SignalesTooManyPumps: player.SendWarningMessage(string.Format( "Warning: This circuit tried to signal {0} Pumps, though the allowed maximum is {1}.", result.SignaledPumps, this.Config.MaxPumpsPerCircuit )); break; case CircuitWarnReason.SignalesTooManyTraps: player.SendWarningMessage(string.Format( "Warning: This circuit tried to signal {0} Traps, though the allowed maximum is {1}.", result.SignaledTraps, this.Config.MaxTrapsPerCircuit )); break; case CircuitWarnReason.SignalesTooManyStatues: player.SendWarningMessage(string.Format( "Warning: This circuit tried to signal {0} Statues, though the allowed maximum is {1}.", result.SignaledStatues, this.Config.MaxStatuesPerCircuit )); break; case CircuitWarnReason.InsufficientPermissionToSignalComponent: player.SendWarningMessage("Warning: You don't have the required permission to signal"); player.SendWarningMessage(string.Format( "the component \"{0}\".", AdvancedCircuits.GetComponentName(result.WarnRelatedComponentType) )); break; case CircuitWarnReason.BlockActivatorChangedTooManyBlocks: player.SendWarningMessage("Warning: A \"Block Activator\" component tried to change more"); player.SendWarningMessage(string.Format( "blocks than the allowed maximum of {0} blocks.", this.Config.BlockActivatorConfig.MaxChangeableBlocks )); break; } switch (result.CancellationReason) { case CircuitCancellationReason.ExceededMaxLength: player.SendErrorMessage("Error: Circuit processing cancelled because it exceeded the maximum length of "); player.SendErrorMessage(string.Format("{0} wires.", this.Config.MaxCircuitLength)); break; case CircuitCancellationReason.SignaledSameComponentTooOften: if (result.CancellationRelatedComponentType == BlockType.Invalid) { player.SendErrorMessage("Error: Circuit processing cancelled because a component was signaled too often."); } else { player.SendErrorMessage("Error: Circuit processing cancelled because the component"); player.SendErrorMessage(string.Format( "\"{0}\" was signaled too often. Check your circuit for loops.", AdvancedCircuits.GetComponentName(result.CancellationRelatedComponentType) )); } break; } }
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; } } }
protected void NotifyPlayer(CircuitProcessingResult result) { TSPlayer player = result.TriggeringPlayer; if (player == TSPlayer.Server) { return; } switch (result.WarnReason) { case CircuitWarnReason.SignalesTooManyPumps: player.SendWarningMessage(string.Format( "Warning: This circuit tried to signal {0} Pumps, though the allowed maximum is {1}.", result.SignaledPumps, this.Config.MaxPumpsPerCircuit )); break; case CircuitWarnReason.SignalesTooManyTraps: player.SendWarningMessage(string.Format( "Warning: This circuit tried to signal {0} Traps, though the allowed maximum is {1}.", result.SignaledTraps, this.Config.MaxTrapsPerCircuit )); break; case CircuitWarnReason.SignalesTooManyStatues: player.SendWarningMessage(string.Format( "Warning: This circuit tried to signal {0} Statues, though the allowed maximum is {1}.", result.SignaledStatues, this.Config.MaxStatuesPerCircuit )); break; case CircuitWarnReason.InsufficientPermissionToSignalComponent: player.SendWarningMessage("Warning: You don't have the required permission to signal"); player.SendWarningMessage(string.Format( "the component \"{0}\".", AdvancedCircuits.GetComponentName(result.WarnRelatedComponentType) )); break; case CircuitWarnReason.BlockActivatorChangedTooManyBlocks: player.SendWarningMessage("Warning: A \"Block Activator\" component tried to change more"); player.SendWarningMessage(string.Format( "blocks than the allowed maximum of {0} blocks.", this.Config.BlockActivatorConfig.MaxChangeableBlocks )); break; } switch (result.CancellationReason) { case CircuitCancellationReason.ExceededMaxLength: player.SendErrorMessage("Error: Circuit processing cancelled because it exceeded the maximum length of "); player.SendErrorMessage(string.Format("{0} wires.", this.Config.MaxCircuitLength)); break; case CircuitCancellationReason.SignaledSameComponentTooOften: if (result.CancellationRelatedComponentType == -1) { player.SendErrorMessage("Error: Circuit processing cancelled because a component was signaled too often."); } else { player.SendErrorMessage("Error: Circuit processing cancelled because the component"); player.SendErrorMessage(string.Format( "\"{0}\" was signaled too often. Check your circuit for loops.", AdvancedCircuits.GetComponentName(result.CancellationRelatedComponentType) )); } break; } }