Files
kiwistation/code/game/objects/items/weapons/kitchen.dm
T
MrPerson 9eee3e5067 First pass at a qdel() garbage collection system for tgstation
Works pretty well. If it can't GC something, it'll just del() it and be done.
Speed is amazing, holy shit.

New procs you should be aware of:
qdel(atom/movable) - sets up an object for garbage collection. Call this rather than del(atom/movable).
atom/movable/Destroy() - called right before the object is GC'd, so it still has a loc. Also called if the object is del()'d.
new controller - garbage.dm has all the details on this. Basically it nulls all references on GC'd objects and force del() them if necessary.
Generally speaking, objects should use Destroy() for behavior prior to deletion rather than Del(). You should also always call the parent so the object gets the right gc_destroyed var set.

ISSUES:
Tries to GC mobs atm. This actually works for new players, not so much for humans/monkies/simple_animals/anything. I'm guessing it needs to clear out their mind and HUD and maybe other things.
Gibbing is really bugged. It works, but the overlays just sit there for awhile and ugh. I'm very tempted just to del() mob/living and mob/camera and call it a day.
qdel() equipment doesn't unequip the item.
Pipes don't generally GC correctly. Debugging suggests they get referenced in many pipenets and that isn't cleared properly. However some do work fine. Need assistance here.
Bots don't GC, probably in the radio controller.
Lots of other shit doesn't GC but it's hard to find them because of the pipe spam.
I think I'm calling Destroy() twice by accident.
2014-02-23 14:55:12 -08:00

438 lines
13 KiB
Plaintext

