Jump to content

Scripting advice


pepperman35

Recommended Posts

Okay, I have made a little script that does the following at a new settlement: 1) counts the number of work objects (food, defense, scavenger, vendors); 2) spawns in an equal amount of NPCs; 3) Unassigns all the NPCs (i.e., makes them unemployed); outfits the NPCs with a select outfit and gear; and final assigns the NPCS to the work object. A few checks needs to be added to the script, especially the assignment functionality; however, it will work. Upon testing the various function, I noticed something that I could not overcome or correct. Unassigning the NPCs will do just that but I noticed that the food value in workshop mode doesn’t go to zero like I expect with no one assigned to the food objects. Is there a way to overcome this?


;-- Properties --------------------------------------
Group BaseGame
	WorkshopParentScript Property WorkshopParent Auto Const Mandatory
	Quest Property pWorkshopParent Auto Const mandatory
	Keyword Property pWorkshopItemKeyword Auto Const Mandatory
	ActorValue Property Food Auto Const Mandatory
	ActorValue Property WorkshopRatingScavengeGeneral Auto Const Mandatory
	ActorValue Property Safety Auto Const Mandatory
	ActorValue Property vendorIncome Auto Const Mandatory
	ActorValue Property pWorkshopRatingPopulation Auto Const mandatory
	ActorValue Property pWorkshopGuardPreference Auto Const mandatory
	Weapon Property GaussRifle Auto Const Mandatory
	Ammo Property Ammo2mmEC Auto Const Mandatory
	MiscObject Property Caps001 Auto Const Mandatory
	Potion Property Stimpak Auto Const Mandatory
EndGroup

Group WorkshopActors
	ObjectReference[] Property ActorsAll auto hidden
EndGroup

Group NWCP2
	GlobalVariable Property pNWCP2_NPCSpawnState Auto Const Mandatory
	Message Property pNWCP2_NoWorkshopMsg Auto Const Mandatory
	Outfit Property NWCP2_CombatUniform01 Auto Const Mandatory
	ObjectReference Property NWCP2_TemporaryChest01 Auto Const Mandatory
EndGroup

;-- Variables ---------------------------------------
int WRFOAdj = 0
int TotalWRS = 0
;-- Functions ---------------------------------------


Function PotentialWorkObjects() 
;
; This function identifies the number of available work objects
; within the settlement
;
	If (pNWCP2_NPCSpawnState.GetValue() == 0 as float)
		WorkshopScript workshopRef = GetLinkedRef(pWorkshopItemKeyword) as WorkshopScript
		If (workshopRef == None)
			Debug.Trace("NWCP2:NPCRequisitionScript.PotentialWorkObjects" +" ERROR NoWorkshop", 0)
			pNWCP2_NoWorkshopMsg.Show(0, 0, 0, 0, 0, 0, 0, 0, 0)
		Else
			; Do lots of cool stuff here
			; Set the global so it can only be run once
			pNWCP2_NPCSpawnState.SetValue(1 as float)
			; Get all of the resources objects and then count the total amount
			ObjectReference[] PotentialFood = workshopRef.GetWorkshopResourceObjects(Food)
			Debug.Trace(self + "NWCP2: No of Workshop Resource Food Objects = " + PotentialFood.Length)
			; Each NPC can farm six food so adjust the value 
			WRFOAdj = PotentialFood.Length/6
			Debug.Trace(self + "NWCP2: Adj No of Workshop Resource Food Objects = " + WRFOAdj)
			ObjectReference[] PotentialScavenge = workshopRef.GetWorkshopResourceObjects(WorkshopRatingScavengeGeneral)
			Debug.Trace(self + "NWCP2: No of Workshop Resource Scavenge Objects = " + PotentialScavenge.Length)
			ObjectReference[] PotentialDefense = workshopRef.GetWorkshopResourceObjects(Safety)
			Debug.Trace(self + "NWCP2: No of Workshop Resource Defense Objects = " + PotentialDefense.Length)
			ObjectReference[] PotentialStores = workshopRef.GetWorkshopResourceObjects(VendorIncome)
			Debug.Trace(self + "NWCP2: Workshop Resource Vendor Objects = " + PotentialStores.Length)
			TotalWRS = WRFOAdj + PotentialScavenge.Length + PotentialDefense.Length + PotentialStores.Length
			Debug.Trace(self + "NWCP2: Total Number of Workshop Resource Objects = " + TotalWRS)
			; Call the function to requisition the required number of NPCs
			NPCRequisition(TotalWRS, workshopRef)
			; Call the function to unassign all the workers
			DischargeNPCs(workshopRef)
			; Call the funcrion to equip all of the NPCs with a select outfit and weapons
			EquipNPCs()
			; Call the function to assign NPCs to workshop resource objects
			EmployNPCs(PotentialStores, PotentialDefense, PotentialScavenge, PotentialFood)
		EndIf
	EndIf
