diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 4d32691a921..2c294e70237 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -215,6 +215,8 @@ #define iscrowbar(I) (istype(I, /obj/item/tool/crowbar)) +#define isplasmacutter(I) (istype(I, /obj/item/tool/pickaxe/plasmacutter)) + #define iscell(I) (istype(I, /obj/item/cell)) #define islascell(I) (istype(I, /obj/item/cell/lasgun)) diff --git a/code/__DEFINES/tools.dm b/code/__DEFINES/tools.dm index 2df7165a98b..0209e174b84 100644 --- a/code/__DEFINES/tools.dm +++ b/code/__DEFINES/tools.dm @@ -5,7 +5,7 @@ #define TOOL_WIRECUTTER "wirecutter" #define TOOL_WRENCH "wrench" #define TOOL_WELDER "welder" -#define TOOL_WELD_CUTTER "weld_cutter" +#define TOOL_PLASMACUTTER "plasmacutter" #define TOOL_ANALYZER "analyzer" #define TOOL_MINING "mining" #define TOOL_SHOVEL "shovel" diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 40f2f1b11d9..c29f9112961 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -33,8 +33,8 @@ return target.wirecutter_act(user, src) if(TOOL_WELDER) return target.welder_act(user, src) - if(TOOL_WELD_CUTTER) - return target.weld_cut_act(user, src) + if(TOOL_PLASMACUTTER) + return target.plasmacutter_act(user, src) if(TOOL_ANALYZER) return target.analyzer_act(user, src) if(TOOL_FULTON) @@ -336,7 +336,7 @@ return FALSE if(!force) - return FALSE + return FALSE if(!M) return FALSE diff --git a/code/game/atoms/_atom.dm b/code/game/atoms/_atom.dm index efe3c85dd04..e25cf1a6140 100644 --- a/code/game/atoms/_atom.dm +++ b/code/game/atoms/_atom.dm @@ -718,7 +718,7 @@ directive is properly returned. /atom/proc/welder_act(mob/living/user, obj/item/I) return FALSE -/atom/proc/weld_cut_act(mob/living/user, obj/item/I) +/atom/proc/plasmacutter_act(mob/living/user, obj/item/tool/pickaxe/plasmacutter/I) return FALSE /atom/proc/analyzer_act(mob/living/user, obj/item/I) diff --git a/code/game/objects/effects/weeds.dm b/code/game/objects/effects/weeds.dm index f544d0a4e9a..04a90400900 100644 --- a/code/game/objects/effects/weeds.dm +++ b/code/game/objects/effects/weeds.dm @@ -32,6 +32,9 @@ SSblackbox.record_feedback(FEEDBACK_TALLY, "round_statistics", 1, "weeds_destroyed") return ..() +/obj/alien/weeds/plasmacutter_act(mob/living/user, obj/item/tool/pickaxe/plasmacutter/I) + return FALSE // Just attack normally. + /obj/alien/weeds/Initialize(mapload, obj/alien/weeds/node/node, swapped = FALSE) . = ..() var/static/list/connections = list( diff --git a/code/game/objects/items/tools/mining_tools.dm b/code/game/objects/items/tools/mining_tools.dm index 93fcd7cf9ae..fae0f13f10d 100644 --- a/code/game/objects/items/tools/mining_tools.dm +++ b/code/game/objects/items/tools/mining_tools.dm @@ -88,11 +88,11 @@ light_range = 2 light_power = 0.6 light_color = LIGHT_COLOR_PURPLE + tool_behaviour = TOOL_PLASMACUTTER var/cutting_sound = 'sound/items/welder2.ogg' var/powered = FALSE var/dirt_amt_per_dig = 5 var/obj/item/cell/rtg/large/cell //The plasma cutter cell is unremovable and recharges over time - tool_behaviour = TOOL_WELD_CUTTER /obj/item/tool/pickaxe/plasmacutter/Initialize(mapload) . = ..() @@ -282,20 +282,3 @@ ST.update_appearance() ST.update_sides() cut_apart(user, target.name, target, 0, "You melt the snow with [src]. ") //costs nothing - - - -/obj/item/tool/pickaxe/plasmacutter/attack_obj(obj/O, mob/living/user) - if(!powered || user.do_actions || CHECK_BITFIELD(O.resistance_flags, INDESTRUCTIBLE) || CHECK_BITFIELD(O.resistance_flags, PLASMACUTTER_IMMUNE)) - ..() - return TRUE - - if(!start_cut(user, O.name, O)) - return TRUE - - if(!do_after(user, calc_delay(user), NONE, O, BUSY_ICON_HOSTILE)) - return TRUE - - cut_apart(user, O.name, O) - O.deconstruct(TRUE) - return TRUE diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index b8fa0441f96..9625cf5efa9 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -301,3 +301,21 @@ playsound(loc, 'sound/items/welder2.ogg', 25, TRUE) handle_weldingtool_overlay(TRUE) return TRUE + +/obj/plasmacutter_act(mob/living/user, obj/item/tool/pickaxe/plasmacutter/I) + if(user.do_actions) + return FALSE + if(!(obj_flags & CAN_BE_HIT) || CHECK_BITFIELD(resistance_flags, PLASMACUTTER_IMMUNE) || CHECK_BITFIELD(resistance_flags, INDESTRUCTIBLE)) + return FALSE + if(!I.powered || (I.flags_item & NOBLUDGEON)) + return FALSE + if(user.a_intent == INTENT_HARM) // Attack normally. + return FALSE + if(!I.start_cut(user, name, src)) + return FALSE + if(!do_after(user, I.calc_delay(user), NONE, src, BUSY_ICON_HOSTILE)) + return TRUE + + I.cut_apart(user, name, src) + deconstruct(FALSE) + return TRUE diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index f6f0a4af0b4..1f94e29ee30 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -83,24 +83,26 @@ else icon_state = "[base_icon_state][smoothing_flags ? "-[smoothing_junction]" : ""]" -/obj/structure/mineral_door/attackby(obj/item/W, mob/living/user) +/obj/structure/mineral_door/attackby(obj/item/attacking_item, mob/living/user) . = ..() if(QDELETED(src)) return - var/multiplier = 1 - if(istype(W, /obj/item/tool/pickaxe/plasmacutter) && !user.do_actions) - var/obj/item/tool/pickaxe/plasmacutter/P = W - if(P.start_cut(user, src.name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD)) - if(istype(src, /obj/structure/mineral_door/resin)) - multiplier += PLASMACUTTER_RESIN_MULTIPLIER //Plasma cutters are particularly good at destroying resin structures. - else - multiplier += PLASMACUTTER_RESIN_MULTIPLIER * 0.5 - P.cut_apart(user, src.name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD) //Minimal energy cost. - if(W.damtype == BURN && istype(src, /obj/structure/mineral_door/resin)) //Burn damage deals extra vs resin structures (mostly welders). - multiplier += 1 //generally means we do double damage to resin doors + if(user.a_intent == INTENT_HARM) + return + + if(!(obj_flags & CAN_BE_HIT)) + return + + return attacking_item.attack_obj(src, user) - take_damage(max(0, W.force * multiplier - W.force), W.damtype, MELEE) +/obj/structure/mineral_door/attacked_by(obj/item/attacking_item, mob/living/user, def_zone) + . = ..() + if(attacking_item.damtype != BURN) + return + var/damage_multiplier = get_burn_damage_multiplier(attacking_item, user, def_zone) + + take_damage(max(0, attacking_item.force * damage_multiplier), attacking_item.damtype, MELEE) /obj/structure/mineral_door/Destroy() if(material_type) @@ -108,6 +110,47 @@ new material_type(get_turf(src)) return ..() +///Takes extra damage if our attacking item does burn damage +/obj/structure/mineral_door/proc/get_burn_damage_multiplier(obj/item/attacking_item, mob/living/user, def_zone, bonus_damage = 0) + if(!isplasmacutter(attacking_item)) + return bonus_damage + + var/obj/item/tool/pickaxe/plasmacutter/attacking_pc = attacking_item + if(attacking_pc.start_cut(user, name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD, no_string = TRUE)) + bonus_damage += PLASMACUTTER_RESIN_MULTIPLIER * 0.5 + attacking_pc.cut_apart(user, name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD) //Minimal energy cost. + + return bonus_damage + +/obj/structure/mineral_door/resin/get_burn_damage_multiplier(obj/item/attacking_item, mob/living/user, def_zone, bonus_damage = 1) + if(!isplasmacutter(attacking_item)) + return bonus_damage + + var/obj/item/tool/pickaxe/plasmacutter/attacking_pc = attacking_item + if(attacking_pc.start_cut(user, name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD, no_string = TRUE)) + bonus_damage += PLASMACUTTER_RESIN_MULTIPLIER + attacking_pc.cut_apart(user, name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD) //Minimal energy cost. + + return bonus_damage + +/obj/structure/mineral_door/resin/plasmacutter_act(mob/living/user, obj/item/tool/pickaxe/plasmacutter/I) + if(user.do_actions) + return FALSE + if(!(obj_flags & CAN_BE_HIT) || CHECK_BITFIELD(resistance_flags, PLASMACUTTER_IMMUNE) || CHECK_BITFIELD(resistance_flags, INDESTRUCTIBLE)) + return FALSE + if(!I.powered || (I.flags_item & NOBLUDGEON)) + return FALSE + var/charge_cost = PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD + if(!I.start_cut(user, name, src, charge_cost, no_string = TRUE)) + return FALSE + + user.changeNext_move(I.attack_speed) + user.do_attack_animation(src, used_item = I) + I.cut_apart(user, name, src, charge_cost) + take_damage(max(0, I.force * (1 + PLASMACUTTER_RESIN_MULTIPLIER)), I.damtype, MELEE) + playsound(src, SFX_ALIEN_RESIN_BREAK, 25) + return TRUE + /obj/structure/mineral_door/get_explosion_resistance() if(CHECK_BITFIELD(resistance_flags, INDESTRUCTIBLE)) return EXPLOSION_MAX_POWER diff --git a/code/game/turfs/closed.dm b/code/game/turfs/closed.dm index 2d024cdf21f..49a24bd7bc4 100644 --- a/code/game/turfs/closed.dm +++ b/code/game/turfs/closed.dm @@ -71,6 +71,24 @@ "The stone. The rock. The boulder. Its name matters not when we consume it.", "Delicious, delectable, simply exquisite. Just a few more minerals and it'd be perfect...")), null, 5) +/turf/closed/plasmacutter_act(mob/living/user, obj/item/tool/pickaxe/plasmacutter/I) + if(user.do_actions) + return FALSE + if(CHECK_BITFIELD(resistance_flags, PLASMACUTTER_IMMUNE) || CHECK_BITFIELD(resistance_flags, INDESTRUCTIBLE)) + to_chat(user, span_warning("[I] can't cut through this!")) + return FALSE + if(!I.powered || (I.flags_item & NOBLUDGEON)) + return FALSE + if(!I.start_cut(user, name, src)) + return FALSE + if(!do_after(user, PLASMACUTTER_CUT_DELAY, NONE, src, BUSY_ICON_FRIENDLY)) + return FALSE + + I.cut_apart(user, name, src) + // Change targetted turf to a new one to simulate deconstruction. + ChangeTurf(open_turf_type) + return TRUE + /turf/closed/mineral/smooth name = "rock" icon = 'icons/turf/walls/lvwall.dmi' @@ -292,24 +310,6 @@ /turf/closed/glass/thin/intersection icon_state = "Intersection" -/turf/closed/attackby(obj/item/I, mob/user, params) - . = ..() - - if(istype(I, /obj/item/tool/pickaxe/plasmacutter) && !user.do_actions) - var/obj/item/tool/pickaxe/plasmacutter/P = I - if(CHECK_BITFIELD(resistance_flags, PLASMACUTTER_IMMUNE)) - to_chat(user, span_warning("[P] can't cut through this!")) - return - else if(!P.start_cut(user, name, src)) - return - else if(!do_after(user, PLASMACUTTER_CUT_DELAY, NONE, src, BUSY_ICON_FRIENDLY)) - return - else - P.cut_apart(user, name, src) //purely a cosmetic effect - - //change targetted turf to a new one to simulate deconstruction - ChangeTurf(open_turf_type) - //Ice Thin Wall /turf/closed/ice/thin name = "thin ice wall" diff --git a/code/game/turfs/walls/resin.dm b/code/game/turfs/walls/resin.dm index 70d7edaea04..25ebd33a938 100644 --- a/code/game/turfs/walls/resin.dm +++ b/code/game/turfs/walls/resin.dm @@ -27,6 +27,23 @@ ChangeTurf(/turf/closed/wall/resin/thick) return TRUE +/turf/closed/wall/resin/plasmacutter_act(mob/living/user, obj/item/tool/pickaxe/plasmacutter/I) + if(user.do_actions) + return FALSE + if(CHECK_BITFIELD(resistance_flags, PLASMACUTTER_IMMUNE) || CHECK_BITFIELD(resistance_flags, INDESTRUCTIBLE)) + return FALSE + if(!I.powered || (I.flags_item & NOBLUDGEON)) + return FALSE + var/charge_cost = PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD + if(!I.start_cut(user, name, src, charge_cost, no_string = TRUE)) + return FALSE + user.changeNext_move(I.attack_speed) + user.do_attack_animation(src, used_item = I) + I.cut_apart(user, name, src, charge_cost) + take_damage(max(0, I.force * (2 + PLASMACUTTER_RESIN_MULTIPLIER)), I.damtype, MELEE) + playsound(src, SFX_ALIEN_RESIN_BREAK, 25) + return TRUE + /turf/closed/wall/resin/thick name = "thick resin wall" desc = "Weird slime solidified into a thick wall." @@ -101,14 +118,8 @@ if(I.damtype == BURN) //Burn damage deals extra vs resin structures (mostly welders). multiplier += 1 - if(istype(I, /obj/item/tool/pickaxe/plasmacutter) && !user.do_actions) - var/obj/item/tool/pickaxe/plasmacutter/P = I - if(P.start_cut(user, name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD)) - multiplier += PLASMACUTTER_RESIN_MULTIPLIER - P.cut_apart(user, name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD) - damage *= max(0, multiplier) - take_damage(damage, BRUTE, MELEE) + take_damage(damage, I.damtype, MELEE) playsound(src, SFX_ALIEN_RESIN_BREAK, 25) /turf/closed/wall/resin/dismantle_wall() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index a03641e2aa1..34b5be0bac7 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -58,20 +58,18 @@ else // pump_direction == SIPHONING icon_state = "[base_icon_state]_in" -/obj/machinery/atmospherics/components/unary/vent_pump/weld_cut_act(mob/living/user, obj/item/W) - if(istype(W, /obj/item/tool/pickaxe/plasmacutter)) - var/obj/item/tool/pickaxe/plasmacutter/P = W - if(!welded) - to_chat(user, span_warning("\The [P] can only cut open welds!")) - return FALSE - if(!(P.start_cut(user, src.name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD))) - return FALSE - if(do_after(user, P.calc_delay(user) * PLASMACUTTER_VLOW_MOD, NONE, src, BUSY_ICON_BUILD)) - P.cut_apart(user, src.name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD) //Vents require much less charge - welded = FALSE - update_icon() - return TRUE - return FALSE +/obj/machinery/atmospherics/components/unary/vent_pump/plasmacutter_act(mob/living/user, obj/item/tool/pickaxe/plasmacutter/I) + if(!welded) + to_chat(user, span_warning("\The [I] can only cut open welds!")) + return FALSE + if(!(I.start_cut(user, src.name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD))) + return FALSE + if(!do_after(user, I.calc_delay(user) * PLASMACUTTER_VLOW_MOD, NONE, src, BUSY_ICON_BUILD)) + return FALSE + I.cut_apart(user, src.name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD) //Vents require much less charge + welded = FALSE + update_icon() + return TRUE /obj/machinery/atmospherics/components/unary/vent_pump/welder_act(mob/living/user, obj/item/I) if(iswelder(I)) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index b872831b846..dd6c9ee33d0 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -64,21 +64,18 @@ ..() update_icon_nopipes() -/obj/machinery/atmospherics/components/unary/vent_scrubber/weld_cut_act(mob/living/user, obj/item/W) - if(istype(W, /obj/item/tool/pickaxe/plasmacutter)) - var/obj/item/tool/pickaxe/plasmacutter/P = W - - if(!welded) - to_chat(user, span_warning("\The [P] can only cut open welds!")) - return FALSE - if(!(P.start_cut(user, src.name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD))) - return FALSE - if(do_after(user, P.calc_delay(user) * PLASMACUTTER_VLOW_MOD, NONE, src, BUSY_ICON_BUILD)) - P.cut_apart(user, src.name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD) //Vents require much less charge - welded = FALSE - update_icon() - return TRUE - return FALSE +/obj/machinery/atmospherics/components/unary/vent_scrubber/plasmacutter_act(mob/living/user, obj/item/tool/pickaxe/plasmacutter/I) + if(!welded) + to_chat(user, span_warning("\The [I] can only cut open welds!")) + return FALSE + if(!(I.start_cut(user, src.name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD))) + return FALSE + if(!do_after(user, I.calc_delay(user) * PLASMACUTTER_VLOW_MOD, NONE, src, BUSY_ICON_BUILD)) + return FALSE + I.cut_apart(user, src.name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD) //Vents require much less charge + welded = FALSE + update_icon() + return TRUE /obj/machinery/atmospherics/components/unary/vent_scrubber/welder_act(mob/living/user, obj/item/W) if(iswelder(W)) diff --git a/code/modules/xenomorph/_xeno_structure.dm b/code/modules/xenomorph/_xeno_structure.dm index e7966558f84..bfe2e5f9985 100644 --- a/code/modules/xenomorph/_xeno_structure.dm +++ b/code/modules/xenomorph/_xeno_structure.dm @@ -63,3 +63,20 @@ balloon_alert_to_viewers("\The [xeno_attacker] tears down \the [src]!", "We tear down \the [src].") playsound(src, SFX_ALIEN_RESIN_BREAK, 25) take_damage(max_integrity) // Ensure its destroyed + +/obj/structure/xeno/plasmacutter_act(mob/living/user, obj/item/tool/pickaxe/plasmacutter/I) + if(user.do_actions) + return FALSE + if(!(obj_flags & CAN_BE_HIT) || CHECK_BITFIELD(resistance_flags, PLASMACUTTER_IMMUNE) || CHECK_BITFIELD(resistance_flags, INDESTRUCTIBLE)) + return FALSE + if(!I.powered || (I.flags_item & NOBLUDGEON)) + return FALSE + var/charge_cost = PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD + if(!I.start_cut(user, name, src, charge_cost, no_string = TRUE)) + return FALSE + user.changeNext_move(I.attack_speed) + user.do_attack_animation(src, used_item = I) + I.cut_apart(user, name, src, charge_cost) + take_damage(max(0, I.force * (1 + PLASMACUTTER_RESIN_MULTIPLIER)), I.damtype, MELEE) + playsound(src, SFX_ALIEN_RESIN_BREAK, 25) + return TRUE diff --git a/code/modules/xenomorph/silo.dm b/code/modules/xenomorph/silo.dm index 8e173895433..0465dcc2268 100644 --- a/code/modules/xenomorph/silo.dm +++ b/code/modules/xenomorph/silo.dm @@ -6,7 +6,7 @@ bound_width = 96 bound_height = 96 max_integrity = 1000 - resistance_flags = UNACIDABLE | DROPSHIP_IMMUNE | PLASMACUTTER_IMMUNE + resistance_flags = UNACIDABLE | DROPSHIP_IMMUNE xeno_structure_flags = IGNORE_WEED_REMOVAL|CRITICAL_STRUCTURE plane = FLOOR_PLANE ///How many larva points one silo produce in one minute diff --git a/code/modules/xenomorph/turret.dm b/code/modules/xenomorph/turret.dm index 53c2496b380..ea7054d8bcf 100644 --- a/code/modules/xenomorph/turret.dm +++ b/code/modules/xenomorph/turret.dm @@ -124,7 +124,7 @@ P.cut_apart(user, name, src, PLASMACUTTER_BASE_COST * PLASMACUTTER_VLOW_MOD) damage *= max(0, multiplier) - take_damage(damage, BRUTE, MELEE) + take_damage(damage, I.damtype, MELEE) playsound(src, SFX_ALIEN_RESIN_BREAK, 25) ///Signal handler for hard del of hostile