Files
VOREStation/code/game/objects/items/weapons/traps.dm
T
Cameron Lennox d5849910e5 Begin clickcode attack_self fix (#18797)
* Begin clickcode attack_self fix

Begins the work to make everything call back to parent for attack_self so that signals are sacred.

* Makes MORE things call the attack_self() parent

Yes, I could make special_handling a var on obj/item HOWEVER i want it to be specific so it can be tracked down later and ONLY the objects that use it can be refactored instead of sitting there literally forever and it just becoming 'a thing'.

* Finishes making the rest of attack_self call parent.

As mentioned, things such as 'specialty_goggles' 'special_handling' and the such are only there to help with attack_self until the attack_self is recoded for those items.

* begone foul demon

* some more cleanup

* These

* GOD this was annoying

* yeh

* Fix this

* fLARES

* Thesee too

* toys!

* Even more!

* More fixes

* Even more

* rest of em

* these too

* Update syndie.dm

* hardref clear

* Update code/game/gamemodes/nuclear/pinpointer.dm

* Update code/game/objects/effects/mines.dm

* Update code/game/objects/items/blueprints_vr.dm

* Update code/game/objects/items/blueprints_vr.dm

* Update code/game/objects/items/contraband_vr.dm

* Update code/game/objects/items/crayons.dm

* Update code/game/objects/items/crayons.dm

* Update code/game/objects/items/gunbox.dm

* Update code/game/objects/items/gunbox.dm

* Update code/game/objects/items/gunbox_vr.dm

* Update code/game/objects/items/gunbox_vr.dm

* Update code/game/objects/items/weapons/gift_wrappaper.dm

* Update code/game/objects/items/crayons.dm

* Update code/game/objects/items/crayons.dm

* Update code/game/objects/items/gunbox.dm

* these too

* Update maintpanel_stack.dm

* angry warning

* Fixes packaged snacks.

Fixes improper var default.

* Special handling for these

* proper poly types

* Fixes magclaws

Makes the 'features' it had just part  of base magboots that can be adjusted via varswap.

* Fixes jackets

Fixes https://github.com/VOREStation/VOREStation/issues/18941

* Small bugfix

Makes p_Theyre properly capitialize
Makes examine show proper wording

* Update gift_wrappaper.dm
2025-12-29 13:21:10 -05:00

405 lines
11 KiB
Plaintext

/*
* Beartraps.
* Buckles crossing individuals, doing moderate brute damage.
*/
/obj/item/beartrap
name = "mechanical trap"
throw_speed = 2
throw_range = 1
gender = PLURAL
icon = 'icons/obj/items.dmi'
icon_state = "beartrap0"
desc = "A mechanically activated leg trap. Low-tech, but reliable. Looks like it could really hurt if you set it off."
randpixel = 0
center_of_mass_x = 0
center_of_mass_y = 0
throwforce = 0
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_MATERIAL = 1)
matter = list(MAT_STEEL = 18750)
var/deployed = 0
var/camo_net = FALSE
var/stun_length = 0.25 SECONDS
/obj/item/beartrap/start_active
deployed = TRUE
/obj/item/beartrap/Initialize(mapload)
. = ..()
if(mapload && deployed)
update_icon()
/obj/item/beartrap/proc/can_use(mob/user)
return (user.IsAdvancedToolUser() && !issilicon(user) && !user.stat && !user.restrained())
/obj/item/beartrap/attack_self(mob/user)
. = ..(user)
if(.)
return TRUE
if(!deployed && can_use(user))
user.visible_message(
span_danger("[user] starts to deploy \the [src]."),
span_danger("You begin deploying \the [src]!"),
"You hear the slow creaking of a spring."
)
if (do_after(user, 6 SECONDS, target = src))
user.visible_message(
span_danger("[user] has deployed \the [src]."),
span_danger("You have deployed \the [src]!"),
"You hear a latch click loudly."
)
playsound(src, 'sound/machines/click.ogg',70, 1)
deployed = 1
user.drop_from_inventory(src)
update_icon()
anchored = TRUE
log_and_message_admins("has set up a [name] at \the [get_area(loc)]", user)
/obj/item/beartrap/attack_hand(mob/user as mob)
if(has_buckled_mobs() && can_use(user))
var/victim = english_list(buckled_mobs)
user.visible_message(
span_notice("[user] begins freeing [victim] from \the [src]."),
span_notice("You carefully begin to free [victim] from \the [src]."),
)
if(do_after(user, 6 SECONDS, target = src))
user.visible_message(span_notice("[victim] has been freed from \the [src] by [user]."))
for(var/A in buckled_mobs)
unbuckle_mob(A)
anchored = FALSE
else if(deployed && can_use(user))
user.visible_message(
span_danger("[user] starts to disarm \the [src]."),
span_notice("You begin disarming \the [src]!"),
"You hear a latch click followed by the slow creaking of a spring."
)
playsound(src, 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 6 SECONDS, target = src))
user.visible_message(
span_danger("[user] has disarmed \the [src]."),
span_notice("You have disarmed \the [src]!")
)
deployed = 0
anchored = FALSE
update_icon()
else
..()
/obj/item/beartrap/proc/attack_mob(mob/living/L)
var/target_zone
if(L.lying)
target_zone = ran_zone()
else
target_zone = pick(BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG)
//armour
var/blocked = L.run_armor_check(target_zone, "melee")
if(blocked >= 100)
return
if(!L.apply_damage(30, BRUTE, target_zone, blocked, used_weapon=src))
return 0
if(ishuman(L))
var/mob/living/carbon/human/H = L
var/obj/item/organ/external/affected = H.get_organ(check_zone(target_zone))
if(!affected) // took it clean off!
to_chat(H, span_danger("The steel jaws of \the [src] take your limb clean off!"))
L.Stun(stun_length*2)
deployed = 0
anchored = FALSE
return
//trap the victim in place
set_dir(L.dir)
can_buckle = TRUE
buckle_mob(L)
L.Stun(stun_length)
to_chat(L, span_danger("The steel jaws of \the [src] bite into you, trapping you in place!"))
deployed = 0
anchored = FALSE
can_buckle = initial(can_buckle)
/obj/item/beartrap/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(deployed && isliving(AM))
var/mob/living/L = AM
if(L.m_intent == I_RUN)
L.visible_message(
span_danger("[L] steps on \the [src]."),
span_danger("You step on \the [src]!"),
span_infoplain(span_bold("You hear a loud metallic snap!"))
)
SSmotiontracker.ping(src,100) // Clunk!
attack_mob(L)
if(!has_buckled_mobs())
anchored = FALSE
deployed = 0
update_icon()
log_and_message_admins("has sprung a [name] at \the [get_area(loc)], last touched by [forensic_data?.get_lastprint()]", L)
..()
/obj/item/beartrap/update_icon()
..()
if(!deployed)
if(camo_net)
alpha = 255
icon_state = "beartrap0"
else
if(camo_net)
alpha = 50
icon_state = "beartrap1"
/obj/item/beartrap/hunting
name = "hunting trap"
desc = "A mechanically activated leg trap. High-tech and reliable. Looks like it could really hurt if you set it off."
stun_length = 1 SECOND
camo_net = TRUE
color = "#C9DCE1"
origin_tech = list(TECH_MATERIAL = 4, TECH_BLUESPACE = 3, TECH_MAGNET = 4, TECH_PHORON = 2, TECH_ARCANE = 1)
/*
* Barbed-Wire.
* Slows individuals crossing it. Barefoot individuals will be cut. Can be electrified by placing over a cable node.
*/
/obj/item/material/barbedwire
name = "barbed wire"
desc = "A coil of wire."
icon = 'icons/obj/trap.dmi'
icon_state = "barbedwire"
anchored = FALSE
layer = TABLE_LAYER
w_class = ITEMSIZE_LARGE
explosion_resistance = 1
can_dull = TRUE
fragile = TRUE
force_divisor = 0.20
thrown_force_divisor = 0.25
sharp = TRUE
/obj/item/material/barbedwire/set_material(var/new_material)
..()
if(!QDELETED(src))
health = round(material.integrity / 3)
name = (material.get_edge_damage() * force_divisor > 15) ? "[material.display_name] razor wire" : "[material.display_name] [initial(name)]"
/obj/item/material/barbedwire/proc/can_use(mob/user)
return (user.IsAdvancedToolUser() && !issilicon(user) && !user.stat && !user.restrained())
/obj/item/material/barbedwire/attack_hand(mob/user as mob)
if(anchored && can_use(user))
user.visible_message(
span_danger("[user] starts to collect \the [src]."),
span_notice("You begin collecting \the [src]!"),
"You hear the sound of rustling [material.name]."
)
playsound(src, 'sound/machines/click.ogg', 50, 1)
if(do_after(user, health, target = src))
user.visible_message(
span_danger("[user] has collected \the [src]."),
span_notice("You have collected \the [src]!")
)
anchored = FALSE
update_icon()
else
..()
/obj/item/material/barbedwire/attack_self(mob/user)
. = ..(user)
if(.)
return TRUE
if(!anchored && can_use(user))
user.visible_message(
span_danger("[user] starts to deploy \the [src]."),
span_danger("You begin deploying \the [src]!"),
"You hear the rustling of [material.name]."
)
if (do_after(user, 6 SECONDS, target = src))
user.visible_message(
span_danger("[user] has deployed \the [src]."),
span_danger("You have deployed \the [src]!"),
"You hear the rustling of [material.name]."
)
playsound(src, 'sound/items/Wirecutter.ogg',70, 1)
spawn(2)
playsound(src, 'sound/items/Wirecutter.ogg',40, 1)
user.drop_from_inventory(src)
forceMove(get_turf(src))
anchored = TRUE
update_icon()
/obj/item/material/barbedwire/attackby(obj/item/W as obj, mob/user as mob)
if(!istype(W))
return
if((W.flags & NOCONDUCT) || !shock(user, 70, pick(BP_L_HAND, BP_R_HAND)))
user.setClickCooldown(user.get_attack_speed(W))
user.do_attack_animation(src)
playsound(src, 'sound/effects/grillehit.ogg', 40, 1)
var/inc_damage = W.force
if(W.has_tool_quality(TOOL_WIRECUTTER))
if(!shock(user, 100, pick(BP_L_HAND, BP_R_HAND)))
playsound(src, W.usesound, 100, 1)
inc_damage *= 3
if(W.damtype != BRUTE)
inc_damage *= 0.3
health -= inc_damage
check_health()
..()
/obj/item/material/barbedwire/update_icon()
..()
if(anchored)
icon_state = "[initial(icon_state)]-out"
else
icon_state = "[initial(icon_state)]"
/obj/item/material/barbedwire/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(anchored && isliving(AM))
var/mob/living/L = AM
if(L.m_intent == I_RUN)
L.visible_message(
span_danger("[L] steps in \the [src]."),
span_danger("You step in \the [src]!"),
span_infoplain(span_bold("You hear a sharp rustling!"))
)
attack_mob(L)
update_icon()
..()
/obj/item/material/barbedwire/proc/shock(mob/user as mob, prb, var/target_zone = BP_TORSO)
if(!anchored || health == 0) // anchored/destroyed grilles are never connected
return 0
if(material.conductivity <= 0)
return 0
if(!prob(prb))
return 0
if(!in_range(src, user))//To prevent TK and mech users from getting shocked
return 0
var/turf/T = get_turf(src)
var/obj/structure/cable/C = T.get_cable_node()
if(C)
if(C.powernet)
var/datum/powernet/PN = C.powernet
if(PN)
PN.trigger_warning()
var/PN_damage = PN.get_electrocute_damage() * (material.conductivity / 50)
var/drained_energy = PN_damage * 10 / CELLRATE
PN.draw_power(drained_energy)
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/obj/item/organ/external/affected = H.get_organ(check_zone(target_zone))
H.electrocute_act(PN_damage, src, H.get_siemens_coefficient_organ(affected))
else
if(isliving(user))
var/mob/living/L = user
L.electrocute_act(PN_damage, src, 0.8)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
if(user.stunned)
return 1
else
return 0
return 0
/obj/item/material/barbedwire/proc/attack_mob(mob/living/L)
var/target_zone
if(L.lying)
target_zone = ran_zone()
else
target_zone = pick(BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG)
//armour
var/blocked = L.run_armor_check(target_zone, "melee")
if(blocked >= 100)
return
if(L.buckled) //wheelchairs, office chairs, rollerbeds
return
shock(L, 100, target_zone)
L.add_modifier(/datum/modifier/entangled, 3 SECONDS)
if(!L.apply_damage(force * (issilicon(L) ? 0.25 : 1), BRUTE, target_zone, blocked, sharp, edge, src))
return
playsound(src, 'sound/effects/glass_step.ogg', 50, 1) // not sure how to handle metal shards with sounds
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.species.siemens_coefficient<0.5) //Thick skin.
return
if( H.shoes || ( H.wear_suit && (H.wear_suit.body_parts_covered & FEET) ) )
return
if(H.species.flags & NO_MINOR_CUT)
return
to_chat(H, span_danger("You step directly on \the [src]!"))
var/list/check = list(BP_L_FOOT, BP_R_FOOT)
while(check.len)
var/picked = pick(check)
var/obj/item/organ/external/affecting = H.get_organ(picked)
if(affecting)
if(affecting.robotic >= ORGAN_ROBOT)
return
if(affecting.take_damage(force, 0))
H.UpdateDamageIcon()
H.updatehealth()
if(affecting.organ_can_feel_pain())
H.Weaken(3)
return
check -= picked
if(material.is_brittle() && prob(material.hardness))
health = 0
else if(!prob(material.hardness))
health--
check_health()
return
/obj/item/material/barbedwire/plastic
name = "snare wire"
default_material = MAT_PLASTIC