Added burrowing, foraging and scavenging interactions for simple_mob animals.

This commit is contained in:
MistakeNot4892
2022-08-12 20:43:31 +10:00
parent 1dd18306d7
commit bbddee97bb
14 changed files with 340 additions and 38 deletions
+161
View File
@@ -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("<b>Click on the den to join as \a [critter].</b>"))
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("<b>You are \a [critter]!</b>"))
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()
+29 -2
View File
@@ -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"
+8 -2
View File
@@ -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