Jump to content

Beginner Scripting: Script communication and settlers.


Recommended Posts

I'm working on a mod that makes some big, but simple world changes - new monster spawns, dead NPCs, deactivated settlements, and so on. My biggest problem right now is that I have the scripting skills of an unripened walnut right now. All I can code is a basic dialogue system through message boxes.

 

My biggest challenge is getting scripts talking to eachother, or to stuff like package conditions. I have no idea how to handle custom events or any kind of inter-script communication like that. Are there any walnut-oriented tutorials out there, or base-game scripts that I should be looking at?

 

A second hurdle is that I'd like to get rid of all the settlers at the player's settlements, as part of a "world restart" kind of quest. I have absolutely no idea how to do this. Ideally, I'd like to strip their inventories, toss them into the workbench inventory, and then scatter all that across the world, but I'm only confident in my ability to handle the last one. Has anyone chewed on this kind of thing before?

Link to comment
Share on other sites

What you are proposing is some intricate and complex scripting. Reflecting on my own learning journey, that's probably several months practice over several smaller mods.

 

Here is a script that will remove all existing settlers (from Fallout 4-76):

WorkshopParentScript Property pWorkshopParent Auto Const Mandatory

Function RemoveAllSettlers(Bool bPlayerOwnedOnly = TRUE)

WorkshopScript[] WorkshopREFs = pWorkshopParent.Workshops
Int iWorkshopIndex = 0

While (iWorkshopIndex < WorkshopREFs.Length)
  WorkshopScript ThisWorkshop = (WorkshopREFs[iWorkshopIndex] as WorkshopScript)
  If (ThisWorkshop != None) && ((bPlayerOwnedOnly == FALSE) || (ThisWorkshop.OwnedByPlayer == TRUE))
    ObjectReference[] WorkshopActors = pWorkshopParent.GetWorkshopActors(ThisWorkshop)
    Int iActorIndex = 0
    While iActorIndex < WorkshopActors.Length
      WorkshopActors[iActorIndex].RemoveAllItems(akTransferTo = ThisWorkshop, abKeepOwnership = false)
      pWorkshopParent.RemoveActorFromWorkshopPUBLIC(WorkshopActors[iActorIndex] as WorkshopNPCScript)
      WorkshopActors[iActorIndex].Disable()
      WorkshopActors[iActorIndex].Delete()
      iActorIndex += 1
    EndWhile
  EndIf
  iWorkshopIndex += 1
EndWhile 

EndFunction
Edited by SKK50
Link to comment
Share on other sites

What you are proposing is some intricate and complex scripting. Reflecting on my own learning journey, that's probably several months practice over several smaller mods.

I guess I was expecting it wasn't going to be easy. I was just hoping it'd be somewhere in my reach.

 

Still, help's help, and I appreciate it. There are a couple small things I wanted to ask about the script you posted, though:

WorkshopParentScript Property pWorkshopParent Auto Const Mandatory

Function RemoveAllSettlers(Bool bPlayerOwnedOnly = TRUE)

WorkshopScript[] WorkshopREFs = pWorkshopParent.Workshops
Int iWorkshopIndex = 0

While (iWorkshopIndex < WorkshopREFs.Length)
  WorkshopScript ThisWorkshop = (WorkshopREFs[iWorkshopIndex] as WorkshopScript)
  If (ThisWorkshop != None) && ((bPlayerOwnedOnly == FALSE) || (ThisWorkshop.OwnedByPlayer == TRUE))
    ObjectReference[] WorkshopActors = pWorkshopParent.GetWorkshopActors(ThisWorkshop)
    Int iActorIndex = 0
    While iActorIndex < WorkshopActors.Length
      WorkshopActors[iActorIndex].RemoveAllItems(akTransferTo = ThisWorkshop, abKeepOwnership = false)
      pWorkshopParent.RemoveActorFromWorkshopPUBLIC(WorkshopActors[iActorIndex] as WorkshopNPCScript)
      WorkshopActors[iActorIndex].RecycleActor()
      WorkshopActors[iActorIndex].Kill()
      iActorIndex += 1
    EndWhile
  EndIf
  iWorkshopIndex += 1
EndWhile 

EndFunction

"Disable" and "Delete" exchanged for "RecycleActor" and "Kill". The intent being to refresh inventory to basic and leave corpses scattered around the settlement.

 

Would these monkey edits work? And would companions be safe from this script?

 

Edit: Well, my tweaks definitely don't compile. The original script does, but not mine. Is there any way I could achieve that?

Edited by PAPVAFS11
Link to comment
Share on other sites

You are hitting some of the basic 101 building block issues of trying to transition from console commands to scripting without the fundamentals of the object model and inheritance. You can't call an Actor script function on an ObjectReference.

 

My advice on how to learn this is largely ignored for instant gratification: no matter what your trying to do, start with the Skyrim Bendu Olo quest tutorial and figure it out from there, because the quest system is the heart of the platform even if your not actually creating quests. That one nugget would have saved me many months of pain and thousands of lines of needlessly clever and elaborate script.

Link to comment
Share on other sites

I did say I was a walnut. The only genius I've ever claimed is in how hard I can break something.

 

I've passed by it a few times, but I'll be sure to give the tutorial a better look now. The Skyrim header had me squeamish before, but now I've got a better understanding that both games operate mostly the same.

Link to comment
Share on other sites

Since the workshop actors are filling an objectreference array, this means for any of the actor functions to work on the array elements, those elements have to be cast to actor. Example: (WorkshopActors[iActorIndex] as actor).Kill()

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...