From bbddee97bb597460f1fe6053d466d78c0ecb8dcd Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Fri, 12 Aug 2022 20:43:31 +1000 Subject: [PATCH] Added burrowing, foraging and scavenging interactions for simple_mob animals. --- code/game/objects/structures/animal_den.dm | 161 ++++++++++++++++++ code/game/objects/structures/flora/flora.dm | 31 +++- code/game/objects/structures/flora/trees.dm | 10 +- .../game/turfs/simulated/outdoors/outdoors.dm | 26 ++- code/modules/mob/living/carbon/human/human.dm | 23 ++- .../carbon/human/species/species_attack.dm | 2 +- code/modules/mob/living/living.dm | 9 +- .../modules/mob/living/simple_mob/on_click.dm | 65 ++++--- .../simple_mob/subtypes/animal/animal.dm | 41 ++++- .../simple_mob/subtypes/animal/sif/kururak.dm | 2 +- .../simple_mob/subtypes/animal/sif/siffet.dm | 7 +- icons/mob/64x32.dmi | Bin 3989 -> 20347 bytes icons/obj/structures/den.dmi | Bin 0 -> 1940 bytes polaris.dme | 1 + 14 files changed, 340 insertions(+), 38 deletions(-) create mode 100644 code/game/objects/structures/animal_den.dm create mode 100644 icons/obj/structures/den.dmi diff --git a/code/game/objects/structures/animal_den.dm b/code/game/objects/structures/animal_den.dm new file mode 100644 index 0000000000..33f50297a0 --- /dev/null +++ b/code/game/objects/structures/animal_den.dm @@ -0,0 +1,161 @@ +/obj/structure/animal_den + name = "den" + icon = 'icons/obj/structures/den.dmi' + icon_state = "den1" + desc = "A rough-walled, shallow den dug into the earth." + density = FALSE + opacity = FALSE + +/obj/structure/animal_den/Initialize() + icon_state = "den[rand(1,3)]" + . = ..() + +/obj/structure/animal_den/proc/remove_from_den(var/atom/movable/AM) + AM.dropInto(get_turf(src)) + if(ismob(AM)) + var/mob/M = AM + if(M.client) + M.client.eye = M.client.mob + M.client.perspective = MOB_PERSPECTIVE + update_icon() + +/obj/structure/animal_den/relaymove(mob/user, direction) + remove_from_den(user) + user.visible_message(SPAN_NOTICE("\The [user] emerges from \the [src].")) + +/obj/structure/animal_den/Destroy() + for(var/atom/movable/AM in contents) + remove_from_den(AM) + . = ..() + +/obj/structure/animal_den/attack_hand(mob/user) + if(try_grab_occupant(user)) + return TRUE + . = ..() + +/obj/structure/animal_den/attackby(obj/item/O, mob/user) + if(O.has_tool_quality(TOOL_SHOVEL) && try_collapse_den(user)) + return TRUE + . = ..() + +/obj/structure/animal_den/proc/try_grab_occupant(var/mob/user) + if(user.a_intent != I_GRAB) + return FALSE + if(!do_after(user, 1 SECOND, src) || QDELETED(src)) + return TRUE + if(!length(contents)) + to_chat(user, SPAN_WARNING("There is nothing inside \the [src].")) + return TRUE + var/atom/movable/AM = pick(contents) + remove_from_den(AM) + user.visible_message(SPAN_NOTICE("\The [user] reaches into \the [src] and pulls out \the [AM]!")) + update_icon() + return TRUE + +/obj/structure/animal_den/proc/try_collapse_den(var/mob/user) + if(user.a_intent != I_HURT) + return FALSE + // Humans can only get here via a shovel, so it's fine for them to be small. + if(user.mob_size < MOB_MEDIUM && !ishuman(user)) + to_chat(user, SPAN_WARNING("You are too small to collapse \the [src].")) + return TRUE + if(!do_after(user, 5 SECONDS, src) || QDELETED(src)) + return TRUE + if(length(contents)) + to_chat(user, SPAN_WARNING("You can't collapse \the [src]; it's occupied.")) + else + to_chat(user, SPAN_NOTICE("You collapse \the [src].")) + playsound(user, 'sound/weapons/thudswoosh.ogg', 50) + qdel(src) + return TRUE + +/obj/structure/animal_den/attack_generic(mob/user, damage, attack_verb) + // Animal interactions with their nests. + if(istype(user, /mob/living/simple_mob/animal)) + if(try_collapse_den(user)) + return TRUE + if(try_grab_occupant(user)) + return TRUE + if(!do_after(user, src, 1 SECOND)) + return TRUE + if(length(contents)) + to_chat(user, SPAN_WARNING("You can't hide in \the [src]; it's occupied.")) + return TRUE + user.visible_message(SPAN_NOTICE("\The [user] disappears into \the [src].")) + user.forceMove(src) + update_icon() + return TRUE + return ..() + +/mob/living/simple_mob/animal/proc/get_eye_color() + return COLOR_WHITE + +/obj/structure/animal_den/update_icon() + cut_overlays() + for(var/mob/living/simple_mob/animal/critter in contents) + if(critter.stat == CONSCIOUS && !critter.resting) + var/image/I = image(icon, "eyes[rand(1,3)]") + I.color = critter.get_eye_color() + I.pixel_x = rand(-3, 3) + I.pixel_y = rand(-3, 3) + add_overlay(I) + +// Joinable den for critter spawns with ghost players. +/obj/structure/animal_den/ghost_join + var/mob/living/critter + var/ban_check = "Critter" + var/welcome_text + +/obj/structure/animal_den/ghost_join/Initialize() + . = ..() + name = "den" // to remove mapping identifiers. + if(ispath(critter)) + critter = new critter(src) + +/obj/structure/animal_den/ghost_join/remove_from_den(var/atom/movable/AM) + . = ..() + if(critter == AM && critter.loc != src) + if(critter.resting) + critter.lay_down() // you woke them up :( + critter = null + +/obj/structure/animal_den/ghost_join/examine(mob/user, infix, suffix) + . = ..() + if(isobserver(user)) + if(critter) + if(ban_check && ckey_is_jobbanned(user.ckey, ban_check)) + to_chat(user, SPAN_WARNING("You are banned from [ban_check] roles and cannot join via this den.")) + else if(user.MayRespawn(TRUE)) + to_chat(user, SPAN_NOTICE("Click on the den to join as \a [critter].")) + else + to_chat(user, SPAN_WARNING("This den is no longer available for joining.")) + +/obj/structure/animal_den/ghost_join/attack_ghost(mob/user) + if(critter) + transfer_personality(user) + return + return ..() + +/obj/structure/animal_den/ghost_join/proc/transfer_personality(var/mob/user) + set waitfor = FALSE + if(!critter) + return + if(user.mind) + user.mind.transfer_to(critter) + else + critter.key = user.key + + var/mob/living/critter_ref = critter + critter = null + + // Sleep long enough for them to login and get any other text out of the way. + sleep(1) + to_chat(critter_ref, SPAN_NOTICE("You are \a [critter]!")) + if(welcome_text) + to_chat(critter_ref, SPAN_NOTICE(welcome_text)) + + // Sleep long enough for the logged-in critter to update state and regen icon. + sleep(SSmobs.wait) + if(critter_ref.resting) // get up lazybones + critter_ref.lay_down() + update_icon() diff --git a/code/game/objects/structures/flora/flora.dm b/code/game/objects/structures/flora/flora.dm index a39370bb7b..ddf70cd639 100644 --- a/code/game/objects/structures/flora/flora.dm +++ b/code/game/objects/structures/flora/flora.dm @@ -71,9 +71,9 @@ ..(W, user) -/obj/structure/flora/proc/can_harvest(var/obj/item/I) +/obj/structure/flora/proc/can_harvest(var/obj/item/I, var/ignore_tool = FALSE) . = FALSE - if(harvest_tool && istype(I, harvest_tool) && harvest_loot && harvest_loot.len && harvest_count < max_harvests) + if((ignore_tool || (harvest_tool && istype(I, harvest_tool))) && harvest_loot && harvest_loot.len && harvest_count < max_harvests) . = TRUE return . @@ -89,6 +89,33 @@ harvest_count++ return AM +/obj/structure/flora/attack_generic(mob/user, damage, attack_verb) + if(istype(user, /mob/living/simple_mob/animal) && user.a_intent != I_HURT) + var/mob/living/simple_mob/animal/critter = user + if(!critter.forager) + return ..() + if(!can_forage(critter)) + to_chat(critter, SPAN_WARNING("You cannot see any edible fruit on \the [src].")) + return TRUE + show_animal_foraging_message(critter) + if(!do_after(critter, 2 SECONDS, src) || QDELETED(src) || !can_forage(user)) + return TRUE + show_animal_eating_message(critter) + playsound(critter, 'sound/items/eatfood.ogg', rand(10,50), 1) + harvest_count++ + critter.eat_food_item(spawn_harvest(pickweight(harvest_loot))) + return TRUE + return ..() + +/obj/structure/flora/proc/can_forage(var/mob/critter) + return can_harvest(ignore_tool = TRUE) + +/obj/structure/flora/proc/show_animal_foraging_message(var/mob/critter) + critter.visible_message(SPAN_NOTICE("\The [critter] begins sniffing at \the [src].")) + +/obj/structure/flora/proc/show_animal_eating_message(var/mob/critter) + critter.visible_message(SPAN_NOTICE("\The [critter] rips away some of the fruit from \the [src].")) + //bushes /obj/structure/flora/bush name = "bush" diff --git a/code/game/objects/structures/flora/trees.dm b/code/game/objects/structures/flora/trees.dm index 6b8ca8c5d1..b7d70d64c6 100644 --- a/code/game/objects/structures/flora/trees.dm +++ b/code/game/objects/structures/flora/trees.dm @@ -30,9 +30,9 @@ /obj/structure/flora/tree/proc/choose_icon_state() return icon_state -/obj/structure/flora/tree/can_harvest(var/obj/item/I) +/obj/structure/flora/tree/can_harvest(var/obj/item/I, var/ignore_tool = FALSE) . = FALSE - if(!is_stump && harvest_tool && istype(I, harvest_tool) && harvest_loot && harvest_loot.len && harvest_count < max_harvests) + if(!is_stump && (ignore_tool || (harvest_tool && istype(I, harvest_tool))) && harvest_loot && harvest_loot.len && harvest_count < max_harvests) . = TRUE return . @@ -139,6 +139,12 @@ return results +/obj/structure/flora/tree/show_animal_foraging_message(var/mob/critter) + critter.visible_message(SPAN_NOTICE("\The [critter] begins searching through the foliage of \the [src].")) + +/obj/structure/flora/tree/show_animal_eating_message(var/mob/critter) + critter.visible_message(SPAN_NOTICE("\The [critter] pulls down some low-hanging fruit from \the [src].")) + // Subtypes. // Pine trees diff --git a/code/game/turfs/simulated/outdoors/outdoors.dm b/code/game/turfs/simulated/outdoors/outdoors.dm index 39bd4ca1b2..61eafef4d3 100644 --- a/code/game/turfs/simulated/outdoors/outdoors.dm +++ b/code/game/turfs/simulated/outdoors/outdoors.dm @@ -8,7 +8,7 @@ var/global/list/turf_edge_cache = list() var/outdoors = OUTDOORS_AREA /area - // If a turf's `outdoors` variable is set to `OUTDOORS_AREA`, + // If a turf's `outdoors` variable is set to `OUTDOORS_AREA`, // it will decide if it's outdoors or not when being initialized based on this var. var/outdoors = OUTDOORS_NO @@ -39,6 +39,30 @@ var/global/list/turf_edge_cache = list() if(can_dig && prob(33)) loot_count = rand(1,3) +/turf/simulated/floor/outdoors/attack_generic(mob/user) + if(isanimal(user) && user.loc == src && user.a_intent == I_HELP) + var/mob/living/simple_mob/animal/critter = user + if(critter.burrower) + if(locate(/obj/structure/animal_den) in contents) + to_chat(critter, SPAN_WARNING("There is already a den here.")) + return TRUE + critter.visible_message(SPAN_NOTICE("\The [critter] begins digging industriously.")) + if(!do_after(critter, 10 SECONDS, src)) + return TRUE + if(locate(/obj/structure/animal_den) in contents) + to_chat(critter, SPAN_WARNING("There is already a den here.")) + return TRUE + critter.visible_message(SPAN_NOTICE("\The [critter] finishes digging a den!")) + new /obj/structure/animal_den(src) + if(prob(66)) + var/worms = 0 + for(var/worm in 1 to rand(3)) + new /obj/item/reagent_containers/food/snacks/worm(src) + worms++ + to_chat(critter, SPAN_NOTICE("You unearthed [worms] worm\s!")) + return TRUE + . = ..() + /turf/simulated/floor/outdoors/attackby(obj/item/C, mob/user) if(can_dig && istype(C, /obj/item/shovel)) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index f4b522598e..29b59d4aed 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1640,4 +1640,25 @@ /mob/living/carbon/human/get_sound_volume_multiplier() . = ..() for(var/obj/item/clothing/C in list(l_ear, r_ear, head)) - . = min(., C.volume_multiplier) \ No newline at end of file + . = min(., C.volume_multiplier) + +/mob/living/carbon/human/rip_out_internal_organ(var/zone, var/skip_wounding = FALSE, var/damage_descriptor) + + var/obj/item/organ/organ + var/obj/item/organ/external/limb + if(zone) + limb = organs_by_name[zone] + if(limb && length(limb.internal_organs)) + organ = pick_n_take(limb.internal_organs) + if(!organ) + organ = ..(skip_wounding = TRUE) + + if(organ) + organ.removed() + if(organ.parent_organ && !limb) + limb = organs_by_name[organ.parent_organ] + if(limb) + limb.take_damage(rand(10,20), 0, TRUE, TRUE, damage_descriptor) + else + take_damage(rand(10, 20)) + return organ diff --git a/code/modules/mob/living/carbon/human/species/species_attack.dm b/code/modules/mob/living/carbon/human/species/species_attack.dm index 9be2a2f7e8..baa083da81 100644 --- a/code/modules/mob/living/carbon/human/species/species_attack.dm +++ b/code/modules/mob/living/carbon/human/species/species_attack.dm @@ -99,4 +99,4 @@ /datum/unarmed_attack/stomp/weak/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) var/obj/item/organ/external/affecting = target.get_organ(zone) user.visible_message("[user] jumped up and down on \the [target]'s [affecting.name]!") - playsound(user, attack_sound, 25, 1, -1) \ No newline at end of file + playsound(user, attack_sound, 25, 1, -1) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index d01f01e461..0188488c7f 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1143,7 +1143,7 @@ var/turf/T = get_turf(src) var/obj/effect/overmap/visitable/M = get_overmap_sector(T.z) - + if(istype(M)) if(M.in_space) if(T.z in using_map.station_levels) @@ -1156,3 +1156,10 @@ var/datum/map_z_level/zlevel = using_map.zlevels["[T.z]"] if(istype(zlevel)) . |= zlevel.event_regions + +// kali maaaaa +/mob/living/proc/rip_out_internal_organ(var/zone, var/skip_wounding = FALSE, var/damage_descriptor) + if(length(internal_organs)) + . = pick_n_take(internal_organs) + if(!skip_wounding) + take_damage(rand(10,20)) diff --git a/code/modules/mob/living/simple_mob/on_click.dm b/code/modules/mob/living/simple_mob/on_click.dm index 4b824c9580..1434373b80 100644 --- a/code/modules/mob/living/simple_mob/on_click.dm +++ b/code/modules/mob/living/simple_mob/on_click.dm @@ -11,32 +11,7 @@ var/obj/O = A return O.attack_hand(src) - switch(a_intent) - if(I_HELP) - if(isliving(A)) - custom_emote(1,"[pick(friendly)] \the [A]!") - - if(I_HURT) - if(can_special_attack(A) && special_attack_target(A)) - return - - else if(melee_damage_upper == 0 && istype(A,/mob/living)) - custom_emote(1,"[pick(friendly)] \the [A]!") - - else - attack_target(A) - - if(I_GRAB) - if(has_hands) - A.attack_hand(src) - else - attack_target(A) - - if(I_DISARM) - if(has_hands) - A.attack_hand(src) - else - attack_target(A) + return do_interaction(A) /mob/living/simple_mob/RangedAttack(var/atom/A) // setClickCooldown(get_attack_speed()) @@ -45,4 +20,40 @@ return if(projectiletype) - shoot_target(A) \ No newline at end of file + shoot_target(A) + +/mob/living/simple_mob/proc/do_interaction(var/atom/A) + switch(a_intent) + if(I_HURT) + return do_hurt_interaction(A) + if(I_GRAB) + return do_grab_interaction(A) + if(I_DISARM) + return do_disarm_interaction(A) + return do_help_interaction(A) + +/mob/living/simple_mob/proc/do_help_interaction(var/atom/A) + if(isliving(A)) + custom_emote(1,"[pick(friendly)] \the [A]!") + return TRUE + return FALSE + +/mob/living/simple_mob/proc/do_hurt_interaction(var/atom/A) + if(can_special_attack(A) && special_attack_target(A)) + return + else if(melee_damage_upper == 0 && istype(A,/mob/living)) + custom_emote(1,"[pick(friendly)] \the [A]!") + else + attack_target(A) + +/mob/living/simple_mob/proc/do_disarm_interaction(var/atom/A) + if(has_hands) + A.attack_hand(src) + else + attack_target(A) + +/mob/living/simple_mob/proc/do_grab_interaction(var/atom/A) + if(has_hands) + A.attack_hand(src) + else + attack_target(A) diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/animal.dm b/code/modules/mob/living/simple_mob/subtypes/animal/animal.dm index fa3f58e219..8200f5f87a 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/animal.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/animal.dm @@ -23,5 +23,44 @@ /obj/item/stack/animalhide = 3\ ) + var/forager = TRUE // Can eat from trees and bushes. + var/scavenger = FALSE // Can eat from corpses. + var/burrower = FALSE // Can dig dens. + /decl/mob_organ_names/quadruped //Most subtypes have this basic body layout. - hit_zones = list("head", "torso", "left foreleg", "right foreleg", "left hind leg", "right hind leg", "tail") \ No newline at end of file + hit_zones = list("head", "torso", "left foreleg", "right foreleg", "left hind leg", "right hind leg", "tail") + +/mob/living/simple_mob/animal/do_interaction(var/atom/A) + var/static/list/atom_types_with_animal_interactions = list( + /obj/structure/animal_den, + /obj/structure/flora, + /turf/simulated/floor/outdoors + ) + for(var/checktype in atom_types_with_animal_interactions) + if(istype(A, checktype)) + attack_generic(A, 0, "investigates") + return TRUE + if(scavenger && isliving(A) && a_intent == I_HURT) + var/mob/living/M = A + if(M.stat == DEAD && length(M.internal_organs)) + to_chat(src, SPAN_NOTICE("You dig into the guts of \the [M], hunting for the sweetest meat.")) + if(do_after(src, M, 2 SECOND) && !QDELETED(M) && length(M.internal_organs)) + var/obj/item/organ = M.rip_out_internal_organ(check_zone(zone_sel.selecting), damage_descriptor = "animal teeth") + if(organ) + visible_message(SPAN_DANGER("\The [src] rips \the [organ] out of \the [M] and devours [organ.gender == PLURAL ? "them" : "it"]!")) + eat_food_item(organ) + if(!length(M.internal_organs) && M.gib_on_butchery) + M.gib() + return TRUE + return ..() + +/mob/living/simple_mob/animal/proc/eat_food_item(var/obj/item/snack, var/silent) + if(istype(snack, /obj/item/organ)) + var/obj/item/organ/organ = snack + if(organ.meat_type) + eat_food_item(new organ.meat_type(src), silent = TRUE) + if(!silent) + playsound(src, 'sound/items/eatfood.ogg', rand(10,50), 1) + if(snack.reagents?.total_volume) + snack.reagents.trans_to_mob(src, snack.reagents.total_volume, CHEM_INGEST) + qdel(snack) diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/kururak.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/kururak.dm index 03a253d0b5..c0d3ad81d9 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/kururak.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/kururak.dm @@ -425,4 +425,4 @@ attack_speed_percent = 0.8 /decl/mob_organ_names/kururak - hit_zones = list("head", "chest", "left foreleg", "right foreleg", "left hind leg", "right hind leg", "far left tail", "far right tail", "left middle tail", "right middle tail") \ No newline at end of file + hit_zones = list("head", "chest", "left foreleg", "right foreleg", "left hind leg", "right hind leg", "far left tail", "far right tail", "left middle tail", "right middle tail") diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/siffet.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/siffet.dm index 40ae65d3bc..1e7a63f417 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/siffet.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/siffet.dm @@ -40,6 +40,7 @@ say_list_type = /datum/say_list/siffet ai_holder_type = /datum/ai_holder/simple_mob/siffet + burrower = TRUE /datum/say_list/siffet speak = list("Yap!", "Heh!", "Huff.") @@ -58,4 +59,8 @@ /mob/living/simple_mob/animal/sif/siffet/IIsAlly(mob/living/L) . = ..() if(!. && L.mob_size > 10) //Attacks things it considers small enough to take on, otherwise only attacks if attacked. - return TRUE \ No newline at end of file + return TRUE + +/obj/structure/animal_den/ghost_join/siffet + name = "siffet den" + critter = /mob/living/simple_mob/animal/sif/siffet diff --git a/icons/mob/64x32.dmi b/icons/mob/64x32.dmi index 615fd87a01f4bf003676f093f2a7df5bfcd4a867..b40f672c2dbf1c51d5f8bc8ef31c262fe55b996b 100644 GIT binary patch literal 20347 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 I?m|xf4c}uthX4Qo literal 3989 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 diff --git a/icons/obj/structures/den.dmi b/icons/obj/structures/den.dmi new file mode 100644 index 0000000000000000000000000000000000000000..8fe7d5ccc7018834105ad91bc09254a6eec815bb GIT binary patch literal 1940 zcma*o`#;l*9|!PhG?zAGl3UE&hH~vp_!iNRqpV zTsABr>$rsTEit!m$}Jf&U*G@W{P2D~U;n`C@lM8D~Y&XEFm1$&bHf+&8!2ZBIhw6u{1!9FdqhhH$es<3Ywtsx^Q)vVI{iC5E= z<4%X0D*e7b)^9dXg&l0Pyh^`pOuyku4J>q3Kc`XElpiXH>GN3W2P$#HgRD+sUzvdO zYjZ1$$9-jp;Lmv~8HZtQ%sw+V}cEppyfZ zfQelg?HfTqeL)ZYLR=hnN^2WR0lQ&)*>ToXE$ra^nq-J0MI~1Fn+DH+~C=oTFxg=aDrUhh5n{a#LFxv_M zY})hPtp*vA9`aFxx%W8Fqd<=X>|HzCt`4VFiTv!PnBJJ(0Crn0VhEt)8hhUP&gOCV zcDwHsRDuDt^t2tEZ}SMfwq!jvkRj>1jVdcFzBA&dHp}3d_ht7TohKhKd1g5000eg2 z#dvHJ&k3*z6Ntf-h-e|P-Z_tht%q33Dh!&e$=G*WXG8lmQU2F72uCWN?=!YCEVDM&h*52#m*4v>-D{yYM&qt5`(fU z8J*Hbk_IHy?XDIGjP01xt3>Y^NrRe1s%?!Ve!evv1}?qoPfSlNTiusu;?Y9NkfM9| zm@H;|+|r{!Q`x#J09xEw6ILZ>IR z%>D{NK~p=nd64vS9>MbCU2&@wuG59gJ^Kn#4F=e{*lUd|n(M#jGJm#wSAaO$2%Vit z())Ca$eTAGgQ(r?+6*k=$jGUCdP=G~Gc4e}w&}^`oy{}$Q%`fD21yccFY99cWh&dB zt_?r%nr(H=+6Wcwpi7$_N*UQoRXxdgyVP2*nX{EZcR!Ll$Ro(w#UVM|Mn|iOUzio& zIk(T2cM08Z3?gi|im$pKyy(n(Q*|BwEGjX{JfZlJiuEh0VkWL_N6Gm)|1->f9Wd^w<6%H`zwkim zqrO%q9dm}5KT-38Z|g(L*F^8YkBK1!GgrL7@(@U}Jl^I(JiSNKXk-)bY_eH+icUUB zxTV6l!V#>$C{)P_hag2G|HttuLwqB=U!$Y|2~T=nr!WH&KL{zE$FdSlYYGC*&@6f7RU#Ll>$} zrzW(!CNtam1HhGEv^ioMuBPz#+OI1QpWOj_?r2d!!ng+ODUPU~JQ8d(HRjWfoR_Ne z0ayb3VV4~5ifU}x&~?lk7v0mVgVLNmSen*jGDIz`IlS>kPe)8Ic;c$}FEHB0*=kW&w~9x8+)NF zA?u+QrY=|bu(ukjdQ;D-2M4~xq8tW2%(}48HL?0Gq$AD{$^P?8Q2V_^hJtwi88Wit z@5*R1>82#Eo7i%&7`gQden10k;Nir)rcv(x@%4Fc)+FQq)ASZ>sb?lUb^2zt-EuT3 zUEWIO!Bi^b<;|JF@VxNJt+OoXuFt24fH|0vwo~nlRQnK53Km4l(f^jJ>m@JSV#%?8 z9Os~qG(V9>UhXOl4gE=2o0jc<$0PZxA%c6!Q?3y#s-Tb5{#Q^-YHBVY{3mtg3|PC)WLcqxLM4_soIy$i2}iVft}T;MwrqyM4RMMdL4(rLE?R zAZjksW}h_#{xq>pFA4eNAJ>V>lW0d+r>;dam@tcfgE70X`JbjWsprRU7G!B=4b)wA GkNqEGW|!0e literal 0 HcmV?d00001 diff --git a/polaris.dme b/polaris.dme index 7325f79a9c..db9da46c5c 100644 --- a/polaris.dme +++ b/polaris.dme @@ -1178,6 +1178,7 @@ #include "code\game\objects\random\mob.dm" #include "code\game\objects\random\spacesuits.dm" #include "code\game\objects\random\unidentified\medicine.dm" +#include "code\game\objects\structures\animal_den.dm" #include "code\game\objects\structures\barricades.dm" #include "code\game\objects\structures\barsign.dm" #include "code\game\objects\structures\bedsheet_bin.dm"