EndFunction


Function NPCRequisition(int NPCMaxCount, WorkshopScript workshopRef)
;
; This function requisition the necessary NPC to fill the available work objects
;
	int iCountNPCIndex = 0
	While (iCountNPCIndex < NPCMaxCount)
		WorkshopParent.CreateActorPUBLIC(workshopRef)
		iCountNPCIndex += 1
		Debug.Notification("A settler has been recruited for the Command Post")
	EndWhile
EndFunction

Function DischargeNPCs(WorkshopScript workshopRef)
;
; This function dischages all the NPCs from their current jobs
;
	; Unassign all NPCs from their current jobs
	ActorsAll.Clear()
	ActorsAll = workshopRef.GetWorkshopResourceObjects(WorkshopParent.WorkshopRatingValues[2])
	int j = 0
	While j < ActorsAll.Length
		WorkshopNPCScript theNPC = ActorsAll[j] as WorkShopNPCScript
		theNPC.Enable(False)
		theNPC.SetValue(pWorkshopRatingPopulation, 1 as float)
		theNPC.SetValue(pWorkshopGuardPreference, 0 as float)
		(theNPC as workshopnpcscript).SetCommandable(True)
		(theNPC as workshopnpcscript).SetAllowCaravan(False)
		(theNPC as workshopnpcscript).SetAllowMove(False)
		WorkshopParent.UnassignActor(theNPC)
		;Debug.Trace(self + "AssignJob: Unassigning " + theNPC)
		j += 1
	EndWhile
EndFunction

Function EquipNPCs()
;
; This function equips all the NPCs with a select outfilt and weapons
;
	; Equip all of our NPCs with a select outfit and gear
	int i = 0
	Debug.Notification("The settlers are being equipped for service")
	while i < ActorsAll.Length
		WorkshopNPCScript theActor = ActorsAll[i] as WorkShopNPCScript
		; Remove all items from the NPC's inventory
		theActor.RemoveAllItems()
		; Add select items to the temporary container
		NWCP2_TemporaryChest01.AddItem(GaussRifle, 1, true)
		NWCP2_TemporaryChest01.AddItem(Ammo2mmEC, 5, true)
		NWCP2_TemporaryChest01.AddItem(Caps001, 100, true)
		NWCP2_TemporaryChest01.AddItem(Stimpak, 3, true)
		NWCP2_TemporaryChest01.RemoveAllItems(theActor, abKeepOwnership = false)
		theActor.EquipItem(GaussRifle, false, false)
		theActor.SetOutfit(NWCP2_CombatUniform01)
		i += 1
	EndWhile
EndFunction

Function EmployNPCs(ObjectReference[] PotentialStores, ObjectReference[] PotentialDefense, ObjectReference[] PotentialScavenge, ObjectReference[] PotentialFood)
;
; This function assigns the NPCs to available work objects
;
int ii = 0
int iii = 0
int jj = 0
int jjj = 0
int kk = 0
int kkk = 0
int mm = 0
int nn = 0
int WRS2 = PotentialStores.Length + PotentialDefense.Length
int WRS3 = WRS2 + PotentialScavenge.Length
; Assign NPCs to vendor stations
	While ii < PotentialStores.Length
		ObjectReference theActor = ActorsAll[ii]
		ObjectReference theVendor = PotentialStores[ii]
		;WorkshopScript.AssignActorToObjectPUBLIC(WorkshopNPCScript theActor, WorkshopObjectScript theVendor, false)
		(pWorkshopParent as workshopparentscript).AssignActorToObjectPUBLIC(theActor as workshopnpcscript, theVendor as workshopobjectscript, False)
		ii = ii + 1
	EndWhile
	Debug.Notification(PotentialStores.Length + " settlers have been assigned to vendor stores")
	jj = ii
	While jj < WRS2
		ObjectReference theActor = ActorsAll[jj]
		theActor.SetValue(pWorkshopGuardPreference, 1 as float)
		ObjectReference theDefender = PotentialDefense[iii]
		(pWorkshopParent as workshopparentscript).AssignActorToObjectPUBLIC(theActor as workshopnpcscript, theDefender as workshopobjectscript, False)
		jj = jj + 1
		iii = iii + 1
	EndWhile
	Debug.Notification(PotentialDefense.Length + " settlers have been assigned to guard stations")
	kk = jj
	While kk < WRS3
		ObjectReference theActor = ActorsAll[kk]
		(theActor as workshopnpcscript).SetScavenger(true)
		ObjectReference theScavengeSta = PotentialScavenge[jjj]
		(pWorkshopParent as workshopparentscript).AssignActorToObjectPUBLIC(theActor as workshopnpcscript, theScavengeSta as workshopobjectscript, False)
		kk = kk + 1
		jjj = jjj + 1
	EndWhile
	Debug.Notification(PotentialScavenge.Length + " settlers have been assigned to scavenger stations")
	mm = kk
	While mm < ActorsAll.Length
		ObjectReference theActor = ActorsAll[mm]
		ObjectReference thePlant = PotentialFood[kkk]
		(pWorkshopParent as workshopparentscript).AssignActorToObjectPUBLIC(theActor as workshopnpcscript, thePlant as workshopobjectscript, False)
		mm = mm + 1
		kkk = kkk + 6
		Debug.Notification(PotentialScavenge.Length/6 + " settlers have been assigned to farming")
	EndWhile
	ii = 0
	While ii < ActorsAll.Length
		ObjectReference theActor = ActorsAll[ii]
		(theActor as workshopnpcscript).EvaluatePackage()
		ii = ii + 1
	EndWhile
