Jump to content

Recommended Posts

Posted (edited)

So I have a small problem in my script. Essentially what it does is check for a food item if it has a certain keyword plus another misc item and then it gives output, but when I compile it through CK, I get a rule func0. Here's my script.

ScriptName rep_Rationkey Extends Quest

MiscObject Property rep_tinkey Auto
Keyword Property rep_canration Auto
ActorValue property HealthAV

Event OnItemEquipped(Form akBaseObject, ObjectReference akReference)
  if akBaseObject as Potion
      if(akBaseObject.HasKeyword(rep_canration) && Game.GetPlayer().GetItemCount(rep_tinkey) == 1)
        Game.GetPlayer().RemoveItem(rep_tinkey)
        Debug.Notification("Your tin key broke! You cannot open another canned ration without hurting yourself.")
      ElseIf(akBaseObject.HasKeyword(rep_canration) && Game.GetPlayer().GetItemCount(rep_tinkey) == 0)
        Game.GetPlayer().DamageValue(HealthAV, 10)
        Debug.Notification("Ouch. You should try to find a tin key to not hurt yourself.")
      Else
      endif
  else
  endif
EndEvent
Edited by RowanSkie
Posted

if akBaseObject as Potion > if (akBaseObject IS Potion)

 

Also to allow for unbounded item counts you may want:

 

GetItemCount(rep_tinkey) == 1) > GetItemCount(rep_tinkey) > 0)

 

Lastly consider using OnEquipped and attach the script to the rep_canration object form rather than actor/OnItemEquipped/quest combo as it saves the hassle of quest aliases or remote event registrations.

Posted
  On 11/16/2019 at 10:28 AM, SKK50 said:

if akBaseObject as Potion > if (akBaseObject IS Potion)

 

Also to allow for unbounded item counts you may want:

 

GetItemCount(rep_tinkey) == 1) > GetItemCount(rep_tinkey) > 0)

 

Lastly consider using OnEquipped and attach the script to the rep_canration object form rather than actor/OnItemEquipped/quest combo as it saves the hassle of quest aliases or remote event registrations.

the rep_canration is a keyword, will it still work?

Posted

You cannot attach a script to a Keyword but the advice of SKK50 is otherwise solid.

 

I looked at what your script does and rewrote it how I would have. There are some optimizations, and in my opinion, more readable code.

ScriptName rep_Rationkey Extends Quest

Actor Player

Group Properties
	MiscObject Property rep_tinkey Auto Const Mandatory
	Keyword Property rep_canration Auto Const Mandatory
	ActorValue property HealthAV Auto Const Mandatory
EndGroup

Event OnQuestInit()
	Player = Game.GetPlayer()
	RegisterForRemoteEvent(Player, "OnItemEquipped")
EndEvent

Event Actor.OnItemEquipped(Actor sender, Form baseObject, ObjectReference reference)
	If (baseObject is Potion)
		If (baseObject.HasKeyword(rep_canration))
			int count = Player.GetItemCount(rep_tinkey)
			If (count == 1)
				Player.RemoveItem(rep_tinkey)
				Debug.Notification("Your tin key broke! You cannot open another canned ration without hurting yourself.")
			ElseIf (count == 0)
				Player.DamageValue(HealthAV, 10)
				Debug.Notification("Ouch. You should try to find a tin key to not hurt yourself.")
			Else
				Debug.TraceSelf(self, "Actor.OnItemEquipped", "The equipped item count of "+count+" is unhandled.")
			EndIf
		Else
			Debug.TraceSelf(self, "Actor.OnItemEquipped", "The equipped item does not have the `rep_canration` keyword.")
		EndIf
	Else
		Debug.TraceSelf(self, "Actor.OnItemEquipped", "The equipped item is NOT of the Potion type.")
	EndIf
EndEvent
Edit: Remote events are not a hassle. Well, I was not hassled by the extra line of code in this sample.
Posted

If multiple potions have the rep_canration keyword then add the script to each of the base forms.

 

Then you dont even need that keyword, as the script will only ever fire on those objects anyway.

ScriptName rep_Rationkey Extends ObjectReference

MiscObject Property rep_tinkey Auto Const Mandatory
ActorValue property HealthAV Auto Const Mandatory

Event OnEquipped(Actor akActor)

if (akActor.GetItemCount(rep_tinkey) == 1 )
        akActor.RemoveItem(rep_tinkey)
        Debug.Notification("Your tin key broke! You cannot open another canned ration without hurting yourself.")
