I pinged you with some of this on discord but I figured I should post in here instead of spamming up things there:
1. This is a neat idea!
2. Don't use hasvar() unless you have a really good reason to do so! It just does thing.vars.Find(varname) and that's way less efficient than just typechecking and typecasting for stuff you know has that var (atm only humans have organHolders so there's no reason to hasvar() instead of ishuman())
3. Avoid using colons unless you're REALLY SURE that the var or proc you're trying to look at/use will be on the thing! Probably just don't use them at all!
EX:
Code:
/obj/item/storage/toilet/MouseDrop_T(mob/M as mob, mob/user as mob)
if (!ticker)
boutput(user, "You can't help relieve anyone before the game starts.")
return
if ((!( istype(M, /mob) ) || get_dist(src, user) > 1 || M.loc != src.loc || user.restrained() || usr.stat))
return
if ((M == usr) && (istype(M:w_uniform, /obj/item/clothing/under/gimmick/mario)) && (istype(M:head, /obj/item/clothing/head/mario)))
Last line is the relevant one. Not all mobs have the w_uniform var - only humans do - so if anything other than a human is usr for this proc (IE a cyborg, a ghost drone) a runtime will happen as soon as it gets to that third if() and the proc will just stop.
This is fixed by doing:
Code:
if (M == user && ishuman(user))
var/mob/living/carbon/human/H = user
if (istype(H.w_uniform, /obj/item/clothing/under/gimmick/mario) && istype(H.head, /obj/item/clothing/head/mario))
4. This section of code:
Code:
for (var/mob/O in AIviewers(head, null))
if (prob(33) && ishuman(O))
O.show_message("<span style='color:red'>You feel ill from watching that.</span>")
for (var/mob/V in viewers(O, null))
V.show_message("<span style='color:red'>[O] pukes all over \himself.</span>", 1)
playsound(O.loc, "sound/effects/splat.ogg", 50, 1)
new /obj/decal/cleanable/vomit(O.loc)
I know this just came from another suicide's code, but be careful with just copy/pasting stuff like this without reading what it really does. I had to fix this for handcuffs, because what happens here is:
1. It loops through all mobs (O) that can see the head.
2. It then only does anything to humans, making looping through all mob types pointless (you can do "for (var/mob/living/carbon/human/O in AIviewers(head, null))")
3. Shows O a message.
4. Loops through all mobs (V) that can see O.
5. Shows V a message.
6. Plays a sound at O's loc
for V.
7. Makes a vomit decal at O's loc
for V.
What this means is that, if 4 people and 3 ghosts can see O,
O will play 7 sounds and make 7 decals at their location.
I'll be implementing this after cleaning it up a little bit to deal with this stuff.