Script Dictionaries: Explain them like I'm Retarded [Solved]

Io
04 Mar 2019, 21:53So I can sort of understand String Dictionaries. I say Player.Status="Hurt", and Player.StatusDict says "Hurt" corresponds to "You are very hurt and need shelter."
So I say:
"Print Player.StatusDict, Hurt"
and I get
"You are very hurt and need shelter."
But I want to be able to say that for ANYONE. Companion1.Status="Hurt" should say "He is very hurt and needs shelter".
But the problem here is, I have Companion1 able to be either Male or Female. So I thought I'd use a Script Dictionary, and have the key "Hurt" go to the script:
msg(Companion1.CustomCapitalizedGender+" is very hurt and needs shelter.")
Which SHOULD then print He/She is very hurt, depending on what it is.
But nothing I do seems to work. Return doesn't work, print doesn't work, any combination I try results in a slew of creative error messages. I can't seem to figure out what 'Run an object's script attribute' and 'Run a script returned by an expression' want from me, PARTICULARLY in their 'Using Parameter Dictionary' slot.
Help?
The Pixie
04 Mar 2019, 22:04You may be making it more complicated than it is. Why not just have a "hurt_response" script attribute for all your characters, and just run that:
do(npc, "hurt_response")
To run a script from a script dictionary:
scr = ScriptDictionaryItem(npc.script_dictionary, "hurt")
invoke(scr)
Note that return
does not work in a script; scripts do not return a value.

Io
04 Mar 2019, 23:51If there was only "Hurt" I'd agree, but if I add others - "Channeling Magic", "Sleeping", "On Fire" etc - then I don't want to go through each and add a new response. I can just go to a Master Dictionary and add the key there.
I'm also getting the error:
ScriptDictionaryItem function expected dictionary parameter but was passed 'null'

