finding jettisoned cargo crates on creation help please

Freeform discussion about anything related to modding Transcendence.
Post Reply
relanat
Militia Captain
Militia Captain
Posts: 941
Joined: Tue Nov 05, 2013 9:56 am

The Commander's Log mod records the uninstalled items in most stations. This is meant to include abandoned cargo crates, &stGenericCargoCrate;, created by the player when they jettison from the cargo hold.

All other stations have their uninstalled items recorded when the player undocks from them. This is done using this (abreviated) code.

Code: Select all

<GetGlobalDockscreen>
	(block Nil
		(if find (staGetDockedShips gSource) gPlayerShip)
			(block Nil
				(typSetData &evD789CommandersLog; 'currentStation gSource)
				(typAddRecurringTimerEvent &evD789CommandersLog; 15 "CheckScreen")
			)
		)
		Nil
	)
</GetGlobalDockscreen>

<CheckScreen>
	(if (eq (scrGetScreen gScreen) Nil)
		(block Nil
			(typCancelTimerEvent &evD789CommandersLog; "CheckScreen")
			(logSetItems
				(set@ (logGetItems)
					(convertTo 'string (objGetID (typGetData &evD789CommandersLog; 'currentStation)))
					(list
						(objGetID (typGetData &evD789CommandersLog; 'currentStation))
						(objGetName (typGetData &evD789CommandersLog; 'currentStation))
						(sysGetNode)
						"Visited"
						(objGetItems (typGetData &evD789CommandersLog; 'currentStation) '*U)
					)
				)
			)
			(typSetData &evD789CommandersLog; 'currentStation Nil)
		)
	)
</CheckScreen>
But it doesn't work on newly created jettisoned crates. The items in the crate aren't recorded unless the player docks with the crate after it has been created.
I had the idea of using another timer event which checked for &dsCargoHold;. This could then record items in the crates within 100 ls of the playership after the player exited the cargo hold.
Ideally an event could be triggered if

Code: Select all

(and (eq gSource gPlayerShip)
	(eq (shpGetDockObj gPlayerShip) Nil)
	(eq aScreenUNID &dsCargoHold;)
)
But unfortunately this doesn't seem to work.
I think this is because gSource in <GetGlobalDockscreen> (quoting from digdug's events doc) is the "spaceObject the player just docked with". The playership hasn't docked with any object, they are just in the cargo hold, so (eq gSource gPlayerShip) isn't a valid reason for <GetGlobalDockscreen>.

Can anyone see a way around this? Using the existing station code modified to work on crates would work. But how to trigger it?

Or is there another way to check for the creation of a jettisoned crate? All crates of this type come from the player, either from jettisoning or game code creating them for the player.
The only other idea I have is an <OnUpdate> event, but these are usually to be avoided.

What is needed is some way to record the items in a newly created jettisoned crate without having to dock the playership with it.
Stupid code. Do what I want, not what I typed in!
NMS
Militia Captain
Militia Captain
Posts: 569
Joined: Tue Mar 05, 2013 8:26 am

Hmm. The global variables gSource and aScreenUNID get set when a screen opens, but they don't get unset when it's closed. Also, if your code is in another type's event, it may set gSource to its own type or object. So it's better to rely on (scrGetScreen gScreen). But note that it's an error if no screen has been opened since the game was started or loaded, so use errBlock or isError or something. (shpGetDockObj gPlayerShip) should be fine.

Periodically checking the screen may not be the best option though. Ideally, you'd only do anything when the data that you want to store changes (perhaps by modifying rpgJettisonItem to update your data if the object is the specified type) or when the data is needed (by searching the system for objects of that type and updating them all when you go to access the data or the player leaves the system).
relanat
Militia Captain
Militia Captain
Posts: 941
Joined: Tue Nov 05, 2013 9:56 am

With no actual dock object when in the cargo hold there doesn't seem to be a way (that I can find) of using <GetGlobalDockscreen>, which has an annoying habit of causing endless game loading if there isn't valid gSource code.
The critical need is to record the items at or near the time of creation. Adding or removing items after this is handled by the existing code.
I've modified 'rpgJettisonItem' and it is working well. This sounds like the least intrusive way to record the items.
Thanks. I never would have seen 'rpgJettisonItem'. I probably would have added code to trigger an event in one of the cargo hold or jettison dockscreen actions.

Code: Select all

	;Standard game lambda 'rpgJettisonItem' overwritten to allow jettisoned cargo
	;	crates and their items to be recorded for access out of system.
(setq rpgJettisonItem (lambda (theObj theItem)
	(block Nil
		(objAddItem theObj theItem)

			;If the player jettisoned explosive items, then mark the object
		(if (or (itmMatches theItem "mf") (itmMatches theItem "* +explosive;"))
			(objSetData theObj "PlayerExplosives" True)
			)

			;This code added by the Commander's Log mod.
			;Add the crate and items to 'logGetItems'.
		(logSetItems
			(set@ (logGetItems)
				(convertTo 'string (objGetID theObj))
				(list
					(objGetID theObj)
					(objGetName theObj)
					(sysGetNode)
					"Visited"
					(objGetItems theObj '*U)
				)
			)
		)
	)
))
But the existing code for updating objects currently recognizes that Salvagers may have looted them and made them vanish. This makes them disappear from the station lists. The Log shouldn't be able to determine this. I'll have to exclude them somehow and handle locating them when they aren't there anymore or flying within visual range of where they were.

And I have also been getting 'scrGetScreen' errors as well since. Thanks for spotting that. It is much easier to fix when you already know what the problem is!
Stupid code. Do what I want, not what I typed in!
Post Reply