Jump to content

Referencing the object to which a script is attached


brown8220

Recommended Posts

Ok, so this is driving me mad.

 

I need to reference the object to which my script is attached. In my case, for testing purposes, it's the plain Elven Boots, but it shouldn't matter. I'm trying to do this without hard-coding the script to a specific Form ID eg. Game.GetForm(XXXXXXXX).

I should mention i'm referencing from within a non-global void function. Also my script extends Form.

 

I've tried any combination of:

Form Item = Game.GetForm(Parent.GetFormID()) ; compiles fine, but Item is allways null

Form Item = Game.GetForm(Self.GetFormID()) ; compiles fine, but Item is allways null

Form Item = Self ; compiles fine, but Item is allways null

Form Item = Parent ; compiles with errors

 

Any help would be much appreciated :)

Edited by brown8220
Link to comment
Share on other sites

Trying to add level requirements to items to which the script is added. I could try to explain it i detail, but i think it will be easier to just look at the code.

 

ScriptName ItemRestriction extends Form

int property requiredLevel auto
bool property playerRestrictionOnly auto

event OnEquipped(Actor akActor)
DoOnEquipped(akActor)
endevent

function DoOnEquipped(Actor akActor)
Actor equipper = akActor
Form equipment = Game.GetForm(Parent.GetFormID())

if(playerRestrictionOnly == true)
	if (equipper == Game.GetPlayer())
		if (equipper.GetLevel() < requiredLevel)
			equipper.UnequipItem(equipment)
			if (UI.IsMenuOpen("InventoryMenu") || UI.IsMenuOpen("FavoritesMenu"))
				Game.DisablePlayerControls(0, 0, 0, 0, 0, 1, 0, 0, 0)
				Utility.Wait(0.1)
				Game.EnablePlayerControls(0, 0, 0, 0, 0, 1, 0, 0, 0)
				Game.GetPlayer().OpenInventory(false)
			endif
			Debug.Notification(equipper.GetName()+ " (" + equipper.GetLevel() + ") does NOT meet the requirements for " + equipment.GetName())
			Debug.Notification("Required Level: " + requiredLevel + ", ItemBaseVal: " + equipment.GetGoldValue())
		endif
	endIf
else
	if (akActor.GetLevel() < requiredLevel)
		equipper.UnequipItem(equipment, true, true)
		if (UI.IsMenuOpen("InventoryMenu") || UI.IsMenuOpen("FavoritesMenu"))
			Game.DisablePlayerControls(0, 0, 0, 0, 0, 1, 0, 0, 0)
			Utility.Wait(0.1)
			Game.EnablePlayerControls(0, 0, 0, 0, 0, 1, 0, 0, 0)
			Game.GetPlayer().OpenInventory(false)
		endif
		Debug.Notification(equipper.GetName()+ " (" + equipper.GetLevel() + ") does NOT meet the requirements for " + equipment.GetName())
		Debug.Notification("Required Level: " + requiredLevel + ", ItemBaseVal: " + equipment.GetGoldValue())
	endif
endif
endfunction

Link to comment
Share on other sites

Yeah, like I said, I think you'll need to extend ObjectReference for that. The OnEquipped event is part of the ObjectReference script, not the (more primal) Form script--which makes sense, since not all forms can be equipped, and when a character does equip something, they're equipping an instance (an in-game object) of the base form, not the base form itself.
Link to comment
Share on other sites

Why so complicated?

 

ScriptName ItemRestriction extends ObjectReference

int property requiredLevel auto
bool property playerRestrictionOnly auto
Actor Property playerREF auto

Event OnEquipped(Actor akActor)
Form baseOb = GetBaseObject()
If akActor.GetLevel() < requiredLevel
	If akActor == playerREF
		akActor.UnequipItem(baseOb)
		If UI.IsMenuOpen("InventoryMenu") || UI.IsMenuOpen("FavoritesMenu")
			Game.DisablePlayerControls(0, 0, 0, 0, 0, 1, 0, 0, 0)
			Utility.Wait(0.1)
			Game.EnablePlayerControls(0, 0, 0, 0, 0, 1, 0, 0, 0)
			akActor.OpenInventory(false)
		EndIf
	ElseIf !playerRestrictionOnly
		akActor.UnequipItem(baseOb, true, true)
	EndIf
	Debug.Notification(akActor.GetName()+ " (" + akActor.GetLevel() + ") does NOT meet the requirements for " + baseOb.GetName())
	Debug.Notification("Required Level: " + requiredLevel + ", ItemBaseVal: " + baseOb.GetGoldValue())
EndIf
EndEvent

Edited by steve40
Link to comment
Share on other sites

steve40 - well i would have put the critical part i a function and clean it ONCE i get it working :)

Are you saying you got it working with that script? I don't understand why you make a playerref a property? That just seems like more hassle to me then using Game.GetPlayer(). Also, the user has no way to restrict the script to only run on the player, in your version. If an NPC picks up the item, he will be restricted no matter what... Anyway, I have no problem referencing the player, its the equipped item that is STILL bothering me.

 

