How to use objSetItemProperty if I can't use gItem?

Freeform discussion about anything related to modding Transcendence.
Post Reply
RPC
Fleet Admiral
Fleet Admiral
Posts: 2876
Joined: Thu Feb 03, 2011 5:21 am
Location: Hmm... I'm confused. Anybody have a starmap to the Core?

Long story short I'm making an upgrading dockscreen which means that objSetItemProperty isn't called from the item and I can't use gItem.
I tried using ObjGetItems and enumerating through that but Transcendence says something about 'object not found'.
How am I supposed to use this function?
Tutorial List on the Wiki and Installing Mods
Get on Discord for mod help and general chat
Image
Image
Der Tod ist der zeitlose Frieden und das leben ist der Krieg
Wir müssen wissen — wir werden wissen!
I don't want any sort of copyright on my Transcendence mods. Feel free to take/modify whatever you want.
TVR
Militia Commander
Militia Commander
Posts: 334
Joined: Sat Sep 08, 2012 3:26 am

objGetItems operates on a spaceObject, and isn't gSource defined as the docking spaceObject at the dockscreen?

Assuming (objGetItems gSource "*") has already been tested, (objGetItems gPlayership "*") is less flexible, but is a good substitute nonetheless.
Fiction is reality, simplified for mass consumption.
PGP: 0x940707ED, 5DB8 4CB4 1EF5 E987 18A0 CD99 3554 3C13 9407 07ED
Bitcoin: 1LLDr7pnZDjXVT5mMDrkqRKkAPByPCQiXQ
RPC
Fleet Admiral
Fleet Admiral
Posts: 2876
Joined: Thu Feb 03, 2011 5:21 am
Location: Hmm... I'm confused. Anybody have a starmap to the Core?

Here is the code that fails, if there's any questions/ambiguities just ask:

Code: Select all

;objSetItemProperty IS IMPOSSIBLE to work with
(setq InstalledItemList (list ""))
(enum (objGetItems gSource "*Id") item (block nil
	(setq InstalledItemList (RPCLnkAppend InstalledItemList (itmGetType item)))
	))
;InstalledItemList is just a list of items from objGetItems
(setq InstalledItemList (filter InstalledItemList ItemElement (eq ItemElement TechItemUNID)))
;after the filter it is just the item that has the same unid as TechItemUNID

