Jump to content

[FO4 CK] General Help Thread


Recommended Posts

Ok starting to dangle my toes into scripting for FO4, I've done a fair bit of Scripting on FONV but none in Skyrim soo pretty newb at a lot of stuff.

This is my first script attempt theres probably all sorts of issues I hope others can pick up on before I even try and compile it.

 

I'm assuming I just drop it in the data/scripts folder and then do some mumbo jumbo in my esp to link it to my esp?

 

Scriptname SoSAddGITSSuits
; This script checks to see if GITSSuits is installed and if so makes them the default outfit
; for actors in the SoSGITSSuitWearers formlist

int iCnt
ref rListREF
ref rActorREF
ref rScriptName = SoSAddGITSSuits

Event OnPlayerLoadGame()

	bool bModInstalled = Game.IsPluginInstalled("GITSSuits.esp")
	if bModInstalled
		Form fNewOutfit = Game.GetFormFromFile("GITSSuits.esp", 0x00015A4F)
		Form fNewSleepUnderwear = Game.GetFormFromFile("GITSSuits.esp", 0x00015A50) 
		Set rListREF to SoSGITSSuitWearers
		Set iCnt to ListGetCount rListREF
		while iCnt > 0
			Debug.Trace(rScriptName + ": Actor: " + (string)iCnt + ": " + rActorRef)
			Set rActorREF to ListGetNthForm rListREF iCnt
			rActorREF.SetOutfit(fNewOutfit); Set Regular Outfit
			rActorREF.SetOutfit(fNewSleepUnderwear, true); Set Sleep Outfit
			iCnt -= 1
		endWhile
	endIf

	Debug.Trace(rScriptName + ": My script finished")
endEvent
Link to comment

There's many places you can use scripts; so far as I know, the easiest way to do what you're trying to do is to make a quest and add a script to it.  (Even if all your quest does is this.  Still, it's a logical place to add more functionality later.)  The CK has a script editor in it.  The first line would have "extends Script" after it but this will be set up by the CK for you.

 

To refer to resources, you don't use GetFormFromFile, you use properties.  The CK has an interface to create these for you and set their initial value.  in the script you will have definitions like

 

Form Property theItem Auto Const

 

The reference to the actual item shouldn't be in the script.  (Imagine the extra work if you change the name of the esp, or you add another mod.)  Instead, use the CK to point to the particular item.

 

Also, you don't have to check if your mod is installed, since if it's not, its scripts won't be executed. :)

 

I can't predict what other errors might be here, but you have one endif too many. :)

Link to comment

I should clarify the purpose better, I am creating a Faction overhaul and one of the things I'm doing is changing all their outfits, so if the user of my mod also has GITSuit.esp installed I am adding the GITSSuit to all the actors in a list.

Ah and fixed the endIf

I didn't realise there was an editor in the CK like GECK had in FNV, I'll have a look at it.

Link to comment

Can anyone figure out why I can't dismember the player?  This is to make the slave collar work.

 

I have code like this:

 

Actor p = Game.GetPlayer()

p.Dismember("Head1", true, true)

p.Kill()

 

The dismember does nothing.  (The  kill works.)

 

However, if I call it on an NPC, it works fine.

 

Here is the code that I use for explosive collars on runaway slaves in F4SS. There is some additional code that you wouldn't need, since in my case the function triggers if the slave is running away and reaches a certain distance from the player - then the function first checks whether the slave has a collar and only if he does it will detonate it. Also it checks if the actor in question is one of the players slaves in the first place, just to make sure it doesn't fire on someone that isn't a slave.

 

Explosion Property explosionSmall Auto

is the property for explosionSmall, I'm using small electrical explosion for the FX.

 

Keyword Property kwExplosiveCollar Auto

is a keyword that I add on all gear that should allow detonating.

 

Tested and works on NPCs. Untested on player.

; Attempts to detonate a slave collar on the specified actor. Returns true on success
bool function explodeCollar(Actor akActor)
	Actor _slave = AkActor
	F4SSscrSlotAlias _slotscript = F4SSfunctions.GetSlotScript(_slave)
	
	if _slotscript
		if _slave.WornHasKeyword(kwExplosiveCollar)
			_slave.UnequipItem(_slotscript.gearCollar)
			_slave.RemoveItem(_slotscript.gearCollar, 1)
			_slave.Dismember("Head1", true)
			_slave.PlaceAtMe(explosionSmall, 1)
			_slave.Kill(Game.GetPlayer())
		endif
	endif
endFunction

Edit: the description lies. It does not return true on success. I will change that in my script immediately.

 

Edit: My slowness strikes again. I just realized that you're specifically looking for a script that works on player. 

Have you tried using Game.ForceThirdPerson() in conjunction with checking against Is3DLoaded before exploding the collar?

Link to comment

Random Question No 2:

Is Sleeping Outfit something NPC's swap to when sleeping and if so does it work in FO4, as far as I can see so far poking with it, the answer seems to be no?

 

It is a legacy from the old game engine.

Already in Skyrim this option was not used by the game.

Link to comment

 

Random Question No 2:

Is Sleeping Outfit something NPC's swap to when sleeping and if so does it work in FO4, as far as I can see so far poking with it, the answer seems to be no?

 

It is a legacy from the old game engine.

Already in Skyrim this option was not used by the game.

 

Ah cool thanks, I suppose maybe we could use it as a variable for a scripted undressing mod :)

