Fix looking at wires, reduce Wire code

Also added two port name properties directly to the wires
Also added support for converting OptionalRefs to Nullables
This commit is contained in:
Norbi Peti 2021-09-03 01:30:15 +02:00
parent 2513040343
commit 033ebdb86d
6 changed files with 117 additions and 176 deletions

View file

@ -103,11 +103,13 @@ namespace TechbloxModdingAPI
{CommonExclusiveGroups.WHEELRIG_BLOCK_BUILD_GROUP, (id => new WheelRig(id), typeof(WheelRig))} {CommonExclusiveGroups.WHEELRIG_BLOCK_BUILD_GROUP, (id => new WheelRig(id), typeof(WheelRig))}
}; };
internal static Block New(EGID egid) internal static Block New(EGID egid, bool signaling = false)
{ {
return GroupToConstructor.ContainsKey(egid.groupID) return GroupToConstructor.ContainsKey(egid.groupID)
? GroupToConstructor[egid.groupID].Constructor(egid) ? GroupToConstructor[egid.groupID].Constructor(egid)
: new Block(egid); : signaling
? new SignalingBlock(egid)
: new Block(egid);
} }
public Block(EGID id) public Block(EGID id)

View file

@ -208,48 +208,35 @@ namespace TechbloxModdingAPI.Blocks.Engines
} }
return outputs; return outputs;
} }
public EGID MatchBlockInputToPort(Block block, byte portUsage, out bool exists) public OptionalRef<PortEntityStruct> MatchBlockIOToPort(Block block, byte portUsage, bool output)
{ {
var ports = entitiesDB.QueryEntityOptional<BlockPortsStruct>(block); return MatchBlockIOToPort(block.Id, portUsage, output);
exists = ports;
return new EGID(ports.Get().firstInputID + portUsage, NamedExclusiveGroup<InputPortsGroup>.Group);
} }
public EGID MatchBlockInputToPort(EGID block, byte portUsage, out bool exists) public OptionalRef<PortEntityStruct> MatchBlockIOToPort(EGID block, byte portUsage, bool output)
{ {
if (!entitiesDB.Exists<BlockPortsStruct>(block)) if (!entitiesDB.Exists<BlockPortsStruct>(block))
{
exists = false;
return default; return default;
} var group = output
exists = true; ? NamedExclusiveGroup<OutputPortsGroup>.Group
: NamedExclusiveGroup<InputPortsGroup>.Group;
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(block); BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(block);
return new EGID(ports.firstInputID + portUsage, NamedExclusiveGroup<InputPortsGroup>.Group); if (!entitiesDB.TryQueryMappedEntities<PortEntityStruct>(group, out var mapper))
}
public EGID MatchBlockOutputToPort(Block block, byte portUsage, out bool exists)
{
var ports = entitiesDB.QueryEntityOptional<BlockPortsStruct>(block);
exists = ports;
return new EGID(ports.Get().firstOutputID + portUsage, NamedExclusiveGroup<OutputPortsGroup>.Group);
}
public EGID MatchBlockOutputToPort(EGID block, byte portUsage, out bool exists)
{
if (!entitiesDB.Exists<BlockPortsStruct>(block))
{
exists = false;
return default; return default;
for (uint i = 0; i < (output ? ports.outputCount : ports.inputCount); ++i)
{
uint entityID = (output ? ports.firstOutputID : ports.firstInputID) + i;
if (!mapper.TryGetArrayAndEntityIndex(entityID, out var index, out var array) ||
array[index].usage != portUsage) continue;
return new OptionalRef<PortEntityStruct>(array, index);
} }
exists = true;
BlockPortsStruct ports = entitiesDB.QueryEntity<BlockPortsStruct>(block); return default;
return new EGID(ports.firstOutputID + portUsage, NamedExclusiveGroup<OutputPortsGroup>.Group);
} }
public ref WireEntityStruct MatchPortToWire(EGID portID, EGID blockID, out bool exists) public ref WireEntityStruct MatchPortToWire(PortEntityStruct port, EGID blockID, out bool exists)
{ {
ref PortEntityStruct port = ref entitiesDB.QueryEntity<PortEntityStruct>(portID);
var wires = entitiesDB.QueryEntities<WireEntityStruct>(NamedExclusiveGroup<WiresGroup>.Group); var wires = entitiesDB.QueryEntities<WireEntityStruct>(NamedExclusiveGroup<WiresGroup>.Group);
var wiresB = wires.ToBuffer().buffer; var wiresB = wires.ToBuffer().buffer;
for (uint i = 0; i < wires.count; i++) for (uint i = 0; i < wires.count; i++)
@ -266,8 +253,7 @@ namespace TechbloxModdingAPI.Blocks.Engines
return ref defRef[0]; return ref defRef[0];
} }
public ref WireEntityStruct MatchBlocksToWire(EGID startBlock, EGID endBlock, out bool exists, byte startPort = byte.MaxValue, public EGID MatchBlocksToWire(EGID startBlock, EGID endBlock, byte startPort = byte.MaxValue, byte endPort = byte.MaxValue)
byte endPort = byte.MaxValue)
{ {
EGID[] startPorts; EGID[] startPorts;
if (startPort == byte.MaxValue) if (startPort == byte.MaxValue)
@ -306,31 +292,23 @@ namespace TechbloxModdingAPI.Blocks.Engines
if ((wiresB[w].destinationPortUsage == endPES.usage && wiresB[w].destinationBlockEGID == endBlock) if ((wiresB[w].destinationPortUsage == endPES.usage && wiresB[w].destinationBlockEGID == endBlock)
&& (wiresB[w].sourcePortUsage == startPES.usage && wiresB[w].sourceBlockEGID == startBlock)) && (wiresB[w].sourcePortUsage == startPES.usage && wiresB[w].sourceBlockEGID == startBlock))
{ {
exists = true; return wiresB[w].ID;
return ref wiresB[w];
} }
} }
} }
} }
exists = false; return EGID.Empty;
WireEntityStruct[] defRef = new WireEntityStruct[1];
return ref defRef[0];
} }
public ref ChannelDataStruct GetChannelDataStruct(EGID portID, out bool exists) public OptionalRef<ChannelDataStruct> GetChannelDataStruct(EGID portID)
{ {
ref PortEntityStruct port = ref entitiesDB.QueryEntity<PortEntityStruct>(portID); var port = GetPort(portID);
var channels = entitiesDB.QueryEntities<ChannelDataStruct>(NamedExclusiveGroup<ChannelDataGroup>.Group); var channels = entitiesDB.QueryEntities<ChannelDataStruct>(NamedExclusiveGroup<ChannelDataGroup>.Group);
var channelsB = channels.ToBuffer(); var channelsB = channels.ToBuffer();
if (port.firstChannelIndexCachedInSim < channels.count) return port.firstChannelIndexCachedInSim < channels.count
{ ? new OptionalRef<ChannelDataStruct>(channelsB.buffer, port.firstChannelIndexCachedInSim)
exists = true; : default;
return ref channelsB.buffer[port.firstChannelIndexCachedInSim];
}
exists = false;
ChannelDataStruct[] defRef = new ChannelDataStruct[1];
return ref defRef[0];
} }
public EGID[] GetElectricBlocks() public EGID[] GetElectricBlocks()

