diff --git a/code/game/objects/random/maintenance.dm b/code/game/objects/random/maintenance.dm
index 25f7092059..b3370c2792 100644
--- a/code/game/objects/random/maintenance.dm
+++ b/code/game/objects/random/maintenance.dm
@@ -113,6 +113,7 @@ something, make sure it's not in one of the other lists.*/
prob(2);/obj/item/toy/tennis/purple,
prob(1);/obj/item/toy/baseball,
prob(1);/obj/item/pizzavoucher,
+ prob(5);/obj/item/weapon/material/fishing_net/butterfly_net,
prob(2);/obj/item/weapon/cracker
/* VOREStation Edit End */
)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm b/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm
index 5eec312418..157354f2c9 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm
@@ -18,7 +18,8 @@
/obj/item/weapon/reagent_containers/spray/plantbgone,
/obj/item/clothing/suit/storage/hooded/wintercoat/hydro,
/obj/item/clothing/shoes/boots/winter/hydro,
- /obj/item/weapon/storage/belt/hydro)
+ /obj/item/weapon/storage/belt/hydro,
+ /obj/item/weapon/material/fishing_net/butterfly_net)
/obj/structure/closet/secure_closet/hydroponics/Initialize()
if(prob(50))
diff --git a/code/modules/fishing/fishing_net.dm b/code/modules/fishing/fishing_net.dm
index 8c98448427..19a3a461f1 100644
--- a/code/modules/fishing/fishing_net.dm
+++ b/code/modules/fishing/fishing_net.dm
@@ -107,3 +107,117 @@
else
slowdown = initial(slowdown)
reach = initial(reach)
+
+/obj/item/weapon/material/fishing_net/butterfly_net
+ name = "butterfly net"
+ desc = "A butterfly net."
+ icon = 'icons/obj/items.dmi'
+ icon_state = "butterfly_net"
+ item_state = "butterfly_net"
+ description_info = "This object can be used to capture certain creatures easily, most commonly butterflies. \
+ It can be emptied by activating it in-hand."
+
+ empty_state = "butterfly_net"
+ contain_state = "butterfly_net_full"
+
+ w_class = ITEMSIZE_SMALL
+ flags = NOBLUDGEON
+
+ reach = 1
+
+ default_material = "cloth"
+
+ accepted_mobs = list(/mob/living/simple_mob/animal/sif/glitterfly, /mob/living/carbon/human)
+
+/obj/item/weapon/material/fishing_net/butterfly_net/afterattack(var/atom/A, var/mob/user, var/proximity)
+ if(get_dist(get_turf(src), A) > reach)
+ return
+
+ if(istype(A, /turf))
+ var/mob/living/Target
+ for(var/type in accepted_mobs)
+ Target = locate(type) in A.contents
+ if(Target)
+ afterattack(Target, user, proximity)
+ break
+
+ if(istype(A, /mob))
+ var/accept = FALSE
+ for(var/D in accepted_mobs)
+ if(istype(A, D))
+ var/mob/M = A
+ if(istype(M, /mob/living/carbon/human) && M.size_multiplier > 0.5)
+ accept = FALSE
+ else if(A == user)
+ accept = FALSE
+ else
+ accept = TRUE
+ for(var/atom/At in src.contents)
+ if(isliving(At))
+ to_chat(user, "Your net is already holding something!")
+ accept = FALSE
+ if(!accept)
+ to_chat(user, "[A] can't be trapped in \the [src].")
+ return
+ var/mob/L = A
+ user.visible_message("[user] snatches [L] with \the [src].", "You snatch [L] with \the [src].")
+ L.forceMove(src)
+ playsound(src, 'sound/effects/plop.ogg', 50, 1)
+ update_icon()
+ update_weight()
+ return
+ return ..()
+
+/obj/item/weapon/material/fishing_net/butterfly_net/attack_self(var/mob/user)
+ for(var/mob/living/M in src)
+ if(!user.get_inactive_hand()) //Check if the inactive hand is empty
+ M.forceMove(get_turf(src))
+ M.attempt_to_scoop(user)
+ user.visible_message("[user] scoops [M] out from \the [src].", "You pull [M] from \the [src].")
+ else
+ M.forceMove(get_turf(src))
+ user.visible_message("[user] releases [M] from \the [src].", "You release [M] from \the [src].")
+ for(var/obj/item/I in src)
+ I.forceMove(get_turf(src))
+ user.visible_message("[user] dumps \the [I] out of \the [src].", "You dump \the [I] out of \the [src].")
+ update_icon()
+ update_weight()
+ return
+
+/obj/item/weapon/material/fishing_net/butterfly_net/container_resist(mob/living/M)
+ if(prob(20))
+ M.forceMove(get_turf(src))
+ to_chat(M, "You climb out of \the [src].")
+ update_icon()
+ update_weight()
+ else
+ to_chat(M, "You fail to escape \the [src].")
+
+/obj/item/weapon/material/fishing_net/butterfly_net/update_icon() // Also updates name and desc
+ underlays.Cut()
+ cut_overlays()
+
+ name = initial(name)
+ desc = initial(desc)
+ var/contains_mob = FALSE
+ for(var/mob/M in src)
+ name = "filled butterfly net"
+ desc = "A net with [M] inside."
+ contains_mob = TRUE
+
+ if(contains_mob)
+ icon_state = contain_state
+
+ else
+ icon_state = empty_state
+
+ return
+
+/datum/crafting_recipe/butterfly_net
+ name = "butterfly net"
+ result = /obj/item/weapon/material/fishing_net/butterfly_net
+ reqs = list(
+ list(/obj/item/stack/material/cloth = 2)
+ )
+ time = 20
+ category = CAT_MISC
diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi
index 866c4136c8..495abac477 100644
Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ
diff --git a/sound/effects/plop.ogg b/sound/effects/plop.ogg
new file mode 100644
index 0000000000..11f138e24c
Binary files /dev/null and b/sound/effects/plop.ogg differ