EndFunction
Link to comment
Share on other sites

It may be the script call to unassign actors does not trigger the stats to update or recalculate. Add something line this;

GlobalVariable Property pWorkshopCurrentWorkshopID Auto Const Mandatory

If (pWorkshopCurrentWorkshopID.GetValue() == (ThisWorkshop as WorkshopScript).GetWorkshopID()) && ((pWorkshopParent as WorkshopParentScript).IsEditLocked() == FALSE)
   (pWorkshopParent as WorkshopParentScript).ResetWorkshop(ThisWorkshop as WorkshopScript)
EndIf
Link to comment
Share on other sites

Ok SKK50, I shall give that a try. Much appreciated!

 

BTW, when you master programmer us the prefix p and the like in front of properties (e.g., pWorkshopCurrentWorkshopID and pWorkshopParent) could you explain what the prefix mean/do?

Edited by pepperman35
Link to comment
Share on other sites

The letter p reminds us it is an external property/pointer rather than a script variable. Its a standard in most of the (better quality) base game scripts.

 

pProperty

iInteger

fFloat

sString

& etc
Link to comment
Share on other sites

Great, the solves that mystery. BTW, your ResetWorkshop seemed to do the trip. First, test showed the values one would expect. I'll run it a few more times, and in a few more checks and declare victory. Updated code as it currently stands.

Scriptname NWCP2:NPCRequisitionScript extends ObjectReference

;-- Properties --------------------------------------
Group BaseGame
	WorkshopParentScript Property WorkshopParent Auto Const Mandatory
	Quest Property pWorkshopParent Auto Const mandatory
	Keyword Property pWorkshopItemKeyword Auto Const Mandatory
	ActorValue Property Food Auto Const Mandatory
	ActorValue Property WorkshopRatingScavengeGeneral Auto Const Mandatory
	ActorValue Property Safety Auto Const Mandatory
	ActorValue Property vendorIncome Auto Const Mandatory
	ActorValue Property pWorkshopRatingPopulation Auto Const mandatory
	ActorValue Property pWorkshopGuardPreference Auto Const mandatory
	Weapon Property GaussRifle Auto Const Mandatory
	Ammo Property Ammo2mmEC Auto Const Mandatory
	MiscObject Property Caps001 Auto Const Mandatory
	Potion Property Stimpak Auto Const Mandatory
	GlobalVariable Property pWorkshopCurrentWorkshopID Auto Const Mandatory
EndGroup

Group WorkshopActors
	ObjectReference[] Property ActorsAll auto hidden
EndGroup

Group NWCP2
	GlobalVariable Property pNWCP2_NPCSpawnState Auto Const Mandatory
	Message Property pNWCP2_NoWorkshopMsg Auto Const Mandatory
	Outfit Property NWCP2_CombatUniform01 Auto Const Mandatory
	ObjectReference Property NWCP2_TemporaryChest01 Auto Const Mandatory
EndGroup

;-- Variables ---------------------------------------
int WRFOAdj = 0
int TotalWRS = 0
int FoodCounter = 0
int ScavengeCounter = 0
int DefenderCounter = 0
int VendorCounter = 0
;-- Functions ---------------------------------------