Hmm or

 

Maybe just a spell like

 

If Package == sleeping on rising edge equip SleepingOutfit

Link to comment

 

 

Random Question No 2:

Is Sleeping Outfit something NPC's swap to when sleeping and if so does it work in FO4, as far as I can see so far poking with it, the answer seems to be no?

 

It is a legacy from the old game engine.

Already in Skyrim this option was not used by the game.

 

Ah cool thanks, I suppose maybe we could use it as a variable for a scripted undressing mod :)

Hmm or

 

Maybe just a spell like

 

If Package == sleeping on rising edge equip SleepingOutfit

 

 

I don't think so.

First, it cannot be set using scripting.

Second, this game engine (like Skyrim, as usual) has the Quest VM Conditional Variables that are way more powerful to control stuff.

Link to comment

Anyone know how the game works out what scrapping Armor and Weapons gives you?

Only Vanilla stuff gives me scrap so far.

Mines are a weapon, but I can't scrap them either.

 

I'm also looking for a function like FONV had GetRadsLevel which told you how many rads the Actor was currently receiving. I found GetRadMultiplier and GetRads Maybe have to do it by script?

 

Also apparently someone called Grant messed up the RadMist at some point in Far Harbour :)

 

<WEATHER> DLC03_RadMistWeatherBeforeGrantMessedItUp

Link to comment

Trying to get a script working here, the documentation for noobs is awful even in the Skyrim pages.

 

I'm looking for the CK equivalent of this GECK page:

 

http://geck.bethsoft...egory:Functions

 

Just a nice simple easy to read list of functions with links to more detail :tongue:

 

I found this but there's no logical order to the way the functions are listed, Alphabetically would be nice and more functions per page

 

http://mod.gib.me/sk.../functions.html

 

The script is designed to heal the objects wearer if they aren't suffering from radiation exposure and they are clean of rads (I'm probably just going to have to work on exposure for NPCs wearing the ring)

Scriptname SuperPowerScript extends ObjectReference Const
{My first script}

Int Property SuperProperty = 0 Auto Const
{Hmm not sure what this is}

Event OnLoad()

		float fPowerLevel
		form akActor= GetOwner(GetSelf) ; this is probably wrong
		float fActorRads = akActor.GetActorValue Rads
		float fActorHealth = akActor.GetActorValue Health

		if (fActorRads <= 0)
			if (fActorHealth < 100) ; Assuming 100% = 100)
				fActorHealth = fActorHealth + 1
				akActor.SetValue Health fActorHealth
				DefaultScriptFunctions.DefaultScriptTrace(self + ":Healing")
			endif 
		endif
	
EndEvent
Compiler Output is this:

Starting 1 compile threads for 1 files...

Compiling "SuperPowerScript"...

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(11,43): no viable alternative at input 'Rads'

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(12,45): no viable alternative at input 'Health'

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(17,21): no viable alternative at input 'Health'

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(17,21): function variable fActorHealth may not shadow a previously defined variable

No output generated for SuperPowerScript, compilation failed.

 

Batch compile of 1 files finished. 0 succeeded, 1 failed.

Failed on SuperPowerScript

As far as I can workout from in GECK Rads and Health are the valid variables
Link to comment

...

 

 

Try this:

 

Scriptname SuperPowerScript extends ObjectReference Const
 
Event OnInit()
; "Be aware that this is run only when the script is loaded for the very first time."
 
float fPowerLevel
form akActor= Self as Actor
float fActorRads = akActor.GetActorValue("Rads")
float fActorHealth = akActor.GetActorValue("Health")
 
if fActorRads <= 0
  if fActorHealth < 100
    fActorHealth += 1
    akActor.SetActorValue("Health", fActorHealth)
    Debug.trace(akActor.getDisplayName() + ":Healing")
  endif 
