What I would like to do would be to implement a filter function such as "scrSetListFilter" or "filter" such that the dock screen would only show items from the master list that match a set of criteria defined in the action in which the dockscreen is called up.
From how I understand it (1), once properly implemented the "scrSetListFilter" function would let the dock screen process the entire list but it would only show the items that match the criteria. My problem with it is that from how I understand it, the Tinker's Guild recipe list that my recipe list is based on is actually a list of lists and I have now idea as to where I should slap on this function to get my idea to work. The only places where I saw this function used in vanilla Transcendence were when it was applied to lists of items generated from the contents of stations or the playership using the <ListOptions> block, and since the Tinker's guild dock screen that I am abusing to create my modified version implements a <List> block instead I have no idea if the function can even be implemented.
From how I understand it (2), once properly implemented the "Filter" function would change which parts of the list the dock screen actually processes and is therefore too complicated for me to even consider using. Also I currently have no idea what exactly the @ and ' symbols do, although I believe using the ' symbol before a variable has something to do with defining it as containing a list or something.
Also, my mod currently has two separate versions for whether or not you have Corporate Command installed. I did this because both versions define the Cabbage Corp sovereign and since I based the recipe lists off of the Tinker's Guild, the recipe lists are defined in the sovereign. I have no idea how to be sure of which version of the sovereign will take precedence if it is defined in both extensions and they are loading at the same time, and I have no idea how to make the Corporate Command version (Cabbage Corporate Command) merely append items to the recipe list without having to define the sovereign.
Any help with either of the issues would be appreciated. I have included copies for the parts of the code for calling up the dock screen and the dock screen itself (which is mostly a copy of the Tinker's custom work dock screen with the mission part removed because I did not want to deal with that). After this dock screen is finished, I would have no problems with setting it up as a fancy library/tutorial of its own and putting on Xelerus for anyone to use freely. I would also have no problems with someone else doing this, and long as credit was given to all those involved, which is what I would do if I uploaded it, which I would be hesitant to do as I am slightly OCD and have already spent one hour and forty minutes creating this post, which seems way too long compared to the 4-5 hours I spent trying to solve this problem on my own.
TLDR: I am trying to set up one custom work dock screen to rule them all. My current version involves allowing the specific recipe list to be defined in the action in which the dock screen is called up, but I would also like to be able to pass through criteria to the dock screen from the action, and use those criteria to filter the custom work screen to only show items that match those criteria such as the level of the item and whether or not it is tagged as illegal or military. Any help would be appreciated. Posting a working alternative of this dock screen with these features and a whole bunch of other random bells and whistles would also be appreciated. Please help me.
Code: Select all
<Action name="Custom Weapons" key="W">
(block Nil
(setq gSovereign &svCCCabbageCorp;)
(setq gRecipes 'WeaponRecipes)
(scrShowScreen gScreen "&dsCCCabbageCustomWork;")
)
</Action>
<Action name="Custom Armor" key="A">
(block Nil
(setq gSovereign &svCCCabbageCorp;)
(setq gRecipes 'ArmorRecipes)
(scrShowScreen gScreen "&dsCCCabbageCustomWork;")
)
</Action>
Code: Select all
<DockScreen UNID="&dsCCCabbageCustomWork;"
type= "customItemPicker"
backgroundID= "&rsItemListScreen;"
nestedScreen= "true"
>
<List>
(map (typGetData gSovereign gRecipes) 'excludeNil theRecipe
(tinkerCreateItem theRecipe 1)
)
</List>
<Panes>
<Default>
<OnPaneInit>
(block (theItem theRecipe theComponents desc componentDesc componentPrice workCost errorDesc missingComponents maxCount availableComponents)
(setq theItem (scrGetItem gScreen))
; Find the recipe for this item
(setq theRecipe
(@ (filter (typGetData gSovereign gRecipes) theRecipe
(eq (@ theRecipe 'item) (itmGetType theItem))
)
0
)
)
; Describe the components needed
(setq theComponents
(map (@ theRecipe 'components) theDesc
(itmCreate (@ theDesc 'item) (@ theDesc 'count))
)
)
(setq componentDesc (strItemList theComponents 0x0108))
; Compute the total price of the components and compare to the
; price of the result.
(setq componentPrice
(map theComponents 'reduceSum theComponent
; For devices we assume a damaged device
(if (itmMatches theComponent "d")
(multiply (itmGetCount theComponent) (itmGetPrice (itmSetProperty theComponent 'damaged True)))
(multiply (itmGetCount theComponent) (itmGetPrice theComponent))
)
)
)
; The total cost of the work compensates for any difference between
; the input and output prices.
(setq workCost
(add
(max
50
(intRoundUp (subtract (itmGetPrice theItem) componentPrice) 25)
)
(@ theRecipe 'extraCost)
)
)
; For each required component, add up the number of items the player
; actually has. Note that we accept damaged items.
(setq availableComponents
(map theComponents theComponent
(block (countAvailable)
(setq countAvailable 0)
; Add the number of non-damaged items we have
(setq countAvailable (add countAvailable
(objHasItem gPlayerShip theComponent 1)
))
; Now add damaged items
(setq countAvailable (add countAvailable
(objHasItem gPlayerShip (itmSetProperty theComponent 'damaged True) 1)
))
; Compose entry
{ item: theComponent
available: countAvailable
}
)
)
)
; Generate a list of the number of items the player is missing.
; Note that we accept damaged items.
(setq missingComponents
(map availableComponents 'excludeNil theEntry
(block (countAvailable)
(switch
(eq (@ theEntry 'available) 0)
(cat "\n\nUnfortunately, you do not have any " (itmGetName (@ theEntry 'item) 0x102) ".")
(ls (@ theEntry 'available) (itmGetCount (@ theEntry 'item)))
(cat "\n\nUnfortunately, you only have " (itmGetName (itmSetCount (@ theEntry 'item) (@ theEntry 'available)) 0x1100) ".")
; Otherwise we have enough, so these items are not missing
Nil
)
)
)
)
; See if the player has the required components and money
(switch
missingComponents
(block Nil
(setq maxCount 0)
(setq errorDesc (@ missingComponents 0))
)
(leq (plyGetCredits gPlayer) workCost)
(block Nil
(setq maxCount 0)
(setq errorDesc "\n\nUnfortunately, you cannot afford the cost.")
)
(block Nil
; Figure out the maximum number of items we could create
(setq maxCount (divide (plyGetCredits gPlayer) workCost))
(enum availableComponents theEntry
(setq maxCount (min
maxCount
(divide (@ theEntry 'available) (itmGetCount (@ theEntry 'item)))
))
)
(setq errorDesc "")
)
)
; Set the description
(switch
(not componentDesc)
(scrSetDesc gScreen
"\"To fabricate " (itmGetName theItem 0x0108) " we charge " workCost " credits."
errorDesc
"\""
)
(scrSetDesc gScreen
"\"To fabricate " (itmGetName theItem 0x0108) " we need "
componentDesc
" plus " workCost " credits."
errorDesc
"\""
)
)
; Remember the recipe, the components, and the cost for later
(scrSetData gScreen 'recipe theRecipe)
(scrSetData gScreen 'components theComponents)
(scrSetData gScreen 'cost workCost)
(scrSetData gScreen 'maxCount maxCount)
; Disable Fabricate action if we can't do it
(scrEnableAction gScreen 0 (gr maxCount 0))
)
</OnPaneInit>
<Actions>
<Action name="Fabricate" default="1" key="F">
(if (gr (scrGetData gScreen 'maxCount) 1)
(scrShowPane gScreen "FabricateCount")
(block Nil
(scrSetData gScreen 'result
(tinkerFabricate
(scrGetData gScreen 'recipe)
(scrGetData gScreen 'cost)
1
)
)
(scrShowPane gScreen "FabricateResult")
)
)
</Action>
<Action name="Done" cancel="1" key="D">
(scrExitScreen gScreen)
</Action>
</Actions>
</Default>
<FabricateCount
showCounter= "true"
>
<OnPaneInit>
(block Nil
(scrSetDesc gScreen (cat "How many items do you wish to fabricate?"))
(scrSetCounter gScreen (scrGetData gScreen 'maxCount))
)
</OnPaneInit>
<Actions>
<Action name="Fabricate" default="1" key="F">
(block (count)
(setq count (scrGetCounter gScreen))
(if (gr count (scrGetData gScreen 'maxCount))
(scrSetCounter gScreen (scrGetData gScreen 'maxCount))
(block Nil
(scrSetData gScreen 'result
(tinkerFabricate
(scrGetData gScreen 'recipe)
(scrGetData gScreen 'cost)
count
)
)
(scrShowPane gScreen "FabricateResult")
)
)
)
</Action>
<Action name="Cancel" cancel="1" key="C">
(scrShowPane gScreen "Default")
</Action>
</Actions>
</FabricateCount>
<FabricateResult
noListNavigation="true"
>
<OnPaneInit>
(block (theResult)
(setq theResult (scrGetData gScreen 'result))
(scrSetDesc gScreen
"After much work with the robots the technician returns with their creation: "
"\"Nothing to it once you know how these machines work.\"\n\n"
"Fabricated: " (itmGetName (@ theResult 'itemsCreated) 0x08) ".\n"
"Consumed: " (strItemList (@ theResult 'itemsConsumed) 0x08) ".\n"
"Total Cost: " (@ theResult 'totalCost) " credits."
)
)
</OnPaneInit>
<Actions>
<Action name="Done" default="1" cancel="1" key="D">
(scrExitScreen gScreen)
</Action>
</Actions>
</FabricateResult>
</Panes>
</DockScreen>