ID:952151
 
(See the best response by Kaiochao.)
Code:
                    if("Swords")
switch(input(usr,"Which Sword","Swords")in list("DragonSword","SaviorSword"))
if("SaviorSword")
var/obj/Bar/IronBar/i = locate() in usr
if(i >= 4)
switch(input(usr,"This Will Cost 300Gold Are You Sure You Want To Buy This","Gold")in list("Yes","No"))
if("Yes")
if(usr.Gold >= 299)
usr.contents += new /obj/Swords/SaviorSword
usr<<"You have just smithed the SaviorSword"
usr.contents -= /obj/Bar/IronBar
usr.contents -= /obj/Bar/IronBar
usr.contents -= /obj/Bar/IronBar
usr.contents -= /obj/Bar/IronBar
usr.contents -= /obj/Bar/IronBar
usr.Smithexp += rand(1,20)
usr.Gold -= 300
usr.SmithingSkillCheck()
return
if(usr.Gold == 300)
usr.contents += new /obj/Swords/SaviorSword
usr<<"You have just smithed the SaviorSword"
usr.Gold -= 300
usr.contents -= /obj/Bar/IronBar
usr.contents -= /obj/Bar/IronBar
usr.contents -= /obj/Bar/IronBar
usr.contents -= /obj/Bar/IronBar
usr.contents -= /obj/Bar/IronBar
usr.Smithexp += rand(1,50)
usr.SmithingSkillCheck()
return
if(usr.Gold <= 300)
usr<<"Not Enough Gold"
return
if("No")
return


Problem description:

runtime error: type mismatch: cannot compare IronBar (/obj/Bar/IronBar) to 4
proc name: Smith (/obj/SmithingTable/verb/Smith)
usr: RGS (/mob)
src: SmithingTable (/obj/SmithingTable)
call stack:
SmithingTable (/obj/SmithingTable): Smith()

It's exactly what the error told you, you're trying to compare an object to a number. You can't do that.
How shall i do this young one.
You'd either have to write some kind of stacking system and check against that, or loop over the objects of that type and increment a variable and check against that variable.

Also, your first two if() statements checking the amount of gold do the exact same thing, you only need one of them.

if(gold >= 300)


damn are you serious. They should really make something that can compare number to objects it would make the world easier. >=3
In response to Dr.Penguin
I don't see how that'd be logical at all. I also don't see how exactly that would work either. What would be the basis for compairing the obj to the num?

What you're attempting to do is compair the amount of a type of obj the player has to a number. You're instead singling out objs inside the contents and trying to compair it to 4.
var/i=0
for(typesof(/obj/Bar/Ironbar) in usr.contents)
//Not sure if this would work exactly; it should in theory.
//Haven't attempted to use typeof() in this manner before.
i++
if(i>=4)
//action here
That won't quite work either, typesof() returns a list of types contained at or underneath the passed argument, usr.contents won't contain types, it'll contain actual objects.

var/i = 0
for(var/obj/Bar/Ironbar/found in usr.contents)
i++
if(i >= 4)
// action here


Ideally though, you'd have some kind of stacking system, then you wouldn't have to loop at all.

var/obj/Bar/Ironbar/found = locate() in usr.contents
if(found)
if(found.stack >= 4)
// action
In response to Nadrew
I apologise, it's 6:30am and I've yet to sleep after the bore of a day beforehand. I understand typesof() and that led me to believe for(typesof(path) in list) would cycle through and find each instance of the paths found.

But thank you very much for the clearification. But wouldn't that also mean that his use of usr.contents -= /obj/Bar/Ironbar would not work either? I hadn't attempted use of this either, but saw you neglected to comment on it before.
It probably won't work, yeah. I honestly hadn't even noticed. I'm not sure if it works like overlays where you can get away with that usage, it's been a long time since I did anything so manually that I was removing things like that.
                                var/i = 0
for(var/obj/Bar/Ironbar/found in usr.contents)
i++
if(i >= 4)

No work
In response to Dr.Penguin
Don't copy and paste snippets of code.. they have both provided solutions..
I got way too lazy and just made a var for it to save time -_-
Best response
"locate(type) in List" returns one object in a given container. You can't compare objects to numbers because DM can't know what numeric property you're trying to compare (how many objects in usr? how many objects in the world? what level the object is? how much damage the object does?).

Instead, you can write a simple function to count how many objects of that type are in a given container.
proc/how_many_items(type, List[])
. = 0
for(var/i in 1 to List.len)
if(istype(List[i], type))
. ++

Since that function returns a number, you can compare that to another number.
if(how_many_items(/obj/Bar/IronBar, usr.contents) >= 5)
src << "You have at least 5 iron bars!"
else
src << "You need at least 5 iron bars."


Or for a more specific situation, you can get a list of how many objects of a type you want, out of a container. If there's not enough, just return false.
proc/get_objects(type, amount, container)
var objects[0]
for(var/object in container)
if(istype(object, type))
objects += object
if(objects.len == amount)
return objects
return 0

// Then when you're looking for a certain number of objects...
var bars[] = get_objects(/obj/Bar/IronBar, 5, usr.contents)
if(bars)
src << "You have at least 5 iron bars!"
for(var/bar in bars) del bar
new /obj/Swords/SaviorSword (usr)
else
src << "You don't have enough iron bars!"


Oh, and by the way. Your Gold comparisons are all completely messed up.
if(usr.Gold >= 299) // true when you have 299 or more
if(usr.Gold == 300) // only true when you have 300 exactly
if(usr.Gold <= 300) // true when you have 300 or less

// all you need is
if(usr.Gold >= 300)
// you have 300 or more

else
// you have less than 300


Additionally, you don't seem to properly understand what the 'contents' list is. You shouldn't think of it as something you add or subtract to. When you set an object's location (loc) to something, that means its location has the object in its contents.
var turf/start = locate(5,5,1)
src.loc = start
// src is now in start.contents

When you create an atom, you pass an initial location.
var obj/o = new (src)
// o is now in src.contents. (o in src) == TRUE

var obj/o = new (src.loc)
// o is now in src.loc.contents. (o in src.loc) == TRUE
o.Move(src) // o is now in src (this is a common "get item" function)
o.Move(src.loc) // o is now in src.loc (this is a common "drop item" function)

The contents list is just something you can check to see if an object is "inside" another object. You don't modify it directly, you move objects into and out of other objects. Every time you take a step in a tile-based world, your loc changes, your old loc loses you from its contents list, and your new loc gains you in its contents list.
getting lazy = bad
never get lazy, or if you do stop/dont code :/
itll save you a WHOLE lot of trouble :P