ElseIf (akActor.GetItemCount(rep_tinkey) == 0)
       akActor.DamageValue(HealthAV, 10)
        Debug.Notification("Ouch. You should try to find a tin key to not hurt yourself.")
Endif
EndEvent
Posted (edited)
  On 11/16/2019 at 10:49 AM, scrivener07 said:

You cannot attach a script to a Keyword but the advice of SKK50 is otherwise solid.

 

I looked at what your script does and rewrote it how I would have. There are some optimizations, and in my opinion, more readable code.

ScriptName rep_Rationkey Extends Quest

Actor Player

Group Properties
	MiscObject Property rep_tinkey Auto Const Mandatory
	Keyword Property rep_canration Auto Const Mandatory
	ActorValue property HealthAV Auto Const Mandatory
EndGroup

Event OnQuestInit()
	Player = Game.GetPlayer()
	RegisterForRemoteEvent(Player, "OnItemEquipped")
EndEvent

Event Actor.OnItemEquipped(Actor sender, Form baseObject, ObjectReference reference)
	If (baseObject is Potion)
		If (baseObject.HasKeyword(rep_canration))
			int count = Player.GetItemCount(rep_tinkey)
			If (count == 1)
				Player.RemoveItem(rep_tinkey)
				Debug.Notification("Your tin key broke! You cannot open another canned ration without hurting yourself.")
			ElseIf (count == 0)
				Player.DamageValue(HealthAV, 10)
				Debug.Notification("Ouch. You should try to find a tin key to not hurt yourself.")
			Else
				Debug.TraceSelf(self, "Actor.OnItemEquipped", "The equipped item count of "+count+" is unhandled.")
			EndIf
		Else
			Debug.TraceSelf(self, "Actor.OnItemEquipped", "The equipped item does not have the `rep_canration` keyword.")
		EndIf
	Else
		Debug.TraceSelf(self, "Actor.OnItemEquipped", "The equipped item is NOT of the Potion type.")
	EndIf
EndEvent
Edit: Remote events are not a hassle. Well, I was not hassled by the extra line of code in this sample.

 

 

  On 11/16/2019 at 10:50 AM, SKK50 said:

 

If multiple potions have the rep_canration keyword then add the script to each of the base forms.

 

Then you dont even need that keyword, as the script will only ever fire on those objects anyway.

ScriptName rep_Rationkey Extends ObjectReference

MiscObject Property rep_tinkey Auto Const Mandatory
ActorValue property HealthAV Auto Const Mandatory

Event OnItemEquipped(Form akBaseObject, ObjectReference akReference)

if Game.GetPlayer().GetItemCount(rep_tinkey) == 1 )
        Game.GetPlayer().RemoveItem(rep_tinkey)
        Debug.Notification("Your tin key broke! You cannot open another canned ration without hurting yourself.")
ElseIf Game.GetPlayer().GetItemCount(rep_tinkey) == 0)
        Game.GetPlayer().DamageValue(HealthAV, 10)
        Debug.Notification("Ouch. You should try to find a tin key to not hurt yourself.")
Endif
EndEvent

Okay, I can see the difference in the code, and the simplification of it. Which is more optimized anyway? I can at least trash my newer (and actually working) version of code which removed the HealthAV property by using GetHealthAV() instead... what's generally faster?

 

Here's my new code anyway, I'm gonna go and optimize it based on Scrivener's after this.

 

  Reveal hidden contents

 

Edited by RowanSkie
Posted

Oh yea, resist the urge to use ANY of the `Debug` functions in your final work. This was acceptable in Skyrim but is no longer the case for Fallout 4. Instead of using `Debug.Notification()` use a proper `Message` form in the CK.

You can have Debug functions in your code. Thats totally fine. Just make sure the functionality of your mod does not depend on these debug functions.

 

For the "best" solution, Im not familiar enough with your end goals to say.

Posted

From a good design perspective you want to use methods that generate the minimum of events (without hacking base game assets).

 

If you attach a script to an actor it will fire every time the actor equips something, even if that something is not your thing.

 

If you attach a script to a new object you create, the script will only fire for that object.

 

For one mod no, it doesn't matter, but in a large load order its death by a thousand little event cuts.

 

Learn more on the Script Lag Detector page.

  • Recently Browsing   0 members

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