ID:723668
 
Keywords: lists, variables
(See the best response by Stephen001.)
Problem description:
I've been working on a merchant system of buying/selling resources and the code length is getting too long. I know of a way to fix it, but I don't know if BYOND actually supports it.

I just want to store variables in a list and index the list rather than having to make a separate if statement for each resource just because I have to put in that resource's unique variables for price and quantity. Is this possible?
The answer to your question is basically "Good God, yes it is. And a much better way of handling merchants."

I assume what you are doing at the minute is something like this?

if <oneitem>
Show the price, ask if they want it
if <a different item>
Show the price, ask if they want it
if <a different item>
Show the price, ask if they want it
if <a different item>
Show the price, ask if they want it


An easier way to do this without the use of multiple if statements and lengthy code is;

-Show the user a list of things the merchant sells.
-Optionally, make this list include pricing (have the list contain [item.name] coupled with [price].)
-When the user picks an item from the list, do your input() statement asking if they'd like to buy it.
-Deduct the gold if so, otherwise return to the list or exit the merchant.


You'll want to use a for list proc followed by Input() to accomplish what your many, many if statements are doing.
Thanks for your reply, Death.

var/b=input("Which resource do you want to buy?") in rlist
switch(b)
if("plastic level 1")
var/c=input("How much of the resource do you want to buy?") in list ("One cargo bay","Two cargo bays","Three cargo bays","Cancel")
switch(c)
if("One cargo bay")
for(var/obj/consoles/merchant_database/M)
if(M.z==usr.z)
usr<<"price: [M.pl1p]"
if(M.pl1p>tcredits)
usr<<"<font color=red><b>Not enough credits to purchase this item!</b></font>"
return
else
if(M.pl1q>=1)
if(c1slots.len>=1)
if(c1contents.len==0)
for(var/obj/c1 in c1slots)
var
i=0
selection
type
for(i=1,i<=1,i++)
selection = rlist[i]
type = rlist[selection]
var/obj/O = new type ()
c1contents.Add(O)
O.loc=c1.loc
spawn(3)
M.pl1q--
M.pl1p=round(M.pl1p*1.1,1)
for(var/obj/consoles/ships_computer/S in world)
if(S.z==usr.oz)
S.credits-=M.pl1p
spawn(1)
usr<<"You now have [S.credits] credits left."
break
usr<<"Thank you for purchasing [b]."
else
usr<<"<font color=red><b>Sorry, but there is not enough in stock to buy that item.</b></font>"
return


The problem isn't much with the organization as it is with the variables. I have separate merchant "databases" that store the quantities of items and their price. The price goes up or down slightly depending on if people are buying or selling it.

The issue is that all these different resources have a price variable and a quantity variable, and I've been putting them in for each resource, but I was wondering if its possible to put them in a list and get the variables that way.
Best response
You really want some datums for this.

Basically, have a bunch of "Product" datums, each for the kind of product that needs selling/buying:

Product
var
item_name
item_type
quantity
price

proc
sell_product(var/mob/player/P)
P.credits -= src.price
var/item = new item_type()
P.contents.Add(item)
item.loc = src.loc
src.decrease_quantity()

decrease_quantity()
src.quantity--
src.price = round(src.price * 1.1)

can_be_bought(var/mob/player/P)
return src.quantity > 0 && src.price <= P.credits

// An example.
obj/vendor
var/list/warez = new()

New()
..()
var/Product/plastic = new()
plastic.item_name = "Plastic"
plastic.item_type = /obj/plastic
plastic.quantity = 100
plastic.price = 10
warez[plastic.item_name] = plastic
var/Product/wood = new()
wood.item_name = "Wood"
wood.item_type = /obj/wood
wood.quantity = 100
wood.price = 10
warez[wood.item_name] = wood

verb
what_are_you_buyin()
set src in oview(1)
var/mob/player/P = usr
var/choice = input("What are you buyin'?") in warez
var/Product/chosen_product = warez[choice]
if (chosen_product.can_be_bought(P))
chosen_product.sell_product(P)
usr << "Much obliged to ya sir!"
else
usr << "You are poor."
view(10) << 'you_are_poor.ogg'


Basically the datums store all pertinent data to a specific stock of a product, for a particular vendor, and controls it's own pricing. The vendor then just needs a list of these.
Thanks, Stephen! I didn't think to do it that way at all. It took me a while to wrap my head around what you were doing but I got it now.