diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm
index 2d046b2596a..2e98a96fe66 100644
--- a/code/modules/vehicles/mecha/_mecha.dm
+++ b/code/modules/vehicles/mecha/_mecha.dm
@@ -37,15 +37,15 @@
mouse_pointer = 'icons/effects/mouse_pointers/mecha_mouse.dmi'
/// Significantly heavier than humans
inertia_force_weight = 5
- ///How much energy the mech will consume each time it moves. this is the current active energy consumed
+ /// How much energy the mech will consume each time it moves. this is the current active energy consumed
var/step_energy_drain = 0.008 * STANDARD_CELL_CHARGE
- ///How much energy we drain each time we mechpunch someone
+ /// How much energy we drain each time we mechpunch someone
var/melee_energy_drain = 0.015 * STANDARD_CELL_CHARGE
- ///Power we use to have the lights on
+ /// Power we use to have the lights on
var/light_power_drain = 0.002 * STANDARD_CELL_RATE
- ///Modifiers for directional damage reduction
+ /// Modifiers for directional damage reduction
var/list/facing_modifiers = list(MECHA_FRONT_ARMOUR = 0.5, MECHA_SIDE_ARMOUR = 1, MECHA_BACK_ARMOUR = 1.5)
- ///if we cant use our equipment(such as due to EMP)
+ /// If we cant use our equipment(such as due to EMP)
var/equipment_disabled = FALSE
/// Keeps track of the mech's cell
var/obj/item/stock_parts/power_store/cell
@@ -55,59 +55,59 @@
var/obj/item/stock_parts/capacitor/capacitor
/// Keeps track of the mech's servo motor
var/obj/item/stock_parts/servo/servo
- ///Contains flags for the mecha
+ /// Contains flags for the mecha
var/mecha_flags = CAN_STRAFE | IS_ENCLOSED | HAS_LIGHTS | MMI_COMPATIBLE | BEACON_TRACKABLE | AI_COMPATIBLE | BEACON_CONTROLLABLE
- ///Spark effects are handled by this datum
+ /// Spark effects are handled by this datum
var/datum/effect_system/basic/spark_spread/spark_system
- ///How powerful our lights are
+ /// How powerful our lights are
var/lights_power = 6
- ///Just stop the mech from doing anything
+ /// Just stop the mech from doing anything
var/completely_disabled = FALSE
- ///Whether this mech is allowed to move diagonally
+ /// Whether this mech is allowed to move diagonally
var/allow_diagonal_movement = TRUE
- ///Whether this mech moves into a direct as soon as it goes to move. Basically, turn and step in the same key press.
+ /// Whether this mech moves into a direct as soon as it goes to move. Basically, turn and step in the same key press.
var/pivot_step = FALSE
- ///Whether or not the mech destroys walls by running into it.
+ /// Whether or not the mech destroys walls by running into it.
var/bumpsmash = FALSE
- ///////////ATMOS
- ///Whether the cabin exchanges gases with the environment
+ // Atmos stuff
+ /// Whether the cabin exchanges gases with the environment
var/cabin_sealed = FALSE
- ///Internal air mix datum
+ /// Internal air mix datum
var/datum/gas_mixture/cabin_air
- ///Volume of the cabin
+ /// Volume of the cabin
var/cabin_volume = TANK_STANDARD_VOLUME * 3
- ///List of installed remote tracking beacons, including AI control beacons
+ /// List of installed remote tracking beacons, including AI control beacons
var/list/trackers = list()
- ///Camera installed into the mech
+ /// Camera installed into the mech
var/obj/machinery/camera/exosuit/chassis_camera
var/max_temperature = 25000
- ///Bitflags for internal damage
+ /// Bitflags for internal damage
var/internal_damage = NONE
/// % chance for internal damage to occur
var/internal_damage_probability = 20
- /// list of possibly dealt internal damage for this mech type
+ /// List of possibly dealt internal damage for this mech type
var/possible_int_damage = MECHA_INT_FIRE|MECHA_INT_TEMP_CONTROL|MECHA_CABIN_AIR_BREACH|MECHA_INT_CONTROL_LOST|MECHA_INT_SHORT_CIRCUIT
- /// damage threshold above which we take component damage
+ /// Damage threshold above which we take component damage
var/component_damage_threshold = 10
- ///Stores the DNA enzymes of a carbon so tht only they can access the mech
+ /// Stores the DNA enzymes of a carbon so tht only they can access the mech
var/dna_lock
/// A list of all granted accesses
var/list/accesses = list()
/// If the mech should require ALL or only ONE of the listed accesses
var/one_access = TRUE
- ///Typepath for the wreckage it spawns when destroyed
+ /// Typepath for the wreckage it spawns when destroyed
var/wreckage
- ///single flag for the type of this mech, determines what kind of equipment can be attached to it
+ /// Single flag for the type of this mech, determines what kind of equipment can be attached to it
var/mech_type
- ///assoc list: key-typepathlist before init, key-equipmentlist after
+ /// Assoc list: key-typepathlist before init, key-equipmentlist after
var/list/equip_by_category = list(
MECHA_L_ARM = null,
MECHA_R_ARM = null,
@@ -115,7 +115,7 @@
MECHA_POWER = list(),
MECHA_ARMOR = list(),
)
- ///assoc list: max equips for modules key-count
+ /// Assoc list: max equips for modules key-count
var/list/max_equip_by_category = list(
MECHA_L_ARM = 1,
MECHA_R_ARM = 1,
@@ -123,94 +123,71 @@
MECHA_POWER = 1,
MECHA_ARMOR = 0,
)
- ///flat equipment for iteration
+ /// Flat equipment for iteration
var/list/flat_equipment
- ///Handles an internal ore box for mining mechs
+ /// Internal ore box for mining mechs, or one picked up by a hydraulic clamp
var/obj/structure/ore_box/ore_box
///Whether our steps are silent due to no gravity
var/step_silent = FALSE
- ///Sound played when the mech moves
+ /// Sound played when the mech moves
var/stepsound = 'sound/vehicles/mecha/mechstep.ogg'
- ///Sound played when the mech walks
+ /// Sound played when the mech walks
var/turnsound = 'sound/vehicles/mecha/mechturn.ogg'
- ///Sounds for types of melee attack
+ /// Sounds for types of melee attack
var/brute_attack_sound = 'sound/items/weapons/punch4.ogg'
var/burn_attack_sound = 'sound/items/tools/welder.ogg'
var/tox_attack_sound = 'sound/effects/spray2.ogg'
- ///Sound on wall destroying
+ /// Sound on wall destroying
var/destroy_wall_sound = 'sound/effects/meteorimpact.ogg'
- ///Melee attack verb
+ /// Melee attack verb
var/list/attack_verbs = list("hit", "hits", "hitting")
- ///Cooldown duration between melee punches
+ /// Cooldown duration between melee punches
var/melee_cooldown = CLICK_CD_SLOW
- ///TIme taken to leave the mech
+ /// Time taken to leave the mech
var/exit_delay = 2 SECONDS
- ///Time you get slept for if you get forcible ejected by the mech exploding
+ /// Time you get slept for if you get forcible ejected by the mech exploding
var/destruction_sleep_duration = 2 SECONDS
- ///In case theres a different iconstate for AI/MMI pilot(currently only used for ripley)
+ /// In case theres a different iconstate for AI/MMI pilot(currently only used for ripley)
var/silicon_icon_state = null
- ///Currently ejecting, and unable to do things
+ /// Currently ejecting, and unable to do things
var/is_currently_ejecting = FALSE
- ///Safety for weapons. Won't fire if enabled, and toggled by middle click.
+ /// Safety for weapons. Won't fire if enabled, and toggled by middle click.
var/weapons_safety = FALSE
- ///Don't play standard sound when set safety if TRUE.
+ /// Don't play standard sound when set safety if TRUE.
var/safety_sound_custom = FALSE
- var/datum/effect_system/fluid_spread/smoke/smoke_system
-
- ////Action vars
- ///Ref to any active thrusters we might have
+ // Action vars
+ /// Ref to any active thrusters we might have
var/obj/item/mecha_parts/mecha_equipment/thrusters/active_thrusters
- ///Bool for energy shield on/off
- var/defense_mode = FALSE
-
- ///Bool for leg overload on/off
+ /// Bool for leg overload on/off
VAR_FINAL/overclock_mode = FALSE
- ///Whether it is possible to toggle overclocking from the cabin
+ /// Whether it is possible to toggle overclocking from the cabin
var/can_use_overclock = FALSE
- ///Speed and energy usage modifier for leg overload
+ /// Speed and energy usage modifier for leg overload
var/overclock_coeff = 1.5
- ///Current leg actuator temperature. Increases when overloaded, decreases when not.
+ /// Current leg actuator temperature. Increases when overloaded, decreases when not.
var/overclock_temp = 0
- ///Temperature threshold at which actuators may start causing internal damage
+ /// Temperature threshold at which actuators may start causing internal damage
var/overclock_temp_danger = 15
- ///Whether the mech has an option to enable safe overclocking
+ /// Whether the mech has an option to enable safe overclocking
var/overclock_safety_available = FALSE
- ///Whether the overclocking turns off automatically when overheated
+ /// Whether the overclocking turns off automatically when overheated
var/overclock_safety = FALSE
/// Action type for overclocking, if null - no action
var/overclock_action_type = /datum/action/vehicle/sealed/mecha/mech_overclock
/// Name of the overclock action
var/overclock_name = "overclock"
- //Bool for zoom on/off
- var/zoom_mode = FALSE
-
- ///Remaining smoke charges
- var/smoke_charges = 5
- ///Cooldown between using smoke
- var/smoke_cooldown = 10 SECONDS
-
- ///check for phasing, if it is set to text (to describe how it is phasing: "flying", "phasing") it will let the mech walk through walls.
- var/phasing = ""
- ///Power we use every time we phaze through something
- var/phasing_energy_drain = 0.2 * STANDARD_CELL_CHARGE
- ///icon_state for flick() when phazing
- var/phase_state = ""
-
- ///Wether we are strafing
+ /// Whether we are strafing
var/strafe = FALSE
- ///Bool for whether this mech can only be used on lavaland
- var/lavaland_only = FALSE
-
- /// ref to screen object that displays in the middle of the UI
+ /// Ref to screen object that displays in the middle of the UI
var/atom/movable/screen/map_view/ui_view
/// Theme of the mech TGUI
@@ -234,7 +211,6 @@
spark_system = new(src, 2, FALSE)
spark_system.attach(src)
- smoke_system = new(src, 3, holder = src)
cabin_air = new(cabin_volume)
@@ -274,9 +250,9 @@
AddElement(/datum/element/hostile_machine)
/obj/vehicle/sealed/mecha/Destroy()
- /// If the former occupants get polymorphed, mutated, chestburstered,
- /// or otherwise replaced by another mob, that mob is no longer in .occupants
- /// and gets deleted with the mech. However, they do remain in .contents
+ // If the former occupants get polymorphed, mutated, chestburstered,
+ // or otherwise replaced by another mob, that mob is no longer in .occupants
+ // and gets deleted with the mech. However, they do remain in .contents
var/list/potential_occupants = contents | occupants
for(var/mob/buggy_ejectee in potential_occupants)
mob_exit(buggy_ejectee, silent = TRUE, forced = TRUE)
@@ -297,7 +273,6 @@
QDEL_NULL(servo)
QDEL_NULL(cabin_air)
QDEL_NULL(spark_system)
- QDEL_NULL(smoke_system)
QDEL_NULL(ui_view)
QDEL_LIST(trackers)
QDEL_NULL(chassis_camera)
@@ -307,7 +282,7 @@
diag_hud.remove_atom_from_hud(src) //YEET
return ..()
-///Add parts on mech spawning. Skipped in manual construction.
+/// Add parts on mech spawning. Skipped in manual construction.
/obj/vehicle/sealed/mecha/proc/populate_parts()
cell = new /obj/item/stock_parts/power_store/cell/high(src)
scanmod = new /obj/item/stock_parts/scanning_module(src)
@@ -329,37 +304,42 @@
var/mob/living/silicon/ai/unlucky_ai
for(var/mob/living/occupant as anything in occupants)
- if(isAI(occupant))
- //FIXME: Nothiing about this block works
- var/mob/living/silicon/ai/ai = occupant
- if(!ai.linked_core && !ai.can_shunt) // we probably shouldnt gib AIs with a core or shunting abilities
- unlucky_ai = occupant
- ai.investigate_log("has been gibbed by having their mech destroyed.", INVESTIGATE_DEATHS)
- ai.gib(DROP_ALL_REMAINS) //No wreck, no AI to recover
- else
- mob_exit(ai, silent = TRUE, forced = TRUE) // so we dont ghost the AI
- continue
- else
+ if(!isAI(occupant))
mob_exit(occupant, forced = TRUE)
if(!isbrain(occupant)) // who would win.. 1 brain vs 1 sleep proc..
occupant.SetSleeping(destruction_sleep_duration)
+ continue
- if(wreckage)
- var/obj/structure/mecha_wreckage/WR = new wreckage(loc, unlucky_ai)
- for(var/obj/item/mecha_parts/mecha_equipment/E in flat_equipment)
- if(E.detachable && prob(30))
- WR.crowbar_salvage += E
- E.detach(WR) //detaches from src into WR
- E.active = TRUE
- else
- E.detach(loc)
- qdel(E)
- if(cell)
- WR.crowbar_salvage += cell
- cell.forceMove(WR)
- cell.use(rand(0, cell.charge), TRUE)
- cell = null
- return ..()
+ var/mob/living/silicon/ai/ai = occupant
+ if(ai.linked_core || ai.can_shunt) // we probably shouldnt gib AIs with a core or shunting abilities
+ mob_exit(ai, silent = TRUE, forced = TRUE) // so we dont ghost the AI
+ continue
+
+ unlucky_ai = occupant
+ ai.investigate_log("has been gibbed by having their mech destroyed.", INVESTIGATE_DEATHS)
+ ai.gib(DROP_ALL_REMAINS) //No wreck, no AI to recover
+
+ if(ore_box)
+ INVOKE_ASYNC(ore_box, TYPE_PROC_REF(/obj/structure/ore_box, dump_box_contents))
+
+ if(!wreckage)
+ return ..()
+
+ var/obj/structure/mecha_wreckage/wreck = new wreckage(loc, unlucky_ai)
+ for(var/obj/item/mecha_parts/mecha_equipment/equipment in flat_equipment)
+ if(equipment.detachable && prob(30))
+ wreck.crowbar_salvage += equipment
+ equipment.detach(wreck) //detaches from src into wreck
+ equipment.active = TRUE
+ else
+ equipment.detach(loc)
+ qdel(equipment)
+
+ if(cell)
+ wreck.crowbar_salvage += cell
+ cell.forceMove(wreck)
+ cell.use(rand(0, cell.charge), TRUE)
+ cell = null
/obj/vehicle/sealed/mecha/update_icon_state()
@@ -400,9 +380,9 @@
mob_occupant.update_mouse_pointer()
//override this proc if you need to split up mecha control between multiple people (see savannah_ivanov.dm)
-/obj/vehicle/sealed/mecha/auto_assign_occupant_flags(mob/M)
+/obj/vehicle/sealed/mecha/auto_assign_occupant_flags(mob/occupant)
if(driver_amount() < max_drivers)
- add_control_flags(M, FULL_MECHA_CONTROL)
+ add_control_flags(occupant, FULL_MECHA_CONTROL)
/obj/vehicle/sealed/mecha/generate_actions()
initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_eject)
@@ -416,14 +396,15 @@
initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/strafe, VEHICLE_CONTROL_DRIVE)
/obj/vehicle/sealed/mecha/add_occupant(mob/M, control_flags, forced)
- if(..())
+ . = ..()
+ if(.)
generate_equipment_actions(M)
/obj/vehicle/sealed/mecha/remove_occupant(mob/M)
remove_all_equipment_actions(M)
return ..()
-///Generates action buttons for all eligible equipment and grants them to the occupant with VEHICLE_CONTROL_SETTINGS flag.
+/// Generates action buttons for all eligible equipment and grants them to the occupant with VEHICLE_CONTROL_SETTINGS flag.
/obj/vehicle/sealed/mecha/proc/generate_equipment_actions(mob/occupant)
if(!(occupant in occupants) || !(occupants[occupant] & VEHICLE_CONTROL_SETTINGS))
return
@@ -433,7 +414,7 @@
grant_equipment_action(occupant, equipment)
-///Removes all equipment actions from a specific occupant.
+/// Removes all equipment actions from a specific occupant.
/obj/vehicle/sealed/mecha/proc/remove_all_equipment_actions(mob/occupant)
var/list/actions = LAZYACCESS(occupant_actions, occupant)
if(!actions)
@@ -442,7 +423,6 @@
for(var/equipment_type in actions)
if(!ispath(equipment_type, /obj/item/mecha_parts/mecha_equipment))
continue
-
remove_action_type_from_mob(equipment_type, occupant)
/**
@@ -497,16 +477,6 @@
return base_icon_state
return "[base_icon_state]-open"
-/obj/vehicle/sealed/mecha/CanPassThrough(atom/blocker, movement_dir, blocker_opinion)
- if(!phasing || get_charge() <= phasing_energy_drain || throwing)
- return ..()
- if(phase_state)
- flick(phase_state, src)
- var/turf/destination_turf = get_step(loc, movement_dir)
- if(!check_teleport_valid(src, destination_turf) || SSmapping.level_trait(destination_turf.z, ZTRAIT_NOPHASE))
- return FALSE
- return TRUE
-
/obj/vehicle/sealed/mecha/get_cell()
return cell
@@ -521,7 +491,8 @@
to_chat(mob_occupant, span_notice("Equipment control unit has been rebooted successfully."))
set_mouse_pointer()
-/obj/vehicle/sealed/mecha/proc/update_part_values() ///Updates the values given by scanning module and capacitor tier, called when a part is removed or inserted.
+/// Updates the values given by scanning module and capacitor tier, called when a part is removed or inserted.
+/obj/vehicle/sealed/mecha/proc/update_part_values()
update_energy_drain()
if(capacitor)
@@ -599,7 +570,7 @@
/obj/vehicle/sealed/mecha/generate_integrity_message()
var/examine_text = ""
- var/integrity = atom_integrity*100/max_integrity
+ var/integrity = atom_integrity / max_integrity * 100
switch(integrity)
if(85 to 100)
@@ -615,7 +586,7 @@
return examine_text
-///Locate an internal tack in the utility modules
+/// Locate an internal tack in the utility modules
/obj/vehicle/sealed/mecha/proc/get_internal_tank()
var/obj/item/mecha_parts/mecha_equipment/air_tank/module = locate(/obj/item/mecha_parts/mecha_equipment/air_tank) in equip_by_category[MECHA_UTILITY]
return module?.internal_tank
@@ -742,7 +713,7 @@
playsound(src,'sound/machines/clockcult/brass_skewer.ogg', 40, TRUE)
log_message("Toggled lights off due to the lack of power.", LOG_MECHA)
-///Called when a driver clicks somewhere. Handles everything like equipment, punches, etc.
+/// Called when a driver clicks somewhere. Handles everything like equipment, punches, etc.
/obj/vehicle/sealed/mecha/proc/on_mouseclick(mob/user, atom/target, list/modifiers)
SIGNAL_HANDLER
if(LAZYACCESS(modifiers, MIDDLE_CLICK))
@@ -756,14 +727,7 @@
return
if(!isturf(target) && !isturf(target.loc)) // Prevents inventory from being drilled
return
- if(completely_disabled || is_currently_ejecting || (mecha_flags & CANNOT_INTERACT))
- return
- if(phasing)
- balloon_alert(user, "not while [phasing]!")
- return
- if(user.incapacitated)
- return
- if(!get_charge())
+ if(can_interact_with(target, user, modifiers))
return
if(src == target)
return
@@ -818,6 +782,15 @@
if(target.mech_melee_attack(src, user))
TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MELEE_ATTACK, melee_cooldown)
+/obj/vehicle/sealed/mecha/proc/can_interact_with(atom/target, mob/user, list/modifiers)
+ if(completely_disabled || is_currently_ejecting || (mecha_flags & CANNOT_INTERACT))
+ return FALSE
+ if(user.incapacitated)
+ return FALSE
+ if(!get_charge())
+ return FALSE
+ return TRUE
+
/// Driver alt clicks anything while in mech
/obj/vehicle/sealed/mecha/proc/on_click_alt(mob/user, atom/target, params)
SIGNAL_HANDLER
@@ -837,13 +810,13 @@
toggle_strafe()
-/// middle mouse click signal wrapper for AI users
+/// Middle mouse click signal wrapper for AI users
/obj/vehicle/sealed/mecha/proc/on_middlemouseclick(mob/user, atom/target, params)
SIGNAL_HANDLER
if(isAI(user))
on_mouseclick(user, target, params)
-///Displays a special speech bubble when someone inside the mecha speaks
+/// Displays a special speech bubble when someone inside the mecha speaks
/obj/vehicle/sealed/mecha/proc/display_speech_bubble(datum/source, list/speech_args)
SIGNAL_HANDLER
var/list/speech_bubble_recipients = list()
@@ -854,10 +827,7 @@
var/image/mech_speech = image('icons/mob/effects/talk.dmi', src, "machine[say_test(speech_args[SPEECH_MESSAGE])]",MOB_LAYER+1)
INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(flick_overlay_global), mech_speech, speech_bubble_recipients, 3 SECONDS)
-/////////////////////////////////////
-//////// Atmospheric stuff ////////
-/////////////////////////////////////
-
+// Atmospheric stuff
/obj/vehicle/sealed/mecha/remove_air(amount)
if((mecha_flags & IS_ENCLOSED) && cabin_sealed)
return cabin_air.remove(amount)
@@ -871,17 +841,17 @@
/obj/vehicle/sealed/mecha/return_analyzable_air()
return cabin_air
-///fetches pressure of the gas mixture we are using
+/// Fetches pressure of the gas mixture we are using
/obj/vehicle/sealed/mecha/proc/return_pressure()
var/datum/gas_mixture/air = return_air()
return air?.return_pressure()
-///fetches temp of the gas mixture we are using
+/// Fetches temp of the gas mixture we are using
/obj/vehicle/sealed/mecha/return_temperature()
var/datum/gas_mixture/air = return_air()
return air?.return_temperature()
-///makes cabin unsealed, dumping cabin air outside or airtight filling the cabin with external air mix
+/// Makes cabin unsealed, dumping cabin air outside or airtight filling the cabin with external air mix
/obj/vehicle/sealed/mecha/proc/set_cabin_seal(mob/user, cabin_sealed)
if(!(mecha_flags & IS_ENCLOSED))
balloon_alert(user, "cabin can't be sealed!")
@@ -962,16 +932,18 @@
overclock_mode = forced_state
else
overclock_mode = !overclock_mode
+
log_message("Toggled [overclock_name].", LOG_MECHA)
for(var/mob/occupant as anything in occupants)
balloon_alert(occupant, "[overclock_name] [overclock_mode ? "on":"off"]")
var/datum/action/act = locate(/datum/action/vehicle/sealed/mecha/mech_overclock) in occupant.actions
act?.build_all_button_icons(UPDATE_BUTTON_ICON)
+
if(overclock_mode)
- movedelay = movedelay / overclock_coeff
+ movedelay /= overclock_coeff
visible_message(span_notice("[src] starts heating up, making humming sounds."))
else
- movedelay = initial(movedelay)
+ movedelay *= overclock_coeff
visible_message(span_notice("[src] cools down and the humming stops."))
update_energy_drain()
return TRUE
@@ -982,15 +954,14 @@
step_energy_drain = initial(step_energy_drain) / servo.rating
else
step_energy_drain = 2 * initial(step_energy_drain)
+
if(overclock_mode)
step_energy_drain *= overclock_coeff
if(capacitor)
- phasing_energy_drain = initial(phasing_energy_drain) / capacitor.rating
melee_energy_drain = initial(melee_energy_drain) / capacitor.rating
light_power_drain = initial(light_power_drain) / capacitor.rating
else
- phasing_energy_drain = initial(phasing_energy_drain)
melee_energy_drain = initial(melee_energy_drain)
light_power_drain = initial(light_power_drain)
diff --git a/code/modules/vehicles/mecha/combat/durand.dm b/code/modules/vehicles/mecha/combat/durand.dm
index 99f32ddc987..05641719ee0 100644
--- a/code/modules/vehicles/mecha/combat/durand.dm
+++ b/code/modules/vehicles/mecha/combat/durand.dm
@@ -20,7 +20,13 @@
MECHA_POWER = 1,
MECHA_ARMOR = 1,
)
- var/obj/durand_shield/shield
+
+ /// Bool for energy shield on/off
+ var/defense_mode = FALSE
+ /// Fake shield object we use as a way to redirect attacks off ourselves
+ var/obj/durand_shield/shield = null
+ /// Is the shield currently switching modes?
+ var/switching = FALSE
/datum/armor/mecha_durand
melee = 40
@@ -33,137 +39,145 @@
/obj/vehicle/sealed/mecha/durand/Initialize(mapload)
. = ..()
- shield = new /obj/durand_shield(loc, src, plane, layer, dir)
- RegisterSignal(src, COMSIG_MECHA_ACTION_TRIGGER, PROC_REF(relay))
+ shield = new(src, src)
+ vis_contents += shield
/obj/vehicle/sealed/mecha/durand/Destroy()
if(shield)
QDEL_NULL(shield)
return ..()
-
/obj/vehicle/sealed/mecha/durand/generate_actions()
. = ..()
initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_defense_mode)
/obj/vehicle/sealed/mecha/durand/process()
. = ..()
- if(defense_mode && !use_energy(0.01 * STANDARD_CELL_CHARGE)) //Defence mode can only be on with a occupant so we check if one of them can toggle it and toggle
- for(var/O in occupants)
- var/mob/living/occupant = O
- var/datum/action/action = LAZYACCESSASSOC(occupant_actions, occupant, /datum/action/vehicle/sealed/mecha/mech_defense_mode)
- if(action)
- action.Trigger()
- break
-
-/obj/vehicle/sealed/mecha/durand/Move(direction)
- . = ..()
- if(shield)
- shield.forceMove(loc)
- shield.setDir(dir)
-
-/obj/vehicle/sealed/mecha/durand/forceMove(turf/T)
- . = ..()
- shield.forceMove(T)
+ // Defence mode can only be on with a occupant so we check if one of them can toggle it and toggle
+ if(defense_mode && !use_energy(0.01 * STANDARD_CELL_CHARGE))
+ toggle_defense()
/obj/vehicle/sealed/mecha/durand/mob_exit(mob/M, silent = FALSE, randomstep = FALSE, forced = FALSE)
if(defense_mode)
- var/datum/action/action = LAZYACCESSASSOC(occupant_actions, M, /datum/action/vehicle/sealed/mecha/mech_defense_mode)
- if(action)
- INVOKE_ASYNC(action, TYPE_PROC_REF(/datum/action, Trigger), null, NONE, FALSE)
+ toggle_defense()
return ..()
-///Relays the signal from the action button to the shield, and creates a new shield if the old one is MIA.
-/obj/vehicle/sealed/mecha/durand/proc/relay(datum/source, mob/owner, list/signal_args)
- SIGNAL_HANDLER
- if(!shield) //if the shield somehow got deleted
- stack_trace("Durand triggered relay without a shield")
- shield = new /obj/durand_shield(loc, src, layer)
- shield.setDir(dir)
-
//Redirects projectiles to the shield if defense_check decides they should be blocked and returns true.
/obj/vehicle/sealed/mecha/durand/projectile_hit(obj/projectile/hitting_projectile, def_zone, piercing_hit, blocked)
if(defense_check(hitting_projectile.loc) && shield)
return shield.projectile_hit(hitting_projectile, def_zone, piercing_hit, blocked)
return ..()
-/**Checks if defense mode is enabled, and if the attacker is standing in an area covered by the shield.
-Expects a turf. Returns true if the attack should be blocked, false if not.*/
+/**
+ * Checks if defense mode is enabled, and if the attacker is standing in an area covered by the shield.
+ * Expects a turf. Returns true if the attack should be blocked, false if not.
+ **/
/obj/vehicle/sealed/mecha/durand/proc/defense_check(turf/aloc)
- if (!defense_mode || !shield || shield.switching)
+ if (!defense_mode || !shield || switching)
return FALSE
- . = FALSE
+
switch(dir)
- if (1)
- if(abs(x - aloc.x) <= (y - aloc.y) * -2)
- . = TRUE
- if (2)
- if(abs(x - aloc.x) <= (y - aloc.y) * 2)
- . = TRUE
- if (4)
- if(abs(y - aloc.y) <= (x - aloc.x) * -2)
- . = TRUE
- if (8)
- if(abs(y - aloc.y) <= (x - aloc.x) * 2)
- . = TRUE
- return
+ if (NORTH)
+ return abs(x - aloc.x) <= (y - aloc.y) * -2
+ if (SOUTH)
+ return abs(x - aloc.x) <= (y - aloc.y) * 2
+ if (EAST)
+ return abs(y - aloc.y) <= (x - aloc.x) * -2
+ if (WEST)
+ return abs(y - aloc.y) <= (x - aloc.x) * 2
+
+/obj/vehicle/sealed/mecha/durand/proc/toggle_defense(mob/living/user)
+ if(!LAZYLEN(occupants))
+ return
+
+ if(switching && (user || !defense_mode)) // Allow force shutdowns during animation
+ return
+
+ if(!defense_mode && cell?.charge < 100) // If it's off, and we have less than 100 units of power
+ if (user)
+ balloon_alert(user, "insufficient power")
+ return
+
+ switching = TRUE
+ defense_mode = !defense_mode
+
+ if(user)
+ balloon_alert(user, "shield [defense_mode ? "enabled" : "disabled"]")
+ log_message("User has toggled defense mode -- now [defense_mode ? "enabled" : "disabled"].", LOG_MECHA)
+ else
+ log_message("defense mode state changed -- now [defense_mode ? "enabled" : "disabled"].", LOG_MECHA)
+
+ for(var/mob/living/occupant as anything in occupants)
+ var/datum/action/button = occupant_actions[occupant][/datum/action/vehicle/sealed/mecha/mech_defense_mode]
+ button.button_icon_state = "mech_defense_mode_[defense_mode ? "on" : "off"]"
+ button.build_all_button_icons()
+
+ shield.set_light_on(defense_mode)
+
+ if(defense_mode)
+ shield.icon_state = "shield"
+ flick("shield_raise", shield)
+ playsound(src, 'sound/vehicles/mecha/mech_shield_raise.ogg', 50, FALSE)
+ else
+ shield.icon_state = "shield_null"
+ flick("shield_drop", shield)
+ playsound(src, 'sound/vehicles/mecha/mech_shield_drop.ogg', 50, FALSE)
+
+ addtimer(VARSET_CALLBACK(src, switching, FALSE), 0.7 SECONDS) // Shield animation length
/obj/vehicle/sealed/mecha/durand/attack_generic(mob/user, damage_amount = 0, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, armor_penetration = 0)
- if(defense_check(user.loc))
+ if(defense_check(get_turf(user)))
log_message("Attack absorbed by defense field. Attacker - [user].", LOG_MECHA, color="orange")
return shield.attack_generic(user, damage_amount, damage_type, damage_flag, sound_effect, armor_penetration)
return ..()
-/obj/vehicle/sealed/mecha/durand/blob_act(obj/structure/blob/B)
- if(defense_check(B.loc))
- log_message("Attack by blob. Attacker - [B].", LOG_MECHA, color="red")
- log_message("Attack absorbed by defense field.", LOG_MECHA, color="orange")
- shield.blob_act(B)
- else
- . = ..()
+/obj/vehicle/sealed/mecha/durand/blob_act(obj/structure/blob/blob)
+ if(!defense_check(get_turf(blob)))
+ return ..()
+ log_message("Attack by blob. Attacker - [blob].", LOG_MECHA, color="red")
+ log_message("Attack absorbed by defense field.", LOG_MECHA, color="orange")
+ return shield.blob_act(blob)
-/obj/vehicle/sealed/mecha/durand/attackby(obj/item/W as obj, mob/user as mob, list/modifiers, list/attack_modifiers)
- if(defense_check(user.loc))
- log_message("Attack absorbed by defense field. Attacker - [user], with [W]", LOG_MECHA, color="orange")
- shield.attackby(W, user, modifiers)
- else
- . = ..()
+/obj/vehicle/sealed/mecha/durand/attackby(obj/item/weapon, mob/user as mob, list/modifiers, list/attack_modifiers)
+ if(defense_check(get_turf(user)))
+ log_message("Attack absorbed by defense field. Attacker - [user], with [weapon]", LOG_MECHA, color="orange")
+ return shield.attackby(weapon, user, modifiers)
+ return ..()
/obj/vehicle/sealed/mecha/durand/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
- if(defense_check(AM.loc))
+ if(defense_check(get_turf(AM)))
log_message("Impact with [AM] absorbed by defense field.", LOG_MECHA, color="orange")
- shield.hitby(AM, skipcatch, hitpush, blocked, throwingdatum)
- else
- . = ..()
+ return shield.hitby(AM, skipcatch, hitpush, blocked, throwingdatum)
+ return ..()
/datum/action/vehicle/sealed/mecha/mech_defense_mode
- name = "Toggle an energy shield that blocks all attacks from the faced direction at a heavy power cost."
+ name = "Toggle Shield"
+ desc = "Toggle an energy shield that blocks all attacks from the faced direction at a heavy power cost."
button_icon_state = "mech_defense_mode_off"
/datum/action/vehicle/sealed/mecha/mech_defense_mode/Trigger(mob/clicker, trigger_flags, forced_state = FALSE)
. = ..()
if(!.)
return
- if(!chassis || !(owner in chassis.occupants))
- return
- SEND_SIGNAL(chassis, COMSIG_MECHA_ACTION_TRIGGER, owner, args) //Signal sent to the mech, to be handed to the shield. See durand.dm for more details
+ if(chassis && (owner in chassis.occupants))
+ var/obj/vehicle/sealed/mecha/durand/durand = chassis
+ durand.toggle_defense(owner)
-////////////////////////////
-///// Shield processing ////
-////////////////////////////
+// Shield processing
-/**An object to take the hit for us when using the Durand's defense mode.
-It is spawned in during the durand's initilization, and always stays on the same tile.
-Normally invisible, until defense mode is actvated. When the durand detects an attack that should be blocked, the
-attack is passed to the shield. The shield takes the damage, uses it to calculate charge cost, and then sets its
-own integrity back to max. Shield is automatically dropped if we run out of power or the user gets out.*/
+/**
+ * An object to take the hit for us when using the Durand's defense mode.
+ * It is spawned in during the durand's initilization.
+ * Normally invisible, until defense mode is actvated. When the durand detects an attack that should be blocked, the
+ * attack is passed to the shield. The shield takes the damage, uses it to calculate charge cost, and then sets its
+ * own integrity back to max. Shield is automatically dropped if we run out of power or the user gets out.
+ **/
/obj/durand_shield //projectiles get passed to this when defense mode is enabled
name = "defense grid"
icon = 'icons/mob/effects/durand_shield.dmi'
icon_state = "shield_null"
- invisibility = INVISIBILITY_MAXIMUM //no showing on right-click
- pixel_y = 4
+ pixel_z = 4
max_integrity = 10000
anchored = TRUE
light_system = OVERLAY_LIGHT
@@ -171,100 +185,22 @@ own integrity back to max. Shield is automatically dropped if we run out of powe
light_power = 1
light_color = LIGHT_COLOR_FAINT_CYAN
light_on = FALSE
- resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF //The shield should not take damage from fire, lava, or acid; that's the mech's job.
- ///Our link back to the durand
+ light_flags = LIGHT_ATTACHED
+ vis_flags = VIS_INHERIT_DIR | VIS_INHERIT_LAYER | VIS_INHERIT_PLANE | VIS_INHERIT_ID
+ resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF // The shield should not take damage from fire, lava, or acid; that's the mech's job.
+ /// Our link back to the durand
var/obj/vehicle/sealed/mecha/durand/chassis
- ///To keep track of things during the animation
- var/switching = FALSE
-/obj/durand_shield/Initialize(mapload, chassis, plane, layer, dir)
+/obj/durand_shield/Initialize(mapload, obj/vehicle/sealed/mecha/durand/chassis)
. = ..()
src.chassis = chassis
- src.layer = ABOVE_MOB_LAYER
- SET_PLANE_IMPLICIT(src, plane)
- setDir(dir)
- RegisterSignal(chassis, COMSIG_MECHA_ACTION_TRIGGER, PROC_REF(activate))
- RegisterSignal(chassis, COMSIG_MOVABLE_UPDATE_GLIDE_SIZE, PROC_REF(shield_glide_size_update))
/obj/durand_shield/Destroy()
- UnregisterSignal(src, COMSIG_MECHA_ACTION_TRIGGER)
if(chassis)
- UnregisterSignal(chassis, COMSIG_MOVABLE_UPDATE_GLIDE_SIZE)
chassis.shield = null
chassis = null
return ..()
-/obj/durand_shield/proc/shield_glide_size_update(datum/source, target)
- SIGNAL_HANDLER
- glide_size = target
-
-/**
- * Handles activating and deactivating the shield.
- *
- * This proc is called by a signal sent from the mech's action button and
- * relayed by the mech itself. The "forced" variable, `signal_args[1]`, will
- * skip the to-pilot text and is meant for when the shield is disabled by
- * means other than the action button (like running out of power).
- *
- * Arguments:
- * * source: the shield
- * * owner: mob that activated the shield
- * * signal_args: whether it's forced
- */
-/obj/durand_shield/proc/activate(datum/source, mob/owner, list/signal_args)
- SIGNAL_HANDLER
- if(!LAZYLEN(chassis?.occupants))
- return
- if(switching && !signal_args[1])
- return
- if(!chassis.defense_mode && (!chassis.cell || chassis.cell.charge < 100)) //If it's off, and we have less than 100 units of power
- chassis.balloon_alert(owner, "insufficient power")
- return
- switching = TRUE
- chassis.defense_mode = !chassis.defense_mode
- if(!signal_args[1])
- chassis.balloon_alert(owner, "shield [chassis.defense_mode?"enabled":"disabled"]")
- chassis.log_message("User has toggled defense mode -- now [chassis.defense_mode?"enabled":"disabled"].", LOG_MECHA)
- else
- chassis.log_message("defense mode state changed -- now [chassis.defense_mode?"enabled":"disabled"].", LOG_MECHA)
- for(var/occupant in chassis.occupants)
- var/datum/action/button = chassis.occupant_actions[occupant][/datum/action/vehicle/sealed/mecha/mech_defense_mode]
- button.button_icon_state = "mech_defense_mode_[chassis.defense_mode ? "on" : "off"]"
- button.build_all_button_icons()
-
- set_light_on(chassis.defense_mode)
-
- if(chassis.defense_mode)
- SetInvisibility(INVISIBILITY_NONE, id=type)
- flick("shield_raise", src)
- playsound(src, 'sound/vehicles/mecha/mech_shield_raise.ogg', 50, FALSE)
- icon_state = "shield"
- resetdir(chassis, dir, dir) // to set the plane for the shield properly when it's turned on
- RegisterSignal(chassis, COMSIG_ATOM_DIR_CHANGE, PROC_REF(resetdir))
- else
- flick("shield_drop", src)
- playsound(src, 'sound/vehicles/mecha/mech_shield_drop.ogg', 50, FALSE)
- icon_state = "shield_null"
- addtimer(CALLBACK(src, PROC_REF(make_invisible)), 1 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE)
- UnregisterSignal(chassis, COMSIG_ATOM_DIR_CHANGE)
- switching = FALSE
-
-/**
- * Sets invisibility to INVISIBILITY_MAXIMUM if defense mode is disabled
- *
- * We need invisibility set to higher than 25 for the shield to not appear
- * in the right-click context menu, but if we do it too early, we miss the
- * deactivate animation. Hense, timer and this proc.
- */
-/obj/durand_shield/proc/make_invisible()
- if(!chassis.defense_mode)
- RemoveInvisibility(type)
-
-/obj/durand_shield/proc/resetdir(datum/source, olddir, newdir)
- SIGNAL_HANDLER
-
- setDir(newdir)
-
/obj/durand_shield/take_damage(damage_amount, damage_type = BRUTE, damage_flag = "", sound_effect = TRUE, attack_dir, armour_penetration = 0)
if(!chassis)
qdel(src)
@@ -277,10 +213,7 @@ own integrity back to max. Shield is automatically dropped if we run out of powe
return
if(!chassis.use_energy(. * (STANDARD_CELL_CHARGE / 150)))
chassis.cell?.charge = 0
- for(var/O in chassis.occupants)
- var/mob/living/occupant = O
- var/datum/action/action = LAZYACCESSASSOC(chassis.occupant_actions, occupant, /datum/action/vehicle/sealed/mecha/mech_defense_mode)
- action.Trigger()
+ chassis.toggle_defense()
atom_integrity = 10000
/obj/durand_shield/play_attack_sound()
diff --git a/code/modules/vehicles/mecha/combat/marauder.dm b/code/modules/vehicles/mecha/combat/marauder.dm
index e316de70bf7..083bf66e3dd 100644
--- a/code/modules/vehicles/mecha/combat/marauder.dm
+++ b/code/modules/vehicles/mecha/combat/marauder.dm
@@ -24,6 +24,15 @@
)
bumpsmash = TRUE
+ /// Reusable smoke generator system
+ var/datum/effect_system/fluid_spread/smoke/smoke_system
+ /// Remaining smoke charges
+ var/smoke_charges = 5
+ /// Cooldown between using smoke
+ var/smoke_cooldown = 10 SECONDS
+ /// Bool for zoom on/off
+ var/zoom_mode = FALSE
+
/datum/armor/mecha_marauder
melee = 70
bullet = 60
@@ -33,6 +42,14 @@
fire = 100
acid = 100
+/obj/vehicle/sealed/mecha/marauder/Initialize(mapload, built_manually)
+ . = ..()
+ smoke_system = new(src, 3, holder = src)
+
+/obj/vehicle/sealed/mecha/marauder/Destroy()
+ QDEL_NULL(smoke_system)
+ return ..()
+
/obj/vehicle/sealed/mecha/marauder/generate_actions()
. = ..()
initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_smoke)
@@ -54,20 +71,51 @@
servo = new /obj/item/stock_parts/servo/femto(src)
update_part_values()
+/obj/vehicle/sealed/mecha/marauder/remove_occupant(mob/driver)
+ . = ..()
+ zoom_mode = FALSE
+
+/obj/vehicle/sealed/mecha/marauder/can_move(direction)
+ . = ..()
+ if(!. || !zoom_mode)
+ return
+
+ if(TIMER_COOLDOWN_FINISHED(src, COOLDOWN_MECHA_MESSAGE))
+ to_chat(occupants, "[icon2html(src, occupants)][span_warning("Unable to move while in zoom mode!")]")
+ TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS)
+ return FALSE
+
/datum/action/vehicle/sealed/mecha/mech_smoke
name = "Smoke"
button_icon_state = "mech_smoke"
+/datum/action/vehicle/sealed/mecha/mech_smoke/IsAvailable(feedback)
+ . = ..()
+ if (!.)
+ return
+
+ var/obj/vehicle/sealed/mecha/marauder/maradeur = chassis
+ if(!TIMER_COOLDOWN_FINISHED(maradeur, COOLDOWN_MECHA_SMOKE))
+ if (feedback)
+ owner.balloon_alert(owner, "smoke charges on cooldown!")
+ return FALSE
+
+ if (!maradeur.smoke_charges)
+ if (feedback)
+ owner.balloon_alert(owner, "out of smoke charges!")
+ return FALSE
+
/datum/action/vehicle/sealed/mecha/mech_smoke/Trigger(mob/clicker, trigger_flags)
. = ..()
if(!.)
return
if(!chassis || !(owner in chassis.occupants))
return
- if(TIMER_COOLDOWN_FINISHED(src, COOLDOWN_MECHA_SMOKE) && chassis.smoke_charges>0)
- chassis.smoke_system.start()
- chassis.smoke_charges--
- TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_SMOKE, chassis.smoke_cooldown)
+ var/obj/vehicle/sealed/mecha/marauder/maradeur = chassis
+ if(TIMER_COOLDOWN_FINISHED(maradeur, COOLDOWN_MECHA_SMOKE) && maradeur.smoke_charges)
+ maradeur.smoke_system.start()
+ maradeur.smoke_charges--
+ TIMER_COOLDOWN_START(maradeur, COOLDOWN_MECHA_SMOKE, maradeur.smoke_cooldown)
/datum/action/vehicle/sealed/mecha/mech_zoom
name = "Zoom"
@@ -79,11 +127,12 @@
return
if(!owner.client || !chassis || !(owner in chassis.occupants))
return
- chassis.zoom_mode = !chassis.zoom_mode
- button_icon_state = "mech_zoom_[chassis.zoom_mode ? "on" : "off"]"
- chassis.log_message("Toggled zoom mode.", LOG_MECHA)
- to_chat(owner, "[icon2html(chassis, owner)]Zoom mode [chassis.zoom_mode?"en":"dis"]abled.")
- if(chassis.zoom_mode)
+ var/obj/vehicle/sealed/mecha/marauder/maradeur = chassis
+ maradeur.zoom_mode = !maradeur.zoom_mode
+ button_icon_state = "mech_zoom_[maradeur.zoom_mode ? "on" : "off"]"
+ maradeur.log_message("Toggled zoom mode.", LOG_MECHA)
+ to_chat(owner, "[icon2html(maradeur, owner)]Zoom mode [maradeur.zoom_mode ? "en" : "dis"]abled.")
+ if(maradeur.zoom_mode)
owner.client.view_size.setTo(4.5)
SEND_SOUND(owner, sound('sound/vehicles/mecha/imag_enh.ogg', volume=50))
else
diff --git a/code/modules/vehicles/mecha/combat/phazon.dm b/code/modules/vehicles/mecha/combat/phazon.dm
index e193f4e5e1c..5ca91ce5817 100644
--- a/code/modules/vehicles/mecha/combat/phazon.dm
+++ b/code/modules/vehicles/mecha/combat/phazon.dm
@@ -1,6 +1,6 @@
/obj/vehicle/sealed/mecha/phazon
- desc = "This is a Phazon exosuit. The pinnacle of scientific research and pride of Nanotrasen, it uses cutting edge anomalous technology and expensive materials."
name = "\improper Phazon"
+ desc = "This is a Phazon exosuit. The pinnacle of scientific research and pride of Nanotrasen, it uses cutting edge anomalous technology and expensive materials."
icon_state = "phazon"
base_icon_state = "phazon"
movedelay = 2
@@ -21,7 +21,13 @@
MECHA_POWER = 1,
MECHA_ARMOR = 2,
)
- phase_state = "phazon-phase"
+
+ /// Are we currently phasing through walls?
+ var/phasing = FALSE
+ /// Power we use every time we phaze through something
+ var/phasing_energy_drain = 0.2 * STANDARD_CELL_CHARGE
+ /// Icon_state for flick() when phasing
+ var/phase_state = "phazon-phase"
/datum/armor/mecha_phazon
melee = 30
@@ -37,6 +43,42 @@
initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_phasing)
initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_switch_damtype)
+/obj/vehicle/sealed/mecha/phazon/CanPassThrough(atom/blocker, movement_dir, blocker_opinion)
+ if(!phasing || get_charge() <= phasing_energy_drain || throwing)
+ return ..()
+ if(phase_state)
+ flick(phase_state, src)
+ var/turf/destination_turf = get_step(loc, movement_dir)
+ if(!check_teleport_valid(src, destination_turf) || SSmapping.level_trait(destination_turf.z, ZTRAIT_NOPHASE))
+ return FALSE
+ return TRUE
+
+/obj/vehicle/sealed/mecha/phazon/vehicle_move(direction, forcerotate)
+ . = ..()
+ if(. && phasing)
+ use_energy(phasing_energy_drain)
+
+/obj/vehicle/sealed/mecha/phazon/try_bumpsmash(atom/obstacle)
+ if(phasing) // Theres only one cause for phasing canpass fails
+ to_chat(occupants, "[icon2html(src, occupants)][span_warning("A dull, universal force is preventing you from phasing here!")]")
+ spark_system.start()
+ return
+ return ..()
+
+/obj/vehicle/sealed/mecha/phazon/update_energy_drain()
+ . = ..()
+ if(capacitor)
+ phasing_energy_drain = initial(phasing_energy_drain) / capacitor.rating
+ else
+ phasing_energy_drain = initial(phasing_energy_drain)
+
+/obj/vehicle/sealed/mecha/phazon/can_interact_with(atom/target, mob/user, list/modifiers)
+ . = ..()
+ if (!. || !phasing)
+ return
+ balloon_alert(user, "not while phasing!")
+ return FALSE
+
/datum/action/vehicle/sealed/mecha/mech_switch_damtype
name = "Reconfigure arm microtool arrays"
button_icon_state = "mech_damtype_brute"
@@ -73,7 +115,8 @@
return
if(!chassis || !(owner in chassis.occupants))
return
- chassis.phasing = chassis.phasing ? "" : "phasing"
- button_icon_state = "mech_phasing_[chassis.phasing ? "on" : "off"]"
- chassis.balloon_alert(owner, "[chassis.phasing ? "enabled" : "disabled"] phasing")
+ var/obj/vehicle/sealed/mecha/phazon/phazon = chassis
+ phazon.phasing = !phazon.phasing
+ button_icon_state = "mech_phasing_[phazon.phasing ? "on" : "off"]"
+ phazon.balloon_alert(owner, "[phazon.phasing ? "enabled" : "disabled"] phasing")
build_all_button_icons()
diff --git a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm
index 13f594f243b..4f9794a7c93 100644
--- a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm
+++ b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm
@@ -37,8 +37,8 @@
MECHA_POWER = 1,
MECHA_ARMOR = 1,
)
- //no tax on flying, since the power cost is in the leap itself.
- phasing_energy_drain = 0
+ /// Are we currently in the middle of a skyfall jump?
+ var/flying = FALSE
/datum/armor/mecha_savannah_ivanov
melee = 45
@@ -71,6 +71,22 @@
initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/skyfall, VEHICLE_CONTROL_DRIVE)
initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/ivanov_strike, VEHICLE_CONTROL_EQUIPMENT)
+// Pass through obstacles freely if we're flying
+/obj/vehicle/sealed/mecha/savannah_ivanov/CanPassThrough(atom/blocker, movement_dir, blocker_opinion)
+ if(!flying || throwing)
+ return ..()
+ var/turf/destination_turf = get_step(loc, movement_dir)
+ if(!check_teleport_valid(src, destination_turf) || SSmapping.level_trait(destination_turf.z, ZTRAIT_NOPHASE))
+ return FALSE
+ return TRUE
+
+/obj/vehicle/sealed/mecha/savannah_ivanov/can_interact_with(atom/target, mob/user, list/modifiers)
+ . = ..()
+ if (!. || !flying)
+ return
+ balloon_alert(user, "not while airborne!")
+ return FALSE
+
///Savannah Skyfall
/datum/action/vehicle/sealed/mecha/skyfall
name = "Savannah Skyfall"
@@ -86,17 +102,18 @@
return
if(!owner || !chassis || !(owner in chassis.occupants))
return
- if(chassis.phasing)
+ var/obj/vehicle/sealed/mecha/savannah_ivanov/savannah = chassis
+ if(savannah.flying)
to_chat(owner, span_warning("You're already airborne!"))
return
- if(TIMER_COOLDOWN_RUNNING(chassis, COOLDOWN_MECHA_SKYFALL))
- var/timeleft = S_TIMER_COOLDOWN_TIMELEFT(chassis, COOLDOWN_MECHA_SKYFALL)
+ if(TIMER_COOLDOWN_RUNNING(savannah, COOLDOWN_MECHA_SKYFALL))
+ var/timeleft = S_TIMER_COOLDOWN_TIMELEFT(savannah, COOLDOWN_MECHA_SKYFALL)
to_chat(owner, span_warning("You need to wait [DisplayTimeText(timeleft, 1)] before attempting to Skyfall."))
return
if(skyfall_charge_level)
abort_skyfall()
return
- chassis.balloon_alert(owner, "charging skyfall...")
+ savannah.balloon_alert(owner, "charging skyfall...")
INVOKE_ASYNC(src, PROC_REF(skyfall_charge_loop))
/**
@@ -146,7 +163,8 @@
new /obj/effect/skyfall_landingzone(launch_turf, chassis)
chassis.resistance_flags |= INDESTRUCTIBLE //not while jumping at least
chassis.mecha_flags |= QUIET_STEPS|QUIET_TURNS|CANNOT_INTERACT
- chassis.phasing = "flying"
+ var/obj/vehicle/sealed/mecha/savannah_ivanov/savannah = chassis
+ savannah.flying = TRUE
chassis.movedelay = 1
chassis.set_density(FALSE)
chassis.layer = ABOVE_ALL_MOB_LAYER
@@ -177,7 +195,8 @@
playsound(chassis, 'sound/effects/explosion/explosion1.ogg', 50, 1)
chassis.resistance_flags &= ~INDESTRUCTIBLE
chassis.mecha_flags &= ~(QUIET_STEPS|QUIET_TURNS|CANNOT_INTERACT)
- chassis.phasing = initial(chassis.phasing)
+ var/obj/vehicle/sealed/mecha/savannah_ivanov/savannah = chassis
+ savannah.flying = FALSE
chassis.movedelay = initial(chassis.movedelay)
chassis.set_density(TRUE)
chassis.layer = initial(chassis.layer)
diff --git a/code/modules/vehicles/mecha/equipment/mecha_equipment.dm b/code/modules/vehicles/mecha/equipment/mecha_equipment.dm
index e367837fb6d..f2f42d1f85b 100644
--- a/code/modules/vehicles/mecha/equipment/mecha_equipment.dm
+++ b/code/modules/vehicles/mecha/equipment/mecha_equipment.dm
@@ -160,8 +160,8 @@
if(flags & MECH_DO_AFTER_ADJACENCY_FLAG && !(chassis.Adjacent(target)))
return FALSE
-/obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/vehicle/sealed/mecha/M, attach_right = FALSE, mob/user)
- return default_can_attach(M, attach_right, user)
+/obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/vehicle/sealed/mecha/mech, attach_right = FALSE, mob/user)
+ return default_can_attach(mech, attach_right, user)
/obj/item/mecha_parts/mecha_equipment/proc/default_can_attach(obj/vehicle/sealed/mecha/mech, attach_right = FALSE, mob/user)
if(!(mech_flags & mech.mech_type))
diff --git a/code/modules/vehicles/mecha/mecha_actions.dm b/code/modules/vehicles/mecha/mecha_actions.dm
index 2fd55c14e4b..34d9e82e53b 100644
--- a/code/modules/vehicles/mecha/mecha_actions.dm
+++ b/code/modules/vehicles/mecha/mecha_actions.dm
@@ -107,7 +107,6 @@
chassis.toggle_strafe()
-
/obj/vehicle/sealed/mecha/proc/toggle_strafe()
if(!(mecha_flags & CAN_STRAFE))
to_chat(occupants, "this mecha doesn't support strafing!")
@@ -124,7 +123,7 @@
var/datum/action/action = LAZYACCESSASSOC(occupant_actions, occupant, /datum/action/vehicle/sealed/mecha/strafe)
action?.build_all_button_icons()
-///swap seats, for two person mecha
+/// Swap seats, for two person mecha
/datum/action/vehicle/sealed/mecha/swap_seat
name = "Switch Seats"
button_icon_state = "mech_seat_swap"
diff --git a/code/modules/vehicles/mecha/mecha_defense.dm b/code/modules/vehicles/mecha/mecha_defense.dm
index f41b3006e03..393c478b519 100644
--- a/code/modules/vehicles/mecha/mecha_defense.dm
+++ b/code/modules/vehicles/mecha/mecha_defense.dm
@@ -59,7 +59,7 @@
/obj/vehicle/sealed/mecha/attack_hand(mob/living/user, list/modifiers)
. = ..()
- if(.)
+ if(. || !user.combat_mode)
return
user.changeNext_move(CLICK_CD_MELEE) // Ugh. Ideally we shouldn't be setting cooldowns outside of click code.
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
@@ -73,26 +73,25 @@
/obj/vehicle/sealed/mecha/attack_alien(mob/living/user, list/modifiers)
log_message("Attack by alien. Attacker - [user].", LOG_MECHA, color="red")
playsound(loc, 'sound/items/weapons/slash.ogg', 100, TRUE)
- attack_generic(user, rand(user.melee_damage_lower, user.melee_damage_upper), BRUTE, MELEE, 0)
+ return attack_generic(user, rand(user.melee_damage_lower, user.melee_damage_upper), BRUTE, MELEE, 0)
/obj/vehicle/sealed/mecha/attack_animal(mob/living/simple_animal/user, list/modifiers)
log_message("Attack by simple animal. Attacker - [user].", LOG_MECHA, color="red")
if(!user.melee_damage_upper && !user.obj_damage)
user.emote("custom", message = "[user.friendly_verb_continuous] [src].")
- return 0
- else
- var/play_soundeffect = 1
- if(user.environment_smash)
- play_soundeffect = 0
- playsound(src, 'sound/effects/bang.ogg', 50, TRUE)
- var/animal_damage = rand(user.melee_damage_lower,user.melee_damage_upper)
- if(user.obj_damage)
- animal_damage = user.obj_damage
- animal_damage = min(animal_damage, 20*user.environment_smash)
- log_combat(user, src, "attacked")
- attack_generic(user, animal_damage, user.melee_damage_type, MELEE, play_soundeffect)
- return 1
+ return FALSE
+ var/play_soundeffect = 1
+ if(user.environment_smash)
+ play_soundeffect = 0
+ playsound(src, 'sound/effects/bang.ogg', 50, TRUE)
+
+ var/animal_damage = rand(user.melee_damage_lower,user.melee_damage_upper)
+ if(user.obj_damage)
+ animal_damage = user.obj_damage
+ animal_damage = min(animal_damage, 20*user.environment_smash)
+ log_combat(user, src, "attacked")
+ return attack_generic(user, animal_damage, user.melee_damage_type, MELEE, play_soundeffect)
/obj/vehicle/sealed/mecha/hulk_damage()
return 15
@@ -420,16 +419,18 @@
if(servo)
stock_parts += servo
- if(length(stock_parts))
- var/obj/item/stock_parts/part_to_remove = tgui_input_list(user, "Which part to remove?", "Part Removal", stock_parts)
- if(!(locate(part_to_remove) in contents))
- return
- user.put_in_hands(part_to_remove)
- locate_parts()
- diag_hud_set_mechcell()
- tool.play_tool_sound(src)
+ if(!length(stock_parts))
+ balloon_alert(user, "no parts!")
return
- balloon_alert(user, "no parts!")
+
+ var/obj/item/stock_parts/part_to_remove = tgui_input_list(user, "Which part to remove?", "Part Removal", stock_parts)
+ if(!(locate(part_to_remove) in contents))
+ return
+
+ user.put_in_hands(part_to_remove)
+ locate_parts()
+ diag_hud_set_mechcell()
+ tool.play_tool_sound(src)
/obj/vehicle/sealed/mecha/welder_act(mob/living/user, obj/item/W)
if(user.combat_mode)
@@ -445,7 +446,7 @@
return
user.balloon_alert_to_viewers("started welding [src]", "started repairing [src]")
audible_message(span_hear("You hear welding."))
- var/did_the_thing
+ var/did_the_thing = FALSE
while(atom_integrity < max_integrity)
if(W.use_tool(src, user, 2.5 SECONDS, volume=50))
did_the_thing = TRUE
@@ -453,12 +454,12 @@
audible_message(span_hear("You hear welding."))
else
break
+
if(did_the_thing)
user.balloon_alert_to_viewers("[(atom_integrity >= max_integrity) ? "fully" : "partially"] repaired [src]")
else
user.balloon_alert_to_viewers("stopped welding [src]", "interrupted the repair!")
-
/obj/vehicle/sealed/mecha/proc/full_repair(charge_cell)
repair_damage(max_integrity)
if(cell && charge_cell)
@@ -489,62 +490,66 @@
visual_effect_icon = ATTACK_EFFECT_MECHFIRE
else if(damtype == TOX)
visual_effect_icon = ATTACK_EFFECT_MECHTOXIN
- ..()
+ return ..()
-
-/obj/vehicle/sealed/mecha/proc/ammo_resupply(obj/item/mecha_ammo/A, mob/user,fail_chat_override = FALSE)
- if(!A.rounds)
+/obj/vehicle/sealed/mecha/proc/ammo_resupply(obj/item/mecha_ammo/ammo, mob/user,fail_chat_override = FALSE)
+ if(!ammo.rounds)
if(!fail_chat_override)
balloon_alert(user, "the box is empty!")
return FALSE
+
var/ammo_needed
var/found_gun
+
for(var/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/gun in flat_equipment)
ammo_needed = 0
- if(gun.ammo_type != A.ammo_type)
+ if(gun.ammo_type != ammo.ammo_type)
continue
found_gun = TRUE
- if(A.direct_load)
+ if(ammo.direct_load)
ammo_needed = initial(gun.projectiles) - gun.projectiles
else
ammo_needed = gun.projectiles_cache_max - gun.projectiles_cache
if(!ammo_needed)
continue
- if(ammo_needed < A.rounds)
- if(A.direct_load)
+
+ if(ammo_needed < ammo.rounds)
+ if(ammo.direct_load)
gun.projectiles = gun.projectiles + ammo_needed
else
gun.projectiles_cache = gun.projectiles_cache + ammo_needed
- playsound(get_turf(user),A.load_audio,50,TRUE)
- to_chat(user, span_notice("You add [ammo_needed] [A.ammo_type][ammo_needed > 1?"s":""] to \the [gun]"))
- A.rounds = A.rounds - ammo_needed
- if(A.custom_materials) //Change material content of the ammo box according to the amount of ammo deposited into the weapon
+ playsound(get_turf(user), ammo.load_audio, 50, TRUE)
+ to_chat(user, span_notice("You add [ammo_needed] [ammo.ammo_type][ammo_needed > 1 ? "s" : ""] to \the [gun]"))
+ ammo.rounds = ammo.rounds - ammo_needed
+ if(ammo.custom_materials) //Change material content of the ammo box according to the amount of ammo deposited into the weapon
/// list of materials contained in the ammo box after we put it through the equation so we can stick this list into set_custom_materials()
var/list/new_material_content = list()
- for(var/datum/material/current_material in A.custom_materials)
+ for(var/datum/material/current_material in ammo.custom_materials)
if(istype(current_material, /datum/material/iron)) //we can flatten an empty ammo box into a sheet of iron (2000 units) so we have to make sure the box always has this amount at minimum
- new_material_content[current_material] = (A.custom_materials[current_material] - SHEET_MATERIAL_AMOUNT) * (A.rounds / initial(A.rounds)) + SHEET_MATERIAL_AMOUNT
+ new_material_content[current_material] = (ammo.custom_materials[current_material] - SHEET_MATERIAL_AMOUNT) * (ammo.rounds / initial(ammo.rounds)) + SHEET_MATERIAL_AMOUNT
else
- new_material_content[current_material] = A.custom_materials[current_material] * (A.rounds / initial(A.rounds))
- A.set_custom_materials(new_material_content)
- A.update_name()
+ new_material_content[current_material] = ammo.custom_materials[current_material] * (ammo.rounds / initial(ammo.rounds))
+ ammo.set_custom_materials(new_material_content)
+ ammo.update_name()
return TRUE
- if(A.direct_load)
- gun.projectiles = gun.projectiles + A.rounds
+ if(ammo.direct_load)
+ gun.projectiles = gun.projectiles + ammo.rounds
else
- gun.projectiles_cache = gun.projectiles_cache + A.rounds
- playsound(get_turf(user),A.load_audio,50,TRUE)
- to_chat(user, span_notice("You add [A.rounds] [A.ammo_type][A.rounds > 1?"s":""] to \the [gun]"))
- if(A.qdel_on_empty)
- qdel(A)
+ gun.projectiles_cache = gun.projectiles_cache + ammo.rounds
+
+ playsound(get_turf(user),ammo.load_audio,50,TRUE)
+ to_chat(user, span_notice("You add [ammo.rounds] [ammo.ammo_type][ammo.rounds > 1 ? "s" : ""] to \the [gun]"))
+ if(ammo.qdel_on_empty)
+ qdel(ammo)
return TRUE
- A.rounds = 0
- A.set_custom_materials(list(/datum/material/iron=SHEET_MATERIAL_AMOUNT))
- A.update_appearance()
+ ammo.rounds = 0
+ ammo.set_custom_materials(list(/datum/material/iron=SHEET_MATERIAL_AMOUNT))
+ ammo.update_appearance()
return TRUE
+
if(!fail_chat_override)
if(found_gun)
balloon_alert(user, "ammo storage is full!")
diff --git a/code/modules/vehicles/mecha/mecha_mob_interaction.dm b/code/modules/vehicles/mecha/mecha_mob_interaction.dm
index 296352dc8c4..3b341120231 100644
--- a/code/modules/vehicles/mecha/mecha_mob_interaction.dm
+++ b/code/modules/vehicles/mecha/mecha_mob_interaction.dm
@@ -197,7 +197,6 @@
if(driver.client)
driver.update_mouse_pointer()
driver.client.view_size.resetToDefault()
- zoom_mode = FALSE
. = ..()
update_appearance()
diff --git a/code/modules/vehicles/mecha/mecha_movement.dm b/code/modules/vehicles/mecha/mecha_movement.dm
index 5477f5f2581..d0121a1b333 100644
--- a/code/modules/vehicles/mecha/mecha_movement.dm
+++ b/code/modules/vehicles/mecha/mecha_movement.dm
@@ -75,49 +75,24 @@
/obj/vehicle/sealed/mecha/vehicle_move(direction, forcerotate = FALSE)
if(!COOLDOWN_FINISHED(src, cooldown_vehicle_move))
return FALSE
+
COOLDOWN_START(src, cooldown_vehicle_move, movedelay)
+
if(completely_disabled)
return FALSE
+
if(!direction)
return FALSE
+
+ if(!can_move(direction))
+ return FALSE
+
if(ismovable(loc)) //Mech is inside an object, tell it we moved
var/atom/loc_atom = loc
return loc_atom.relaymove(src, direction)
- var/obj/machinery/portable_atmospherics/canister/internal_tank = get_internal_tank()
- if(internal_tank?.connected_port)
- if(TIMER_COOLDOWN_FINISHED(src, COOLDOWN_MECHA_MESSAGE))
- to_chat(occupants, "[icon2html(src, occupants)][span_warning("Unable to move while connected to the air system port!")]")
- TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS)
- return FALSE
+
if(!Process_Spacemove(direction))
return FALSE
- if(zoom_mode)
- if(TIMER_COOLDOWN_FINISHED(src, COOLDOWN_MECHA_MESSAGE))
- to_chat(occupants, "[icon2html(src, occupants)][span_warning("Unable to move while in zoom mode!")]")
- TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS)
- return FALSE
- var/list/missing_parts = list()
- if(isnull(cell))
- missing_parts += "power cell"
- if(isnull(capacitor))
- missing_parts += "capacitor"
- if(isnull(servo))
- missing_parts += "servo"
- if(length(missing_parts))
- if(TIMER_COOLDOWN_FINISHED(src, COOLDOWN_MECHA_MESSAGE))
- to_chat(occupants, "[icon2html(src, occupants)][span_warning("Missing [english_list(missing_parts)].")]")
- TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS)
- return FALSE
- if((step_energy_drain != 0) && !use_energy(step_energy_drain))
- if(TIMER_COOLDOWN_FINISHED(src, COOLDOWN_MECHA_MESSAGE))
- to_chat(occupants, "[icon2html(src, occupants)][span_warning("Insufficient power to move!")]")
- TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS)
- return FALSE
- if(lavaland_only && is_mining_level(z))
- if(TIMER_COOLDOWN_FINISHED(src, COOLDOWN_MECHA_MESSAGE))
- to_chat(occupants, "[icon2html(src, occupants)][span_warning("Invalid Environment.")]")
- TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS)
- return FALSE
var/olddir = dir
@@ -148,20 +123,46 @@
//Otherwise just walk normally
. = try_step_multiz(direction)
- if(phasing)
- use_energy(phasing_energy_drain)
if(strafe)
setDir(olddir)
+/// Check if anything is blocking our movement
+/obj/vehicle/sealed/mecha/proc/can_move(direction)
+ var/obj/machinery/portable_atmospherics/canister/internal_tank = get_internal_tank()
+ if(internal_tank?.connected_port)
+ if(TIMER_COOLDOWN_FINISHED(src, COOLDOWN_MECHA_MESSAGE))
+ to_chat(occupants, "[icon2html(src, occupants)][span_warning("Unable to move while connected to the air system port!")]")
+ TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS)
+ return FALSE
+
+ var/list/missing_parts = list()
+ if(isnull(cell))
+ missing_parts += "power cell"
+ if(isnull(capacitor))
+ missing_parts += "capacitor"
+ if(isnull(servo))
+ missing_parts += "servo"
+
+ if(length(missing_parts))
+ if(TIMER_COOLDOWN_FINISHED(src, COOLDOWN_MECHA_MESSAGE))
+ to_chat(occupants, "[icon2html(src, occupants)][span_warning("Missing [english_list(missing_parts)].")]")
+ TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS)
+ return FALSE
+
+ if((step_energy_drain != 0) && !use_energy(step_energy_drain))
+ if(TIMER_COOLDOWN_FINISHED(src, COOLDOWN_MECHA_MESSAGE))
+ to_chat(occupants, "[icon2html(src, occupants)][span_warning("Insufficient power to move!")]")
+ TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS)
+ return FALSE
+ return TRUE
+
/obj/vehicle/sealed/mecha/Bump(atom/obstacle)
. = ..()
- if(phasing) //Theres only one cause for phasing canpass fails
- to_chat(occupants, "[icon2html(src, occupants)][span_warning("A dull, universal force is preventing you from [phasing] here!")]")
- spark_system.start()
- return
if(.) //mech was thrown/door/whatever
return
+ try_bumpsmash(obstacle)
+/obj/vehicle/sealed/mecha/proc/try_bumpsmash(atom/obstacle)
// Whether or not we're on our mecha melee cooldown
var/on_cooldown = TIMER_COOLDOWN_RUNNING(src, COOLDOWN_MECHA_MELEE_ATTACK)
@@ -172,6 +173,7 @@
TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MELEE_ATTACK, melee_cooldown * 0.3)
if(!obstacle || obstacle.CanPass(src, get_dir(obstacle, src) || dir)) // The else is in case the obstacle is in the same turf.
step(src,dir)
+
if(isobj(obstacle))
var/obj/obj_obstacle = obstacle
if(!obj_obstacle.anchored && obj_obstacle.move_resist <= move_force)
diff --git a/code/modules/vehicles/mecha/working/clarke.dm b/code/modules/vehicles/mecha/working/clarke.dm
index 98907b8a26e..5a484fbe07b 100644
--- a/code/modules/vehicles/mecha/working/clarke.dm
+++ b/code/modules/vehicles/mecha/working/clarke.dm
@@ -47,19 +47,13 @@
. = ..()
ore_box = new(src)
-/obj/vehicle/sealed/mecha/clarke/atom_destruction()
- if(ore_box)
- INVOKE_ASYNC(ore_box, TYPE_PROC_REF(/obj/structure/ore_box, dump_box_contents))
- return ..()
-
/obj/vehicle/sealed/mecha/clarke/generate_actions()
. = ..()
initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_search_ruins)
initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/clarke_scoop_body)
-//Ore Box Controls
-
-///Special equipment for the Clarke mech, handles moving ore without giving the mech a hydraulic clamp and cargo compartment.
+// Ore Box Controls
+/// Special equipment for the Clarke mech, handles moving ore without giving the mech a hydraulic clamp and cargo compartment.
/obj/item/mecha_parts/mecha_equipment/orebox_manager
name = "ore storage module"
desc = "An automated ore box management device, complete with a built-in boulder processor."