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

Io

So 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?


You 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

If 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

Nevermind, I had a typo in my dictionary name. Works now, thanks!


a 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)


If 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.


In 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))

This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums