mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
Overclocked Vent Pumps (#78583)
## About The Pull Request Adds in the capability for vent pumps to be overclocked, which allows them to ignore pressure differentials and move their entire air contents each process. Doing this causes them to take damage over time however which causes them to be less effective in normal operation. **the penalty for low integrity does not apply to fans which are overclocked, however reaching 0 integrity will still disable them** ## Why It's Good For The Game Engineers got used to vent pumps being stupid and ignoring pressure, now its a feature not a bug. ## Changelog 🆑 add: Vent Pumps can now be overclocked, do some light reading in the air alarm to figure out what this means. balance: Vent Pumps now have fan integrity, the damaging of which reduces their ability to move air. sound: Overclocking sounds, including spool, stop, and loop /🆑 --------- Co-authored-by: Emmett Gaines <ninjanomnom@gmail.com>
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
/datum/looping_sound/vent_pump_overclock
|
||||
start_sound = 'sound/machines/fan_start.ogg'
|
||||
start_length = 1.5 SECONDS
|
||||
end_sound = 'sound/machines/fan_stop.ogg'
|
||||
end_sound = 1.5 SECONDS
|
||||
mid_sounds = 'sound/machines/fan_loop.ogg'
|
||||
mid_length = 2 SECONDS
|
||||
@@ -51,6 +51,13 @@
|
||||
if(atom_integrity == new_value)
|
||||
return
|
||||
atom_integrity = new_value
|
||||
on_update_integrity(old_value, new_value)
|
||||
return new_value
|
||||
|
||||
/// Handle updates to your atom's integrity
|
||||
/atom/proc/on_update_integrity(old_value, new_value)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_INTEGRITY_CHANGED, old_value, new_value)
|
||||
|
||||
/// This mostly exists to keep atom_integrity private. Might be useful in the future.
|
||||
@@ -58,6 +65,11 @@
|
||||
SHOULD_BE_PURE(TRUE)
|
||||
return atom_integrity
|
||||
|
||||
/// Similar to get_integrity, but returns the percentage as [0-1] instead.
|
||||
/atom/proc/get_integrity_percentage()
|
||||
SHOULD_BE_PURE(TRUE)
|
||||
return round(atom_integrity / max_integrity, 0.01)
|
||||
|
||||
///returns the damage value of the attack after processing the atom's various armor protections
|
||||
/atom/proc/run_atom_armor(damage_amount, damage_type, damage_flag = 0, attack_dir, armour_penetration = 0)
|
||||
if(!uses_integrity)
|
||||
|
||||
@@ -287,6 +287,8 @@ GLOBAL_LIST_EMPTY_TYPED(air_alarms, /obj/machinery/airalarm)
|
||||
"refID" = REF(vent),
|
||||
"long_name" = sanitize(vent.name),
|
||||
"power" = vent.on,
|
||||
"overclock" = vent.fan_overclocked,
|
||||
"integrity" = vent.get_integrity_percentage(),
|
||||
"checks" = vent.pressure_checks,
|
||||
"excheck" = vent.pressure_checks & ATMOS_EXTERNAL_BOUND,
|
||||
"incheck" = vent.pressure_checks & ATMOS_INTERNAL_BOUND,
|
||||
@@ -356,6 +358,14 @@ GLOBAL_LIST_EMPTY_TYPED(air_alarms, /obj/machinery/airalarm)
|
||||
powering.on = !!params["val"]
|
||||
powering.atmos_conditions_changed()
|
||||
powering.update_appearance(UPDATE_ICON)
|
||||
|
||||
if("overclock")
|
||||
if(isnull(vent))
|
||||
return TRUE
|
||||
vent.toggle_overclock()
|
||||
vent.update_appearance(UPDATE_ICON)
|
||||
return TRUE
|
||||
|
||||
if ("direction")
|
||||
if (isnull(vent))
|
||||
return TRUE
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
shift_underlay_only = FALSE
|
||||
pipe_state = "uvent"
|
||||
vent_movement = VENTCRAWL_ALLOWED | VENTCRAWL_CAN_SEE | VENTCRAWL_ENTRANCE_ALLOWED
|
||||
// vents are more complex machinery and so are less resistant to damage
|
||||
max_integrity = 100
|
||||
|
||||
///Direction of pumping the gas (ATMOS_DIRECTION_RELEASING or ATMOS_DIRECTION_SIPHONING)
|
||||
var/pump_direction = ATMOS_DIRECTION_RELEASING
|
||||
@@ -34,6 +36,18 @@
|
||||
///area this vent is assigned to
|
||||
var/area/assigned_area
|
||||
|
||||
/// Is this vent currently overclocked, removing pressure limits but damaging the fan?
|
||||
var/fan_overclocked = FALSE
|
||||
|
||||
/// Rate of damage per atmos process to the fan when overclocked. Set to 0 to disable damage.
|
||||
var/fan_damage_rate = 0.5
|
||||
|
||||
/// The cached string we show for examine that lets you know how fucked up the fan is.
|
||||
var/examine_condition
|
||||
|
||||
/// Datum for managing the overclock sound loop
|
||||
var/datum/looping_sound/vent_pump_overclock/sound_loop
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/Initialize(mapload)
|
||||
if(!id_tag)
|
||||
id_tag = assign_random_name()
|
||||
@@ -42,16 +56,44 @@
|
||||
tool_screentips = string_assoc_nested_list(list(
|
||||
TOOL_MULTITOOL = list(
|
||||
SCREENTIP_CONTEXT_LMB = "Log to link later with air sensor",
|
||||
)
|
||||
),
|
||||
TOOL_SCREWDRIVER = list(
|
||||
SCREENTIP_CONTEXT_LMB = "Repair",
|
||||
),
|
||||
))
|
||||
AddElement(/datum/element/contextual_screentip_tools, tool_screentips)
|
||||
. = ..()
|
||||
sound_loop = new(src)
|
||||
assign_to_area()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/on_update_integrity(old_value, new_value)
|
||||
. = ..()
|
||||
var/condition_string
|
||||
switch(get_integrity_percentage())
|
||||
if(1)
|
||||
condition_string = "perfect"
|
||||
if(0.75 to 0.99)
|
||||
condition_string = "good"
|
||||
if(0.50 to 0.74)
|
||||
condition_string = "okay"
|
||||
if(0.25 to 0.49)
|
||||
condition_string = "bad"
|
||||
else
|
||||
condition_string = "terrible"
|
||||
examine_condition = "The fan is in [condition_string] condition."
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/examine(mob/user)
|
||||
. = ..()
|
||||
. += span_notice("You can link it with an air sensor using a multitool.")
|
||||
|
||||
if(fan_overclocked)
|
||||
. += span_warning("It is currently overclocked causing it to take damage over time.")
|
||||
|
||||
if(get_integrity() > 0)
|
||||
. += span_notice(examine_condition)
|
||||
else
|
||||
. += span_warning("The fan is broken.")
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/multitool_act(mob/living/user, obj/item/multitool/multi_tool)
|
||||
if(istype(multi_tool.buffer, /obj/machinery/air_sensor))
|
||||
var/obj/machinery/air_sensor/sensor = multi_tool.buffer
|
||||
@@ -63,8 +105,33 @@
|
||||
multi_tool.set_buffer(src)
|
||||
return TOOL_ACT_TOOLTYPE_SUCCESS
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/screwdriver_act(mob/living/user, obj/item/tool)
|
||||
var/time_to_repair = (10 SECONDS) * (1 - get_integrity_percentage())
|
||||
if(!time_to_repair)
|
||||
return FALSE
|
||||
|
||||
balloon_alert(user, "repairing vent...")
|
||||
if(do_after(user, time_to_repair, src))
|
||||
balloon_alert(user, "vent repaired")
|
||||
repair_damage(max_integrity)
|
||||
|
||||
else
|
||||
balloon_alert(user, "interrupted!")
|
||||
return TOOL_ACT_TOOLTYPE_SUCCESS
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/atom_fix()
|
||||
set_is_operational(TRUE)
|
||||
update_appearance()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/atom_break(damage_flag)
|
||||
set_is_operational(FALSE)
|
||||
update_appearance()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/Destroy()
|
||||
disconnect_from_area()
|
||||
QDEL_NULL(sound_loop)
|
||||
|
||||
var/area/vent_area = get_area(src)
|
||||
if(vent_area)
|
||||
@@ -107,6 +174,17 @@
|
||||
. = ..()
|
||||
disconnect_from_area(area_to_unregister)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/update_overlays()
|
||||
. = ..()
|
||||
if(!powered())
|
||||
return
|
||||
|
||||
if(get_integrity() <= 0)
|
||||
. += mutable_appearance(icon, "broken")
|
||||
|
||||
else if(fan_overclocked)
|
||||
. += mutable_appearance(icon, "overclocked")
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/update_icon_nopipes()
|
||||
cut_overlays()
|
||||
if(showpipe)
|
||||
@@ -144,6 +222,20 @@
|
||||
else // pump_direction == SIPHONING
|
||||
icon_state = "vent_in"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/proc/toggle_overclock(from_break = FALSE)
|
||||
fan_overclocked = !fan_overclocked
|
||||
|
||||
if(from_break)
|
||||
playsound(src, 'sound/machines/fan_break.ogg', 100)
|
||||
fan_overclocked = FALSE
|
||||
|
||||
if(fan_overclocked)
|
||||
sound_loop.start()
|
||||
else
|
||||
sound_loop.stop()
|
||||
|
||||
update_appearance()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/process_atmos()
|
||||
if(!is_operational)
|
||||
return
|
||||
@@ -154,6 +246,17 @@
|
||||
var/turf/open/us = loc
|
||||
if(!istype(us))
|
||||
return
|
||||
|
||||
var/current_integrity = get_integrity()
|
||||
if(fan_overclocked)
|
||||
take_damage(fan_damage_rate, sound_effect=FALSE)
|
||||
if(current_integrity == 0)
|
||||
on = FALSE
|
||||
set_is_operational(FALSE)
|
||||
toggle_overclock(from_break = TRUE)
|
||||
return
|
||||
|
||||
var/percent_integrity = get_integrity_percentage()
|
||||
var/datum/gas_mixture/air_contents = airs[1]
|
||||
var/datum/gas_mixture/environment = us.return_air()
|
||||
var/environment_pressure = environment.return_pressure()
|
||||
@@ -168,9 +271,13 @@
|
||||
|
||||
if(pressure_delta > 0)
|
||||
if(air_contents.temperature > 0)
|
||||
if(environment_pressure >= 50 * ONE_ATMOSPHERE)
|
||||
if(!fan_overclocked && (environment_pressure >= 50 * ONE_ATMOSPHERE))
|
||||
return FALSE
|
||||
|
||||
var/transfer_moles = (pressure_delta * environment.volume) / (air_contents.temperature * R_IDEAL_GAS_EQUATION)
|
||||
if(!fan_overclocked && (percent_integrity < 1))
|
||||
transfer_moles *= percent_integrity
|
||||
|
||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
||||
|
||||
if(!removed || !removed.total_moles())
|
||||
@@ -187,9 +294,12 @@
|
||||
pressure_delta = min(pressure_delta, (internal_pressure_bound - air_contents.return_pressure()))
|
||||
|
||||
if(pressure_delta > 0 && environment.temperature > 0)
|
||||
if(air_contents.return_pressure() >= 50 * ONE_ATMOSPHERE)
|
||||
if(!fan_overclocked && (air_contents.return_pressure() >= 50 * ONE_ATMOSPHERE))
|
||||
return FALSE
|
||||
|
||||
var/transfer_moles = (pressure_delta * air_contents.volume) / (environment.temperature * R_IDEAL_GAS_EQUATION)
|
||||
if(!fan_overclocked && (percent_integrity < 1))
|
||||
transfer_moles *= percent_integrity
|
||||
|
||||
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 99 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1459,6 +1459,7 @@
|
||||
#include "code\datums\looping_sounds\item_sounds.dm"
|
||||
#include "code\datums\looping_sounds\machinery_sounds.dm"
|
||||
#include "code\datums\looping_sounds\music.dm"
|
||||
#include "code\datums\looping_sounds\vents.dm"
|
||||
#include "code\datums\looping_sounds\weather.dm"
|
||||
#include "code\datums\mapgen\_MapGenerator.dm"
|
||||
#include "code\datums\mapgen\CaveGenerator.dm"
|
||||
|
||||
@@ -8,6 +8,8 @@ export type VentProps = {
|
||||
refID: string;
|
||||
long_name: string;
|
||||
power: BooleanLike;
|
||||
overclock: BooleanLike;
|
||||
integrity: number;
|
||||
checks: number;
|
||||
excheck: BooleanLike;
|
||||
incheck: BooleanLike;
|
||||
@@ -37,6 +39,8 @@ export const Vent = (props: VentProps, context) => {
|
||||
refID,
|
||||
long_name,
|
||||
power,
|
||||
overclock,
|
||||
integrity,
|
||||
checks,
|
||||
excheck,
|
||||
incheck,
|
||||
@@ -50,19 +54,41 @@ export const Vent = (props: VentProps, context) => {
|
||||
<Section
|
||||
title={decodeHtmlEntities(long_name)}
|
||||
buttons={
|
||||
<Button
|
||||
icon={power ? 'power-off' : 'times'}
|
||||
selected={power}
|
||||
content={power ? 'On' : 'Off'}
|
||||
onClick={() =>
|
||||
act('power', {
|
||||
ref: refID,
|
||||
val: Number(!power),
|
||||
})
|
||||
}
|
||||
/>
|
||||
<>
|
||||
<Button
|
||||
icon={power ? 'power-off' : 'times'}
|
||||
selected={power}
|
||||
disabled={integrity <= 0}
|
||||
content={power ? 'On' : 'Off'}
|
||||
onClick={() =>
|
||||
act('power', {
|
||||
ref: refID,
|
||||
val: Number(!power),
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
icon="gauge-high"
|
||||
color={overclock ? 'green' : 'yellow'}
|
||||
disabled={integrity <= 0}
|
||||
onClick={() =>
|
||||
act('overclock', {
|
||||
ref: refID,
|
||||
})
|
||||
}
|
||||
tooltip={`${overclock ? 'Disable' : 'Enable'} overclocking`}
|
||||
/>
|
||||
</>
|
||||
}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Integrity">
|
||||
<p
|
||||
title={
|
||||
'Overclocking will allow the vent to overpower extreme pressure conditions. However, it will also cause the vent to become damaged over time and eventually fail. The lower the integrity, the less effective the vent will be when in normal operation.'
|
||||
}>
|
||||
Integrity: {(integrity * 100).toFixed(2)}%
|
||||
</p>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Mode">
|
||||
<Button
|
||||
icon="sign-in-alt"
|
||||
|
||||
Reference in New Issue
Block a user