165 lines
7.5 KiB
C#
165 lines
7.5 KiB
C#
namespace ReactorMaintenance.Simulation;
|
|
|
|
public enum EEditorTool
|
|
{
|
|
Cursor,
|
|
Floor,
|
|
Wall,
|
|
FuelUnderground,
|
|
CoolantUnderground,
|
|
ElectricityUnderground,
|
|
FuelFlow,
|
|
CoolantFlow,
|
|
ElectricityFlow,
|
|
FuelConsumer,
|
|
CoolantConsumer,
|
|
ElectricityConsumer,
|
|
TJunction,
|
|
CrossJunction,
|
|
Door,
|
|
AllSeeingEyeTerminal,
|
|
FuelRemedySupply,
|
|
CoolantRemedySupply,
|
|
ElectricityRemedySupply,
|
|
HeatRemedySupply,
|
|
ReactorControl,
|
|
FuelLeak,
|
|
CoolantLeak,
|
|
ElectricityLeak,
|
|
FuelHazard,
|
|
CoolantHazard,
|
|
ElectricityHazard,
|
|
Heat,
|
|
Robot
|
|
}
|
|
|
|
public static class LevelEditor
|
|
{
|
|
public static LevelState Apply(LevelState level, GridPosition position, EEditorTool tool)
|
|
{
|
|
if (!level.InBounds(position))
|
|
return level;
|
|
|
|
return tool switch {
|
|
EEditorTool.Cursor => level,
|
|
EEditorTool.Floor => level.SetTerrain(position, ECellTerrain.Floor),
|
|
EEditorTool.Wall => level.SetTerrain(position, ECellTerrain.Wall),
|
|
EEditorTool.FuelUnderground => SetUnderground(level, position, ECarrierType.Fuel),
|
|
EEditorTool.CoolantUnderground => SetUnderground(level, position, ECarrierType.Coolant),
|
|
EEditorTool.ElectricityUnderground => SetUnderground(level, position, ECarrierType.Electricity),
|
|
EEditorTool.FuelFlow => SetCarrierProp(level, position, EPropType.Flow, ECarrierType.Fuel),
|
|
EEditorTool.CoolantFlow => SetCarrierProp(level, position, EPropType.Flow, ECarrierType.Coolant),
|
|
EEditorTool.ElectricityFlow => SetCarrierProp(level, position, EPropType.Flow, ECarrierType.Electricity),
|
|
EEditorTool.FuelConsumer => SetCarrierProp(level, position, EPropType.Consumer, ECarrierType.Fuel),
|
|
EEditorTool.CoolantConsumer => SetCarrierProp(level, position, EPropType.Consumer, ECarrierType.Coolant),
|
|
EEditorTool.ElectricityConsumer => SetCarrierProp(level, position, EPropType.Consumer, ECarrierType.Electricity),
|
|
EEditorTool.TJunction => SetFloorProp(level, position, new() { Type = EPropType.TJunction }),
|
|
EEditorTool.CrossJunction => SetFloorProp(level, position, new() { Type = EPropType.CrossJunction }),
|
|
EEditorTool.Door => SetDoor(level, position),
|
|
EEditorTool.AllSeeingEyeTerminal => SetFloorProp(level, position, new() { Type = EPropType.AllSeeingEyeTerminal }),
|
|
EEditorTool.FuelRemedySupply => SetFloorProp(level, position, new() { Type = EPropType.RemedySupply, RemedyType = ERemedyType.FuelNeutralizer }),
|
|
EEditorTool.CoolantRemedySupply => SetFloorProp(level, position, new() { Type = EPropType.RemedySupply, RemedyType = ERemedyType.CoolantNeutralizer }),
|
|
EEditorTool.ElectricityRemedySupply => SetFloorProp(level, position, new() { Type = EPropType.RemedySupply, RemedyType = ERemedyType.ElectricityNeutralizer }),
|
|
EEditorTool.HeatRemedySupply => SetFloorProp(level, position, new() { Type = EPropType.RemedySupply, RemedyType = ERemedyType.HeatShield }),
|
|
EEditorTool.ReactorControl => SetReactorControl(level, position),
|
|
EEditorTool.FuelLeak => SetLeak(level, position, ECarrierType.Fuel),
|
|
EEditorTool.CoolantLeak => SetLeak(level, position, ECarrierType.Coolant),
|
|
EEditorTool.ElectricityLeak => SetLeak(level, position, ECarrierType.Electricity),
|
|
EEditorTool.FuelHazard => level.SetSurface(position, level.GetSurface(position) with { Fuel = level.GetSurface(position).Fuel + 1 }),
|
|
EEditorTool.CoolantHazard => level.SetSurface(position, level.GetSurface(position) with { Coolant = level.GetSurface(position).Coolant + 1 }),
|
|
EEditorTool.ElectricityHazard => level.SetSurface(position, level.GetSurface(position) with { Electricity = level.GetSurface(position).Electricity + 1 }),
|
|
EEditorTool.Heat => level.SetSurface(position, level.GetSurface(position) with { Heat = level.GetSurface(position).Heat + 1 }),
|
|
EEditorTool.Robot => level.IsFloor(position) ? level with { Robot = level.Robot with { Position = position } } : level,
|
|
_ => level
|
|
};
|
|
}
|
|
|
|
public static LevelState BindFirstReactorToConsumers(LevelState level, GridPosition fuelConsumer, GridPosition coolantConsumer, GridPosition electricityConsumer)
|
|
{
|
|
if (level.Reactors.Count == 0)
|
|
return level;
|
|
|
|
var reactors = level.Reactors.ToArray();
|
|
reactors[0] = reactors[0] with {
|
|
FuelConsumerPosition = fuelConsumer,
|
|
CoolantConsumerPosition = coolantConsumer,
|
|
ElectricityConsumerPosition = electricityConsumer
|
|
};
|
|
return level with { Reactors = reactors };
|
|
}
|
|
|
|
private static LevelState SetUnderground(LevelState level, GridPosition position, ECarrierType carrier)
|
|
{
|
|
return level.SetUnderground(position, carrier, new() { State = EUndergroundState.Intact });
|
|
}
|
|
|
|
private static LevelState SetCarrierProp(LevelState level, GridPosition position, EPropType type, ECarrierType carrier)
|
|
{
|
|
return SetFloorProp(level, position, new() { Type = type, Carrier = carrier, SwitchState = EPropSwitchState.Enabled });
|
|
}
|
|
|
|
private static LevelState SetFloorProp(LevelState level, GridPosition position, PropState prop)
|
|
{
|
|
return level.IsFloor(position) ? level.SetProp(position, prop) : level;
|
|
}
|
|
|
|
private static LevelState SetDoor(LevelState level, GridPosition position)
|
|
{
|
|
if (!level.IsFloor(position))
|
|
return level;
|
|
|
|
var neighbor = position.Neighbors().FirstOrDefault(level.IsFloor);
|
|
if (neighbor is null)
|
|
return SetFloorProp(level, position, new() { Type = EPropType.Door });
|
|
|
|
return SetFloorProp(level, position, new() { Type = EPropType.Door }) with {
|
|
Doors = [.. level.Doors, new DoorState { A = position, B = neighbor }]
|
|
};
|
|
}
|
|
|
|
private static LevelState SetReactorControl(LevelState level, GridPosition position)
|
|
{
|
|
if (!level.IsFloor(position))
|
|
return level;
|
|
|
|
var id = level.Reactors.Count == 0 ? 1 : level.Reactors.Max(reactor => reactor.ReactorId) + 1;
|
|
var levelWithProp = level.SetProp(position, new() { Type = EPropType.ReactorControl, ReactorId = id });
|
|
return levelWithProp with {
|
|
Reactors = [
|
|
.. level.Reactors,
|
|
new ReactorBinding {
|
|
ReactorId = id,
|
|
ControlPosition = position,
|
|
FuelConsumerPosition = position,
|
|
CoolantConsumerPosition = position,
|
|
ElectricityConsumerPosition = position
|
|
}
|
|
]
|
|
};
|
|
}
|
|
|
|
private static LevelState SetLeak(LevelState level, GridPosition position, ECarrierType carrier)
|
|
{
|
|
if (!level.InBounds(position))
|
|
return level;
|
|
|
|
var accessPosition = carrier == ECarrierType.Electricity && level.GetTerrain(position) == ECellTerrain.Wall
|
|
? position.Neighbors().FirstOrDefault(level.IsFloor)
|
|
: position;
|
|
|
|
if (accessPosition is null || !level.IsFloor(accessPosition))
|
|
return level;
|
|
|
|
var next = level.SetUnderground(position, carrier, new() { State = EUndergroundState.Leaking });
|
|
return next with {
|
|
Leaks = [
|
|
.. next.Leaks,
|
|
new LeakState {
|
|
Carrier = carrier,
|
|
UndergroundPosition = position,
|
|
AccessPosition = accessPosition
|
|
}
|
|
]
|
|
};
|
|
}
|
|
} |