partial name item search query

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

Wed Nov 01, 2017 3:34 am

I'm trying to add a search function to the Scorpion GodPlayership items screens. ATM you get all items for whichever criteria/attribute and have to scroll down and manually find what you want. Not as useful as I would like as some of the lists are very long despite my efforts to reduce them.
The aim is to be able to create a shortened list of items containing the desired item which can then be created without having to scroll down really long lists.

eg, typing 'ore' into the text box would bring up everything with 'ore' in its name. Which would include explorer autons and tailored silk suits as well as all ores but is sufficiently reduced to make it quick to scroll down. This list could further be limited by item criteria.


GodMod had a filter action using a text input screen which was excellent, see attached image (note: GodMod is really suffering in 1.8a3). That's the sort of thing I'm looking for but dsf, etc is gibberish to me. Trading Post Menu does the same sort of thing but by using custom functions elsewhere, like GodMod does, becomes too confusing for me.

I've found that itmCreateByName works with partial names. Do any other functions do the same, possibly lookup or match?

The mod currently uses a virtual station stocked with one of every item with a reduced list available according to criteria or attributes but I don't know how to reduce the list with a partial name.


Code for the virtual station which contains one of every item.

Code: Select all

<StationType UNID="&stD789GodItemsVirtualStation;"
		virtual=	"true"
		>

	<Events>
		<OnCreate>
			(block Nil
				(setq allList (itmEnumTypes "*" list (objAddItem gSource list 1)))
			)
		</OnCreate>
	</Events>
</StationType>
And here's the standard 'create' screen which has the list shortened by item criteria and attributes carried over from a category select screen.
I would think another screen would be required because the partial name search can't be represented by normal item criteria or attribute data.

Code: Select all