View file

@ -46,9 +46,9 @@ namespace TechbloxModdingAPI.Blocks
/// <returns>The connected wire.</returns> /// <returns>The connected wire.</returns>
/// <param name="portId">Port identifier.</param> /// <param name="portId">Port identifier.</param>
/// <param name="connected">Whether the port has a wire connected to it.</param> /// <param name="connected">Whether the port has a wire connected to it.</param>
protected ref WireEntityStruct GetConnectedWire(EGID portId, out bool connected) protected ref WireEntityStruct GetConnectedWire(PortEntityStruct port, out bool connected)
{ {
return ref SignalEngine.MatchPortToWire(portId, Id, out connected); return ref SignalEngine.MatchPortToWire(port, Id, out connected);
} }
/// <summary> /// <summary>
@ -56,10 +56,9 @@ namespace TechbloxModdingAPI.Blocks
/// </summary> /// </summary>
/// <returns>The channel data.</returns> /// <returns>The channel data.</returns>
/// <param name="portId">Port identifier.</param> /// <param name="portId">Port identifier.</param>
/// <param name="exists">Whether the channel actually exists.</param> protected OptionalRef<ChannelDataStruct> GetChannelData(EGID portId)
protected ref ChannelDataStruct GetChannelData(EGID portId, out bool exists)
{ {
return ref SignalEngine.GetChannelDataStruct(portId, out exists); return SignalEngine.GetChannelDataStruct(portId);
} }
/// <summary> /// <summary>