endif
EndEvent

 

Now, the event will run only once. At the very first time it is loaded.

If you want a constant effect you may want to use the script to a magic effect, and assign the effect to an actor using a spell (yep, exactly like Skyrim)

And maybe use an Update event to increase the health every num seconds.

 

The best way to find the functions is to open the basic scripts that have the same name of the main objects (like Actor.psc, ObectReference.psc, etc.)

All the functions inside will, of course, apply to the given class and its sub-classes.

 

Keep in mind that everything is a function in Papyrus. So you need parentheses everywhere.

 

Last word: also if my Papyrus Guide is for Skyrim, it works about 90% also for FO4.

Link to comment

 

...

 

Try this:

 

Now, the event will run only once. At the very first time it is loaded.

If you want a constant effect you may want to use the script to a magic effect, and assign the effect to an actor using a spell (yep, exactly like Skyrim)

And maybe use an Update event to increase the health every num seconds.

 

The best way to find the functions is to open the basic scripts that have the same name of the main objects (like Actor.psc, ObectReference.psc, etc.)

All the functions inside will, of course, apply to the given class and its sub-classes.

 

Keep in mind that everything is a function in Papyrus. So you need parentheses everywhere.

 

Last word: also if my Papyrus Guide is for Skyrim, it works about 90% also for FO4.

 

Hmm sorry I've had signatures turned off due to how insanely large some peoples signature pictures were and they don't seem to turn back on yet. Can you please post the link here.

 

I'm intending this to just work when they are wearing a ring, if I get what you are saying I need to have an ObjectEffect on the ring cast a Scripted Spell on the actor wearing it rather than just put the scripted spell in the ObjectEffect, sorry I've never scripted in Skyrim or I would have half an idea what I was doing GECK NV is a fair bit different to this, Most of my experience is in C64 BASIC, LSL, GECK & PLC/SCADA :)

 

I've now got this but screwed something up with registering of the update Event as I copied from the wiki:

http://www.creationkit.com/index.php?title=OnUpdate_-_Form

Scriptname SuperPowerScript extends ObjectReference Const
{My first script}

Int Property SuperProperty = 0 Auto Const
{Hmm not sure what this is}

Function SomeFunction()                
	RegisterForUpdate(1.0) ; Before we can use OnUpdate() we must register.
EndFunction
	
Event OnUpdate() ; This event occurs every five seconds	

		float fPowerLevel
		actor akActor = Self as Actor
		float fActorRads = akActor.GetActorValue ("Rads")
		float fActorHealth = akActor.GetActorValue ("Health")
		int iCurrRads = fActorRads
		int iPrevRads
		iRadDamage = iPrevRads - iCurrRads
		
		if (fActorRads <= 0)
			if (fActorHealth < 100) ; Assuming 100% = 100)
				fActorHealth = fActorHealth + 1
				akActor.SetValue ("Health", fActorHealth)
				DefaultScriptFunctions.DefaultScriptTrace(self + ":Healing")
			endif 
		else
			if (iRadDamage < 1)
				fActorRads = fActorRads - 1
				akActor.SetValue ("Rads", fActorRads)
			endif
		endif
		iPrevRads = iCurrRads
	
EndEvent
And is update in RealWorldSeconds or GameSeconds?
Link to comment

 

I'm intending this to just work when they are wearing a ring, if I get what you are saying I need to have an ObjectEffect on the ring cast a Scripted Spell on the actor wearing it rather than just put the scripted spell in the ObjectEffect, sorry I've never scripted in Skyrim or I would have half an idea what I was doing GECK NV is a fair bit different to this, Most of my experience is in C64 BASIC, LSL, GECK & PLC/SCADA :)

 

I've now got this but screwed something up with registering of the update Event as I copied from the wiki:

http://www.creationkit.com/index.php?title=OnUpdate_-_Form

...
And is update in RealWorldSeconds or GameSeconds?

 

 

 

Here is the link: Papyrus for Skyrim guide.

 

About the OnUpdate. NEVER use RegisterForUpdates. Use RegisterForSingleUpdate and then re-register if you need.

The time is real time in seconds. Fractional values are valid (0.05 is still a good value with a real good approximation, lover values usually do not respect the time specified.)

 

Here my previous script with the OnUpdate.

 

 

Scriptname SuperPowerScript extends ObjectReference Const
 
Event OnInit()
  RegisterForSingleUpdate(1.0)
EndEvent
 
Event OnUpdate()
 