<Dockscreen UNID= "&dsD789GodGetItemsDockscreen;"
		name=		"=(if (@ gData 'descName) (@ gData 'descName))"
		type=			"itemPicker"
		nestedScreen=	"true"
		>

	<ListOptions
		dataFrom=	"=(setq nonStation (sysCreateStation &stD789GodItemsVirtualStation; Nil))"
		list=		"*"
		>
		(scrSetListFilter gScreen (@ gData 'criteria))
	</ListOptions>
	..........
Anyone got any ideas? TIA.
Attachments
GodMod ore list.JPG
GodMod ore list.JPG (74.6 KiB) Viewed 109 times

NMS
Militia Commander
Militia Commander
Posts: 400
Joined: Tue Mar 05, 2013 8:26 am

Wed Nov 01, 2017 9:56 am

I don't think there are any other functions that do that. Lookup is the same as find except it returns the thing it finds rather than its position in a string or list. (This could have been useful in conjunction with the keyIndex argument, but most things it would have been used for are probably easier to do with structs now.) Match returns the first item from a list that makes some condition true.

But you could get a list of matching items using something like:

Code: Select all

(filter (itmGetTypes criteria) theItem
	(find (itmGetName theItem '(short actual)) partial-string)
)
That's assuming you only want to search using the identified short names ("bar" wouldn't match "barrel of x"). Adjust the flags otherwise.

Then add the items to a virtual station and show a screen with data from that station, I guess.

relanat
Militia Commander
Militia Commander
Posts: 438
Joined: Tue Nov 05, 2013 9:56 am

Fri Nov 03, 2017 11:30 pm

Got it working. Many thanks. For some reason I didn't think 'find' worked with partial strings. Possibly my own attempts may have confused me! I found 'find' to be a bit fussy about strings and variables.

Here's the code for the virtual station I used. It puts one of every item in the station if that item has the variable 'searchTerm' somewhere in it's identified name. 'searchTerm' is set from the scrGetInputText of the previous screen. Useful examples include "ore", "plasma" and "shield".

Code: Select all

<StationType UNID="&vtD789GodItemsSearchStation;">
	<Events>
		<OnCreate>
			(block Nil
				(setq listToAdd (filter (itmGetTypes '*) theItem (find (itmGetName theItem 'actual) searchTerm)))
				(enum listToAdd theItem (block Nil
											(itmSetKnown theItem 'true)
											(objAddItem gSource theItem 1)
										)
				)
			)
		</OnCreate>
	</Events>
</StationType>
I spent a couple of hours trying to get this code to work in the <ListOptions> section of dsD789GodGetItemsDockscreen (code in the OP). No success. I was thinking of an 'if' function that used this code if 'searchTerm' existed or used the existing code if not. I did get a list of launchers come up once with 'searchTerm' set as "ore". :o But all the lists (except the launchers) were coming up as True, not a list of items.

Thanks again. Using this search function is a lot better than scrolling down 50 or 60 items to find the one you want.

NMS
Militia Commander
Militia Commander
Posts: 400
Joined: Tue Mar 05, 2013 8:26 am

Sat Nov 04, 2017 4:00 pm

Glad it's working. But a couple points:

- It looks like you're passing searchTerm to the station as a global variable. This works, but isn't considered best practice. It's better to pass it via the data argument of scrShowScreen or set data on a type or object.

- I think you're permanently identifying any item that appears on the filtered screen. I'm not sure if there's a way to make them appear identified but not do this, but you could revert them when exiting.

Maybe for the action to show the screen try something like:

Code: Select all

(block (theStation itemList unidentifiedList)
	(setq theStation (sysCreateStation ...))
	(setq itemList (filter (itmGetTypes '*) theItem (find (itmGetName theItem 'actual) searchTerm)))
	(setq unidentifiedList (filter itemList theItem (not (itmIsKnown theItem))))
	(enum itemList theItem (objAddItem theStation theItem 1))
	(enum unidentifiedList theItem (itmSetKnown theItem))
	(scrShowScreen gScreen yourScreen { station:theStation unidentifiedList:unidentifiedList })
	)
Then your screen can have:

Code: Select all

	<ListOptions
		dataFrom=	"=(@ gData 'station)"
		list=		"*"
		/>
And the action to exit the screen can have:

Code: Select all

(enum (@ gData 'unidentifiedList) theItem (itmSetKnown theItem Nil))
Then the station just needs to be virtual. It doesn't need any code.

relanat
Militia Commander
Militia Commander
Posts: 438
Joined: Tue Nov 05, 2013 9:56 am

Sun Nov 05, 2017 8:35 am

Thanks, that is a much better way of doing it. It never occurred to me to put the code in the action. Then the same station can handle everything including any future features. Good stuff. One thing I was wondering is whether I need to destroy the stations after using them. If I'm doing a lot of testing I can use the item lists dozens of times. Do they build up and cause problems in any way?
NMS wrote:- It looks like you're passing searchTerm to the station as a global variable.
Yes, partly laziness because I use globals until I get code working . I was thinking of using scrSetData but wasn't sure if scrSetData info could be passed to a station or was restricted to inside screens (I never thought of the data argument of scrShowScreen option and will use that in the next version). Using trial and error to work this out chews up a lot of time and since the code was working any testing got shunted down the priority list. I'm going to open another topic on dockscreen sequencing and how to use scrSetData was one of the questions I was going to ask. Although you may see that function used in my code, it's usually just a cut and paste of other code; I'm still not sure of what it can do.

The "identify all' is deliberate. In V3 I've added another action in a previous screen where you can identify or unidentify all game items with one click. One of the annoying things about V2 was items came up as unidentified by default in the lists. It made finding a system map ROM, for example, difficult because the setKnown/Unknown action had to be performed for every unidentified ROM.
Now if I want a ROM, they will all appear as identified automatically making finding the right one easy and they can be set as unknown on the way out of the screens if that's what is needed.

NMS
Militia Commander
Militia Commander
Posts: 400
Joined: Tue Mar 05, 2013 8:26 am

Tue Nov 07, 2017 4:07 pm

relanat wrote:
Sun Nov 05, 2017 8:35 am
One thing I was wondering is whether I need to destroy the stations after using them. If I'm doing a lot of testing I can use the item lists dozens of times. Do they build up and cause problems in any way?
According to George, virtual stations cease to exist as soon as nothing is referencing them, so you shouldn't have to delete them manually. But you can check with (sysFindObject Nil 'tV).
relanat wrote:
Sun Nov 05, 2017 8:35 am
I was thinking of using scrSetData but wasn't sure if scrSetData info could be passed to a station or was restricted to inside screens (I never thought of the data argument of scrShowScreen option and will use that in the next version). Using trial and error to work this out chews up a lot of time and since the code was working any testing got shunted down the priority list. I'm going to open another topic on dockscreen sequencing and how to use scrSetData was one of the questions I was going to ask. Although you may see that function used in my code, it's usually just a cut and paste of other code; I'm still not sure of what it can do.
I just did some testing, and data set with scrSetData is available on any pane of the DockScreen that's open when it's set, as long as any DockScreen stays open. If a different DockScreen is shown, the data is unavailable, but will be restored if you return to the one where it was set. But if all DockScreens are closed, all data set on them is cleared. Passing a struct as the data argument to scrShowScreen seems to be the best way to get data from one screen to a different one. For more permanent data that persists with all screens closed, use objSetData or typSetData.
relanat wrote:
Sun Nov 05, 2017 8:35 am
The "identify all' is deliberate. In V3 I've added another action in a previous screen where you can identify or unidentify all game items with one click. One of the annoying things about V2 was items came up as unidentified by default in the lists. It made finding a system map ROM, for example, difficult because the setKnown/Unknown action had to be performed for every unidentified ROM.
Now if I want a ROM, they will all appear as identified automatically making finding the right one easy and they can be set as unknown on the way out of the screens if that's what is needed.
That's fine for a godmod, but I was pointing out that you could show them identified in the list, but not leave them permanently identified if they weren't before.

Post Reply