randomizing strings

Hey everyone,

I found this amazing script by pix for creating zombies, which I have altered to work for items. The only issue is when I have the function name the object it always comes out in the same order, whereas I'm hoping to select random options from a split. Anyways here's the code.

if (HasInt(game, "newhelmra")) {
  game.newhelmra = game.newhelmra + 1
}
else {
  game.newhelmra = 1
}
create ("rahelm" + game.newhelmra)
obj = GetObject("rahelm" + game.newhelmra)
obj.parent = loc
obj.displayverbs = Split("Take;Equip;Unequip", ";")
obj.inventoryverbs = Split("Drop;Equip;Unequip", ";")
obj.equiped = false
obj.lvl = player.lvl
obj.equip => {
  if (Got(this)) {
    equiphelm (this)
  }
  else {
    msg ("You can't equip a helmet unless its in your inventory.")
  }
}
obj.take => {
  AddToInventory (this)
}
obj.drop => {
  MoveObjectHere (this)
  candrop (this)
}
obj.unequip => {
  unequiphelm (this)
}

This is the section where I set the options I would like to be randomly selected.

names7 = Split("durable ;reflective ;strong ;quick ;smart ;keen ", ";") 
names8 = Split(" and defensive ; and resistive ; and tough ; and agile ; and educated ; and wise ", ";")
if (player.lvl <= 5) {

This is where I name the object. I thought the % would randomize for me, but I'm honestly not entirely sure whats happening in the "StringListItem" function.

  obj.alias = StringListItem(names7, game.newhelmra % ListCount(names7)) + StringListItem(names8, game.newhelmra %
ListCount(names8)) + "rare wooden helmet"
  obj.listalias = CapFirst(obj.alias)
  obj.res = 1
  obj.def = 2
  obj.str = 0
  obj.agi = 0
  obj.int = 0
  obj.perc = 0
}
else if (player.lvl > 5 and player.lvl <=10) {
  obj.alias = StringListItem(names7, game.newhelmra % ListCount(names7)) + StringListItem(names8, game.newhelmra % ListCount(names8)) + "rare stone helmet"
  obj.listalias = CapFirst(obj.alias)
  obj.res = 2
  obj.def = 4
  obj.str = 0
  obj.agi = 0
  obj.int = 0
  obj.perc = 0
}
else if (player.lvl > 10 and player.lvl <= 50) {
  obj.alias = StringListItem(names7, game.newhelmra % ListCount(names7)) + StringListItem(names8, game.newhelmra % ListCount(names8)) + "rare metal helmet"
  obj.listalias = CapFirst(obj.alias)
  obj.res = 4
  obj.def = 8
  obj.str = 0
  obj.agi = 0
  obj.int = 0
  obj.perc = 0
}
if (IsRegexMatch ("durable ", obj.alias)) {
  obj.def = obj.def + player.lvl
}
else if (IsRegexMatch ("reflective ", obj.alias)) {
  obj.res = obj.res + player.lvl
}
else if (IsRegexMatch ("strong ", obj.alias)) {
  obj.str = obj.str + player.lvl
}
else if (IsRegexMatch ("quick ", obj.alias)) {
  obj.agi = obj.agi + player.lvl
}
else if (IsRegexMatch ("smart ", obj.alias)) {
  obj.int = obj.int + player.lvl
}
else if (IsRegexMatch ("keen ", obj.alias)) {
  obj.perc = obj.perc + player.lvl
}
if (IsRegexMatch (" and defensive ", obj.alias)) {
  obj.def = obj.def + player.lvl
}
else if (IsRegexMatch (" and resistive ", obj.alias)) {
  obj.res = obj.res + player.lvl
}
else if (IsRegexMatch (" and tough ", obj.alias)) {
  obj.str = obj.str + player.lvl
}
else if (IsRegexMatch (" and agile ", obj.alias)) {
  obj.agi = obj.agi + player.lvl
}
else if (IsRegexMatch (" and educated ", obj.alias)) {
  obj.int = obj.int + player.lvl
}
else if (IsRegexMatch (" and wise ", obj.alias)) {
  obj.perc = obj.perc + player.lvl
}

I'm stilling getting on my feet with coding and any help with this would be awesome!


