ID:142855
 
Code:
mob
proc
ItemChance(mob/player/P,mob/monsters/M)
var/chance1 = rand(1.20)
var/chance2 = rand(5,5)
var/continues = 1
if(chance2 == 5)
var/obj/O
if(M.drop2)
O = new M.drop2
else
return
if(istype(O,/obj/keys))
world << "Here"
if(!(O.type in P.keys))
AddInfo(P,"An item drops from the monster!","It's a [O]!")
sleep(12)
O.Hloc = P.keys
continues = 0
else
AddInfo(P,"An item drops from the monster!","It is a [O]!")
sleep(12)
O.loc = P.contents
continues = 0
else if(chance1 == 10 && continues == 1)
var/obj/O
if(M.drop1)
O = new M.drop1
else
return
AddInfo(P,"An item drops from the monster!","It is a [O]!")
sleep(12)
O.loc = P.contents


Problem description:
The code is simple. The mob (monster) has one or two drop items defined by drop1 and drop2 variables in it's specs. What this code does is that it checks the two chance variables chance1 and chance2, basically a percentage thing. if chance2 is good, they get drop2, and if chance1 is good, they get drop1. The problem is that drop2 can be a key to progress into the game, and as such I want the key to enter a special Key inventory (P.keys). ALL of this code works except for the fact that the keys do not enter the key inventory, or any inventory for that matter. At least, as far as I know, they do not. How do I know? I have a statpanel named Keys that is P.keys, that's it, much like an Inventory statpanel where you make it P.contents (I'm saying this as if P is the player, so the Player's inventory/keys/whatever) Nothing ever shows up in the Keys statpanel AND the code continues to give me more of the key, so nothing ever enters P.keys.

Before anyone tries to tell me about my rands and such, chance2 is rand(5,5) FOR A REASON. SO I CAN TEST IT. PLEASE DO NOT TELL ME ABOUT IT I KNOW.

/*
associated list containing types of mobs and a list of what
they drop, which itself is an associated list of drop types
and their probabilities
*/


var/const/list/drops = list(
/mob/something = list(/item/item1 = 100, /item/item2 = 10),
/mob/somethingelse = list(/item/item1 = 20, /item/item3 = 50)
)

mob
player
//an obj to keep track of keys
var/obj/keyring = new()

//an item is any obj which can be picked up in some way
item
proc
//give src to M
acquire(var/mob/M)
//obviously simple in the basic case
loc = M
M << "You get \a [src]"
key
//keys go into a player's keyring, not their contents
acquire(var/mob/player/M)
//only players can hold keys
if(istype(M))
//a player can only have one key of each type
if(!(locate(src.type) in M.keyring))
loc = M.keyring
M << "You get \a [src]"

mob
proc
//generate up to [max] (0 is unlimited) items that this mob drops and give them to receiver
createdrops(var/mob/receiver, var/max = 0)
//obviously, the receiver needs to exist
if(!receiver) return
//get the list of possible drops associated with our type from the global drops list
var/list/lootlist = drops[src.type]
//also obviously, we need the list
if(lootlist)
//go through each item type in lootlist
for(var/type in lootlist)
//with the associated probability...
if(prob(lootlist[type]))
//create the item and give it to the player
var/item/I = new(type)
I.acquire(receiver)
//break if we've created enough items
if(--max == 0) break


That's a much more robust solution. The specific problem I believe you were having was that the location of an atom can't be a list. A list can only contain references to objects, not the objects themselves.
In response to Garthor
Thanks, I'll see how I can work that in. In the meanwhile, I have a question then: How does mob.contents work then?
In response to Polantaris
It's a special list. It behaves in the same way as obj.contents, almost the same way as turf.contents, and vaguely similar to area.contents.
In response to Garthor
I used the example you showed me an incorperated an obj/keyring type thing into my code. Now I do get the items to go into the list and everything as wanted, but now I have a different problem:
if(istype(O,/obj/keys))
if(!(O in P.keyring))
AddInfo(P,"An item drops from the beast!","It's a [O]!")
sleep(12)
O.loc = P.keyring
continues = 0

The problem is that the if(!(O in P.keyring)) doesn't work. I don't really know why, but it always comes out as true, even if I have 1+ of the item in my keyring already. I tried several variations of this changing O to O.type and P.keyring to P.keyring.contents and all the such combinations with this. None work.
In response to Polantaris
O in P.keyring won't be true because that specific object is not in the keyring. You need to use locate() to find another key of the same type (see: my example).
In response to Garthor
There we go, now it works. Thanks.