diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm
index a4525bfb3d1..fcc27fcb8d2 100644
--- a/code/modules/mob/holder.dm
+++ b/code/modules/mob/holder.dm
@@ -12,10 +12,6 @@
var/name_dead
var/isalive
- var/last_loc_general//This stores a general location of the object. Ie, a container or a mob
- var/last_loc_specific//This stores specific extra information about the location, pocket, hand, worn on head, etc. Only relevant to mobs
- var/checkverb
-
/obj/item/weapon/holder/New()
if (!item_state)
item_state = icon_state
@@ -29,52 +25,42 @@
/obj/item/weapon/holder/process()
- if (!(istype(loc,/obj/item/weapon/storage)))//Mobs bug out if placed directly into a container
- if(!get_holding_mob())
-
- for(var/mob/M in contents)
-
- var/atom/movable/mob_container
- mob_container = M
- mob_container.loc = src.loc//if the holder was placed into a disposal, this should place the animal in the disposal
- M.reset_view()
- M.verbs -= /mob/living/proc/get_holder_location
- qdel(src)
+ if(!get_holding_mob() || contained.loc != src)
+ if (is_unsafe_container(loc) && contained.loc == src)
return
+
+
+ for(var/mob/M in contents)
+
+ var/atom/movable/mob_container
+ mob_container = M
+ mob_container.forceMove(src.loc)//if the holder was placed into a disposal, this should place the animal in the disposal
+ M.reset_view()
+
+ var/mob/L = get_holding_mob()
+ if (L)
+ L.drop_from_inventory(src)
+
+ qdel(src)
if (isalive && contained.stat == DEAD)
held_death(1)//If we get here, it means the mob died sometime after we picked it up. We pass in 1 so that we can play its deathmessage
+
+//This function checks if the current location is safe to release inside
+//it returns 1 if the creature will bug out when released
+/obj/item/weapon/holder/proc/is_unsafe_container(var/obj/place)
+ if (istype(place, /obj/item/weapon/storage))
+ return 1
+ else if (istype(place, /obj/structure/closet/crate))
+ return 1
+ else
+ return 0
+
+
/obj/item/weapon/holder/attackby(obj/item/weapon/W as obj, mob/user as mob)
for(var/mob/M in src.contents)
M.attackby(W,user)
-/obj/item/weapon/holder/dropped(mob/user)
-
- ///When an object is put into a container, drop fires twice.
- //once with it on the floor, and then once in the container
- //This conditional allows us to ignore that first one. Handling of mobs dropped on the floor is done in process
- if (istype(loc, /turf))
- return
-
- if (istype(loc, /obj/item/weapon/storage)) //The second drop reads the container its placed into as the location
- update_location()
-
-
-/obj/item/weapon/holder/equipped(var/mob/user, var/slot)
- ..()
- update_location(slot)
-
-/obj/item/weapon/holder/proc/update_location(var/slotnumber = null)
- if (!slotnumber)
- if (istype(loc, /mob))
- slotnumber = get_equip_slot()
-
- report_onmob_location(1, slotnumber, contained)
-
-
-
-
-
/obj/item/weapon/holder/attack_self(mob/M as mob)
if (contained && !(contained.stat & DEAD))
@@ -121,51 +107,34 @@
//update_icon()
-/mob/living/proc/get_scooped(var/mob/living/carbon/grabber)
- if(!holder_type || buckled || pinned.len)
+/mob/living/proc/get_scooped(var/mob/living/carbon/grabber, var/mob/user = null)
+ if(!holder_type || buckled || pinned.len || !Adjacent(grabber))
return
if ((grabber.hand == 0 && grabber.r_hand) || (grabber.hand == 1 && grabber.l_hand))//Checking if the hand is full
grabber << "Your hand is full!"
return
- src.verbs += /mob/living/proc/get_holder_location//This has to be before we move the mob into the holder
+ var/obj/item/weapon/holder/H = new holder_type(loc)
+ src.forceMove(H)
+ H.name = loc.name
+ H.attack_hand(grabber)
+ H.contained = src
- spawn(2)
- var/obj/item/weapon/holder/H = new holder_type(loc)
- src.loc = H
- H.name = loc.name
+ if (src.stat == DEAD)
+ H.held_death()//We've scooped up an animal that's already dead. use the proper dead icons
+ else
+ H.isalive = 1//We note that the mob is alive when picked up. If it dies later, we can know that its death happened while held, and play its deathmessage for it
- H.contained = src
-
-
-
- if (src.stat == DEAD)
- H.held_death()//We've scooped up an animal that's already dead. use the proper dead icons
- else
- H.isalive = 1//We note that the mob is alive when picked up. If it dies later, we can know that its death happened while held, and play its deathmessage for it
-
- grabber << "You scoop up [src]."
- src << "[grabber] scoops you up."
- grabber.status_flags |= PASSEMOTES
-
- H.attack_hand(grabber)//We put this last to prevent some race conditions
- return
-
-
-/mob/living/proc/get_holder_location()
- set category = "Abilities"
- set name = "Check held location"
- set desc = "Find out where on their person, someone is holding you."
-
- if (!usr.get_holding_mob())
- src << "Nobody is holding you!"
- return
-
- if (istype(usr.loc, /obj/item/weapon/holder))
- var/obj/item/weapon/holder/H = usr.loc
- H.report_onmob_location(0, H.get_equip_slot(), src)
+ if (user == src)
+ grabber << "[src.name] climbs up onto you."
+ src << "You climb up onto [grabber]."
+ else
+ grabber << "You scoop up [src]."
+ src << "[grabber] scoops you up."
+ grabber.status_flags |= PASSEMOTES
+ return
//Mob specific holders.
//w_class mainly determines whether they can fit in trashbags. <=2 can, >=3 cannot
@@ -262,6 +231,7 @@
origin_tech = "biotech=2"
w_class = 1
+
/obj/item/weapon/holder/mouse/white
icon_state = "mouse_white"
icon_state_dead = "mouse_white_dead"
diff --git a/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm b/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm
index 7289c96c3bc..fdf2004612c 100644
--- a/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm
+++ b/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm
@@ -12,5 +12,5 @@
var/mob/living/carbon/H = over_object
if(!istype(H) || !Adjacent(H))
return ..()
- get_scooped(H)
+ get_scooped(H, usr)
return
diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm
index b7e37c279b0..9ac2ce277cf 100644
--- a/code/modules/mob/living/simple_animal/friendly/cat.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cat.dm
@@ -129,16 +129,6 @@
. = ..()
set_flee_target(AM.thrower? AM.thrower : src.loc)
-/mob/living/simple_animal/cat/MouseDrop(atom/over_object)
-
- var/mob/living/carbon/H = over_object
- if(!istype(H) || !Adjacent(H)) return ..()
-
- if(H.a_intent == "help")
- get_scooped(H)
- return
- else
- return ..()
//Basic friend AI
/mob/living/simple_animal/cat/fluff
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index ecd53691e25..7d45fabbaf5 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -156,17 +156,6 @@
squeak_loud()//You trod on its tail
..()
-/mob/living/simple_animal/mouse/MouseDrop(atom/over_object)
-
- var/mob/living/carbon/H = over_object
- if(!istype(H) || !Adjacent(H)) return ..()
-
- if(H.a_intent == "help")
- get_scooped(H)
- return
- else
- return ..()
-
/mob/living/simple_animal/mouse/death()
layer = MOB_LAYER
if (ckey || prob(50))
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 8c8a7ba66b2..162577ae187 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -490,6 +490,6 @@
if(!istype(H) || !Adjacent(H))
return ..()
- get_scooped(H)
+ get_scooped(H, usr)
return
return ..()
\ No newline at end of file
diff --git a/html/changelogs/Nanako-HeldFix.yml b/html/changelogs/Nanako-HeldFix.yml
new file mode 100644
index 00000000000..5b567b20fc0
--- /dev/null
+++ b/html/changelogs/Nanako-HeldFix.yml
@@ -0,0 +1,40 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Nanako
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - bugfix: "Animals climbing onto people will now show a different, correct message, instead of the scooped one"
+ - bugfix: "Fixed an issue where a held animal could be duplicated"
+ - bugfix: "Fixed animals bugging out when placed in crates or unworn containers"
+
+
\ No newline at end of file