diff --git a/code/modules/mob/living/basic/snails/snail.dm b/code/modules/mob/living/basic/snails/snail.dm index 4d12c928c34..cd721d9b98d 100644 --- a/code/modules/mob/living/basic/snails/snail.dm +++ b/code/modules/mob/living/basic/snails/snail.dm @@ -10,6 +10,8 @@ icon = 'icons/mob/simple/pets.dmi' butcher_results = list(/obj/item/food/meat/slab/bugmeat = 1) mob_biotypes = MOB_ORGANIC + density = FALSE + pass_flags = PASSTABLE | PASSMOB health = 30 maxHealth = 30 speed = 6 diff --git a/code/modules/mob/living/basic/stoats/stoat.dm b/code/modules/mob/living/basic/stoats/stoat.dm index 43fa3e3be7e..a3e635ccd6e 100644 --- a/code/modules/mob/living/basic/stoats/stoat.dm +++ b/code/modules/mob/living/basic/stoats/stoat.dm @@ -9,6 +9,8 @@ butcher_results = list(/obj/item/food/meat/slab = 1) mob_biotypes = MOB_ORGANIC mob_size = MOB_SIZE_SMALL + pass_flags = PASSTABLE | PASSMOB + density = FALSE health = 40 maxHealth = 40 melee_damage_lower = 6 diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index 8c5718305db..050ebad7e9b 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -1,8 +1,9 @@ -// Disposal bin and Delivery chute. -GLOBAL_VAR_INIT(animals_spawned, 0) +/// Number of animals infesting disposal bins. +GLOBAL_VAR_INIT(disposals_animals_spawned, 0) + #define CONTAINS_ANIMAL_CHANCE 5 #define MAXIMUM_ANIMAL_SPAWNS 1 -#define ANIMAL_SHAKE_CHANCE 10 +#define ANIMAL_SHAKE_CHANCE 20 #define SEND_PRESSURE (0.05*ONE_ATMOSPHERE) /obj/machinery/disposal @@ -35,12 +36,6 @@ GLOBAL_VAR_INIT(animals_spawned, 0) var/last_sound = 0 /// The stored disposal construction pipe var/obj/structure/disposalconstruct/stored - ///a weighted list of all the possible animals we can have - var/static/list/weighted_animal_list = list( - /mob/living/basic/stoat = 1, - ) - /// do we contain an animal? - var/contained_animal /datum/armor/machinery_disposal melee = 25 @@ -76,8 +71,7 @@ GLOBAL_VAR_INIT(animals_spawned, 0) ) AddElement(/datum/element/connect_loc, loc_connections) ADD_TRAIT(src, TRAIT_COMBAT_MODE_SKIP_INTERACTION, INNATE_TRAIT) - if(mapload) - spawn_contained_animal() + return INITIALIZE_HINT_LATELOAD //we need turfs to have air /// Checks if there a connecting trunk diposal pipe under the disposal @@ -378,7 +372,51 @@ GLOBAL_VAR_INIT(animals_spawned, 0) visible_message(span_warning("[src] is ripped free from the floor!")) deconstruct() -// Disposal bin + +/// Handles the signal for the rat king looking inside the disposal +/obj/machinery/disposal/proc/on_rat_rummage(datum/source, mob/living/basic/regal_rat/king) + SIGNAL_HANDLER + if(king.combat_mode) + return + + INVOKE_ASYNC(src, TYPE_PROC_REF(/obj/machinery/disposal/, rat_rummage), king) + return COMPONENT_RAT_INTERACTED + +/// Handles a carbon mob getting shoved into the disposal bin +/obj/machinery/disposal/proc/trash_living(datum/source, mob/living/shover, mob/living/target, shove_flags, obj/item/weapon) + SIGNAL_HANDLER + if((shove_flags & SHOVE_KNOCKDOWN_BLOCKED) || !(shove_flags & SHOVE_BLOCKED)) + return + var/cur_density = density + density = FALSE + if (!target.Move(get_turf(src), get_dir(target, src))) + density = cur_density + return + density = cur_density + target.Knockdown(SHOVE_KNOCKDOWN_SOLID) + target.forceMove(src) + target.visible_message(span_danger("[shover.name] shoves [target.name] into \the [src]!"), + span_userdanger("You're shoved into \the [src] by [target.name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, shover) + to_chat(src, span_danger("You shove [target.name] into \the [src]!")) + log_combat(shover, target, "shoved", "into [src] (disposal bin)[weapon ? " with [weapon]" : ""]") + return COMSIG_LIVING_SHOVE_HANDLED + +///Called when a push broom is trying to sweep items onto the turf this object is standing on. Garbage will be moved inside. +/obj/machinery/disposal/proc/ready_for_trash(datum/source, obj/item/pushbroom/broom, mob/user, list/items_to_sweep) + SIGNAL_HANDLER + if(!items_to_sweep) + return + for (var/obj/item/garbage in items_to_sweep) + user.transferItemToLoc(garbage, src) + + items_to_sweep.Cut() + + update_appearance() + to_chat(user, span_notice("You sweep the pile of garbage into [src].")) + playsound(broom.loc, 'sound/items/weapons/thudswoosh.ogg', 30, TRUE, -1) + + +/// Disposal bin // Holds items for disposal into pipe system // Draws air from turf, gradually charges internal reservoir // Once full (~1 atm), uses air resv to flush items into the pipes @@ -392,6 +430,17 @@ GLOBAL_VAR_INIT(animals_spawned, 0) interaction_flags_atom = parent_type::interaction_flags_atom | INTERACT_ATOM_IGNORE_MOBILITY /// Reference to the mounted destination tagger for disposal bins with one mounted. var/obj/item/dest_tagger/mounted_tagger + ///a weighted list of all the possible animals we can have + var/static/list/weighted_animal_list = list( + /mob/living/basic/stoat = 1, + ) + /// do we contain an animal? + var/contained_animal + +/obj/machinery/disposal/bin/Initialize(mapload, obj/structure/disposalconstruct/make_from) + . = ..() + if(mapload && prob(CONTAINS_ANIMAL_CHANCE) && GLOB.disposals_animals_spawned < MAXIMUM_ANIMAL_SPAWNS) + spawn_contained_animal() // attack by item places it in to disposal /obj/machinery/disposal/bin/attackby(obj/item/weapon, mob/user, list/modifiers, list/attack_modifiers) @@ -563,6 +612,20 @@ GLOBAL_VAR_INIT(animals_spawned, 0) . += "dispover-ready" . += emissive_appearance(icon, "dispover-ready-glow", src, alpha = src.alpha) +/// Create a random animal to be infesting this disposals bin +/obj/machinery/disposal/bin/proc/spawn_contained_animal() + contained_animal = pick_weight(weighted_animal_list) + GLOB.disposals_animals_spawned++ + +/// Release whoever is living inside here +/obj/machinery/disposal/bin/proc/release_animal() + var/list/open_turfs = get_adjacent_open_turfs(src) + var/turf/final_turf = length(open_turfs) ? pick(open_turfs) : drop_location() + var/mob/living/startled_animal = new contained_animal(drop_location()) + startled_animal.Move(final_turf) + visible_message(span_notice("A startled [startled_animal] jumps out of [src]")) + contained_animal = null + /// Initiates flushing /obj/machinery/disposal/bin/proc/do_flush() set waitfor = FALSE @@ -572,8 +635,8 @@ GLOBAL_VAR_INIT(animals_spawned, 0) //charge the gas reservoir and perform flush if ready /obj/machinery/disposal/bin/process(seconds_per_tick) - if(contained_animal) - Shake(duration = 2 SECONDS) + if(contained_animal && prob(ANIMAL_SHAKE_CHANCE)) + Shake(duration = 2 SECONDS, pixelshiftx = 1, pixelshifty = 0, duration = (seconds_per_tick SECONDS), shake_interval = 0.1 SECONDS) if(machine_stat & BROKEN) //nothing can happen if broken return @@ -628,7 +691,8 @@ GLOBAL_VAR_INIT(animals_spawned, 0) mounted_tagger = new /obj/item/dest_tagger(null) return ..() -//Delivery Chute + +/// Delivery Chute /obj/machinery/disposal/delivery_chute name = "delivery chute" @@ -670,6 +734,7 @@ GLOBAL_VAR_INIT(animals_spawned, 0) M.forceMove(src) flush() + /// Called to check if an atom can fit inside the diposal /atom/movable/proc/CanEnterDisposals() return TRUE @@ -683,61 +748,6 @@ GLOBAL_VAR_INIT(animals_spawned, 0) /obj/vehicle/sealed/mecha/CanEnterDisposals() return -/// Handles the signal for the rat king looking inside the disposal -/obj/machinery/disposal/proc/on_rat_rummage(datum/source, mob/living/basic/regal_rat/king) - SIGNAL_HANDLER - if(king.combat_mode) - return - - INVOKE_ASYNC(src, TYPE_PROC_REF(/obj/machinery/disposal/, rat_rummage), king) - return COMPONENT_RAT_INTERACTED - -/// Handles a carbon mob getting shoved into the disposal bin -/obj/machinery/disposal/proc/trash_living(datum/source, mob/living/shover, mob/living/target, shove_flags, obj/item/weapon) - SIGNAL_HANDLER - if((shove_flags & SHOVE_KNOCKDOWN_BLOCKED) || !(shove_flags & SHOVE_BLOCKED)) - return - var/cur_density = density - density = FALSE - if (!target.Move(get_turf(src), get_dir(target, src))) - density = cur_density - return - density = cur_density - target.Knockdown(SHOVE_KNOCKDOWN_SOLID) - target.forceMove(src) - target.visible_message(span_danger("[shover.name] shoves [target.name] into \the [src]!"), - span_userdanger("You're shoved into \the [src] by [target.name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, shover) - to_chat(src, span_danger("You shove [target.name] into \the [src]!")) - log_combat(shover, target, "shoved", "into [src] (disposal bin)[weapon ? " with [weapon]" : ""]") - return COMSIG_LIVING_SHOVE_HANDLED - -///Called when a push broom is trying to sweep items onto the turf this object is standing on. Garbage will be moved inside. -/obj/machinery/disposal/proc/ready_for_trash(datum/source, obj/item/pushbroom/broom, mob/user, list/items_to_sweep) - SIGNAL_HANDLER - if(!items_to_sweep) - return - for (var/obj/item/garbage in items_to_sweep) - user.transferItemToLoc(garbage, src) - - items_to_sweep.Cut() - - update_appearance() - to_chat(user, span_notice("You sweep the pile of garbage into [src].")) - playsound(broom.loc, 'sound/items/weapons/thudswoosh.ogg', 30, TRUE, -1) - -/obj/machinery/disposal/proc/spawn_contained_animal() - if(!prob(CONTAINS_ANIMAL_CHANCE) || GLOB.animals_spawned >= MAXIMUM_ANIMAL_SPAWNS) - return - contained_animal = pick_weight(weighted_animal_list) - GLOB.animals_spawned++ - -/obj/machinery/disposal/bin/proc/release_animal() - var/list/open_turfs = get_adjacent_open_turfs(src) - var/turf/final_turf = length(open_turfs) ? pick(open_turfs) : drop_location() - var/mob/living/startled_animal = new contained_animal(final_turf) - visible_message(span_notice("A startled [startled_animal] jumps out of [src]")) - - #undef SEND_PRESSURE #undef CONTAINS_ANIMAL_CHANCE #undef ANIMAL_SHAKE_CHANCE diff --git a/icons/mob/simple/pets.dmi b/icons/mob/simple/pets.dmi index 64a9f3038f7..907ac1d7d6f 100644 Binary files a/icons/mob/simple/pets.dmi and b/icons/mob/simple/pets.dmi differ