setting cursor pos to an item in OnGlobalPaneInit

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

Noticed a glitch when updating TransGeek's Identify Before Buying mod.

Using (scrShowPane gScreen "Default") will show the same item but the item description can be larger for items after they have been IDed. This can overlap the item below. See composite before/after image of the cannon accelerator attached.

Using (scrRefreshScreen gScreen) instead fixes this as the item box size is reset to match the item description. Unfortunately it also resets the list order which will frequently jump the item to further up the list as it has a higher level when identified. Ideally the same item would show under the cursor before and after identification, so the player could see what item they have just identified.

Sounds easy enough, just set the list cursor to the same spot. But this doesn't work as the item is often moved in the list as the screen refreshes, so a different item shows.

Generally initialItem code can be used to set the cursor pos, but the mod uses scrAddAction in <OnGlobalPaneInit> so this isn't an option (as far as I know).

XML functions could be used to add initialItem code to the two dockscreens used by the mod, RPGCommoditiesExchangeBuy and Sell, but a lighter way of doing it would be getting the list cursor position of the item after it has been identified and setting the cursor to this value.

But I don't know how to do this or even if it is possible. Is there a way of getting the index/pos of an item in an itemPicker list. It would seem to need a list of the items displayed which can be searched or 'find'ed but I'm not sure if this list is available.

Is there a way to find the list pos of the item, in this case 'theItem', in the dockscreen list after it has been identified. I checked and it seems that the unknown item remains the same item after being identified. So searching for it would seem to be simple. Just need a dockscreen list to search.

Anyone know how to do this inside <OnGlobalPaneInit>?

The only other option I can see is to reset the item box size to handle the larger item description without refreshing the screen. Then scrShowPane would work. Can this be done?
Attachments
UpdatedIdentify.xml
(3.73 KiB) Downloaded 234 times
unknown showPane use.jpg
unknown showPane use.jpg (64.54 KiB) Viewed 7914 times
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

Maybe this?

Code: Select all

(block (
	(theItem (scrGetItem gScreen))
	(cursor 0)
	done
	)
	(scrRefreshScreen gScreen)
	(loop (not done)
		(scrSetListCursor gScreen cursor)
		(if (neq (scrGetListCursor gScreen) cursor)
			(block Nil
				(scrSetListCursor gScreen 0)
				(setq done True)
				)
			)
		(if (eq theItem (scrGetItem gScreen))
			(setq done True)
			)
		(setq cursor (add cursor 1))
		)
	)
There should probably be a built-in engine function for this, but if this works we could at least make it a lambda.
relanat
Militia Captain
Militia Captain
Posts: 941
Joined: Tue Nov 05, 2013 9:56 am

Thanks. Got it working as a lambda or event run outside of 'scrAddAction'. But not in the 'scrAddAction' code block. I often have trouble getting code to work in 'scrAddAction'.

Much butchered code where 'theItem' is the item to set the cursor on:

Code: Select all

(setq rpgD789SetCursorToItem (lambda (theItem)
	(block (
		(cursor 0)
		done
		)
		(scrRefreshScreen gScreen)
		(scrSetListCursor gScreen cursor)
		(loop (not done)
			(if (eq theItem (scrGetItem gScreen))
				(setq done True)
				(block Nil
					(setq cursor (add cursor 1))
					(scrSetListCursor gScreen cursor)
				)
			)
		)
	)
))
Thanks for the help. I was absolutely clueless on how to do this. This is a very clever solution.

Although this code works with only a tiny bit of lag in really long lists there is a mod killing bug in it. Identifying the EMP or radiation ammo box or a barrel of radioactive waste freezes the game. All other unknown items (afaik) ID fine.
Oddly, the three items only freeze the game in the Buy screen, &dsRPGCommoditiesExchangeBuy;. They can be identified in the Sell screen with no problems.

Another version using 'scrShowPane' instead of 'scrRefreshScreen' is ready for release. It just needs a bit more testing. It uses XML functions to reset the item box sizes for the unknown analyzers. The unknown analyzer items look a bit bigger than normal (by one empty line) in item lists but this is the least intrusive way I can find of fixing the display glitch.
The new mod doesn't reset the list order which is good because it was pretty jarring having the items jump around as they were identified.
Ideally the item box size would reset as required automatically but this'll do.


