Using String Dictionaries

KiraxSummers
21 Mar 2013, 05:07Heya everybody,
I'm Kira, nice to meet'cha! I've been using Quest for a few weeks now, registered recently. It's a whole lot of fun
I try to figure things out for myself as much as I can (I have some programming knowledge with C++ but not much else) but I've run into a brick wall. This will sound like a dumb question but I couldn't find an answer anywhere T_T So, on to the actual problem,
I have an npc object. I've given this npc an attribute called "conversation" of the type "String Dictionary". Now, every time the user speaks to this npc, I want to print a random string from this dictionary. Can I do that? I can't seem to access the strings one by one based on key number. And, obviously, printing the expression: npc.conversation will print every dictionary item. If there's another thread that answers this question, I'm really sorry, I must have missed it. But a link would be nice ^_^;
Thanks in advance!
-Kira Summers
I'm Kira, nice to meet'cha! I've been using Quest for a few weeks now, registered recently. It's a whole lot of fun

I try to figure things out for myself as much as I can (I have some programming knowledge with C++ but not much else) but I've run into a brick wall. This will sound like a dumb question but I couldn't find an answer anywhere T_T So, on to the actual problem,
I have an npc object. I've given this npc an attribute called "conversation" of the type "String Dictionary". Now, every time the user speaks to this npc, I want to print a random string from this dictionary. Can I do that? I can't seem to access the strings one by one based on key number. And, obviously, printing the expression: npc.conversation will print every dictionary item. If there's another thread that answers this question, I'm really sorry, I must have missed it. But a link would be nice ^_^;
Thanks in advance!
-Kira Summers
sonic102
21 Mar 2013, 06:12Take a look at this: http://quest5.net/wiki/StringDictionaryItem
You'll need to use Code View, which is easier in 5.4 Beta, but there should be a GUI item I missed.
You'll need to use Code View, which is easier in 5.4 Beta, but there should be a GUI item I missed.

