diff --git a/baystation12.dme b/baystation12.dme index 97ffa020d6..a780bc568a 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1021,6 +1021,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/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 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 7526951920..6363f94398 100644 --- a/code/modules/chemical/Chemistry-Tools.dm +++ b/code/modules/chemical/Chemistry-Tools.dm @@ -722,7 +722,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() @@ -1339,7 +1340,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 c0dd32e8f3..8f25d7e0a0 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