buy

introduction
you only have to write 1 buy code no matter how big your game gets

  1. create room1 and link it to room
  2. create umbrella object at room and give it alias 'umbrella'
  3. create action object and move it into player's object, add a verb 'buy'
  4. In 'buy', change assignment to run script, open verb code view, and type in
shop_menu = NewStringList()
foreach (buyitem, GetDirectChildren(game.pov.parent)) {
  if (buyitem.name="player") {
  }
  else {
    list add (shop_menu, ""+buyitem.alias)
  }
}
ShowMenu ("buy what", shop_menu, true) {
}
  1. play test it, you can find out that we disabled player object from being chosen because it wouldn't make sense for player to buy himself
  2. At umbrella's attributes, add in 'buy_value' with integer 1
  3. At game object's features, click money
  4. Rewrite 'buy' code view
shop_menu = NewStringList()
foreach (buyitem, GetDirectChildren(game.pov.parent)) {
  if (HasAttribute(buyitem, "buy_value")) {
    list add (shop_menu, buyitem.alias+" $"+buyitem.buy_value)
  }
}
ShowMenu ("buy what", shop_menu, true) {
  msg ("--" + result + "--")
  if (result<>null) {
    foreach (chosenitem, GetDirectChildren(game.pov.parent)) {
      if (chosenitem.alias+" $"+chosenitem.buy_value=result) {
        if (player.money >= chosenitem.buy_value) {
          msg ("you bought "+chosenitem.alias+" for $"+chosenitem.buy_value)
          player.money = player.money-chosenitem.buy_value
          AddToInventory (chosenitem)
        }
        else {
          msg ("not enough money")
        }
      }
    }
  }
  else {
    msg ("You have chosen to press cancel")
  }
}
  1. play test the game, oops not enough money
  2. at game object's script, in start script code view, type
player.money=10
  1. now the game starts with $10 and when you buy an umbrella, it goes into your pocket, reminder if you place the add money code in enter 'room', every time the player enters that room, he gains an additional $10, kinda overpowered, so dun do dat
  2. in action object's object tab, delete all the display verbs and inventory verbs to avoid annoying your players with verbs that does nothing

for the extra challenge, we will add in sell_value

  1. add attribute 'sell_value' to umbrella, give it integer 1
  2. change 'buy_value' of umbrella to integer 5
  3. in action object, add sell verb, give it a script
shop_menu = NewStringList()
foreach (sellitem, GetDirectChildren(game.pov)) {
  if (HasAttribute(sellitem, "sell_value")) {
    list add (shop_menu, sellitem.alias+" $"+sellitem.sell_value)
  }
}
ShowMenu ("sell what", shop_menu, true) {
  msg ("--" + result + "--")
  if (result<>null) {
    foreach (chosenitem, GetDirectChildren(game.pov)) {
      if (chosenitem.alias+" $"+chosenitem.sell_value=result) {
        msg ("you sold "+chosenitem.alias+" for $"+chosenitem.sell_value)
        player.money = player.money+chosenitem.sell_value
        RemoveObject (chosenitem)
      }
    }
  }
  else {
    msg ("You have chosen to press cancel")
  }
}
  1. play test, you should be able to sell items now
  2. if an item is required to complete a quest, you should avoid adding a sell_value to that object, this will automatically disable selling of dat object

for the logical ones, we will add in shopkeeper
because players shouldn't be able to buy or sell items without a shopkeeper

  1. add object 'scholar', give it attribute 'shopkeeper'
  2. change buy verb
shopkeeperaround = false
foreach (merchant, GetDirectChildren(game.pov.parent)) {
  if (HasAttribute(merchant, "shopkeeper")) {
    shopkeeperaround = true
  }
  else {
  }
}
if (shopkeeperaround=true) {
  shop_menu = NewStringList()
  foreach (buyitem, GetDirectChildren(game.pov.parent)) {
    if (HasAttribute(buyitem, "buy_value")) {
      list add (shop_menu, buyitem.alias+" $"+buyitem.buy_value)
    }
  }
  ShowMenu ("buy what", shop_menu, true) {
    msg ("--" + result + "--")
    if (result<>null) {
      foreach (chosenitem, GetDirectChildren(game.pov.parent)) {
        if (chosenitem.alias+" $"+chosenitem.buy_value=result) {
          if (player.money >= chosenitem.buy_value) {
            msg ("you bought "+chosenitem.alias+" for $"+chosenitem.buy_value)
            player.money = player.money-chosenitem.buy_value
            AddToInventory (chosenitem)
          }
          else {
            msg ("not enough money")
          }
        }
      }
    }
    else {
      msg ("You have chosen to press cancel")
    }
  }
}
else {
  msg ("there is no shopkeeper around")
}

  1. change sell verb