Function PotentialWorkObjects() 
;
; This function identifies the number of available work objects
; within the settlement
;
	If (pNWCP2_NPCSpawnState.GetValue() == 0 as float)
		WorkshopScript workshopRef = GetLinkedRef(pWorkshopItemKeyword) as WorkshopScript
		If (workshopRef == None)
			Debug.Trace("NWCP2:NPCRequisitionScript.PotentialWorkObjects" +" ERROR NoWorkshop", 0)
			pNWCP2_NoWorkshopMsg.Show(0, 0, 0, 0, 0, 0, 0, 0, 0)
		Else
			; Set the global so the script can only run once
			pNWCP2_NPCSpawnState.SetValue(1 as float)
			;
			; Get all of the resources objects and then count the total amount
			;
			ObjectReference[] PotentialFood = workshopRef.GetWorkshopResourceObjects(Food)
			Debug.Trace(self + "NWCP2: No of Workshop Resource Food Objects = " + PotentialFood.Length)
			; Each NPC can farm six food so adjust the value 
			WRFOAdj = PotentialFood.Length/6
			Debug.Trace(self + "NWCP2: Adj No of Workshop Resource Food Objects = " + WRFOAdj)
			ObjectReference[] PotentialScavenge = workshopRef.GetWorkshopResourceObjects(WorkshopRatingScavengeGeneral)
			Debug.Trace(self + "NWCP2: No of Workshop Resource Scavenge Objects = " + PotentialScavenge.Length)
			ObjectReference[] PotentialDefense = workshopRef.GetWorkshopResourceObjects(Safety)
			Debug.Trace(self + "NWCP2: No of Workshop Resource Defense Objects = " + PotentialDefense.Length)
			ObjectReference[] PotentialStores = workshopRef.GetWorkshopResourceObjects(VendorIncome)
			Debug.Trace(self + "NWCP2: Workshop Resource Vendor Objects = " + PotentialStores.Length)
			TotalWRS = WRFOAdj + PotentialScavenge.Length + PotentialDefense.Length + PotentialStores.Length
			Debug.Trace(self + "NWCP2: Total Number of Workshop Resource Objects = " + TotalWRS)
			;
			; Call the function to requisition the required number of NPCs
			;
			NPCRequisition(TotalWRS, workshopRef)
			;
			; Call the function to unassign all the workers
			;
			DischargeNPCs(workshopRef)
			;
			; Call the funcrion to equip all of the NPCs with a select outfit and weapons
			EquipNPCs()
			;
			; Call the function to assign NPCs to workshop resource objects
			;
			EmployNPCs(PotentialStores, PotentialDefense, PotentialScavenge, PotentialFood)
		EndIf
	EndIf
EndFunction


Function NPCRequisition(int NPCMaxCount, WorkshopScript workshopRef)
;
; This function requisition the necessary NPC to fill the available work objects
;
	int iCountNPCIndex = 0
	While (iCountNPCIndex < NPCMaxCount)
		Debug.Notification("Onboarding in-progress ... please wait")
		WorkshopParent.CreateActorPUBLIC(workshopRef)
		iCountNPCIndex += 1
		Utility.Wait(1.0)
		Debug.Notification("A settler has been successfully recruited")
	EndWhile
EndFunction

Function DischargeNPCs(WorkshopScript workshopRef)
;
; This function dischages all the NPCs from their current jobs
;
	; Unassign all NPCs from their current jobs
	ActorsAll.Clear()
	ActorsAll = workshopRef.GetWorkshopResourceObjects(WorkshopParent.WorkshopRatingValues[2])
	int j = 0
	While j < ActorsAll.Length
		WorkshopNPCScript theNPC = ActorsAll[j] as WorkShopNPCScript
		theNPC.Enable(False)
		theNPC.SetValue(pWorkshopRatingPopulation, 1 as float)
		theNPC.SetValue(pWorkshopGuardPreference, 0 as float)
		(theNPC as workshopnpcscript).SetCommandable(True)
		(theNPC as workshopnpcscript).SetAllowCaravan(False)
		(theNPC as workshopnpcscript).SetAllowMove(False)
		WorkshopParent.UnassignActor(theNPC)
		;Debug.Trace(self + "AssignJob: Unassigning " + theNPC)
		j += 1
	EndWhile
	If (pWorkshopCurrentWorkshopID.GetValue() == (workshopRef as WorkshopScript).GetWorkshopID()) && ((pWorkshopParent as WorkshopParentScript).IsEditLocked() == FALSE)
		(pWorkshopParent as WorkshopParentScript).ResetWorkshop(workshopRef as WorkshopScript)
	EndIf
EndFunction