DreamKingMods - thank you for your help - my initial tests with using ObjectReference have failed - ill keep you updated when i get this to work.

Edited by brown8220
Link to comment
Share on other sites

On the request of cleaning it, the script now looks as follows:

 

ScriptName ItemRestriction extends ObjectReference

bool property playerRestrictionOnly auto
int property requiredLevel auto

event OnEquipped(Actor akActor)
DoOnEquipped(akActor)
endevent

function DoOnEquipped(Actor akActor)
Actor equipper = akActor
ObjectReference equipment = self

if(playerRestrictionOnly == true)
	if (equipper == Game.GetPlayer())
		if (equipper.GetLevel() < requiredLevel)
			equipper.UnequipItem(equipment)
			CrashMenu()
		endif
	endif
else
	if (akActor.GetLevel() < requiredLevel)
		equipper.UnequipItem(equipment, true, true)
		if (equipper == Game.GetPlayer())
			CrashMenu()
		endif
	endif
endif
endfunction

function CrashMenu()
if (UI.IsMenuOpen("InventoryMenu") || UI.IsMenuOpen("FavoritesMenu"))
	Game.DisablePlayerControls(0, 0, 0, 0, 0, 1, 0, 0, 0)
	Utility.Wait(0.1)
	Game.EnablePlayerControls(0, 0, 0, 0, 0, 1, 0, 0, 0)
endif 
endfunction

 

However it still doesn't work. Self/self/Parent/parent, when script is placed on ArmorElvenBoots for testing, is always null/empty/0. I think the problem is that in changing to ObjectReference i'm no longer referencing a Form-->Armor of which ArmorElvenBoots is a type. So my dilemma now is; I can't use Form because OnEquipped() is an ObjectRef specific Event; I can't use ObjectRef as base because Armor/Weapon are simply not of this type.

Edited by brown8220
Link to comment
Share on other sites

Working script:

 

ScriptName ItemRestriction extends ObjectReference

bool property playerRestrictionOnly auto
int property requiredLevel auto
Actor equipper
Form equipment

event OnEquipped(Actor akActor)
DoOnEquipped(akActor)
endevent

function DoOnEquipped(Actor akActor)
equipper = akActor
equipment = GetBaseObject()

if(playerRestrictionOnly == true)
	if (equipper == Game.GetPlayer())
		if (equipper.GetLevel() < requiredLevel)
			equipper.UnequipItem(equipment)
			CrashMenu()
		endif
	endif
else
	if (akActor.GetLevel() < requiredLevel)
		equipper.UnequipItem(equipment, true, true)
		if (equipper == Game.GetPlayer())
			CrashMenu()
		endif
	endif
endif
endfunction

function CrashMenu()
if (UI.IsMenuOpen("InventoryMenu") || UI.IsMenuOpen("FavoritesMenu"))
	Game.DisablePlayerControls(0, 0, 0, 0, 0, 1, 0, 0, 0)
	Utility.Wait(0.1)
	Game.EnablePlayerControls(0, 0, 0, 0, 0, 1, 0, 0, 0)
endif
Debug.Notification(equipper.GetName()+ " (" + equipper.GetLevel() + ") does NOT meet the requirements for " + equipment.GetName() + "(Required Level: " + requiredLevel + ")")
endfunction

 

Id like to extend my thanks to Plastrader, who helped me locate the problem via PM, so thank you very much. I appreciate the time you took to help me :)

Also thank you again DreamKingMods for your initial help :)

You boths deserve a medal!

Edited by brown8220
Link to comment
Share on other sites

Using playerREF is about 1000x faster than calling Game.GetPlayer(), which is a very slow function. There's a thread in the Bethesda forums on "best scripting practice" where they have the metrics of various script functions, but I don't have the link atm.

 

ScriptName ItemRestriction extends ObjectReference

int property requiredLevel auto
bool property playerRestrictionOnly auto
Actor Property playerREF auto

Event OnEquipped(Actor akActor)
       Form baseOb = GetBaseObject()
       If akActor.GetLevel() < requiredLevel
               If akActor == playerREF
                       akActor.UnequipItem(baseOb)
                       If UI.IsMenuOpen("InventoryMenu") || UI.IsMenuOpen("FavoritesMenu")
                               Game.DisablePlayerControls(0, 0, 0, 0, 0, 1, 0, 0, 0)
                               Utility.Wait(0.1)
                               Game.EnablePlayerControls(0, 0, 0, 0, 0, 1, 0, 0, 0)
                               akActor.OpenInventory(false)
                       EndIf
               ElseIf !playerRestrictionOnly
                       akActor.UnequipItem(baseOb, true, true)
               EndIf
               Debug.Notification(akActor.GetName()+ " (" + akActor.GetLevel() + ") does NOT meet the requirements for " + baseOb.GetName())
               Debug.Notification("Required Level: " + requiredLevel + ", ItemBaseVal: " + baseOb.GetGoldValue())
       EndIf
EndEvent

Link to comment
Share on other sites

  • Recently Browsing   0 members

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