;this is where objSetItemProperty fails, several times:
(enum InstalledItemList ItemElement (block (newItem)
	(setq newItem (objSetItemProperty gSource ItemElement 'damaged True))
	(objSetItemProperty gSource newItem 'damaged True)
	(PrintTo 'log (objSetItemProperty gSource ItemElement 'fireArc 'omnidirectional))
	(PrintTo 'log (objSetItemProperty gSource ItemElement 'omnidirectional true))
	(PrintTo 'log (objSetItemProperty gSource ItemElement 'secondary True))
	))
Tutorial List on the Wiki and Installing Mods
Get on Discord for mod help and general chat
Image
Image
Der Tod ist der zeitlose Frieden und das leben ist der Krieg
Wir müssen wissen — wir werden wissen!
I don't want any sort of copyright on my Transcendence mods. Feel free to take/modify whatever you want.
TVR
Militia Commander
Militia Commander
Posts: 334
Joined: Sat Sep 08, 2012 3:26 am

This is a theory that I can't test now, but I believe objSetItemProperty works by altering the itemStruct, an itemStruct just being a list with the itemUNID, status flags and quantity, therefore reusing the itemStruct ItemElement several times in one iteration is meaningless - ItemElement refers to the itemStruct before it was altered by objSetItemProperty into a new itemStruct, and no longer exists after the first objSetItemProperty.

If that assumption holds, then to fix this:

Code: Select all


;objSetItemProperty IS IMPOSSIBLE to work with
(setq InstalledItemList (list ""))
(enum (objGetItems gSource "*Id") item (block nil
   (setq InstalledItemList (RPCLnkAppend InstalledItemList (itmGetType item)))
   ))
;InstalledItemList is just a list of items from objGetItems
(setq InstalledItemList (filter InstalledItemList ItemElement (eq ItemElement TechItemUNID)))
;after the filter it is just the item that has the same unid as TechItemUNID

;this is where objSetItemProperty fails, several times:
(enum InstalledItemList ItemElement 
	(block (newItem)
		(setq newItem ItemElement)
		(setq newItem (objSetItemProperty gSource newItem 'damaged True))
		(setq newItem (objSetItemProperty gSource newItem 'fireArc 'omnidirectional))
		(setq newItem (objSetItemProperty gSource newItem 'omnidirectional true))
		(setq newItem (objSetItemProperty gSource newItem 'secondary True))
	) <!-- Update newItem after every instance of objSetItemProperty -->
)
   
Tell me how it goes, alright? Best of luck!
Fiction is reality, simplified for mass consumption.
PGP: 0x940707ED, 5DB8 4CB4 1EF5 E987 18A0 CD99 3554 3C13 9407 07ED
Bitcoin: 1LLDr7pnZDjXVT5mMDrkqRKkAPByPCQiXQ
RPC
Fleet Admiral
Fleet Admiral
Posts: 2876
Joined: Thu Feb 03, 2011 5:21 am
Location: Hmm... I'm confused. Anybody have a starmap to the Core?

Sorry for the late reply D:
I just tried it, game still complains:

Code: Select all

12/31/2013 17:50:27	Exception in objSetItemProperty; arg = (241941120 16483 damaged True)
12/31/2013 17:50:28	Upgrade [Laser Defender]: Exception in objSetItemProperty; arg = (241941120 16483 damaged True) [(241941120 16483 damaged True)] ### (objSetItemProperty gSource newItem "damaged" True) ###
12/31/2013 17:50:28	Exception in objSetItemProperty; arg = (241941120 16483 damaged True) [(241941120 16483 damaged True)] ### (objSetItemProperty gSource newItem "damaged" True) ###
I've hacked a workaround to this for now but an explanation of why objSetItemProperty fails would be appreciated and/or an example of objSetItemProperty that does not use gItem would be amazing as well. :S
Tutorial List on the Wiki and Installing Mods
Get on Discord for mod help and general chat
Image
Image
Der Tod ist der zeitlose Frieden und das leben ist der Krieg
Wir müssen wissen — wir werden wissen!
I don't want any sort of copyright on my Transcendence mods. Feel free to take/modify whatever you want.
TVR
Militia Commander
Militia Commander
Posts: 334
Joined: Sat Sep 08, 2012 3:26 am

This works:

Code: Select all

<ItemType UNID="&itTDBlanket;"
		name=				"TD Blanket"
		level=				"11"
		value=				"1000000"
		mass=				"2000"
		frequency=			"notrandom"
		modifiers=			"MajorItem; NotForSale; TD;"
		
		description=		"This device is responsible for generating the GN particles required to sustain a GN reactor."
		
		virtual=			"true"
		>

	<Image imageID="&rsItems1;" imageX="0" imageY="192" imageWidth="96" imageHeight="96"/>

	<AutoDefenseDevice
			targetCriteria=	"G N:20000"
			weapon=			"&vtRefuelWeapon;"
			fireRate=		"2"
			
			deviceSlots=	"0"
			/>
			
	<Events>
		<OnUpdate>
			(block Nil
				(objEnumItems gSource "*IV +TD" itemVar
					(if (and (eq (objGetItemProperty gSource itemVar 'enabled) Nil) (leq (shpGetFuelLeft gSource) 0))
						(block Nil
							(shpRefuelFromItem gSource (itmCreate (itmGetType &vtOneUnitFuelRod;) 1))
							(objSetItemProperty gSource itemVar 'enabled true)
							(printTo 'console "reenabling")
						)
					)
				)
			)
		</OnUpdate>
	</Events>
</ItemType>
Notice the use of (objEnumItems) instead of:

Code: Select all

(setq InstalledItemList (list ""))
(enum (objGetItems gSource "*Id") item (block nil
   (setq InstalledItemList (RPCLnkAppend InstalledItemList (itmGetType item)))
   ))
(setq InstalledItemList (filter InstalledItemList ItemElement (eq ItemElement TechItemUNID)))
Not sure how (RPCLnkAppend) works, but given that the error output:
RPC wrote:12/31/2013 17:50:27 Exception in objSetItemProperty; arg = (241941120 16483 damaged True)
Yields a single item UNID, rather than the two element list returned by (objEnumItems):

Code: Select all

(-536862702 16777217)
Which appears to indicate that (objGetItems) returns a list of UNIDs, whereas (objEnumItems) operates on a list of itemStructs.

The difference? A simple list of UNIDs is not an itemStruct, it does not include quantity of items in the stack, nor device position number, it cannot be used like gItem, which is an itemStruct. (objSetItemProperty) needs an itemStruct.

Alright, to fix that, replace the entire provided code with this:

Code: Select all


(objEnumItems gSource "*Id" ItemElement
   (block (newItem)
      (setq newItem ItemElement)
      (setq newItem (objSetItemProperty gSource newItem 'damaged True))
      (setq newItem (objSetItemProperty gSource newItem 'fireArc 'omnidirectional))
      (setq newItem (objSetItemProperty gSource newItem 'omnidirectional true))
      (setq newItem (objSetItemProperty gSource newItem 'secondary True))
   ) <!-- Update newItem after every instance of objSetItemProperty -->
)
One last piece of trivia: the (setq newItem) does not appear to be necessary to actually set the item property, but Transcendence still complains unless given the updated itemStruct.
Fiction is reality, simplified for mass consumption.
PGP: 0x940707ED, 5DB8 4CB4 1EF5 E987 18A0 CD99 3554 3C13 9407 07ED
Bitcoin: 1LLDr7pnZDjXVT5mMDrkqRKkAPByPCQiXQ
RPC
Fleet Admiral
Fleet Admiral
Posts: 2876
Joined: Thu Feb 03, 2011 5:21 am
Location: Hmm... I'm confused. Anybody have a starmap to the Core?

Thank you so much TVR. You're correct when objGetItems enums through unids. The right function to use for this was objEnumItems >.<
Thanks for the catch, now I can use objSetItemProperty properly.
Tutorial List on the Wiki and Installing Mods
Get on Discord for mod help and general chat
Image
Image
Der Tod ist der zeitlose Frieden und das leben ist der Krieg
Wir müssen wissen — wir werden wissen!
I don't want any sort of copyright on my Transcendence mods. Feel free to take/modify whatever you want.
Post Reply