shopkeeperaround = false
foreach (merchant, GetDirectChildren(game.pov.parent)) {
  if (HasAttribute(merchant, "shopkeeper")) {
    shopkeeperaround = true
  }
  else {
  }
}
if (shopkeeperaround=true) {
  shop_menu = NewStringList()
  foreach (sellitem, GetDirectChildren(game.pov)) {
    if (HasAttribute(sellitem, "sell_value")) {
      list add (shop_menu, sellitem.alias+" $"+sellitem.sell_value)
    }
  }
  ShowMenu ("sell what", shop_menu, true) {
    msg ("--" + result + "--")
    if (result<>null) {
      foreach (chosenitem, GetDirectChildren(game.pov)) {
        if (chosenitem.alias+" $"+chosenitem.sell_value=result) {
          msg ("you sold "+chosenitem.alias+" for $"+chosenitem.sell_value)
          player.money = player.money+chosenitem.sell_value
          RemoveObject (chosenitem)
        }
      }
    }
    else {
      msg ("You have chosen to press cancel")
    }
  }
}
else {
  msg ("there is no shopkeeper around")
}

And for completeness, there are occasions where there is nothing to be bought or sold,
but it still says 'buy what' and 'sell what'

  1. change buy verb ( for your learning convenience, we only added in a listcount )
shopkeeperaround = false
foreach (merchant, GetDirectChildren(game.pov.parent)) {
  if (HasAttribute(merchant, "shopkeeper")) {
    shopkeeperaround = true
  }
  else {
  }
}
if (shopkeeperaround=true) {
  shop_menu = NewStringList()
  foreach (buyitem, GetDirectChildren(game.pov.parent)) {
    if (HasAttribute(buyitem, "buy_value")) {
      list add (shop_menu, buyitem.alias+" $"+buyitem.buy_value)
    }
  }
  if (ListCount(shop_menu)=0) {
    msg ("there is nothing to buy for now")
  }
  else {
    ShowMenu ("buy what", shop_menu, true) {
      msg ("--" + result + "--")
      if (result<>null) {
        foreach (chosenitem, GetDirectChildren(game.pov.parent)) {
          if (chosenitem.alias+" $"+chosenitem.buy_value=result) {
            if (player.money >= chosenitem.buy_value) {
              msg ("you bought "+chosenitem.alias+" for $"+chosenitem.buy_value)
              player.money = player.money-chosenitem.buy_value
              AddToInventory (chosenitem)
            }
            else {
              msg ("not enough money")
            }
          }
        }
      }
      else {
        msg ("You have chosen to press cancel")
      }
    }
  }
}
else {
  msg ("there is no shopkeeper around")
}
  1. change sell verb ( for your learning convenience, we only added in a listcount )
shopkeeperaround = false
foreach (merchant, GetDirectChildren(game.pov.parent)) {
  if (HasAttribute(merchant, "shopkeeper")) {
    shopkeeperaround = true
  }
  else {
  }
}
if (shopkeeperaround=true) {
  shop_menu = NewStringList()
  foreach (sellitem, GetDirectChildren(game.pov)) {
    if (HasAttribute(sellitem, "sell_value")) {
      list add (shop_menu, sellitem.alias+" $"+sellitem.sell_value)
    }
  }
  if (ListCount(shop_menu)=0) {
    msg ("there is nothing to sell for now")
  }
  else {
    ShowMenu ("sell what", shop_menu, true) {
      msg ("--" + result + "--")
      if (result<>null) {
        foreach (chosenitem, GetDirectChildren(game.pov)) {
          if (chosenitem.alias+" $"+chosenitem.sell_value=result) {
            msg ("you sold "+chosenitem.alias+" for $"+chosenitem.sell_value)
            player.money = player.money+chosenitem.sell_value
            RemoveObject (chosenitem)
          }
        }
      }
      else {
        msg ("You have chosen to press cancel")
      }
    }
  }
}
else {
  msg ("there is no shopkeeper around")
}

In summary, even though we do not have to write any more codes for any new buying and selling of items, since this code will automatically do it for you
you must still remember to give attributes to items or shopkeeper

list of attributes required

  1. buy_value
  2. sell_value
  3. shopkeeper

