introduction
you only have to write 1 buy code no matter how big your game gets
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) {
}
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")
}
}
player.money=10
for the extra challenge, we will add in sell_value
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")
}
}
for the logical ones, we will add in shopkeeper
because players shouldn't be able to buy or sell items without a shopkeeper
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")
}
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'
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")
}
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
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>