diff --git a/code/ATMOSPHERICS/_atmospherics_helpers.dm b/code/ATMOSPHERICS/_atmospherics_helpers.dm index 1f73566fbce..14fc5a496bb 100644 --- a/code/ATMOSPHERICS/_atmospherics_helpers.dm +++ b/code/ATMOSPHERICS/_atmospherics_helpers.dm @@ -29,8 +29,6 @@ if (source.total_moles < MINIMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing return -1 - //var/source_moles_initial = source.total_moles - if (isnull(transfer_moles)) transfer_moles = source.total_moles else @@ -69,6 +67,40 @@ return power_draw +//Gas 'pumping' proc for the case where the gas flow is passive and driven entirely by pressure differences (but still one-way). +/proc/pump_gas_passive(var/obj/machinery/M, var/datum/gas_mixture/source, var/datum/gas_mixture/sink, var/transfer_moles = null) + if (source.total_moles < MINUMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing + return -1 + + if (isnull(transfer_moles)) + transfer_moles = source.total_moles + else + transfer_moles = min(source.total_moles, transfer_moles) + + var/equalize_moles = calculate_equalize_moles(source, sink) + transfer_moles = min(transfer_moles, equalize_moles) + + if (transfer_moles < MINUMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing + return -1 + + //Update flow rate meter + if (istype(M, /obj/machinery/atmospherics)) + var/obj/machinery/atmospherics/A = M + A.last_flow_rate = (transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here + if (A.debug) + A.visible_message("[A]: moles transferred = [transfer_moles] mol") + + if (istype(M, /obj/machinery/portable_atmospherics)) + var/obj/machinery/portable_atmospherics/P = M + P.last_flow_rate = (transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here + + var/datum/gas_mixture/removed = source.remove(transfer_moles) + if(!removed) //Just in case + return -1 + sink.merge(removed) + + return 0 + //Generalized gas scrubbing proc. //Selectively moves specified gasses one gas_mixture to another and returns the amount of power needed (assuming 1 second), or -1 if no gas was filtered. //filtering - A list of gasids to be scrubbed from source @@ -400,4 +432,17 @@ var/output_volume = (sink.volume * sink.group_multiplier) + sink_volume_mod //get the number of moles that would have to be transfered to bring sink to the target pressure - return pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION) \ No newline at end of file + return pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION) + +//Calculates the APPROXIMATE amount of moles that would need to be transferred to bring source and sink to the same pressure +/proc/calculate_equalize_moles(datum/gas_mixture/source, datum/gas_mixture/sink) + if(source.temperature == 0) return 0 + + //Make the approximation that the sink temperature is unchanged after transferring gas + var/source_volume = source.volume * source.group_multiplier + var/sink_volume = sink.volume * sink.group_multiplier + + var/source_pressure = source.return_pressure() + var/sink_pressure = sink.return_pressure() + + return (source_pressure - sink_pressure)/(R_IDEAL_GAS_EQUATION * (source.temperature/source_volume + sink.temperature/sink_volume)) diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index 51035c5d760..b0ef990145c 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -80,7 +80,7 @@ transfer_moles = min(transfer_moles, calculate_transfer_moles(air1, air2, pressure_delta, (network2)? network2.volume : 0)) //pump_gas() will return a negative number if no flow occurred - returnval = pump_gas(src, air1, air2, transfer_moles, available_power=0) //available_power=0 means we only move gas if it would flow naturally + returnval = pump_gas_passive(src, air1, air2, transfer_moles) if (returnval >= 0) if(network1) diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 6026166b6b8..47bf531d5eb 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -8,6 +8,7 @@ var/valve_open = 0 var/release_pressure = ONE_ATMOSPHERE + var/release_flow_rate = ATMOS_DEFAULT_VOLUME_PUMP //in L/s var/canister_color = "yellow" var/can_label = 1 @@ -178,21 +179,15 @@ update_flag environment = loc.return_air() var/env_pressure = environment.return_pressure() - var/pressure_delta = min(release_pressure - env_pressure, (air_contents.return_pressure() - env_pressure)/2) - //Can not have a pressure delta that would cause environment pressure > tank pressure + var/pressure_delta = release_pressure - env_pressure - var/transfer_moles = 0 if((air_contents.temperature > 0) && (pressure_delta > 0)) - transfer_moles = pressure_delta*environment.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION) + var/transfer_moles = calculate_transfer_moles(air_contents, environment, pressure_delta) + transfer_moles = min(transfer_moles, (release_flow_rate/air_contents.volume)*air_contents.total_moles) //flow rate limit - //Actually transfer the gas - var/datum/gas_mixture/removed = air_contents.remove(transfer_moles) - - if(holding) - environment.merge(removed) - else - loc.assume_air(removed) - src.update_icon() + var/returnval = pump_gas_passive(src, air_contents, environment, transfer_moles) + if(returnval >= 0) + src.update_icon() if(air_contents.return_pressure() < 1) can_label = 1 diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 758d50ebdd1..c09f06372ca 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -59,20 +59,10 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT var/list/possible_events = list() for(var/datum/event_meta/EM in available_events) - var/event_weight = EM.get_weight(active_with_role) - if(EM.enabled && event_weight) + var/event_weight = get_weight(EM, active_with_role) + if(event_weight) possible_events[EM] = event_weight - for(var/event_meta in last_event_time) if(possible_events[event_meta]) - var/time_passed = world.time - event_last_fired[event_meta] - var/weight_modifier = max(0, (config.expected_round_length - time_passed) / 300) - var/new_weight = max(possible_events[event_meta] - weight_modifier, 0) - - if(new_weight) - possible_events[event_meta] = new_weight - else - possible_events -= event_meta - if(possible_events.len == 0) return null @@ -81,6 +71,19 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT available_events -= picked_event return picked_event +/datum/event_container/proc/get_weight(var/datum/event_meta/EM, var/list/active_with_role) + if(!EM.enabled) + return 0 + + var/weight = EM.get_weight(active_with_role) + var/last_time = last_event_time[EM] + if(last_time) + var/time_passed = world.time - last_time + var/weight_modifier = max(0, round((config.expected_round_length - time_passed) / 300)) + weight = weight - weight_modifier + + return weight + /datum/event_container/proc/set_event_delay() // If the next event time has not yet been set and we have a custom first time start if(next_event_time == 0 && config.event_first_run[severity]) diff --git a/code/modules/events/event_manager.dm b/code/modules/events/event_manager.dm index 85ee89a89ab..f56bb52d7c4 100644 --- a/code/modules/events/event_manager.dm +++ b/code/modules/events/event_manager.dm @@ -89,6 +89,7 @@ html += "
| Name | Weight | MinWeight | MaxWeight | OneShot | Enabled | CurrWeight | Remove |
| [EM.name] | " @@ -97,7 +98,7 @@ html += "[EM.max_weight] | " html += "[EM.one_shot] | " html += "[EM.enabled] | " - html += "[EM.get_weight(number_active_with_role())] | " + html += "[selected_event_container.get_weight(EM, active_with_role)] | " html += "Remove | " html += "