Quick demo/ Sample code

To paste the code
Startup your quest gamebook/textadventure, on the right side of the big play button, you can see a code view button
Copy my code to replace the code in the text box, click code view button again.
Viola, it is done, press play button to test out the game and modify the code to your preference.

<!--Saved by Quest 5.8.6836.13983-->
<asl version="580">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="test16">
    <gameid>d1fa92b0-fc94-4d74-822d-558893f309ba</gameid>
    <version>1.0</version>
    <firstpublished>2024</firstpublished>
    <showmoney />
    <start type="script">
      player.money = 10
    </start>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <isroom />
    <enter type="script">
    </enter>
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
      <object name="action">
        <inherit name="editor_object" />
        <displayverbs type="stringlist" />
        <inventoryverbs type="stringlist" />
        <buy type="script"><![CDATA[
          shopkeeperaround = false
          foreach (merchant, GetDirectChildren(game.pov.parent)) {
            if (HasAttribute(merchant, "shopkeeper")) {
              shopkeeperaround = true
            }
            else {
            }
          }
          if (shopkeeperaround=true) {
            shop_menu = NewStringList()
            foreach (buyitem, GetDirectChildren(game.pov.parent)) {
              if (HasAttribute(buyitem, "buy_value")) {
                list add (shop_menu, buyitem.alias+" $"+buyitem.buy_value)
              }
            }
            if (ListCount(shop_menu)=0) {
              msg ("there is nothing to buy for now")
            }
            else {
              ShowMenu ("buy what", shop_menu, true) {
                msg ("--" + result + "--")
                if (result<>null) {
                  foreach (chosenitem, GetDirectChildren(game.pov.parent)) {
                    if (chosenitem.alias+" $"+chosenitem.buy_value=result) {
                      if (player.money >= chosenitem.buy_value) {
                        msg ("you bought "+chosenitem.alias+" for $"+chosenitem.buy_value)
                        player.money = player.money-chosenitem.buy_value
                        AddToInventory (chosenitem)
                      }
                      else {
                        msg ("not enough money")
                      }
                    }
                  }
                }
                else {
                  msg ("You have chosen to press cancel")
                }
              }
            }
          }
          else {
            msg ("there is no shopkeeper around")
          }
        ]]></buy>
        <sell type="script"><![CDATA[
          shopkeeperaround = false
          foreach (merchant, GetDirectChildren(game.pov.parent)) {
            if (HasAttribute(merchant, "shopkeeper")) {
              shopkeeperaround = true
            }
            else {
            }
          }
          if (shopkeeperaround=true) {
            shop_menu = NewStringList()
            foreach (sellitem, GetDirectChildren(game.pov)) {
              if (HasAttribute(sellitem, "sell_value")) {
                list add (shop_menu, sellitem.alias+" $"+sellitem.sell_value)
              }
            }
            if (ListCount(shop_menu)=0) {
              msg ("there is nothing to sell for now")
            }
            else {
              ShowMenu ("sell what", shop_menu, true) {
                msg ("--" + result + "--")
                if (result<>null) {
                  foreach (chosenitem, GetDirectChildren(game.pov)) {
                    if (chosenitem.alias+" $"+chosenitem.sell_value=result) {
                      msg ("you sold "+chosenitem.alias+" for $"+chosenitem.sell_value)
                      player.money = player.money+chosenitem.sell_value
                      RemoveObject (chosenitem)
                    }
                  }
                }
                else {
                  msg ("You have chosen to press cancel")
                }
              }
            }
          }
          else {
            msg ("there is no shopkeeper around")
          }
        ]]></sell>
      </object>
    </object>
    <exit alias="south" to="room1">
      <inherit name="southdirection" />
    </exit>
    <object name="umbrella">
      <inherit name="editor_object" />
      <alias>umbrella</alias>
      <attr name="buy_value" type="int">5</attr>
      <attr name="sell_value" type="int">1</attr>
    </object>
    <object name="scholar">
      <inherit name="editor_object" />
      <shopkeeper type="string"></shopkeeper>
    </object>
  </object>
  <object name="room1">
    <inherit name="editor_room" />
    <exit alias="north" to="room">
      <inherit name="northdirection" />
    </exit>
  </object>
  <verb>
    <property>sell</property>
    <pattern>sell</pattern>
    <defaultexpression>"You can't sell " + object.article + "."</defaultexpression>
  </verb>
</asl>


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

Support

Forums