ID:1378219
 
(See the best response by Ter13.)
Code:
if("Sell Items")
var/obj/I=input("What would you like to sell?","Sell to Shopkeeper") in usr.contents + "Cancel"
if(I=="Cancel")
usr<<"You sell nothing."
return ..()
else
if(!I.worn)
switch(input("Are you sure you'd like to sell this [I] for [num2text(I.value,20)] gold?","Shopkeeper") in list ("Yes","No"))
if("Yes")
usr.contents-=I
usr.spaces--
usr.gold+=I.value
usr<<"\green You sell your [I] for [num2text(I.value,20)] gold."
if("No")
return ..()
else
return ..()
else
usr<<"\red You must first unequip your [I] before trying to sell it."


Problem description:
This code works perfectly fine for its purposes, but the issue comes in when a user has more than one of an item to sell and the first of those is equipped. Is there a way to make this code so that it will continue checking for others of the same object type in usr.contents instead of stopping at the first?

To illustrate:

1:
-user has two swords, first is equipped
-user tries to sell a sword, cannot

2:
-usr has two swords, second is equipped
-user tries to sell a sword, can

Any ideas? :/
You can loop through your inventory and fill up a custom list with all of the objects you aren't wearing, then have them select from that list.
In response to Albro1
Albro1 wrote:
You can loop through your inventory and fill up a custom list with all of the objects you aren't wearing, then have them select from that list.

Right, that's what I figured, but how do I actually make it loop through the inventory?
This would be a quick way to do it. Honestly, though, I would recommend removing equipped items from the user's contents when they are equipped, and keeping them in a separate list.

for(var/obj/o in usr.contents)
if(I.type==o.type)
if(!o.worn)
I = o
break
if(I.worn)
//we couldn't find a version of I that isn't worn.
else
//we managed to find a version of I that isn't worn.
In response to Ter13
Ter13 wrote:
This would be a quick way to do it. Honestly, though, I would recommend removing equipped items from the user's contents when they are equipped, and keeping them in a separate list.

> for(var/obj/o in usr.contents)
> if(I.type==o.type)
> if(!o.worn)
> I = o
> break
> if(I.worn)
> //we couldn't find a version of I that isn't worn.
> else
> //we managed to find a version of I that isn't worn.
>


Almost perfect! The only issue now is that it still gives me the error for the worn equipment before allowing me to sell the non-worn equipment. Here's the code I have:

                                    for(var/obj/O in usr.contents)
if(I.type==O.type)
if(!O.worn)
I = O
switch(input("Are you sure you'd like to sell this [I] for [num2text(I.value,20)] gold?","Shopkeeper") in list ("Yes","No"))
if("Yes")
usr.contents-=I
usr.spaces--
usr.gold+=I.value
usr<<"\green You sell your [I] for [num2text(I.value,20)] gold."
if("No")
return ..()
else
return ..()
break
if(I.worn)
usr<<"\red You must first unequip your [I] before trying to sell it."
That is because it is reaching the one you have equipped before it reaches the one you don't.

You have two main options here - go with Ter's suggestion of keeping the inventory and worn items separate (Which is probably the better suggestion for the long-run), or loop through the contents and fill up a var/list with the items that aren't worn and have them pick from that list.
In response to Albro1
Albro1 wrote:
That is because it is reaching the one you have equipped before it reaches the one you don't.

You have two main options here - go with Ter's suggestion of keeping the inventory and worn items separate (Which is probably the better suggestion for the long-run), or loop through the contents and fill up a var/list with the items that aren't worn and have them pick from that list.

Well...I've been planning on making a separate tab for worn equipment anyway, so I'll just forget about the tmp list for now and go with that when I get to it. Thanks for the help, guys =D
Best response
var/obj/I=input("What would you like to sell?","Sell to Shopkeeper") as obj|null in usr.contents 
if(I!=null)
if(I.worn)
for(var/obj/O in usr.contents)
if(!O.worn)
I = O
break
if(I.worn)
usr<<"\red You must first unequip your [I] before trying to sell it."
return ..()
switch(alert("Are you sure you'd like to sell this [I] for [I.value] gold?","Shopkeeper","Yes","No"))
if("Yes")
usr.contents -= I
usr.spaces--
usr.gold+= I.value
usr<<"\green You sell your [I] for [I.value)] gold."
if("No")
return ..()
else
usr<<"You sell nothing."
return ..()


You were using the loop wrong. You don't need to put the resulting behavior inside of the loop. Since you are only performing the alert/switch once, there's no need for it to be in the loop.

Instead, we hunt through the contents, find a suitable item, forcibly exit the loop using break, then we check if we found a suitable item after the loop, and if we did, we perform the resulting switch.

I also wanted to show you some additional features of the input(), which allows you to add a cancel button (By adding |null to the as type.), and the alert() function allows you to do yes/no prompts a bit more elegantly.
In response to Ter13
Working absolutely perfectly now! The only things I did differently than what you showed me were the obj|null because that came back with errors no matter what I tried and everything below the switch statement, I indented less so that I could sell items that aren't equipped, too :P

Thanks so much for your help!!!!