float fPowerLevel
form akActor= Self as Actor
float fActorRads = akActor.GetActorValue("Rads")
float fActorHealth = akActor.GetActorValue("Health")
 
if fActorRads <= 0
  if fActorHealth < 100
    fActorHealth += 1
    akActor.SetActorValue("Health", fActorHealth)
    Debug.trace(akActor.getDisplayName() + ":Healing") ; "WARNING!!! <--- This will be written every second in the papyrus. Use only for debug."
  endif 
endif
RegisterForSingleUpdate(1.0) ; "Re-call in a second." 
EndEvent
 

 

Now, if I understand correctly you want this to happen on an object you wear. Any type of Armor will work.

In this case you may need a slightly different script, that catches the event "OnEquip" and "OnUnequip", to start the healing cycle and then stop it.

Link to comment

Anyone know how the game works out what scrapping Armor and Weapons gives you?

Only Vanilla stuff gives me scrap so far.

Mines are a weapon, but I can't scrap them either.

 

 

Having a root around in the ck, it looks like its all done with FLST, and you would need to add your weapons/armour to the lists that provide that material when scrapped;

 

Eg, if you want it to provide steel then for example it the weapon would need to be added to the modScrapRecipe_NullMelee_Steel form list, and it would need to be done for each material you get when scapping that item, and also for each weapon/armour item that can be scrapped.

 

This is just a guess from looking at the vanilla stuff and seeing what it generates when scapped, I can not test this as the damn ck will not save, view sure but save no.

 

Looking at mines/grenades, none of them seem to be scrappable in vanilla game, though you could go through them and add them to the appropriate scrap formlists.

Link to comment

Having a root around in the ck, it looks like its all done with FLST, and you would need to add your weapons/armour to the lists that provide that material when scrapped;

Cool, I'll poke around with that :)

 

Back to my HealingRing script, its a script attached to a copy of the wedding ring that just slowly heals the actor if they aren't suffering radiation poisoning

 

So far I have this and it seems const in wrong type of scrip, so is native or I'm doing it all wrong with use of OnEquip and also not sure I'm setting akActor to be the wearer of the ring properly

 

Scriptname SuperPowerScript extends ObjectReference const
{My first script}

bool bItemWorn ; it doesn't seem to like this, how am I to tell my main part to keep running or am I wrong in assuming OnEquip is an edge trigger?

Event OnEquip()
		bItemWorn = 1
EndEvent

Event OnLoad() 
		float fPowerLevel
		if (bItemWorn)
			actor akActor = GetActorOwner() ; I'm trying to set the owner here, probably doing it wrong
			float fActorRads = akActor.GetActorValue ("Rads")
			float fActorHealth = akActor.GetActorValue ("Health")
			int iCurrRads = fActorRads
			int iPrevRads
			iRadDamage = iPrevRads - iCurrRads
		
			if (fActorRads <= 0)
				if (fActorHealth < 100) ; Assuming 100% = 100)
					fActorHealth = fActorHealth + 1
					akActor.SetValue ("Health", fActorHealth)
					DefaultScriptFunctions.DefaultScriptTrace(self + ":Healing")
				endif
			else
				if (iRadDamage < 1)
					fActorRads = fActorRads - 1
					akActor.SetValue ("Rads", fActorRads)
				endif
			endif
			iPrevRads = iCurrRads
		endif
EndEvent

Event OnUnequip()
	bItemWorn = 0
EndEvent
Compiler errors

Papyrus Compiler Version 2.8.0.4 for Fallout 4

Copyright © ZeniMax Media. All rights reserved.

Starting 1 compile threads for 1 files...

Compiling "SuperPowerScript"...

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(4,0): const scripts may not contain data, script variable bItemWorn cannot be defined

No output generated for SuperPowerScript, compilation failed.

 

Batch compile of 1 files finished. 0 succeeded, 1 failed.

Link to comment

Ok, I'm trying this then, but it doesn't like it still, am I wrong in assuming I need to set a bool to make my main bit run continuously while the ring is equipped, I'm assuming OnEquip is a one shot edge trigger?

Scriptname SuperPowerScript extends ObjectReference const

bool bItemWorn ; it doesn't seem to like this, how am I to tell my main part to keep running or am I wrong in assuming OnEquip is an edge trigger?

Event OnEquip()
		bItemWorn = 1
EndEvent