For info, the above code refreshes the screen (to reset the item box sizes) then sets the cursor to '0' which is the first item in the list (zero-based numbering is used).
Then, inside the loop function, checks if the item at that cursor position is the same as the item we want the cursor to be on. If it is then 'done' is set to 'True'. The 'loop' function then stops because the condition '(not done)' translates as "not True" or 'Nil'. 'Loop' code stops when the condition returns 'Nil'. This leaves the cursor on that item.
If the items are not the same, the second lot of 'if' code runs. This adds 1 to 'cursor' (making it 1; 0+1). The cursor is set to cursor position '1' (the second item in the list) and the 'loop' function runs again. It checks the cursor item against the desired item, etc, etc.
It will continue to do this all the way down the list until the items match. Then the code will stop and the screen will have the cursor set on the item we just identified. This happens so rapidly that we only ever see the cursor set to the final position even though it works it way down the list.
Note that there is always a chance of causing endless loops when using the 'loop' function (this freezes the game; the code in the second post does this). This can't happen here because the item will always be present so the code will find it, just in an unknown position in the list. (The three items mentioned above will cause the game to freeze but this is unrelated to the 'loop' code). EDIT: But refreshing the screen removes these items from the station 'Buy' list because they don't buy them when they are identified. So the game can't find them and freezes. This is why it only happens in the 'Buy' screen, not the 'Sell' screen. In the 'Sell' screen the station will show the identified item but say they are "not interested in buying" them. Hat-tip to NMS for explaining that further down. End EDIT.

=========

The 'freezing' mod is attached. Of note is the simplicity of the updated currency code compared to the original (although the original hasn't got much code either). TransGeek needed separate code to handle rin transactions in the original mod. George has added new functions and options which means the updated mod can handle any currency using one set of code. It's another example of small improvements over time making the game much better.
Attachments
UpdatedIdentify last version 11 broken.xml
(6.81 KiB) Downloaded 179 times
Last edited by relanat on Sat Nov 24, 2018 10:31 am, edited 1 time in total.
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

The reason you're getting freezes is that you removed this section from my code:

Code: Select all

		(if (neq (scrGetListCursor gScreen) cursor)
			(block Nil
				(scrSetListCursor gScreen 0)
				(setq done True)
				)
			)
If you set the cursor to a value, but then getting the cursor doesn't return that value, you've reached the end of the list, so end the loop and reset to the top.

I'm not sure why it would fail to match after identifying normal items (not ones that randomly become different things when identified). I don't think the items should change. You could use itmIsEqual instead of eq, but that ignores quantity and possibly other data/properties, so you might match the wrong instance of an item sometimes.
relanat
Militia Captain
Militia Captain
Posts: 941
Joined: Tue Nov 05, 2013 9:56 am

I'm working my way through this. Possibly the first lot of code needs the 'exp' part of the 'loop' code in a 'block'. So the reason it initially froze (before I mutilated it near beyond recognition) was the code was endlessly setting the cursor to 'cursor'. Dunno. If I get time I'll mess about with it again.

I'm happy with the separate 'scrShowPane' version so will upload that. The slightly oversized item boxes look a little odd but reset once identified which I feel is better than having the list reshuffle and jump about. I think I've found all the unknown items that have larger descriptions. Time will tell! Thanks.
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

I fixed the version you uploaded by adding the error check to your function and using it in the action code. But the item moving around in the list is a bit annoying.
Attachments
UpdatedIdentify NMS.xml
(6.59 KiB) Downloaded 165 times
relanat
Militia Captain
Militia Captain
Posts: 941
Joined: Tue Nov 05, 2013 9:56 am

Ah, so that's what was happening. When the radioactive/EMP items became known and the screen was refreshed it removed those items from the list because stations don't sell them. So the cursor couldn't be set to them. This doesn't happen using 'scrShowPane' because it doesn't reset the list so the identified radioactive/EMP items still show. Thanks, I couldn't work it out.
Stupid code. Do what I want, not what I typed in!
Post Reply