0 votes
by (220 points)

First: I guess the title might be somewhat misleading but I didn't know how to phrase it short. 

I'm patching together an inventory and settled for:

<<set $waffen to {
    Pistole01 : {
				typ: "Pistole", 
				name: "name 1", 
				cost: 64,
				has: false,
				description: "Text 1"
    Gewehr01 : {
				typ: "Gewehr", 
				name: "name 2", 
				cost: 122,
				has: false,
				description: "Text 2"
	Pistole02 : {
				typ: "Pistole", 
				name: "name 3", 
				cost: 342,
				has: false,
				description: "Text 3"

To print it in the inventory passage I use: 

<<set $tmpKeys to Object.keys($waffen)>>
<<for $i to 0; $i lt $tmpKeys.length; $i++>>
	<<if $waffen[$tmpKeys[$i]].has is false>>
		<<print $waffen[$tmpKeys[$i]].typ>>
		<<print $waffen[$tmpKeys[$i]].name>>
		<<print $waffen[$tmpKeys[$i]].cost>>
		<<print $waffen[$tmpKeys[$i]].has>>
<<unset $tmpKeys>>

Works fine. Now I'd like the name to be clickable. A new window (I tried dialog and ui.alert) should open and display the items description.

<<print $waffen[$tmpKeys[$i]].description>>

Any chance thats somehow possible in an easy way? My coding knowledge is basically 0 so just to get to this point took me lot of copy/pasting different kinds of code snippets to make it work. 

Thanks for any help in advance!


1 Answer

+1 vote
by (159k points)
selected by
Best answer

Your issue can be broken down into to tasks:

1. Display a link that opens a Alert or Dialog containing some text.
This is fairly simple to do using the <<link>> macro and the <<run>> macro, along with the relevant UI API or Dialog API functions. 

<<link `link text`>>
	<<run UI.alert("content to display inside the alert")>>\


<<link `link text`>>
	<<run Dialog.wiki("content to display inside the dialog").open()>>\

2. Getting the alert / dialog to show the description of the correct item.

Because the body of a interactive macro like <<link>> doesn't get processed until after the related link is selected any variables referenced within that body will equal the values they have at the time of the selection. This can be an issue when the link in question was created within a looping process like that of the <<for>> macro and if that link's body references one of the loop's variables, because by the time the link is selected the related variables will equal the current values they had at the end of the looping process.

eg. If each of your link bodies references the $i variable in your example then when any of those links are selected the current value of $i will always equal the same value as $tmpKeys.length which should be 3 in your example.

To overcome this issue you need to use the <<capture>> macro to capture the current values of the relevant variables at the time the <<link>> macro is being processed to create the link.

<<capture $variable>>\
	<<link "link text">>\
		<<run UI.alert($variable)>>\


So an updated version of your original loop process example could look something like the following:

<<set _keys to Object.keys($waffen)>>
<<for _i to 0; _i lt _keys.length; _i++>>
	<<set _item to $waffen[_keys[_i]]>>
	<<if not _item.has>>
		<<print _item.typ>>
		<<capture _item>>\
			<<link `_item.name`>>\
				<<run UI.alert(_item.description)>>\
		<<print _item.cost>>
		<<print _item.has>>

a. I replaced your temporary story variables with actual temporary variables, this way you don't need to remember to <<unset>> them.
b. I have modified the has property Boolean check so that it is more correct.
c. I added a new _item temporary variable so that the code didn't need to keep looking up the object referenced by the $waffen[$tmpKeys[$i]] expression.
d. I am capturing the current item object instead of just the value of the description property in case you want to display other properties of that object within the Alert / Dialog.

by (220 points)
I'm going to have a more in-depth look into the capture macro to understand, what exactly is going on here. But this works great though.

Your answers on this and on numerous other topics helped me in the past a lot. Thank you very much!