if (bItemWorn)
		float fPowerLevel
		actor akActor = GetActorOwner() ; I'm trying to set the owner here, probably doing it wrong
		float fActorRads = akActor.GetActorValue ("Rads")
		float fActorHealth = akActor.GetActorValue ("Health")
		int iCurrRads = fActorRads
		int iPrevRads
		iRadDamage = iPrevRads - iCurrRads
	
		if (fActorRads <= 0)
			if (fActorHealth < 100) ; Assuming 100% = 100)
				fActorHealth = fActorHealth + 1
				akActor.SetValue ("Health", fActorHealth)
				DefaultScriptFunctions.DefaultScriptTrace(self + ":Healing")
			endif
		else
			if (iRadDamage < 1)
				fActorRads = fActorRads - 1
				akActor.SetValue ("Rads", fActorRads)
			endif
		endif
		iPrevRads = iCurrRads
endif

Papyrus Compiler Version 2.8.0.4 for Fallout 4

Copyright © ZeniMax Media. All rights reserved.

Starting 1 compile threads for 1 files...

Compiling "SuperPowerScript"...

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(3,0): const scripts may not contain data, script variable bItemWorn cannot be defined

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(9,0): missing EndOfFile at 'if'

No output generated for SuperPowerScript, compilation failed.

Sorry for all the noob questions, once I get how this Papyrus stuff works hopefully I be less annoying :)
Link to comment

What about:

 

Scriptname SuperPowerScript extends ObjectReference const

 

Now your script will not compile anymore, because you cannot call functions or do code, outside a function.

 

 

Link to comment

Scriptname SuperPowerScript extends ObjectReference native

Event OnEquip()
		bool bItemWorn ; it doesn't seem to like this, how am I to tell my main part to keep running or am I wrong in assuming OnEquip is an edge trigger?
		bItemWorn = 1
EndEvent

Function MainPart ()
		bool bItemWorn ; it doesn't seem to like this, how am I to tell my main part to keep running or am I wrong in assuming OnEquip is an edge trigger?
		if (bItemWorn)
		float fPowerLevel
		actor akActor = GetActorOwner() ; I'm trying to set the owner here, I'm doing it wrong
		float fActorRads = akActor.GetActorValue ("Rads")
		float fActorHealth = akActor.GetActorValue ("Health")
		int iCurrRads = fActorRads
		int iPrevRads
		iRadDamage = iPrevRads - iCurrRads
	
		if (fActorRads <= 0)
			if (fActorHealth < 100) ; Assuming 100% = 100)
				fActorHealth = fActorHealth + 1
				akActor.SetValue ("Health", fActorHealth)
				DefaultScriptFunctions.DefaultScriptTrace(self + ":Healing")
			endif
		else
			if (iRadDamage < 1)
				fActorRads = fActorRads - 1
				akActor.SetValue ("Rads", fActorRads)
			endif
		endif
		iPrevRads = iCurrRads
	endif
EndFunction

Event OnUnequip()
		bool bItemWorn ; it doesn't seem to like this, how am I to tell my main part to keep running or am I wrong in assuming OnEquip is an edge trigger?
		bItemWorn = 0
EndEvent

Papyrus Compiler Version 2.8.0.4 for Fallout 4

Copyright © ZeniMax Media. All rights reserved.

Starting 1 compile threads for 1 files...

Compiling "SuperPowerScript"...

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(12,8): type mismatch while assigning to a actor (cast missing or types unrelated)

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(13,29): GetActorValue is not a function or does not exist

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(13,8): type mismatch while assigning to a float (cast missing or types unrelated)

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(14,31): GetActorValue is not a function or does not exist

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(14,8): type mismatch while assigning to a float (cast missing or types unrelated)

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(15,6): type mismatch while assigning to a int (cast missing or types unrelated)

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(17,2): variable iRadDamage is undefined

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(17,2): type mismatch while assigning to a none (cast missing or types unrelated)

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(22,22): type mismatch on parameter 1 - cannot pass a string to a actorvalue

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(23,27): argument showtrace is not specified and has no default value

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(26,7): variable iRadDamage is undefined

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(26,18): cannot compare a none to a int (cast missing or types unrelated)

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(26,18): cannot relatively compare variables to None

C:\Users\Owner\AppData\Local\Temp\PapyrusTemp\SuperPowerScript.psc(28,22): type mismatch on parameter 1 - cannot pass a string to a actorvalue

No output generated for SuperPowerScript, compilation failed.

 

Batch compile of 1 files finished. 0 succeeded, 1 failed.

Failed on SuperPowerScript

Link to comment

Any ideas if you can use lists in recipes to achieve an "OR" type situation?

I'd like to have it be something like "1 Steel" OR "Bonesaw" for example in a recipe and I'm wondering if you can throw lists or would it treat everything in the list as an and?

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. For more information, see our Privacy Policy & Terms of Use