This is where I name the object. I thought the % would randomize for me, but I'm honestly not entirely sure whats happening in the "StringListItem" function.
obj.alias = StringListItem(names7, game.newhelmra % ListCount(names7)) + StringListItem(names8, game.newhelmra % ListCount(names8)) + "rare wooden helmet"

No; % is the modulo operator; it finds the remainder of a division. Your names7 array has 6 elements, so if game.newhelmra is 0-5, it returns that number. As the number goes up by 1 every time this function is run, then game.newhelmra % ListCount(names7) will start by giving 1 the first time it is run, then 2, then 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2 and so on.

If you want to pick a random element each time, you want to use random numbers. Like this:

obj.alias = PickOneString (names7) + PickOneString (names8) + "rare wooden helmet"

That's actually shorthand for:

obj.alias = ListItem (names7, GetRandomInt (0, ListCount (names7) - 1)) + ListItem (names8, GetRandomInt (0, ListCount (names8) - 1)) + "rare wooden helmet"

I think that should answer your question. There's a few other things that would bug me about the script (like not being able to put the helmet in a container, and using quite a lot of code to do things that there are simple functions for), but I know I shouldn't interfere with someone else's code.

Happy to help if there's anything else giving you a problem.


mrangel that answers my question perfectly!

I'm not really great at utilizing all of the built in functions yet, as this is my second week or so using the program. I would definitely be interested in any ways you know of that I could make this prettier if that's that word?

I've been doing my best to scour the forums for answers, but I worry that this is causing a hodge-podge of extra code and clunky functions.

To be completely honest, I was so proud of myself for even getting this to make an item I had to have a short celebration xD


One thing I would simplify is this code, which I've seen pasted on the forum by so many people:

if (HasInt(game, "newhelmra")) {
  game.newhelmra = game.newhelmra + 1
}
else {
  game.newhelmra = 1
}
create ("rahelm" + game.newhelmra)
obj = GetObject("rahelm" + game.newhelmra)

My version, which does exactly the same thing:

name = GetUniqueElementName ("rahelm")
create (name)
obj = GetObject(name)