KiraxSummers
21 Mar 2013, 07:53Hi Sonic and thanks for looking in!
Okay, the StringDictionaryItem function. I've tried that. I did try again though.
And this is what the npc object looks like now:
But it gives me the error :
Error running script: FunctionCallElement: Could find not function 'StringDictionaryItem(QuestDictionary`1, Int32)'
Which is pretty baffling... Am I doing something wrong?
Gosh this should be so simple, I must be missing something tiny...
Okay, the StringDictionaryItem function. I've tried that. I did try again though.
And this is what the npc object looks like now:
<object name="npc">
<inherit name="editor_object" />
<conversation type="stringdictionary">1 = A;2 = B;3 = C</conversation>
<speak type="script">
msg (StringDictionaryItem (npc.conversation , GetRandomint (1,3)))
</speak>
</object>
But it gives me the error :
Error running script: FunctionCallElement: Could find not function 'StringDictionaryItem(QuestDictionary`1, Int32)'
Which is pretty baffling... Am I doing something wrong?
Gosh this should be so simple, I must be missing something tiny...
HegemonKhan
21 Mar 2013, 08:06I'm still using quest version 5.3, and so v5.4 changes the format~syntax slightly on how to write out the code for lists and dictionaries. This is easy enough to look up, if not, then ask, hehe.
Also, I'm going to be telling you how to do this via code, so, if you want help in the gui~editor, let me know, and I'll try to help you with doing it via that way too.
----------------------------
so, you can get to the game code in two different ways:
from the gui~editor, click on the notepaper like button at the top, it's the button between the play and ? (help) buttons
this notepaper button, is a toggle button, switching between the gui~editor mode and the code view mode.
~OR~
you can just open up your game (or library) file, using notepad, notepad++, or wordpad
-----------------------------
here's some links:
http://quest5.net/wiki/Main_Page
http://quest5.net/wiki/How_to
http://quest5.net/wiki/Conversations
http://quest5.net/wiki/Dynamic_Menus_for_Conversations
http://quest5.net/wiki/Random_default_answers
http://quest5.net/wiki/Unlockdoor
http://quest5.net/wiki/Category:All_Fun ... t_Commands
http://quest5.net/wiki/Using_Lists
http://quest5.net/wiki/Using_Dictionaries
viewtopic.php?f=10&t=3444
viewtopic.php?f=10&t=3439
viewtopic.php?f=10&t=3435
--------------------
the code is: GetRandomInt (min_value,max_value)
http://quest5.net/wiki/GetRandomInt
so for example: GetRandomInt (1,5)
I think that maybe this code can't start from 0, so you'll have to do this to get it to start from 0: GetRandomInt (1,6) - 1
which does this:
[ selected random integer from GetRandomInt (1,5) ] and then [ - 1 ] and finally = [ resulting value after the subtraction ]
1 - 1 = 0
2 - 1 = 1
3 - 1 = 2
4 - 1 = 3
5 - 1 = 4
6 - 1 = 5
now, for lists and dictionaries, each item is enumerated, but it starts from 0, thus why we needed to do the above, of: GetRandomInt (1,6) - 1
Lists:
stringlist is known~used as just: list
objectlist
Dictionaries:
stringdictionary
objectdictionary
scriptdictionary
so for example, using a stringdictionary:
key ~ value ~ enumeration count
sword ~ message1 ~ 0
dragon ~ message2 ~ 1
evil_sorcerer ~ message3 ~ 2
magic ~ message4 ~ 3
crown ~ message5 ~ 4
queen ~ message6 ~ 5
then, if you want to randomly get a response:
StringDictionaryItem ( stringdictionary , string key )
using my example:
StringDictionaryItem (conversation_topics_structure.conversation_topics,GetRandomInt(1,6)-1)
(then just write this code line above, into whatever script location, that you want it)
if you want to specify a conversation topic:
StringDictionaryItem ( stringdictionary , string key )
using my example:
for the "sword": StringDictionaryItem (conversation_topics_structure.conversation_topics,0)
for the "dragon": StringDictionaryItem (conversation_topics_structure.conversation_topics,1)
for the "evil_sorcerer": StringDictionaryItem (conversation_topics_structure.conversation_topics,2)
for the "magic": StringDictionaryItem (conversation_topics_structure.conversation_topics,3)
for the "crown": StringDictionaryItem (conversation_topics_structure.conversation_topics,4)
for the "queen": StringDictionaryItem (conversation_topics_structure.conversation_topics,5)
Also, I'm going to be telling you how to do this via code, so, if you want help in the gui~editor, let me know, and I'll try to help you with doing it via that way too.
----------------------------
so, you can get to the game code in two different ways:
from the gui~editor, click on the notepaper like button at the top, it's the button between the play and ? (help) buttons
this notepaper button, is a toggle button, switching between the gui~editor mode and the code view mode.
~OR~
you can just open up your game (or library) file, using notepad, notepad++, or wordpad
-----------------------------
here's some links:
http://quest5.net/wiki/Main_Page
http://quest5.net/wiki/How_to
http://quest5.net/wiki/Conversations
http://quest5.net/wiki/Dynamic_Menus_for_Conversations
http://quest5.net/wiki/Random_default_answers
http://quest5.net/wiki/Unlockdoor
http://quest5.net/wiki/Category:All_Fun ... t_Commands
http://quest5.net/wiki/Using_Lists
http://quest5.net/wiki/Using_Dictionaries
viewtopic.php?f=10&t=3444
viewtopic.php?f=10&t=3439
viewtopic.php?f=10&t=3435
--------------------
the code is: GetRandomInt (min_value,max_value)
http://quest5.net/wiki/GetRandomInt
so for example: GetRandomInt (1,5)
I think that maybe this code can't start from 0, so you'll have to do this to get it to start from 0: GetRandomInt (1,6) - 1
which does this:
[ selected random integer from GetRandomInt (1,5) ] and then [ - 1 ] and finally = [ resulting value after the subtraction ]
1 - 1 = 0
2 - 1 = 1
3 - 1 = 2
4 - 1 = 3
5 - 1 = 4
6 - 1 = 5
now, for lists and dictionaries, each item is enumerated, but it starts from 0, thus why we needed to do the above, of: GetRandomInt (1,6) - 1
Lists:
stringlist is known~used as just: list
objectlist
Dictionaries:
stringdictionary
objectdictionary
scriptdictionary
so for example, using a stringdictionary:
<object name="conversation_topics_structure">
<conversation_topics type="stringdictionary">sword=message1;dragon=message2;evil_sorcerer=message3;magic=message4;crown=message5;queen=message6</conversation>
</object>
key ~ value ~ enumeration count
sword ~ message1 ~ 0
dragon ~ message2 ~ 1
evil_sorcerer ~ message3 ~ 2
magic ~ message4 ~ 3
crown ~ message5 ~ 4
queen ~ message6 ~ 5
then, if you want to randomly get a response:
StringDictionaryItem ( stringdictionary , string key )
using my example:
StringDictionaryItem (conversation_topics_structure.conversation_topics,GetRandomInt(1,6)-1)
(then just write this code line above, into whatever script location, that you want it)
if you want to specify a conversation topic:
StringDictionaryItem ( stringdictionary , string key )
using my example:
for the "sword": StringDictionaryItem (conversation_topics_structure.conversation_topics,0)
for the "dragon": StringDictionaryItem (conversation_topics_structure.conversation_topics,1)
for the "evil_sorcerer": StringDictionaryItem (conversation_topics_structure.conversation_topics,2)
for the "magic": StringDictionaryItem (conversation_topics_structure.conversation_topics,3)
for the "crown": StringDictionaryItem (conversation_topics_structure.conversation_topics,4)
for the "queen": StringDictionaryItem (conversation_topics_structure.conversation_topics,5)
HegemonKhan
21 Mar 2013, 08:16this is what you have:
so, first, just remove the: msg ()
and see if it nor works
if, you still get the error, then try changing the npc to: this
so, here's what it should look like:
(first try this)
and, if the error still comes up, then try this:
otherwise, then try this instead:
---------------------------
actually, I know what's causing the error, I think, lol:
first, you still got to remove the msg ()
so, you first need it to look like this:
now, the error is because the ' StringDictionaryItem ' gets the enumerated stringdictionary:
0: 1 = A
1: 2 = B
2: 3 = C
but the ' GetRandomInt (1,3) ' gets literally 1, 2, or 3
and thus you have a problem: as there is no "3"
GetRandomInt value ~ StringDictionaryItem enumeration
N/A ~ 1 = A ~ (error)
1 ~ 2 = B
2 ~ 3 = C
3 ~ N/A ~ (error)
so, you don't have any matching up of the "1=A" nor do you have a 3rd StringDictionary topic (as the count starts from 0, not 1)
so, you need it to look like this:
<object name="npc">
<inherit name="editor_object" />
<conversation type="stringdictionary">1 = A;2 = B;3 = C</conversation>
<speak type="script">
StringDictionaryItem (npc.conversation,GetRandomint (1,3)-1)
</speak>
</object>
-----------------
if you wanted to just use the: GetRandomInt (1,3)
then you'd need to use it with the switch script:
so, basically you can't do both the: (GetRandomInt) and (StringDictionaryItem)
however, you can do both of: (GetRandomInt - 1) and (StringDictionaryItem)
or, you don't use the StringDictionaryItem, and instead use: (GetRandomInt) with (result=GetRandomInt expression) and the (Switch:result script)
<object name="npc">
<inherit name="editor_object" />
<conversation type="stringdictionary">1 = A;2 = B;3 = C</conversation>
<speak type="script">
msg (StringDictionaryItem (npc.conversation , GetRandomint (1,3)))
</speak>
</object>
so, first, just remove the: msg ()
and see if it nor works
if, you still get the error, then try changing the npc to: this
so, here's what it should look like:
(first try this)
<object name="npc">
<inherit name="editor_object" />
<conversation type="stringdictionary">1 = A;2 = B;3 = C</conversation>
<speak type="script">
StringDictionaryItem (npc.conversation , GetRandomint (1,3))
</speak>
</object>
and, if the error still comes up, then try this:
<object name="npc">
<inherit name="editor_object" />
<conversation type="stringdictionary">1 = A;2 = B;3 = C</conversation>
<speak type="script">
StringDictionaryItem (this.conversation , GetRandomint (1,3))
</speak>
</object>
otherwise, then try this instead:
<object name="npc">
<inherit name="editor_object" />
<conversation type="stringdictionary">1 = A;2 = B;3 = C</conversation>
<speak type="script">
StringDictionaryItem (this.conversation , GetRandomint (1,3)-1)
</speak>
</object>
---------------------------
actually, I know what's causing the error, I think, lol:
first, you still got to remove the msg ()
so, you first need it to look like this:
<object name="npc">
<inherit name="editor_object" />
<conversation type="stringdictionary">1 = A;2 = B;3 = C</conversation>
<speak type="script">
StringDictionaryItem (npc.conversation,GetRandomint(1,3))
</speak>
</object>
now, the error is because the ' StringDictionaryItem ' gets the enumerated stringdictionary:
0: 1 = A
1: 2 = B
2: 3 = C
but the ' GetRandomInt (1,3) ' gets literally 1, 2, or 3
and thus you have a problem: as there is no "3"
GetRandomInt value ~ StringDictionaryItem enumeration
N/A ~ 1 = A ~ (error)
1 ~ 2 = B
2 ~ 3 = C
3 ~ N/A ~ (error)
so, you don't have any matching up of the "1=A" nor do you have a 3rd StringDictionary topic (as the count starts from 0, not 1)
so, you need it to look like this:
<object name="npc">
<inherit name="editor_object" />
<conversation type="stringdictionary">1 = A;2 = B;3 = C</conversation>
<speak type="script">
StringDictionaryItem (npc.conversation,GetRandomint (1,3)-1)
</speak>
</object>
-----------------
if you wanted to just use the: GetRandomInt (1,3)
then you'd need to use it with the switch script:
result = GetRandomInt (1,3)
switch (result) {
case ("1") {
msg ("A")
}
case ("2") {
msg ("B")
}
case ("3") {
msg ("C")
}
}
so, basically you can't do both the: (GetRandomInt) and (StringDictionaryItem)
however, you can do both of: (GetRandomInt - 1) and (StringDictionaryItem)
or, you don't use the StringDictionaryItem, and instead use: (GetRandomInt) with (result=GetRandomInt expression) and the (Switch:result script)

