pepperman35 Posted September 8, 2019 Share Posted September 8, 2019 Okay, scripting warriors I have another question for you. Background: I want to use the RelayTowerPublic [aka Radio tower 3SM-U81 (RelayTower01ext cell)] as a custom recruitment radio beacon for my settlement, which will be activated by a terminal. I’d like for the beacon to become active once the antennas are deployed and deactivate when the antenna are retracted. Actions Take: The Relay Tower is added with the following keyword: WorkshopRadioObject, and the following actor values: PowerRadiation(1500), WorkshopRatingRadio(1), and WorkshopResourceObject(1). Ref links, scripts and fragment match those from RelayTower01ext cell. Currently, my version works just like the one in cell RelayTower01ext (i.e., antenna deploy and retract on command via the terminal). However, it is unclear to me where and how to get the rest of it to work (broadcast signal as desired). Help Requested (scripting): What do I need to do in order to get the beacon to broadcast signal when the antennas are deployed (i.e., Tower is in the up position) and stop broadcasting signal when the antennas are retracted (i.e. Tower is in the down position). Any help would be welcomed and most appreciated. Link to comment Share on other sites More sharing options...
pepperman35 Posted September 15, 2019 Author Share Posted September 15, 2019 After looking at the WorkshopObjectScript and the WorkshopParentScript, I decided to start small. I added the WorkshopRadioBeacon and a default terminal into the mod. Within the terminal I added the two menu items: Activate Radio Beacon and Deactivate Radio Beacon. I added a property with the following values:Property Name: myBeaconType: ObjectReferenceValue: Pointed it to the Radio Beacon For a simple Papyrus Fragment I used myBeacon.SetOpen(false) for the Activate Radio Beacon menu item and myBeacon.SetOpen(true).In game, I manually added a small generator to power the Radio Beacon, tested it manually to confirm it was working and then shut it down via the switch. I then tried using the terminal to turn the radio beacon on and the switch light turns green, and there is an audio of the switch activating; however, no signal was apparently being broadcast. At this point I am at a loss on how to proceed. I fast traveled away and back. Repeated the process but the results were the same ...no broadcast signal via the terminal. Any pointers. Link to comment Share on other sites More sharing options...
pra Posted September 16, 2019 Share Posted September 16, 2019 Can't remember exactly what it was, but there is code for this whole radio thing in the WorkshopObject script. You will most definitely need to extend it. I think there was either a bool property or a function which returns bool, which determines whenever the radio is on or not. Search for "radio" in the file. Link to comment Share on other sites More sharing options...
pepperman35 Posted September 16, 2019 Author Share Posted September 16, 2019 Thanks for the reply. In the WorkshopObjectScript there is the event Event OnActivate(ObjectReference akActionRef);WorkshopParent.wsTrace(self + " activated by " + akActionRef + " isradio?" + HasKeyword(WorkshopParent.WorkshopRadioObject))if akActionRef == Game.Getplayer() ;WorkshopParent.wstrace(self + " activated by player")if CanProduceForWorkshop()if HasKeyword(WorkshopParent.WorkshopRadioObject); radio on/off; toggle statebRadioOn = !bRadioOnWorkshopParent.UpdateRadioObject(self)endifelseendif; player commentif IsBed() == falseWorkshopParent.PlayerComment(self)endifendif if GetBaseObject() as FloraSetValue(WorkshopParent.WorkshopFloraHarvestTime, Utility.GetCurrentGameTime())endifEndEvent Inside the WorkshopParentScript there is the function ... function UpdateRadioObject(WorkshopObjectScript radioObject) wsTrace("UpdateRadioObject for " + radioObject) WorkshopScript workshopRef = GetWorkshop(radioObject.workshopID) ; radio if radioObject.bRadioOn && radioObject.IsPowered() wsTrace(" starting radio station") ; make me a transmitter and start radio scene ; 1.6: allow workshop-specific override if workshopRef.WorkshopRadioRef workshopRef.WorkshopRadioRef.Enable() ; enable in case this is a unique station radioObject.MakeTransmitterRepeater(workshopRef.WorkshopRadioRef, workshopRef.workshopRadioInnerRadius, workshopRef.workshopRadioOuterRadius) if workshopRef.WorkshopRadioScene.IsPlaying() == false workshopRef.WorkshopRadioScene.Start() endif else radioObject.MakeTransmitterRepeater(WorkshopRadioRef, workshopRadioInnerRadius, workshopRadioOuterRadius) if WorkshopRadioScene01.IsPlaying() == false WorkshopRadioScene01.Start() endif endif if workshopRef.RadioBeaconFirstRecruit == false WorkshopEventRadioBeacon.SendStoryEvent(akRef1 = workshopRef) endif else wsTrace(" stopping radio station") radioObject.MakeTransmitterRepeater(NONE, 0, 0) ; if unique radio, turn it off completely if workshopRef.WorkshopRadioRef && workshopRef.bWorkshopRadioRefIsUnique wsTrace(" custom station: disabling transmitter") workshopRef.WorkshopRadioRef.Disable() ; stop custom scene if unique workshopRef.WorkshopRadioScene.Stop() endif endif ; send power change event so quests can react to this workshopRef.RecalculateWorkshopResources() SendPowerStateChangedEvent(radioObject, workshopRef)endFunction So how do I change the bRadioOn variable and send it back to the function via a Papyrus Fragment? I tried defining the variable bool Property bRadioOn = true auto hidden to start and it didn't like that. Rather a noob when it comes to scripting. Link to comment Share on other sites More sharing options...
niston Posted September 21, 2019 Share Posted September 21, 2019 I implemented a custom radio beacon in the next update (not published so far) to my "forest grove water lock" mod. Basically reused an existing made a new object based on the workshop beacon, gave it a different NIF (invisible or whatever), made it self powered and powered on by default (keywords) and then controlled the beacon ON/OFF by enable()/disable() it. Had to add a small script to activate() it on load, it's posted below. Link to comment Share on other sites More sharing options...
niston Posted September 22, 2019 Share Posted September 22, 2019 Ok, here's my activator script. It's really simple: Scriptname ForestGroveSluice:FGS_RecruitmentBeaconActivator extends ObjectReference ; custom scripting by niston Event OnLoad() If !(IsDisabled()) Self.Activate(Game.GetPlayer(), true) EndIf EndEvent Link to comment Share on other sites More sharing options...
pepperman35 Posted September 22, 2019 Author Share Posted September 22, 2019 thanks niston, much appreciated. I'll give this a look see and see how it might work within the context RelayTowerPublic [aka Radio tower 3SM-U81 (RelayTower01ext cell)]. Link to comment Share on other sites More sharing options...
niston Posted September 23, 2019 Share Posted September 23, 2019 So I've had a quick look at RelayTowerScript.psc and it's state based. You should be able to make a control script that registers for remote OnBeginState event on RelayTowerScript. This event will inform the control script whenever the relay tower script enters a new state. If the new state is DownPosition, the tower is retracted. If new state is UpPosition, the tower is extended. It could also be MovingUp *while* its extending, or MovingDown *while* it's retracting, but these are probably not relevant to your use case. This mechanism will also initialize "automagically" because the DownPosition is auto state. Nice! The control script may then simply enable the custom recruitment beacon on receiving UpPosition and disable it on receiving DownPosition. Something like this perhaps: Scriptname RTRB_ControlScript extends ObjectReference ; custom scripting by niston ObjectReference Property RecruitmentBeacon Auto Const { Pick Custom Recruitment Beacon reference in Render Window } Event OnInit() ; register OnBeginState event on RelayTowerScript attached to same reference we are attached to RegisterForRemoteEvent((((Self as ObjectReference) as RelayTowerScript) as ScriptObject), "OnBeginState") EndEvent Event OnLoad() ; re-register remote event on load, make sure we dont stack up registrations UnRegisterForRemoteEvent((((Self as ObjectReference) as RelayTowerScript) as ScriptObject), "OnBeginState") RegisterForRemoteEvent((((Self as ObjectReference) as RelayTowerScript) as ScriptObject), "OnBeginState") EndEvent Event ScriptObject.OnBeginState(ScriptObject akSender, String oldState) ; state change event received, decide based on current state ScriptObject refRTSO = (((Self as ObjectReference) as RelayTowerScript) as ScriptObject) If (refRTSO.GetState() == "DownPosition") ; tower is retracted, disable beacon Debug.Notification("Tower retracted") RecruitmentBeacon.Disable() ElseIf (refRTSO.GetState() == "UpPosition") ; tower is extended, enable beacon Debug.Notification("Tower extended") RecruitmentBeacon.Enable() EndIf EndEvent Attach the script to the relay tower and fill out the RecruitmentBeacon property in CK and see if it works. I also suggest to not test with an invisible NIF for the custom recruitment beacon. This way, you can actually observe the beacon properly spawning into or vanishing from existence. You may always switch over to invisible.NIF later on, when stuff has been verified to work. Link to comment Share on other sites More sharing options...
niston Posted September 23, 2019 Share Posted September 23, 2019 Welp, I just tested the above and it doesn't work. LOL. I really don't understand why though. The runtime error is: error: [RelayTowerScript < (001D1AEA)>] does not receive "OnBeginState" events, registration request ignored But the RelayTowerScript clearly does receive OnBeginState events, it even handles them. :huh: Link to comment Share on other sites More sharing options...
niston Posted September 23, 2019 Share Posted September 23, 2019 After dabbling around for a while, I fail to see why my above script doesn't work. It makes no sense. Anyways, I made another one, working with OnAnimationEvent this time: Scriptname RTRB_ControlScript extends ObjectReference ; custom scripting by niston ObjectReference Property RecruitmentBeacon Auto Const { Pick Custom Recruitment Beacon reference in Render Window } Event OnInit() ; call setup procedure from OnInit event Debug.Trace(self + " - OnInit()") Setup() EndEvent Event OnLoad() ; call setup procedure from OnLoad event Debug.Trace(self + " - OnLoad()") Setup() EndEvent Event OnAnimationEvent(ObjectReference akSource, String eventName) ; animation event received Debug.Trace(self + " - Animation Event received") ; update beacon according to current state UpdateBeacon() EndEvent Function Setup() ; (re-)register animation event, make sure we dont stack up registrations UnRegisterForAnimationEvent(self, "done") If (RegisterForAnimationEvent(self, "done")) Debug.Trace(self + " - Animation Event registered succcessfully") Else Debug.Trace(self + " - Failed to register Animation Event") EndIf ; update beacon according to current state UpdateBeacon() EndFunction Function UpdateBeacon() ; enables/disables the RecruitmentBeacon, depending on wether the radio tower is extended or retracted RelayTowerScript refRTSO = ((Self as ObjectReference) as RelayTowerScript) If (refRTSO.GetState() == "DownPosition" || refRTSO.GetState() == "MovingDown") ; tower is retracted, disable beacon Debug.Notification("Tower retracted; Disabling beacon...") RecruitmentBeacon.Disable() ElseIf ((refRTSO.GetState() == "UpPosition") || (refRTSO.GetState() == "MovingUp")) ; tower is extended, enable beacon Debug.Notification("Tower extended; Enabling beacon...") RecruitmentBeacon.Enable() EndIf EndFunction Attach script to relay tower, fill out RecruitmentBeacon property. Tested it in my game and found it working. You might want to remove the Debug.Notification() calls in UpdateBeacon() function after testing. Something else to be aware of: The relay towers retract on their own, after some time. Link to comment Share on other sites More sharing options...
Recommended Posts