Is it possible to use the Initialize element in DockScreen to hide inappropriate items in a list?
For example, when you go to a tinker station and ask for a 'custom job' you could remove all the items that cannot be made into anything useful.
Initialize element
- alterecco
- Fleet Officer
- Posts: 1658
- Joined: Wed Jan 14, 2009 3:08 am
- Location: Previously enslaved by the Iocrym
That can be done using the <ListOptions> element of itemPicker screens. There should be some examples of that in vanilla code. I think the armor repair screens use them to limit the items to only damaged ones. If not I think I have used it in godmod, via DSF. If you have any questions I would be happy to help, but after dinner 

Yes, but the List attribute where you set criteria does not allow you to include specific items - only select by item type, modifier, etc.alterecco wrote:That can be done using the <ListOptions> element of itemPicker screens.
- alterecco
- Fleet Officer
- Posts: 1658
- Joined: Wed Jan 14, 2009 3:08 am
- Location: Previously enslaved by the Iocrym
You do not control this in the list attribute, but inside the body of the element. Have a look at the dsExchangeBuy screen from Transcendence.xml line 2992
Basically what goes on is: You can use scrSetListFilter inside the the ListOptions body. It takes two arguments; the screen (always gScreen) and then a mixed argument (it can be a boolean, a criteria string and more). What you can do is pass it a function that takes one argument. This function will be called once for every item in the initial list (as controlled by the `list' attribute) and if the function returns true the item is included, else it is excluded.
Hope that makes sense
Basically what goes on is: You can use scrSetListFilter inside the the ListOptions body. It takes two arguments; the screen (always gScreen) and then a mixed argument (it can be a boolean, a criteria string and more). What you can do is pass it a function that takes one argument. This function will be called once for every item in the initial list (as controlled by the `list' attribute) and if the function returns true the item is included, else it is excluded.
Hope that makes sense
Well, I thought it did, but I still haven't quite got things working.alterecco wrote:Hope that makes sense
The following is what I tried sticking into ListOptions, but it doesn't display any items even when they should match (e.g. when I have Titanium ore in the cargo hold)
Any ideas?
Code: Select all
<ListOptions
dataFrom= "player"
list= "*U"
>
(block (thisItem itemUNID)
(setq thisItem (scrGetItem gScreen))
(setq itemUNID (itmGetUNID thisItem))
(setq gMargin (lambda Nil
(switch
(eq itemUNID &itTitaniumOre;)
True
(eq itemUNID &itHeavyWater;)
True
(eq itemUNID &itSiliconArmorPatch;)
True
(eq itemUNID &itCarbonSpool;)
True
(eq itemUNID &itPlasteelOre;)
True
(eq itemUNID &itHyperfiberRoll;)
True
(eq itemUNID &itDuralloyOre;)
True
(eq itemUNID &itReactiveArmor;)
True
(eq itemUNID &itCeralloyOre;)
True
(eq itemUNID &itOrthoSteelOre;)
True
(eq itemUNID &itClass1Deflector;)
True
(eq itemUNID &itClass2Deflector;)
True
(eq itemUNID &itSuperconductingCoil;)
True
(eq itemUNID &itLaserCannon;)
True
(eq itemUNID &itPartisanCannon;)
True
(eq itemUNID &itTurbolaserCannon;)
True
(eq itemUNID &itRadioactiveWaste;)
True
(eq itemUNID &itFusionTrigger;)
True
(eq itemUNID &itRepairingNanos;)
True
NIl
)
))
(scrSetListFilter gScreen gMargin)
)
</ListOptions>
Code: Select all
(block (thisItem itemUNID)
(setq thisItem (scrGetItem gScreen))
(setq itemUNID (itmGetUNID thisItem))
(setq gMargin (lambda Nil
(block (testWork foundPartial)
; Loop through our table looking to see if there
; is something that we can convert
(setq foundPartial Nil)
(enum (objGetStaticData gSource 'CustomWork) testWork
(block Nil
(if (eq (item testWork 0) (itmGetUNID gItem))
(setq foundPartial True)
)
) ; close block
)
)
foundPartial
))
(scrSetListFilter gScreen gMargin)
) ; close block
- alterecco
- Fleet Officer
- Posts: 1658
- Joined: Wed Jan 14, 2009 3:08 am
- Location: Previously enslaved by the Iocrym
You have to pass it a lambda, not a block. Like so:ptbptb wrote:Well, I thought it did, but I still haven't quite got things working.
Code: Select all
<ListOptions
dataFrom= "player"
list= "*U"
>
(scrSetListFilter gScreen (lambda (itm)
(block (whatever)
(if (something)
;; then True
True
;; else false
Nil
)
)
))
</ListOption>
Sorry to be a pest, but still not there (although hopefully closer). Where does 'itm' get defined? Is it automatically defined inside the ListOption element or something?
Anyway, this is what I've got now.
Anyway, this is what I've got now.
Code: Select all
(scrSetListFilter gScreen (lambda (itm)
(block (testWork foundPartial)
(setq thisItem (scrGetItem gScreen))
(setq itemUNID (itmGetUNID thisItem))
; Loop through our table looking to see if there
; is something that we can convert
(setq foundPartial Nil)
(enum (objGetStaticData gSource 'CustomWork) testWork
(if (eq (item testWork 0) (itmGetUNID gItem))
(setq foundPartial True)
)
)
foundPartial
)
))
- alterecco
- Fleet Officer
- Posts: 1658
- Joined: Wed Jan 14, 2009 3:08 am
- Location: Previously enslaved by the Iocrym
After reading your post again I realised I perhaps should have used your example for explaining, and actually answered your question
I will leave my original post below intact
`itm' is defined in the lambda as the name of the arguement passed in. When the list is filtered the engine passes each item to this lambda, so whichever lambda you use for the filter, must take at least one argument.
This is how I would write your function
====================================================
Original Post
Hmm, ok... Let me see how I can explain this properly.
If the argument to scrSetListFilter is a lambda (a function, but let us just call them lambdas), then that lambda will be called once for each item in the list, with the item as it's argument
Let us take an example. In this dockscreen I only want uninstalled enhanced weapons to show up. I will use the built in (itmIsEnhanced item) -> Nil or mods lambda for testing this:
Here, the `list' attribute limits the list to uninstalled weapons, and since I set the ListFilter (by using scrSetListFilter) to a lambda, this lambda will be called over and over again for each uninstalled weapon, and only return Non-Nil on weapons that are enhanced. Thus, the final item list will only contain enhanced uninstalled weapons.
Let us try another example, where we build the lambda ourselves. For example if I want to show all items on a station produced by Makayev or Bushido. I will spell the code out a bit more than I would normally.
Now our homemade lambda will do all the hard work of weeding out unwanted items from the final list. The version I would actually use looks like this
I hope that it makes sense now 

`itm' is defined in the lambda as the name of the arguement passed in. When the list is filtered the engine passes each item to this lambda, so whichever lambda you use for the filter, must take at least one argument.
This is how I would write your function
Code: Select all
(scrSetListFilter gScreen (lambda (itm)
(block (found)
(enumWhile (objGetStaticData gSource 'CustomWork) (not found) work
(if (eq (item work 0) (itmGetUNID itm)) (setq found True))
)
found
)
))
====================================================
Original Post
Hmm, ok... Let me see how I can explain this properly.
If the argument to scrSetListFilter is a lambda (a function, but let us just call them lambdas), then that lambda will be called once for each item in the list, with the item as it's argument
Let us take an example. In this dockscreen I only want uninstalled enhanced weapons to show up. I will use the built in (itmIsEnhanced item) -> Nil or mods lambda for testing this:
Code: Select all
<ListOptions
dataFrom="player"
list="*wU"
>
(scrSetListFilter gScreen itmIsEnhanced)
</ListOptions>
Let us try another example, where we build the lambda ourselves. For example if I want to show all items on a station produced by Makayev or Bushido. I will spell the code out a bit more than I would normally.
Code: Select all
;; first we define the lambda we will use for the list filter.
;; It takes one argument: the current item being queried for
;; inclusion in the final list
(setq itmIsMakayevOrBushido (lambda (itm)
(block (affirmative)
(if (or (itmHasAttribute itm "Makayev")
(itmHasAttribute itm "Bushido")
)
;; item has one of the two modifiers
(setq affirmative True)
;; item has none of the modifiers
(setq affirmative Nil)
)
)
))
;; now we use this function inside of the ListOptions tag...
;; so imagine the following is inside a DockScreen somewhere
<ListOptions
dataFrom="station"
list="*"
>
(scrSetListFilter gScreen itmIsMakayevOrBushido)
</ListOptions>
Code: Select all
<ListOptions
dataFrom="station"
list="*"
>
(scrSetListFilter gScreen (lambda (itm) (or (itmHasAttribute itm "Makayev") (itmHasAttribute itm "Bushido"))))
</ListOptions>

The 'lambda' thing is one of the points I struggle most with in tscript. I shall probably come back to read this several times in the future.
Anyway, thanks very much on behalf of myself an any other confused would-be modder who finds this thread.

Anyway, thanks very much on behalf of myself an any other confused would-be modder who finds this thread.
- alterecco
- Fleet Officer
- Posts: 1658
- Joined: Wed Jan 14, 2009 3:08 am
- Location: Previously enslaved by the Iocrym
A lambda is just a function definition. It wraps a piece of code for later execution:
You can pass arguments to lambdas, just like other languages allow you to.
Code: Select all
(dbgOutput "I will run immediately")
;; vs
(setq runIt (lambda Nil (dbgOutput "I will not run until I am called")))
;; to call the above lambda, use parentheses
(runIt)
Code: Select all
;; let us define a lambda that takes one argument
(setq myLambda (lambda (arg)
(dbgOutput "I was passed the argument: " arg)
))
;; call the lambda with one argument
(myLambda "I am the value being passed")
;; call it again, just for fun
(myLambda (cat 42 "The result of the cat will be the value passed"))