Files
GS13NG/code/modules/vehicles/mecha/equipment/tools/work_tools.dm
T
2024-01-05 00:28:56 -03:00

411 lines
16 KiB
Plaintext

//Hydraulic clamp, Kill clamp, Extinguisher, RCD, Cable layer.
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp
name = "hydraulic clamp"
desc = "Equipment for engineering exosuits. Lifts objects and loads them into cargo."
icon_state = "mecha_clamp"
equip_cooldown = 15
energy_drain = 10
tool_behaviour = TOOL_RETRACTOR
range = MECHA_MELEE
toolspeed = 0.8
var/dam_force = 20
var/obj/vehicle/sealed/mecha/working/ripley/cargo_holder
harmful = TRUE
mech_flags = EXOSUIT_MODULE_RIPLEY
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/can_attach(obj/vehicle/sealed/mecha/working/ripley/M)
if(..())
if(istype(M))
return TRUE
return FALSE
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/attach(obj/vehicle/sealed/mecha/M)
..()
cargo_holder = M
return
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/detach(atom/moveto = null)
..()
cargo_holder = null
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/action(mob/source, atom/target, params)
if(!action_checks(target))
return
if(!cargo_holder)
return
if(ismecha(target))
var/obj/vehicle/sealed/mecha/M = target
var/have_ammo
for(var/obj/item/mecha_ammo/box in cargo_holder.cargo)
if(istype(box, /obj/item/mecha_ammo) && box.rounds)
have_ammo = TRUE
if(M.ammo_resupply(box, source, TRUE))
return
if(have_ammo)
to_chat(source, "No further supplies can be provided to [M].")
else
to_chat(source, "No providable supplies found in cargo hold")
return
if(isobj(target))
var/obj/O = target
if(istype(O, /obj/machinery/door/firedoor))
var/obj/machinery/door/firedoor/D = O
D.try_to_crowbar(src, source)
return
if(istype(O, /obj/machinery/door/airlock/))
var/obj/machinery/door/airlock/D = O
D.try_to_crowbar(src, source)
return
if(!O.anchored)
if(cargo_holder.cargo.len < cargo_holder.cargo_capacity)
chassis.visible_message("<span class='notice'>[chassis] lifts [target] and starts to load it into cargo compartment.</span>")
O.set_anchored(TRUE)
if(do_after_cooldown(target, source))
cargo_holder.cargo += O
O.forceMove(chassis)
O.set_anchored(FALSE)
to_chat(source, "[icon2html(src, source)]<span class='notice'>[target] successfully loaded.</span>")
log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]", LOG_MECHA)
else
O.set_anchored(initial(O.anchored))
else
to_chat(source, "[icon2html(src, source)]<span class='warning'>Not enough room in cargo compartment!</span>")
else
to_chat(source, "[icon2html(src, source)]<span class='warning'>[target] is firmly secured!</span>")
else if(isliving(target))
var/mob/living/M = target
if(M.stat == DEAD)
return
if(source.a_intent == INTENT_HARM)
M.take_overall_damage(dam_force)
if(!M)
return
M.adjustOxyLoss(round(dam_force/2))
M.updatehealth()
target.visible_message("<span class='danger'>[chassis] squeezes [target]!</span>", \
"<span class='userdanger'>[chassis] squeezes you!</span>",\
"<span class='hear'>You hear something crack.</span>")
log_combat(source, M, "attacked", "[name]", "(INTENT: [uppertext(source.a_intent)]) (DAMTYPE: [uppertext(damtype)])")
else
step_away(M,chassis)
to_chat(source, "[icon2html(src, source)]<span class='notice'>You push [target] out of the way.</span>")
chassis.visible_message("<span class='notice'>[chassis] pushes [target] out of the way.</span>")
return ..()
//This is pretty much just for the death-ripley
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill
name = "\improper KILL CLAMP"
desc = "They won't know what clamped them!"
energy_drain = 0
dam_force = 0
var/real_clamp = FALSE
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/real
desc = "They won't know what clamped them! This time for real!"
energy_drain = 10
dam_force = 20
real_clamp = TRUE
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/action(mob/source, atom/target, params)
if(!action_checks(target))
return
if(!cargo_holder)
return
if(isobj(target))
var/obj/O = target
if(!O.anchored)
if(cargo_holder.cargo.len < cargo_holder.cargo_capacity)
chassis.visible_message("<span class='notice'>[chassis] lifts [target] and starts to load it into cargo compartment.</span>")
O.set_anchored(TRUE)
if(do_after_cooldown(target, source))
cargo_holder.cargo += O
O.forceMove(chassis)
O.set_anchored(FALSE)
to_chat(source, "[icon2html(src, source)]<span class='notice'>[target] successfully loaded.</span>")
log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]", LOG_MECHA)
else
O.set_anchored(initial(O.anchored))
else
to_chat(source, "[icon2html(src, source)]<span class='warning'>Not enough room in cargo compartment!</span>")
else
to_chat(source, "[icon2html(src, source)]<span class='warning'>[target] is firmly secured!</span>")
else if(isliving(target))
var/mob/living/M = target
if(M.stat == DEAD)
return
if(source.a_intent == INTENT_HARM)
if(real_clamp)
M.take_overall_damage(dam_force)
if(!M)
return
M.adjustOxyLoss(round(dam_force/2))
M.updatehealth()
target.visible_message("<span class='danger'>[chassis] destroys [target] in an unholy fury!</span>", \
"<span class='userdanger'>[chassis] destroys you in an unholy fury!</span>")
log_combat(source, M, "attacked", "[name]", "(INTENT: [uppertext(source.a_intent)]) (DAMTYPE: [uppertext(damtype)])")
else
target.visible_message("<span class='danger'>[chassis] destroys [target] in an unholy fury!</span>", \
"<span class='userdanger'>[chassis] destroys you in an unholy fury!</span>")
else if(source.a_intent == INTENT_DISARM)
if(real_clamp)
var/mob/living/carbon/C = target
var/play_sound = FALSE
var/limbs_gone = ""
var/obj/item/bodypart/affected = C.get_bodypart(BODY_ZONE_L_ARM)
if(affected != null)
affected.dismember(damtype)
play_sound = TRUE
limbs_gone = ", [affected]"
affected = C.get_bodypart(BODY_ZONE_R_ARM)
if(affected != null)
affected.dismember(damtype)
play_sound = TRUE
limbs_gone = "[limbs_gone], [affected]"
if(play_sound)
playsound(src, get_dismember_sound(), 80, TRUE)
target.visible_message("<span class='danger'>[chassis] rips [target]'s arms off!</span>", \
"<span class='userdanger'>[chassis] rips your arms off!</span>")
log_combat(source, M, "dismembered of[limbs_gone],", "[name]", "(INTENT: [uppertext(source.a_intent)]) (DAMTYPE: [uppertext(damtype)])")
else
target.visible_message("<span class='danger'>[chassis] rips [target]'s arms off!</span>", \
"<span class='userdanger'>[chassis] rips your arms off!</span>")
else
step_away(M,chassis)
target.visible_message("<span class='danger'>[chassis] tosses [target] like a piece of paper!</span>", \
"<span class='userdanger'>[chassis] tosses you like a piece of paper!</span>")
return ..()
/obj/item/mecha_parts/mecha_equipment/extinguisher
name = "exosuit extinguisher"
desc = "Equipment for engineering exosuits. A rapid-firing high capacity fire extinguisher."
icon_state = "mecha_exting"
equip_cooldown = 5
energy_drain = 0
range = MECHA_MELEE|MECHA_RANGED
mech_flags = EXOSUIT_MODULE_WORKING
/obj/item/mecha_parts/mecha_equipment/extinguisher/Initialize(mapload)
. = ..()
create_reagents(1000)
reagents.add_reagent(/datum/reagent/water, 1000)
/obj/item/mecha_parts/mecha_equipment/extinguisher/action(mob/source, atom/target, params) //copypasted from extinguisher. TODO: Rewrite from scratch.//Still todo
if(!action_checks(target) || get_dist(chassis, target)>3)
return
if(istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1)
var/obj/structure/reagent_dispensers/watertank/WT = target
WT.reagents.trans_to(src, 1000)
to_chat(chassis.occupants,"<span class='notice'>Extinguisher refilled.</span>")
playsound(chassis, 'sound/effects/refill.ogg', 50, 1, -6)
else
if(reagents.total_volume > 0)
playsound(chassis, 'sound/effects/extinguish.ogg', 75, 1, -3)
var/direction = get_dir(chassis,target)
var/turf/T = get_turf(target)
var/turf/T1 = get_step(T,turn(direction, 90))
var/turf/T2 = get_step(T,turn(direction, -90))
var/list/the_targets = list(T,T1,T2)
spawn(0)
for(var/a=0, a<5, a++)
var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water(get_turf(chassis))
if(!W)
return
var/turf/my_target = pick(the_targets)
var/datum/reagents/R = new/datum/reagents(5)
W.reagents = R
R.my_atom = W
reagents.trans_to(W,1)
for(var/b=0, b<4, b++)
if(!W)
return
step_towards(W,my_target)
if(!W)
return
var/turf/W_turf = get_turf(W)
W.reagents.reaction(W_turf)
for(var/atom/atm in W_turf)
W.reagents.reaction(atm)
if(W.loc == my_target)
break
sleep(2)
return TRUE
/obj/item/mecha_parts/mecha_equipment/extinguisher/get_equip_info()
return "[..()] \[[src.reagents.total_volume]\]"
/obj/item/mecha_parts/mecha_equipment/extinguisher/can_attach(obj/vehicle/sealed/mecha/working/M as obj)
if(..())
if(istype(M))
return TRUE
return FALSE
/obj/item/mecha_parts/mecha_equipment/rcd
name = "mounted RCD"
desc = "An exosuit-mounted Rapid Construction Device."
icon_state = "mecha_rcd"
equip_cooldown = 10
energy_drain = 250
range = MECHA_MELEE|MECHA_RANGED
item_flags = NO_MAT_REDEMPTION
var/mode = 0 //0 - deconstruct, 1 - wall or floor, 2 - airlock.
/obj/item/mecha_parts/mecha_equipment/rcd/Initialize(mapload)
. = ..()
GLOB.rcd_list += src
/obj/item/mecha_parts/mecha_equipment/rcd/Destroy()
GLOB.rcd_list -= src
return ..()
/obj/item/mecha_parts/mecha_equipment/rcd/action(mob/source, atom/target, params)
if(istype(target, /turf/open/space/transit))//>implying these are ever made -Sieve
return
if(!isturf(target) && !istype(target, /obj/machinery/door/airlock))
target = get_turf(target)
if(!action_checks(target) || get_dist(chassis, target)>3)
return
playsound(chassis, 'sound/machines/click.ogg', 50, TRUE)
switch(mode)
if(0)
if(iswallturf(target))
var/turf/closed/wall/W = target
to_chat(source, "[icon2html(src, source)]<span class='notice'>Deconstructing [W]...</span>")
if(do_after_cooldown(W, source))
chassis.spark_system.start()
W.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
playsound(W, 'sound/items/deconstruct.ogg', 50, TRUE)
else if(isfloorturf(target))
var/turf/open/floor/F = target
to_chat(source, "[icon2html(src, source)]<span class='notice'>Deconstructing [F]...</span>")
if(do_after_cooldown(target, source))
chassis.spark_system.start()
F.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
playsound(F, 'sound/items/deconstruct.ogg', 50, TRUE)
else if (istype(target, /obj/machinery/door/airlock))
to_chat(source, "[icon2html(src, source)]<span class='notice'>Deconstructing [target]...</span>")
if(do_after_cooldown(target, source))
chassis.spark_system.start()
qdel(target)
playsound(target, 'sound/items/deconstruct.ogg', 50, TRUE)
if(1)
if(isspaceturf(target))
var/turf/open/space/S = target
to_chat(source, "[icon2html(src, source)]<span class='notice'>Building Floor...</span>")
if(do_after_cooldown(S, source))
S.PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
playsound(S, 'sound/items/deconstruct.ogg', 50, TRUE)
chassis.spark_system.start()
else if(isfloorturf(target))
var/turf/open/floor/F = target
to_chat(source, "[icon2html(src, source)]<span class='notice'>Building Wall...</span>")
if(do_after_cooldown(F, source))
F.PlaceOnTop(/turf/closed/wall)
playsound(F, 'sound/items/deconstruct.ogg', 50, TRUE)
chassis.spark_system.start()
if(2)
if(isfloorturf(target))
to_chat(source, "[icon2html(src, source)]<span class='notice'>Building Airlock...</span>")
if(do_after_cooldown(target, source))
chassis.spark_system.start()
var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock(target)
T.autoclose = TRUE
playsound(target, 'sound/items/deconstruct.ogg', 50, TRUE)
playsound(target, 'sound/effects/sparks2.ogg', 50, TRUE)
return ..()
/obj/item/mecha_parts/mecha_equipment/rcd/Topic(href,href_list)
..()
if(href_list["mode"])
mode = text2num(href_list["mode"])
switch(mode)
if(0)
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]<span class='notice'>Switched RCD to Deconstruct.</span>")
energy_drain = initial(energy_drain)
if(1)
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]<span class='notice'>Switched RCD to Construct.</span>")
energy_drain = 2*initial(energy_drain)
if(2)
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]<span class='notice'>Switched RCD to Construct Airlock.</span>")
energy_drain = 2*initial(energy_drain)
return
/obj/item/mecha_parts/mecha_equipment/rcd/get_equip_info()
return "[..()] \[<a href='?src=[REF(src)];mode=0'>D</a>|<a href='?src=[REF(src)];mode=1'>C</a>|<a href='?src=[REF(src)];mode=2'>A</a>\]"
//Dunno where else to put this so shrug
/obj/item/mecha_parts/mecha_equipment/ripleyupgrade
name = "Ripley MK-II Conversion Kit"
desc = "A pressurized canopy attachment kit for an Autonomous Power Loader Unit \"Ripley\" MK-I mecha, to convert it to the slower, but space-worthy MK-II design. This kit cannot be removed, once applied."
icon_state = "tesla"
mech_flags = EXOSUIT_MODULE_RIPLEY
/obj/item/mecha_parts/mecha_equipment/ripleyupgrade/can_attach(obj/vehicle/sealed/mecha/working/ripley/M)
if(M.type != /obj/vehicle/sealed/mecha/working/ripley)
to_chat(loc, "<span class='warning'>This conversion kit can only be applied to APLU MK-I models.</span>")
return FALSE
if(M.cargo.len)
to_chat(loc, "<span class='warning'>[M]'s cargo hold must be empty before this conversion kit can be applied.</span>")
return FALSE
if(!(M.mecha_flags & ADDING_MAINT_ACCESS_POSSIBLE)) //non-removable upgrade, so lets make sure the pilot or owner has their say.
to_chat(loc, "<span class='warning'>[M] must have maintenance protocols active in order to allow this conversion kit.</span>")
return FALSE
if(LAZYLEN(M.occupants)) //We're actualy making a new mech and swapping things over, it might get weird if players are involved
to_chat(loc, "<span class='warning'>[M] must be unoccupied before this conversion kit can be applied.</span>")
return FALSE
if(!M.cell) //Turns out things break if the cell is missing
to_chat(loc, "<span class='warning'>The conversion process requires a cell installed.</span>")
return FALSE
return TRUE
/obj/item/mecha_parts/mecha_equipment/ripleyupgrade/attach(obj/vehicle/sealed/mecha/M)
var/obj/vehicle/sealed/mecha/working/ripley/mkii/N = new /obj/vehicle/sealed/mecha/working/ripley/mkii(get_turf(M),1)
if(!N)
return
QDEL_NULL(N.cell)
if (M.cell)
N.cell = M.cell
M.cell.forceMove(N)
M.cell = null
QDEL_NULL(N.scanmod)
if (M.scanmod)
N.scanmod = M.scanmod
M.scanmod.forceMove(N)
M.scanmod = null
QDEL_NULL(N.capacitor)
if (M.capacitor)
N.capacitor = M.capacitor
M.capacitor.forceMove(N)
M.capacitor = null
N.update_part_values()
for(var/obj/item/mecha_parts/E in M.contents)
if(istype(E, /obj/item/mecha_parts/concealed_weapon_bay)) //why is the bay not just a variable change who did this
E.forceMove(N)
for(var/obj/item/mecha_parts/mecha_equipment/E in M.equipment) //Move the equipment over...
E.detach(M)
E.attach(N)
N.dna_lock = M.dna_lock
N.mecha_flags = M.mecha_flags
N.strafe = M.strafe
N.obj_integrity = M.obj_integrity //This is not a repair tool
if (M.name != "\improper APLU MK-I \"Ripley\"")
N.name = M.name
M.wreckage = 0
qdel(M)
playsound(get_turf(N),'sound/items/ratchet.ogg',50,TRUE)
return