From 1dbc4997fb1f143b337c0f40e26d2a9e45874a02 Mon Sep 17 00:00:00 2001 From: Tastyfish Date: Sat, 14 Jan 2012 00:54:58 -0500 Subject: [PATCH 1/2] put filing cabinet in correct path in tg standards --- code/WorkInProgress/filing.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/WorkInProgress/filing.dm b/code/WorkInProgress/filing.dm index 5bbfdf29ff..5f6363dadc 100644 --- a/code/WorkInProgress/filing.dm +++ b/code/WorkInProgress/filing.dm @@ -1,4 +1,4 @@ -/obj/filingcabinet +/obj/structure/filingcabinet name = "Filing Cabinet" desc = "A large cabinet with drawers." icon = 'computer.dmi' @@ -6,7 +6,7 @@ density = 1 anchored = 1 -/obj/filingcabinet/attackby(obj/item/weapon/paper/P,mob/M) +/obj/structure/filingcabinet/attackby(obj/item/weapon/paper/P,mob/M) if(istype(P)) M << "You put the [P] in the [src]." M.drop_item() @@ -14,7 +14,7 @@ else M << "You can't put a [P] in the [src]!" -/obj/filingcabinet/attack_hand(mob/user) +/obj/structure/filingcabinet/attack_hand(mob/user) if(src.contents.len <= 0) user << "The [src] is empty." return From df208f718938a01ef80979f027ff892b7d0f618f Mon Sep 17 00:00:00 2001 From: Tastyfish Date: Mon, 16 Jan 2012 20:26:17 -0500 Subject: [PATCH 2/2] added orderable chickens and cows --- baystation12.dme | 1 + code/WorkInProgress/Tastyfish/livestock.dm | 185 +++++++++++++++++++++ code/defines/mob/simple_animal/life.dm | 7 +- code/game/machinery/kitchen/gibber.dm | 105 ++++++++---- code/game/supplyshuttle.dm | 10 +- code/modules/chemical/Chemistry-Tools.dm | 56 ++++++- code/modules/food/food.dm | 7 - code/modules/mob/living/living.dm | 5 +- icons/obj/storage.dmi | Bin 41479 -> 42281 bytes 9 files changed, 335 insertions(+), 41 deletions(-) create mode 100644 code/WorkInProgress/Tastyfish/livestock.dm diff --git a/baystation12.dme b/baystation12.dme index f12f62af8e..ee4c31cdc0 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1015,6 +1015,7 @@ #include "code\WorkInProgress\SkyMarshal\traitoritems.dm" #include "code\WorkInProgress\Tastyfish\Eliza.dm" #include "code\WorkInProgress\Tastyfish\Eliza_Data.dm" +#include "code\WorkInProgress\Tastyfish\livestock.dm" #include "code\WorkInProgress\Tastyfish\paiLiza.dm" #include "code\WorkInProgress\Tastyfish\Parser.dm" #include "code\WorkInProgress\Tastyfish\wallmount_frame.dm" diff --git a/code/WorkInProgress/Tastyfish/livestock.dm b/code/WorkInProgress/Tastyfish/livestock.dm new file mode 100644 index 0000000000..dcabe381ec --- /dev/null +++ b/code/WorkInProgress/Tastyfish/livestock.dm @@ -0,0 +1,185 @@ +// Base Class +/mob/living/simple_animal/livestock + desc = "Tasty!" + icon = 'livestock.dmi' + emote_see = list("shakes its head", "kicks the ground") + speak_chance = 1 + turns_per_move = 15 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + response_help = "pets the" + response_disarm = "gently pushes aside the" + response_harm = "kicks the" + var/max_nutrition = 100 // different animals get hungry faster, basically number of 5-second steps from full to starving (60 == 5 minutes) + var/nutrition_step // cycle step in nutrition system + var/obj/movement_target // eating-ing target + + New() + if(!nutrition) + nutrition = max_nutrition * 0.33 // at 1/3 nutrition + + Life() + ..() + + if(alive) + meat_amount = round(nutrition / 50) + + nutrition_step-- + if(nutrition_step <= 0) + // handle animal digesting + if(nutrition > 0) + nutrition-- + else + health-- + nutrition_step = 50 // only tick this every 5 seconds + + // handle animal eating (borrowed from Ian code) + + // not hungry if full + if(nutrition >= max_nutrition) + return + + if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) )) + movement_target = null + stop_automated_movement = 0 + if( !movement_target || !(movement_target.loc in oview(src, 3)) ) + movement_target = null + stop_automated_movement = 0 + for(var/obj/item/weapon/reagent_containers/food/snacks/S in oview(src,3)) + if(isturf(S.loc) || ishuman(S.loc)) + movement_target = S + break + if(movement_target) + stop_automated_movement = 1 + step_to(src,movement_target,1) + sleep(3) + step_to(src,movement_target,1) + sleep(3) + step_to(src,movement_target,1) + + if(movement_target) //Not redundant due to sleeps, Item can be gone in 6 decisecomds + if (movement_target.loc.x < src.x) + dir = WEST + else if (movement_target.loc.x > src.x) + dir = EAST + else if (movement_target.loc.y < src.y) + dir = SOUTH + else if (movement_target.loc.y > src.y) + dir = NORTH + else + dir = SOUTH + + if(isturf(movement_target.loc)) + movement_target.attack_animal(src) + if(istype(movement_target, /obj/item/weapon/reagent_containers/food/snacks)) + var/obj/item/I = movement_target + I.attack(src, src, "mouth") // eat it, if it's food + + if(a_intent == "hurt") // to make raging critter harm, then disarm, then stop + a_intent = "disarm" + else if(a_intent == "disarm") + a_intent = "help" + movement_target = null + turns_per_move = initial(turns_per_move) + else if(ishuman(movement_target.loc)) + if(prob(20)) + emote("stares at the [movement_target] that [movement_target.loc] has with a longing expression.") + + proc/rage_at(mob/living/M) + movement_target = M // pretty simple + turns_per_move = 1 + emote("becomes enraged") + a_intent = "hurt" + + attackby(var/obj/item/O as obj, var/mob/user as mob) + if(nutrition < max_nutrition && istype(O,/obj/item/weapon/reagent_containers/food/snacks)) + O.attack_animal(src) + else + ..(O, user) + +// Cow +/mob/living/simple_animal/livestock/cow + name = "cow" + icon_state = "cow" + icon_living = "cow" + icon_dead = "cow_d" + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/cow + meat_amount = 10 + max_nutrition = 1000 + speak = list("Moo.","Moooo!","Snort.") + speak_emote = list("moos") + emote_hear = list("moos", "snorts") + + attackby(var/obj/item/O as obj, var/mob/user as mob) + if(istype(O,/obj/item/weapon/reagent_containers/glass)) + var/datum/reagents/R = O:reagents + + R.add_reagent("milk", 50) + nutrition -= 50 + usr << "\blue You milk the cow." + else if(O.force > 0 && O.w_class >= 2) + rage_at(user) + else + ..(O, user) + + attack_hand(var/mob/user as mob) + ..() + if(user.a_intent == "hurt") + rage_at(user) + +/obj/item/weapon/reagent_containers/food/snacks/meat/cow + name = "Beef" + desc = "It's what's for dinner!" + +// Chicken +/mob/living/simple_animal/livestock/chicken + name = "chicken" + icon_state = "chick" + icon_living = "chick" + icon_dead = "chick_d" + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/chicken + meat_amount = 3 + max_nutrition = 200 + speak = list("Bock bock!","Cl-cluck.","Click.") + speak_emote = list("bocks","clucks") + emote_hear = list("bocks", "clucks", "squacks") + +/mob/living/simple_animal/livestock/chicken/Life() + ..() + + // go right before cycle elapses, and if animal isn't starving + if(alive && nutrition_step == 1 && nutrition > max_nutrition / 2) + // lay an egg with probability of 5% in 5 second time period + if(prob(33)) + new/obj/item/weapon/reagent_containers/food/snacks/egg(src.loc) // lay an egg + nutrition -= 5 + +/obj/item/weapon/reagent_containers/food/snacks/meat/chicken + name = "Chicken" + desc = "Tasty!" + +/obj/structure/closet/critter + desc = "A critter crate." + name = "Critter Crate" + icon = 'storage.dmi' + icon_state = "critter" + density = 1 + icon_opened = "critteropen" + icon_closed = "critter" + +/datum/supply_packs/chicken + name = "Chicken crate" + contains = list("/mob/living/simple_animal/livestock/chicken", + "/obj/item/weapon/reagent_containers/food/snacks/grown/corn") + cost = 10 + containertype = "/obj/structure/closet/critter" + containername = "Chicken crate" + group = "Hydroponics" + +/datum/supply_packs/cow + name = "Cow crate" + contains = list("/mob/living/simple_animal/livestock/cow", + "/obj/item/weapon/reagent_containers/food/snacks/grown/corn") + cost = 50 + containertype = "/obj/structure/closet/critter" + containername = "Cow crate" + group = "Hydroponics" diff --git a/code/defines/mob/simple_animal/life.dm b/code/defines/mob/simple_animal/life.dm index bf045bde53..cc8a746abb 100644 --- a/code/defines/mob/simple_animal/life.dm +++ b/code/defines/mob/simple_animal/life.dm @@ -189,8 +189,11 @@ return "[emote], \"[text]\"" return "says, \"[text]\""; -/mob/living/simple_animal/emote(var/act) - if(act) +/mob/living/simple_animal/emote(var/act,var/m_type=1,var/message = null) + if(act == "me") + for (var/mob/O in viewers(src, null)) + O.show_message("[src] [message]") + else if(act) for (var/mob/O in viewers(src, null)) O.show_message("[src] [act].") diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index 7da11995c9..f22e963b13 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -13,7 +13,7 @@ use_power = 1 idle_power_usage = 2 active_power_usage = 500 - + var/emagged = 0 /obj/machinery/gibber/New() ..() @@ -49,20 +49,36 @@ src.startgibbing(user) /obj/machinery/gibber/attackby(obj/item/weapon/grab/G as obj, mob/user as mob) - if(src.occupant) - user << "\red The gibber is full, empty it first!" - return - if (!( istype(G, /obj/item/weapon/grab)) || !(istype(G.affecting, /mob/living/carbon/human))) - user << "\red This item is not suitable for the gibber!" - return - if(G.affecting.abiotic(1)) - user << "\red Subject may not have abiotic items on." + if(istype(G,/obj/item/weapon/card/emag)) + user.visible_message( \ + "\red [user] swipes a strange card through \the [src]'s control panel!", \ + "\red You swipe a strange card through \the [src]'s control panel!", \ + "You hear a scratchy sound.") + emagged = 1 return - user.visible_message("\red [user] starts to put [G.affecting] into the gibber!") + if(src.occupant) + user << "\red \The [src] is full, empty it first!" + return + if (!istype(G, /obj/item/weapon/grab)) + user << "\red This item is not suitable for \the [src]!" + return + if(istype(G.affecting, /mob/living/carbon/human)) + if(!emagged) + user << "\red \The [src] buzzes and spits [G.affecting] back out." + return + if(G.affecting.abiotic(1)) + user << "\red Subject may not have abiotic items on." + return + else if(istype(G.affecting, /mob/living/carbon/monkey) || istype(G.affecting, /mob/living/carbon/alien) || istype(G.affecting, /mob/living/simple_animal)) + // do nothing special + else + user << "\red This item is not suitable for \the [src]!" + + user.visible_message("\red [user] starts to put [G.affecting] into \the [src]!") src.add_fingerprint(user) if(do_after(user, 30) && G && G.affecting && !occupant) - user.visible_message("\red [user] stuffs [G.affecting] into the gibber!") + user.visible_message("\red [user] stuffs [G.affecting] into \the [src]!") var/mob/M = G.affecting if(M.client) M.client.perspective = EYE_PERSPECTIVE @@ -109,21 +125,56 @@ M.show_message("\red You hear a loud squelchy grinding sound.", 1) src.operating = 1 update_icon() - var/sourcename = src.occupant.real_name - var/sourcejob = src.occupant.job - var/sourcenutriment = src.occupant.nutrition / 15 - var/sourcetotalreagents = src.occupant.reagents.total_volume - var/totalslabs = 3 - var/obj/item/weapon/reagent_containers/food/snacks/meat/human/allmeat[totalslabs] - for (var/i=1 to totalslabs) - var/obj/item/weapon/reagent_containers/food/snacks/meat/human/newmeat = new - newmeat.name = sourcename + newmeat.name - newmeat.subjectname = sourcename - newmeat.subjectjob = sourcejob - newmeat.reagents.add_reagent ("nutriment", sourcenutriment / totalslabs) // Thehehe. Fat guys go first - src.occupant.reagents.trans_to (newmeat, round (sourcetotalreagents / totalslabs, 1)) // Transfer all the reagents from the - allmeat[i] = newmeat + var/list/obj/item/weapon/reagent_containers/food/snacks/allmeat = new() + + if(istype(occupant,/mob/living/carbon/human)) + var/sourcename = src.occupant.real_name + var/sourcejob = src.occupant.job + var/sourcenutriment = src.occupant.nutrition / 15 + var/sourcetotalreagents = src.occupant.reagents.total_volume + var/totalslabs = 8 + + for (var/i=1 to totalslabs) + var/obj/item/weapon/reagent_containers/food/snacks/meat/human/newmeat = new() + newmeat.name = sourcename + newmeat.name + newmeat.subjectname = sourcename + newmeat.subjectjob = sourcejob + newmeat.reagents.add_reagent("nutriment", sourcenutriment / totalslabs) // Thehehe. Fat guys go first + src.occupant.reagents.trans_to(newmeat, round(sourcetotalreagents / totalslabs, 1)) // Transfer all the reagents from the + allmeat += newmeat + else if(istype(occupant,/mob/living/carbon/monkey)) + var/sourcename = src.occupant.real_name + var/sourcenutriment = src.occupant.nutrition / 15 + var/sourcetotalreagents = src.occupant.reagents.total_volume + var/totalslabs = 5 + + for (var/i=1 to totalslabs) + var/obj/item/weapon/reagent_containers/food/snacks/meat/monkey/newmeat = new() + newmeat.name = sourcename + newmeat.name + newmeat.reagents.add_reagent("nutriment", sourcenutriment / totalslabs) // Thehehe. Fat guys go first + src.occupant.reagents.trans_to(newmeat, round(sourcetotalreagents / totalslabs, 1)) // Transfer all the reagents from the + allmeat += newmeat + else if(istype(occupant,/mob/living/carbon/alien)) + var/sourcename = src.occupant.real_name + var/sourcenutriment = src.occupant.nutrition / 15 + var/sourcetotalreagents = src.occupant.reagents.total_volume + var/totalslabs = 5 + + for (var/i=1 to totalslabs) + var/obj/item/weapon/reagent_containers/food/snacks/xenomeat/newmeat = new() + newmeat.name = sourcename + newmeat.name + newmeat.reagents.add_reagent("nutriment", sourcenutriment / totalslabs) // Thehehe. Fat guys go first + src.occupant.reagents.trans_to(newmeat, round(sourcetotalreagents / totalslabs, 1)) // Transfer all the reagents from the + allmeat += newmeat + else if(istype(occupant,/mob/living/simple_animal)) + var/sourcenutriment = src.occupant.nutrition / 15 + var/totalslabs = occupant:meat_amount + + for (var/i=1 to totalslabs) + var/obj/item/weapon/reagent_containers/food/snacks/newmeat = new occupant:meat_type() + newmeat.reagents.add_reagent("nutriment", sourcenutriment / totalslabs) // Thehehe. Fat guys go first + allmeat += newmeat src.occupant.death(1) src.occupant.ghostize() @@ -131,7 +182,7 @@ spawn(src.gibtime) playsound(src.loc, 'splat.ogg', 50, 1) operating = 0 - for (var/i=1 to totalslabs) + for (var/i=1 to allmeat.len) var/obj/item/meatslab = allmeat[i] var/turf/Tx = locate(src.x - i, src.y, src.z) meatslab.loc = src.loc @@ -140,5 +191,3 @@ new /obj/effect/decal/cleanable/blood/gibs(Tx,i) src.operating = 0 update_icon() - - diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index e6153220bf..f3fc7c70ff 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -155,7 +155,8 @@ var/list/supply_groups = new() if((locate(/mob/living) in T)) return 0 if((locate(/obj/item/device/radio/beacon) in T)) return 0 for(var/atom/ATM in T) - if((locate(/mob/living) in ATM)) return 0 + if((locate(/mob/living/carbon) in ATM)) return 0 // allow simple_animals to be transported in containers + if((locate(/mob/living/silicon) in ATM)) return 0 if((locate(/obj/item/device/radio/beacon) in ATM)) return 0 return 1 @@ -172,6 +173,10 @@ var/list/supply_groups = new() /obj/item/weapon/paper/manifest name = "Supply Manifest" + New() + ..() + overlays += "paper_words" + /proc/process_supply_order() var/shuttleat = supply_shuttle_at_station ? SUPPLY_STATION_AREATYPE : SUPPLY_DOCK_AREATYPE @@ -187,7 +192,7 @@ var/list/supply_groups = new() var/pickedloc = 0 var/found = 0 for(var/C in markers) - if (locate(/obj/structure/closet/crate) in get_turf(C)) continue + if (locate(/obj/structure/closet) in get_turf(C)) continue found = 1 pickedloc = get_turf(C) if (!found) pickedloc = get_turf(pick(markers)) @@ -305,6 +310,7 @@ var/list/supply_groups = new() var/reason = input(usr,"Reason:","Why do you require this item?","") reqform.name = "Requisition Form - [P.name]" + reqform.overlays += "paper_words" reqform.info += "