The 'drop' script is used when the [player enters "drop helmet", but also when the player does something like "put helmet in bag". In the latter case, you don't want the helmet to end up on the floor; so unless you're removing the put command, I think you probably want MoveObject (this, destination) rather than MoveObjectHere (this).

(I can't say anything about your candrop function, because I don't know what it does. But the name seems a little confusing; anyone helping with some other part of the code in future might expect it to be a function that tests it an object can be dropped, rather than a function which is run after dropping an object.


The long section of determining the object's stats is an interesting way to do it, but I think there's a lot of repetition of code there; and although regular expressions are relatively fast, compiling and running 12 of them is still quite slow.

I think this is more a matter of personal style; but I would have gone for something more like:

foreach (word, Split(obj.alias, " ")) {
  switch (word) {
    case ("durable", "defensive") {
      obj.def = obj.def + player.lvl
    }
    case ("reflective", "resistive") {
      obj.res = obj.res + player.lvl
    }
    case ("strong", "tough") {
      obj.str = obj.str + player.lvl
    }
    case ("quick", "agile") {
      obj.agi = obj.agi + player.lvl
    }
    case ("smart", "educated") {
      obj.int = obj.int + player.lvl
    }
    case ("keen", "wise") {
      obj.perc = obj.perc + player.lvl
    }
  }
}

(or, depending on the options that might be available in other parts of this code, put some kind of markup in with the strings. Like:

name_part = PickOneString (Split ("durable/def;reflective/res;strong/str;quick/agi;smart/int;keen/perc"))

and split the resulting name_part at the slash; putting the first part in the alias and the second as a stat increase.


A comment on: else if (player.lvl > 10 and player.lvl <= 50) {

You already know at this point that the level is greater than 10, because the else takes care of that. And if the level is greater than 50, it won't give the item any stats at all, causing an error when it tries to add something to them later. If the player's level can't go above 50 (which I'd guess is the case), you could replace this line with simply else {.

If you're using the (player.lvl > 10 and player.lvl <= 50) as a memo to yourself, to remind you of what conditions lead to that branch, that's fine. Seems to be quite common around here. But really, that's what comments are meant for.


I'm definitely a fan of the way to create an object! Will I have to use a different name variables for different items? I.E. I have rahelm/rasword/raarmor will I have to use

name = GetUniqueElementName ("rahelm")
create (name)
obj = GetObject(name)

then

name1 = GetUniqueElementName ("rasword")
create (name1)
obj = GetObject(name1)

for different objects? Also I have different rarities, I.E unhelm/rahelm/leghelm. I'm currently just calling different functions for each rarity of each item type based off a random integer roll in a "pickitem" function.

I.E
if dice > 5 and <= 10 then call function (createrasword)
if dice > 10 and <50 then call function (createunsword)

My candrop function is definitely wonky because I didn't understand how to edit the drop command when I made it. It basically forceruns the take command on the item after you drop it, if the item has a boolean "equiped = true". I just need to change the default drop script on initialize to check the boolean before it places the item I think.

The foreach function there seems to be what I've been trying to figure out as far my Regex lines go. Does that take each word in the alias and check it through the case functions? If so I think that answers my question about the uncommon/rare/legendary problem, as I could just add a check for that word and set the type based on which case it finds.

The name_part section looks interesting, but is a little more complicated then my brain can process right now, does it do the same thing as the foreach? I'll do some more research on PickOneString and Split then take another look at this.

The player level is set to 50 for now because I'm planning on adding more else if's I just wasn't sure to call the next one after metal helmet, or how strong it should be yet so I set it to a level you probably wont reach xD I will set the final option to else.

Lastly the container section. I have been thinking about adding a weapon/armor rack to store items, but was thinking I would have to add a separate verb for it(I have friends who aren't great at spelling would rather click a button that spells it for them). It sounds like the option your suggesting wouldn't quite accommodate that.

Thank you So So much!!!


I'm definitely a fan of the way to create an object! Will I have to use a different name variables for different items?

Probably not. The variable name doesn't belong to an object, so it's discarded as soon as the script finishes. If you need to refer to the last object created of a certain type, you could make it an attribute of some object; but I don't think there's any more reason to refer to the name once you have the object.

Also I have different rarities, I.E unhelm/rahelm/leghelm. I'm currently just calling different functions for each rarity of each item type based off a random integer roll in a "pickitem" function.

How different are the different rarities? If they're pretty similar, it might be easier to make it all part of one function.

My candrop function is definitely wonky because I didn't understand how to edit the drop command when I made it. It basically forceruns the take command on the item after you drop it, if the item has a boolean "equiped = true". I just need to change the default drop script on initialize to check the boolean before it places the item I think.

In that case, I think you'd want:

obj.drop => {
  if (this.equipped) {
    msg ("You need to take it off first")
  }
  else {
    msg ("OK.")
    MoveObject (this, destination)
  }
}

The foreach function there seems to be what I've been trying to figure out as far my Regex lines go. Does that take each word in the alias and check it through the case functions? If so I think that answers my question about the uncommon/rare/legendary problem, as I could just add a check for that word and set the type based on which case it finds.

That's what I was thinking :) And yes; it uses Split to break the alias up into words, and then does a switch call for each of them.

Explaining switch/case is a little hard. A lot of people would say that it's like if/else if. You could say that these two scripts are the same:

if (word = "red") {
  // first response
}
else if (word = "green") {
  // second response
}
else {
  //default response
}
switch (word) {
  case ("red") {
    // first response
  }
  case ("green") {
    // second response
  }
  default {
    // default response
  }
}

But as you saw in the example above, a case can have more than one option in it, with commas between them. And it can only test if things are equal.

The more important difference is that if/else if/else if is like flipping through a book looking for the chapter you want. On every page, you check which title you're looking for and compare them, until you find it. But switch/case basically constructs an 'index' first from all the "case" statements, and then looks up the word in it. Not 100% sure, but in most programming languages it will only need to build the index the first time; which means that it can be a lot faster (especially for large numbers of options).

The name_part section looks interesting, but is a little more complicated then my brain can process right now, does it do the same thing as the foreach?

I think it could do. The code might be a little more complex to start with, but it means that each additional option adds less extra code. (It would be a lot easier to do it this way in Perl, my preferred programming language. But Quest's limited functionality requires some extra work)

If you're dealing with rarity in the same place, I suspect that using switch/case to handle different variants is probably the best option; because they are likely to have slightly different code.


I'm imagining now a function with an extra parameter 'rarity', which would look something like:

name = GetUniqueElementName (rarity + "helm")
create (name)
obj = GetObject(name)
obj.parent = loc
obj.displayverbs = Split("Take;Equip;Unequip", ";")
obj.inventoryverbs = Split("Drop;Equip;Unequip", ";")
obj.equiped = false
obj.lvl = player.lvl
obj.equip => {
  if (Got(this)) {
    equiphelm (this)
  }
  else {
    msg ("You can't equip a helmet unless its in your inventory.")
  }
}
obj.take => {
  AddToInventory (this)
}
obj.drop => {
  if (this.equipped) {
    msg ("You need to take it off first")
  }
  else {
    msg ("OK.")
    MoveObject (this, destination)
  }
}
obj.unequip => {
  unequiphelm (this)
}
alias = PickOneString (Split("durable;reflective;strong;quick;smart;keen"))
alias = alias + " and " + PickOneString (Split ("defensive;resistive;tough;agile;educated;wise"))
alias = alias + " " + rarity
if (obj.lvl <= 5) {
  alias = alias + " wooden helmet"
}
else if (obj.lvl <= 10) {
  alias = alias + " stone helmet"
}
else if (obj.lvl <= 50) {
  alias = alias + " metal helmet"
}
else {
  alias = alias + " cheese helmet"
}
obj.alias = alias
obj.listalias = CapFirst (alias)
foreach (attr, Split("res;def;str;agi;int;perc")) {
  set (obj, attr, 0)
}
foreach (word, Split(obj.alias, " ")) {
  switch (word) {
    case ("wooden") {
      obj.res = obj.res + 1
      obj.def = obj.def + 2
    }
    case ("stone") {
      obj.res = obj.res + 2
      obj.def = obj.def + 4
    }
    case ("metal") {
      obj.res = obj.res + 4
      obj.def = obj.def + 8
    }
    case ("cheese") {
      obj.res = obj.res + 10
      obj.def = obj.def + 12
    }
    case ("durable", "defensive") {
      obj.def = obj.def + player.lvl
    }
    case ("reflective", "resistive") {
      obj.res = obj.res + player.lvl
    }
    case ("strong", "tough") {
      obj.str = obj.str + player.lvl
    }
    case ("quick", "agile") {
      obj.agi = obj.agi + player.lvl
    }
    case ("smart", "educated") {
      obj.int = obj.int + player.lvl
    }
    case ("keen", "wise") {
      obj.perc = obj.perc + player.lvl
    }
    case ("rare") {
      // whatever difference it makes
    }
    case ("legendary") {
      // whatever difference it makes
    }
  }
}

:'D it's so pretty. . .

So the only major difference between rarities is the number of names it gets. Uncommon gets the first set, rare also gets the and set, and legendary gets an of set on top of those. I'm thinking we could change this section

alias = PickOneString (Split("durable;reflective;strong;quick;smart;keen"))
alias = alias + " and " + PickOneString (Split ("defensive;resistive;tough;agile;educated;wise"))
alias = alias + " " + rarity

I'm thinking this would work.

if (rarity = uncommon) {
  alias = PickOneString (Split("durable;reflective;strong;quick;smart;keen"))
  alias = alias + " " + rarity
else if (rarity = rare) {
  alias = PickOneString (Split("durable;reflective;strong;quick;smart;keen"))
  alias = alias + " and " + PickOneString (Split ("defensive;resistive;tough;agile;educated;wise"))
  alias = alias + " " + rarity
else if (rarity = legendary)  
  alias = PickOneString (Split("durable;reflective;strong;quick;smart;keen"))
  alias = alias + " and " + PickOneString (Split ("defensive;resistive;tough;agile;educated;wise"))
  alias = alias + " " + rarity
  alias = alias + " of " + PickOneString (Split ("armor;magic resistance;the bear;speed;wits;sight"))

Do you think it would be better to set the helmets base def/res/str/agi/int/perc in this if check, and remove the rarity case check; or set them later in the case check, and leave this function for setting the name; or neither because I'm looking at this the hard way? I do need the base for them all set, even if they are 0 for my equip/unequip function.


Okay I took a look at this all again and realized that wouldn't work and you already added a case for the base stats. I also changed my equip function to check if the item has a variable before it check its. So I don't need 0's anymore.
I started working on the script for a weapon and broke it somehow. I think I'm just missing a bracket somewhere.

name = GetUniqueElementName (rarity + "sword")
create (name)
obj = GetObject(name)
obj.parent = loc
obj.displayverbs = "Take"
obj.inventoryverbs = Split("Drop;Equip;Unequip", ";")
obj.equiped = false
obj.lvl = player.lvl
obj.equip => {
  if (Got(this)) {
    equipweapon (this)
  }
  else {
    msg ("You can't equip a weapon unless its in your inventory.")
  }
}
obj.take => {
  AddToInventory (this)
}
obj.drop => {
  if (this.equipped) {
    msg ("You need to take it off first")
  }
  else {
    msg ("OK.")
    MoveObject (this, destination)
  }
}
obj.unequip => {
  unequipwep (this)
}
if (rarity = "uncommon") {
  alias = PickOneString (Split("sharp;magical;strong;quick;smart;keen"))
  alias = alias + " " + rarity
  if (obj.lvl <= 5) {
    alias = alias + " wooden helmet"
  }
  else if (obj.lvl <= 10) {
    alias = alias + " stone helmet"
  }
  else if (obj.lvl <= 50) {
    alias = alias + " metal helmet"
  }
  else {
    alias = alias + " cheese helmet"
  }
  else if (rarity = "rare") {
    alias = PickOneString (Split("sharp;magical;strong;quick;smart;keen"))
    alias = alias + " and " + PickOneString (Split ("deadly;mystical;tough;agile;educated;wise"))
    alias = alias + " " + rarity
    if (obj.lvl <= 5) {
      alias = alias + " wooden helmet"
    }
    else if (obj.lvl <= 10) {
      alias = alias + " stone helmet"
    }
    else if (obj.lvl <= 50) {
      alias = alias + " metal helmet"
    }
    else {
      alias = alias + " cheese helmet"
    }
    else if (rarity = "legendary") {
      alias = PickOneString (Split("sharp;magical;strong;quick;smart;keen"))
      alias = alias + " and " + PickOneString (Split ("deadly;mystical;tough;agile;educated;wise"))
      alias = alias + " " + rarity
      if (obj.lvl <= 5) {
        alias = alias + " wooden helmet"
        alias = alias + " of " + PickOneString (Split ("power;runes;the bear;speed;wits;sight"))
      }
      else if (obj.lvl <= 10) {
        alias = alias + " stone helmet"
        alias = alias + " of " + PickOneString (Split ("power;runes;the bear;speed;wits;sight"))
      }
      else if (obj.lvl <= 50) {
        alias = alias + " metal helmet"
        alias = alias + " of " + PickOneString (Split ("power;runes;the bear;speed;wits;sight"))
      }
      else {
        alias = alias + " cheese helmet"
        alias = alias + " of " + PickOneString (Split ("power;runes;the bear;speed;wits;sight"))
      }
    }
    foreach (word, Split(obj.alias, " ")) {
      switch (word) {
        case ("wooden") {
          obj.dmg = obj.dmg + 7
          obj.str = obj.str + 2
          case ("stone")
          obj.dmg = obj.dmg + 20
          obj.str = obj.str + 5
          case ("metal")
          obj.dmg = obj.dmg + 45
          obj.str = obj.str + 10
          case ("cheese")
          obj.dmg = obj.dmg + 80
          obj.str = obj.str + 18
          case ("sharp", "deadly", "power") {
            obj.dmg = obj.dmg + player.lvl + 2
          }
          case ("magical", "mystical", "runes") {
            obj.mag = obj.mag + player.lvl + 2
          }
          case ("strong", "tough", "bear") {
            obj.str = obj.str + player.lvl + 1
          }
          case ("quick", "agile", "speed") {
            obj.agi = obj.agi + player.lvl + 1
          }
          case ("smart", "educated", "wits") {
            obj.int = obj.int + player.lvl + 1
          }
          case ("keen", "wise", "sight") {
            obj.perc = obj.perc + player.lvl + 1
          }
        }
      }
   }
 }

I took one more crack at it. It's working and I think I did it about as simply as I could. Let me know what you think. Your help was absolutely amazing.

create (name)
obj = GetObject(name)
obj.parent = loc
obj.displayverbs = Split("Take", ";")
obj.inventoryverbs = Split("Drop;Equip;Unequip", ";")
obj.equiped = false
obj.lvl = player.lvl
obj.equip => {
  if (Got(this)) {
    equipweapon (this)
  }
  else {
    msg ("You can't equip a weapon unless its in your inventory.")
  }
}
obj.take => {
  AddToInventory (this)
}
obj.drop => {
  if (this.equipped) {
    msg ("You need to take it off first")
  }
  else {
    msg ("OK.")
    MoveObject (this, destination)
  }
}
obj.unequip => {
  unequipwep (this)
}
if (rarity = "uncommon") {
  obj.alias = PickOneString (Split("sharp;magical;strong;quick;smart;keen"))
  obj.alias = obj.alias + " " + rarity
  if (obj.lvl <= 5) {
    obj.alias = obj.alias + " wooden sword"
  }
  else if (obj.lvl <= 10) {
    obj.alias = obj.alias + " stone sword"
  }
  else if (obj.lvl <= 50) {
    obj.alias = obj.alias + " metal sword"
  }
  else {
    obj.alias = obj.alias + " cheese sword"
  }
}
else if (rarity = "rare") {
  obj.alias = PickOneString (Split("sharp;magical;strong;quick;smart;keen"))
  obj.alias = obj.alias + " and " + PickOneString (Split ("deadly;mystical;tough;agile;educated;wise"))
  obj.alias = obj.alias + " " + rarity
  if (obj.lvl <= 5) {
    obj.alias = obj.alias + " wooden sword"
  }
  else if (obj.lvl <= 10) {
    obj.alias = obj.alias + " stone sword"
  }
  else if (obj.lvl <= 50) {
    obj.alias = obj.alias + " metal sword"
  }
  else {
    obj.alias = obj.alias + " cheese sword"
  }
}
else if (rarity = "legendary") {
  obj.alias = PickOneString (Split("sharp;magical;strong;quick;smart;keen"))
  obj.alias = obj.alias + " and " + PickOneString (Split ("deadly;mystical;tough;agile;educated;wise"))
  obj.alias = obj.alias + " " + rarity
  if (obj.lvl <= 5) {
    obj.alias = obj.alias + " wooden sword"
    obj.alias = obj.alias + " of " + PickOneString (Split ("power;runes;the bear;speed;wits;sight"))
  }
  else if (obj.lvl <= 10) {
    obj.alias = obj.alias + " stone sword"
    alias = alias + " of " + PickOneString (Split ("power;runes;the bear;speed;wits;sight"))
  }
  else if (obj.lvl <= 50) {
    obj.alias = obj.alias + " metal sword"
    obj.alias = obj.alias + " of " + PickOneString (Split ("power;runes;the bear;speed;wits;sight"))
  }
  else {
    obj.alias = obj.alias + " cheese sword"
    obj.alias = obj.alias + " of " + PickOneString (Split ("power;runes;the bear;speed;wits;sight"))
  }
}
foreach (word, Split(obj.alias, " ")) {
  switch (word) {
    case ("wooden") {
      obj.dmg = 7
      obj.mag = 0
      obj.str = 2
      obj.agi = 0
      obj.int = 0
      obj.perc = 0
    }
    case ("stone") {
      obj.dmg = 20
      obj.mag = 0
      obj.str = 5
      obj.agi = 0
      obj.int = 0
      obj.perc = 0
    }
    case ("metal") {
      obj.dmg = 45
      obj.mag = 0
      obj.str = 10
      obj.agi = 0
      obj.int = 0
      obj.perc = 0
    }
    case ("cheese") {
      obj.dmg = 80
      obj.mag = 0
      obj.str = 18
      obj.agi = 0
      obj.int = 0
      obj.perc = 0
    }
  }
}
foreach (word, Split(obj.alias, " ")) {
  switch (word) {
    case ("sharp", "deadly", "power") {
      obj.dmg = obj.dmg + player.lvl + 2
    }
    case ("magical", "mystical", "runes") {
      obj.mag = obj.mag + player.lvl + 2
    }
    case ("strong", "tough", "bear") {
      obj.str = obj.str + player.lvl + 1
    }
    case ("quick", "agile", "speed") {
      obj.agi = obj.agi + player.lvl + 1
    }
    case ("smart", "educated", "wits") {
      obj.int = obj.int + player.lvl + 1
    }
    case ("keen", "wise", "sight") {
      obj.perc = obj.perc + player.lvl + 1
    }
  }
}
obj.alias = CapFirst (obj.alias)

I also changed my equip function to check if the item has a variable before it check its. So I don't need 0's anymore.

The 0s still need to be inserted because adding a number to an undefined attribute would be an error.
I figured that setting all the stats to zero first and then having the wooden/stone/metal cases just add on the values that they need makes sense because it means you don't have so many different copies of the = 0 lines; and that way it doesn't matter which order the words are processed in so you don't need a second loop.

I took one more crack at it. It's working and I think I did it about as simply as I could. Let me know what you think.

You seem to have some repeated code (code that's the same inside all the 'if' blocks).

Unless this is going to change later, it might be easier to move it outside the condition. Like so:

obj.alias = PickOneString (Split("sharp;magical;strong;quick;smart;keen"))
if (rarity = "rare" or rarity = "legendary") {
  obj.alias = obj.alias + " and " + PickOneString (Split ("deadly;mystical;tough;agile;educated;wise"))
}

if (obj.lvl <= 5) {
  obj.alias = obj.alias + " wooden sword"
}
else if (obj.lvl <= 10) {
  obj.alias = obj.alias + " stone sword"
}
else if (obj.lvl <= 50) {
  obj.alias = obj.alias + " metal sword"
}
else {
  obj.alias = obj.alias + " cheese sword"
}

if (rarity = "legendary") {
  obj.alias = obj.alias + " of " + PickOneString (Split ("power;runes;the bear;speed;wits;sight"))
}

Having two separate loops (one for the material and one for the other bonuses) is kind of inefficient; but if you find it easier to follow that way it's not going to make a big difference.

(Repetition of code is something I tend to pick up on in other people's code; because if you change something later it makes it easier to make a mistake. For example, my code includes the word "metal" in two places (where it's added and in the case statement); and includes the word "bear" in two places (where it's added to the alias, and in the case). Yours includes "metal" 4 times, and "bear" 5 times - which makes it a lot easier to miss one if you decide to change one of the names. The script is just as efficient, but repeating code both increases the chance of a typo, and makes it less likely you'd notice when testing)


!!!The thing that bugs me the most about coding is changing the word "stone" to "metal" 40 times because I added so many if statements!!! I literally can not overstate the unignorable backache that sets in after searching boundless lines of code meticulously to make sure I didn't miss one. . .

That last example did an amazing job of pointing out that I should double check for repeating lines, and try to think of a way to use it once instead of twice or more times.

Thank you for your patient and educating help on this! Consider this one resolved!


One thing I might also suggest to help take care of typos, is adding a couple of extra cases:

  case ("and", "of", "the", "sword", "helmet") {
    // words that don't mean anything
  }
  default {
    msg ("Unexpected word in object name: "+word)
  }

That will print out any words it doesn't know rather than ignoring them; so if a typo gets through, you're more likely to notice it.
It might even be worth changing the message to add something like: "This might be a bug. Please let the developer know if you see this message in the game."


If you want to easily change all instances of a word to something else in your game, go to full code view and use the "Find" or "Replace" functions under the "Edit" tab. This has been a godsend for my games. The only place it will not see are attached .js scripts, which you probably don't use anyway.


That typo fix has already helped me several times!

Thanks for the tip mrangel

That's super cool! I had avoided code view for the time as it seemed simpler to get things written and organized with button view, but I will definitely utilize those edit tools in the future.

Thank you Dcoder!


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

Support

Forums