Merge pull request #6380 from Zuhayr/master

Calamity fix.
This commit is contained in:
Snapshot
2014-09-14 22:03:06 -07:00
4 changed files with 122 additions and 103 deletions
+75 -75
View File
@@ -1,6 +1,6 @@
/*
Atmos processes
These procs generalize various processes used by atmos machinery, such as pumping, filtering, or scrubbing gas, allowing them to be reused elsewhere.
If no gas was moved/pumped/filtered/whatever, they return a negative number.
Otherwise they return the amount of energy needed to do whatever it is they do (equivalently power if done over 1 second).
@@ -28,45 +28,45 @@
/proc/pump_gas(var/obj/machinery/M, var/datum/gas_mixture/source, var/datum/gas_mixture/sink, var/transfer_moles = null, var/available_power = null)
if (source.total_moles < MINUMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing
return -1
var/source_moles_initial = source.total_moles
//var/source_moles_initial = source.total_moles
if (!transfer_moles)
transfer_moles = source.total_moles
else
transfer_moles = min(source.total_moles, transfer_moles)
//Calculate the amount of energy required and limit transfer_moles based on available power
var/specific_power = calculate_specific_power(source, sink)/ATMOS_PUMP_EFFICIENCY //this has to be calculated before we modify any gas mixtures
if (!isnull(available_power) && specific_power > 0)
transfer_moles = min(transfer_moles, available_power / specific_power)
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]: source entropy: [round(source.specific_entropy(), 0.01)] J/Kmol --> sink entropy: [round(sink.specific_entropy(), 0.01)] J/Kmol")
A.visible_message("[A]: specific entropy change = [round(sink.specific_entropy() - source.specific_entropy(), 0.01)] J/Kmol")
A.visible_message("[A]: specific power = [round(specific_power, 0.1)] W/mol")
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
var/power_draw = specific_power*transfer_moles
sink.merge(removed)
return power_draw
//Generalized gas scrubbing proc.
@@ -78,42 +78,42 @@
if (source.total_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
return -1
var/source_moles_initial = source.total_moles
//var/source_moles_initial = source.total_moles
filtering = filtering & source.gas //only filter gasses that are actually there. DO NOT USE &=
//Determine the specific power of each filterable gas type, and the total amount of filterable gas (gasses selected to be scrubbed)
var/total_filterable_moles = 0 //the total amount of filterable gas
var/list/specific_power_gas = list() //the power required to remove one mole of pure gas, for each gas type
for (var/g in filtering)
if (source.gas[g] < MINUMUM_MOLES_TO_FILTER)
continue
var/specific_power = calculate_specific_power_gas(g, source, sink)/ATMOS_FILTER_EFFICIENCY
specific_power_gas[g] = specific_power
total_filterable_moles += source.gas[g]
if (total_filterable_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
return -1
//now that we know the total amount of filterable gas, we can calculate the amount of power needed to scrub one mole of gas
var/total_specific_power = 0 //the power required to remove one mole of filterable gas
for (var/g in filtering)
var/ratio = source.gas[g]/total_filterable_moles //this converts the specific power per mole of pure gas to specific power per mole of scrubbed gas
total_specific_power = specific_power_gas[g]*ratio
//Figure out how much of each gas to filter
if (!total_transfer_moles)
total_transfer_moles = total_filterable_moles
else
total_transfer_moles = min(total_transfer_moles, total_filterable_moles)
//limit transfer_moles based on available power
if (!isnull(available_power) && total_specific_power > 0)
total_transfer_moles = min(total_transfer_moles, available_power/total_specific_power)
if (total_transfer_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
return -1
//Update flow rate var
if (istype(M, /obj/machinery/atmospherics))
var/obj/machinery/atmospherics/A = M
@@ -121,27 +121,27 @@
if (istype(M, /obj/machinery/portable_atmospherics))
var/obj/machinery/portable_atmospherics/P = M
P.last_flow_rate = (total_transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here
var/power_draw = 0
for (var/g in filtering)
var/transfer_moles = source.gas[g]
//filter gas in proportion to the mole ratio
transfer_moles = min(transfer_moles, total_transfer_moles*(source.gas[g]/total_filterable_moles))
//use update=0. All the filtered gasses are supposed to be added simultaneously, so we update after the for loop.
source.adjust_gas(g, -transfer_moles, update=0)
sink.adjust_gas_temp(g, transfer_moles, source.temperature, update=0)
power_draw += specific_power_gas[g]*transfer_moles
//Remix the resulting gases
sink.update_values()
source.update_values()
return power_draw
//Generalized gas filtering proc.
//Filtering is a bit different from scrubbing. Instead of selectively moving the targeted gas types from one gas mix to another, filtering splits
//Filtering is a bit different from scrubbing. Instead of selectively moving the targeted gas types from one gas mix to another, filtering splits
//the input gas into two outputs: one that contains /only/ the targeted gas types, and another that completely clean of the targeted gas types.
//filtering - A list of gasids to be filtered. These gasses get moved to sink_filtered, while the other gasses get moved to sink_clean.
//total_transfer_moles - Limits the amount of moles to input. The actual amount of gas filtered may also be limited by available_power, if given.
@@ -152,7 +152,7 @@
var/source_moles_initial = source.total_moles
filtering = filtering & source.gas //only filter gasses that are actually there. DO NOT USE &=
var/total_specific_power = 0 //the power required to remove one mole of input gas
var/total_filterable_moles = 0 //the total amount of filterable gas
var/total_unfilterable_moles = 0 //the total amount of non-filterable gas
@@ -160,30 +160,30 @@
for (var/g in source.gas)
if (source.gas[g] < MINUMUM_MOLES_TO_FILTER)
continue
if (g in filtering)
specific_power_gas[g] = calculate_specific_power_gas(g, source, sink_filtered)/ATMOS_FILTER_EFFICIENCY
total_filterable_moles += source.gas[g]
else
specific_power_gas[g] = calculate_specific_power_gas(g, source, sink_clean)/ATMOS_FILTER_EFFICIENCY
total_unfilterable_moles += source.gas[g]
var/ratio = source.gas[g]/source.total_moles //converts the specific power per mole of pure gas to specific power per mole of input gas mix
total_specific_power = specific_power_gas[g]*ratio
//Figure out how much of each gas to filter
if (!total_transfer_moles)
total_transfer_moles = source.total_moles
else
total_transfer_moles = min(total_transfer_moles, source.total_moles)
//limit transfer_moles based on available power
if (!isnull(available_power) && total_specific_power > 0)
total_transfer_moles = min(total_transfer_moles, available_power/total_specific_power)
if (total_transfer_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
return -1
//Update flow rate var
if (istype(M, /obj/machinery/atmospherics))
var/obj/machinery/atmospherics/A = M
@@ -191,18 +191,18 @@
if (istype(M, /obj/machinery/portable_atmospherics))
var/obj/machinery/portable_atmospherics/P = M
P.last_flow_rate = (total_transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here
var/datum/gas_mixture/removed = source.remove(total_transfer_moles)
if (!removed) //Just in case
return -1
var/filtered_power_used = 0 //power used to move filterable gas to sink_filtered
var/unfiltered_power_used = 0 //power used to move unfilterable gas to sink_clean
var/filtered_heat = 0
//var/a = 0
for (var/g in removed.gas)
var/power_used = specific_power_gas[g]*removed.gas[g]
if (g in filtering)
//use update=0. All the filtered gasses are supposed to be added simultaneously, so we update after the for loop.
removed.adjust_gas(g, -removed.gas[g], update=0)
@@ -212,12 +212,12 @@
//a += (removed.gas[g] / source.total_moles)
else
unfiltered_power_used += power_used
sink_filtered.update_values()
removed.update_values()
sink_clean.merge(removed)
return filtered_power_used + unfiltered_power_used
//For omni devices. Instead filtering is an associative list mapping gasids to gas mixtures.
@@ -229,7 +229,7 @@
var/source_moles_initial = source.total_moles
filtering = filtering & source.gas //only filter gasses that are actually there. DO NOT USE &=
var/total_specific_power = 0 //the power required to remove one mole of input gas
var/total_filterable_moles = 0 //the total amount of filterable gas
var/total_unfilterable_moles = 0 //the total amount of non-filterable gas
@@ -237,7 +237,7 @@
for (var/g in source.gas)
if (source.gas[g] < MINUMUM_MOLES_TO_FILTER)
continue
if (g in filtering)
var/datum/gas_mixture/sink_filtered = filtering[g]
specific_power_gas[g] = calculate_specific_power_gas(g, source, sink_filtered)/ATMOS_FILTER_EFFICIENCY
@@ -245,23 +245,23 @@
else
specific_power_gas[g] = calculate_specific_power_gas(g, source, sink_clean)/ATMOS_FILTER_EFFICIENCY
total_unfilterable_moles += source.gas[g]
var/ratio = source.gas[g]/source.total_moles //converts the specific power per mole of pure gas to specific power per mole of input gas mix
total_specific_power = specific_power_gas[g]*ratio
//Figure out how much of each gas to filter
if (!total_transfer_moles)
total_transfer_moles = source.total_moles
else
total_transfer_moles = min(total_transfer_moles, source.total_moles)
//limit transfer_moles based on available power
if (!isnull(available_power) && total_specific_power > 0)
total_transfer_moles = min(total_transfer_moles, available_power/total_specific_power)
if (total_transfer_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
return -1
//Update Flow Rate var
if (istype(M, /obj/machinery/atmospherics))
var/obj/machinery/atmospherics/A = M
@@ -269,17 +269,17 @@
if (istype(M, /obj/machinery/portable_atmospherics))
var/obj/machinery/portable_atmospherics/P = M
P.last_flow_rate = (total_transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here
var/datum/gas_mixture/removed = source.remove(total_transfer_moles)
if (!removed) //Just in case
return -1
var/list/filtered_power_used = list() //power used to move filterable gas to the filtered gas mixes
var/unfiltered_power_used = 0 //power used to move unfilterable gas to sink_clean
var/list/filtered_heat = list()
for (var/g in removed.gas)
var/power_used = specific_power_gas[g]*removed.gas[g]
if (g in filtering)
var/datum/gas_mixture/sink_filtered = filtering[g]
//use update=0. All the filtered gasses are supposed to be added simultaneously, so we update after the for loop.
@@ -290,15 +290,15 @@
filtered_heat[sink_filtered] = power_used * (removed.gas[g] / source_moles_initial)
else
unfiltered_power_used += power_used
removed.update_values()
var/power_draw = unfiltered_power_used
for (var/datum/gas_mixture/sink_filtered in filtered_power_used)
power_draw += filtered_power_used[sink_filtered]
sink_clean.merge(removed)
return power_draw
//Similar deal as the other atmos process procs.
@@ -306,7 +306,7 @@
/proc/mix_gas(var/obj/machinery/M, var/list/mix_sources, var/datum/gas_mixture/sink, var/total_transfer_moles = null, var/available_power = null)
if (!mix_sources.len)
return -1
var/total_specific_power = 0 //the power needed to mix one mole of gas
var/total_mixing_moles = null //the total amount of gas that can be mixed, given our mix ratios
var/total_input_volume = 0 //for flow rate calculation
@@ -315,36 +315,36 @@
for (var/datum/gas_mixture/source in mix_sources)
if (source.total_moles < MINUMUM_MOLES_TO_FILTER)
return -1 //either mix at the set ratios or mix no gas at all
var/mix_ratio = mix_sources[source]
if (!mix_ratio)
continue //this gas is not being mixed in
//mixing rate is limited by the source with the least amount of available gas
var/this_mixing_moles = source.total_moles/mix_ratio
if (isnull(total_mixing_moles) || total_mixing_moles > this_mixing_moles)
total_mixing_moles = this_mixing_moles
source_specific_power[source] = calculate_specific_power(source, sink)*mix_ratio/ATMOS_FILTER_EFFICIENCY
total_specific_power += source_specific_power[source]
total_input_volume += source.volume
total_input_moles += source.total_moles
if (total_mixing_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
return -1
if (!total_transfer_moles)
total_transfer_moles = total_mixing_moles
else
total_transfer_moles = min(total_mixing_moles, total_transfer_moles)
//limit transfer_moles based on available power
if (!isnull(available_power) && total_specific_power > 0)
total_transfer_moles = min(total_transfer_moles, available_power / total_specific_power)
if (total_transfer_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
return -1
//Update flow rate var
if (istype(M, /obj/machinery/atmospherics))
var/obj/machinery/atmospherics/A = M
@@ -352,22 +352,22 @@
if (istype(M, /obj/machinery/portable_atmospherics))
var/obj/machinery/portable_atmospherics/P = M
P.last_flow_rate = (total_transfer_moles/total_input_moles)*total_input_volume //group_multiplier gets divided out here
var/total_power_draw = 0
for (var/datum/gas_mixture/source in mix_sources)
var/mix_ratio = mix_sources[source]
if (!mix_ratio)
continue
var/transfer_moles = total_transfer_moles * mix_ratio
var/datum/gas_mixture/removed = source.remove(transfer_moles)
var/power_draw = transfer_moles * source_specific_power[source]
total_power_draw += power_draw
sink.merge(removed)
return total_power_draw
/*
@@ -380,11 +380,11 @@
var/air_temperature = (sink.temperature > 0)? sink.temperature : source.temperature
var/specific_entropy = sink.specific_entropy() - source.specific_entropy() //sink is gaining moles, source is loosing
var/specific_power = 0 // W/mol
//If specific_entropy is < 0 then power is required to move gas
if (specific_entropy < 0)
specific_power = -specific_entropy*air_temperature //how much power we need per mole
return specific_power
//Calculates the amount of power needed to move one mole of a certain gas from source to sink.
@@ -393,11 +393,11 @@
var/air_temperature = (sink.temperature > 0)? sink.temperature : source.temperature
var/specific_entropy = sink.specific_entropy_gas(gasid) - source.specific_entropy_gas(gasid) //sink is gaining moles, source is loosing
var/specific_power = 0 // W/mol
//If specific_entropy is < 0 then power is required to move gas
if (specific_entropy < 0)
specific_power = -specific_entropy*air_temperature //how much power we need per mole
return specific_power
//This proc handles power usages.
@@ -413,7 +413,7 @@
use_power = 1 //Don't update here. We will use more power than we are supposed to, but trigger less area power updates.
else
update_use_power(1)
switch (use_power)
if (0) return 0
if (1) return idle_power_usage
+31 -13
View File
@@ -23,8 +23,8 @@
var/list/already_assigned_candidates = list()
//At one antagonist group per 10 players we are just going to go with tiny groups.
var/max_antags = 3 // Antag groups spawn with this many members.
var/antag_type_ratio = 10 // 1 antag type per this many players.
var/max_antags = 5 // Antag groups spawn with this many members.
var/antag_type_ratio = 8 // 1 antag type per this many players.
var/const/waittime_l = 600
var/const/waittime_h = 1800
@@ -62,12 +62,19 @@
chosen_atypes += atype
for(var/j=0;j<max_antags;j++)
if(!candidates || !candidates.len)
break
var/datum/mind/chosen_candidate = pick(candidates)
//Traitors and lings spawn THEN have roles applied; hence we don't set assigned_role here.
if(atype != "tater" && atype != "ling" && atype != "cult")
chosen_candidate.assigned_role = "MODE"
chosen_candidate.special_role = atype
chosen_candidates += chosen_candidate
candidates -= chosen_candidate
chosen_candidates |= chosen_candidate
if(atypes.len - i <= 0) break //Not enough valid types left to populate the remaining antag slots.
@@ -81,7 +88,7 @@
for(var/datum/mind/player in chosen_candidates)
if(player.special_role == atype)
candidates += player
candidates |= player
chosen_candidates -= player
if(!candidates || !candidates.len)
@@ -191,7 +198,18 @@
if("syndi")
possible_antags = get_players_for_role(BE_OPERATIVE)
if("ling")
possible_antags = get_players_for_role(BE_CHANGELING)
var/list/unsuitable_players = list()
for(var/datum/mind/player in possible_antags)
if(player && (player.assigned_role == "Cyborg" || player.assigned_role == "AI"))
unsuitable_players |= player
if(unsuitable_players.len)
possible_antags -= unsuitable_players
if("tater")
possible_antags = get_players_for_role(BE_TRAITOR)
if("wiz")
@@ -231,7 +249,7 @@
for(var/datum/mind/player in candidates)
syndicates += player
syndicates |= player
if(spawnpos > synd_spawn.len)
spawnpos = 1
@@ -264,7 +282,7 @@
for(var/datum/mind/player in candidates)
changelings += player
changelings |= player
grant_changeling_powers(player.current)
player.special_role = "Changeling"
@@ -278,7 +296,7 @@
/datum/game_mode/calamity/proc/spawn_traitors(var/list/candidates)
for(var/datum/mind/player in candidates)
traitors += player
traitors |= player
if(!config.objectives_disabled)
player.objectives += new /datum/objective/escape()
@@ -292,7 +310,7 @@
/datum/game_mode/calamity/proc/spawn_cabal(var/list/candidates)
for(var/datum/mind/player in candidates)
wizards += player
wizards |= player
if(!config.objectives_disabled)
player.objectives += new /datum/objective/escape()
@@ -314,7 +332,7 @@
ninjastart.Add(L)
for(var/datum/mind/player in candidates)
ninjas += player
ninjas |= player
player.current << browse(null, "window=playersetup")
player.current = create_space_ninja(pick(ninjastart))
@@ -347,7 +365,7 @@
//Create raiders.
for(var/datum/mind/player in candidates)
raiders += player
raiders |= player
//Place them on the shuttle.
var/index = 1
@@ -375,14 +393,14 @@
var/list/possible_hosts = list()
for(var/mob/living/carbon/human/H in mob_list)
if(!(H.species.flags & IS_SYNTHETIC))
possible_hosts += H
possible_hosts |= H
for(var/datum/mind/player in candidates)
if(!possible_hosts || possible_hosts.len)
break
borers += player
borers |= player
var/mob/living/carbon/human/target_host = pick(possible_hosts)
possible_hosts -= target_host
@@ -430,7 +448,7 @@
if(player.assigned_role == job)
continue
cult += player
cult |= player
equip_cultist(player.current)
grant_runeword(player.current)
update_cult_icons_added(player)
+5 -8
View File
@@ -32,7 +32,7 @@
"Chirp" = list("chirps","chirrups","cheeps"),
"Feline" = list("purrs","yowls","meows")
)
var/obj/item/weapon/pai_cable/cable // The cable we produce and use when door or camera jacking
var/master // Name of the one who commands us
@@ -84,7 +84,6 @@
add_language("Tradeband", 1)
add_language("Gutter", 1)
verbs += /mob/living/silicon/pai/proc/fold_out
verbs += /mob/living/silicon/pai/proc/choose_chassis
verbs += /mob/living/silicon/pai/proc/choose_verbs
@@ -301,7 +300,7 @@
// mobile pai mob. This also includes handling some of the general shit that can occur
// to it. Really this deserves its own file, but for the moment it can sit here. ~ Z
/mob/living/silicon/pai/proc/fold_out()
/mob/living/silicon/pai/verb/fold_out()
set category = "pAI Commands"
set name = "Unfold Chassis"
@@ -315,8 +314,6 @@
return
last_special = world.time + 100
verbs -= /mob/living/silicon/pai/proc/fold_out
verbs += /mob/living/silicon/pai/proc/fold_up
var/turf/T = get_turf(src)
if(istype(T)) T.visible_message("<b>[src]</b> folds outwards, expanding into a mobile form.")
@@ -333,7 +330,7 @@
src.forceMove(get_turf(card))
card.forceMove(src)
/mob/living/silicon/pai/proc/fold_up()
/mob/living/silicon/pai/verb/fold_up()
set category = "pAI Commands"
set name = "Collapse Chassis"
@@ -412,8 +409,8 @@
last_special = world.time + 100
verbs -= /mob/living/silicon/pai/proc/fold_up
verbs += /mob/living/silicon/pai/proc/fold_out
if(src.loc == card)
return
var/turf/T = get_turf(src)
if(istype(T)) T.visible_message("<b>[src]</b> neatly folds inwards, compacting down to a rectangular card.")
+11 -7
View File
@@ -16,12 +16,12 @@ var/global/list/power_update_requests_by_area = list()
power_update_requests_by_machine[machine_type] += 1
else
power_update_requests_by_machine[machine_type] = 1
if (A.name in power_update_requests_by_area)
power_update_requests_by_area[A.name] += 1
else
power_update_requests_by_area[A.name] = 1
power_profiled_time += (world.time - power_last_profile_time)
power_last_profile_time = world.time
@@ -33,25 +33,27 @@ var/global/list/power_update_requests_by_area = list()
if(enable_power_update_profiling)
enable_power_update_profiling = 0
usr << "Area power update profiling disabled."
message_admins("[key_name(src)] toggled area power update profiling off.")
log_admin("[key_name(src)] toggled area power update profiling off.")
else
enable_power_update_profiling = 1
power_last_profile_time = world.time
usr << "Area power update profiling enabled."
message_admins("[key_name(src)] toggled area power update profiling on.")
log_admin("[key_name(src)] toggled area power update profiling on.")
feedback_add_details("admin_verb","APUP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/view_power_update_stats_machines()
set name = "View Area Power Update Statistics By Machines"
set desc = "See which types of machines are triggering area power updates."
set category = "Debug"
if(!check_rights(R_DEBUG)) return
usr << "Total profiling time: [power_profiled_time] ticks"
for (var/M in power_update_requests_by_machine)
usr << "[M] = [power_update_requests_by_machine[M]]"
@@ -60,7 +62,9 @@ var/global/list/power_update_requests_by_area = list()
set name = "View Area Power Update Statistics By Area"
set desc = "See which areas are having area power updates."
set category = "Debug"
if(!check_rights(R_DEBUG)) return
usr << "Total profiling time: [power_profiled_time] ticks"
usr << "Total profiling time: [power_profiled_time] ticks"
for (var/A in power_update_requests_by_area)