ID:2086663
 
(See the best response by Ter13.)
Code:
obj/scroll/recipe
minor_hp_potion
icon = 'Icons.dmi'
icon_state = "Scroll1"
var/materials
verb
Get()
set src in oview(1)
usr.contents += src
Use()
var/a = /obj/food/mushroom/red_mushroom
var/b = /obj/alchemy/slime
if(a && b in usr.contents)
new /obj/potion/hp/minor_hp_potion(usr.loc)


Problem description: Could someone show me what I did wrong and point me in the right direction? I have no errors or warnings, but the new item doesn't show up in game.

Certainly at least one problem is this.
if(a && b in usr.contents)

This is parsed as
if(a && (b in usr.contents))

The second is that neither of those typepaths will be in usr.contents, even though items of that time may be.
Best response
Let's talk generics. You are going to want to minimize the amount of work you need to do for each recipe by using generic behavior.

obj/item
var
usable = 0
verb
Get()
set src in oview(1)
if(isturf(loc))
loc = usr

Drop()
set src in usr
if(loc==usr)
loc = usr.loc

Use()
set src in usr
New()
if(!usable) verbs -= /obj/item/verb/Use
..()


You don't want to redefine the get/drop business for every single item. Just define it on a root type like /obj/item.

Now let's create a crafting recipe with the generic behavior out of the way:
obj/item/scroll/recipe
usable = 1
var
list/ingredients
creates
proc
Craft(mob/m)
var/list/inv = m.contents.Copy()
var/list/found = list()
var/obj/item
for(var/t in ingredients)
item = locate(t) in inv
if(item)
inv -= item
found += item
else
return null
for(var/obj/i in inv)
del i
return new creates()
Use()
set src in usr
if(loc==usr)
var/obj/item/i = Craft(usr)
if(i) i.loc = usr


Now let's set up a recipe:

obj/item/scroll/recipe
minor_hp_potion
ingredients = list(/obj/item/food/mushroom/red_mushroom,/obj/item/alchemy/slime)
creates = /obj/item/potion/hp/minor_hp_potion


And there you have it. No need to rewrite your code for every possible recipe. Set it up once and forget about it.
It's probably also important to note that the |= operator allows you to add something to a list only if it isn't already in the list, even though it's only a safety check and isn't typically necessary.

e.g.
mob/verb/joinGroup()
usr.group |= src
Of course there is a downside to defining recipes in this way: the ingredients list is initialized at runtime, in a hidden init proc. If a lot of these run when your world begins, it can slow things down. But it's a pretty simple way to get it setup.

Another option you have with crafting is using associative lists. If you want to use 2 of an item, rather than adding it twice to the list you could set /obj/item/blah=2 and then modify your crafting like so:

    proc
Craft(mob/m)
var/list/inv = m.contents.Copy()
var/list/found = list()
var/obj/item
for(var/t in ingredients)
var/quantity = ingredients[t] || 1
while(quantity-- > 0)
item = locate(t) in inv
if(item)
inv -= item
found += item
else
return null
for(item in inv)
del item
return new creates()

Of course crafting can be as complex as you like: creating multiple items in a single reaction, adding catalysts, factoring in chances for failure and other items you might get as a result, etc.

If your game gets very big, you may want to get away from hard-coding things and instead move toward putting your recipes, and even many of your items, in a file that you can read as needed.