Jump to content

Switching out items on pick up


MikePayne307

Recommended Posts

**** I fully expect I have missed something stupid, but I can't for the life of me see it ****

 

Having made collectible versions of all the movable statics so that players would be able to break them down for more crafting material options, it occurred to me that a lot of mods that add locations also add in their own versions of the objects.

I had the idea of swithcing out these items when the player picks them up to hopefully provide a seamless experience without needing to create patches for every situation.

 

I have an onAdd event handler implemented like this:

SetEventHandler "onAdd" AAJunkSwitchoutScript "second"::playerref

and the main script:

scn AAJunkSwitchoutScript

int SearchIndex
int SearchCount
ref SearchItemBase


ref rItem
ref rActor
ref rItemBase

string_var OriginalObjectName
string_var SearchItemName

begin Function { rItem, rActor }

	if IsReference rItem
		let rItemBase := rItem.GetBaseObject

		if GetObjectType rItemBase == 31
			set OriginalObjectName to GetName rItemBase
			Set SearchIndex to -1
			Set SearchCount to ListGetCount AAScavengeJunkList
				while (SearchIndex += 1) < SearchCount
					set SearchItemBase to ListGetNthForm AAScavengeJunkList SearchIndex
					set SearchItemName to GetName SearchItemBase
						if eval OriginalObjectName == SearchItemName
							Player.RemoveItem rItemBase 1 0
							Player.additem SearchItemBase 1 0
						endif				
				Loop
		endif
		sv_destruct OriginalObjectName SearchItemName ;Remove strings from save file
	endif
end

But whilst it will happily add in the replacement items correctly, it won't remove the original.

I think I am failing to capture the baseobject (if that makes sense?) but having tried GetBaseObject, GetBaseForm, and a few other methods I haven't been able to make it work.

Link to comment
Share on other sites

RemoveMeIR is only useful for inventory references, not base objects. In other words, it won't work on rItemBase.

 

Ok, so I guess RemoveMe doesn't work cause it would point to the UDF and not the item that triggered the OnAdd event (news to me). Here's another two guesses then:

 

  1. You can't remove an item so soon after getting it. So delaying the removal by some frames will fix it.
  2. The item that triggered the OnAdd event can't be deleted while a function that it triggered is still running. So have the function flag the removal of the item and finish (thereby ending the OnAdd block as well), and then have another script come in and remove the item.

 

I wanna bet on (2) here.

Edited by WarMachineDD7
Link to comment
Share on other sites

@GamerRick

Apologies. I may be being a bit thick, but I can't see how that script connects to a quest script could you show me what you mean please? I did try adding a similar script to objects when picked up which was fired successfully on all subsequent pickups but I couldn't get it to run on the first instance. Perhaps I am better off scanning for all items from a startquest?

 

@WarMachineDD7

I added a ref and a short to fire a gamemode block in my main quest script and pass it the current rItembase reference, but to no avail so I am not sure if I am interpreting your suggestion correctly?

Link to comment
Share on other sites

I found that it's YUP that made the changes to the bulk items script to use a quest.

 

A quest script runs its GameMode block as often as you set it to. So, you can have your object script set a flag that tells it to replace items in your inventory. You would need to look it over to see how it works.

Link to comment
Share on other sites

Thanks guys.

Finally got it all working :smile:

I've added my new scripts here in case it's useful to anyone in the future

scn AAJunkSwitchoutScript

ref rItem
ref rActor
ref rItemBase

begin Function { rItem, rActor }
	if IsReference rItem
		let rItemBase := rItem.GetBaseObject
		if GetObjectType rItemBase == 31
			set AAJunkSwitchoutQuest.ReadyFlag to 1
			SetQuestDelay AAJunkSwitchoutQuest 0.5
		endif
	endif
end

scn AAJunkHandlerQuestScript

short index
short ReadyFlag
short SearchCount
short SearchIndex
ref SearchItemBase
ref Ref_Item
ref Ref_ItemBase
string_var OriginalObjectName
string_var SearchItemName

Begin GameMode

	if getGameRestarted
		SetEventHandler "onAdd" AAJunkSwitchoutScript "second"::playerref
	endif

	if ReadyFlag == 0
		;printc "Junk Handler Script is IDLE"
		return
	elseif ReadyFlag > 0

	;Process Items In Inventory

	;reset the ReadyFlag
		set ReadyFlag to 0

		;printc "Junk Handler Script is ONLINE"

		let index := Player.GetNumItems
		while index > 0
			let index -= 1
			let Ref_Item := Player.GetInventoryObject index
			if (GetType Ref_Item) == 31
				set OriginalObjectName to GetName Ref_Item
				Set SearchIndex to -1
				Set SearchCount to ListGetCount AAScavengeJunkList
				while (SearchIndex += 1) < SearchCount
					set SearchItemBase to ListGetNthForm AAScavengeJunkList SearchIndex
					set SearchItemName to GetName SearchItemBase
						if eval OriginalObjectName == SearchItemName
							Player.additem SearchItemBase 1 1
							Player.removeitem Ref_Item 1 1
						endif				
				Loop
				sv_destruct OriginalObjectName SearchItemName ;Remove strings from save file
			endif
		loop
		SetQuestDelay AAJunkSwitchoutQuest 2
	endif
End
Link to comment
Share on other sites

  • Recently Browsing   0 members

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