View file

@ -43,14 +43,12 @@ namespace TechbloxModdingAPI.Blocks
/// <returns>The wire, where the end of the wire is the block port specified, or null if does not exist.</returns> /// <returns>The wire, where the end of the wire is the block port specified, or null if does not exist.</returns>
public static Wire ConnectedToInputPort(SignalingBlock end, byte endPort) public static Wire ConnectedToInputPort(SignalingBlock end, byte endPort)
{ {
EGID port = signalEngine.MatchBlockInputToPort(end, endPort, out bool exists); var port = signalEngine.MatchBlockIOToPort(end, endPort, false);
if (!exists) return null; if (!port) return null;
WireEntityStruct wire = signalEngine.MatchPortToWire(port, end.Id, out exists); WireEntityStruct wire = signalEngine.MatchPortToWire(port, end.Id, out var exists);
if (exists) return exists
{ ? new Wire(wire.sourceBlockEGID, end.Id, wire.sourcePortUsage, endPort, wire.ID, false)
return new Wire(Block.New(wire.sourceBlockEGID), end, wire.sourcePortUsage, endPort); : null;
}
return null;
} }
/// <summary> /// <summary>
@ -62,18 +60,16 @@ namespace TechbloxModdingAPI.Blocks
/// <returns>The wire, where the start of the wire is the block port specified, or null if does not exist.</returns> /// <returns>The wire, where the start of the wire is the block port specified, or null if does not exist.</returns>
public static Wire ConnectedToOutputPort(SignalingBlock start, byte startPort) public static Wire ConnectedToOutputPort(SignalingBlock start, byte startPort)
{ {
EGID port = signalEngine.MatchBlockOutputToPort(start, startPort, out bool exists); var port = signalEngine.MatchBlockIOToPort(start, startPort, true);
if (!exists) return null; if (!port) return null;
WireEntityStruct wire = signalEngine.MatchPortToWire(port, start.Id, out exists); WireEntityStruct wire = signalEngine.MatchPortToWire(port, start.Id, out var exists);
if (exists) return exists
{ ? new Wire(start.Id, wire.destinationBlockEGID, startPort, wire.destinationPortUsage, wire.ID, false)
return new Wire(start, Block.New(wire.destinationBlockEGID), startPort, wire.destinationPortUsage); : null;
}
return null;
} }
/// <summary> /// <summary>
/// Construct a wire object from an existing connection. /// Construct a wire object froam n existing connection.
/// </summary> /// </summary>
/// <param name="start">Starting block ID.</param> /// <param name="start">Starting block ID.</param>
/// <param name="end">Ending block ID.</param> /// <param name="end">Ending block ID.</param>
@ -84,40 +80,25 @@ namespace TechbloxModdingAPI.Blocks
{ {
startBlockEGID = start.Id; startBlockEGID = start.Id;
endBlockEGID = end.Id; endBlockEGID = end.Id;
bool flipped = false;
// find block ports // find block ports
WireEntityStruct wire = signalEngine.MatchBlocksToWire(start.Id, end.Id, out bool exists, startPort, endPort); EGID wire = signalEngine.MatchBlocksToWire(start.Id, end.Id, startPort, endPort);
if (exists) if (wire == EGID.Empty)
{ {
wireEGID = wire.ID; // flip I/O around and try again
endPortEGID = signalEngine.MatchBlockInputToPort(end, wire.destinationPortUsage, out exists); wire = signalEngine.MatchBlocksToWire(end.Id, start.Id, endPort, startPort);
if (!exists) throw new WireInvalidException("Wire end port not found"); flipped = true;
startPortEGID = signalEngine.MatchBlockOutputToPort(start, wire.sourcePortUsage, out exists); // NB: start and end are handled exactly as they're received as params.
if (!exists) throw new WireInvalidException("Wire start port not found"); // This makes wire traversal easier, but makes logic in this class a bit more complex
inputToOutput = false; }
endPort = wire.destinationPortUsage;
startPort = wire.sourcePortUsage; if (wire != EGID.Empty)
{
Construct(start.Id, end.Id, startPort, endPort, wire, flipped);
} }
else else
{ {
// flip I/O around and try again throw new WireInvalidException("Wire not found");
wire = signalEngine.MatchBlocksToWire(end.Id, start.Id, out exists, endPort, startPort);
if (exists)
{
wireEGID = wire.ID;
endPortEGID = signalEngine.MatchBlockOutputToPort(end, wire.sourcePortUsage, out exists);
if (!exists) throw new WireInvalidException("Wire end port not found");
startPortEGID = signalEngine.MatchBlockInputToPort(start, wire.destinationPortUsage, out exists);
if (!exists) throw new WireInvalidException("Wire start port not found");
inputToOutput = true; // end is actually the source
// NB: start and end are handled exactly as they're received as params.
// This makes wire traversal easier, but makes logic in this class a bit more complex
endPort = wire.sourcePortUsage;
startPort = wire.destinationPortUsage;
}
else
{
throw new WireInvalidException("Wire not found");
}
} }
} }
@ -131,25 +112,25 @@ namespace TechbloxModdingAPI.Blocks
/// <param name="wire">The wire ID.</param> /// <param name="wire">The wire ID.</param>
/// <param name="inputToOutput">Whether the wire direction goes input -> output (true) or output -> input (false, preferred).</param> /// <param name="inputToOutput">Whether the wire direction goes input -> output (true) or output -> input (false, preferred).</param>
public Wire(Block start, Block end, byte startPort, byte endPort, EGID wire, bool inputToOutput) public Wire(Block start, Block end, byte startPort, byte endPort, EGID wire, bool inputToOutput)
: this(start.Id, end.Id, startPort, endPort, wire, inputToOutput)
{ {
this.startBlockEGID = start.Id; }
this.endBlockEGID = end.Id;
private Wire(EGID startBlock, EGID endBlock, byte startPort, byte endPort, EGID wire, bool inputToOutput)
{
Construct(startBlock, endBlock, startPort, endPort, wire, inputToOutput);
}
private void Construct(EGID startBlock, EGID endBlock, byte startPort, byte endPort, EGID wire, bool inputToOutput)
{
this.startBlockEGID = startBlock;
this.endBlockEGID = endBlock;
this.inputToOutput = inputToOutput; this.inputToOutput = inputToOutput;
this.wireEGID = wire; this.wireEGID = wire;
if (inputToOutput) endPortEGID = signalEngine.MatchBlockIOToPort(startBlock, startPort, inputToOutput).Nullable()?.ID ?? EGID.Empty;
{ if (endPortEGID == EGID.Empty) throw new WireInvalidException("Wire end port not found");
endPortEGID = signalEngine.MatchBlockOutputToPort(start, startPort, out bool exists); startPortEGID = signalEngine.MatchBlockIOToPort(endBlock, endPort, !inputToOutput).Nullable()?.ID ?? EGID.Empty;
if (!exists) throw new WireInvalidException("Wire end port not found"); if (startPortEGID == EGID.Empty) throw new WireInvalidException("Wire start port not found");
startPortEGID = signalEngine.MatchBlockInputToPort(end, endPort, out exists);
if (!exists) throw new WireInvalidException("Wire start port not found");
}
else
{
endPortEGID = signalEngine.MatchBlockInputToPort(end, endPort, out bool exists);
if (!exists) throw new WireInvalidException("Wire end port not found");
startPortEGID = signalEngine.MatchBlockOutputToPort(start, startPort, out exists);
if (!exists) throw new WireInvalidException("Wire start port not found");
}
this.startPort = startPort; this.startPort = startPort;
this.endPort = endPort; this.endPort = endPort;
} }
@ -160,31 +141,14 @@ namespace TechbloxModdingAPI.Blocks
/// <param name="wireEgid">The wire ID.</param> /// <param name="wireEgid">The wire ID.</param>
public Wire(EGID wireEgid) public Wire(EGID wireEgid)
{ {
this.wireEGID = wireEgid;
WireEntityStruct wire = signalEngine.GetWire(wireEGID); WireEntityStruct wire = signalEngine.GetWire(wireEGID);
this.startBlockEGID = wire.sourceBlockEGID; Construct(wire.sourceBlockEGID, wire.destinationBlockEGID, wire.sourcePortUsage, wire.destinationPortUsage,
this.endBlockEGID = wire.destinationBlockEGID; wireEgid, false);
this.inputToOutput = false;
endPortEGID = signalEngine.MatchBlockInputToPort(wire.destinationBlockEGID, wire.destinationPortUsage, out bool exists);
if (!exists) throw new WireInvalidException("Wire end port not found");
startPortEGID = signalEngine.MatchBlockOutputToPort(wire.sourceBlockEGID, wire.sourcePortUsage, out exists);
if (!exists) throw new WireInvalidException("Wire start port not found");
this.endPort = wire.destinationPortUsage;
this.startPort = wire.sourcePortUsage;
} }
internal Wire(WireEntityStruct wire, SignalingBlock src, SignalingBlock dest) private Wire(WireEntityStruct wire, SignalingBlock src, SignalingBlock dest)
: this(src, dest, wire.sourcePortUsage, wire.destinationPortUsage, wire.ID, false)
{ {
this.wireEGID = wire.ID;
this.startBlockEGID = wire.sourceBlockEGID;
this.endBlockEGID = wire.destinationBlockEGID;
inputToOutput = false;
endPortEGID = signalEngine.MatchBlockInputToPort(dest, wire.destinationPortUsage, out bool exists);
if (!exists) throw new WireInvalidException("Wire end port not found");
startPortEGID = signalEngine.MatchBlockOutputToPort(src, wire.sourcePortUsage, out exists);
if (!exists) throw new WireInvalidException("Wire start port not found");
this.endPort = wire.destinationPortUsage;
this.startPort = wire.sourcePortUsage;
} }
/// <summary> /// <summary>
@ -202,16 +166,12 @@ namespace TechbloxModdingAPI.Blocks
{ {
get get
{ {
ref ChannelDataStruct cds = ref signalEngine.GetChannelDataStruct(startPortEGID, out bool exists); return signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsFloat;
if (!exists) return 0f;
return cds.valueAsFloat;
} }
set set
{ {
ref ChannelDataStruct cds = ref signalEngine.GetChannelDataStruct(startPortEGID, out bool exists); signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsFloat = value;
if (!exists) return;
cds.valueAsFloat = value;
} }
} }
@ -222,16 +182,12 @@ namespace TechbloxModdingAPI.Blocks
{ {
get get
{ {
ref ChannelDataStruct cds = ref signalEngine.GetChannelDataStruct(startPortEGID, out bool exists); return signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsEcsString;
if (!exists) return "";
return cds.valueAsEcsString;
} }
set set
{ {
ref ChannelDataStruct cds = ref signalEngine.GetChannelDataStruct(startPortEGID, out bool exists); signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsEcsString.Set(value);
if (!exists) return;
cds.valueAsEcsString.Set(value);
} }
} }
@ -242,16 +198,12 @@ namespace TechbloxModdingAPI.Blocks
{ {
get get
{ {
ref ChannelDataStruct cds = ref signalEngine.GetChannelDataStruct(startPortEGID, out bool exists); return signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsEcsString;
if (!exists) return default;
return cds.valueAsEcsString;
} }
set set
{ {
ref ChannelDataStruct cds = ref signalEngine.GetChannelDataStruct(startPortEGID, out bool exists); signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsEcsString = value;
if (!exists) return;
cds.valueAsEcsString = value;
} }
} }
@ -263,16 +215,12 @@ namespace TechbloxModdingAPI.Blocks
{ {
get get
{ {
ref ChannelDataStruct cds = ref signalEngine.GetChannelDataStruct(startPortEGID, out bool exists); return signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsID;
if (!exists) return uint.MaxValue;
return cds.valueAsID;
} }
set set
{ {
ref ChannelDataStruct cds = ref signalEngine.GetChannelDataStruct(startPortEGID, out bool exists); signalEngine.GetChannelDataStruct(startPortEGID).Get().valueAsID = value;
if (!exists) return;
cds.valueAsID = value;
} }
} }
@ -281,7 +229,7 @@ namespace TechbloxModdingAPI.Blocks
/// </summary> /// </summary>
public SignalingBlock Start public SignalingBlock Start
{ {
get => new SignalingBlock(startBlockEGID); get => (SignalingBlock)Block.New(startBlockEGID);
} }
/// <summary> /// <summary>
@ -291,13 +239,21 @@ namespace TechbloxModdingAPI.Blocks
{ {
get => startPort; get => startPort;
} }
/// <summary>
/// The display name of the start port.
/// </summary>
public string StartPortName
{
get => signalEngine.GetPort(startPortEGID).portNameLocalised;
}
/// <summary> /// <summary>
/// The block at the end of the wire. /// The block at the end of the wire.
/// </summary> /// </summary>
public SignalingBlock End public SignalingBlock End
{ {
get => new SignalingBlock(endBlockEGID); get => (SignalingBlock)Block.New(endBlockEGID);
} }
/// <summary> /// <summary>
@ -308,6 +264,14 @@ namespace TechbloxModdingAPI.Blocks
get => endPort; get => endPort;
} }
/// <summary>
/// The display name of the end port.
/// </summary>
public string EndPortName
{
get => signalEngine.GetPort(endPortEGID).portNameLocalised;
}
/// <summary> /// <summary>
/// Create a copy of the wire object where the direction of the wire is guaranteed to be from a block output to a block input. /// Create a copy of the wire object where the direction of the wire is guaranteed to be from a block output to a block input.
/// This is simply a different memory configuration and does not affect the in-game wire (which is always output -> input). /// This is simply a different memory configuration and does not affect the in-game wire (which is always output -> input).
@ -329,15 +293,11 @@ namespace TechbloxModdingAPI.Blocks
{ {
inputToOutput = false; inputToOutput = false;
// swap inputs and outputs // swap inputs and outputs
EGID temp = endBlockEGID; (endBlockEGID, startBlockEGID) = (startBlockEGID, endBlockEGID);
endBlockEGID = startBlockEGID; var tempPort = endPortEGID;
startBlockEGID = temp;
temp = endPortEGID;
endPortEGID = startPortEGID; endPortEGID = startPortEGID;
startPortEGID = temp; startPortEGID = tempPort;
byte tempPortNumber = endPort; (endPort, startPort) = (startPort, endPort);
endPort = startPort;
startPort = tempPortNumber;
} }
} }
@ -345,7 +305,7 @@ namespace TechbloxModdingAPI.Blocks
{ {
if (signalEngine.Exists<WireEntityStruct>(wireEGID)) if (signalEngine.Exists<WireEntityStruct>(wireEGID))
{ {
return $"{nameof(Id)}: {Id}, Start{nameof(Start.Id)}: {Start.Id}, End{nameof(End.Id)}: {End.Id}, ({Start.Type}::{StartPort} aka {Start.PortName(StartPort, inputToOutput)}) -> ({End.Type}::{EndPort} aka {End.PortName(EndPort, !inputToOutput)})"; return $"{nameof(Id)}: {Id}, Start{nameof(Start.Id)}: {Start.Id}, End{nameof(End.Id)}: {End.Id}, ({Start.Type}::{StartPort} aka {(StartPort != byte.MaxValue ? Start.PortName(StartPort, inputToOutput) : "")}) -> ({End.Type}::{EndPort} aka {(EndPort != byte.MaxValue ? End.PortName(EndPort, !inputToOutput) : "")})";
} }
return $"{nameof(Id)}: {Id}, Start{nameof(Start.Id)}: {Start.Id}, End{nameof(End.Id)}: {End.Id}, ({Start.Type}::{StartPort} -> {End.Type}::{EndPort})"; return $"{nameof(Id)}: {Id}, Start{nameof(Start.Id)}: {Start.Id}, End{nameof(End.Id)}: {End.Id}, ({Start.Type}::{StartPort} -> {End.Type}::{EndPort})";
} }

View file

@ -1,4 +1,5 @@
using System; using System;
using Gamecraft.Wires;
using RobocraftX.Character; using RobocraftX.Character;
using RobocraftX.Character.Movement; using RobocraftX.Character.Movement;
using Unity.Mathematics; using Unity.Mathematics;
@ -460,7 +461,7 @@ namespace TechbloxModdingAPI
{ {
var egid = playerEngine.GetThingLookedAt(Id, maxDistance); var egid = playerEngine.GetThingLookedAt(Id, maxDistance);
return egid != EGID.Empty && egid.groupID == WiresGUIExclusiveGroups.WireGroup return egid != EGID.Empty && egid.groupID == WiresGUIExclusiveGroups.WireGroup
? new Wire(egid) ? new Wire(new EGID(egid.entityID, NamedExclusiveGroup<WiresGroup>.Group))
: null; : null;
} }

View file

@ -65,6 +65,7 @@ namespace TechbloxModdingAPI.Utility
} }
public bool Exists => state != State.Empty; public bool Exists => state != State.Empty;
public T? Nullable() => this ? Get() : default;
public static implicit operator T(OptionalRef<T> opt) => opt.Get(); public static implicit operator T(OptionalRef<T> opt) => opt.Get();