This commit is contained in:
Hatterhat
2020-01-12 02:49:58 -06:00
129 changed files with 4829 additions and 6595 deletions
@@ -104,15 +104,4 @@
if(explosion_message)
location.visible_message("<span class='danger'>The solution violently explodes!</span>", \
"<span class='italics'>You hear an explosion!</span>")
if (amount < 1)
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(2, 1, location)
s.start()
for(var/mob/living/L in viewers(1, location))
if(prob(50 * amount))
to_chat(L, "<span class='danger'>The explosion knocks you down.</span>")
L.Knockdown(rand(20,100))
return
else
dyn_explosion(location, amount, flashing_factor)
dyn_explosion(location, amount, flashing_factor)
@@ -452,4 +452,45 @@
icon_state = "slugboom"
randomdir = FALSE
duration = 30
pixel_x = -24
pixel_x = -24
/obj/effect/constructing_effect
icon = 'icons/effects/effects_rcd.dmi'
icon_state = ""
layer = ABOVE_ALL_MOB_LAYER
anchored = TRUE
var/status = 0
var/delay = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/obj/effect/constructing_effect/Initialize(mapload, rcd_delay, rcd_status)
. = ..()
status = rcd_status
delay = rcd_delay
if (status == RCD_DECONSTRUCT)
addtimer(CALLBACK(src, /atom/.proc/update_icon), 11)
delay -= 11
icon_state = "rcd_end_reverse"
else
update_icon()
/obj/effect/constructing_effect/update_icon()
icon_state = "rcd"
if (delay < 10)
icon_state += "_shortest"
else if (delay < 20)
icon_state += "_shorter"
else if (delay < 37)
icon_state += "_short"
if (status == RCD_DECONSTRUCT)
icon_state += "_reverse"
/obj/effect/constructing_effect/proc/end_animation()
if (status == RCD_DECONSTRUCT)
qdel(src)
else
icon_state = "rcd_end"
addtimer(CALLBACK(src, .proc/end), 15)
/obj/effect/constructing_effect/proc/end()
qdel(src)
+29 -9
View File
@@ -47,7 +47,11 @@ RLD
/obj/item/construction/examine(mob/user)
. = ..()
. += "\A [src]. It currently holds [matter]/[max_matter] matter-units."
. += "It currently holds [matter]/[max_matter] matter-units."
if(upgrade & RCD_UPGRADE_FRAMES)
. += "It contains the design for machine frames, computer frames and deconstruction."
if(upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS)
. += "It contains the design for firelock, air alarm, fire alarm, apc circuits and crap power cells."
/obj/item/construction/Destroy()
QDEL_NULL(spark_system)
@@ -85,9 +89,11 @@ RLD
to_chat(user, "<span class='notice'>[src] now holds [matter]/[max_matter] matter-units.</span>")
else if(istype(W, /obj/item/rcd_upgrade))
to_chat(user, "<span class='notice'>You upgrade the RCD with the [W]!</span>")
upgrade = TRUE
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
qdel(W)
var/obj/item/rcd_upgrade/rcd_up = W
if(!(upgrade & rcd_up.upgrade))
upgrade |= rcd_up.upgrade
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
qdel(W)
else
return ..()
update_icon() //ensures that ammo counters (if present) get updated
@@ -116,10 +122,10 @@ RLD
if(matter < amount)
if(user)
to_chat(user, no_ammo_message)
return 0
return FALSE
matter -= amount
update_icon()
return 1
return TRUE
/obj/item/construction/proc/checkResource(amount, mob/user)
. = matter >= amount
@@ -439,18 +445,22 @@ RLD
var/list/rcd_results = A.rcd_vals(user, src)
if(!rcd_results)
return FALSE
var/delay = rcd_results["delay"] * delay_mod
var/obj/effect/constructing_effect/rcd_effect = new(get_turf(A), delay, src.mode)
var/turf/the_turf = get_turf(A)
var/turf_coords = "[COORD(the_turf)]"
investigate_log("[user] is attempting to use [src] on [A] (loc [turf_coords] at [the_turf]) with cost [rcd_results["cost"]], delay [rcd_results["delay"]], mode [rcd_results["mode"]].", INVESTIGATE_RCD)
if(do_after(user, rcd_results["delay"] * delay_mod, target = A))
if(do_after(user, delay, target = A))
if(checkResource(rcd_results["cost"], user))
var/atom/cached = A
if(A.rcd_act(user, src, rcd_results["mode"]))
rcd_effect.end_animation()
useResource(rcd_results["cost"], user)
activate()
investigate_log("[user] used [src] on [cached] (loc [turf_coords] at [the_turf]) with cost [rcd_results["cost"]], delay [rcd_results["delay"]], mode [rcd_results["mode"]].", INVESTIGATE_RCD)
playsound(src, 'sound/machines/click.ogg', 50, 1)
return TRUE
qdel(rcd_effect)
/obj/item/construction/rcd/Initialize()
. = ..()
@@ -467,7 +477,7 @@ RLD
"Grilles & Windows" = image(icon = 'icons/mob/radial.dmi', icon_state = "grillewindow"),
"Floors & Walls" = image(icon = 'icons/mob/radial.dmi', icon_state = "wallfloor")
)
if(upgrade)
if(upgrade & RCD_UPGRADE_FRAMES)
choices += list(
"Deconstruct" = image(icon= 'icons/mob/radial.dmi', icon_state = "delete"),
"Machine Frames" = image(icon = 'icons/mob/radial.dmi', icon_state = "machine"),
@@ -593,6 +603,7 @@ RLD
energyfactor = 66
/obj/item/construction/rcd/loaded
materials = list(MAT_METAL=48000, MAT_GLASS=32000)
matter = 160
/obj/item/construction/rcd/loaded/upgraded
@@ -825,9 +836,18 @@ RLD
/obj/item/rcd_upgrade
name = "RCD advanced design disk"
desc = "It contains the design for machine frames, computer frames, and deconstruction."
desc = "It seems to be empty."
icon = 'icons/obj/module.dmi'
icon_state = "datadisk3"
var/upgrade
/obj/item/rcd_upgrade/frames
desc = "It contains the design for machine frames, computer frames and deconstruction."
upgrade = RCD_UPGRADE_FRAMES
/obj/item/rcd_upgrade/simple_circuits
desc = "It contains the design for firelock, air alarm, fire alarm, apc circuits and crap power cells."
upgrade = RCD_UPGRADE_SIMPLE_CIRCUITS
#undef GLOW_MODE
#undef LIGHT_MODE
@@ -7,6 +7,10 @@
/obj/item/stack/cable_coil = 1,
/obj/item/stack/sheet/glass = 2)
/obj/item/circuitboard/machine/sleeper/syndie
name = "Syndicate Sleeper (Machine Board)"
build_path = /obj/machinery/sleeper/syndie
/obj/item/circuitboard/machine/vr_sleeper
name = "VR Sleeper (Machine Board)"
build_path = /obj/machinery/vr_sleeper
@@ -1000,3 +1004,16 @@
/obj/item/stock_parts/capacitor = 1,
/obj/item/stack/cable_coil = 5,
/obj/item/reagent_containers/glass/beaker = 6) //So it can hold lots of chems
/obj/item/circuitboard/machine/kinkmate
name = "Kinkmate Vendor (Machine Board)"
build_path = /obj/machinery/vending/kink
req_components = list(/obj/item/vending_refill/kink = 1)
/obj/item/circuitboard/machine/autoylathe
name = "Autoylathe (Machine Board)"
build_path = /obj/machinery/autoylathe
req_components = list(
/obj/item/stock_parts/matter_bin = 3,
/obj/item/stock_parts/manipulator = 1,
/obj/item/stack/sheet/glass = 1)
@@ -16,14 +16,14 @@
/obj/item/doorCharge/ex_act(severity, target)
switch(severity)
if(1)
if(EXPLODE_DEVASTATE)
visible_message("<span class='warning'>[src] detonates!</span>")
explosion(src.loc,0,2,1,flame_range = 4)
qdel(src)
if(2)
if(EXPLODE_HEAVY)
if(prob(50))
ex_act(EXPLODE_DEVASTATE)
if(3)
if(EXPLODE_LIGHT)
if(prob(25))
ex_act(EXPLODE_DEVASTATE)
@@ -10,7 +10,7 @@
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
materials = list(MAT_METAL=250, MAT_GLASS=500)
var/max_shield_integrity = 250
var/max_shield_integrity = 100
var/shield_integrity = 250
var/max_fields = 3
var/list/current_fields
@@ -87,7 +87,7 @@
mouse_opacity = MOUSE_OPACITY_OPAQUE
resistance_flags = INDESTRUCTIBLE
CanAtmosPass = ATMOS_PASS_DENSITY
armor = list("melee" = 0, "bullet" = 25, "laser" = 50, "energy" = 50, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
armor = list("melee" = 0, "bullet" = 25, "laser" = 25, "energy" = 25, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
var/obj/item/forcefield_projector/generator
/obj/structure/projected_forcefield/Initialize(mapload, obj/item/forcefield_projector/origin)
@@ -10,22 +10,23 @@
slot_flags = ITEM_SLOT_BACK
w_class = WEIGHT_CLASS_HUGE
materials = list(MAT_METAL=10000, MAT_GLASS=2500)
var/on = TRUE
var/code = 2
var/frequency = FREQ_ELECTROPACK
var/shock_cooldown = 0
var/on = TRUE
var/shock_cooldown = FALSE
/obj/item/electropack/suicide_act(mob/user)
/obj/item/electropack/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] hooks [user.p_them()]self to the electropack and spams the trigger! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (FIRELOSS)
/obj/item/electropack/Initialize()
. = ..()
SSradio.add_object(src, frequency, RADIO_SIGNALER)
set_frequency(frequency)
/obj/item/electropack/Destroy()
SSradio.remove_object(src, frequency)
return ..()
. = ..()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/electropack/attack_hand(mob/user)
@@ -36,7 +37,7 @@
return
return ..()
/obj/item/electropack/attackby(obj/item/W, mob/user, params)
/obj/item/electropack/attackby(obj/item/W, mob/living/user, params)
if(istype(W, /obj/item/clothing/head/helmet))
var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit(user)
A.icon = 'icons/obj/assemblies.dmi'
@@ -57,43 +58,47 @@
return ..()
/obj/item/electropack/Topic(href, href_list)
//..()
var/mob/living/carbon/C = usr
if(usr.stat || usr.restrained() || C.back == src)
return
if((ishuman(usr) && usr.contents.Find(src)) || usr.contents.Find(master) || (in_range(src, usr) && isturf(loc)))
usr.set_machine(src)
if(href_list["freq"])
SSradio.remove_object(src, frequency)
frequency = sanitize_frequency(frequency + text2num(href_list["freq"]))
SSradio.add_object(src, frequency, RADIO_SIGNALER)
else
if(href_list["code"])
code += text2num(href_list["code"])
code = round(code)
code = min(100, code)
code = max(1, code)
else
if(href_list["power"])
on = !( on )
icon_state = "electropack[on]"
if(!( master ))
if(ismob(loc))
attack_self(loc)
else
for(var/mob/M in viewers(1, src))
if(M.client)
attack_self(M)
else
if(ismob(master.loc))
attack_self(master.loc)
else
for(var/mob/M in viewers(1, master))
if(M.client)
attack_self(M)
else
if(!usr.canUseTopic(src, BE_CLOSE))
usr << browse(null, "window=radio")
onclose(usr, "radio")
return
if(href_list["set"])
if(href_list["set"] == "freq")
var/new_freq = input(usr, "Input a new receiving frequency", "Electropack Frequency", format_frequency(frequency)) as num|null
if(!usr.canUseTopic(src, BE_CLOSE))
return
new_freq = unformat_frequency(new_freq)
new_freq = sanitize_frequency(new_freq, TRUE)
set_frequency(new_freq)
if(href_list["set"] == "code")
var/new_code = input(usr, "Input a new receiving code", "Electropack Code", code) as num|null
if(!usr.canUseTopic(src, BE_CLOSE))
return
new_code = round(new_code)
new_code = CLAMP(new_code, 1, 100)
code = new_code
if(href_list["set"] == "power")
if(!usr.canUseTopic(src, BE_CLOSE))
return
on = !(on)
icon_state = "electropack[on]"
if(usr)
attack_self(usr)
return
/obj/item/electropack/proc/set_frequency(new_frequency)
SSradio.remove_object(src, frequency)
frequency = new_frequency
SSradio.add_object(src, frequency, RADIO_SIGNALER)
return
/obj/item/electropack/receive_signal(datum/signal/signal)
@@ -101,10 +106,10 @@
return
if(isliving(loc) && on)
if(shock_cooldown != 0)
if(shock_cooldown == TRUE)
return
shock_cooldown = 1
addtimer(VARSET_CALLBACK(src, shock_cooldown, 0), 100)
shock_cooldown = TRUE
addtimer(VARSET_CALLBACK(src, shock_cooldown, FALSE), 100)
var/mob/living/L = loc
step(L, pick(GLOB.cardinals))
@@ -119,25 +124,22 @@
master.receive_signal()
return
/obj/item/electropack/attack_self(mob/user)
/obj/item/electropack/ui_interact(mob/user)
if(!ishuman(user))
return
user.set_machine(src)
var/dat = {"<TT>Turned [on ? "On" : "Off"] -
<A href='?src=[REF(src)];power=1'>Toggle</A><BR>
var/dat = {"
<TT>
Turned [on ? "On" : "Off"] - <A href='?src=[REF(src)];set=power'>Toggle</A><BR>
<B>Frequency/Code</B> for electropack:<BR>
Frequency:
<A href='byond://?src=[REF(src)];freq=-10'>-</A>
<A href='byond://?src=[REF(src)];freq=-2'>-</A> [format_frequency(frequency)]
<A href='byond://?src=[REF(src)];freq=2'>+</A>
<A href='byond://?src=[REF(src)];freq=10'>+</A><BR>
[format_frequency(src.frequency)]
<A href='byond://?src=[REF(src)];set=freq'>Set</A><BR>
Code:
<A href='byond://?src=[REF(src)];code=-5'>-</A>
<A href='byond://?src=[REF(src)];code=-1'>-</A> [code]
<A href='byond://?src=[REF(src)];code=1'>+</A>
<A href='byond://?src=[REF(src)];code=5'>+</A><BR>
[src.code]
<A href='byond://?src=[REF(src)];set=code'>Set</A><BR>
</TT>"}
user << browse(dat, "window=radio")
onclose(user, "radio")
+12 -11
View File
@@ -466,17 +466,18 @@ SLIME SCANNER
msg += "<span class='notice'>Subject is not addicted to any reagents.</span>\n"
var/datum/reagent/impure/fermiTox/F = M.reagents.has_reagent(/datum/reagent/impure/fermiTox)
switch(F?.volume)
if(5 to 10)
msg += "<span class='notice'>Subject contains a low amount of toxic isomers.</span>\n"
if(10 to 25)
msg += "<span class='danger'>Subject contains toxic isomers.</span>\n"
if(25 to 50)
msg += "<span class='danger'>Subject contains a substantial amount of toxic isomers.</span>\n"
if(50 to 95)
msg += "<span class='danger'>Subject contains a high amount of toxic isomers.</span>\n"
if(95 to INFINITY)
msg += "<span class='danger'>Subject contains a extremely dangerous amount of toxic isomers.</span>\n"
if(istype(F))
switch(F.volume)
if(5 to 10)
msg += "<span class='notice'>Subject contains a low amount of toxic isomers.</span>\n"
if(10 to 25)
msg += "<span class='danger'>Subject contains toxic isomers.</span>\n"
if(25 to 50)
msg += "<span class='danger'>Subject contains a substantial amount of toxic isomers.</span>\n"
if(50 to 95)
msg += "<span class='danger'>Subject contains a high amount of toxic isomers.</span>\n"
if(95 to INFINITY)
msg += "<span class='danger'>Subject contains a extremely dangerous amount of toxic isomers.</span>\n"
msg += "*---------*</span>"
to_chat(user, msg)
+1 -1
View File
@@ -65,7 +65,7 @@
icon_state = "foam_extinguisher0"
//item_state = "foam_extinguisher" needs sprite
dog_fashion = null
chem = "firefighting_foam"
chem = /datum/reagent/firefighting_foam
tanktype = /obj/structure/reagent_dispensers/foamtank
sprite_name = "foam_extinguisher"
precision = TRUE
+1 -1
View File
@@ -62,7 +62,7 @@
location = get_turf(target)
target.cut_overlay(plastic_overlay, TRUE)
if(!ismob(target) || full_damage_on_mobs)
target.ex_act(2, target)
target.ex_act(EXPLODE_HEAVY, target)
else
location = get_turf(src)
if(location)
+9 -1
View File
@@ -78,12 +78,20 @@
/obj/item/holosign_creator/atmos
name = "ATMOS holofan projector"
desc = "A holographic projector that creates holographic barriers that prevent changes in atmosphere conditions."
desc = "A holographic projector that creates holographic fans that prevent changes in atmosphere conditions. Somehow."
icon_state = "signmaker_atmos"
holosign_type = /obj/structure/holosign/barrier/atmos
creation_time = 0
max_signs = 3
/obj/item/holosign_creator/firelock
name = "ATMOS holofirelock projector"
desc = "A holographic projector that creates holographic barriers that prevent changes in temperature conditions."
icon_state = "signmaker_engi"
holosign_type = /obj/structure/holosign/barrier/firelock
creation_time = 0
max_signs = 3
/obj/item/holosign_creator/medical
name = "\improper PENLITE barrier projector"
desc = "A holographic projector that creates PENLITE holobarriers. Useful during quarantines since they halt those with malicious diseases."
+7 -1
View File
@@ -886,7 +886,7 @@
else
O.anchored = initial(O.anchored)
else
to_chat(user, "<span class='warning'>Not enough room in cargo compartment! Maximum of eight objects!</span>")
to_chat(user, "<span class='warning'>Not enough room in cargo compartment! Maximum of [cargo_capacity] objects!</span>")
else
to_chat(user, "<span class='warning'>[target] is firmly secured!</span>")
@@ -899,6 +899,12 @@
user.visible_message("[user] unloads [chosen_cargo] from its cargo.")
playsound(loc, 'sound/effects/bin_close.ogg', 50, 0)
/obj/item/cyborg_clamp/Destroy()
for(var/atom/movable/target in cargo)
target.forceMove(get_turf(src))
playsound(loc, 'sound/effects/bin_close.ogg', 50, 0)
return ..()
/obj/item/card/id/miningborg
name = "mining point card"
desc = "A robotic ID strip used for claiming and transferring mining points. Must be held in an active slot to transfer points."
+9 -3
View File
@@ -781,6 +781,11 @@
throwforce = 20
throw_speed = 4
attack_verb = list("gored")
var/clonechance = 50
var/clonedamage = 12
var/clonespeed = 0
var/clone_replication_chance = 30
var/clone_lifespan = 100
/obj/item/twohanded/spear/grey_tide/afterattack(atom/movable/AM, mob/living/user, proximity)
. = ..()
@@ -791,10 +796,11 @@
var/mob/living/L = AM
if(istype (L, /mob/living/simple_animal/hostile/illusion))
return
if(!L.stat && prob(50))
if(!L.stat && prob(clonechance))
var/mob/living/simple_animal/hostile/illusion/M = new(user.loc)
M.faction = user.faction.Copy()
M.Copy_Parent(user, 100, user.health/2.5, 12, 30)
M.set_varspeed(clonespeed)
M.Copy_Parent(user, clone_lifespan, user.health/2.5, clonedamage, clone_replication_chance)
M.GiveTarget(L)
/obj/item/twohanded/pitchfork
@@ -1010,4 +1016,4 @@
var/client/C = user.client
C.change_view(CONFIG_GET(string/default_view))
user.client.pixel_x = 0
user.client.pixel_y = 0
user.client.pixel_y = 0
@@ -91,6 +91,7 @@
new /obj/item/tank/internals/emergency_oxygen/engi(src)
new /obj/item/analyzer(src)
new /obj/item/holosign_creator/atmos(src)
new /obj/item/holosign_creator/firelock(src)
new /obj/item/watertank/atmos(src)
new /obj/item/clothing/suit/fire/atmos(src)
new /obj/item/clothing/head/hardhat/atmos(src)
@@ -619,6 +619,24 @@
skip_reentry_check = TRUE
banType = "ghostcafe"
/datum/action/toggle_dead_chat_mob
icon_icon = 'icons/mob/mob.dmi'
button_icon_state = "ghost"
name = "Toggle deadchat"
desc = "Turn off or on your ability to hear ghosts."
/datum/action/toggle_dead_chat_mob/Trigger()
if(!..())
return 0
var/mob/M = target
if(HAS_TRAIT_FROM(M,TRAIT_SIXTHSENSE,GHOSTROLE_TRAIT))
REMOVE_TRAIT(M,TRAIT_SIXTHSENSE,GHOSTROLE_TRAIT)
to_chat(M,"<span class='notice'>You're no longer hearing deadchat.</span>")
else
ADD_TRAIT(M,TRAIT_SIXTHSENSE,GHOSTROLE_TRAIT)
to_chat(M,"<span class='notice'>You're once again longer hearing deadchat.</span>")
/obj/effect/mob_spawn/human/ghostcafe/special(mob/living/carbon/human/new_spawn)
if(new_spawn.client)
new_spawn.client.prefs.copy_to(new_spawn)
@@ -629,10 +647,13 @@
new_spawn.AddElement(/datum/element/ghost_role_eligibility)
ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT)
ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT)
to_chat(new_spawn,"<span class='boldwarning'>You maybe sharing your cafe with some ninja-captured individuals, so make sure to only interact with the ghosts you hear as a ghost!</span>")
ADD_TRAIT(new_spawn,TRAIT_PACIFISM,GHOSTROLE_TRAIT)
to_chat(new_spawn,"<span class='boldwarning'>You may be sharing your cafe with some ninja-captured individuals, so make sure to only interact with the ghosts you hear as a ghost!</span>")
to_chat(new_spawn,"<span class='boldwarning'>You can turn yourself into a ghost and freely reenter your body with the ghost action.</span>")
var/datum/action/ghost/G = new(new_spawn)
G.Grant(new_spawn)
var/datum/action/toggle_dead_chat_mob/D = new(new_spawn)
D.Grant(new_spawn)
/datum/outfit/ghostcafe
name = "ID, jumpsuit and shoes"
+15 -3
View File
@@ -69,9 +69,9 @@
rad_insulation = RAD_LIGHT_INSULATION
/obj/structure/holosign/barrier/atmos
name = "holo firelock"
desc = "A holographic barrier resembling a firelock. Though it does not prevent solid objects from passing through, gas is kept out."
icon_state = "holo_firelock"
name = "holo fan"
desc = "A holographic barrier resembling a tiny fan. Though it does not prevent solid objects from passing through, gas is kept out. Somehow."
icon_state = "holo_fan"
density = FALSE
anchored = TRUE
CanAtmosPass = ATMOS_PASS_NO
@@ -81,6 +81,18 @@
. = ..()
air_update_turf(TRUE)
/obj/structure/holosign/barrier/firelock
name = "holo firelock"
desc = "A holographic barrier resembling a firelock. Though it does not prevent solid objects or gas from passing through, temperature changes are kept out."
icon_state = "holo_firelock"
density = FALSE
anchored = TRUE
alpha = 150
resistance_flags = FIRE_PROOF
/obj/structure/holosign/barrier/firelock/blocksTemperature()
return TRUE
/obj/structure/holosign/barrier/cyborg
name = "Energy Field"
desc = "A fragile energy field that blocks movement. Excels at blocking lethal projectiles."
+1 -1
View File
@@ -184,7 +184,7 @@
/obj/structure/table/alt_attack_hand(mob/user)
if(user && Adjacent(user) && !user.incapacitated())
user.setClickCooldown(CLICK_CD_MELEE)
user.setClickCooldown(4)
if(istype(user) && user.a_intent == INTENT_HARM)
user.visible_message("<span class='warning'>[user] slams [user.p_their()] palms down on [src].</span>", "<span class='warning'>You slam your palms down on [src].</span>")
playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 50, 1)