[station_name] Supply Requisition Form


" if (istype(usr:wear_id, /obj/item/weapon/card/id)) diff --git a/code/modules/chemical/Chemistry-Tools.dm b/code/modules/chemical/Chemistry-Tools.dm index bfe65f3b68..18475475a6 100644 --- a/code/modules/chemical/Chemistry-Tools.dm +++ b/code/modules/chemical/Chemistry-Tools.dm @@ -731,7 +731,8 @@ /obj/machinery/disposal, /obj/machinery/disease2/incubator, /obj/machinery/disease2/isolator, - /obj/machinery/disease2/biodestroyer + /obj/machinery/disease2/biodestroyer, + /mob/living/simple_animal/livestock/cow ) examine() @@ -1346,7 +1347,60 @@ del(src) playsound(M.loc,'eatfood.ogg', rand(10,50), 1) return 1 + else if(istype(M, /mob/living/simple_animal/livestock)) + if(M == user) //If you're eating it yourself. + var/fullness = (M.nutrition + (M.reagents.get_reagent_amount("nutriment") * 25)) / M:max_nutrition + if (fullness <= 0.1) + M << "\red You hungrily chew out a piece of [src] and gobble it!" + if (fullness > 0.1 && fullness <= 0.27) + M << "\blue You hungrily begin to eat [src]." + if (fullness > 0.27 && fullness <= 0.64) + M << "\blue You take a bite of [src]." + if (fullness > 0.64 && fullness <= 1) + M << "\blue You unwillingly chew a bit of [src]." + if (fullness > 1) + M << "\red You cannot force any more of [src] to go down your throat." + return 0 + else + var/fullness = (M.nutrition + (M.reagents.get_reagent_amount("nutriment") * 25)) / M:max_nutrition + if (fullness <= 1) + for(var/mob/O in viewers(world.view, user)) + O.show_message("\red [user] attempts to feed [M] [src].", 1) + else + for(var/mob/O in viewers(world.view, user)) + O.show_message("\red [user] cannot force anymore of [src] down [M]'s throat.", 1) + return 0 + if(!do_mob(user, M)) return + + M.attack_log += text("\[[time_stamp()]\] Has been fed [src.name] by [user.name] ([user.ckey]) Reagents: \ref[reagents]") + user.attack_log += text("\[[time_stamp()]\] Fed [M.name] by [M.name] ([M.ckey]) Reagents: \ref[reagents]") + + for(var/mob/O in viewers(world.view, user)) + O.show_message("\red [user] feeds [M] [src].", 1) + + if(reagents) //Handle ingestion of the reagent. + if(reagents.total_volume) + reagents.reaction(M, INGEST) + spawn(5) + if(reagents.total_volume > bitesize) + /* + * I totally cannot understand what this code supposed to do. + * Right now every snack consumes in 2 bites, my popcorn does not work right, so I simplify it. -- rastaf0 + var/temp_bitesize = max(reagents.total_volume /2, bitesize) + reagents.trans_to(M, temp_bitesize) + */ + reagents.trans_to(M, bitesize) + else + reagents.trans_to(M, reagents.total_volume) + bitecount++ + On_Consume() + if(!reagents.total_volume) + if(M == user) user << "\red You finish eating [src]." + else user << "\red [M] finishes eating [src]." + del(src) + playsound(M.loc,'eatfood.ogg', rand(10,50), 1) + return 1 return 0 attackby(obj/item/I as obj, mob/user as mob) diff --git a/code/modules/food/food.dm b/code/modules/food/food.dm index bb92d7f53e..f4c354d07d 100644 --- a/code/modules/food/food.dm +++ b/code/modules/food/food.dm @@ -40,13 +40,6 @@ else if(bitecount == 0 || prob(50)) M.emote("nibbles away at the [src]") - bitecount++ - if(bitecount >= 5) - var/speak_emote = pick(M:speak_emote) - var/sattisfaction_text = pick("[speak_emote] for more!", "[speak_emote] from enjoyment.", "looks at the area where the [src] was") - if(sattisfaction_text) - M.emote("[sattisfaction_text]") - del(src) /obj/item/weapon/reagent_containers/food/snacks/candy name = "candy" diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 24a2083bf8..65f228af50 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -165,7 +165,10 @@ return /mob/living/proc/UpdateDamageIcon() - return + return + +/mob/living/attack_animal(mob/M) + attack_paw(M) // treat it like a normal non-human attack /mob/living/verb/change_flavor_text() set name = "Change Flavor Text" diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index c0dd32e8f36ece50564e1d883da96108a5c1d928..8f25d7e0a0e98b659e224c2546285005e6f1177a 100644 GIT binary patch delta 2959 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