diff --git a/code/modules/heavy_vehicle/_mech_setup.dm b/code/modules/heavy_vehicle/_mech_setup.dm index 0e870814e52..2b1f8ade590 100644 --- a/code/modules/heavy_vehicle/_mech_setup.dm +++ b/code/modules/heavy_vehicle/_mech_setup.dm @@ -35,4 +35,9 @@ var/global/list/mecha_damage_overlay_cache = list() #define FRAME_REINFORCED_WELDED 3 #define FRAME_WIRED 1 -#define FRAME_WIRED_ADJUSTED 2 \ No newline at end of file +#define FRAME_WIRED_ADJUSTED 2 + +//POWER! +#define MECH_POWER_OFF 0 +#define MECH_POWER_TRANSITION 1 +#define MECH_POWER_ON 2 \ No newline at end of file diff --git a/code/modules/heavy_vehicle/components/head.dm b/code/modules/heavy_vehicle/components/head.dm index 2148b199758..318deebfa68 100644 --- a/code/modules/heavy_vehicle/components/head.dm +++ b/code/modules/heavy_vehicle/components/head.dm @@ -62,18 +62,18 @@ camera = locate() in src software = locate() in src -/obj/item/mech_component/sensors/proc/get_sight() +/obj/item/mech_component/sensors/proc/get_sight(powered) var/flags = 0 - if(total_damage >= 0.8 * max_damage) + if((total_damage >= 0.8 * max_damage) || !powered) flags |= BLIND - else if(active_sensors) + else if(active_sensors && powered) flags |= vision_flags return flags -/obj/item/mech_component/sensors/proc/get_invisible() +/obj/item/mech_component/sensors/proc/get_invisible(powered) var/invisible = 0 - if((total_damage <= 0.8 * max_damage) && active_sensors) + if((total_damage <= 0.8 * max_damage) && active_sensors && powered) invisible = see_invisible return invisible diff --git a/code/modules/heavy_vehicle/equipment/_equipment.dm b/code/modules/heavy_vehicle/equipment/_equipment.dm index 632804a5640..385fd0ef662 100644 --- a/code/modules/heavy_vehicle/equipment/_equipment.dm +++ b/code/modules/heavy_vehicle/equipment/_equipment.dm @@ -15,6 +15,7 @@ var/passive_power_use = 0 var/active_power_use = 1 KILOWATTS var/require_adjacent = TRUE + var/active = FALSE //For gear that has an active state (ie, floodlights) /obj/item/mecha_equipment/examine(mob/user, distance) . = ..() @@ -59,12 +60,18 @@ else return 0 +/obj/item/mecha_equipment/proc/deactivate() + active = FALSE + return + /obj/item/mecha_equipment/proc/installed(var/mob/living/heavy_vehicle/_owner) owner = _owner //generally attached. Nothing should be able to grab it canremove = FALSE /obj/item/mecha_equipment/proc/uninstalled() + if(active) + deactivate() owner = null canremove = TRUE diff --git a/code/modules/heavy_vehicle/equipment/combat.dm b/code/modules/heavy_vehicle/equipment/combat.dm index 50c0fe6d56a..78b30d161ce 100644 --- a/code/modules/heavy_vehicle/equipment/combat.dm +++ b/code/modules/heavy_vehicle/equipment/combat.dm @@ -295,8 +295,15 @@ START_PROCESSING(SSprocessing, src) else STOP_PROCESSING(SSprocessing, src) + active = aura.active + passive_power_use = active ? 1 KILOWATTS : 0 owner.update_icon() +/obj/item/mecha_equipment/shield/deactivate() + if(active) + toggle() + ..() + /obj/item/mecha_equipment/shield/update_icon() . = ..() if(!aura) @@ -314,7 +321,8 @@ var/obj/item/cell/cell = owner.get_cell() var/actual_required_power = Clamp(max_charge - charge, 0, charging_rate) - charge += cell.use(actual_required_power) + if(cell) + charge += cell.use(actual_required_power) /obj/item/mecha_equipment/shield/get_hardpoint_status_value() return charge / max_charge diff --git a/code/modules/heavy_vehicle/equipment/utility.dm b/code/modules/heavy_vehicle/equipment/utility.dm index 051a2764cd0..2ef3113ac4c 100644 --- a/code/modules/heavy_vehicle/equipment/utility.dm +++ b/code/modules/heavy_vehicle/equipment/utility.dm @@ -202,10 +202,20 @@ /obj/item/mecha_equipment/light/attack_self(var/mob/user) . = ..() if(.) - on = !on + toggle() to_chat(user, "You switch \the [src] [on ? "on" : "off"].") - update_icon() - owner.update_icon() + +/obj/item/mecha_equipment/light/proc/toggle() + on = !on + update_icon() + owner.update_icon() + active = on + passive_power_use = on ? 0.1 KILOWATTS : 0 + +/obj/item/mecha_equipment/light/deactivate() + if(on) + toggle() + ..() /obj/item/mecha_equipment/light/update_icon() if(on) diff --git a/code/modules/heavy_vehicle/interface/_interface.dm b/code/modules/heavy_vehicle/interface/_interface.dm index 4d2f116405a..109a15bdb10 100644 --- a/code/modules/heavy_vehicle/interface/_interface.dm +++ b/code/modules/heavy_vehicle/interface/_interface.dm @@ -21,6 +21,7 @@ i++ var/list/additional_hud_elements = list( + /obj/screen/mecha/toggle/power_control, /obj/screen/mecha/toggle/maint, /obj/screen/mecha/eject, /obj/screen/mecha/toggle/hardpoint, @@ -55,6 +56,7 @@ hud_power = new /obj/screen/mecha/power(src) hud_power.screen_loc = "EAST-1:12,CENTER-4:25" hud_elements |= hud_power + hud_power_control = locate(/obj/screen/mecha/toggle/power_control) in hud_elements refresh_hud() diff --git a/code/modules/heavy_vehicle/interface/screen_objects.dm b/code/modules/heavy_vehicle/interface/screen_objects.dm index b51cb504535..21bfecf3869 100644 --- a/code/modules/heavy_vehicle/interface/screen_objects.dm +++ b/code/modules/heavy_vehicle/interface/screen_objects.dm @@ -69,6 +69,7 @@ var/list/new_overlays = list() if(!owner.get_cell() || (owner.get_cell().charge <= 0)) overlays.Cut() + maptext = "" return maptext = "[holding.get_hardpoint_maptext()]" @@ -223,6 +224,23 @@ maptext = "MAINT" notify_user(usr, SPAN_NOTICE("Maintenance protocols [owner.maintenance_protocols ? "enabled" : "disabled"].")) +/obj/screen/mecha/toggle/power_control + name = "power control" + icon_state = "large_base" + maptext = "POWER" + maptext_x = 1 + maptext_y = 11 + +/obj/screen/mecha/toggle/power_control/toggled() + toggled = !toggled + owner.toggle_power(usr) + var/main_color = toggled ? "#d1d1d1" : "#525252" + maptext = "POWER" + +/obj/screen/mecha/toggle/power_control/update_icon() + toggled = (owner.power == MECH_POWER_ON) + return ..() + /obj/screen/mecha/toggle/hardpoint name = "toggle hardpoint lock" icon_state = "base" diff --git a/code/modules/heavy_vehicle/mech_interaction.dm b/code/modules/heavy_vehicle/mech_interaction.dm index 8ddd6fc7045..b0087494f9c 100644 --- a/code/modules/heavy_vehicle/mech_interaction.dm +++ b/code/modules/heavy_vehicle/mech_interaction.dm @@ -76,7 +76,8 @@ return if(!(get_cell()?.checked_use(arms.power_use * CELLRATE))) - to_chat(user, "Error: Power levels insufficient.") + to_chat(user, power == MECH_POWER_ON ? SPAN_WARNING("Error: Power levels insufficient.") : SPAN_WARNING("\The [src] is powered off.")) + return if(user != src) set_intent(user.a_intent) @@ -236,7 +237,6 @@ LAZYDISTINCTADD(pilots, user) sync_access() playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) - user << sound('sound/mecha/nominal.ogg',volume=50) if(user.client) user.client.screen |= hud_elements LAZYDISTINCTADD(user.additional_vision_handlers, src) update_icon() @@ -426,6 +426,8 @@ to_chat(user, "You remove \the [body.cell] from \the [src].") playsound(user.loc, thing.usesound, 50, 1) visible_message("\The [user] pries out \the [body.cell] using the \the [thing].") + power = MECH_POWER_OFF + hud_power_control.update_icon() body.cell = null return else if(istype(thing, /obj/item/cell)) diff --git a/code/modules/heavy_vehicle/mech_life.dm b/code/modules/heavy_vehicle/mech_life.dm index e7e22b28e4f..cfd6e07b10d 100644 --- a/code/modules/heavy_vehicle/mech_life.dm +++ b/code/modules/heavy_vehicle/mech_life.dm @@ -21,15 +21,25 @@ UNSETEMPTY(pilots) if(radio) - radio.on = (head?.radio && head.radio.is_functional()) + radio.on = (head?.radio && head.radio.is_functional() && get_cell()) if(camera) camera.status = (head?.camera && head.camera.is_functional()) body.update_air(hatch_closed && use_air) - if((client || LAZYLEN(pilots)) && get_cell()) - get_cell()?.drain_power(0, 0, calc_power_draw()) + var/powered = FALSE + if(get_cell()) + powered = get_cell().drain_power(0, 0, calc_power_draw()) > 0 + + if(!powered) + //Shut down all systems + if(head) + head.active_sensors = FALSE + for(var/hardpoint in hardpoints) + var/obj/item/mecha_equipment/M = hardpoints[hardpoint] + if(istype(M) && M.active && M.passive_power_use) + M.deactivate() updatehealth() if(health <= 0 && stat != DEAD) @@ -38,7 +48,7 @@ ..() lying = 0 // Fuck off, carp. - handle_vision() + handle_vision(powered) handle_hud_icons() /mob/living/heavy_vehicle/think() @@ -60,9 +70,11 @@ else walk(src, 0) // this stops them from moving -/mob/living/heavy_vehicle/get_cell() +/mob/living/heavy_vehicle/get_cell(force) RETURN_TYPE(/obj/item/cell) - return body?.cell + if(power == MECH_POWER_ON || force) //For most intents we can assume that a powered off exosuit acts as if it lacked a cell + return body ? body.cell : null + return null /mob/living/heavy_vehicle/proc/calc_power_draw() var/total_draw = 0 @@ -147,13 +159,18 @@ qdel(src) return -/mob/living/heavy_vehicle/handle_vision() +/mob/living/heavy_vehicle/handle_vision(powered) + var/was_blind = sight & BLIND if(head) - sight = head.get_sight() - see_invisible = head.get_invisible() - if(body && (body.pilot_coverage < 100 || body.transparent_cabin)) + sight = head.get_sight(powered) + see_invisible = head.get_invisible(powered) + if(!hatch_closed || (body && (body.pilot_coverage < 100 || body.transparent_cabin))) sight &= ~BLIND + if(sight & BLIND && !was_blind) + for(var/mob/pilot in pilots) + to_chat(pilot, SPAN_WARNING("The camera sensors flicker out and you lose sight of the outside world!")) + /mob/living/heavy_vehicle/additional_sight_flags() return sight diff --git a/code/modules/heavy_vehicle/mecha.dm b/code/modules/heavy_vehicle/mecha.dm index 79b3e0fd624..6b357750585 100644 --- a/code/modules/heavy_vehicle/mecha.dm +++ b/code/modules/heavy_vehicle/mecha.dm @@ -85,6 +85,9 @@ var/obj/screen/mecha/health/hud_health var/obj/screen/mecha/toggle/hatch_open/hud_open var/obj/screen/mecha/power/hud_power + var/obj/screen/mecha/toggle/power_control/hud_power_control + //POWER + var/power = MECH_POWER_OFF /mob/living/heavy_vehicle/Destroy() unassign_leader() @@ -229,6 +232,26 @@ /mob/living/heavy_vehicle/GetIdCard() return access_card +/mob/living/heavy_vehicle/proc/toggle_power(var/mob/user) + if(power == MECH_POWER_TRANSITION) + to_chat(user, SPAN_NOTICE("Power transition in progress. Please wait.")) + else if(power == MECH_POWER_ON) //Turning it off is instant + playsound(src, 'sound/mecha/mech-shutdown.ogg', 100, 0) + power = MECH_POWER_OFF + else if(get_cell(TRUE)) + //Start power up sequence + power = MECH_POWER_TRANSITION + playsound(src, 'sound/mecha/powerup.ogg', 50, 0) + if(do_after(user, 1.5 SECONDS) && power == MECH_POWER_TRANSITION) + playsound(src, 'sound/mecha/nominal.ogg', 50, 0) + power = MECH_POWER_ON + else + to_chat(user, SPAN_WARNING("You abort the powerup sequence.")) + power = MECH_POWER_OFF + hud_power_control?.queue_icon_update() + else + to_chat(user, SPAN_WARNING("Error: No power cell was detected.")) + /obj/item/device/radio/exosuit name = "exosuit radio" cell = null diff --git a/html/changelogs/geeves-mech_power_states.yml b/html/changelogs/geeves-mech_power_states.yml new file mode 100644 index 00000000000..966481de284 --- /dev/null +++ b/html/changelogs/geeves-mech_power_states.yml @@ -0,0 +1,7 @@ +author: Geeves + +delete-after: True + +changes: + - rscadd: "Added the ability to turn off exosuits. This counts as physically disconnecting the power cell, it will no longer drain, but it will also no longer charge." + - tweak: "Exosuits with open hatches will no longer cause blindness if the camera system goes down." \ No newline at end of file diff --git a/sound/mecha/mech-shutdown.ogg b/sound/mecha/mech-shutdown.ogg new file mode 100644 index 00000000000..9733bb26df5 Binary files /dev/null and b/sound/mecha/mech-shutdown.ogg differ