Generating stuff

The Pixie
Occasionally you want to create items in the middle of a game, and you want some variety. Random treasure in an RPG is a good example (see Deeper for instance). Here is a way of doing that. Just paste the code at the bottom into your own game (in code view, paste it just before the last line, which will be "</asl>").

The way it works is you send a prototype and a location to the ClonePrototype function, and a copy of the prototype will appear at the given location. Let us say we want lots of hats in the game. Create a prototype hat in a hidden room, and the you can place copies with this function.
ClonePrototype (hat, room)


No different to CloneObjectAndMove so far, but you can set up the prototype to give some variety to the cloned object. Firstly you can set attributes.


Random Integer Attributes

If your prototype has a string attribute that in the form "r_int_<attname>", this will set an attribute, "<attname>", as an integer. Set "r_int_<attname>" to the range (no spaces). For example, for the hat, you might set this:
hat.r_int_size = "2-5"


The first clone will get the name hat1. The system will then set hat1.size to a random number from 2 to 5.


Random String Attributes

If your prototype has a stringlist attribute that in the form "r_str_<attname>", this will set an attribute, "<attname>", as a string, randomly chosen from the string list.
hat.r_str_colour = "blue;green;red"


The system will set hat1.colour to a randomly chosen colour.


Random Description

Set the description (the "look" attribute) like this:
It was a [big|small|floppy] hat.


... and one of "big", "small" and "floppy" will be selected at random. Why not use the text processor? Well the random option in the text processor makes a new selection each time the text is displayed. This will just do it when the item is created; thereafter it will stay the same for that specific hat.

Or it can select from a list on any object; useful if you want the same set of options several times:
It was a [big|small|floppy] hat made of [#game.hatmaterials].


In this case, hatmaterials is a string list on the game object. You can also include attributes of the object:
It was a [big|small|floppy] hat made of [#game.hatmaterials]. It was [#colour], and size [#size].


Here it is also including the string attribute colour and the integer size set up earlier.


Random Alias

It will do the same for the alias, so you could set that like this:
[#colour] hat


Note the name and description will match, because both use the "colour" attribute set up previously.


Text Process Directives

There is a issue using the text processor with cloned items (whether made by this system or not) in that you do not know what the name in advance. For this, you can use #### as a stand-in for the object name. For instance:
A [#colour] hat.{if ####.size>4: It is too big for you.}{if ####.size<5: It is too small for you.}



The Code

This is version 1.1 (23/Apr/16), and includes the text processor bit.

  <function name="ClonePrototype" parameters="obj, room">
o = CloneObjectAndMove(obj, room)
foreach (att, GetAttributeNames(o, true)) {
if (StartsWith(att, "r_")) {
s = GetString(o, att)
name = Mid(att, 7)
if (StartsWith(att, "r_int_")) {
l = Split(s, "-")
if (not ListCount(l) = 2) {
error ("Failed to clone object, could not parse attribute " + att + " (" + s + ")")
}
val = GetRandomInt(ToInt(StringListItem(l, 0)), ToInt(StringListItem(l, 1)))
}
if (StartsWith(att, "r_str_")) {
val = PickOneStr(GetAttribute(o, att))
}
// msg ("setting; " + name + " with " + val)
set (o, name, val)
}
}
if (HasString(o, "look")) {
o.look = Randomise(o, "look")
}
if (HasString(o, "alias")) {
o.alias = Randomise(o, "alias")
}
</function>
<function name="Randomise" parameters="o, attname" type="string">
s = GetAttribute(o, attname)
mylist = Split (s, "[")
output = StringListItem (mylist, 0)
list remove (mylist, output)
foreach (s1, mylist) {
list1 = Split (s1, "]")
if (not ListCount (list1) = 2) {
error ("Unable to parse (no matching ]): " + s)
}
s2 = StringListItem (list1, 0)
if (StartsWith(s2, "#")) {
s2 = Mid(s2, 2)
list2 = Split (s2, ".")
if (ListCount (list2) = 1) {
extra = GetAttribute(o, StringListItem(list2, 0))
}
else if (ListCount (list2) = 2) {
obj = GetObject(StringListItem(list2, 0))
if (obj = null) {
error ("Unable to parse (could not find object in the {#...} bit): " + s2)
}
list3 = GetAttribute(obj, StringListItem(list2, 1))
if (not TypeOf(list3) = "stringlist") {
error ("Unable to parse (could not find list attribute in the {#...} bit): " + s2)
}
extra = PickOneStr(list3)
}
else {
error ("Unable to parse (the {#...} bit): " + s2)
}
}
else {
list2 = Split (s2, "|")
pos = GetRandomInt (0, ListCount (list2) - 1)
extra = StringListItem (list2, pos)
}
output = output + extra + StringListItem (list1, 1)
}
return (Replace(output, "####", o.name))
</function>
<function name="PickOneStr" parameters="lst" type="string">
if (TypeOf(lst) = "string") {
lst = Split(lst, "|")
}
index = GetRandomInt(0, ListCount(lst) - 1)
return (StringListItem(lst, index))
</function>

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

Support

Forums