Files
VOREStation/code/game/objects/items/weapons/traps.dm
T
Cameron Lennox c42610c5ae Have you bingled that (#17407)
* Initial wiki system

* wiki organization and spoilers

* hide belly chems

* move ads to tgui

* add search

* .

* load screen

* error screen

* 8

* center

* .

* .

* make this more realistic

* tgui errro col

* move search to top

* .

* non NT theme

* logo to common

* base custom theme

* .

* wip refactor

* almost halfway

* reworked wiki data

* easy fix

* get data fix

* Material Page in tgui

* catch null supply points

* .

* forward crash

* reset pages

* .

* canvas prep

* fix icon stacking

* .

* colored outlined images

* fix sm datum

* fix material names

* subType prep

* only on crash

* fix null crash

* .

* fix solgov

* clean hiding

* .

* implement catalog page

* .

* particle smasher page

* I'm lazy

* unfuck some sins

* ore page

* botany page

* allergen list

* allergen returns null too

* slime injection var

* slime core data

* fixed warning

* wip

* proper data list for chems

* pass is_slime as null

* chems

* split that

* .

* .

* .

* .

* donation for bingle, some cleanup

* return types

* partially colord icons for chemistry

* .

* more sillies

* donation page

* thaler

* needs some variation

* .

* this will crash until implemented

* handle it

* fix that

* dismiss donation banner button

* .

* fix that

* donating procs

* donation stuff for comp

* -

* drink glass for drinks

* illegal iconstate pass

* fixes

* .

* nuke drink fix

* .

* .

* .

* Drink reagent fix

* more cleanup

* adjust

* .

* simple food

* .

* food list

* sending nulls, removed flavor from recipes

* .

* .

* get_donation_current added

* .

* missing key

* .

* duped recipes fixed

* .

* .

* wiki food reagent recipes

* double list add

* properly forbid remaining bad reagent

* hide this too

* stacky

* enable eslint const

* fix typing

* update that

* use proper donation proc

* printing fixes

* grinding

* .

* beaker fill volume

* plant ore and mat grinding results

* duped recipes fixed, unit test tweak

* yes this is terrible

* .

* .

* .

* chem analyzer tgui mode, some subsystem changes to support it

* redoce

* .

* ,

* .

* small fixes, missing reagent volume

* push

* sort

* catalog entries unlocked by explo

* new chem stuff

* .

* fix byond code

* fix scroll tracking

* comment

* alphabetical

* also this

* .

* fallback icon

* .

* ...

* rel path

* that too

* to defines

* organ to define

* .

* .

* .

---------

Co-authored-by: Willburd <7099514+Willburd@users.noreply.github.com>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
2025-03-28 19:00:50 +01:00

399 lines
10 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/proc/can_use(mob/user)
return (user.IsAdvancedToolUser() && !issilicon(user) && !user.stat && !user.restrained())
/obj/item/beartrap/attack_self(mob/user as mob)
..()
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, 60))
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
/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, 60))
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, 60))
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")
var/soaked = L.get_armor_soak(target_zone, "melee")
if(blocked >= 100)
return
if(soaked >= 30)
return
if(!L.apply_damage(30, BRUTE, target_zone, blocked, soaked, 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()
..()
/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))
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 as mob)
..()
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, 60))
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")
var/soaked = L.get_armor_soak(target_zone, "melee")
if(blocked >= 100)
return
if(soaked >= 30)
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, soaked, 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