diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm
index 982116fe9651..39656c05156d 100644
--- a/code/game/objects/items/mop.dm
+++ b/code/game/objects/items/mop.dm
@@ -22,6 +22,7 @@
/obj/item/mop/Initialize(mapload)
. = ..()
create_reagents(mopcap, REFILLABLE)
+ AddComponent(/datum/component/liquids_interaction, TYPE_PROC_REF(/obj/item/mop, attack_on_liquids_turf))
/obj/item/mop/proc/clean(turf/A)
@@ -73,6 +74,33 @@
to_chat(user, span_warning("You are unable to fit your [name] into the [J.name]."))
return
+/obj/item/mop/proc/attack_on_liquids_turf(obj/item/mop/the_mop, turf/target, mob/user, obj/effect/abstract/liquid_turf/liquids)
+ if(!user.Adjacent(target))
+ return FALSE
+ var/free_space = mopcap - reagents.total_volume
+ var/speed_mult = 1
+ var/datum/liquid_group/targeted_group = target?.liquids?.liquid_group
+ while(!QDELETED(targeted_group))
+ if(speed_mult >= 0.2)
+ speed_mult -= 0.05
+ if(free_space <= 0)
+ to_chat(user, span_warning("Your [src] can't absorb any more!"))
+ return TRUE
+ if(!do_after(user, src.mopspeed * speed_mult, target = target))
+ break
+ if(the_mop.reagents.total_volume == the_mop.mopcap)
+ to_chat(user, span_warning("Your [src] can't absorb any more!"))
+ break
+ if(targeted_group?.reagents_per_turf)
+ targeted_group?.trans_to_seperate_group(the_mop.reagents, min(targeted_group?.reagents_per_turf, 5))
+ to_chat(user, span_notice("You soak up some liquids with \the [src]."))
+ else if(!QDELETED(target?.liquids?.liquid_group))
+ targeted_group = target.liquids.liquid_group
+ else
+ break
+ user.changeNext_move(CLICK_CD_MELEE)
+ return TRUE
+
/obj/item/mop/cyborg
insertable = FALSE
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index d51b807d5ba4..5ba737c25b54 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -25,6 +25,37 @@
add_initial_reagents()
+ AddComponent(/datum/component/liquids_interaction, TYPE_PROC_REF(/obj/item/reagent_containers, attack_on_liquids_turf))
+
+/obj/item/reagent_containers/proc/attack_on_liquids_turf(obj/item/reagent_containers/my_beaker, turf/T, mob/living/user, obj/effect/abstract/liquid_turf/liquids)
+ if(!user.Adjacent(T))
+ return FALSE
+ if(!my_beaker.spillable)
+ return FALSE
+ if(!user.Adjacent(T))
+ return FALSE
+ if(user.combat_mode)
+ return FALSE
+ if(liquids.fire_state) //Use an extinguisher first
+ to_chat(user, "You can't scoop up anything while it's on fire!")
+ return TRUE
+ if(liquids.liquid_group.expected_turf_height == 1)
+ to_chat(user, "The puddle is too shallow to scoop anything up!")
+ return TRUE
+ var/free_space = my_beaker.reagents.maximum_volume - my_beaker.reagents.total_volume
+ if(free_space <= 0)
+ to_chat(user, "You can't fit any more liquids inside [my_beaker]!")
+ return TRUE
+ var/desired_transfer = my_beaker.amount_per_transfer_from_this
+ if(desired_transfer > free_space)
+ desired_transfer = free_space
+ if(desired_transfer > liquids.liquid_group.reagents_per_turf)
+ desired_transfer = liquids.liquid_group.reagents_per_turf
+ liquids.liquid_group.trans_to_seperate_group(my_beaker.reagents, desired_transfer, liquids)
+ to_chat(user, "You scoop up around [round(desired_transfer)] units of liquids with [my_beaker].")
+ user.changeNext_move(CLICK_CD_MELEE)
+ return TRUE
+
/obj/item/reagent_containers/proc/add_initial_reagents()
if(list_reagents)
reagents.add_reagent_list(list_reagents)