diff --git a/code/game/objects/items/weapons/traps.dm b/code/game/objects/items/weapons/traps.dm
index 0986abffa8f..57b450ac0e6 100644
--- a/code/game/objects/items/weapons/traps.dm
+++ b/code/game/objects/items/weapons/traps.dm
@@ -11,36 +11,41 @@
desc = "A mechanically activated leg trap. Low-tech, but reliable. Looks like it could really hurt if you set it off."
throwforce = 0
w_class = 3
- origin_tech = list(TECH_MATERIAL = 1)
+ origin_tech = list(TECH_ENGINEERING = 2)
matter = list(DEFAULT_WALL_MATERIAL = 18750)
- var/deployed = 0
+ var/deployed = FALSE
var/time_to_escape = 60
/obj/item/weapon/trap/proc/can_use(mob/user)
return (user.IsAdvancedToolUser() && !issilicon(user) && !user.stat && !user.restrained())
-/obj/item/weapon/trap/attack_self(mob/user as mob)
+/obj/item/weapon/trap/attack_self(mob/user)
..()
if(!deployed && can_use(user))
+ if(deploy(user))
+ user.drop_from_inventory(src)
+ anchored = TRUE
+
+/obj/item/weapon/trap/proc/deploy(mob/user)
+ user.visible_message(
+ "[user] starts to deploy \the [src].",
+ "You begin deploying \the [src]!",
+ "You hear the slow creaking of a spring."
+ )
+
+ if (do_after(user, 5 SECONDS))
user.visible_message(
- "[user] starts to deploy \the [src].",
- "You begin deploying \the [src]!",
- "You hear the slow creaking of a spring."
+ "[user] deploys \the [src].",
+ "You deploy \the [src]!",
+ "You hear a latch click loudly."
)
- if (do_after(user, 60))
- user.visible_message(
- "[user] has deployed \the [src].",
- "You have deployed \the [src]!",
- "You hear a latch click loudly."
- )
+ deployed = TRUE
+ update_icon()
+ return TRUE
+ return FALSE
- deployed = 1
- user.drop_from_inventory(src)
- update_icon()
- anchored = 1
-
-/obj/item/weapon/trap/user_unbuckle_mob(mob/user as mob)
+/obj/item/weapon/trap/user_unbuckle_mob(mob/user)
if(buckled_mob && can_use(user))
user.visible_message(
"\The [user] begins freeing \the [buckled_mob] from \the [src].",
@@ -48,33 +53,33 @@
"You hear metal creaking."
)
if(do_after(user, time_to_escape))
- user.visible_message("\The [buckled_mob] has been freed from \the [src] by \the [user].")
+ user.visible_message("\The [buckled_mob] is freed from \the [src] by \the [user].")
unbuckle_mob()
- anchored = 0
+ anchored = FALSE
-/obj/item/weapon/trap/attack_hand(mob/user as mob)
+/obj/item/weapon/trap/attack_hand(mob/user)
if(buckled_mob && can_use(user))
user.visible_message(
"[user] begins freeing [buckled_mob] from \the [src].",
"You carefully begin to free [buckled_mob] from \the [src]."
)
if(do_after(user, time_to_escape))
- user.visible_message("[buckled_mob] has been freed from \the [src] by [user].")
+ user.visible_message("[buckled_mob] is freed from \the [src] by [user].")
unbuckle_mob()
- anchored = 0
+ anchored = FALSE
else if(deployed && can_use(user))
user.visible_message(
"[user] starts to disarm \the [src].",
"You begin disarming \the [src]!",
"You hear a latch click followed by the slow creaking of a spring."
)
- if(do_after(user, 60))
+ if(do_after(user, 6 SECONDS))
user.visible_message(
- "[user] has disarmed \the [src].",
- "You have disarmed \the [src]!"
+ "[user] disarms \the [src].",
+ "You disarm \the [src]!"
)
- deployed = 0
- anchored = 0
+ deployed = FALSE
+ anchored = FALSE
update_icon()
else
..()
@@ -98,10 +103,10 @@
//trap the victim in place
set_dir(L.dir)
- can_buckle = 1
+ can_buckle = TRUE
buckle_mob(L)
to_chat(L, "The steel jaws of \the [src] bite into you, trapping you in place!")
- deployed = 0
+ deployed = FALSE
can_buckle = initial(can_buckle)
playsound(src, 'sound/weapons/beartrap_shut.ogg', 100, 1)//Really loud snapping sound
@@ -110,7 +115,7 @@
bear.anger += 15//traps make bears really angry
bear.instant_aggro()
-/obj/item/weapon/trap/Crossed(AM as mob|obj)
+/obj/item/weapon/trap/Crossed(atom/movable/AM)
if(deployed && isliving(AM))
var/mob/living/L = AM
L.visible_message(
@@ -120,8 +125,8 @@
)
attack_mob(L)
if(!buckled_mob)
- anchored = 0
- deployed = 0
+ anchored = FALSE
+ deployed = FALSE
update_icon()
..()
@@ -137,15 +142,15 @@
icon = 'icons/obj/items.dmi'
icon_base = "small"
icon_state = "small0"
- desc = "A small mechanical trap thas is used to catch small animals like rats, lizards, chick and spiderlings."
+ desc = "A small mechanical trap that's used to catch small animals like rats, lizards, and chicks."
throwforce = 2
force = 1
w_class = 2
- origin_tech = list(TECH_MATERIAL = 1)
+ origin_tech = list(TECH_ENGINEERING = 1)
matter = list(DEFAULT_WALL_MATERIAL = 1750)
- deployed = 0
+ deployed = FALSE
time_to_escape = 3 // Minutes
- can_buckle = FALSE
+ can_buckle = TRUE
var/breakout = FALSE
var/last_shake = 0
var/list/allowed_mobs = list(/mob/living/simple_animal/rat, /mob/living/simple_animal/chick, /mob/living/simple_animal/lizard)
@@ -155,6 +160,17 @@
health = 100
var/datum/weakref/captured = null
+/obj/item/weapon/trap/animal/MouseDrop_T(mob/living/M, mob/living/user)
+ if(!istype(M))
+ return
+
+ if(!captured)
+ if(!is_type_in_list(M, allowed_mobs))
+ to_chat(user, span("warning", "[M] won't fit in there!"))
+ else if(do_after(user, 5 SECONDS))
+ capture(M)
+ else
+ to_chat(user, "\The [src] is already full!")
/obj/item/weapon/trap/animal/update_icon()
icon = initial(icon)
@@ -164,50 +180,44 @@
..()
if(captured)
var/datum/L = captured.resolve()
- if (!L)
+ if (L)
+ to_chat(user, "[L] is trapped inside!")
return
- to_chat(user, "\The [src] has [L].")
-
+ else if(deployed)
+ to_chat(user, span("warning", "It's set up and ready to capture something."))
else
- to_chat(user, "\The [src] is empty.")
+ to_chat(user, "\The [src] is empty and un-deployed.")
-/obj/item/weapon/trap/animal/Crossed(AM as mob|obj)
- if(world.time - release_time < 50) // If we just released the animal, not to let it get caught again right away
+/obj/item/weapon/trap/animal/Crossed(atom/movable/AM)
+ if(!deployed || !anchored)
return
- if(captured?.resolve()) // It is full
+ if(captured) // just in case but this shouldn't happen
return
+
capture(AM)
-/obj/item/weapon/trap/animal/proc/capture(var/mob/AM)
- if(isliving(AM))
+/obj/item/weapon/trap/animal/proc/capture(var/mob/AM, var/msg = 1)
+ if(isliving(AM) && is_type_in_list(AM, allowed_mobs))
var/mob/living/L = AM
- for(var/f in allowed_mobs)
- if(istype(AM, f))
- L.visible_message(
- "[L] enters \the [src], and it snaps shut with a clatter!",
- "You enter \the [src], and it snaps shut with a clatter!",
- "You hear a loud metallic snap!"
- )
- can_buckle = TRUE
- captured = WEAKREF(L)
- playsound(src, 'sound/weapons/beartrap_shut.ogg', 100, 1)
- deployed = 1
- buckle_mob(L)
- src.animate_shake()
-
- else if(istype(AM, /obj/effect/spider/spiderling) && spider) // for spiderlings
- var/obj/effect/spider/spiderling/S = AM
- captured = WEAKREF(S)
+ if(msg)
+ L.visible_message(
+ "[L] enters \the [src], and it snaps shut with a clatter!",
+ "You enter \the [src], and it snaps shut with a clatter!",
+ "You hear a loud metallic snap!"
+ )
+ if(AM.loc != loc)
+ AM.forceMove(loc)
+ captured = WEAKREF(L)
+ buckle_mob(L)
playsound(src, 'sound/weapons/beartrap_shut.ogg', 100, 1)
- deployed = 1
- buckle_mob(S)
+ deployed = FALSE
src.animate_shake()
- update_icon()
+ update_icon()
/obj/item/weapon/trap/animal/proc/req_breakout()
- if(!deployed)
- return 0 // Cage is open... wait, why are you in it's contents then?
+ if(deployed || !captured)
+ return 0 // Trap-door is open, no one is captured.
if(breakout)
return -1 //Already breaking out.
return 1
@@ -242,25 +252,19 @@
breakout = FALSE
to_chat(escapee, "You successfully break out!")
- visible_message("\the [escapee] successfully broke out of \the [src]!")
+ visible_message("\The [escapee] successfully breaks out of \the [src]!")
playsound(loc, "sound/effects/grillehit.ogg", 100, 1)
release()
-/obj/item/weapon/trap/animal/Collide(AM as mob|obj)
- if(isliving(AM))
- Crossed(AM)
- else
- ..()
-
/obj/item/weapon/trap/animal/CollidedWith(atom/AM)
- if(isliving(AM))
+ if(deployed && is_type_in_list(AM, allowed_mobs))
Crossed(AM)
else
..()
/obj/item/weapon/trap/animal/verb/release_animal()
- set src in oview(1)
+ set src in orange(1)
set category = "Object"
set name = "Release animal"
@@ -273,8 +277,8 @@
var/datum/M = captured ? captured.resolve() : null
- if(deployed)
- var/open = alert("Do you want to open the cage and free what is inside?",,"No","Yes")
+ if(M)
+ var/open = alert("Do you want to open the cage and free \the [M]?",,"No","Yes")
if(open == "No")
return
@@ -284,30 +288,22 @@
return
if(usr == M)
- to_chat(usr, "You cannot open lock \the [src] from the inside. You would have to forcefully open it.")
+ to_chat(usr, "You can't open \the [src] from the inside! You'll need to force it open.")
return
- var/turf/T_cage = get_turf(src)
- var/turf/T_user= get_turf(usr)
-
- if(!T_cage)
+ var/adj = src.Adjacent(usr)
+ if(!adj)
attack_self(src)
return
- var/turf/target = get_turf(locate(T_cage.x + (T_cage.x - T_user.x), T_cage.y + (T_cage.y - T_user.y), T_cage.z))
- if(!target)
- attack_self(src)
- return
-
- release(usr, target)
+ release(usr)
/obj/item/weapon/trap/animal/crush_act()
- for (var/atom/movable/A in src)
- if(istype(A, /mob/living))
- var/mob/living/M = A
- M.gib()
- else if(A.simulated)
- A.ex_act(1)
+ if(captured)
+ var/datum/L = captured ? captured.resolve() : null
+ if(L && isliving(L))
+ var/mob/living/LL = L
+ LL.gib()
new /obj/item/stack/material/steel(get_turf(src))
qdel(src)
@@ -321,8 +317,8 @@
health -= rand(30, 60)
if (health <= 0)
- for (var/atom/movable/A as mob|obj in src)
- A.ex_act(severity + 1)
+ if(captured)
+ release()
new /obj/item/stack/material/steel(get_turf(src))
qdel(src)
@@ -340,7 +336,6 @@
var/datum/L = captured ? captured.resolve() : null
if (!L)
- deployed = FALSE
captured = null
release_time = world.time
return
@@ -349,41 +344,51 @@
if (isliving(L))
var/mob/living/ll = L
msg = "[ll] runs out of \the [src]."
- else if (istype(L, /obj/effect/spider/spiderling))
- var/obj/effect/spider/spiderling/S = L
- msg = "[S] jumps out of \the [src]."
unbuckle_mob()
captured = null
visible_message(msg)
animate_shake()
- deployed = FALSE
update_icon()
release_time = world.time
- can_buckle = FALSE
-/obj/item/weapon/trap/animal/attackby(obj/item/W as obj, mob/user as mob)
- if(istype(W, /obj/item/weapon/reagent_containers) && contents.len)
- var/mob/living/L = pick(contents)
- W.afterattack(L, user, TRUE)
+/obj/item/weapon/trap/animal/attackby(obj/item/W, mob/user)
+ if(istype(W, /obj/item/weapon/grab))
+ var/obj/item/weapon/grab/G = W
+ var/mob/living/M = G.affecting
+
+ if (G.state == GRAB_PASSIVE || G.state == GRAB_UPGRADING)
+ to_chat(user, span("notice", "You need a better grip on \the [M]!"))
+ return
+
+ user.visible_message("[user] starts putting [M] into \the [src].", "You start putting [M] into \the [src].")
+
+ if (!is_type_in_list(M, allowed_mobs))
+ to_chat(user, span("warning", "[M] won't fit in there!"))
+ return
+
+ if (do_mob(user, M, 3 SECONDS, needhand = 0))
+ if(captured?.resolve())
+ return
+ capture(M)
+
else if(W.iswelder())
var/obj/item/weapon/weldingtool/WT = W
- if (!WT.welding)
- to_chat(user, "Your \the [W] is off!")
+ if(!WT.welding)
+ to_chat(user, span("warning", "Your \the [W] is off!"))
return
- user.visible_message("[user] is trying to slice \the [src]!",
- "You are trying to slice \the [src]!")
+ user.visible_message("[user] is trying to slice \the [src] open!",
+ "You are trying to slice \the [src] open!")
- if (!do_after(user, 3 SECONDS, act_target = src))
- return
- if(WT.remove_fuel(0, user))
- user.visible_message("[user] is sliced \the [src]!",
- "You sliced \the [src]!")
- new /obj/item/stack/rods(src.loc, resources["rods"])
- if(resources.len == 2)
- new /obj/item/stack/material/steel(src.loc, resources["metal"])
- release(user)
- qdel(src)
+ if (do_after(user, 30/W.toolspeed, act_target = src))
+ if(WT.remove_fuel(2, user))
+ user.visible_message("[user] slices \the [src] open!",
+ "You slice \the [src] open!")
+ new /obj/item/stack/rods(src.loc, resources["rods"])
+ if(resources.len == 2)
+ new /obj/item/stack/material/steel(src.loc, resources["metal"])
+ release(user)
+ qdel(src)
else if(W.isscrewdriver())
var/turf/T = get_turf(src)
@@ -392,19 +397,14 @@
return
user.visible_message("[user] is trying to [anchored ? "un" : "" ]secure \the [src]!",
- "You are trying to [anchored ? "un" : "" ]secure \the [src]!")
+ "You are trying to [anchored ? "un" : "" ]secure \the [src]!")
playsound(src.loc, "sound/items/[pick("Screwdriver", "Screwdriver2")].ogg", 50, 1)
- if (!do_after(user, 3 SECONDS, act_target = src))
- return
- density = !density
- anchored = !anchored
- user.visible_message("[user] has [anchored ? "" : "un" ]secured \the [src]!",
- "You have [anchored ? "" : "un" ]secured \the [src]!")
-
- else if(istype(W, /obj/item/weapon) && contents.len)
- var/mob/living/L = pick(contents)
- L.attackby(W, user)
+ if (do_after(user, 30/W.toolspeed, act_target = src))
+ density = !density
+ anchored = !anchored
+ user.visible_message("[user] [anchored ? "" : "un" ]secures \the [src]!",
+ "You [anchored ? "" : "un" ]secure \the [src]!")
else
..()
@@ -412,169 +412,107 @@
..()
if(captured)
var/datum/M = captured.resolve()
- if(!M)
- captured = null
- return
if(isliving(M))
var/mob/living/L = M
if(L && buckled_mob.buckled == src)
- L.forceMove(src.loc)
+ L.forceMove(loc)
else if(L)
captured = null
+ else
+ captured = null
-/obj/item/weapon/trap/animal/attack_hand(mob/user as mob)
-
- if (!user) return
- if(user.loc == src) // not to pick ourselves
+/obj/item/weapon/trap/animal/attack_hand(mob/user)
+ if(user.loc == src || captured)
return
- if(anchored)
- to_chat(user, "\The [src] is achorned to the floor!")
- return
-
- if (hasorgans(user))
- var/mob/living/carbon/human/H = user
- var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
- if (user.hand)
- temp = H.organs_by_name["l_hand"]
- if(temp && !temp.is_usable())
- to_chat(user, "You try to move your [temp.name], but cannot!")
- return
- if(!temp)
- to_chat(user, "You try to use your hand, but realize it is no longer attached!")
- return
- src.pickup(user)
- if (istype(src.loc, /obj/item/weapon/storage))
- var/obj/item/weapon/storage/S = src.loc
- S.remove_from_storage(src)
-
- src.throwing = 0
- if (src.loc == user)
- if(!user.prepare_for_slotmove(src))
- return
- else if(isliving(src.loc))
- return
-
- // If equipping onto active hand fails, drop it on the floor.
- if (!user.put_in_active_hand(src))
- forceMove(user.loc)
- return
-
-/obj/item/weapon/trap/animal/MouseDrop(over_object, src_location, over_location)
- if(isliving(usr))
- if(usr.isMonkey() && (/mob/living/carbon/human/monkey in allowed_mobs)) // Because monkeys can be of type of just human.
- usr.visible_message("[usr] is attempting to enter \the [src] without triggering it to pass through.",
- "You are attempting to enter \the [src] without triggering it to pass through. "
- )
- if (!do_after(usr, 2 SECONDS, act_target = src))
- return
- if(prob(50)) // 50% chance to pass by without getting caught.
- usr.forceMove(src.loc)
- usr.visible_message("[usr] pass through \the [src] without triggering it.",
- "You pass through \the [src] without triggering it."
- )
- return
- usr.forceMove(src)
-
- usr.visible_message("[usr] accidentally triggered \the [src]",
- "You accidentally triggered \the [src]"
- )
- playsound(src, 'sound/weapons/beartrap_shut.ogg', 100, 1)
- deployed = 1
- update_icon()
- src.animate_shake()
- return
- for(var/f in allowed_mobs)
- if(istype(usr, f))
- usr.visible_message("[usr] is attempting to enter \the [src] without triggering it to pass through.",
- "You are attempting to enter \the [src] without triggering it to pass through. "
- )
- if (!do_after(usr, 2 SECONDS, act_target = src))
- return
- if(prob(50)) // 50% chance to pass by without getting caught.
- usr.forceMove(src.loc)
- usr.visible_message("[usr] pass through \the [src] without triggering it.",
- "You pass through \the [src] without triggering it."
- )
- return
- usr.forceMove(src)
-
- usr.visible_message("[usr] accidentally triggered \the [src]",
- "You accidentally triggered \the [src]"
- )
- playsound(src, 'sound/weapons/beartrap_shut.ogg', 100, 1)
- deployed = 1
- update_icon()
- src.animate_shake()
- if(iscarbon(usr))
- usr.visible_message("[usr] is attempting to enter \the [src] without triggering it to pass through.",
- "You are attempting to enter \the [src] without triggering it to pass through. "
- )
- if (!do_after(usr, 2 SECONDS, act_target = src))
- return
- usr.forceMove(src.loc)
- usr.visible_message("[usr] pass through \the [src] without triggering it.",
- "You pass through \the [src] without triggering it."
- )
+ if(anchored && deployed)
+ to_chat(user, span("notice", "\The [src] is already anchored and set!"))
+ else if(anchored)
+ deploy(user)
else
..()
-/obj/item/weapon/trap/animal/attack_self(mob/user as mob)
+/obj/item/weapon/trap/animal/proc/pass_without_trace(mob/user, pct = 100)
+ if(!is_type_in_list(user, allowed_mobs))
+ user.forceMove(loc)
+ user.visible_message("[user] passes over \the [src] without triggering it.",
+ "You pass over \the [src] without triggering it."
+ )
+ else
+ user.visible_message("[user] attempts to pass through \the [src] without triggering it.",
+ "You attempt to pass through \the [src] without triggering it. "
+ )
+ if(do_after(user, 2 SECONDS, act_target = src))
+ if(prob(pct))
+ user.forceMove(loc)
+ user.visible_message("[user] passes through \the [src] without triggering it.",
+ "You pass through \the [src] without triggering it."
+ )
+ else
+ user.forceMove(loc)
+ user.visible_message("[user] accidentally triggers \the [src]!",
+ "You accidentally trigger \the [src]!"
+ )
+ capture(user)
+
+/obj/item/weapon/trap/animal/MouseDrop(over_object, src_location, over_location)
+ if(!isliving(usr) || !src.Adjacent(usr))
+ return
+
+ if(captured)
+ pass_without_trace(usr) // It's full
+
+ if((usr.isMonkey() && (/mob/living/carbon/human/monkey in allowed_mobs)) || is_type_in_list(usr, allowed_mobs)) // Because monkeys can be of type of just human.
+ pass_without_trace(usr, 50)
+ return
+
+ else if(iscarbon(usr))
+ pass_without_trace(usr)
+
+ else
+ ..()
+
+/obj/item/weapon/trap/animal/attack_self(mob/user)
if(!can_use(user))
to_chat(user, "You cannot use \the [src].")
return
- if(!contents.len)
- return
-
- release(user, user.loc)
+ if(captured)
+ release(user, user.loc)
/obj/item/weapon/trap/animal/attack(var/target, mob/living/user)
- if(world.time - release_time < 50) // If we just released the animal, not to let it get caught again right away
+ if(!deployed)
return
- if(contents.len) // It is full
+ if(captured) // It is full
return
if(isliving(target))
var/mob/living/M = target
- for(var/f in allowed_mobs)
- if(istype(M, f))
- user.visible_message(
- "[user] traps [M] inside of \the [src].",
- "You trap [M] inside of the \the [src]!",
- "You hear a loud metallic snap!"
- )
- captured = WEAKREF(M)
- M.forceMove(src)
- playsound(src, 'sound/weapons/beartrap_shut.ogg', 100, 1)
- deployed = TRUE
- update_icon()
- src.animate_shake()
-
- else if(istype(target, /obj/effect/spider/spiderling) && spider) // for spiderlings
- var/obj/effect/spider/spiderling/S = target
- captured = WEAKREF(S)
- S.forceMove(src)
- STOP_PROCESSING(SSprocessing, S)
- playsound(src, 'sound/weapons/beartrap_shut.ogg', 100, 1)
- deployed = TRUE
- update_icon()
- src.animate_shake()
+ if(is_type_in_list(M, allowed_mobs))
+ user.visible_message(
+ "[user] traps [M] inside of \the [src].",
+ "You trap [M] inside of the \the [src]!",
+ "You hear a loud metallic snap!"
+ )
+ capture(M, msg = 0)
else
..()
+/obj/item/weapon/trap/animal/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ return TRUE
+
/obj/item/weapon/trap/animal/medium
name = "medium trap"
- desc = "A medium mechanical trap thas is used to catch medium size animals like cat, corgi, diyaab, monkey, yithian, pengiuns, chicken, nymph. Sometimes even maintainence drones, spiderbots and PAi."
+ desc = "A medium mechanical trap that is used to catch moderately-sized animals like cats, monkeys, nymphs, and wayward maintenance drones."
icon_base = "medium"
icon_state = "medium0"
throwforce = 4
force = 5
w_class = 4
- origin_tech = list(TECH_MATERIAL = 3)
+ origin_tech = list(TECH_ENGINEERING = 3)
matter = list(DEFAULT_WALL_MATERIAL = 5750)
- deployed = 0
+ deployed = FALSE
resources = list(rods = 12)
spider = FALSE
@@ -587,16 +525,16 @@
/obj/item/weapon/trap/animal/large
name = "large trap"
- desc = "A large mechanical trap thas is used to catch medium size animals like dog, spider, carp, goat, cow, shark, fox, bear, cavern dwellers, and other kinds of Xenomorphs."
+ desc = "A large mechanical trap that is used to catch larger animals, from spiders and dogs to bears and even larger mammals."
icon_base = "large"
icon_state = "large0"
throwforce = 6
force = 10
w_class = 6
density = 1
- origin_tech = list(TECH_MATERIAL = 4)
+ origin_tech = list(TECH_ENGINEERING = 3)
matter = list(DEFAULT_WALL_MATERIAL = 15750)
- deployed = 0
+ deployed = FALSE
resources = list(rods = 12, metal = 4)
spider = FALSE
@@ -607,55 +545,66 @@
/mob/living/simple_animal/hostile/carp, /mob/living/simple_animal/hostile/bear, /mob/living/simple_animal/hostile/alien, /mob/living/simple_animal/hostile/giant_spider,
/mob/living/simple_animal/hostile/commanded/dog, /mob/living/simple_animal/hostile/retaliate/cavern_dweller, /mob/living/carbon/human/)
-/obj/item/weapon/trap/animal/large/attack_hand(mob/user as mob)
- return
+/obj/item/weapon/trap/animal/large/attack_hand(mob/user)
+ if(user == buckled_mob)
+ return
+ else if(!anchored)
+ to_chat(user, span("warning", "You need to anchor \the [src] first!"))
+ else if(captured)
+ to_chat(user, span("warning", "You can't deploy \the [src] with something caught!"))
+ else
+ ..()
-/obj/item/weapon/trap/animal/large/attackby(obj/item/W as obj, mob/user as mob)
- if(iswrench(W))
+/obj/item/weapon/trap/animal/large/attackby(obj/item/W, mob/user)
+ if(W.iswrench())
var/turf/T = get_turf(src)
if(!T)
to_chat(user, "There is nothing to secure [src] to!")
return
- user.visible_message("[user] is trying to [anchored ? "un" : "" ]secure \the [src]!",
- "You are trying to [anchored ? "un" : "" ]secure \the [src]!")
- playsound(src.loc, W.usesound, 50, 1)
-
- if (!do_after(user, 3 SECONDS, act_target = src))
+ if(anchored && deployed)
+ to_chat(user, span("warning", "You can't do that while \the [src] is deployed! Undeploy it first."))
return
- anchored = !anchored
- user.visible_message("[user] has [anchored ? "" : "un" ]secured \the [src]!",
- "You have [anchored ? "" : "un" ]secured \the [src]!")
- else if(istype(W, /obj/item/weapon/screwdriver))
+ user.visible_message("[user] begins [anchored ? "un" : "" ]securing \the [src]!",
+ "You beign [anchored ? "un" : "" ]securing \the [src]!")
+ playsound(src.loc, W.usesound, 50, 1)
+
+ if(do_after(user, 30/W.toolspeed, act_target = src))
+ anchored = !anchored
+ user.visible_message("[user] [anchored ? "" : "un" ]secures \the [src]!",
+ "You [anchored ? "" : "un" ]secure \the [src]!")
+
+ else if(W.isscrewdriver())
+ // Unlike smaller traps, screwdriver shouldn't work on this.
return
else
..()
/obj/item/weapon/trap/animal/large/MouseDrop(over_object, src_location, over_location)
- if(isliving(usr) && ishuman(usr))
- usr.visible_message("[usr] is attempting to enter \the [src] without triggering it to pass through.",
- "You are attempting to enter \the [src] without triggering it to pass through. "
- )
- if (!do_after(usr, 2 SECONDS, act_target = src))
- return
- if(usr.a_intent == I_HELP || captured?.resolve() || (usr.a_intent != I_HURT && prob(50))) // 50% chance to pass by without getting caught on disarm, drag, 100% on help. Harm will get you caught.
- usr.forceMove(src.loc)
- usr.visible_message("[usr] pass through \the [src] without triggering it.",
- "You pass through \the [src] without triggering it."
- )
- return
- usr.forceMove(src)
+ if(captured)
+ to_chat(usr, span("warning", "The trap door's down, you can't get through there!"))
+ return
- usr.visible_message("[usr] accidentally triggered \the [src]",
- "You accidentally triggered \the [src]"
- )
- playsound(src, 'sound/weapons/beartrap_shut.ogg', 100, 1)
- deployed = 1
- update_icon()
- src.animate_shake()
- else
+ if(!src.Adjacent(usr))
+ return
+
+ if(!ishuman(usr))
..()
+ return
+
+ var/pct = 0
+ if(usr.a_intent == I_HELP)
+ pct = 100
+ else if(usr.a_intent != I_HURT)
+ pct = 50
+
+ pass_without_trace(usr, pct)
+
+/obj/item/weapon/trap/animal/large/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ if(deployed)
+ return TRUE
+ return FALSE
/obj/item/weapon/large_trap_foundation
name = "large trap foundation"
@@ -666,7 +615,7 @@
force = 5
w_class = 5
-/obj/item/weapon/large_trap_foundation/attackby(obj/item/W as obj, mob/user as mob)
+/obj/item/weapon/large_trap_foundation/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/stack/rods))
var/obj/item/stack/rods/O = W
if(O.get_amount() >= 12)
diff --git a/html/changelogs/johnwildkins-trapfix.yml b/html/changelogs/johnwildkins-trapfix.yml
new file mode 100644
index 00000000000..5f1d3c87a55
--- /dev/null
+++ b/html/changelogs/johnwildkins-trapfix.yml
@@ -0,0 +1,46 @@
+################################
+# 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
+# balance
+# admin
+# backend
+# security
+# refactor
+#################################
+
+# Your name.
+author: JohnWildkins
+
+# 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:
+ - refactor: "Traps have been overhauled on the back-end, and their interactions simplified to the end-user."
+ - tweak: "Large traps must now be anchored and then set before use. The process takes three seconds with a wrench and five seconds with an open hand respectively. Large traps can only deploy once anchored."
+ - tweak: "You can place someone/thing into a large trap (via buckling) regardless of the trap's deployment."
+ - bugfix: "You can once again anchor large traps to the floor with a wrench."
+ - bugfix: "Fixed certain parts of the trap capture event not firing depending on the method of capture."
+ - bugfix: "You can no longer teleport inside of traps by attempting to sneak through them from a long distance away."
diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi
index 9386cbeca7a..c7feb6943b9 100644
Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