/* Kitchen tools
* Contains:
* Utensils
* Spoons
* Forks
* Knives
* Kitchen knives
* Butcher's cleaver
* Rolling Pins
* Trays
*/
/obj/item/weapon/kitchen
icon = 'icons/obj/kitchen.dmi'
/*
* Utensils
*/
/obj/item/weapon/kitchen/utensil
force = 5.0
w_class = 1.0
throwforce = 0
throw_speed = 3
throw_range = 5
flags = CONDUCT
origin_tech = "materials=1"
attack_verb = list("attacked", "stabbed", "poked")
hitsound = 'sound/weapons/bladeslice.ogg'
/obj/item/weapon/kitchen/utensil/New()
if (prob(60))
src.pixel_y = rand(0, 4)
return
/*
* Spoons
*/
/obj/item/weapon/kitchen/utensil/spoon
name = "spoon"
desc = "SPOON!"
icon_state = "spoon"
attack_verb = list("attacked", "poked")
/*
* Forks
*/
/obj/item/weapon/kitchen/utensil/fork
name = "fork"
desc = "Pointy."
icon_state = "fork"
/obj/item/weapon/kitchen/utensil/fork/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(!istype(M))
return ..()
if(user.zone_sel.selecting != "eyes" && user.zone_sel.selecting != "head")
return ..()
if (src.icon_state == "forkloaded") //This is a poor way of handling it, but a proper rewrite of the fork to allow for a more varied foodening can happen when I'm in the mood. --NEO
if(M == user)
for(var/mob/O in viewers(M, null))
O.show_message(text("\blue [] eats a delicious forkful of omelette!", user), 1)
M.reagents.add_reagent("nutriment", 1)
else
for(var/mob/O in viewers(M, null))
O.show_message(text("\blue [] feeds [] a delicious forkful of omelette!", user, M), 1)
M.reagents.add_reagent("nutriment", 1)
src.icon_state = "fork"
return
else
if((CLUMSY in user.mutations) && prob(50))
M = user
return eyestab(M,user)
/*
* Knives
*/
/obj/item/weapon/kitchen/utensil/knife
name = "knife"
desc = "Can cut through any food."
icon_state = "knife"
force = 10.0
throwforce = 10.0
suicide_act(mob/user)
viewers(user) << pick("<span class='suicide'>[user] is slitting \his wrists with the [src.name]! It looks like \he's trying to commit suicide.</span>", \
"<span class='suicide'>[user] is slitting \his throat with the [src.name]! It looks like \he's trying to commit suicide.</span>", \
"<span class='suicide'>[user] is slitting \his stomach open with the [src.name]! It looks like \he's trying to commit seppuku.</span>")
return (BRUTELOSS)
/obj/item/weapon/kitchen/utensil/knife/attack(target as mob, mob/living/user as mob)
if ((CLUMSY in user.mutations) && prob(50))
user << "\red You accidentally cut yourself with the [src]."
user.take_organ_damage(20)
return
playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
return ..()
/*
* Kitchen knives
*/
/obj/item/weapon/kitchenknife
name = "kitchen knife"
icon = 'icons/obj/kitchen.dmi'
icon_state = "knife"
desc = "A general purpose Chef's Knife made by SpaceCook Incorporated. Guaranteed to stay sharp for years to come."
flags = CONDUCT
force = 10.0
w_class = 3.0
throwforce = 10.0
throw_speed = 3
throw_range = 6
m_amt = 12000
origin_tech = "materials=1"
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
suicide_act(mob/user)
viewers(user) << pick("<span class='suicide'>[user] is slitting \his wrists with the [src.name]! It looks like \he's trying to commit suicide.</span>", \
"<span class='suicide'>[user] is slitting \his throat with the [src.name]! It looks like \he's trying to commit suicide.</span>", \
"<span class='suicide'>[user] is slitting \his stomach open with the [src.name]! It looks like \he's trying to commit seppuku.</span>")
return (BRUTELOSS)
/obj/item/weapon/kitchenknife/ritual
name = "ritual knife"
desc = "The unearthly energies that once powered this blade are now dormant."
icon = 'icons/obj/wizard.dmi'
icon_state = "render"
/*
* Bucher's cleaver
*/
/obj/item/weapon/butch
name = "butcher's cleaver"
icon = 'icons/obj/kitchen.dmi'
icon_state = "butch"
desc = "A huge thing used for chopping and chopping up meat. This includes clowns and clown-by-products."
flags = CONDUCT
force = 15.0
w_class = 2.0
throwforce = 8.0
throw_speed = 3
throw_range = 6
m_amt = 12000
origin_tech = "materials=1"
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("cleaved", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
/*
* Rolling Pins
*/
/obj/item/weapon/kitchen/rollingpin
name = "rolling pin"
desc = "Used to knock out the Bartender."
icon_state = "rolling_pin"
force = 8.0
throwforce = 5.0
throw_speed = 3
throw_range = 7
w_class = 3.0
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") //I think the rollingpin attackby will end up ignoring this anyway.
/obj/item/weapon/kitchen/rollingpin/attack(mob/living/M as mob, mob/living/user as mob)
if ((CLUMSY in user.mutations) && prob(50))
user << "\red The [src] slips out of your hand and hits your head."
user.take_organ_damage(10)
user.Paralyse(2)
return
add_logs(user, M, "attacked", object="[src.name]")
var/t = user:zone_sel.selecting
if (t == "head")
if(ishuman(M))
var/mob/living/carbon/human/H = M
if (H.stat < 2 && H.health < 50 && prob(90))
// ******* Check
if (istype(H, /obj/item/clothing/head) && H.flags & 8 && prob(80))
H << "\red The helmet protects you from being hit hard in the head!"
return
var/time = rand(2, 6)
if (prob(75))
H.Paralyse(time)
else
H.Stun(time)
if(H.stat != 2) H.stat = 1
for(var/mob/O in viewers(H, null))
O.show_message(text("\red <B>[] has been knocked unconscious!</B>", H), 1, "\red You hear someone fall.", 2)
else
H << text("\red [] tried to knock you unconscious!",user)
H.eye_blurry += 3
return
/*
* Trays - Agouri
*/
/obj/item/weapon/tray
name = "tray"
icon = 'icons/obj/food.dmi'
icon_state = "tray"
desc = "A metal tray to lay food on."
throwforce = 10.0
throw_speed = 3
throw_range = 5
w_class = 3.0
flags = CONDUCT
m_amt = 3000
var/list/carrying = list() // List of things on the tray. - Doohl
var/max_carry = 10 // w_class = 1 -- takes up 1
// w_class = 2 -- takes up 3
// w_class = 3 -- takes up 5
/obj/item/weapon/tray/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
// Drop all the things. All of them.
overlays.Cut()
for(var/obj/item/I in carrying)
I.loc = M.loc
carrying.Remove(I)
if(isturf(I.loc))
spawn()
for(var/i = 1, i <= rand(1,2), i++)
if(I)
step(I, pick(NORTH,SOUTH,EAST,WEST))
sleep(rand(2,4))
if((CLUMSY in user.mutations) && prob(50)) //What if he's a clown?
M << "\red You accidentally slam yourself with the [src]!"
M.Weaken(1)
user.take_organ_damage(2)
if(prob(50))
playsound(M, 'sound/items/trayhit1.ogg', 50, 1)
return
else
playsound(M, 'sound/items/trayhit2.ogg', 50, 1) //sound playin'
return //it always returns, but I feel like adding an extra return just for safety's sakes. EDIT; Oh well I won't :3
var/mob/living/carbon/human/H = M ///////////////////////////////////// /Let's have this ready for later.
if(!(user.zone_sel.selecting == ("eyes" || "head"))) //////////////hitting anything else other than the eyes
if(prob(33))
src.add_blood(H)
var/turf/location = H.loc
if (istype(location, /turf/simulated))
location.add_blood(H) ///Plik plik, the sound of blood
add_logs(user, M, "attacked", object="[src.name]")
if(prob(15))
M.Weaken(3)
M.take_organ_damage(3)
else
M.take_organ_damage(5)
if(prob(50))
playsound(M, 'sound/items/trayhit1.ogg', 50, 1)
for(var/mob/O in viewers(M, null))
O.show_message(text("\red <B>[] slams [] with the tray!</B>", user, M), 1)
return
else
playsound(M, 'sound/items/trayhit2.ogg', 50, 1) //we applied the damage, we played the sound, we showed the appropriate messages. Time to return and stop the proc
for(var/mob/O in viewers(M, null))
O.show_message(text("\red <B>[] slams [] with the tray!</B>", user, M), 1)
return
if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.flags & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES)))
M << "\red You get slammed in the face with the tray, against your mask!"
if(prob(33))
src.add_blood(H)
if (H.wear_mask)
H.wear_mask.add_blood(H)
if (H.head)
H.head.add_blood(H)
if (H.glasses && prob(33))
H.glasses.add_blood(H)
var/turf/location = H.loc
if (istype(location, /turf/simulated)) //Addin' blood! At least on the floor and item :v
location.add_blood(H)
if(prob(50))
playsound(M, 'sound/items/trayhit1.ogg', 50, 1)
for(var/mob/O in viewers(M, null))
O.show_message(text("\red <B>[] slams [] with the tray!</B>", user, M), 1)
else
playsound(M, 'sound/items/trayhit2.ogg', 50, 1) //sound playin'
for(var/mob/O in viewers(M, null))
O.show_message(text("\red <B>[] slams [] with the tray!</B>", user, M), 1)
if(prob(10))
M.Stun(rand(1,3))
M.take_organ_damage(3)
return
else
M.take_organ_damage(5)
return
else //No eye or head protection, tough luck!
M << "\red You get slammed in the face with the tray!"
if(prob(33))
src.add_blood(M)
var/turf/location = H.loc
if (istype(location, /turf/simulated))
location.add_blood(H)
if(prob(50))
playsound(M, 'sound/items/trayhit1.ogg', 50, 1)
for(var/mob/O in viewers(M, null))
O.show_message(text("\red <B>[] slams [] in the face with the tray!</B>", user, M), 1)
else
playsound(M, 'sound/items/trayhit2.ogg', 50, 1) //sound playin' again
for(var/mob/O in viewers(M, null))
O.show_message(text("\red <B>[] slams [] in the face with the tray!</B>", user, M), 1)
if(prob(30))
M.Stun(rand(2,4))
M.take_organ_damage(4)
return
else
M.take_organ_damage(8)
if(prob(30))
M.Weaken(2)
return
return
/*
===============~~~~~================================~~~~~====================
= =
= Code for trays carrying things. By Doohl for Doohl erryday Doohl Doohl~ =
= =
===============~~~~~================================~~~~~====================
*/
/obj/item/weapon/tray/proc/calc_carry()
// calculate the weight of the items on the tray
var/val = 0 // value to return
for(var/obj/item/I in carrying)
if(I.w_class == 1.0)
val ++
else if(I.w_class == 2.0)
val += 3
else
val += 5
return val
/obj/item/weapon/tray/pickup(mob/user)
if(!isturf(loc))
return
for(var/obj/item/I in loc)
if( I != src && !I.anchored && !istype(I, /obj/item/clothing/under) && !istype(I, /obj/item/clothing/suit) && !istype(I, /obj/item/projectile) )
var/add = 0
if(I.w_class == 1.0)
add = 1
else if(I.w_class == 2.0)
add = 3
else
add = 5
if(calc_carry() + add >= max_carry)
break
I.loc = src
carrying.Add(I)
overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = 30 + I.layer)
/obj/item/weapon/tray/dropped(mob/user)
var/mob/living/M
for(M in src.loc) //to handle hand switching
return
var/foundtable = 0
for(var/obj/structure/table/T in loc)
foundtable = 1
break
overlays.Cut()
for(var/obj/item/I in carrying)
I.loc = loc
carrying.Remove(I)
if(!foundtable && isturf(loc))
// if no table, presume that the person just shittily dropped the tray on the ground and made a mess everywhere!
spawn()
for(var/i = 1, i <= rand(1,2), i++)
if(I)
step(I, pick(NORTH,SOUTH,EAST,WEST))
sleep(rand(2,4))
/////////////////////////////////////////////////////////////////////////////////////////
//Enough with the violent stuff, here's what happens if you try putting food on it
/////////////////////////////////////////////////////////////////////////////////////////////
/*/obj/item/weapon/tray/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/weapon/kitchen/utensil/fork))
if (W.icon_state == "forkloaded")
user << "\red You already have omelette on your fork."
return
W.icon = 'icons/obj/kitchen.dmi'
W.icon_state = "forkloaded"
viewers(3,user) << "[user] takes a piece of omelette with his fork!"
reagents.remove_reagent("nutriment", 1)
if (reagents.total_volume <= 0)
qdel(src)*/
/* if (prob(33))
var/turf/location = H.loc
if (istype(location, /turf/simulated))
location.add_blood(H)
if (H.wear_mask)
H.wear_mask.add_blood(H)
if (H.head)
H.head.add_blood(H)
if (H.glasses && prob(33))
H.glasses.add_blood(H)
if (istype(user, /mob/living/carbon/human))
var/mob/living/carbon/human/user2 = user
if (user2.gloves)
user2.gloves.add_blood(H)
else
user2.add_blood(H)
if (prob(15))
if (user2.wear_suit)
user2.wear_suit.add_blood(H)
else if (user2.w_uniform)
user2.w_uniform.add_blood(H)*/