vonBennett Posted March 14, 2020 Share Posted March 14, 2020 I am trying to add a settlement recruitment beacon to each of my settlements that I created for my settlement mod (six settlements total so far). I got the recruitment beacons to work (mostly) but I am having an issue. I created the recruitment beacons as follows: I created a new form using the standard workshop recruitment beacon. I changed the .nif on the new form to one of the vault lights (green lit). Each settlement has its own specific recruitment beacon form along with a settlement specific reference ID. (example: Form: vonBennett_RecruitmentBeacon_CountyCrossing; ref id:: RecruitmentBeacon_CountyCrossing). The recruitment beacon is given its own internal power source so that it will work when activated since items created in the Creation Kit seem not to be able to be powered when the mod is loaded in the game (seems like this is an issue with the Creation Kit). The recruitment beacons need a power source and they will not work even if you remove the power requirement in the form. The recruitment beacon is then linked to the workshop (link reference; keyword: workshopitemkeyword). The settlement recruitment beacon is also liked to a Enable Marker (active parent; set to initially disabled). The Enable Marker is linked to the settlement recruitment switch (red rocket button) using the standard light switch script (used to turn lights off and on in the game). So basically, in game, you flip the switch and the settlement recruitment beacon appears (as it is s enabled) and after a short warm up period in game, it begins to work. The recruitment single appears in the Pip Boy Radio and settlers begin to show up. The problem is that when I turn the settlement recruitment beacons off (by flipping the switch thus disabling them) in all of the settlements, it seems that even through all the beacons are off, including the fact that no radio recruitment broadcast is coming over the Pip Boy, one settlement (not always the same one) seems to still get settlers coming to that settlement. It appears that only one settlement at a time does that and the rest do not get any. Even if I directly flip on the beacon (which turns it off) and then flip the settlement beacon switch (which disables the beacon), settlers still come to one of the settlements. I am assuming that it has something to do with adding an internal power source to the recruitment beacons as the only way to stop the settlers coming is to remove the internal power source while in the Creation Kit; then load the saved game back up. I think the only real option to prevent this from happening is to have an external power source that can be turned off in game thus truly deactivating the recruitment beacons. However, there is the issue with items that require power that are added in the Creation kit cannot be powered up in the game (unless power lines are attached in workshop mode; not an option in my situation). Doe's anyone have a solution to this problem? Link to comment Share on other sites More sharing options...
SKKmods Posted March 14, 2020 Share Posted March 14, 2020 No direct solution, but from some current work on detecting and fixing workshop resource issues: The actual function that recruits settlers depending on the radio state is WorkshopScript.DailyUpdate process which calls DailyUpdateAttractNewSettlers() That checks the Workshop ActorValue WorkshopRatingRadio which if > 0 (plus population cap tests) will start a recruitment. Test this in the console, click on the workshop and [ getvalue 127241 ] is it zero with the beacon switched off ? If not its probably the super fragile rats nest of scripting WorkshopParentScript > WorkshopObjectScript > WorkshopScript plus the Papyrus limitation of 128 elements in arrays can cause the workshop resource actor values to become screwed. Check how many resource objects the workshop has to manage in script with; ActorValue pWorkshopResourceObject = Game.GetFormFromFile(0x00129a8c, "Fallout4.esm") as ActorValueDebug.Trace("WorkshopResourceObjects " + (ThisWorkshop.GetWorkshopResourceObjects(akAV = pWorkshopResourceObject, aiOption=0)).Length) Link to comment Share on other sites More sharing options...
vonBennett Posted March 14, 2020 Author Share Posted March 14, 2020 (edited) Testing...but so far I get inconsistent readings. In County Crossing when I switched the beacon on, typing getvalue 127241 on the workshop returned zero value; switching beacon off same return value of zero. When doing the same on the beacon itself, the return value was one when the beacon was on and the return value was zero when the beacon was off. I did the same set of tests in Outpost Zimonja and got return values of one on the beacon both on and off, and a return value of one on the workshop with beacon both on and off. I will continue testing the rest of the settlements with my beacons Edited March 14, 2020 by vonBennett Link to comment Share on other sites More sharing options...
SKKmods Posted March 14, 2020 Share Posted March 14, 2020 OK two other things to check if they are switching on and off OK on the object script, which is two things: script variable bRadioOn and function IsPowered() Click on the radio beacon, then console [ sv ] to show the object variables, your looking for: bRadioOn Unfortunately you will need to script the IsPowered() function output Link to comment Share on other sites More sharing options...
niston Posted March 14, 2020 Share Posted March 14, 2020 You can try adding the switch keyword to the beacon and then use SetOpen(true)/SetOpen(false) to enable/disable the beacon. Link to comment Share on other sites More sharing options...
SKKmods Posted March 14, 2020 Share Posted March 14, 2020 That reminds me we danced around this one a couple of months ago. The control script looks at both bRadioOn and IsPowered to set the actual recruitment state and this may be the IsPowered lag still reporting true after being switched off for a while .... >"Agree that GetOpenState is more robust than IsPowered which will flip instantly from False to True, but then lags reporting True for a while after switch off (see last debug line)" Link to comment Share on other sites More sharing options...
vonBennett Posted March 14, 2020 Author Share Posted March 14, 2020 I am still testing things out. I had removed the self powered ability from each of the settlement recruitment beacon forms (to stop the previous recruitment of settlers) and I added them back in the Creation Kit. I am running around to each settlement to test. So far at the settlements I have tested, when I turn the radio beacons on and check [ sv ] in the console, bRadioOn = true. When I switch of there is no return reading as the beacons are disable by the 'light switch script'. I am testing and am trying to recreate one of the settlements continuing to recruit even thought he beacon is off. @Niston: The individual recruitment beacon forms all have the keyword 'WorkshopSwitchActivatorKeyword'. Is that the one you are referring to? Also, when you state "and then use SetOpen(true)/SetOpen(false) to enable/disable the beacon." is that something different to what I am already doing (hooking things up using the light switch script n conjunction with an Enable Marker and activator switch) when I hit the switch and the recruitment beacons are enabled (appear and start to work) and when I hit the switch again, they are disabled (disappear and stop working)? Link to comment Share on other sites More sharing options...
niston Posted March 15, 2020 Share Posted March 15, 2020 That's the keyword yes. SetOpen() triggers a power grid update, whereas enabling/disabling a reference does not. Try it. SetOpen(true) == circuit is open == power does not flowSetOpen(false) == circuit is closed == power does flow This works on a lot of powered references btw. You can turn on/off all vanilla generators and even some consumers with this. A completely diamteral approach you can try is, removing the Switch keyword (while keeping them self powered) and then enabling/disabling them. I use this technique for my forest grove water lock recruitment beacon. The only downside I found: The first time you enable the beacon, it won't show up on pipboy until you change cell - But it'll nonetheless start recruiting right away. Something I noticed with the vanilla recruitment beacon (the one from workshop) is, the switch doesn't work right. So it might just be that and getting rid of the switch keyword may work around the bug. *shrug* Link to comment Share on other sites More sharing options...
vonBennett Posted March 15, 2020 Author Share Posted March 15, 2020 Thank you Niston, I will give removing the Switch Keyword a try since I already have the recruitment beacons set to be enabled and disable via the Enable Marker and Red Rocket Switch (using the light switch script). Link to comment Share on other sites More sharing options...
SKKmods Posted March 15, 2020 Share Posted March 15, 2020 Just remembered, I re-wrote a simplified yet strengthened beacon script for one of my mods which has been working flawlessly (with the normal recruitment beacon NIF and other non animated models like the ham radio) for several years. Some of the elements may be useful to you if the current scripts are bein unpredictable, or just slap it on with a global variable and message. Scriptname SKK_WUWorkshopRecruitmentBeaconScript extends ObjectReference Group BaseGame Actor Property pPlayerREF Auto Const Mandatory Quest Property pWorkshopParent Auto Const Mandatory Keyword Property pWorkshopType02 Auto Const Mandatory Keyword Property pWorkshopItemKeyword Auto Const Mandatory ActorValue Property pPowerRequired Auto Const mandatory ;av 6 ActorValue Property pBed Auto Const mandatory ;av 6 ActorValue Property pWorkshopRatingPopulation Auto Const mandatory ;av 2 EndGroup Group SKK_WU Message Property pSKK_WUWorkshopRecruitmentBeaconON Auto Const Mandatory GlobalVariable Property pSKK_WURecruitmentGameHours Auto Const Mandatory EndGroup Bool bStateON = False Bool bPowerON = False Int iRecruitmentTimer = 10 ;Enables recruitment: ; >If the workshop is still player owned (could be lost) after building. ; >If the device is switched ON (and has Power if it needs power). ;Recruits: ; >When Global variable driven game timer expires. ; >If the workshop is still player owned (could be lost) after building. ; >If the device is switched ON and has Power (if it needs power). ; >If the population is below 127. ; >If the population is smaller than the number of beds (because the CHR based mechanic is lame). ; >If a normal settlement calls WorkshopParent.CreateActor to spawn a WorkshopNPC. ; >If a Type02 raider outpost remote calls DLC04WorkshopParent.CreateRaider. ;************************************************************************************* Event OnPowerOn(ObjectReference akPowerGenerator) Debug.Trace ("SKK_WUWorkshopRecruitmentRadioScript.OnPowerOn " + Self) bPowerON = TRUE SwitchState(bPowerEvent = TRUE) EndEvent ;************************************************************************************* Event OnPowerOff() Debug.Trace ("SKK_WUWorkshopRecruitmentRadioScript.OnPowerOff " + Self) bPowerON = FALSE SwitchState(bPowerEvent = TRUE) EndEvent ;************************************************************************************* Event OnActivate(ObjectReference akActionRef) Self.BlockActivation(True, True) ;avoid keybounce queue If (akActionRef == (pPlayerREF as ObjectReference)) Debug.Trace ("SKK_WUWorkshopRecruitmentRadioScript.OnActivate " + Self) SwitchState(bPowerEvent = FALSE) EndIf Self.BlockActivation(false, False) EndEvent ;************************************************************************************* Function SwitchState(Bool bPowerEvent) ObjectReference WorkshopREF = Self.GetLinkedRef(pWorkshopItemKeyword) If ((WorkshopREF as WorkshopScript).OwnedByPlayer == FALSE) bStateON = FALSE ElseIf (bPowerEvent == FALSE) && (bStateON == FALSE) ;This state logic incase the NIF does not support GetOpenState() bStateON = TRUE ElseIf (bPowerEvent == FALSE) && (bStateON == TRUE) bStateON = FALSE EndIf If (bStateON == TRUE) && (WorkshopREF != None) && ( (Self.GetValue(pPowerRequired) > 0) && (bPowerON == TRUE) ) ;Incase the object does not need power StartTheTimer() pSKK_WUWorkshopRecruitmentBeaconON.Show(pSKK_WURecruitmentGameHours.GetValue()) ;New settlers should arrive in around %.0f hours. Debug.Trace ("SKK_WUWorkshopRecruitmentRadioScript.SwitchState OFF>ON " + Self + " Workshop " + WorkshopREF) Else Self.CancelTimerGameTime(iRecruitmentTimer) Debug.Trace ("SKK_WUWorkshopRecruitmentRadioScript.SwitchState ON>OFF " + Self + " Workshop " + WorkshopREF) EndIf EndFunction ;************************************************************************************* Function StartTheTimer() Float fThisWaitTime = Utility.RandomFloat((pSKK_WURecruitmentGameHours.GetValue() * 0.75), (pSKK_WURecruitmentGameHours.GetValue() * 1.25)) ;add jitter Self.StartTimerGameTime(fThisWaitTime, iRecruitmentTimer) EndFunction ;************************************************************************************* Event OnTimerGameTime(Int iTimer) ; this script timer keeps running even when the parent object is unloaded, so HA! If (iTimer == iRecruitmentTimer) && (Self.IsBoundGameObjectAvailable() == TRUE) && (bStateON == TRUE) && ( (Self.GetValue(pPowerRequired) > 0) && (bPowerON == TRUE) ) ;I have not been stored or destroyed in the meantime ObjectReference WorkshopREF = Self.GetLinkedRef(pWorkshopItemKeyword) If (WorkshopREF != None) && ((WorkshopREF as WorkshopScript).OwnedByPlayer == TRUE) && (TestPopulationAndBeds(WorkshopREF) == TRUE) ; someone needs to enforce the Papyrys array limit for f*#@s sake WorkshopNPCScript ThisWorkshopNPC If ( WorkshopREF.HasKeyword(pWorkshopType02) == TRUE) && (Game.IsPluginInstalled("DLCNukaWorld.esm") == TRUE) ;Its a raider Outpost Quest rDLC04WorkshopParent = Game.GetFormFromFile(0x00007be6, "DLCNukaWorld.esm") as Quest If (rDLC04WorkshopParent != None) Var[] kArgs = new Var[2] kArgs[0] = WorkshopREF as WorkshopScript kArgs[1] = None ScriptObject RemoteScript = rDLC04WorkshopParent.CastAs("DLC04:DLC04WorkshopParentScript") Var vReturn = RemoteScript.CallFunction("CreateRaider", kArgs) ThisWorkshopNPC = (vReturn as WorkshopNPCScript) ;ThisREF = (rDLC04WorkshopParent as DLC04:DLC04WorkshopParentScript).CreateRaider(( WorkshopREF as WorkshopScript), spawnMarker = NONE) EndIf Else ThisWorkshopNPC = (pWorkshopParent as WorkshopParentScript).CreateActor(( WorkshopREF as WorkshopScript), bBrahmin = FALSE, spawnMarker = NONE, bNewSettlerAlias = FALSE) EndIf Debug.Trace ("SKK_WUWorkshopSpawnRadioScript.OnTimerGameTime WorkshopREF " + WorkshopREF + " settler " + ThisWorkshopNPC ) SwitchState(bPowerEvent = TRUE) ;do not reset state, just restart the timer EndIf EndIf EndEvent ;************************************************************************************* Bool Function TestPopulationAndBeds(ObjectReference WorkshopREF) Float fCurrentPopulation = WorkshopREF.GetBaseValue(pWorkshopRatingPopulation) Float fNumberOfBeds = WorkshopREF.GetBaseValue(pBed) Bool bPass = TRUE If (fCurrentPopulation > 127) || (fCurrentPopulation >= fNumberOfBeds) bPass = FALSE Endif Return bPass EndFunction ;************************************************************************************* Event OnWorkshopObjectDestroyed (ObjectReference akWorkshopRef) ; triggers on store or scrap Self.CancelTimerGameTime(iRecruitmentTimer) EndEvent ;************************************************************************************* Link to comment Share on other sites More sharing options...
Recommended Posts