Issue Data
|
Issue #26196: PipboyMiscItemScript: Cannot call IsInFaction() on a None object[02/13/2019 - 07:27:04PM] error: Cannot call IsInFaction() on a None object, aborting function call stack: [None].DLC06:PipboyMiscItemScript.OnContainerChanged() - "g:\_F4\DLC06\Art\Raw\Scripts\DLC06\PipboyMiscItemScript.psc" Line 10 [02/13/2019 - 07:27:04PM] warning: Assigning None to a non-object variable named "::temp4" stack: [None].DLC06:PipboyMiscItemScript.OnContainerChanged() - "g:\_F4\DLC06\Art\Raw\Scripts\DLC06\PipboyMiscItemScript.psc" Line 10 Note: In case it's not obvious, this error occurs when giving a settler a Pip-Boy (from the misc section of your inventory). |
Posting the full script here because this error is somewhat unexpected:
The script equips a PipBoy on an actor. It runs on the MiscItem PipBoy objects in vault 88's PipBoy crate. These items cannot be equipped on actors (only armor items can), so the script silently replaces the MiscItem PipBoy with an Armor PipBoy and equips that one instead. The MiscItem PipBoy is subsequently removed. This means that the script always runs twice if you give a PipBoy to a settler: the event fires again when the PipBoy is removed from the settler's inventory.
In the event that fires upon removal of the item, akNewContainer = none, and this is where the error occurs:
The "is" check is supposed to return true if akNewContainer is an actor. Though, it is NOT supposed to only return true if the actor is not none. In fact, it still returns true if the actor IS none because none is a perfectly valid value for an actor
To make this work as expected, an "as" check has to be used. Unlike the "is" check, the "as" check casts akNewContainer as an actor (so it is also a tad slower than an "is" check) and then basically performe an "if <actor>" check that will never return true if the actor is none.
Scriptname DLC06: PipboyMiscItemScript extends ObjectReference Const Faction property WorkshopNPCFaction auto const mandatory Armor property DLC06PipboyVault88 auto const mandatory Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer) if akNewContainer is Actor Actor myActor = akNewContainer as Actor if myActor != Game.GetPlayer() && myActor.IsInFaction(WorkshopNPCFaction) && myActor.GetItemCount(DLC06PipboyVault88) == 0 debug.trace(self + " OnContainerChanged: equipping pipboy on " + myActor) ; add and equip real pipboy on actor myActor.EquipItem(DLC06PipboyVault88) myActor.RemoveItem(self.GetBaseObject()) endif endif EndEvent
The script equips a PipBoy on an actor. It runs on the MiscItem PipBoy objects in vault 88's PipBoy crate. These items cannot be equipped on actors (only armor items can), so the script silently replaces the MiscItem PipBoy with an Armor PipBoy and equips that one instead. The MiscItem PipBoy is subsequently removed. This means that the script always runs twice if you give a PipBoy to a settler: the event fires again when the PipBoy is removed from the settler's inventory.
In the event that fires upon removal of the item, akNewContainer = none, and this is where the error occurs:
if akNewContainer is Actor
The "is" check is supposed to return true if akNewContainer is an actor. Though, it is NOT supposed to only return true if the actor is not none. In fact, it still returns true if the actor IS none because none is a perfectly valid value for an actor
To make this work as expected, an "as" check has to be used. Unlike the "is" check, the "as" check casts akNewContainer as an actor (so it is also a tad slower than an "is" check) and then basically performe an "if <actor>" check that will never return true if the actor is none.
Comment #1 Aug 10, 2019 1:48 am
Edited by Sclerocephalus on Aug 16, 2019 4:59 pm
Showing Comments 1 - 1 of 1