Io
05 Mar 2019, 00:09Nevermind, I had a typo in my dictionary name. Works now, thanks!
hegemonkhan
05 Mar 2019, 04:16a bit late, but here's how lists and dictionaries work:
Both Lists and Dictionaries, are basically input-output functionality
for both Lists and Dictionaries, in the GUI/Editor and/or directly in code:
the 'input' is also known as its 'key': input <---> key
the 'output' is also known as its 'value': output <---> value
for Lists, I think, quest is able to automatically handle/convert an Integer into a String, for its String Inputs (so, you can just input an integer number, example: 0, you don't have to have it as a string number, example: "0")
String List:
Item:
String Input: "INDEX_NUMBER"
String Output: "WHATEVER"
Object List:
Item:
String Input: "INDEX_NUMBER"
Object Output: WHATEVER_OBJECT_REFERENCE_POINTER
String Dictionary:
Item:
String Input: "WHATEVER"
String Output: "WHATEVER"
Object Dictionary:
Item:
String Input: "WHATEVER"
Object Output: WHATEVER_OBJECT_REFERENCE_POINTER
Script Dictionary:
Item:
String Input: "WHATEVER"
Script Output: [WHATEVER_SCRIPT/S]
notice that the only difference between Lists and Dictionaries (aside from Lists not being able to return Script/s), is that the index numbering is automatically/forcedly created for its String Inputs, whereas for Dictionaries, the String Inputs are custom, you can have them as whatever you want:
Lists start with '0' as its first item's index number, and NOT '1', so the last Item's index number is always: ListCount (LIST) - 1, for example, a List having 3 items, with its 3rd/last item's index number, thus being '2'
List:
Item1:
String Input: "0"
String/Object Output: "WHATEVER_String"/WHATEVER_OBJECT_REFERENCE_POINTER
item2:
String Input: "1"
String/Object Output: "WHATEVER_String"/WHATEVER_OBJECT_REFERENCE_POINTER
item3:
String Input: "2"
String/Object Output: "WHATEVER_String"/WHATEVER_OBJECT_REFERENCE_POINTER
Dictionary:
Item1:
String Input: "WHATEVER"
String/Object/Script Output: "WHATEVER_String"/WHATEVER_OBJECT_REFERENCE_POINTER/WHATEVER_SCRIPT-S
item2:
String Input: "WHATEVER"
String/Object/Script Output: "WHATEVER_String"/WHATEVER_OBJECT_REFERENCE_POINTER/WHATEVER_SCRIPT-S
item3:
String Input: "WHATEVER"
String/Object/Script Output: "WHATEVER_String"/WHATEVER_OBJECT_REFERENCE_POINTER/WHATEVER_SCRIPT-S
to then do the input-output functionality of Lists and Dictionaries:
(you don't need to store the return value, the OUTPUT, into a VARIABLE, if you're using it directly within another Function/Script, but you got to do something with the returned value: storing it into a VARIABLE or using it directly within another Function/Script, else I hope quest does return/produce an error, as you don't want floating/in-accessable values/wasted-lost-memory)
VARIABLE = ListItem (LIST, INPUT)
// VARIABLE <=== [ OUTPUT <=== ListItem (LIST, INPUT) ]
// VARIABLE = OUTPUT
VARIABLE = StringListItem (STRINGLIST, INPUT)
// VARIABLE <=== [ STRING_OUTPUT <=== StringListItem (STRINGLIST, INPUT) ]
// VARIABLE = STRING_OUTPUT
VARIABLE = ObjectListItem (OBJECTLIST, INPUT)
// VARIABLE <=== [ OBJECT_REFERENCE_POINTER_OUTPUT <=== ObjectListItem (OBJECTLIST, INPUT) ]
// VARIABLE = OBJECT_REFERENCE_POINTER_OUTPUT
VARIABLE = DictionaryItem (DICTIONARY, INPUT)
// VARIABLE <=== [ OUTPUT <=== DictionaryItem (DICTIONARY, INPUT) ]
// VARIABLE = OUTPUT
VARIABLE = StringDictionaryItem (STRINGDICTIONARY, INPUT)
// VARIABLE <=== [ STRING_OUTPUT <=== StringDictionaryItem (STRINGDICTIONARY, INPUT) ]
// VARIABLE = STRING_OUTPUT
VARIABLE = ObjectDictionaryItem (OBJECTDICTIONARY, INPUT)
// VARIABLE <=== [ OBJECT_REFERENCE_POINTER_OUTPUT <=== ObjectDictionaryItem (OBJECTDICTIONARY, INPUT) ]
// VARIABLE = OBJECT_REFERENCE_POINTER_OUTPUT
VARIABLE = ScriptDictionaryItem (SCRIPTDICTIONARY, INPUT)
// VARIABLE <=== [ SCRIPT-S_OUTPUT <=== ScriptDictionaryItem (ScriptDICTIONARY, INPUT) ]
// VARIABLE = SCRIPT-S_OUTPUT
you can then use 'invoke', to run/do the returned Script/s:
invoke (VARIABLE)
// or:
invoke (VARIABLE, ANOTHER_DICTIONARY_IN_WHICH_ITS_INPUTS_ARE_USED_AS_PARAMETERS_AND_ITS_OUTPUTS_AS_ITS_ARGUMENTS_BOTH_FOR_WITHIN_THE_INVOKE'S_SCRIPTING)
The Pixie
05 Mar 2019, 09:58If there was only "Hurt" I'd agree, but if I add others - "Channeling Magic", "Sleeping", "On Fire" etc - then I don't want to go through each and add a new response. I can just go to a Master Dictionary and add the key there.
If you are using the desktop version, you could create a new type with all these defined. You could then create sub-types with alternative versions, so the fire imp's "On Fire" does something quite different to the the standard script. Want to add a new response? Just add it to the type, and every object that inherits from it gets it automatically.
http://docs.textadventures.co.uk/quest/using_inherited_types.html
Just a suggestion; script dictionaries may be better for what you are doing.
mrangel
05 Mar 2019, 15:19In this case, I'd suggest using a string dictionary. You could then do something like:
msg(Eval(DictionaryItem(character.StatusDict, character.Status), QuickParams("this", character))
Then the dictionary could contain a simple string like: "You are tired and need rest."
, or an expression such as: CapFirst(WriteVerb(this, "be"))+" is very hurt and needs shelter."
I've found that it's often better to have a stringdictionary passed through eval
for things like that, because you really want an expression rather than a script.
Or, for that example, you could use the text processor rather than eval. Make StatusDict a stringdictionary with values like: {=CapFirst(WriteVerb(this, "be"))} is very hurt and needs shelter.
In which case the code to display it would be something like:
game.text_processor_this = Companion1
msg (DictionaryItem (Companion1.StatusDict, Companion1.Status))