niston Posted May 27 Share Posted May 27 I wish there was a thumbs up icon to select. *sigh* have this instead: Spoiler 1 Link to comment Share on other sites More sharing options...
South8028 Posted May 28 Author Share Posted May 28 13 minutes ago, niston said: I wish there was a thumbs up icon to select. *sigh* have this instead: Reveal hidden contents In general, we make one long panel for the numbers. I just think that the panel itself should be narrower. The numbers don't have to be gigantic. Dark glass panel, small numbers in its center. Not the entire length of the panel. Huge numbers like red clown noses will look in combination with touch buttons. Vintage from AliExpress. Link to comment Share on other sites More sharing options...
niston Posted May 28 Share Posted May 28 I agree. What style do you want for the numbers? The original's 7 segment LED style? Link to comment Share on other sites More sharing options...
South8028 Posted May 28 Author Share Posted May 28 33 minutes ago, niston said: I agree. What style do you want for the numbers? The original's 7 segment LED style? Which one is easier for you to implement. Let it be what is easier to do. The main thing is that the numbers are not gigantic. I think when I make the model... When there is a ready segment for placing the panel... Then we will deal with these numbers step by step. The main thing is that you don’t have to redo it again. Link to comment Share on other sites More sharing options...
niston Posted May 28 Share Posted May 28 Easiest is just using the nixies as is - very little additional work, as rescaling is just a few clicks in nifskope. Also very easy for me: You make an animated model of a single digit 7 segment display, exactly as specified earlier. I can very easily integrate it. Bit of work for whomever choose to do it: Making new textures for the existing nixies, so they won't look like nixies anymore. I suggest we simply use existing nixies for now. We can still change it later if we feel like. You can experiment with the NIFs I sent you and determine scale of the individual nixie element as you see fit. Once you know scale multiplier, I can apply it on my side in nifskope. Limitation: I can only do unform scale in niskope. You can also determine placement of each element by positioning NiNodes to which the elements attach to. Link to comment Share on other sites More sharing options...
South8028 Posted May 28 Author Share Posted May 28 6 minutes ago, niston said: Easiest is just using the nixies as is - very little additional work, as rescaling is just a few clicks in nifskope. Also very easy for me: You make an animated model of a single digit 7 segment display, exactly as specified earlier. I can very easily integrate it. Bit of work for whomever choose to do it: Making new textures for the existing nixies, so they won't look like nixies anymore. I suggest we simply use existing nixies for now. We can still change it later if we feel like. You can experiment with the NIFs I sent you and determine scale of the individual nixie element as you see fit. Once you know scale multiplier, I can apply it on my side in nifskope. You can also determine placement of each element by positioning NiNodes to which the elements attach to. Yes. Let's do so. Link to comment Share on other sites More sharing options...
niston Posted May 28 Share Posted May 28 Current state of NetLink:SOUL:Protocol class: Spoiler Scriptname NetLink:SOUL:Protocol extends NetLink:API:NetworkLayerBase ; audio-team SOUL (SOUTHLINK) protocol V1.0 ; custom scripting by niston ; Implementation version info Int Property IMPL_VERSION_MAJOR = 0 AutoReadOnly Hidden ; SOUL implementation version major (should match NetLink LinkLayer version) Int Property IMPL_VERSION_MINOR = 54 AutoReadOnly Hidden ; SOUL implementation version minor (should match NetLink LinkLayer version) ; SOUL protocol identifiers Int Property NETLINK_FRAMETYPE_SOUL = 8028 AutoReadOnly Hidden ; SOUL protocol uses netlink frametype 8028 Int Property PROTOCOL_VERSION = 1 AutoReadOnly Hidden ; SOUL protocol version String Property PROTOCOL_MAGIC = "SOUL" AutoReadOnly Hidden ; SOUL packet magic ; SOUL error codes Int Property ERROR_SOUL_NOTSTARTED = -3100 AutoReadOnly Hidden ; SOUL protocol not started Int Property ERROR_SOUL_NOPOWER = -3101 AutoReadOnly Hidden ; SOUL device not powered Int Property ERROR_SOUL_LINKLAYER = -3102 AutoReadOnly Hidden ; LinkLayer reference is unavailable ; SOUL packet types Int Property SOUL_PACKETTYPE_VC = 1 AutoReadonly Hidden ; Virtual Circuit packet Int Property SOUL_PACKETTYPE_SINK = 3 AutoReadonly Hidden ; SINK packet Int Property SOUL_PACKETTYPE_CONTROL = 5 AutoReadOnly Hidden ; CONTROL packet Int Property SOUL_PACKETTYPE_SOURCE = 7 AutoReadOnly Hidden ; SOURCE packet ; SOUL device types Int Property SOUL_DEVICETYPE_UNSPECIFIED = 0 AutoReadOnly Hidden ; SOUL device type not specified Int Property SOUL_DEVICETYPE_SOURCE = 1 AutoReadOnly Hidden ; SOURCE type SOUL device Int Property SOUL_DEVICETYPE_CONTROL = 2 AutoReadOnly Hidden ; CONTROL type SOUL device Int Property SOUL_DEVICETYPE_SINK = 3 AutoReadOnly Hidden ; SINK type SOUL device Int Property SOUL_DEVICETYPE_REMOTE = 4 AutoReadOnly Hidden ; REMOTE type SOUL device ; SOUL source types Int Property SOUL_SOURCETYPE_RADIO = 1 AutoReadOnly Hidden ; RADIO source type Int Property SOUL_SOURCETYPE_DESCR = 2 AutoReadOnly Hidden ; DESCRIPTOR source type ; Virtual Circuit Control Int Property VC_SYNCREQ = 1 AutoReadOnly Hidden ; synchronization request Int Property VC_SYNCACK = 2 AutoReadOnly Hidden ; synchronization acknowledgement Int Property VC_SYNCEST = 3 AutoReadOnly Hidden ; synchronization established Int Property VC_SYNCCHK = 4 AutoReadOnly Hidden ; synchronization test Int Property VC_SYNCBYE = 99 AutoReadOnly Hidden ; teardown notification ; Sink Control Int Property SINK_CMD_CLEAR = 1 AutoReadOnly Hidden ; clear (stop) emitter Int Property SINK_CMD_SYNC = 2 AutoReadOnly Hidden ; synchronize emitter Int Property SINK_CMD_PLAYBACK = 5 AutoReadOnly Hidden ; clear any existing emitter, create new emitter for SOUL Zone and start playback Int Property SINK_CMD_UPDATE = 6 AutoReadOnly Hidden ; update zone emitter Int Property SINK_CMD_VOLCNTRL = 11 AutoReadOnly Hidden ; update zone emitter volume String Property SystemNameDefault = "MySystem" Auto Const { SOUL Default System Name } Bool Property EnableRxRaw = false Auto Hidden Bool Property EnableRxVC = true Auto Hidden Bool Property EnableRxSink = true Auto Hidden Bool Property EnableRxControl = true Auto Hidden Bool Property EnableRxSource = true Auto Hidden ; Local SOUL System Name String _SystemName String Property SystemName String Function Get() Return _SystemName EndFunction Function Set(String value) _SystemName = value ; TODO: notification EndFunction EndProperty Struct SOULSourceDef String SourceName ; Name of source component Int SourceType ; SOUL source type Var SourceData ; source data EndStruct Struct SOULSourceDataRadioDef ; RADIO source Float Frequency ; radio frequency Bool Boost ; volume boost enable EndStruct Struct SOULSourceDataDescrDef ; DESCRIPTOR source Sound Descriptor ; sound descriptor ObjectReference SyncRef ; emitter synchronization reference Int Position ; playback position Int Duration ; total duration Bool Paused ; source paused EndStruct Struct SOULZoneDef ; speaker ZONE String ZoneName ; zone name SourceDef Source ; selected listening source Float VolumeL ; playback volume left hand Float VolumeR ; playback volume right hand EndStruct Struct SOULPacket String Magic Int Version String System Int PacketType Var Data EndStruct Struct SOULPacketVCType Int Command EndStruct Struct SOULPacketSinkType String Zone Int Command Var Data EndStruct Struct SOULPacketSourceType String Name Int Command Var Data EndStruct Struct DataVolumeControl Float VolumeL Float VolumeR EndStruct ; L3 protocol overrides String Function GetIdentifier() Return "SOUL" EndFunction String Function GetIdentifierDesc() Return "SOUTHLINK" EndFunction Int Function GetVersionMajor() Return IMPL_VERSION_MAJOR EndFunction Int Function GetVersionMinor() Return IMPL_VERSION_MINOR EndFunction ; SOUL packet received event CustomEvent Started CustomEvent Stopping CustomEvent SOULReceiveRaw CustomEvent SOULReceiveVC CustomEvent SOULReceiveSink Group SOULProtocolSettings Bool Property RequirePower = true Auto Const { If true, attached reference must be powered for SOUL to work } EndGroup ; true while SOUL protocol is started Bool Property IsStarted Hidden Bool Function Get() Return bStarted EndFunction EndProperty Bool bStarted = false Event OnInit() Int result = Start() EndEvent Event OnWorkshopObjectPlaced(ObjectReference refWorkshop) Int result = Start() EndEvent Event OnWorkshopObjectDestroyed(ObjectReference refWorkshop) Stop() EndEvent Event NetLink:LinkLayer.Started(NetLink:LinkLayer refLinkLayer, Var[] noneArgs) ; link layer has started If (bStarted) ; SOUL protocol still started? ; register SOUL protocol with LinkLayer _FrameTypeRegistration() EndIf EndEvent Event NetLink:LinkLayer.Stopping(NetLink:LinkLayer refLinkLayer, Var[] noneArgs) If (bStarted) ; unregister SOUL protocol from LinkLayer _FrameTypeRegistration(unregisterFrameType = true) EndIf EndEvent Int Function Start() If (!IsBoundGameObjectAvailable()) Return ERROR_UNAVAILABLE EndIf If (bStarted) ; already started Return OK_NOERROR EndIf ; start networklayer base Int result = Parent.Start() If (!CheckSuccessCode(result)) ; failed Return result EndIf ; register for link layer lifecycle events RegisterForCustomEvent(LinkLayer, "Started") RegisterForCustomEvent(LinkLayer, "Stopping") ; if linklayer is started, register networklayer frametypes If (LinkLayer.IsStarted) result = _FrameTypeRegistration() If (!CheckSuccessCode(result)) Debug.Trace(Self + ": ERROR - Protocol Start failed: FTR for FrameType (" + LinkLayer.NETLINK_FRAMETYPE_SOUL + ") failed with code (" + ResolveErrorCode(result) + ").") Return result EndIf EndIf ;Debug.Trace(Self + ": DEBUG - Protocol scriptname is (" + NetworkLayerScriptname + ").") ; log chatter Debug.Trace(Self + ": INFO - Protocol started.") ; SOUL protocol started bStarted = true SendCustomEvent("Started", new Var[0]) Return OK_NOERROR EndFunction Function Stop() If (bStarted) ; SOUL protocol no longer started bStarted = false SendCustomEvent("Stopping", new Var[0]) ; unregister this networklayer from linklayer If (LinkLayer != none) If (LinkLayer.IsStarted) _FrameTypeRegistration(unregisterFrameType = true) EndIf ; unregister link layer lifecycle events UnRegisterForCustomEvent(LinkLayer, "Started") UnRegisterForCustomEvent(LinkLayer, "Stopping") EndIf ; stop NetworkLayer base class Parent.Stop() ; log chatter Debug.Trace(Self + ": INFO - Protocol stopped.") EndIf EndFunction send a SOUL SINK command to a system/zone Int Function SendCommandSink(ObjectReference refRecipient, String zoneName, Int commandId, Var commandData) If (!_IsDevicePowered()) Debug.Trace(Self + ": WARNING - SendCommandSink() skipped: Device not powered.") Return ERROR_SOUL_NOPOWER EndIf If (!bStarted) Debug.Trace(Self + ": ERROR - SendCommandSink() failed: Protocol not started.") Return ERROR_SOUL_NOTSTARTED EndIf SOULPacketSinkType outPacket = new SOULPacketSinkType outPacket.Zone = zoneName outPacket.Command = commandId outPacket.Data = commandData Return SendSOULPacket(refRecipient, systemName, outPacket) EndFunction Int Function SendSOULPacket(ObjectReference refRecipient, Int packetType, Var packetData) SOULPacket outPacket = new SOULPacket outPacket.Magic = PROTOCOL_MAGIC outPacket.Version = PROTOCOL_VERSION outPacket.System = _SystemName outPacket.PacketType = packetType outPacket.Data = packetData If (!bStarted) Debug.Trace(Self + ": ERROR - SendSOULPacket() failed: Protocol not started.") Return ERROR_SOUL_NOTSTARTED EndIf If (!_IsDevicePowered()) Debug.Trace(Self + ": WARNING - SendSinkCommand() skipped: Device not powered.") Return ERROR_SOUL_NOPOWER EndIf Debug.Trace(Self + ": DEBUG - Sending SOUL Packet (" + outPacket + ") for System (" + outPacket.System + ") to Link Layer...") Int success = LinkLayer.LinkSend(refRecipient, NETLINK_FRAMETYPE_SOUL, outPacket) Return success EndFunction ; function to transmit "raw" SOUL packets Int Function SendSOULPacketRaw(ObjectReference refRecipient, SOULPacket outPacket) If (!bStarted) Debug.Trace(Self + ": ERROR - SendSOULPacketRaw() failed: SOUL protocol not started.") Return ERROR_SOUL_NOTSTARTED EndIf If (!_IsDevicePowered()) Return ERROR_SOUL_NOPOWER EndIf Debug.Trace(Self + ": DEBUG - Sending SOUL Packet (" + outPacket + ") for System (" + outPacket.System + ") to Link Layer...") Int success = LinkLayer.LinkSend(refRecipient, NETLINK_FRAMETYPE_SOUL, outPacket) Return success EndFunction Function OnLinkReceive(Var[] eventArgs) ; SUP accelerated version NetLink:API:LinkLayerBase srcLinkLayer = eventArgs[0] as NetLink:LinkLayer NetLink:API:LinkLayerBase:NetLinkFrame inFrame = eventArgs[1] as NetLink:API:LinkLayerBase:NetLinkFrame ; RX filters If (srcLinkLayer == none) ; missing or invalid source linklayer: discard frame. Return EndIf If (inFrame == none) ; missing or non-netlink frame: discard. Return EndIf If (inFrame.FrameType != NETLINK_FRAMETYPE_SOUL) ; not a SOUL type NetLink Frame: discard. Return EndIf ; protocol started? If (!bStarted) ;Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: Protocol not started.") Return EndIf ; device powered? If (!_IsDevicePowered()) ;Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: Device not powered.") Return EndIf ; SOUL FrameType received, extract SOUL packet payload SOULPacket soulPacket = inFrame.Payload as SOULPacket If (soulPacket == none) Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: Null Payload.") Return EndIf If (soulPacket.Magic != PROTOCOL_MAGIC) Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: Invalid MAGIC (" + soulPacket.Magic + ").") Return EndIf ; SOUL type frame has proper SOUL protocol version? If (soulPacket.Version != PROTOCOL_VERSION) Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: SOUL Protocol version (" + soulPacket.VERSION + ") not supported.") Return EndIf ;Debug.Trace(Self + ": DEBUG - Received SOUL type Frame from Link Layer.") If (EnableRxRaw) ; generate raw rx event Var[] outEventArgs = new Var[3] outEventArgs[0] = inFrame.Source ; netlink source ref outEventArgs[1] = inFrame.Destination ; netlink destination ref outEventArgs[2] = soulPacket ; SOUL packet received SendCustomEvent("SOULReceiveRaw", outEventArgs) EndIf ; decode PacketType If ((soulPacket.PacketType == SOUL_PACKETTYPE_VC) & EnableRxVC) ; # virtual circuit packet rxVCCtrl = inFrame.Data as SOULPacketVCType If (rxVCCtrl == none) Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: Invalid or missing Data segment for PacketType (SOUL_PACKETTYPE_VC).") Return EndIf ; TODO: actual implementation ElseIf ((inFrame.PacketType == SOUL_PACKETTYPE_SINK) & EnableRxSink) ; # sink packet rxSinkCtrl = inFrame.Data as SOULPacketSinkType If (rxSinkCtrl == none) Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: Invalid or missing Data segment for PacketType (SOUL_PACKETTYPE_SINK).") Return EndIf Var[] rxSCEventArgs = new Var[6] rxSCEventArgs[0] = inFrame.Source rxSCEventArgs[1] = inFrame.Destination rxSCEventArgs[2] = soulPacket.System rxSCEventArgs[3] = rxSinkCtrl.Zone rxSCEventArgs[4] = rxSinkCtrl.Command rxSCEventArgs[5] = rxSinkCtrl.Data SendCustomEvent("SOULReceiveSink", rxSCEventArgs) ElseIf ((inFrame.PacketType == SOUL_PACKETTYPE_CONTROL) & EnableRxControl) ElseIf ((inFrame.PacketType == SOUL_PACKETTYPE_SOURCE) & EnableRxSource) Else Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: Unknown PacketType (" + inFrame.PacketType + ").") EndIf EndFunction String Function ResolveErrorCode(Int code) ; resolve SOUL protocol error codes If (code == OK_NOERROR) Return "OK_NOERROR" ElseIf (code == ERROR_SOUL_NOPOWER) Return "ERROR_SOUL_NOPOWER" ElseIf (code == ERROR_SOUL_NOTSTARTED) Return "ERROR_SOUL_NOTSTARTED" Else Return Parent.ResolveErrorCode(code) EndIf EndFunction ; internal functions Bool Function _IsDevicePowered() If (!RequirePower) Return True Else Return IsPowered() EndIf EndFunction Int Function _FrameTypeRegistration(Bool unregisterFrameType = false) If (!LinkLayer) Return ERROR_SOUL_LINKLAYER EndIf Int nlCode = OK_NOERROR If (unregisterFrameType == true) ; unregister frame type LinkLayer.FTRUnregisterNetworkLayerForFrameType(Self, LinkLayer.NETLINK_FRAMETYPE_SOUL) Else nlCode = LinkLayer.FTRRegisterNetworkLayerForFrameType(Self, LinkLayer.NETLINK_FRAMETYPE_SOUL) EndIf Return nlCode EndFunction Unfinished. Didn't even try to compile. Link to comment Share on other sites More sharing options...
South8028 Posted May 29 Author Share Posted May 29 (edited) On 5/28/2024 at 11:44 PM, niston said: Current state of NetLink:SOUL:Protocol class: Reveal hidden contents Scriptname NetLink:SOUL:Protocol extends NetLink:API:NetworkLayerBase ; audio-team SOUL (SOUTHLINK) protocol V1.0 ; custom scripting by niston ; Implementation version info Int Property IMPL_VERSION_MAJOR = 0 AutoReadOnly Hidden ; SOUL implementation version major (should match NetLink LinkLayer version) Int Property IMPL_VERSION_MINOR = 54 AutoReadOnly Hidden ; SOUL implementation version minor (should match NetLink LinkLayer version) ; SOUL protocol identifiers Int Property NETLINK_FRAMETYPE_SOUL = 8028 AutoReadOnly Hidden ; SOUL protocol uses netlink frametype 8028 Int Property PROTOCOL_VERSION = 1 AutoReadOnly Hidden ; SOUL protocol version String Property PROTOCOL_MAGIC = "SOUL" AutoReadOnly Hidden ; SOUL packet magic ; SOUL error codes Int Property ERROR_SOUL_NOTSTARTED = -3100 AutoReadOnly Hidden ; SOUL protocol not started Int Property ERROR_SOUL_NOPOWER = -3101 AutoReadOnly Hidden ; SOUL device not powered Int Property ERROR_SOUL_LINKLAYER = -3102 AutoReadOnly Hidden ; LinkLayer reference is unavailable ; SOUL packet types Int Property SOUL_PACKETTYPE_VC = 1 AutoReadonly Hidden ; Virtual Circuit packet Int Property SOUL_PACKETTYPE_SINK = 3 AutoReadonly Hidden ; SINK packet Int Property SOUL_PACKETTYPE_CONTROL = 5 AutoReadOnly Hidden ; CONTROL packet Int Property SOUL_PACKETTYPE_SOURCE = 7 AutoReadOnly Hidden ; SOURCE packet ; SOUL device types Int Property SOUL_DEVICETYPE_UNSPECIFIED = 0 AutoReadOnly Hidden ; SOUL device type not specified Int Property SOUL_DEVICETYPE_SOURCE = 1 AutoReadOnly Hidden ; SOURCE type SOUL device Int Property SOUL_DEVICETYPE_CONTROL = 2 AutoReadOnly Hidden ; CONTROL type SOUL device Int Property SOUL_DEVICETYPE_SINK = 3 AutoReadOnly Hidden ; SINK type SOUL device Int Property SOUL_DEVICETYPE_REMOTE = 4 AutoReadOnly Hidden ; REMOTE type SOUL device ; SOUL source types Int Property SOUL_SOURCETYPE_RADIO = 1 AutoReadOnly Hidden ; RADIO source type Int Property SOUL_SOURCETYPE_DESCR = 2 AutoReadOnly Hidden ; DESCRIPTOR source type ; Virtual Circuit Control Int Property VC_SYNCREQ = 1 AutoReadOnly Hidden ; synchronization request Int Property VC_SYNCACK = 2 AutoReadOnly Hidden ; synchronization acknowledgement Int Property VC_SYNCEST = 3 AutoReadOnly Hidden ; synchronization established Int Property VC_SYNCCHK = 4 AutoReadOnly Hidden ; synchronization test Int Property VC_SYNCBYE = 99 AutoReadOnly Hidden ; teardown notification ; Sink Control Int Property SINK_CMD_CLEAR = 1 AutoReadOnly Hidden ; clear (stop) emitter Int Property SINK_CMD_SYNC = 2 AutoReadOnly Hidden ; synchronize emitter Int Property SINK_CMD_PLAYBACK = 5 AutoReadOnly Hidden ; clear any existing emitter, create new emitter for SOUL Zone and start playback Int Property SINK_CMD_UPDATE = 6 AutoReadOnly Hidden ; update zone emitter Int Property SINK_CMD_VOLCNTRL = 11 AutoReadOnly Hidden ; update zone emitter volume String Property SystemNameDefault = "MySystem" Auto Const { SOUL Default System Name } Bool Property EnableRxRaw = false Auto Hidden Bool Property EnableRxVC = true Auto Hidden Bool Property EnableRxSink = true Auto Hidden Bool Property EnableRxControl = true Auto Hidden Bool Property EnableRxSource = true Auto Hidden ; Local SOUL System Name String _SystemName String Property SystemName String Function Get() Return _SystemName EndFunction Function Set(String value) _SystemName = value ; TODO: notification EndFunction EndProperty Struct SOULSourceDef String SourceName ; Name of source component Int SourceType ; SOUL source type Var SourceData ; source data EndStruct Struct SOULSourceDataRadioDef ; RADIO source Float Frequency ; radio frequency Bool Boost ; volume boost enable EndStruct Struct SOULSourceDataDescrDef ; DESCRIPTOR source Sound Descriptor ; sound descriptor ObjectReference SyncRef ; emitter synchronization reference Int Position ; playback position Int Duration ; total duration Bool Paused ; source paused EndStruct Struct SOULZoneDef ; speaker ZONE String ZoneName ; zone name SourceDef Source ; selected listening source Float VolumeL ; playback volume left hand Float VolumeR ; playback volume right hand EndStruct Struct SOULPacket String Magic Int Version String System Int PacketType Var Data EndStruct Struct SOULPacketVCType Int Command EndStruct Struct SOULPacketSinkType String Zone Int Command Var Data EndStruct Struct SOULPacketSourceType String Name Int Command Var Data EndStruct Struct DataVolumeControl Float VolumeL Float VolumeR EndStruct ; L3 protocol overrides String Function GetIdentifier() Return "SOUL" EndFunction String Function GetIdentifierDesc() Return "SOUTHLINK" EndFunction Int Function GetVersionMajor() Return IMPL_VERSION_MAJOR EndFunction Int Function GetVersionMinor() Return IMPL_VERSION_MINOR EndFunction ; SOUL packet received event CustomEvent Started CustomEvent Stopping CustomEvent SOULReceiveRaw CustomEvent SOULReceiveVC CustomEvent SOULReceiveSink Group SOULProtocolSettings Bool Property RequirePower = true Auto Const { If true, attached reference must be powered for SOUL to work } EndGroup ; true while SOUL protocol is started Bool Property IsStarted Hidden Bool Function Get() Return bStarted EndFunction EndProperty Bool bStarted = false Event OnInit() Int result = Start() EndEvent Event OnWorkshopObjectPlaced(ObjectReference refWorkshop) Int result = Start() EndEvent Event OnWorkshopObjectDestroyed(ObjectReference refWorkshop) Stop() EndEvent Event NetLink:LinkLayer.Started(NetLink:LinkLayer refLinkLayer, Var[] noneArgs) ; link layer has started If (bStarted) ; SOUL protocol still started? ; register SOUL protocol with LinkLayer _FrameTypeRegistration() EndIf EndEvent Event NetLink:LinkLayer.Stopping(NetLink:LinkLayer refLinkLayer, Var[] noneArgs) If (bStarted) ; unregister SOUL protocol from LinkLayer _FrameTypeRegistration(unregisterFrameType = true) EndIf EndEvent Int Function Start() If (!IsBoundGameObjectAvailable()) Return ERROR_UNAVAILABLE EndIf If (bStarted) ; already started Return OK_NOERROR EndIf ; start networklayer base Int result = Parent.Start() If (!CheckSuccessCode(result)) ; failed Return result EndIf ; register for link layer lifecycle events RegisterForCustomEvent(LinkLayer, "Started") RegisterForCustomEvent(LinkLayer, "Stopping") ; if linklayer is started, register networklayer frametypes If (LinkLayer.IsStarted) result = _FrameTypeRegistration() If (!CheckSuccessCode(result)) Debug.Trace(Self + ": ERROR - Protocol Start failed: FTR for FrameType (" + LinkLayer.NETLINK_FRAMETYPE_SOUL + ") failed with code (" + ResolveErrorCode(result) + ").") Return result EndIf EndIf ;Debug.Trace(Self + ": DEBUG - Protocol scriptname is (" + NetworkLayerScriptname + ").") ; log chatter Debug.Trace(Self + ": INFO - Protocol started.") ; SOUL protocol started bStarted = true SendCustomEvent("Started", new Var[0]) Return OK_NOERROR EndFunction Function Stop() If (bStarted) ; SOUL protocol no longer started bStarted = false SendCustomEvent("Stopping", new Var[0]) ; unregister this networklayer from linklayer If (LinkLayer != none) If (LinkLayer.IsStarted) _FrameTypeRegistration(unregisterFrameType = true) EndIf ; unregister link layer lifecycle events UnRegisterForCustomEvent(LinkLayer, "Started") UnRegisterForCustomEvent(LinkLayer, "Stopping") EndIf ; stop NetworkLayer base class Parent.Stop() ; log chatter Debug.Trace(Self + ": INFO - Protocol stopped.") EndIf EndFunction send a SOUL SINK command to a system/zone Int Function SendCommandSink(ObjectReference refRecipient, String zoneName, Int commandId, Var commandData) If (!_IsDevicePowered()) Debug.Trace(Self + ": WARNING - SendCommandSink() skipped: Device not powered.") Return ERROR_SOUL_NOPOWER EndIf If (!bStarted) Debug.Trace(Self + ": ERROR - SendCommandSink() failed: Protocol not started.") Return ERROR_SOUL_NOTSTARTED EndIf SOULPacketSinkType outPacket = new SOULPacketSinkType outPacket.Zone = zoneName outPacket.Command = commandId outPacket.Data = commandData Return SendSOULPacket(refRecipient, systemName, outPacket) EndFunction Int Function SendSOULPacket(ObjectReference refRecipient, Int packetType, Var packetData) SOULPacket outPacket = new SOULPacket outPacket.Magic = PROTOCOL_MAGIC outPacket.Version = PROTOCOL_VERSION outPacket.System = _SystemName outPacket.PacketType = packetType outPacket.Data = packetData If (!bStarted) Debug.Trace(Self + ": ERROR - SendSOULPacket() failed: Protocol not started.") Return ERROR_SOUL_NOTSTARTED EndIf If (!_IsDevicePowered()) Debug.Trace(Self + ": WARNING - SendSinkCommand() skipped: Device not powered.") Return ERROR_SOUL_NOPOWER EndIf Debug.Trace(Self + ": DEBUG - Sending SOUL Packet (" + outPacket + ") for System (" + outPacket.System + ") to Link Layer...") Int success = LinkLayer.LinkSend(refRecipient, NETLINK_FRAMETYPE_SOUL, outPacket) Return success EndFunction ; function to transmit "raw" SOUL packets Int Function SendSOULPacketRaw(ObjectReference refRecipient, SOULPacket outPacket) If (!bStarted) Debug.Trace(Self + ": ERROR - SendSOULPacketRaw() failed: SOUL protocol not started.") Return ERROR_SOUL_NOTSTARTED EndIf If (!_IsDevicePowered()) Return ERROR_SOUL_NOPOWER EndIf Debug.Trace(Self + ": DEBUG - Sending SOUL Packet (" + outPacket + ") for System (" + outPacket.System + ") to Link Layer...") Int success = LinkLayer.LinkSend(refRecipient, NETLINK_FRAMETYPE_SOUL, outPacket) Return success EndFunction Function OnLinkReceive(Var[] eventArgs) ; SUP accelerated version NetLink:API:LinkLayerBase srcLinkLayer = eventArgs[0] as NetLink:LinkLayer NetLink:API:LinkLayerBase:NetLinkFrame inFrame = eventArgs[1] as NetLink:API:LinkLayerBase:NetLinkFrame ; RX filters If (srcLinkLayer == none) ; missing or invalid source linklayer: discard frame. Return EndIf If (inFrame == none) ; missing or non-netlink frame: discard. Return EndIf If (inFrame.FrameType != NETLINK_FRAMETYPE_SOUL) ; not a SOUL type NetLink Frame: discard. Return EndIf ; protocol started? If (!bStarted) ;Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: Protocol not started.") Return EndIf ; device powered? If (!_IsDevicePowered()) ;Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: Device not powered.") Return EndIf ; SOUL FrameType received, extract SOUL packet payload SOULPacket soulPacket = inFrame.Payload as SOULPacket If (soulPacket == none) Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: Null Payload.") Return EndIf If (soulPacket.Magic != PROTOCOL_MAGIC) Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: Invalid MAGIC (" + soulPacket.Magic + ").") Return EndIf ; SOUL type frame has proper SOUL protocol version? If (soulPacket.Version != PROTOCOL_VERSION) Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: SOUL Protocol version (" + soulPacket.VERSION + ") not supported.") Return EndIf ;Debug.Trace(Self + ": DEBUG - Received SOUL type Frame from Link Layer.") If (EnableRxRaw) ; generate raw rx event Var[] outEventArgs = new Var[3] outEventArgs[0] = inFrame.Source ; netlink source ref outEventArgs[1] = inFrame.Destination ; netlink destination ref outEventArgs[2] = soulPacket ; SOUL packet received SendCustomEvent("SOULReceiveRaw", outEventArgs) EndIf ; decode PacketType If ((soulPacket.PacketType == SOUL_PACKETTYPE_VC) & EnableRxVC) ; # virtual circuit packet rxVCCtrl = inFrame.Data as SOULPacketVCType If (rxVCCtrl == none) Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: Invalid or missing Data segment for PacketType (SOUL_PACKETTYPE_VC).") Return EndIf ; TODO: actual implementation ElseIf ((inFrame.PacketType == SOUL_PACKETTYPE_SINK) & EnableRxSink) ; # sink packet rxSinkCtrl = inFrame.Data as SOULPacketSinkType If (rxSinkCtrl == none) Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: Invalid or missing Data segment for PacketType (SOUL_PACKETTYPE_SINK).") Return EndIf Var[] rxSCEventArgs = new Var[6] rxSCEventArgs[0] = inFrame.Source rxSCEventArgs[1] = inFrame.Destination rxSCEventArgs[2] = soulPacket.System rxSCEventArgs[3] = rxSinkCtrl.Zone rxSCEventArgs[4] = rxSinkCtrl.Command rxSCEventArgs[5] = rxSinkCtrl.Data SendCustomEvent("SOULReceiveSink", rxSCEventArgs) ElseIf ((inFrame.PacketType == SOUL_PACKETTYPE_CONTROL) & EnableRxControl) ElseIf ((inFrame.PacketType == SOUL_PACKETTYPE_SOURCE) & EnableRxSource) Else Debug.Trace(Self + ": WARNING - SOUL type Frame discarded: Unknown PacketType (" + inFrame.PacketType + ").") EndIf EndFunction String Function ResolveErrorCode(Int code) ; resolve SOUL protocol error codes If (code == OK_NOERROR) Return "OK_NOERROR" ElseIf (code == ERROR_SOUL_NOPOWER) Return "ERROR_SOUL_NOPOWER" ElseIf (code == ERROR_SOUL_NOTSTARTED) Return "ERROR_SOUL_NOTSTARTED" Else Return Parent.ResolveErrorCode(code) EndIf EndFunction ; internal functions Bool Function _IsDevicePowered() If (!RequirePower) Return True Else Return IsPowered() EndIf EndFunction Int Function _FrameTypeRegistration(Bool unregisterFrameType = false) If (!LinkLayer) Return ERROR_SOUL_LINKLAYER EndIf Int nlCode = OK_NOERROR If (unregisterFrameType == true) ; unregister frame type LinkLayer.FTRUnregisterNetworkLayerForFrameType(Self, LinkLayer.NETLINK_FRAMETYPE_SOUL) Else nlCode = LinkLayer.FTRRegisterNetworkLayerForFrameType(Self, LinkLayer.NETLINK_FRAMETYPE_SOUL) EndIf Return nlCode EndFunction Unfinished. Didn't even try to compile. I apologize for the delay. I was very busy. Only now was I finally able to calmly sit down at the computer. I remade the model, now I'm redoing the uv. How do we make touch buttons? Is each button a separate nif (2 sequences)? Are buttons a group with a set of sequences? Edited May 30 by South8028 1 Link to comment Share on other sites More sharing options...
niston Posted May 30 Share Posted May 30 Quote How do we make touch buttons? Is each button a separate nif (2 sequences)? Yes, every button must be separate - If they were grouped together, player could only activate the entire group as a whole. Basically, anything that needs to be interacted with must be a separate object. Link to comment Share on other sites More sharing options...
South8028 Posted May 30 Author Share Posted May 30 (edited) 9 minutes ago, niston said: Yes, every button must be separate - If they were grouped together, player could only activate the entire group as a whole. Basically, anything that needs to be interacted with must be a separate object. Respectively. Round buttons: Power – 4 states. Config - 4 states. Sensors - 2 states each. I probably need to make small indicators above the buttons. I wanted the splines themselves to glow, but it won't look nice. The buttons themselves are splines with text/numbers (we will attach collisions to them). Collisions are large rectangles hung in a row away from the buttons. You can make a fun effect with virtual buttons. I'm not sure if this is a good idea, but technically it's not difficult. When you press one button, a series of huge buttons will appear in space - clones of the sensor row in the form of, for example, a hologram with collisions. Edited May 30 by South8028 Link to comment Share on other sites More sharing options...
Recommended Posts