I've got a couple of mods that produce full or partial system lists in custompicker screens. I'm trying to set the cursor to come up on the current system when you go to the screen for the first time, eg if you are in Sanctuary have the cursor appear on the Sanctuary listing rather than defauting to Eridani or the top of the list all the time.
The functions are easy enough. 'scrSetListCursor' and 'find'. I can reset the position with the debug screen. Remembering the cursor position is easy too and there are examples of doing this in some of the mods.
The only result I've had is using the code in <OnPaneInit> but this just locked the cursor in the one position no matter what happened. Apparently <OnPaneInit> is used on every cursor movement.
I've tried a number of the dockscreen <OnWhicheverInitiailizeEtc> areas with no success (but can't rule out coding errors).
Does anyone know where the code should go? Or if its possible at all? TIA.
Setting cursor position in system list first appearance
Yes. <ListOptions> can have the attribute initialItem, which is set to a TLisp script. The game iterates through the items on the list, and the first one for which the script returns True will be selected. If none return True, the last item will be selected, though I opened a ticket suggesting it should default to the first one instead.
Note that because it's inside an XML attribute, the code has to be surrounded by quotes and thus can't contain the same type of quotes. However, you can use the other type of quotes (single inside, double outside, or maybe vice versa), or I think you can escape the quotes in the code by putting a backslash in front.
Here's an example from AutonBay.xml:
Those who are familiar with the auton bay will know this doesn't always work there, but that's due to unrelated bugs.
Note that because it's inside an XML attribute, the code has to be surrounded by quotes and thus can't contain the same type of quotes. However, you can use the other type of quotes (single inside, double outside, or maybe vice versa), or I think you can escape the quotes in the code by putting a backslash in front.
Here's an example from AutonBay.xml:
Code: Select all
<DockScreen UNID="&dsAutonBay;"
type= "itemPicker"
backgroundID= "&rsItemListScreen;"
>
<ListOptions
dataFrom= "player"
list= "* +auton;"
initialItem="
(or
(not (scrGetData gScreen 'currentAuton))
(itmIsEqual (scrGetItem gScreen) (scrGetData gScreen 'currentAuton))
)"
/>
Got it. So easy (relatively ) when you know how!
Final code:
'rowHeight="32" puts about a dozen system names on the one dockscreen, compared to 4 or 5 with full size rows, which makes it a bit quicker to scroll down.
The code is duplicated outside of 'initialItem' because un'block'ing galaxyTravelList made the list add on every time you entered the dockscreen.
And I didn't need to get system names in the 'intialItem' area, nodes would have done, but the code was there so 'copy and paste' was easier.
Many thanks, NMS. I never would have found this on my own.
Final code:
Code: Select all
<Dockscreen UNID="&dsD789GodTravelGalaxyDockscreen;"
name= "Galaxy Travel"
type= "customPicker"
nestedScreen= "true"
>
<List
rowHeight="32"
initialItem="= (block (systemList nameList galaxyTravelList currentSystemName systemListPos)
(setq systemList (sysGetNodes))
(enum systemList nameList (setq galaxyTravelList (lnkAppend galaxyTravelList (sysGetProperty nameList 'name))))
(setq currentSystemName (sysGetName (sysGetNode)))
(setq systemListPos (find galaxyTravelList currentSystemName))
(scrSetListCursor gScreen systemListPos)
)
"
>
(block (systemList nameList galaxyTravelList)
(setq systemList (sysGetNodes))
(enum systemList nameList (setq galaxyTravelList (lnkAppend galaxyTravelList (sysGetProperty nameList 'name))))
)
</List>
The code is duplicated outside of 'initialItem' because un'block'ing galaxyTravelList made the list add on every time you entered the dockscreen.
And I didn't need to get system names in the 'intialItem' area, nodes would have done, but the code was there so 'copy and paste' was easier.
Many thanks, NMS. I never would have found this on my own.
Stupid code. Do what I want, not what I typed in!
That statement sums up my modding. I really don't know how to write code. And the lack of documentation doesn't help along with being offline most of the time so IRC is out. I could only find three examples of 'initialItem' use so just kept trying stuff based on that until it worked.NMS wrote:Well, I'm glad it works, though I'm a bit confused about how.
All I do is copy someone else's code and modify it to do what I want. If there's nothing available I search the functionlist to find a function that sounds like it might do the job and give that a go. It's incredibly time-consuming but gets the job done in the end. Along with dozens of 'help please' forum topics.
I try to add numerous comments to my mods to help new modders but there is a real worry that I'm getting it wrong or making it much harder than it needs to be, thereby leading people astray.
But it is fun so that makes up for a lot of things.
Thanks again for your help, and everyone else as well.
Stupid code. Do what I want, not what I typed in!
Yes, there is indeed easier code.
This is a modified copy of the 'initialItem' code in &dsRPGRepairArmor; in RPGCompatibility.xml. It uses the system name instead of armor segment info. Confusing layout though.
is the same I think. I still don't get it though.
Code: Select all
initialItem="=(block (
(desiredName (sysGetProperty (sysGetNode) 'name))
(name (scrGetListEntry gScreen))
)
(or (not desiredName) (eq name desiredName))
)"
Code: Select all
(block (desiredName name)
(setq desiredName (sysGetProperty (sysGetNode) 'name))
(setq name (scrGetListEntry gScreen))
(or (not desiredName)(eq name desiredName)
)
Stupid code. Do what I want, not what I typed in!
Yeah, that looks good. The game selects each entry in the itemPicker one at a time and runs the initialItem code. When the code returns true, it stops and leaves that item selected. So that code returns true if the name of the item matches the name of the current system, or the current system has no name for some reason (so in that case the first item is selected instead of the last one).
Got it now, thanks. '(not "Lacaille")' returns Nil. So does any system name. I was thinking that '(not "Lacaille")' was True because I wanted the current system selected, but the code isn't checking the current system there, its only checking for True/Nil. (Note to self; must think more like a machine.)
I think that's so there is always a True value in there to have the first entry selected by default (to counter the "select last entry if no True value" condition of the code). Because having the last entry selected wouldn't match everything else in the game.
The following 'eq' code is then free to choose the current system.
Thanks for that. This will help in other mods as well.
I think that's so there is always a True value in there to have the first entry selected by default (to counter the "select last entry if no True value" condition of the code). Because having the last entry selected wouldn't match everything else in the game.
The following 'eq' code is then free to choose the current system.
Thanks for that. This will help in other mods as well.
Stupid code. Do what I want, not what I typed in!