diff --git a/baystation12.dme b/baystation12.dme index 97ffa020d64..a780bc568a6 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 00000000000..dcabe381eca --- /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 5bbfdf29ff9..5f6363dadc6 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 bf045bde534..cc8a746abb6 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/defines/turf.dm b/code/defines/turf.dm index 87c7f682868..ea30f6e5368 100644 --- a/code/defines/turf.dm +++ b/code/defines/turf.dm @@ -1,253 +1,259 @@ -/turf - icon = 'floors.dmi' - var/intact = 1 //for floors, use is_plating(), is_steel_floor() and is_light_floor() - - level = 1.0 - - var - //Properties for open tiles (/floor) - oxygen = 0 - carbon_dioxide = 0 - nitrogen = 0 - toxins = 0 - - //Properties for airtight tiles (/wall) - thermal_conductivity = 0.05 - heat_capacity = 1 - - //Properties for both - temperature = T20C - - blocks_air = 0 - icon_old = null - pathweight = 1 - - proc/is_plating() - return 0 - proc/is_asteroid_floor() - return 0 - proc/is_steel_floor() - return 0 - proc/is_light_floor() - return 0 - proc/is_grass_floor() - return 0 - proc/return_siding_icon_state() - return 0 - -/turf/space - icon = 'space.dmi' - name = "space" - icon_state = "placeholder" - - temperature = TCMB - thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT - heat_capacity = 700000 - -/turf/space/New() -// icon = 'space.dmi' - icon_state = "[pick(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)]" - -/turf/simulated - name = "station" - var/wet = 0 - var/image/wet_overlay = null - - var/thermite = 0 - oxygen = MOLES_O2STANDARD - nitrogen = MOLES_N2STANDARD - var/to_be_destroyed = 0 //Used for fire, if a melting temperature was reached, it will be destroyed - var/max_fire_temperature_sustained = 0 //The max temperature of the fire which it was subjected to - - - -/turf/simulated/wall/r_wall - name = "r wall" - desc = "A huge chunk of reinforced metal used to seperate rooms." - icon_state = "r_wall" - opacity = 1 - density = 1 - - walltype = "rwall" - - var/d_state = 0 - -/turf/simulated/wall - name = "wall" - desc = "A huge chunk of metal used to seperate rooms." - icon = 'walls.dmi' - opacity = 1 - density = 1 - blocks_air = 1 - - thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT - heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m steel wall - - var/walltype = "wall" - -/turf/simulated/shuttle - name = "shuttle" - icon = 'shuttle.dmi' - thermal_conductivity = 0.05 - heat_capacity = 0 - -/turf/simulated/shuttle/wall - name = "wall" - icon_state = "wall1" - opacity = 1 - density = 1 - blocks_air = 1 - -/turf/simulated/shuttle/floor - name = "floor" - icon_state = "floor" - -/turf/simulated/shuttle/floor4 // Added this floor tile so that I have a seperate turf to check in the shuttle -- Polymorph - name = "Brig floor" // Also added it into the 2x3 brig area of the shuttle. - icon_state = "floor4" - -/turf/unsimulated - intact = 1 - name = "command" - oxygen = MOLES_O2STANDARD - nitrogen = MOLES_N2STANDARD - -/turf/unsimulated/floor - name = "floor" - icon = 'floors.dmi' - icon_state = "Floor3" - -/turf/unsimulated/wall - name = "wall" - icon = 'walls.dmi' - icon_state = "riveted" - opacity = 1 - density = 1 - -/turf/unsimulated/wall/other - icon_state = "r_wall" - -/turf/proc - AdjacentTurfs() - var/L[] = new() - for(var/turf/simulated/t in oview(src,1)) - if(!t.density) - if(!LinkBlocked(src, t) && !TurfBlockedNonWindow(t)) - L.Add(t) - return L - Distance(turf/t) - if(get_dist(src,t) == 1) - var/cost = (src.x - t.x) * (src.x - t.x) + (src.y - t.y) * (src.y - t.y) - cost *= (pathweight+t.pathweight)/2 - return cost - else - return get_dist(src,t) - AdjacentTurfsSpace() - var/L[] = new() - for(var/turf/t in oview(src,1)) - if(!t.density) - if(!LinkBlocked(src, t) && !TurfBlockedNonWindow(t)) - L.Add(t) - return L - - - -/turf/simulated/wall/mineral - icon = 'mineral_walls.dmi' - walltype = "iron" - - var/oreAmount = 1 - var/hardness = 1 - - New() - ..() - name = "[walltype] wall" - - dismantle_wall(devastated = 0) - if(!devastated) - var/ore = text2path("/obj/item/weapon/ore/[walltype]") - for(var/i = 1, i <= oreAmount, i++) - new ore(src) - ReplaceWithFloor() - else - ReplaceWithSpace() - - attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W,/obj/item/weapon/pickaxe)) - var/obj/item/weapon/pickaxe/digTool = W - user << "You start digging the [name]." - if(do_after(user,digTool.digspeed*hardness) && src) - user << "You finished digging." - dismantle_wall() - else if(istype(W,/obj/item/weapon)) //not sure, can't not just weapons get passed to this proc? - hardness -= W.force/100 - user << "You hit the [name] with your [W.name]!" - CheckHardness() - else - attack_hand(user) - return - - proc/CheckHardness() - if(hardness <= 0) - dismantle_wall() - -/turf/simulated/wall/mineral/iron - walltype = "iron" - hardness = 3 - -/turf/simulated/wall/mineral/silver - walltype = "silver" - hardness = 3 - -/turf/simulated/wall/mineral/uranium - walltype = "uranium" - hardness = 3 - - New() - ..() - sd_SetLuminosity(3) - -/turf/simulated/wall/mineral/gold - walltype = "gold" - -/turf/simulated/wall/mineral/sand - walltype = "sand" - hardness = 0.5 - -/turf/simulated/wall/mineral/transparent - opacity = 0 - -/turf/simulated/wall/mineral/transparent/diamond - walltype = "diamond" - hardness = 10 - -/turf/simulated/wall/mineral/transparent/plasma - walltype = "plasma" - - attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W,/obj/item/weapon/weldingtool)) - if(W:welding) - return TemperatureAct(100) - ..() - - temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(exposed_temperature > 300) - TemperatureAct(exposed_temperature) - - proc/TemperatureAct(temperature) - for(var/turf/simulated/floor/target_tile in range(2,loc)) - if(target_tile.parent && target_tile.parent.group_processing) - target_tile.parent.suspend_group_processing() - - var/datum/gas_mixture/napalm = new - - var/toxinsToDeduce = temperature/10 - - napalm.toxins = toxinsToDeduce - napalm.temperature = 400+T0C - - target_tile.assume_air(napalm) - spawn (0) target_tile.hotspot_expose(temperature, 400) - - hardness -= toxinsToDeduce/100 - CheckHardness() +/turf + icon = 'floors.dmi' + var/intact = 1 //for floors, use is_plating(), is_steel_floor() and is_light_floor() + + level = 1.0 + + var + //Properties for open tiles (/floor) + oxygen = 0 + carbon_dioxide = 0 + nitrogen = 0 + toxins = 0 + + //Properties for airtight tiles (/wall) + thermal_conductivity = 0.05 + heat_capacity = 1 + + //Properties for both + temperature = T20C + + blocks_air = 0 + icon_old = null + pathweight = 1 + + proc/is_plating() + return 0 + proc/is_asteroid_floor() + return 0 + proc/is_steel_floor() + return 0 + proc/is_light_floor() + return 0 + proc/is_grass_floor() + return 0 + proc/return_siding_icon_state() + return 0 + +/turf/space + icon = 'space.dmi' + name = "space" + icon_state = "placeholder" + + temperature = TCMB + thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT + heat_capacity = 700000 + +/turf/space/New() +// icon = 'space.dmi' + icon_state = "[pick(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)]" + +/turf/simulated + name = "station" + var/wet = 0 + var/image/wet_overlay = null + + var/thermite = 0 + oxygen = MOLES_O2STANDARD + nitrogen = MOLES_N2STANDARD + var/to_be_destroyed = 0 //Used for fire, if a melting temperature was reached, it will be destroyed + var/max_fire_temperature_sustained = 0 //The max temperature of the fire which it was subjected to + + + +/turf/simulated/wall/r_wall + name = "r wall" + desc = "A huge chunk of reinforced metal used to seperate rooms." + icon_state = "r_wall" + opacity = 1 + density = 1 + + walltype = "rwall" + + var/d_state = 0 + +/turf/simulated/wall + name = "wall" + desc = "A huge chunk of metal used to seperate rooms." + icon = 'walls.dmi' + opacity = 1 + density = 1 + blocks_air = 1 + + thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT + heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m steel wall + + var/walltype = "wall" + +/turf/simulated/shuttle + name = "shuttle" + icon = 'shuttle.dmi' + thermal_conductivity = 0.05 + heat_capacity = 0 + +/turf/simulated/shuttle/wall + name = "wall" + icon_state = "wall1" + opacity = 1 + density = 1 + blocks_air = 1 + +/turf/simulated/shuttle/floor + name = "floor" + icon_state = "floor" + +/turf/simulated/shuttle/floor4 // Added this floor tile so that I have a seperate turf to check in the shuttle -- Polymorph + name = "Brig floor" // Also added it into the 2x3 brig area of the shuttle. + icon_state = "floor4" + +/turf/unsimulated + intact = 1 + name = "command" + oxygen = MOLES_O2STANDARD + nitrogen = MOLES_N2STANDARD + +/turf/unsimulated/floor + name = "floor" + icon = 'floors.dmi' + icon_state = "Floor3" + +/turf/unsimulated/wall + name = "wall" + icon = 'walls.dmi' + icon_state = "riveted" + opacity = 1 + density = 1 + +/turf/unsimulated/wall/other + icon_state = "r_wall" + +/turf/proc + AdjacentTurfs() + var/L[] = new() + for(var/turf/simulated/t in oview(src,1)) + if(!t.density) + if(!LinkBlocked(src, t) && !TurfBlockedNonWindow(t)) + L.Add(t) + return L + + Distance(turf/t) + if(get_dist(src,t) == 1) + var/cost = (src.x - t.x) * (src.x - t.x) + (src.y - t.y) * (src.y - t.y) + cost *= (pathweight+t.pathweight)/2 + return cost + + else + return get_dist(src,t) + + Distance_ortho(turf/t) + return abs(src.x - t.x) + abs(src.y - t.y) + + AdjacentTurfsSpace() + var/L[] = new() + for(var/turf/t in oview(src,1)) + if(!t.density) + if(!LinkBlocked(src, t) && !TurfBlockedNonWindow(t)) + L.Add(t) + return L + + + +/turf/simulated/wall/mineral + icon = 'mineral_walls.dmi' + walltype = "iron" + + var/oreAmount = 1 + var/hardness = 1 + + New() + ..() + name = "[walltype] wall" + + dismantle_wall(devastated = 0) + if(!devastated) + var/ore = text2path("/obj/item/weapon/ore/[walltype]") + for(var/i = 1, i <= oreAmount, i++) + new ore(src) + ReplaceWithFloor() + else + ReplaceWithSpace() + + attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W,/obj/item/weapon/pickaxe)) + var/obj/item/weapon/pickaxe/digTool = W + user << "You start digging the [name]." + if(do_after(user,digTool.digspeed*hardness) && src) + user << "You finished digging." + dismantle_wall() + else if(istype(W,/obj/item/weapon)) //not sure, can't not just weapons get passed to this proc? + hardness -= W.force/100 + user << "You hit the [name] with your [W.name]!" + CheckHardness() + else + attack_hand(user) + return + + proc/CheckHardness() + if(hardness <= 0) + dismantle_wall() + +/turf/simulated/wall/mineral/iron + walltype = "iron" + hardness = 3 + +/turf/simulated/wall/mineral/silver + walltype = "silver" + hardness = 3 + +/turf/simulated/wall/mineral/uranium + walltype = "uranium" + hardness = 3 + + New() + ..() + sd_SetLuminosity(3) + +/turf/simulated/wall/mineral/gold + walltype = "gold" + +/turf/simulated/wall/mineral/sand + walltype = "sand" + hardness = 0.5 + +/turf/simulated/wall/mineral/transparent + opacity = 0 + +/turf/simulated/wall/mineral/transparent/diamond + walltype = "diamond" + hardness = 10 + +/turf/simulated/wall/mineral/transparent/plasma + walltype = "plasma" + + attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W,/obj/item/weapon/weldingtool)) + if(W:welding) + return TemperatureAct(100) + ..() + + temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + if(exposed_temperature > 300) + TemperatureAct(exposed_temperature) + + proc/TemperatureAct(temperature) + for(var/turf/simulated/floor/target_tile in range(2,loc)) + if(target_tile.parent && target_tile.parent.group_processing) + target_tile.parent.suspend_group_processing() + + var/datum/gas_mixture/napalm = new + + var/toxinsToDeduce = temperature/10 + + napalm.toxins = toxinsToDeduce + napalm.temperature = 400+T0C + + target_tile.assume_air(napalm) + spawn (0) target_tile.hotspot_expose(temperature, 400) + + hardness -= toxinsToDeduce/100 + CheckHardness() diff --git a/code/game/machinery/bots/cleanbot.dm b/code/game/machinery/bots/cleanbot.dm index 78b31ac8b69..1580c00c0aa 100644 --- a/code/game/machinery/bots/cleanbot.dm +++ b/code/game/machinery/bots/cleanbot.dm @@ -232,7 +232,7 @@ text("[src.oddbutton ? "Yes" : "No" if (!next_dest_loc) next_dest_loc = closest_loc if (next_dest_loc) - src.patrol_path = AStar(src.loc, next_dest_loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id=botcard, exclude=null) + src.patrol_path = AStar(src.loc, next_dest_loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_ortho, 0, 120, id=botcard, exclude=null) src.patrol_path = reverselist(src.patrol_path) else patrol_move() diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index 4143f4e5de0..e588570cf95 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -563,7 +563,7 @@ Auto Patrol: []"}, // calculates a path to the current destination // given an optional turf to avoid /obj/machinery/bot/ed209/proc/calc_path(var/turf/avoid = null) - src.path = AStar(src.loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id=botcard, exclude=avoid) + src.path = AStar(src.loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_ortho, 0, 120, id=botcard, exclude=avoid) src.path = reverselist(src.path) diff --git a/code/game/machinery/bots/medbot.dm b/code/game/machinery/bots/medbot.dm index 8e4381baf24..8c211975961 100644 --- a/code/game/machinery/bots/medbot.dm +++ b/code/game/machinery/bots/medbot.dm @@ -296,7 +296,7 @@ if(src.patient && src.path.len == 0 && (get_dist(src,src.patient) > 1)) spawn(0) - src.path = AStar(src.loc, get_turf(src.patient), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30,id=botcard) + src.path = AStar(src.loc, get_turf(src.patient), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_ortho, 0, 30,id=botcard) src.path = reverselist(src.path) if(src.path.len == 0) src.oldpatient = src.patient diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index eec60faf6f0..909dcce3ded 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -694,7 +694,7 @@ // calculates a path to the current destination // given an optional turf to avoid /obj/machinery/bot/mulebot/proc/calc_path(var/turf/avoid = null) - src.path = AStar(src.loc, src.target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 250, id=botcard, exclude=avoid) + src.path = AStar(src.loc, src.target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_ortho, 0, 250, id=botcard, exclude=avoid) src.path = reverselist(src.path) diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index 03208420a67..e926bea08cb 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -543,7 +543,7 @@ Auto Patrol: []"}, // calculates a path to the current destination // given an optional turf to avoid /obj/machinery/bot/secbot/proc/calc_path(var/turf/avoid = null) - src.path = AStar(src.loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id=botcard, exclude=avoid) + src.path = AStar(src.loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance_ortho, 0, 120, id=botcard, exclude=avoid) src.path = reverselist(src.path) diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index 7da11995c97..f22e963b133 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 e6153220bf6..f3fc7c70ff5 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 7526951920a..6363f943988 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 bb92d7f53ec..f4c354d07d0 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 24a2083bf8f..65f228af505 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/stationobjs.dmi b/icons/obj/stationobjs.dmi index d244526134d..3653168102e 100644 Binary files a/icons/obj/stationobjs.dmi and b/icons/obj/stationobjs.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index c0dd32e8f36..8f25d7e0a0e 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