Mechs can be repaired from destruction, capacitor no longer protects from EMP (#15121)

* capacitor mech repair rework

* typo

* better visibility

* attach the equipment bozo
This commit is contained in:
ynot01
2022-08-14 12:20:40 -04:00
committed by GitHub
parent 38134cdc7d
commit a5e6aed15d
8 changed files with 129 additions and 178 deletions

View File

@@ -31,6 +31,12 @@
#define RWINDOW_BOLTS_HEATED 7
#define RWINDOW_SECURE 8
//mecha wreckage repair states
#define MECHA_WRECK_CUT 0
#define MECHA_WRECK_DENTED 1
#define MECHA_WRECK_LOOSE 2
#define MECHA_WRECK_UNWIRED 3
//airlock assembly construction states
#define AIRLOCK_ASSEMBLY_NEEDS_WIRES 0
#define AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS 1

View File

@@ -235,10 +235,6 @@
else
normal_step_energy_drain = 500
step_energy_drain = normal_step_energy_drain
if(capacitor)
armor = armor.modifyRating(energy = (capacitor.rating * 5)) //Each level of capacitor protects the mech against emp by 5%
else //because we can still be hit without a cap, even if we can't move
armor = armor.setRating(energy = 0)
////////////////////////

View File

@@ -374,17 +374,27 @@
AI = occupant
occupant = null
var/obj/structure/mecha_wreckage/WR = new wreckage(loc, AI)
if(capacitor)
WR.repair_efficiency = capacitor.rating // Capacitor is destroyed regardless of rating
for(var/obj/item/mecha_parts/mecha_equipment/E in equipment)
if(E.salvageable && prob(30))
WR.crowbar_salvage += E
if(E.salvageable && prob(20*WR.repair_efficiency))
E.detach(WR) //detaches from src into WR
E.equip_ready = 1
WR.equipment += E
else
E.detach(loc)
qdel(E)
if(cell)
WR.crowbar_salvage += cell
if(scanmod && WR.repair_efficiency > 2) // Scanning module is retained if capacitor is T3+
WR.scanmod = scanmod
scanmod.forceMove(WR)
scanmod = null
if(cell && WR.repair_efficiency > 3) // Cell is retained if capacitor is T4
WR.cell = cell
cell.forceMove(WR)
cell.charge = rand(0, cell.charge)
cell = null
if(WR.repair_efficiency <= 0)
WR.can_be_reconstructed = FALSE
else
WR.hint = span_notice("The parts are scattered apart, but can be <b>welded</b> back together.")
. = ..()

View File

@@ -5,19 +5,41 @@
/obj/structure/mecha_wreckage
name = "exosuit wreckage"
desc = "Remains of some unfortunate mecha. Completely irreparable, but perhaps something can be salvaged."
desc = "Remains of some unfortunate mecha. Repairable, given some work."
icon = 'icons/mecha/mecha.dmi'
density = TRUE
anchored = FALSE
opacity = 0
var/list/welder_salvage = list(/obj/item/stack/sheet/plasteel, /obj/item/stack/sheet/metal, /obj/item/stack/rods)
var/list/wirecutters_salvage = list(/obj/item/stack/cable_coil)
var/list/crowbar_salvage = list()
var/salvage_num = 5
var/state = MECHA_WRECK_CUT
var/orig_mecha
var/can_be_reconstructed = TRUE
var/hint // Examine hint
var/list/equipment = list() // Equipment that the mech retains
// Total repair will take 80/40/27/20 seconds depending on capacitor tier. Roboticists repair 20% faster, so 64/32/21/16 seconds instead.
var/repair_efficiency = 0 // Capacitor tier
var/obj/item/stock_parts/cell/cell ///Keeps track of the mech's cell
var/obj/item/stock_parts/scanning_module/scanmod ///Keeps track of the mech's scanning module
var/mob/living/silicon/ai/AI //AIs to be salvaged
/obj/structure/mecha_wreckage/examine(mob/user)
. = ..()
switch(repair_efficiency)
if(0)
. += span_danger("There was no capacitor to save this poor mecha from its doomed fate!")
if(1)
. += span_danger("The weak capacitor did what little it could in preventing total destruction of this mecha. It is barely recoverable.")
if(2)
. += span_danger("The capacitor barely held the parts together upon its destruction. Repair will be difficult.")
if(3)
. += span_danger("The capacitor did well in preventing too much damage. Repair will be manageable.")
if(4)
. += span_danger("The capacitor did such a good job in preserving the chassis that you could almost call it functional. But it isn't. Repair should be easy though.")
if(hint)
. += hint
/obj/structure/mecha_wreckage/Initialize(mapload, mob/living/silicon/ai/AI_pilot)
. = ..()
if(!AI_pilot) //Type-checking for this is already done in mecha/Destroy()
return
@@ -35,49 +57,69 @@
. += span_notice("The AI recovery beacon is active.")
/obj/structure/mecha_wreckage/attackby(obj/item/I, mob/user, params)
if(I.tool_behaviour == TOOL_WELDER)
if(salvage_num <= 0 || !length(welder_salvage))
to_chat(user, span_warning("You don't see anything that can be cut with [I]!"))
if(!can_be_reconstructed)
return ..()
switch(state)
if(MECHA_WRECK_CUT)
if(I.tool_behaviour == TOOL_WELDER && user.a_intent == INTENT_HELP)
user.visible_message(span_notice("[user] begins to weld together \the [src]'s broken parts..."),
span_notice("You begin welding together \the [src]'s broken parts..."))
if(I.use_tool(src, user, 200/repair_efficiency, amount = 5, volume = 100, robo_check = TRUE))
state = MECHA_WRECK_DENTED
hint = span_notice("The chassis has suffered major damage and will require the dents to be smoothed out with a <b>welder</b>.")
to_chat(user, span_notice("The parts are loosely reattached, but are dented wildly out of place."))
return
if(MECHA_WRECK_DENTED)
if(I.tool_behaviour == TOOL_WELDER && user.a_intent == INTENT_HELP)
user.visible_message(span_notice("[user] welds out the many, many dents in \the [src]'s chassis..."),
span_notice("You weld out the many, many dents in \the [src]'s chassis..."))
if(I.use_tool(src, user, 200/repair_efficiency, amount = 5, volume = 100, robo_check = TRUE))
state = MECHA_WRECK_LOOSE
hint = span_notice("The mecha wouldn't make it two steps before falling apart. The bolts must be tightened with a <b>wrench</b>.")
to_chat(user, span_notice("The chassis has been repaired, but the bolts are incredibly loose and need to be tightened."))
return
if(MECHA_WRECK_LOOSE)
if(I.tool_behaviour == TOOL_WRENCH)
user.visible_message(span_notice("[user] slowly tightens the bolts of \the [src]..."),
span_notice("You slowly tighten the bolts of \the [src]..."))
if(I.use_tool(src, user, 180/repair_efficiency, volume = 50, robo_check = TRUE))
state = MECHA_WRECK_UNWIRED
hint = span_notice("The mech is nearly ready, but the <b>wiring</b> has been fried and needs repair.")
to_chat(user, span_notice("The bolts are tightened and the mecha is looking as good as new, but the wiring was fried in the destruction and needs repair."))
return
if(MECHA_WRECK_UNWIRED)
if(istype(I, /obj/item/stack/cable_coil) && I.tool_start_check(user, amount=5))
user.visible_message(span_notice("[user] starts repairing the wiring on \the [src]..."),
span_notice("You start repairing the wiring on \the [src]..."))
if(I.use_tool(src, user, 120/repair_efficiency, amount = 5, volume = 50, robo_check = TRUE))
create_mech()
to_chat(user, span_notice("The mecha has been fully repaired."))
return
return ..()
/obj/structure/mecha_wreckage/proc/create_mech()
if(!orig_mecha)
return
if(!I.use_tool(src, user, 0, volume=50))
return
var/obj/mecha/M = new orig_mecha(loc)
QDEL_NULL(M.cell)
QDEL_NULL(M.scanmod)
QDEL_NULL(M.capacitor)
var/type = prob(70) ? pick(welder_salvage) : null
if(type)
var/N = new type(get_turf(user))
user.visible_message("[user] cuts [N] from [src].", span_notice("You cut [N] from [src]."))
if(istype(N, /obj/item/mecha_parts/part))
welder_salvage -= type
salvage_num--
else
to_chat(user, span_warning("You fail to salvage anything valuable from [src]!"))
return
if(cell)
cell.forceMove(M)
if(scanmod)
scanmod.forceMove(M)
else if(I.tool_behaviour == TOOL_WIRECUTTER)
if(salvage_num <= 0)
to_chat(user, span_warning("You don't see anything that can be cut with [I]!"))
return
else if(wirecutters_salvage && wirecutters_salvage.len)
var/type = prob(70) ? pick(wirecutters_salvage) : null
if(type)
var/N = new type(get_turf(user))
user.visible_message("[user] cuts [N] from [src].", span_notice("You cut [N] from [src]."))
wirecutters_salvage -= type
salvage_num--
else
to_chat(user, span_warning("You fail to salvage anything valuable from [src]!"))
for(var/obj/item/mecha_parts/mecha_equipment/E in equipment)
E.attach(M)
else if(I.tool_behaviour == TOOL_CROWBAR)
if(crowbar_salvage && crowbar_salvage.len)
var/obj/S = pick(crowbar_salvage)
if(S)
S.forceMove(user.drop_location())
crowbar_salvage -= S
user.visible_message("[user] pries [S] from [src].", span_notice("You pry [S] from [src]."))
return
else
to_chat(user, span_warning("You don't see anything that can be pried with [I]!"))
M.CheckParts(M.contents)
qdel(src)
QDEL_NULL(scanmod)
QDEL_NULL(cell)
/obj/structure/mecha_wreckage/transfer_ai(interaction, mob/user, mob/living/silicon/ai/ai_unused, obj/item/aicard/card) //ai_unused is unused but having it is better than having it be null or _ for readability
@@ -105,167 +147,73 @@
/obj/structure/mecha_wreckage/gygax
name = "\improper Gygax wreckage"
icon_state = "gygax-broken"
/obj/structure/mecha_wreckage/gygax/Initialize()
. = ..()
var/list/parts = list(/obj/item/mecha_parts/part/gygax_torso,
/obj/item/mecha_parts/part/gygax_head,
/obj/item/mecha_parts/part/gygax_left_arm,
/obj/item/mecha_parts/part/gygax_right_arm,
/obj/item/mecha_parts/part/gygax_left_leg,
/obj/item/mecha_parts/part/gygax_right_leg)
for(var/i = 0; i < 2; i++)
if(parts.len && prob(40))
var/part = pick(parts)
welder_salvage += part
parts -= part
orig_mecha = /obj/mecha/combat/gygax
/obj/structure/mecha_wreckage/gygax/dark
name = "\improper Dark Gygax wreckage"
icon_state = "darkgygax-broken"
orig_mecha = /obj/mecha/combat/gygax/dark
/obj/structure/mecha_wreckage/marauder
name = "\improper Marauder wreckage"
icon_state = "marauder-broken"
orig_mecha = /obj/mecha/combat/marauder
/obj/structure/mecha_wreckage/mauler
name = "\improper Mauler wreckage"
icon_state = "mauler-broken"
desc = "The syndicate won't be very happy about this..."
desc = "The Syndicate won't be very happy about this..."
orig_mecha = /obj/mecha/combat/marauder/mauler
/obj/structure/mecha_wreckage/seraph
name = "\improper Seraph wreckage"
icon_state = "seraph-broken"
orig_mecha = /obj/mecha/combat/marauder/seraph
/obj/structure/mecha_wreckage/reticence
name = "\improper Reticence wreckage"
icon_state = "reticence-broken"
color = "#87878715"
desc = "..."
orig_mecha = /obj/mecha/combat/reticence
/obj/structure/mecha_wreckage/ripley
name = "\improper Ripley wreckage"
icon_state = "ripley-broken"
/obj/structure/mecha_wreckage/ripley/Initialize()
. = ..()
var/list/parts = list(/obj/item/mecha_parts/part/ripley_torso,
/obj/item/mecha_parts/part/ripley_left_arm,
/obj/item/mecha_parts/part/ripley_right_arm,
/obj/item/mecha_parts/part/ripley_left_leg,
/obj/item/mecha_parts/part/ripley_right_leg)
for(var/i = 0; i < 2; i++)
if(parts.len && prob(40))
var/part = pick(parts)
welder_salvage += part
parts -= part
orig_mecha = /obj/mecha/working/ripley
/obj/structure/mecha_wreckage/ripley/mkii
name = "\improper Ripley MK-II wreckage"
icon_state = "ripleymkii-broken"
/obj/structure/mecha_wreckage/ripley/mkii/Initialize()
. = ..()
var/list/parts = list(/obj/item/mecha_parts/part/ripley_torso,
/obj/item/mecha_parts/part/ripley_left_arm,
/obj/item/mecha_parts/part/ripley_right_arm,
/obj/item/mecha_parts/part/ripley_left_leg,
/obj/item/mecha_parts/part/ripley_right_leg)
for(var/i = 0; i < 2; i++)
if(parts.len && prob(40))
var/part = pick(parts)
welder_salvage += part
parts -= part
orig_mecha = /obj/mecha/working/ripley/mkii
/obj/structure/mecha_wreckage/ripley/firefighter
name = "\improper Firefighter wreckage"
icon_state = "firefighter-broken"
/obj/structure/mecha_wreckage/ripley/firefighter/Initialize()
. = ..()
var/list/parts = list(/obj/item/mecha_parts/part/ripley_torso,
/obj/item/mecha_parts/part/ripley_left_arm,
/obj/item/mecha_parts/part/ripley_right_arm,
/obj/item/mecha_parts/part/ripley_left_leg,
/obj/item/mecha_parts/part/ripley_right_leg,
/obj/item/clothing/suit/fire)
for(var/i = 0; i < 2; i++)
if(parts.len && prob(40))
var/part = pick(parts)
welder_salvage += part
parts -= part
orig_mecha = /obj/mecha/working/ripley/firefighter
/obj/structure/mecha_wreckage/ripley/deathripley
name = "\improper Death-Ripley wreckage"
icon_state = "deathripley-broken"
orig_mecha = /obj/mecha/working/ripley/deathripley
/obj/structure/mecha_wreckage/honker
name = "\improper H.O.N.K wreckage"
icon_state = "honker-broken"
desc = "All is right in the universe."
/obj/structure/mecha_wreckage/honker/Initialize()
. = ..()
var/list/parts = list(
/obj/item/mecha_parts/chassis/honker,
/obj/item/mecha_parts/part/honker_torso,
/obj/item/mecha_parts/part/honker_head,
/obj/item/mecha_parts/part/honker_left_arm,
/obj/item/mecha_parts/part/honker_right_arm,
/obj/item/mecha_parts/part/honker_left_leg,
/obj/item/mecha_parts/part/honker_right_leg)
for(var/i = 0; i < 2; i++)
if(parts.len && prob(40))
var/part = pick(parts)
welder_salvage += part
parts -= part
orig_mecha = /obj/mecha/combat/honker
/obj/structure/mecha_wreckage/durand
name = "\improper Durand wreckage"
icon_state = "durand-broken"
/obj/structure/mecha_wreckage/durand/Initialize()
. = ..()
var/list/parts = list(
/obj/item/mecha_parts/part/durand_torso,
/obj/item/mecha_parts/part/durand_head,
/obj/item/mecha_parts/part/durand_left_arm,
/obj/item/mecha_parts/part/durand_right_arm,
/obj/item/mecha_parts/part/durand_left_leg,
/obj/item/mecha_parts/part/durand_right_leg)
for(var/i = 0; i < 2; i++)
if(parts.len && prob(40))
var/part = pick(parts)
welder_salvage += part
parts -= part
orig_mecha = /obj/mecha/combat/durand
/obj/structure/mecha_wreckage/phazon
name = "\improper Phazon wreckage"
icon_state = "phazon-broken"
orig_mecha = /obj/mecha/combat/phazon
/obj/structure/mecha_wreckage/odysseus
name = "\improper Odysseus wreckage"
icon_state = "odysseus-broken"
/obj/structure/mecha_wreckage/odysseus/Initialize()
. = ..()
var/list/parts = list(
/obj/item/mecha_parts/part/odysseus_torso,
/obj/item/mecha_parts/part/odysseus_head,
/obj/item/mecha_parts/part/odysseus_left_arm,
/obj/item/mecha_parts/part/odysseus_right_arm,
/obj/item/mecha_parts/part/odysseus_left_leg,
/obj/item/mecha_parts/part/odysseus_right_leg)
for(var/i = 0; i < 2; i++)
if(parts.len && prob(40))
var/part = pick(parts)
welder_salvage += part
parts -= part
orig_mecha = /obj/mecha/medical/odysseus

View File

@@ -793,14 +793,14 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
// Called when a mob tries to use the item as a tool.
// Handles most checks.
/obj/item/proc/use_tool(atom/target, mob/living/user, delay, amount=0, volume=0, datum/callback/extra_checks)
/obj/item/proc/use_tool(atom/target, mob/living/user, delay, amount=0, volume=0, datum/callback/extra_checks, robo_check)
// No delay means there is no start message, and no reason to call tool_start_check before use_tool.
// Run the start check here so we wouldn't have to call it manually.
if(!delay && !tool_start_check(user, amount))
return
delay *= toolspeed
if(IS_ENGINEERING(user) && tool_behaviour != TOOL_MINING) //if the user is an engineer, they'll use the tool faster. Doesn't apply to mining tools.
if((IS_ENGINEERING(user) || (robo_check && IS_JOB(user, "Roboticist"))) && tool_behaviour != TOOL_MINING) //if the user is an engineer, they'll use the tool faster. Doesn't apply to mining tools.
delay *= 0.8
// Play tool sound at the beginning of tool usage.

View File

@@ -155,7 +155,7 @@
update_icon()
/obj/item/weldingtool/use_tool(atom/target, mob/living/user, delay, amount, volume, datum/callback/extra_checks)
/obj/item/weldingtool/use_tool(atom/target, mob/living/user, delay, amount, volume, datum/callback/extra_checks, robo_check)
target.add_overlay(GLOB.welding_sparks)
. = ..()
target.cut_overlay(GLOB.welding_sparks)

View File

@@ -203,7 +203,7 @@
else
progress_flash_divisor--
/obj/item/gun/energy/plasmacutter/use_tool(atom/target, mob/living/user, delay, amount=1, volume=0, datum/callback/extra_checks)
/obj/item/gun/energy/plasmacutter/use_tool(atom/target, mob/living/user, delay, amount=1, volume=0, datum/callback/extra_checks, robo_check)
if(amount)
target.add_overlay(GLOB.welding_sparks)
. = ..()

View File

@@ -4,14 +4,5 @@
/obj/structure/mecha_wreckage/loaded_ripley
name = "intact Ripley wreckage"
icon_state = "ripley-broken"
salvage_num = 20
/obj/structure/mecha_wreckage/loaded_ripley/Initialize()
. = ..()
welder_salvage = list(/obj/item/mecha_parts/part/ripley_torso,
/obj/item/mecha_parts/part/ripley_left_arm,
/obj/item/mecha_parts/part/ripley_right_arm,
/obj/item/mecha_parts/part/ripley_left_leg,
/obj/item/mecha_parts/part/ripley_right_leg)
crowbar_salvage = list(new /obj/item/circuitboard/mecha/ripley/peripherals(),
new /obj/item/circuitboard/mecha/ripley/main())
repair_efficiency = 4
orig_mecha = /obj/mecha/working/ripley