KiraxSummers
21 Mar 2013, 08:33Hi Hegemon and thanks for the detailed answers! Those wiki pages are rad, I wish I'd found them sooner! And while they're full of interesting stuff and your reply full of win, I'm STILL getting an error. This thing has me at my wit's end now T_T
I did everything the way you told me to and got this error right off the bat:
Error: Error adding script attribute 'speak' to element 'npc': Function not found: 'StringDictionaryItem'
Is this thing telling me the StringDictionaryItem function doesn't exist? Have things changed in my version of Quest? ...Wow. I'm just gonna attach the game file this time.
-----------
Reuploaded the file.
I did everything the way you told me to and got this error right off the bat:
Error: Error adding script attribute 'speak' to element 'npc': Function not found: 'StringDictionaryItem'
Is this thing telling me the StringDictionaryItem function doesn't exist? Have things changed in my version of Quest? ...Wow. I'm just gonna attach the game file this time.
-----------
Reuploaded the file.
HegemonKhan
21 Mar 2013, 08:39I edited a bit more into my previous post, and it's quite technical (codey, lol), so, if you're new to quest, it might be hard to follow. Though, let me take a look at your attachment, and see what I can do too, in the meantime.
-----
edit:
don't pull your hair out yet, it's just a simple mistake, we need to correct, often times it is, one small simple little mistake, lol
I'll get this figured out for you (if others don't beat me first ~ I'm still a noob myself though I've learned quest and its coding pretty well now over the ~ few months of studying it and asking lots of questions), very soon, so don't worry.
a quick guess (before I test out how to get it to work for you):
change the "this" back to npc, and see if that works.
("this" can sometimes be used as a shorthand of refering to the object, instead of writing out the object's name, but it only works locally and may have more limitations too)
if not, then it's something else minor that's causing the error, which I'm working on right now.
-----
edit:
don't pull your hair out yet, it's just a simple mistake, we need to correct, often times it is, one small simple little mistake, lol
I'll get this figured out for you (if others don't beat me first ~ I'm still a noob myself though I've learned quest and its coding pretty well now over the ~ few months of studying it and asking lots of questions), very soon, so don't worry.
a quick guess (before I test out how to get it to work for you):
change the "this" back to npc, and see if that works.
("this" can sometimes be used as a shorthand of refering to the object, instead of writing out the object's name, but it only works locally and may have more limitations too)
if not, then it's something else minor that's causing the error, which I'm working on right now.

KiraxSummers
21 Mar 2013, 08:41Actually, the switch case was how I used to handle things and it's great but, if I wanted to add another value like, for example:
You pick up an item
'talk to npc' may have it randomly reference that item.
I thought it would be easier to add that value to a dictionary as soon as the player picks the item up and update a counter to keep track of the topics available.
But if I can't make this work, I have no qualms about going back to switch cases!
Again, thanks!
You pick up an item
'talk to npc' may have it randomly reference that item.
I thought it would be easier to add that value to a dictionary as soon as the player picks the item up and update a counter to keep track of the topics available.

But if I can't make this work, I have no qualms about going back to switch cases!

Again, thanks!
HegemonKhan
21 Mar 2013, 08:48the dictionary is a lot more handy than the switch script, just give me a few moments to get this working~fixed for you, hehe.

KiraxSummers
21 Mar 2013, 08:49Oh cool, thanks man! 

HegemonKhan
21 Mar 2013, 08:51I edited in some more (sorry it's a habit, how I write, lol), an "Edit: yada yada yada" to the last post of mine (the short response one).
are you using 5.4 or 5.3, btw? it might well be that you just need to change around how you write out the code, if you're using 5.4, as it was changed a bit from how its done in 5.3
are you using 5.4 or 5.3, btw? it might well be that you just need to change around how you write out the code, if you're using 5.4, as it was changed a bit from how its done in 5.3

KiraxSummers
21 Mar 2013, 09:00Ah, I'm using 5.3, same as you! Which makes my problem strange... I've seen examples but even copy/pasting code directly gives me some sort of error. Like, what? XD Oh, I did switch 'this' back to 'npc' though.
HegemonKhan
21 Mar 2013, 09:04K, I got it fixed, hehe:
you *DO* need the msg (), my bad!
and the problem was the GetRandomInt, which returns the value as an "Integer" type, whereas it needs to be a "String" type for the StringDictionaryItem to read~understand it.
GetRandomInt (returns value as an integer type) = GetStringDictionary (needs value to be as a string type)
integer = string -> ERROR! (as an integer is NOT a string, and thus they're not equal, lol)
integer = integer -> NO error
string = string -> NO error
ToString converts the value (as integer type) into a string type
lastly, you don't need the ( -1 ) either, my bad!
also, make sure you got 4 ")" marks after the 3, lol
<asl version="530">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="StringDicTest">
<gameid>490059fa-4154-4263-afa3-33dab1095527</gameid>
<version>1.0</version>
<firstpublished>2013</firstpublished>
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
<object name="npc">
<inherit name="editor_object" />
<conversation type="stringdictionary">1 = A;2 = B;3 = C</conversation>
<speak type="script">
msg (StringDictionaryItem (npc.conversation , ToString (GetRandomInt (1,3))))
</speak>
</object>
</object>
</asl>
you *DO* need the msg (), my bad!
and the problem was the GetRandomInt, which returns the value as an "Integer" type, whereas it needs to be a "String" type for the StringDictionaryItem to read~understand it.
GetRandomInt (returns value as an integer type) = GetStringDictionary (needs value to be as a string type)
integer = string -> ERROR! (as an integer is NOT a string, and thus they're not equal, lol)
integer = integer -> NO error
string = string -> NO error
ToString converts the value (as integer type) into a string type
lastly, you don't need the ( -1 ) either, my bad!
also, make sure you got 4 ")" marks after the 3, lol

KiraxSummers
21 Mar 2013, 09:10A - HA! Wowie, it was that simple, eh? I feel a bit silly now ^^; I was considering everything from a messed up core file to the apocalypse!
But hey, thanks a whole bunch hegemon, I owe ya one! 


HegemonKhan
21 Mar 2013, 09:13np (no problem), hehe.
it's funny, as you're releaved (can't spell arg) it is a simple problem~fix, but you're annoyed at how much work it takes to find and then to fix it, when it is such a simple problem (you almost wish it was a more difficult problem for the amount of work it took).
--------------
P.S.
you can replace (npc.conversation) with (this.conversation), too btw
it's funny, as you're releaved (can't spell arg) it is a simple problem~fix, but you're annoyed at how much work it takes to find and then to fix it, when it is such a simple problem (you almost wish it was a more difficult problem for the amount of work it took).
--------------
P.S.
you can replace (npc.conversation) with (this.conversation), too btw


KiraxSummers
21 Mar 2013, 09:16Haha, exactly! I swear, 'Could find not function' has been on my mind all the damn time since it happened.
But, 'tis the plight of all programmers, I think! One and a half day for an eight-character fix! And I'm gonna start learning Java pretty soon so the agony of debugging will never really go away 


HegemonKhan
21 Mar 2013, 09:25I forgot your first post, lol, you know programming, I thought you didn't, lol. You know much more programming than I do, as I know ZERO programming.
ya, in my attempt at learning quest coding (I've never taken a programming class yet ~ I plan to though sighs wish I had done this when I was a kid, I'm old now), I'm learning that trouble shooting is really fun... though when I'm able to trouble shoot, I feel like I got to be learning quest code, if I can trouble shoot it, lol. Now, if only I could understand exactly what the errors are saying, so it can speed up my fixing of the errors, lol.
the integer=/=string, is becoming a common problem for people (this maybe should be documented in the wiki, such as a faq on common mistakes)
so, the ToString function is the answer to a lot of recent problems that've been coming up on this board, lol.
ya, in my attempt at learning quest coding (I've never taken a programming class yet ~ I plan to though sighs wish I had done this when I was a kid, I'm old now), I'm learning that trouble shooting is really fun... though when I'm able to trouble shoot, I feel like I got to be learning quest code, if I can trouble shoot it, lol. Now, if only I could understand exactly what the errors are saying, so it can speed up my fixing of the errors, lol.
the integer=/=string, is becoming a common problem for people (this maybe should be documented in the wiki, such as a faq on common mistakes)
so, the ToString function is the answer to a lot of recent problems that've been coming up on this board, lol.

jaynabonne
21 Mar 2013, 13:39Sorry to jump in at the last minute just to kibitz, but why would you use a string dictionary when the string list is a list of strings indexed by an integer? Easier to setup and easier to index. 
If you want a data structure where you look up a string by number, the string list is what you want.

If you want a data structure where you look up a string by number, the string list is what you want.
sonic102
22 Mar 2013, 02:26Hmm, obviously you have NPC troubles like every IFer.
We really need a NPC library. (Do you hear me, Pixie?)
We really need a NPC library. (Do you hear me, Pixie?)
HegemonKhan
22 Mar 2013, 06:31We've already covered pretty much everything needed for NPCs on this board, my own problem is just brainstorming on game design, on what I want and then how to do it, but implementing it, shouldn't be too hard, as I think I've learned enough to do whatever I want with the coding. I'm actually more stuck with the game design (what I want in the game and how I want to do it) and with game mechanics (no Idea on how I want to set up the equations and the relationships, and to what stats, etc).
NPCs:
diplomacy system (talking, messages, taunting, etc)
hostility~disposition system (how much you're liked vs them becoming an enemy trying to kill you)
stealth system (stealing, pickpocketing, sneaking ~ being "noticed" or not ~ bonus damage in combat)
magic system (using spells on NPCs and them using spells on you)
business system (buying~selling, equipment, spells, items, banking, storage ~ an alternative method, etc)
equipment system (NPCs have equipment too)
travel system (NPCs used to transport you)
enchantment and alchemy system (NPC business dealing with magic)
team system (NPCs that follow and aide you, or maybe betray you too, hehe)
skills system (NPCs that teach you abilities, boost stats, and etc)
etc etc etc
-------------------
Pixie has helped enough, he~she has already made plenty of libraries, it's time that we make our own... very slowly, lol
NPCs:
diplomacy system (talking, messages, taunting, etc)
hostility~disposition system (how much you're liked vs them becoming an enemy trying to kill you)
stealth system (stealing, pickpocketing, sneaking ~ being "noticed" or not ~ bonus damage in combat)
magic system (using spells on NPCs and them using spells on you)
business system (buying~selling, equipment, spells, items, banking, storage ~ an alternative method, etc)
equipment system (NPCs have equipment too)
travel system (NPCs used to transport you)
enchantment and alchemy system (NPC business dealing with magic)
team system (NPCs that follow and aide you, or maybe betray you too, hehe)
skills system (NPCs that teach you abilities, boost stats, and etc)
etc etc etc
-------------------
Pixie has helped enough, he~she has already made plenty of libraries, it's time that we make our own... very slowly, lol