Function EquipNPCs()
;
; This function equips all the NPCs with a select outfilt and weapons
;
	; Equip all of our NPCs with a select outfit and gear
	int i = 0
	while i < ActorsAll.Length
		WorkshopNPCScript theActor = ActorsAll[i] as WorkShopNPCScript
		; Remove all items from the NPC's inventory
		theActor.RemoveAllItems()
		; Add select items to the temporary container
		NWCP2_TemporaryChest01.AddItem(GaussRifle, 1, true)
		NWCP2_TemporaryChest01.AddItem(Ammo2mmEC, 5, true)
		NWCP2_TemporaryChest01.AddItem(Caps001, 100, true)
		NWCP2_TemporaryChest01.AddItem(Stimpak, 3, true)
		NWCP2_TemporaryChest01.RemoveAllItems(theActor, abKeepOwnership = false)
		theActor.EquipItem(GaussRifle, false, false)
		theActor.SetOutfit(NWCP2_CombatUniform01)
		i += 1
	EndWhile
	Debug.Notification("All of the settlers have beed equipped for service")
EndFunction

Function EmployNPCs(ObjectReference[] PotentialStores, ObjectReference[] PotentialDefense, ObjectReference[] PotentialScavenge, ObjectReference[] PotentialFood)
;
; This function assigns the NPCs to available work objects
;
int ii = 0
int iii = 0
int jj = 0
int jjj = 0
int kk = 0
int kkk = 0
int mm = 0
int nn = 0
int WRS2 = PotentialStores.Length + PotentialDefense.Length
int WRS3 = WRS2 + PotentialScavenge.Length
; Assign NPCs to vendor stations
	While ii < PotentialStores.Length
		ObjectReference theActor = ActorsAll[ii]
		ObjectReference theVendor = PotentialStores[ii]
		;WorkshopScript.AssignActorToObjectPUBLIC(WorkshopNPCScript theActor, WorkshopObjectScript theVendor, false)
		(pWorkshopParent as workshopparentscript).AssignActorToObjectPUBLIC(theActor as workshopnpcscript, theVendor as workshopobjectscript, False)
		ii = ii + 1
		VendorCounter = VendorCounter + 1
	EndWhile
	Debug.Notification(VendorCounter + " of the settlers have been assigned to vendor stores")
	jj = ii
	While jj < WRS2
		ObjectReference theActor = ActorsAll[jj]
		theActor.SetValue(pWorkshopGuardPreference, 1 as float)
		ObjectReference theDefender = PotentialDefense[iii]
		(pWorkshopParent as workshopparentscript).AssignActorToObjectPUBLIC(theActor as workshopnpcscript, theDefender as workshopobjectscript, False)
		jj = jj + 1
		iii = iii + 1
		DefenderCounter = DefenderCounter + 1
		Utility.Wait(1.0)
	EndWhile
	Debug.Notification(DefenderCounter + " of the settlers have been assigned to guard stations")
	kk = jj
	While kk < WRS3
		ObjectReference theActor = ActorsAll[kk]
		(theActor as workshopnpcscript).SetScavenger(true)
		ObjectReference theScavengeSta = PotentialScavenge[jjj]
		(pWorkshopParent as workshopparentscript).AssignActorToObjectPUBLIC(theActor as workshopnpcscript, theScavengeSta as workshopobjectscript, False)
		kk = kk + 1
		jjj = jjj + 1
		ScavengeCounter = ScavengeCounter + 1
		Utility.Wait(1.0)
	EndWhile
	Debug.Notification(ScavengeCounter + " of the settlers have been assigned to scavenging")
	mm = kk
	While mm < ActorsAll.Length
		ObjectReference theActor = ActorsAll[mm]
		ObjectReference thePlant = PotentialFood[kkk]
		(pWorkshopParent as workshopparentscript).AssignActorToObjectPUBLIC(theActor as workshopnpcscript, thePlant as workshopobjectscript, False)
		mm = mm + 1
		kkk = kkk + 6
		If kkk >= PotentialFood.Length
			kkk = PotentialFood.Length - 1
		EndIf
		FoodCounter = FoodCounter + 1
	EndWhile
	Debug.Notification(FoodCounter + " of the settlers have been assigned to farming")
	;
	; Evaluate packages on the NPCs
	;
	ii = 0
	While ii < ActorsAll.Length
		ObjectReference theActor = ActorsAll[ii]
		(theActor as workshopnpcscript).EvaluatePackage()
		ii = ii + 1
	EndWhile
EndFunction
Edited by pepperman35
Link to comment
Share on other sites

  • Recently Browsing   0 members

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