Merge pull request #6493 from Zuhayr/dev

Dev
This commit is contained in:
Zuhayr
2014-09-24 22:06:07 +09:30
164 changed files with 8009 additions and 7210 deletions
+1 -1
View File
@@ -764,7 +764,6 @@
#include "code\modules\clothing\gloves\color.dm"
#include "code\modules\clothing\gloves\miscellaneous.dm"
#include "code\modules\clothing\gloves\ninja.dm"
#include "code\modules\clothing\gloves\stungloves.dm"
#include "code\modules\clothing\head\collectable.dm"
#include "code\modules\clothing\head\hardhat.dm"
#include "code\modules\clothing\head\helmet.dm"
@@ -1141,6 +1140,7 @@
#include "code\modules\power\port_gen.dm"
#include "code\modules\power\power.dm"
#include "code\modules\power\power_monitor.dm"
#include "code\modules\power\powernet.dm"
#include "code\modules\power\profiling.dm"
#include "code\modules\power\smes.dm"
#include "code\modules\power\smes_construction.dm"
+14 -1
View File
@@ -110,6 +110,19 @@ var/global/list/pipe_colors = list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_
I.color = pipe_colors[pipe_color]
pipe_icons[state + "[pipe_colors[pipe_color]]"] = I
pipe = new ('icons/atmos/heat.dmi')
for(var/state in pipe.IconStates())
if(!state || findtext(state, "map"))
continue
pipe_icons["hepipe" + state] = image('icons/atmos/heat.dmi', icon_state = state)
pipe = new ('icons/atmos/junction.dmi')
for(var/state in pipe.IconStates())
if(!state || findtext(state, "map"))
continue
pipe_icons["hejunction" + state] = image('icons/atmos/junction.dmi', icon_state = state)
/datum/pipe_icon_manager/proc/gen_manifold_icons()
if(!manifold_icons)
manifold_icons = new()
@@ -268,4 +281,4 @@ var/global/list/pipe_colors = list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_
if("pipe_intact-scrubbers")
pipe_underlays_intact["[D]" + pipe_colors[pipe_color]] = I
*/
*/
+94 -90
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).
@@ -11,6 +11,15 @@
/obj/machinery/atmospherics/var/last_flow_rate = 0
/obj/machinery/portable_atmospherics/var/last_flow_rate = 0
/obj/machinery/atmospherics/var/debug = 0
/client/proc/atmos_toggle_debug(var/obj/machinery/atmospherics/M in view())
set name = "Toggle Debug Messages"
set category = "Debug"
M.debug = !M.debug
usr << "[M]: Debug messages toggled [M.debug? "on" : "off"]."
//Generalized gas pumping proc.
//Moves gas from one gas_mixture to another and returns the amount of power needed (assuming 1 second), or -1 if no gas was pumped.
//transfer_moles - Limits the amount of moles to transfer. The actual amount of gas moved may also be limited by available_power, if given.
@@ -18,38 +27,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
if (!transfer_moles)
//var/source_moles_initial = source.total_moles
if (isnull(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
if (power_draw > 0)
removed.add_thermal_energy(power_draw) //1st law - energy is conserved
sink.merge(removed)
return power_draw
//Generalized gas scrubbing proc.
@@ -62,40 +78,40 @@
return -1
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)
if (isnull(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
@@ -103,30 +119,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()
if (power_draw > 0)
sink.add_thermal_energy(power_draw) //gotta conserve that energy
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.
@@ -136,7 +149,7 @@
return -1
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
@@ -144,30 +157,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)
if (isnull(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
@@ -175,16 +188,16 @@
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
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.
sink_filtered.adjust_gas_temp(g, removed.gas[g], removed.temperature, update=0)
@@ -192,17 +205,12 @@
filtered_power_used += power_used
else
unfiltered_power_used += power_used
sink_filtered.update_values()
removed.update_values()
sink_clean.merge(removed)
//1LTD energy is conserved
if (filtered_power_used > 0)
sink_filtered.add_thermal_energy(filtered_power_used)
if (unfiltered_power_used > 0)
sink_clean.add_thermal_energy(unfiltered_power_used)
return filtered_power_used + unfiltered_power_used
//For omni devices. Instead filtering is an associative list mapping gasids to gas mixtures.
@@ -213,7 +221,7 @@
return -1
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
@@ -221,7 +229,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
@@ -229,23 +237,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)
if (isnull(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
@@ -253,16 +261,16 @@
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
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.
@@ -272,18 +280,15 @@
filtered_power_used[sink_filtered] = power_used
else
unfiltered_power_used += power_used
removed.update_values()
sink_clean.merge(removed)
//1st LTD energy is conserved
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_filtered.add_thermal_energy(filtered_power_used[sink_filtered])
if (unfiltered_power_used > 0)
sink_clean.add_thermal_energy(unfiltered_power_used)
sink_clean.merge(removed)
return power_draw
//Similar deal as the other atmos process procs.
@@ -291,7 +296,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
@@ -300,36 +305,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)
if (isnull(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
@@ -337,23 +342,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]
removed.add_thermal_energy(power_draw) //conservation of energy
total_power_draw += power_draw
sink.merge(removed)
return total_power_draw
/*
@@ -366,11 +370,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.
@@ -379,11 +383,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.
@@ -399,7 +403,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
@@ -129,7 +129,7 @@
var/transfer_moles = pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION)
//limit flow rate from turfs
transfer_moles = min(transfer_moles, environment.total_moles*MAX_SIPHON_FLOWRATE/environment.volume) //group_multiplier gets divided out here
transfer_moles = min(transfer_moles, environment.total_moles*air2.volume/environment.volume) //group_multiplier gets divided out here
power_draw = pump_gas(src, environment, air2, transfer_moles, active_power_usage)
@@ -63,7 +63,7 @@
pressure_delta = target_pressure - output_starting_pressure
var/flowing_old = flowing
if((REGULATE_NONE || pressure_delta > 0.01) && (air1.temperature > 0 || air2.temperature > 0)) //since it's basically a valve, it makes sense to check both temperatures
if((regulate_mode == REGULATE_NONE || pressure_delta > 0.01) && (air1.temperature > 0 || air2.temperature > 0)) //since it's basically a valve, it makes sense to check both temperatures
flowing = 1
//flow rate limit
@@ -8,14 +8,14 @@
var/list/filters = new()
var/datum/omni_port/input
var/datum/omni_port/output
use_power = 1
idle_power_usage = 150 //internal circuitry, friction losses and stuff
active_power_usage = 7500 //This also doubles as a measure of how powerful the filter is, in Watts. 7500 W ~ 10 HP
var/max_flow_rate = 200
var/set_flow_rate = 200
var/list/filtering_outputs = list() //maps gasids to gas_mixtures
/obj/machinery/atmospherics/omni/filter/New()
@@ -58,32 +58,26 @@
return 0
/obj/machinery/atmospherics/omni/filter/process()
..()
if(error_check())
on = 0
if((stat & (NOPOWER|BROKEN)) || !on)
update_use_power(0) //usually we get here because a player turned a pump off - definitely want to update.
last_flow_rate = 0
return
if(!..())
return 0
var/datum/gas_mixture/output_air = output.air //BYOND doesn't like referencing "output.air.return_pressure()" so we need to make a direct reference
var/datum/gas_mixture/input_air = input.air // it's completely happy with them if they're in a loop though i.e. "P.air.return_pressure()"... *shrug*
//Figure out the amount of moles to transfer
var/transfer_moles = (set_flow_rate/input_air.volume)*input_air.total_moles
var/power_draw = -1
if (transfer_moles > MINUMUM_MOLES_TO_FILTER)
power_draw = filter_gas_multi(src, filtering_outputs, input_air, output_air, transfer_moles, active_power_usage)
if (power_draw < 0)
//update_use_power(0)
use_power = 0 //don't force update - easier on CPU
last_flow_rate = 0
else
handle_power_draw(power_draw)
if(input.network)
input.network.update = 1
if(output.network)
@@ -91,7 +85,7 @@
for(var/datum/omni_port/P in filters)
if(P.network)
P.network.update = 1
return 1
/obj/machinery/atmospherics/omni/filter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
@@ -252,7 +246,7 @@
P.mode = previous_mode
if(P.mode != old_mode)
handle_port_change(P)
update_ports()
/obj/machinery/atmospherics/omni/filter/proc/rebuild_filtering_list()
@@ -17,10 +17,10 @@
var/tag_south_con
var/tag_east_con
var/tag_west_con
var/max_flow_rate = 200
var/set_flow_rate = 200
var/list/mixing_inputs = list()
/obj/machinery/atmospherics/omni/mixer/New()
@@ -45,7 +45,7 @@
if(tag_west_con && tag_west == 1)
P.concentration = tag_west_con
con += max(0, tag_west_con)
for(var/datum/omni_port/P in ports)
P.air.volume = ATMOS_DEFAULT_VOLUME_MIXER
@@ -86,32 +86,26 @@
return 1
if(inputs.len < 2) //requires at least 2 inputs ~otherwise why are you using a mixer?
return 1
//concentration must add to 1
var/total = 0
for (var/datum/omni_port/P in inputs)
total += P.concentration
if (total != 1)
return 1
return 0
/obj/machinery/atmospherics/omni/mixer/process()
..()
if(error_check())
on = 0
if((stat & (NOPOWER|BROKEN)) || !on)
update_use_power(0) //usually we get here because a player turned a pump off - definitely want to update.
last_flow_rate = 0
return
if(!..())
return 0
//Figure out the amount of moles to transfer
var/transfer_moles = 0
for (var/datum/omni_port/P in inputs)
transfer_moles += (set_flow_rate*P.concentration/P.air.volume)*P.air.total_moles
var/power_draw = -1
if (transfer_moles > MINUMUM_MOLES_TO_FILTER)
power_draw = mix_gas(src, mixing_inputs, output, transfer_moles, active_power_usage)
@@ -122,14 +116,14 @@
last_flow_rate = 0
else
handle_power_draw(power_draw)
for(var/datum/omni_port/P in inputs)
if(P.concentration && P.network)
P.network.update = 1
if(output.network)
output.network.update = 1
return 1
/obj/machinery/atmospherics/omni/mixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
@@ -291,7 +285,7 @@
P.concentration = new_con
else if(!P.con_lock)
P.concentration = remain_con
rebuild_mixing_inputs()
/obj/machinery/atmospherics/omni/mixer/proc/rebuild_mixing_inputs()
@@ -50,10 +50,8 @@
/obj/machinery/atmospherics/omni/update_icon()
if(stat & NOPOWER)
overlays = overlays_off
on = 0
else if(error_check())
overlays = overlays_error
on = 0
else
overlays = on ? (overlays_on) : (overlays_off)
@@ -64,6 +62,16 @@
/obj/machinery/atmospherics/omni/proc/error_check()
return
/obj/machinery/atmospherics/omni/process()
if(error_check())
on = 0
if((stat & (NOPOWER|BROKEN)) || !on)
update_use_power(0) //usually we get here because a player turned a pump off - definitely want to update.
last_flow_rate = 0
return 0
return 1
/obj/machinery/atmospherics/omni/power_change()
var/old_stat = stat
..()
@@ -23,7 +23,7 @@
3: Carbon Dioxide: Carbon Dioxide ONLY
4: Sleeping Agent (N2O)
*/
var/filter_type = 0
var/filter_type = -1
var/list/filtered_out = list()
@@ -38,6 +38,18 @@
/obj/machinery/atmospherics/trinary/filter/New()
..()
switch(filter_type)
if(0) //removing hydrocarbons
filtered_out = list("phoron", "oxygen_agent_b")
if(1) //removing O2
filtered_out = list("oxygen")
if(2) //removing N2
filtered_out = list("nitrogen")
if(3) //removing CO2
filtered_out = list("carbon_dioxide")
if(4)//removing N2O
filtered_out = list("sleeping_agent")
air1.volume = ATMOS_DEFAULT_VOLUME_FILTER
air2.volume = ATMOS_DEFAULT_VOLUME_FILTER
air3.volume = ATMOS_DEFAULT_VOLUME_FILTER
+44 -19
View File
@@ -1,3 +1,6 @@
//TODO: Put this under a common parent type with heaters to cut down on the copypasta
#define FREEZER_PERF_MULT 2.5
/obj/machinery/atmospherics/unary/freezer
name = "gas cooling system"
desc = "Cools gas when connected to pipe network"
@@ -7,14 +10,17 @@
anchored = 1.0
var/heatsink_temperature = T20C //the constant temperature resevoir into which the freezer pumps heat. Probably the hull of the station or something.
var/heatsink_temperature = T20C //the constant temperature resevoir into which the freezer pumps heat. Probably the hull of the station or something.
var/internal_volume = 600 //L
var/on = 0
use_power = 0
idle_power_usage = 5 //5 Watts for thermostat related circuitry
active_power_usage = 50000 //50 kW. The power rating of the freezer
idle_power_usage = 5 //5 Watts for thermostat related circuitry
active_power_usage //50 kW. The power rating of the freezer
var/max_power_usage = 20000 //power rating when the usage is turned up to 100
var/power_setting = 100
var/set_temperature = T20C //thermostat
var/cooling = 0
var/opened = 0 //for deconstruction
@@ -23,14 +29,16 @@
..()
air_contents.volume = internal_volume
initialize_directions = dir
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/gas_cooler(src)
component_parts += new /obj/item/weapon/circuitboard/unary_atmos/cooler(src)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
active_power_usage = max_power_usage * (power_setting/100)
/obj/machinery/atmospherics/unary/freezer/initialize()
if(node) return
@@ -72,7 +80,8 @@
data["minGasTemperature"] = 0
data["maxGasTemperature"] = round(T20C+500)
data["targetGasTemperature"] = round(set_temperature)
data["powerSetting"] = power_setting
var/temp_class = "good"
if (air_contents.temperature > (T0C - 20))
temp_class = "bad"
@@ -104,6 +113,9 @@
src.set_temperature = min(src.set_temperature+amount, 1000)
else
src.set_temperature = max(src.set_temperature+amount, 0)
if(href_list["setPower"]) //setting power to 0 is redundant anyways
var/new_setting = between(0, text2num(href_list["setPower"]), 100)
set_power_level(new_setting)
src.add_fingerprint(usr)
return 1
@@ -113,30 +125,33 @@
if(stat & (NOPOWER|BROKEN) || !on)
cooling = 0
update_use_power(0)
update_icon()
return
if (network && air_contents.temperature > set_temperature)
cooling = 1
update_use_power(2)
var/heat_transfer = min(abs(air_contents.get_thermal_energy_change(set_temperature)), active_power_usage)
var/heat_transfer = max( -air_contents.get_thermal_energy_change(set_temperature - 5), 0 )
//Assume the heat is being pumped into the hull which is fixed at heatsink_temperature
//not /really/ proper thermodynamics but whatever
var/cop = air_contents.temperature/heatsink_temperature //heatpump coefficient of performance from thermodynamics -> power used = heat_transfer/cop
var/cop = FREEZER_PERF_MULT * air_contents.temperature/heatsink_temperature //heatpump coefficient of performance from thermodynamics -> power used = heat_transfer/cop
heat_transfer = min(heat_transfer, cop * active_power_usage) //limit heat transfer by available power
air_contents.add_thermal_energy(-heat_transfer) //remove the heat
var/removed = -air_contents.add_thermal_energy(-heat_transfer) //remove the heat
if (debug)
visible_message("[src]: Removing [removed] W.")
network.update = 1
else
cooling = 0
update_use_power(1)
update_icon()
//upgrading parts
/obj/machinery/atmospherics/unary/freezer/RefreshParts()
/obj/machinery/atmospherics/unary/freezer/RefreshParts()
..()
var/cap_rating = 0
var/cap_count = 0
@@ -144,7 +159,7 @@
var/manip_count = 0
var/bin_rating = 0
var/bin_count = 0
for(var/obj/item/weapon/stock_parts/P in component_parts)
if(istype(P, /obj/item/weapon/stock_parts/capacitor))
cap_rating += P.rating
@@ -158,10 +173,20 @@
cap_rating /= cap_count
bin_rating /= bin_count
manip_rating /= manip_count
active_power_usage = initial(active_power_usage)*cap_rating //more powerful
heatsink_temperature = initial(heatsink_temperature)/((manip_rating+bin_rating)/2) //more efficient
air_contents.volume = max(initial(internal_volume) - 200, 0) + 200*bin_rating
set_power_level(power_setting)
/obj/machinery/atmospherics/unary/freezer/proc/set_power_level(var/new_power_setting)
power_setting = new_power_setting
var/old_power_usage = active_power_usage
active_power_usage = max_power_usage * (power_setting/100)
if (use_power >= 2 && old_power_usage != active_power_usage)
force_power_update()
//dismantling code. copied from autolathe
/obj/machinery/atmospherics/unary/freezer/attackby(var/obj/item/O as obj, var/mob/user as mob)
@@ -173,7 +198,7 @@
if (opened && istype(O, /obj/item/weapon/crowbar))
dismantle()
return
..()
/obj/machinery/atmospherics/unary/freezer/examine()
@@ -1,3 +1,5 @@
//TODO: Put this under a common parent type with freezers to cut down on the copypasta
/obj/machinery/atmospherics/unary/heater
name = "gas heating system"
desc = "Heats gas when connected to a pipe network"
@@ -13,9 +15,12 @@
var/on = 0
use_power = 0
idle_power_usage = 5 //5 Watts for thermostat related circuitry
active_power_usage = 50000 //50 kW. The power rating of the heater
idle_power_usage = 5 //5 Watts for thermostat related circuitry
active_power_usage //50 kW. The power rating of the heater
var/max_power_usage = 20000 //power rating when the usage is turned up to 100
var/power_setting = 100
var/heating = 0 //mainly for icon updates
var/opened = 0 //for deconstruction
@@ -23,12 +28,14 @@
..()
air_contents.volume = internal_volume
initialize_directions = dir
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/gas_heater(src)
component_parts += new /obj/item/weapon/circuitboard/unary_atmos/heater(src)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
active_power_usage = max_power_usage * (power_setting/100)
/obj/machinery/atmospherics/unary/heater/initialize()
if(node) return
@@ -52,26 +59,27 @@
else
icon_state = "heater_0"
return
/obj/machinery/atmospherics/unary/heater/process()
..()
if(stat & (NOPOWER|BROKEN) || !on)
heating = 0
update_use_power(0)
update_icon()
return
if (network && air_contents.temperature < set_temperature)
if (network && air_contents.total_moles && air_contents.temperature < set_temperature)
update_use_power(2)
air_contents.add_thermal_energy(active_power_usage)
heating = 1
network.update = 1
else
heating = 0
update_use_power(1)
update_icon()
/obj/machinery/atmospherics/unary/heater/attack_ai(mob/user as mob)
@@ -82,7 +90,7 @@
/obj/machinery/atmospherics/unary/heater/attack_hand(mob/user as mob)
src.ui_interact(user)
/obj/machinery/atmospherics/unary/heater/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
// this is the data which will be sent to the ui
var/data[0]
@@ -92,7 +100,8 @@
data["minGasTemperature"] = 0
data["maxGasTemperature"] = round(max_temperature)
data["targetGasTemperature"] = round(set_temperature)
data["powerSetting"] = power_setting
var/temp_class = "normal"
if (air_contents.temperature > (T20C+40))
temp_class = "bad"
@@ -122,14 +131,17 @@
src.set_temperature = min(src.set_temperature+amount, max_temperature)
else
src.set_temperature = max(src.set_temperature+amount, 0)
if(href_list["setPower"]) //setting power to 0 is redundant anyways
var/new_setting = between(0, text2num(href_list["setPower"]), 100)
set_power_level(new_setting)
src.add_fingerprint(usr)
return 1
//upgrading parts
/obj/machinery/atmospherics/unary/heater/RefreshParts()
/obj/machinery/atmospherics/unary/heater/RefreshParts()
..()
var/cap_rating = 0
var/cap_count = 0
var/bin_rating = 0
@@ -143,10 +155,20 @@
bin_count++
cap_rating /= cap_count
bin_rating /= bin_count
active_power_usage = initial(active_power_usage)*cap_rating
max_power_usage = initial(max_power_usage)*cap_rating
max_temperature = max(initial(max_temperature) - T20C, 0)*((bin_rating*2 + cap_rating)/3) + T20C
air_contents.volume = max(initial(internal_volume) - 200, 0) + 200*bin_rating
set_power_level(power_setting)
/obj/machinery/atmospherics/unary/heater/proc/set_power_level(var/new_power_setting)
power_setting = new_power_setting
var/old_power_usage = active_power_usage
active_power_usage = max_power_usage * (power_setting/100)
if (use_power >= 2 && old_power_usage != active_power_usage)
force_power_update()
//dismantling code. copied from autolathe
/obj/machinery/atmospherics/unary/heater/attackby(var/obj/item/O as obj, var/mob/user as mob)
@@ -158,7 +180,7 @@
if (opened && istype(O, /obj/item/weapon/crowbar))
dismantle()
return
..()
/obj/machinery/atmospherics/unary/heater/examine()
@@ -1,6 +1,6 @@
//Basically a one way passive valve. If the pressure inside is greater than the environment then gas will flow passively,
//but it does not permit gas to flow back from the environment into the injector. Can be turned off to prevent any gas flow.
//When it recieves the "inject" signal, it will try to pump it's entire contents into the environment regardless of pressure, using power.
//When it receives the "inject" signal, it will try to pump it's entire contents into the environment regardless of pressure, using power.
/obj/machinery/atmospherics/unary/outlet_injector
icon = 'icons/atmos/injector.dmi'
@@ -12,8 +12,8 @@
desc = "Passively injects air into its surroundings. Has a valve attached to it that can control flow rate."
use_power = 1
idle_power_usage = 5 //internal circuitry
var/inject_power = 15000 //15000 kW ~ 20 HP
idle_power_usage = 150 //internal circuitry, friction losses and stuff
active_power_usage = 15000 //This also doubles as a measure of how powerful the pump is, in Watts. 15000 W ~ 20 HP
var/on = 0
var/injecting = 0
@@ -54,26 +54,28 @@
..()
injecting = 0
if(!on) //only uses power when injecting
return 0
if((stat & (NOPOWER|BROKEN)) || !on)
update_use_power(0) //usually we get here because a player turned a pump off - definitely want to update.
last_flow_rate = 0
return
var/power_draw = -1
var/datum/gas_mixture/environment = loc.return_air()
if(environment && air_contents.temperature > 0)
var/air_temperature = environment.temperature? environment.temperature : air_contents.temperature
var/pressure_delta = air_contents.return_pressure() - environment.return_pressure()
var/output_volume = environment.volume * environment.group_multiplier
if (pressure_delta > 0.01)
var/transfer_moles = pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION)
transfer_moles = min(transfer_moles, (volume_rate/air_contents.volume)*air_contents.total_moles) //apply flow rate limit
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
loc.assume_air(removed)
if(network)
network.update = 1
var/transfer_moles = (volume_rate/air_contents.volume)*air_contents.total_moles //apply flow rate limit
power_draw = pump_gas(src, air_contents, environment, transfer_moles, active_power_usage)
if (power_draw < 0)
//update_use_power(0)
use_power = 0 //don't force update - easier on CPU
last_flow_rate = 0
else
handle_power_draw(power_draw)
if(network)
network.update = 1
return 1
/obj/machinery/atmospherics/unary/outlet_injector/proc/inject()
@@ -87,7 +89,7 @@
injecting = 1
if(air_contents.temperature > 0)
var/power_used = pump_gas(src, air_contents, environment, air_contents.total_moles, inject_power)
var/power_used = pump_gas(src, air_contents, environment, air_contents.total_moles, active_power_usage)
use_power(power_used)
if(network)
@@ -88,6 +88,15 @@
..()
air_contents.volume = ATMOS_DEFAULT_VOLUME_PUMP + 800
/obj/machinery/atmospherics/unary/vent_pump/engine
name = "Engine Core Vent"
power_channel = ENVIRON
active_power_usage = 15000 //15 kW ~ 20 HP
/obj/machinery/atmospherics/unary/vent_pump/engine/New()
..()
air_contents.volume = ATMOS_DEFAULT_VOLUME_PUMP + 500 //meant to match air injector
/obj/machinery/atmospherics/unary/vent_pump/update_icon(var/safety = 0)
if(!check_icon_cache())
return
@@ -174,7 +183,7 @@
var/transfer_moles = pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION)
//limit flow rate from turfs
transfer_moles = min(transfer_moles, environment.total_moles*MAX_SIPHON_FLOWRATE/environment.volume) //group_multiplier gets divided out here
transfer_moles = min(transfer_moles, environment.total_moles*air_contents.volume/environment.volume) //group_multiplier gets divided out here
power_draw = pump_gas(src, environment, air_contents, transfer_moles, active_power_usage)
@@ -20,7 +20,7 @@
var/on = 0
var/scrubbing = 1 //0 = siphoning, 1 = scrubbing
var/list/scrubbing_gas = list()
var/list/scrubbing_gas = list("carbon_dioxide")
var/panic = 0 //is this scrubber panicked?
+3
View File
@@ -202,6 +202,9 @@ datum/pipeline
//surface must be the surface area in m^2
proc/radiate_heat_to_space(surface, thermal_conductivity)
var/gas_density = air.total_moles/air.volume
thermal_conductivity *= min(gas_density / ( RADIATOR_OPTIMUM_PRESSURE/(R_IDEAL_GAS_EQUATION*T20C) ), 1)
//if the h/e pipes radiate less than the AVERAGE_SOLAR_RADIATION, then they will heat up, otherwise they will cool down. It turns out the critical temperature is -26 C
var/heat_gain = surface*(AVERAGE_SOLAR_RADIATION - STEFAN_BOLTZMANN_CONSTANT*thermal_conductivity*(air.temperature - COSMIC_RADIATION_TEMPERATURE) ** 4)
+12 -12
View File
@@ -1,7 +1,8 @@
obj/machinery/atmospherics/pipe/simple/heat_exchanging
icon = 'icons/obj/pipes/heat.dmi'
icon = 'icons/atmos/heat.dmi'
icon_state = "intact"
pipe_icon = "hepipe"
level = 2
var/initialize_directions_he
var/surface = 2 //surface area in m^2
@@ -35,6 +36,10 @@ obj/machinery/atmospherics/pipe/simple/heat_exchanging
if(target.initialize_directions_he & get_dir(target,src))
node2 = target
break
if(!node1 && !node2)
del(src)
return
update_icon()
return
@@ -58,8 +63,9 @@ obj/machinery/atmospherics/pipe/simple/heat_exchanging
obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction
icon = 'icons/obj/pipes/junction.dmi'
icon = 'icons/atmos/junction.dmi'
icon_state = "intact"
pipe_icon = "hejunction"
level = 2
minimum_temperature_difference = 300
thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
@@ -82,16 +88,6 @@ obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction
initialize_directions_he = WEST
// BubbleWrap END
update_icon()
if(node1&&node2)
icon_state = "intact"
else
var/have_node1 = node1?1:0
var/have_node2 = node2?1:0
icon_state = "exposed[have_node1][have_node2]"
if(!node1&&!node2)
del(src)
initialize()
for(var/obj/machinery/atmospherics/target in get_step(src,initialize_directions))
if(target.initialize_directions & get_dir(target,src))
@@ -102,5 +98,9 @@ obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction
node2 = target
break
if(!node1&&!node2)
del(src)
return
update_icon()
return
+18 -8
View File
@@ -15,7 +15,7 @@
/obj/machinery/atmospherics/pipe/New()
..()
//so pipes under walls are hidden
if(!istype(get_turf(src), /turf/simulated/floor))
if(istype(get_turf(src), /turf/simulated/wall) || istype(get_turf(src), /turf/simulated/shuttle/wall) || istype(get_turf(src), /turf/unsimulated/wall))
level = 1
/obj/machinery/atmospherics/pipe/proc/pipeline_expansion()
@@ -137,6 +137,7 @@
/obj/machinery/atmospherics/pipe/simple
icon = 'icons/atmos/pipes.dmi'
icon_state = ""
var/pipe_icon = "" //what kind of pipe it is and from which dmi is the icon manager getting its icons, "" for simple pipes, "hepipe" for HE pipes, "hejunction" for HE junctions
name = "pipe"
desc = "A one meter section of regular pipe"
@@ -571,6 +572,10 @@
if (node3)
break
if(!node1 && !node2 && !node3)
del(src)
return
var/turf/T = get_turf(src)
if(istype(T))
hide(T.intact)
@@ -825,6 +830,10 @@
node4 = target
break
if(!node1 && !node2 && !node3 && !node4)
del(src)
return
var/turf/T = get_turf(src)
if(istype(T))
hide(T.intact)
@@ -1028,6 +1037,7 @@
desc = "A large vessel containing pressurized gas."
volume = 10000 //in liters, 1 meters by 1 meters by 2 meters ~tweaked it a little to simulate a pressure tank without needing to recode them yet
var/start_pressure = 25*ONE_ATMOSPHERE
level = 1
dir = SOUTH
@@ -1120,8 +1130,8 @@
air_temporary.volume = volume
air_temporary.temperature = T20C
air_temporary.adjust_multi("oxygen", (25*ONE_ATMOSPHERE*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature), \
"nitrogen",(25*ONE_ATMOSPHERE*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
air_temporary.adjust_multi("oxygen", (start_pressure*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature), \
"nitrogen",(start_pressure*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
..()
@@ -1136,7 +1146,7 @@
air_temporary.volume = volume
air_temporary.temperature = T20C
air_temporary.adjust_gas("oxygen", (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
air_temporary.adjust_gas("oxygen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
..()
icon_state = "o2"
@@ -1150,7 +1160,7 @@
air_temporary.volume = volume
air_temporary.temperature = T20C
air_temporary.adjust_gas("nitrogen", (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
air_temporary.adjust_gas("nitrogen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
..()
icon_state = "n2"
@@ -1164,7 +1174,7 @@
air_temporary.volume = volume
air_temporary.temperature = T20C
air_temporary.adjust_gas("carbon_dioxide", (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
air_temporary.adjust_gas("carbon_dioxide", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
..()
icon_state = "co2"
@@ -1178,7 +1188,7 @@
air_temporary.volume = volume
air_temporary.temperature = T20C
air_temporary.adjust_gas("phoron", (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
air_temporary.adjust_gas("phoron", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
..()
icon_state = "phoron"
@@ -1192,7 +1202,7 @@
air_temporary.volume = volume
air_temporary.temperature = T0C
air_temporary.adjust_gas("sleeping_agent", (25*ONE_ATMOSPHERE)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
air_temporary.adjust_gas("sleeping_agent", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
..()
icon_state = "n2o"
+16 -4
View File
@@ -5,7 +5,7 @@ var/list/alldepartments = list("Central Command")
name = "fax machine"
icon = 'icons/obj/library.dmi'
icon_state = "fax"
req_one_access = list(access_lawyer, access_heads)
req_one_access = list(access_lawyer, access_heads, access_armory) //Warden needs to be able to Fax solgov too.
anchored = 1
density = 1
use_power = 1
@@ -23,12 +23,14 @@ var/list/alldepartments = list("Central Command")
var/dpt = "Central Command" // the department we're sending to
/obj/machinery/faxmachine/New()
..()
allfaxes += src
if( !("[department]" in alldepartments) )
alldepartments += department
alldepartments += "Sol Government"
/obj/machinery/faxmachine/process()
return 0
@@ -95,9 +97,12 @@ var/list/alldepartments = list("Central Command")
if(tofax)
if(dpt == "Central Command")
Centcomm_fax(tofax.info, tofax.name, usr)
Centcomm_fax(src, tofax.info, tofax.name, usr)
sendcooldown = 1800
else if(dpt == "Sol Government")
Solgov_fax(src, tofax.info, tofax.name, usr)
sendcooldown = 1800
else
SendFax(tofax.info, tofax.name, usr, dpt)
sendcooldown = 600
@@ -177,11 +182,18 @@ var/list/alldepartments = list("Central Command")
user << "<span class='notice'>You [anchored ? "wrench" : "unwrench"] \the [src].</span>"
return
/proc/Centcomm_fax(var/sent, var/sentname, var/mob/Sender)
/proc/Centcomm_fax(var/originfax, var/sent, var/sentname, var/mob/Sender)
var/msg = "\blue <b><font color='#006100'>CENTCOMM FAX: </font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<a href='?_src_=holder;CentcommFaxReply=\ref[Sender];originfax=\ref[originfax]'>RPLY</a>)</b>: Receiving '[sentname]' via secure connection ... <a href='?_src_=holder;CentcommFaxView=\ref[sent]'>view message</a>"
var/msg = "\blue <b><font color='orange'>CENTCOMM FAX: </font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<a href='?_src_=holder;CentcommFaxReply=\ref[Sender]'>RPLY</a>)</b>: Receiving '[sentname]' via secure connection ... <a href='?_src_=holder;CentcommFaxView=\ref[sent]'>view message</a>"
admins << msg
/proc/Solgov_fax(var/originfax, var/sent, var/sentname, var/mob/Sender)
var/msg = "\blue <b><font color='#1F66A0'>SOL GOVERNMENT FAX: </font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<a href='?_src_=holder;SolGovFaxReply=\ref[Sender];originfax=\ref[originfax]'>RPLY</a>)</b>: Receiving '[sentname]' via secure connection ... <a href='?_src_=holder;CentcommFaxView=\ref[sent]'>view message</a>"
admins << msg
proc/SendFax(var/sent, var/sentname, var/mob/Sender, var/dpt)
for(var/obj/machinery/faxmachine/F in allfaxes)
+5 -6
View File
@@ -1,15 +1,14 @@
/turf/simulated/var/zone/zone
/turf/simulated/var/open_directions
/turf/simulated/var/gas_graphic
/turf/var/needs_air_update = 0
/turf/var/datum/gas_mixture/air
/turf/simulated/proc/set_graphic(new_graphic)
gas_graphic = new_graphic
overlays.Cut()
for(var/i in gas_graphic)
overlays += i
/turf/simulated/proc/update_graphic(list/graphic_add = null, list/graphic_remove = null)
if(graphic_add)
overlays += graphic_add
if(graphic_remove)
overlays -= graphic_remove
/turf/proc/update_air_properties()
var/block = c_airblock(src)
+9 -4
View File
@@ -51,6 +51,9 @@ Class Procs:
/zone/var/datum/gas_mixture/air = new
/zone/var/list/graphic_add = list()
/zone/var/list/graphic_remove = list()
/zone/New()
air_master.add_zone(src)
air.temperature = TCMB
@@ -71,7 +74,7 @@ Class Procs:
if(T.fire)
fire_tiles.Add(T)
air_master.active_fire_zones.Add(src)
T.set_graphic(air.graphic)
T.update_graphic(air.graphic)
/zone/proc/remove(turf/simulated/T)
#ifdef ZASDBG
@@ -83,7 +86,7 @@ Class Procs:
contents.Remove(T)
fire_tiles.Remove(T)
T.zone = null
T.set_graphic(0)
T.update_graphic(graphic_remove = air.graphic)
if(contents.len)
air.group_multiplier = contents.len
else
@@ -128,9 +131,11 @@ Class Procs:
air.group_multiplier = contents.len+1
/zone/proc/tick()
if(air.check_tile_graphic())
if(air.check_tile_graphic(graphic_add, graphic_remove))
for(var/turf/simulated/T in contents)
T.set_graphic(air.graphic)
T.update_graphic(graphic_add, graphic_remove)
graphic_add.len = 0
graphic_remove.len = 0
/zone/proc/dbg_data(mob/M)
M << name
+21 -12
View File
@@ -112,7 +112,7 @@
//Returns the thermal energy change required to get to a new temperature
/datum/gas_mixture/proc/get_thermal_energy_change(var/new_temperature)
return heat_capacity()*(new_temperature - temperature)
return heat_capacity()*(max(new_temperature, 0) - temperature)
//Technically vacuum doesn't have a specific entropy. Just use a really big number (infinity would be ideal) here so that it's easy to add gas to vacuum and hard to take gas out.
#define SPECIFIC_ENTROPY_VACUUM 150000
@@ -124,19 +124,32 @@
. = 0
for(var/g in gas)
var/ratio = gas[g] / total_moles
. += ratio * specific_entropy_gas(g)
. += gas[g] * specific_entropy_gas(g)
. /= total_moles
//Returns the ideal gas specific entropy of a specific gas in the mix. This is the entropy due to that gas per mole of /that/ gas in the mixture, not the entropy due to that gas per mole of gas mixture.
/*
It's arguable whether this should even be called entropy anymore. It's more "based on" entropy than actually entropy now.
Returns the ideal gas specific entropy of a specific gas in the mix. This is the entropy due to that gas per mole of /that/ gas in the mixture, not the entropy due to that gas per mole of gas mixture.
For the purposes of SS13, the specific entropy is just a number that tells you how hard it is to move gas. You can replace this with whatever you want.
Just remember that returning a SMALL number == adding gas to this gas mix is HARD, taking gas away is EASY, and that returning a LARGE number means the opposite (so a vacuum should approach infinity).
So returning a constant/(partial pressure) would probably do what most players expect. Although the version I have implemented below is a bit more nuanced than simply 1/P in that it scales in a way
which is bit more realistic (natural log), and returns a fairly accurate entropy around room temperatures and pressures.
*/
/datum/gas_mixture/proc/specific_entropy_gas(var/gasid)
if (!(gasid in gas) || gas[gasid] == 0)
return SPECIFIC_ENTROPY_VACUUM //that gas isn't here
//group_multiplier gets divided out in volume/gas[gasid] - also, V/(m*T) = R/(partial pressure)
var/molar_mass = gas_data.molar_mass[gasid]
var/specific_heat = gas_data.specific_heat[gasid]
//group_multiplier gets divided out in volume/gas[gasid]
return R_IDEAL_GAS_EQUATION * ( log( (IDEAL_GAS_ENTROPY_CONSTANT*volume/gas[gasid]) * sqrt((molar_mass*specific_heat*temperature)**3) + 1 ) + 5/2 )
return R_IDEAL_GAS_EQUATION * ( log( (IDEAL_GAS_ENTROPY_CONSTANT*volume/(gas[gasid] * temperature)) * (molar_mass*specific_heat*temperature)**(2/3) + 1 ) + 15 )
//alternative, simpler equation
//var/partial_pressure = gas[gasid] * R_IDEAL_GAS_EQUATION * temperature / volume
//return R_IDEAL_GAS_EQUATION * ( log (1 + IDEAL_GAS_ENTROPY_CONSTANT/partial_pressure) + 20 )
//Updates the total_moles count and trims any empty gases.
/datum/gas_mixture/proc/update_values()
@@ -255,12 +268,8 @@
zburn(null)
//Rechecks the gas_mixture and adjusts the graphic list if needed.
/datum/gas_mixture/proc/check_tile_graphic()
//List of new overlays that weren't valid before.
var/list/graphic_add = null
//List of overlays that need to be removed now that they're not valid.
var/list/graphic_remove = null
//Two lists can be passed by reference if you need know specifically which graphics were added and removed.
/datum/gas_mixture/proc/check_tile_graphic(list/graphic_add = null, list/graphic_remove = null)
for(var/g in gas_data.overlay_limit)
if(graphic.Find(gas_data.tile_overlay[g]))
//Overlay is already applied for this gas, check if it's still valid.
+62 -1
View File
@@ -398,4 +398,65 @@ datum/projectile_data
var/r = mixOneColor(weights, reds)
var/g = mixOneColor(weights, greens)
var/b = mixOneColor(weights, blues)
return rgb(r,g,b)
return rgb(r,g,b)
/**
* Gets the highest and lowest pressures from the tiles in cardinal directions
* around us, then checks the difference.
*/
/proc/getOPressureDifferential(var/turf/loc)
var/minp=16777216;
var/maxp=0;
for(var/dir in cardinal)
var/turf/simulated/T=get_turf(get_step(loc,dir))
var/cp=0
if(T && istype(T) && T.zone)
var/datum/gas_mixture/environment = T.return_air()
cp = environment.return_pressure()
else
if(istype(T,/turf/simulated))
continue
if(cp<minp)minp=cp
if(cp>maxp)maxp=cp
return abs(minp-maxp)
/proc/convert_k2c(var/temp)
return ((temp - T0C))
/proc/convert_c2k(var/temp)
return ((temp + T0C))
/proc/getCardinalAirInfo(var/turf/loc, var/list/stats=list("temperature"))
var/list/temps = new/list(4)
for(var/dir in cardinal)
var/direction
switch(dir)
if(NORTH)
direction = 1
if(SOUTH)
direction = 2
if(EAST)
direction = 3
if(WEST)
direction = 4
var/turf/simulated/T=get_turf(get_step(loc,dir))
var/list/rstats = new /list(stats.len)
if(T && istype(T) && T.zone)
var/datum/gas_mixture/environment = T.return_air()
for(var/i=1;i<=stats.len;i++)
if(stats[i] == "pressure")
rstats[i] = environment.return_pressure()
else
rstats[i] = environment.vars[stats[i]]
else if(istype(T, /turf/simulated))
rstats = null // Exclude zone (wall, door, etc).
else if(istype(T, /turf))
// Should still work. (/turf/return_air())
var/datum/gas_mixture/environment = T.return_air()
for(var/i=1;i<=stats.len;i++)
if(stats[i] == "pressure")
rstats[i] = environment.return_pressure()
else
rstats[i] = environment.vars[stats[i]]
temps[direction] = rstats
return temps
+1 -1
View File
@@ -91,7 +91,7 @@
if(master)
var/obj/item/I = usr.get_active_hand()
if(I)
master.attackby(I, usr)
usr.ClickOn(master)
usr.next_move = world.time+2
return 1
@@ -74,6 +74,7 @@ datum/light_source
changed = 1
if (owner.l_color != _l_color)
readrgb(owner.l_color)
changed = 1
if(changed)
+3 -9
View File
@@ -40,7 +40,7 @@
obj/proc/receive_signal(datum/signal/signal, var/receive_method as num, var/receive_param)
Handler from received signals. By default does nothing. Define your own for your object.
Avoid of sending signals directly from this proc, use spawn(-1). Do not use sleep() here please.
Avoid of sending signals directly from this proc, use spawn(-1). DO NOT use sleep() here or call procs that sleep please. If you must, use spawn()
parameters:
signal - see description below. Extract all needed data from the signal before doing sleep(), spawn() or return!
receive_method - may be TRANSMISSION_WIRE or TRANSMISSION_RADIO.
@@ -84,7 +84,7 @@ On the map:
1311 for prison shuttle console (in fact, it is not used)
1435 for status displays
1437 for atmospherics/fire alerts
1439 for engine components
1438 for engine components
1439 for air pumps, air scrubbers, atmo control
1441 for atmospherics - supply tanks
1443 for atmospherics - distribution loop/mixed air tank
@@ -237,13 +237,7 @@ var/global/datum/controller/radio/radio_controller
if(start_point.z!=end_point.z || get_dist(start_point, end_point) > range)
continue
//allow sequential signals before round start, so that every air alarm sounding off at once doesn't cause trouble.
if(!ticker || ticker.current_state < 3)
device.receive_signal(signal, TRANSMISSION_RADIO, frequency)
else
spawn(0)
if(device) //in case the device got destroyed somehow
device.receive_signal(signal, TRANSMISSION_RADIO, frequency)
device.receive_signal(signal, TRANSMISSION_RADIO, frequency)
/datum/radio_frequency/proc/add_listener(obj/device as obj, var/filter as text|null)
if (!filter)
-1
View File
@@ -536,7 +536,6 @@
if("limbs_can_break")
config.limbs_can_break = value
if("run_speed")
config.run_speed = value
if("walk_speed")
-10
View File
@@ -16,7 +16,6 @@ datum/controller/lighting
var/list/changed_turfs = list()
var/changed_turfs_workload_max = 0
var/list/changed_areas = list()
datum/controller/lighting/New()
lighting_states = max( 0, length(icon_states(LIGHTING_ICON))-1 )
@@ -55,18 +54,9 @@ datum/controller/lighting/proc/process()
for(var/i=1, i<=changed_turfs.len, i++)
var/turf/T = changed_turfs[i]
if(T && T.lighting_changed)
changed_areas |= T.loc
T.shift_to_subarea()
changed_turfs.Cut() // reset the changed list
for(var/i = 1; i <= changed_areas.len, i++)
var/area/A = changed_areas[i]
if(A.master != A && !A.contents.len)
A.related -= A
active_areas -= A
all_areas -= A
changed_areas.Cut()
process_cost = (world.timeofday - started)
sleep(processing_interval)
+2 -1
View File
@@ -307,6 +307,7 @@ datum/controller/game_controller/proc/process_machines_power()
var/area/A = active_areas[i]
if(A.powerupdate && A.master == A)
A.powerupdate -= 1
A.clear_usage()
for(var/j = 1; j <= A.related.len; j++)
var/area/SubArea = A.related[j]
for(var/obj/machinery/M in SubArea)
@@ -362,7 +363,7 @@ datum/controller/game_controller/proc/process_powernets()
while(i<=powernets.len)
var/datum/powernet/Powernet = powernets[i]
if(Powernet)
Powernet.reset()
Powernet.process()
i++
continue
powernets.Cut(i,i+1)
-15
View File
@@ -30,20 +30,5 @@
/datum/powernet
var/list/cables = list() // all cables & junctions
var/list/nodes = list() // all APCs & sources
var/newload = 0
var/load = 0
var/newavail = 0
var/avail = 0
var/viewload = 0
var/number = 0
var/perapc = 0 // per-apc avilability
var/netexcess = 0
/datum/debug
var/list/debuglist
+10 -15
View File
@@ -22,11 +22,9 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/datum/supply_packs/New()
manifest += "<ul>"
for(var/path in contains)
for(var/atom/movable/path in contains)
if(!path) continue
var/atom/movable/AM = new path()
manifest += "<li>[AM.name]</li>"
AM.loc = null //just to make sure they're deleted by the garbage collector
manifest += "<li>[initial(path.name)]</li>"
manifest += "</ul>"
/datum/supply_packs/specialops
@@ -348,20 +346,17 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/datum/supply_packs/exoticseeds
name = "Exotic seeds crate"
contains = list(/obj/item/seeds/nettleseed,
contains = list(/obj/item/seeds/replicapod,
/obj/item/seeds/replicapod,
/obj/item/seeds/replicapod,
/obj/item/seeds/replicapod,
/obj/item/seeds/plumpmycelium,
/obj/item/seeds/libertymycelium,
/obj/item/seeds/amanitamycelium,
/obj/item/seeds/reishimycelium,
/obj/item/seeds/bananaseed,
/obj/item/seeds/riceseed,
/obj/item/seeds/eggplantseed,
/obj/item/seeds/limeseed,
/obj/item/seeds/grapeseed,
/obj/item/seeds/eggyseed)
/obj/item/seeds/random,
/obj/item/seeds/random,
/obj/item/seeds/random,
/obj/item/seeds/random,
/obj/item/seeds/random,
/obj/item/seeds/random,
/obj/item/seeds/kudzuseed)
cost = 15
containertype = /obj/structure/closet/crate/hydroponics
containername = "Exotic Seeds crate"
+9 -4
View File
@@ -380,7 +380,7 @@ var/list/ghostteleportlocs = list()
//SYNDICATES
/area/syndicate_mothership
name = "\improper Syndicate Mothership"
name = "\improper Syndicate Base"
icon_state = "syndie-ship"
requires_power = 0
unlimited_power = 1
@@ -1103,7 +1103,8 @@ var/list/ghostteleportlocs = list()
//Solars
/area/solar
requires_power = 0
requires_power = 1
always_unpowered = 1
luminosity = 1
lighting_use_dynamic = 0
@@ -1133,7 +1134,7 @@ var/list/ghostteleportlocs = list()
/area/maintenance/auxsolarport
name = "Fore Port Solar Maintenance"
icon_state = "SolarcontrolA"
icon_state = "SolarcontrolP"
/area/maintenance/starboardsolar
name = "Aft Starboard Solar Maintenance"
@@ -1145,7 +1146,7 @@ var/list/ghostteleportlocs = list()
/area/maintenance/auxsolarstarboard
name = "Fore Starboard Solar Maintenance"
icon_state = "SolarcontrolA"
icon_state = "SolarcontrolS"
/area/maintenance/foresolar
name = "Fore Solar Maintenance"
@@ -1460,6 +1461,10 @@ var/list/ghostteleportlocs = list()
name = "\improper Research and Development"
icon_state = "research"
/area/rnd/docking
name = "\improper Research Dock"
icon_state = "research"
/area/rnd/lab
name = "\improper Research Lab"
icon_state = "toxlab"
+69 -45
View File
@@ -17,14 +17,14 @@
uplink_uses = 10
//Possible roundstart antag types.
var/list/atypes = list("syndi","ling","tater","wiz","ninja","vox","slug","cult")
var/list/atypes = list("syndi","ling","tater","wiz","ninja","vox","cult") //Readd slug when borer spawn is fixed.
var/list/chosen_atypes = list()
var/list/chosen_candidates = list()
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
@@ -48,26 +48,37 @@
var/atype
var/list/candidates = list()
while(atypes.len && candidates.len == 0) //While there are untested antag mode types and we don't have any candidates selected, loop.
// Go through antag types at random until we find one that has candidates.
while(atypes.len && !candidates.len)
atype = pick(atypes)
log_debug("Calamity: checking [atype].")
atypes -= atype
candidates = get_role_candidates(atype)
if(!candidates.len)
log_debug("Calamity mode setup failed, no antag types or candidates left.")
return 0
//Prune out candidates who are already antagonists.
var/list/remove_players = list()
for(var/datum/mind/player in candidates)
if(player.special_role || player.assigned_role == "MODE")
remove_players += player
candidates -= remove_players
log_debug("Calamity: selected [atype] (possible candidates: [candidates.len])")
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
chosen_candidates |= chosen_candidate
candidates -= chosen_candidate
if(atypes.len - i <= 0) break //Not enough valid types left to populate the remaining antag slots.
@@ -81,7 +92,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 +202,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")
@@ -222,7 +244,7 @@
//TO BE FIXED UP. NINJA, NUKE AND CULT IN PARTICULAR ARE FUCKING AWFUL. ~ Z
/datum/game_mode/calamity/proc/spawn_syndicate(var/list/candidates)
var/obj/effect/landmark/uplinklocker = locate("landmark*Syndicate-Uplink")
var/obj/effect/landmark/uplinkdevice = locate("landmark*Syndicate-Uplink")
var/obj/effect/landmark/nuke_spawn = locate("landmark*Nuclear-Bomb")
var/nuke_code = "[rand(10000, 99999)]"
@@ -231,7 +253,7 @@
for(var/datum/mind/player in candidates)
syndicates += player
syndicates |= player
if(spawnpos > synd_spawn.len)
spawnpos = 1
@@ -254,8 +276,9 @@
update_all_synd_icons()
if(uplinklocker)
new /obj/structure/closet/syndicate/nuclear(uplinklocker.loc)
if(uplinkdevice)
var/obj/item/device/radio/uplink/U = new(uplinkdevice.loc)
U.hidden_uplink.uses = 40
if(nuke_spawn && synd_spawn.len > 0)
var/obj/machinery/nuclearbomb/the_bomb = new /obj/machinery/nuclearbomb(nuke_spawn.loc)
the_bomb.r_code = nuke_code
@@ -264,7 +287,7 @@
for(var/datum/mind/player in candidates)
changelings += player
changelings |= player
grant_changeling_powers(player.current)
player.special_role = "Changeling"
@@ -278,7 +301,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 +315,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 +337,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 +370,7 @@
//Create raiders.
for(var/datum/mind/player in candidates)
raiders += player
raiders |= player
//Place them on the shuttle.
var/index = 1
@@ -375,42 +398,43 @@
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)
spawn(10)
for(var/datum/mind/player in candidates)
if(!possible_hosts || possible_hosts.len)
break
if(!possible_hosts || possible_hosts.len)
break
borers += player
var/mob/living/carbon/human/target_host = pick(possible_hosts)
possible_hosts -= target_host
borers |= player
var/mob/living/carbon/human/target_host = pick(possible_hosts)
possible_hosts -= target_host
var/mob/living/simple_animal/borer/roundstart/B = new(target_host)
var/mob/living/simple_animal/borer/roundstart/B = new(target_host)
player.current = B
B.mind = player
B.key = player.key
player.assigned_role = "Cortical Borer"
player.special_role = "Cortical Borer"
player.current = B
B.mind = player
B.key = player.key
player.assigned_role = "Cortical Borer"
player.special_role = "Cortical Borer"
B.host = target_host
B.host_brain.name = target_host.name
B.host_brain.real_name = target_host.real_name
B.host = target_host
B.host_brain.name = target_host.name
B.host_brain.real_name = target_host.real_name
var/datum/organ/external/head = target_host.get_organ("head")
head.implants += B
var/datum/organ/external/head = target_host.get_organ("head")
head.implants += B
player.current << "\blue <b>You are a cortical borer!</b> You are a brain slug that worms its way \
into the head of its victim, lurking out of sight until it needs to take control."
player.current << "You can speak to your victim with <b>say</b>, to other borers with <b>say ;</b>, and use your Alien tab for abilities."
player.current << "\blue <b>You are a cortical borer!</b> You are a brain slug that worms its way \
into the head of its victim, lurking out of sight until it needs to take control."
player.current << "You can speak to your victim with <b>say</b>, to other borers with <b>say ;</b>, and use your Alien tab for abilities."
if(!config.objectives_disabled)
player.objectives += new /datum/objective/borer_survive()
player.objectives += new /datum/objective/borer_reproduce()
player.objectives += new /datum/objective/escape()
if(!config.objectives_disabled)
player.objectives += new /datum/objective/borer_survive()
player.objectives += new /datum/objective/borer_reproduce()
player.objectives += new /datum/objective/escape()
show_objectives(player)
show_objectives(player)
/datum/game_mode/calamity/proc/spawn_cultists(var/list/candidates)
@@ -430,7 +454,7 @@
if(player.assigned_role == job)
continue
cult += player
cult |= player
equip_cultist(player.current)
grant_runeword(player.current)
update_cult_icons_added(player)
+1 -1
View File
@@ -104,7 +104,7 @@ var/list/sacrificed = list()
if(M.stat==2)
continue
usr.say("Mah[pick("'","`")]weyh pleggh at e'ntrath!")
M.visible_message("\red [M] writhes in pain as the markings below him glow a bloody red.", \
M.visible_message("\red [M] writhes in pain as the markings below \him glow a bloody red.", \
"\red AAAAAAHHHH!.", \
"\red You hear an anguished scream.")
if(is_convertable_to_cult(M.mind) && !jobban_isbanned(M, "cultist"))//putting jobban check here because is_convertable uses mind as argument
+1 -1
View File
@@ -142,7 +142,7 @@ Malf AIs/silicons aren't added. Monkeys aren't added. Messes with objective comp
//Here we pick a location and spawn the ninja.
if(ninjastart.len == 0)
for(var/obj/effect/landmark/L in landmarks_list)
if(L.name == "carpspawn")
if(L.name == "carpspawn" && locate(/turf/simulated) in range(7, L))
ninjastart.Add(L)
var/ninja_key = null
+5 -1
View File
@@ -37,6 +37,8 @@ var/global/datum/controller/gameticker/ticker
var/triai = 0//Global holder for Triumvirate
var/round_end_announced = 0 // Spam Prevention. Announce round end only once.
/datum/controller/gameticker/proc/pregame()
login_music = pick(\
/*'sound/music/halloween/skeletons.ogg',\
@@ -360,7 +362,9 @@ var/global/datum/controller/gameticker/ticker
//call a transfer shuttle vote
spawn(50)
world << "\red The round has ended!"
if(!round_end_announced) // Spam Prevention. Now it should announce only once.
world << "\red The round has ended!"
round_end_announced = 1
vote.autotransfer()
return 1
+57 -9
View File
@@ -53,6 +53,7 @@
AI_mind.current.verbs += /mob/living/silicon/ai/proc/choose_modules
AI_mind.current:laws = new /datum/ai_laws/malfunction
AI_mind.current:malf_picker = new /datum/AI_Module/module_picker
AI_mind.current.verbs += /datum/game_mode/malfunction/proc/ai_win // We run checks if AI overtaken the station in the proc itself. This guarantees you won't have to relog when it refuses to appear on takeover completion.
AI_mind.current:show_laws()
greet_malf(AI_mind)
@@ -113,11 +114,8 @@
for(var/datum/mind/AI_mind in malf_ai)
AI_mind.current << "Congratulations you have taken control of the station."
AI_mind.current << "You may decide to blow up the station. You have 60 seconds to choose."
AI_mind.current << "You should have a new verb in the Malfunction tab. If you dont - rejoin the game."
AI_mind.current.verbs += /datum/game_mode/malfunction/proc/ai_win
AI_mind.current << "You can use the \"Explode\" verb to activate the self-destruct"
spawn (600)
for(var/datum/mind/AI_mind in malf_ai)
AI_mind.current.verbs -= /datum/game_mode/malfunction/proc/ai_win
to_nuke_or_not_to_nuke = 0
return
@@ -182,19 +180,69 @@
set category = "Malfunction"
set name = "Explode"
set desc = "Station go boom"
if (!ticker.mode:to_nuke_or_not_to_nuke)
if(!ticker.mode:station_captured)
usr << "You are unable to access the self-destruct system as you don't control the station yet."
return
if(ticker.mode:explosion_in_progress || ticker.mode:station_was_nuked)
usr << "The self-destruct countdown is already triggered!"
return
if(!ticker.mode:to_nuke_or_not_to_nuke) //Takeover IS completed, but 60s timer passed.
usr << "You lost control over self-destruct system. It seems to be behind firewall. Unable to hack"
return
usr << "\red Self-Destruct sequence initialised!"
ticker.mode:to_nuke_or_not_to_nuke = 0
for(var/datum/mind/AI_mind in ticker.mode:malf_ai)
AI_mind.current.verbs -= /datum/game_mode/malfunction/proc/ai_win
ticker.mode:explosion_in_progress = 1
for(var/mob/M in player_list)
M << 'sound/machines/Alarm.ogg'
world << "Self-destructing in 10"
var/obj/item/device/radio/R = new (src)
var/AN = "Self-Destruct System"
R.autosay("Caution. Self-Destruct sequence has been actived. Self-destructing in Ten..", AN)
for (var/i=9 to 1 step -1)
sleep(10)
world << i
var/msg = ""
switch(i)
if(9)
msg = "Nine.."
if(8)
msg = "Eight.."
if(7)
msg = "Seven.."
if(6)
msg = "Six.."
if(5)
msg = "Five.."
if(4)
msg = "Four.."
if(3)
msg = "Three.."
if(2)
msg = "Two.."
if(1)
msg = "One.."
R.autosay(msg, AN)
sleep(10)
var/msg = ""
var/abort = 0
if(ticker.mode:is_malf_ai_dead()) // That. Was. CLOSE.
msg = "Self-destruct sequence has been cancelled."
abort = 1
else
msg = "Zero. Have a nice day."
R.autosay(msg, AN)
if(abort)
ticker.mode:explosion_in_progress = 0
set_security_level("red") //Delta's over
return
enter_allowed = 0
if(ticker)
ticker.station_explosion_cinematic(0,null)
+2 -4
View File
@@ -208,6 +208,7 @@ var/global/list/turf/synd_spawn = list()
/datum/game_mode/proc/equip_syndicate(mob/living/carbon/human/synd_mob)
var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate(synd_mob)
R.set_frequency(SYND_FREQ)
R.freerange = 1
synd_mob.equip_to_slot_or_del(R, slot_l_ear)
synd_mob.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(synd_mob), slot_w_uniform)
@@ -217,11 +218,8 @@ var/global/list/turf/synd_spawn = list()
if(synd_mob.backbag == 2) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(synd_mob), slot_back)
if(synd_mob.backbag == 3) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(synd_mob), slot_back)
if(synd_mob.backbag == 4) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(synd_mob), slot_back)
synd_mob.equip_to_slot_or_del(new /obj/item/ammo_magazine/a12mm(synd_mob), slot_in_backpack)
synd_mob.equip_to_slot_or_del(new /obj/item/ammo_magazine/a12mm(synd_mob), slot_in_backpack)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/pill/cyanide(synd_mob), slot_in_backpack)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/automatic/c20r(synd_mob), slot_belt)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(synd_mob.back), slot_in_backpack)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/pill/cyanide(synd_mob), slot_in_backpack)
/* Commented; nukes now have a suit cycler for changing rig-suits, they don't need to spawn with them
var/obj/item/clothing/suit/space/rig/syndi/new_suit = new(synd_mob)
+16 -8
View File
@@ -123,18 +123,26 @@
set category = "Object"
set src in oview(1)
if(usr.stat || !ishuman(usr) || usr.buckled || usr.restrained())
return
if(src.victim)
usr << "\blue <B>The table is already occupied!</B>"
if(usr.stat || !ishuman(usr) || usr.restrained() || !check_table(usr))
return
take_victim(usr,usr)
/obj/machinery/optable/attackby(obj/item/weapon/W as obj, mob/living/carbon/user as mob)
if (istype(W, /obj/item/weapon/grab))
if(iscarbon(W:affecting))
take_victim(W:affecting,usr)
var/obj/item/weapon/grab/G = W
if(iscarbon(G.affecting) && check_table(G.affecting))
take_victim(G.affecting,usr)
del(W)
return
return
/obj/machinery/optable/proc/check_table(mob/living/carbon/patient as mob)
if(src.victim)
usr << "\blue <B>The table is already occupied!</B>"
return 0
if(patient.buckled)
usr << "\blue <B>Unbuckle first!</B>"
return 0
return 1
+399 -272
View File
@@ -1,4 +1,4 @@
obj/machinery/air_sensor
/obj/machinery/air_sensor
icon = 'icons/obj/stationobjs.dmi'
icon_state = "gsensor1"
name = "Gas Sensor"
@@ -22,59 +22,58 @@ obj/machinery/air_sensor
var/datum/radio_frequency/radio_connection
update_icon()
icon_state = "gsensor[on]"
/obj/machinery/air_sensor/update_icon()
icon_state = "gsensor[on]"
process()
if(on)
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.data["tag"] = id_tag
signal.data["timestamp"] = world.time
/obj/machinery/air_sensor/process()
if(on)
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.data["tag"] = id_tag
signal.data["timestamp"] = world.time
var/datum/gas_mixture/air_sample = return_air()
var/datum/gas_mixture/air_sample = return_air()
if(output&1)
signal.data["pressure"] = num2text(round(air_sample.return_pressure(),0.1),)
if(output&2)
signal.data["temperature"] = round(air_sample.temperature,0.1)
if(output&1)
signal.data["pressure"] = num2text(round(air_sample.return_pressure(),0.1),)
if(output&2)
signal.data["temperature"] = round(air_sample.temperature,0.1)
if(output>4)
var/total_moles = air_sample.total_moles
if(total_moles > 0)
if(output&4)
signal.data["oxygen"] = round(100*air_sample.gas["oxygen"]/total_moles,0.1)
if(output&8)
signal.data["phoron"] = round(100*air_sample.gas["phoron"]/total_moles,0.1)
if(output&16)
signal.data["nitrogen"] = round(100*air_sample.gas["nitrogen"]/total_moles,0.1)
if(output&32)
signal.data["carbon_dioxide"] = round(100*air_sample.gas["carbon_dioxide"]/total_moles,0.1)
else
signal.data["oxygen"] = 0
signal.data["phoron"] = 0
signal.data["nitrogen"] = 0
signal.data["carbon_dioxide"] = 0
signal.data["sigtype"]="status"
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
if(output>4)
var/total_moles = air_sample.total_moles
if(total_moles > 0)
if(output&4)
signal.data["oxygen"] = round(100*air_sample.gas["oxygen"]/total_moles,0.1)
if(output&8)
signal.data["phoron"] = round(100*air_sample.gas["phoron"]/total_moles,0.1)
if(output&16)
signal.data["nitrogen"] = round(100*air_sample.gas["nitrogen"]/total_moles,0.1)
if(output&32)
signal.data["carbon_dioxide"] = round(100*air_sample.gas["carbon_dioxide"]/total_moles,0.1)
else
signal.data["oxygen"] = 0
signal.data["phoron"] = 0
signal.data["nitrogen"] = 0
signal.data["carbon_dioxide"] = 0
signal.data["sigtype"]="status"
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
proc
set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
/obj/machinery/air_sensor/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
initialize()
/obj/machinery/air_sensor/initialize()
set_frequency(frequency)
/obj/machinery/air_sensor/New()
..()
if(radio_controller)
set_frequency(frequency)
New()
..()
if(radio_controller)
set_frequency(frequency)
obj/machinery/computer/general_air_control
/obj/machinery/computer/general_air_control
icon = 'icons/obj/computer.dmi'
icon_state = "tank"
@@ -87,298 +86,426 @@ obj/machinery/computer/general_air_control
var/datum/radio_frequency/radio_connection
circuit = /obj/item/weapon/circuitboard/air_management
attack_hand(mob/user)
if(..(user))
return
user << browse(return_text(),"window=computer")
user.set_machine(src)
onclose(user, "computer")
/obj/machinery/computer/general_air_control/attack_hand(mob/user)
if(..(user))
return
user << browse(return_text(),"window=computer")
user.set_machine(src)
onclose(user, "computer")
process()
..()
src.updateUsrDialog()
/obj/machinery/computer/general_air_control/process()
..()
src.updateUsrDialog()
receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
/obj/machinery/computer/general_air_control/receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
var/id_tag = signal.data["tag"]
if(!id_tag || !sensors.Find(id_tag)) return
var/id_tag = signal.data["tag"]
if(!id_tag || !sensors.Find(id_tag)) return
sensor_information[id_tag] = signal.data
sensor_information[id_tag] = signal.data
proc/return_text()
var/sensor_data
if(sensors.len)
for(var/id_tag in sensors)
var/long_name = sensors[id_tag]
var/list/data = sensor_information[id_tag]
var/sensor_part = "<B>[long_name]</B>:<BR>"
/obj/machinery/computer/general_air_control/proc/return_text()
var/sensor_data
if(sensors.len)
for(var/id_tag in sensors)
var/long_name = sensors[id_tag]
var/list/data = sensor_information[id_tag]
var/sensor_part = "<B>[long_name]</B>:<BR>"
if(data)
if(data["pressure"])
sensor_part += " <B>Pressure:</B> [data["pressure"]] kPa<BR>"
if(data["temperature"])
sensor_part += " <B>Temperature:</B> [data["temperature"]] K<BR>"
if(data["oxygen"]||data["phoron"]||data["nitrogen"]||data["carbon_dioxide"])
sensor_part += " <B>Gas Composition :</B>"
if(data["oxygen"])
sensor_part += "[data["oxygen"]]% O2; "
if(data["nitrogen"])
sensor_part += "[data["nitrogen"]]% N; "
if(data["carbon_dioxide"])
sensor_part += "[data["carbon_dioxide"]]% CO2; "
if(data["phoron"])
sensor_part += "[data["phoron"]]% TX; "
sensor_part += "<HR>"
if(data)
if(data["pressure"])
sensor_part += " <B>Pressure:</B> [data["pressure"]] kPa<BR>"
if(data["temperature"])
sensor_part += " <B>Temperature:</B> [data["temperature"]] K<BR>"
if(data["oxygen"]||data["phoron"]||data["nitrogen"]||data["carbon_dioxide"])
sensor_part += " <B>Gas Composition :</B>"
if(data["oxygen"])
sensor_part += "[data["oxygen"]]% O2; "
if(data["nitrogen"])
sensor_part += "[data["nitrogen"]]% N; "
if(data["carbon_dioxide"])
sensor_part += "[data["carbon_dioxide"]]% CO2; "
if(data["phoron"])
sensor_part += "[data["phoron"]]% TX; "
sensor_part += "<HR>"
else
sensor_part = "<FONT color='red'>[long_name] can not be found!</FONT><BR>"
else
sensor_part = "<FONT color='red'>[long_name] can not be found!</FONT><BR>"
sensor_data += sensor_part
sensor_data += sensor_part
else
sensor_data = "No sensors connected."
else
sensor_data = "No sensors connected."
var/output = {"<B>[name]</B><HR>
var/output = {"<B>[name]</B><HR>
<B>Sensor Data:</B><HR><HR>[sensor_data]"}
return output
return output
proc
set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
/obj/machinery/computer/general_air_control/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
initialize()
set_frequency(frequency)
large_tank_control
icon = 'icons/obj/computer.dmi'
icon_state = "tank"
var/input_tag
var/output_tag
var/list/input_info
var/list/output_info
var/pressure_setting = ONE_ATMOSPHERE * 45
circuit = /obj/item/weapon/circuitboard/air_management/tank_control
/obj/machinery/computer/general_air_control/initialize()
set_frequency(frequency)
return_text()
var/output = ..()
//if(signal.data)
// input_info = signal.data // Attempting to fix intake control -- TLE
/obj/machinery/computer/general_air_control/large_tank_control
icon = 'icons/obj/computer.dmi'
icon_state = "tank"
output += "<B>Tank Control System</B><BR>"
if(input_info)
var/power = (input_info["power"])
var/volume_rate = input_info["volume_rate"]
output += {"<B>Input</B>: [power?("Injecting"):("On Hold")] <A href='?src=\ref[src];in_refresh_status=1'>Refresh</A><BR>
Rate: [volume_rate] L/sec<BR>"}
output += "Command: <A href='?src=\ref[src];in_toggle_injector=1'>Toggle Power</A><BR>"
frequency = 1441
var/input_tag
var/output_tag
else
output += "<FONT color='red'>ERROR: Can not find input port</FONT> <A href='?src=\ref[src];in_refresh_status=1'>Search</A><BR>"
var/list/input_info
var/list/output_info
output += "<BR>"
var/input_flow_setting = 200
var/pressure_setting = ONE_ATMOSPHERE * 45
circuit = /obj/item/weapon/circuitboard/air_management/tank_control
if(output_info)
var/power = (output_info["power"])
var/output_pressure = output_info["internal"]
output += {"<B>Output</B>: [power?("Open"):("On Hold")] <A href='?src=\ref[src];out_refresh_status=1'>Refresh</A><BR>
/obj/machinery/computer/general_air_control/large_tank_control/return_text()
var/output = ..()
//if(signal.data)
// input_info = signal.data // Attempting to fix intake control -- TLE
output += "<B>Tank Control System</B><BR><BR>"
if(input_info)
var/power = (input_info["power"])
var/volume_rate = round(input_info["volume_rate"], 0.1)
output += "<B>Input</B>: [power?("Injecting"):("On Hold")] <A href='?src=\ref[src];in_refresh_status=1'>Refresh</A><BR>Flow Rate Limit: [volume_rate] L/s<BR>"
output += "Command: <A href='?src=\ref[src];in_toggle_injector=1'>Toggle Power</A> <A href='?src=\ref[src];in_set_flowrate=1'>Set Flow Rate</A><BR>"
else
output += "<FONT color='red'>ERROR: Can not find input port</FONT> <A href='?src=\ref[src];in_refresh_status=1'>Search</A><BR>"
output += "Flow Rate Limit: <A href='?src=\ref[src];adj_input_flow_rate=-100'>-</A> <A href='?src=\ref[src];adj_input_flow_rate=-10'>-</A> <A href='?src=\ref[src];adj_input_flow_rate=-1'>-</A> <A href='?src=\ref[src];adj_input_flow_rate=-0.1'>-</A> [round(input_flow_setting, 0.1)] L/s <A href='?src=\ref[src];adj_input_flow_rate=0.1'>+</A> <A href='?src=\ref[src];adj_input_flow_rate=1'>+</A> <A href='?src=\ref[src];adj_input_flow_rate=10'>+</A> <A href='?src=\ref[src];adj_input_flow_rate=100'>+</A><BR>"
output += "<BR>"
if(output_info)
var/power = (output_info["power"])
var/output_pressure = output_info["internal"]
output += {"<B>Output</B>: [power?("Open"):("On Hold")] <A href='?src=\ref[src];out_refresh_status=1'>Refresh</A><BR>
Max Output Pressure: [output_pressure] kPa<BR>"}
output += "Command: <A href='?src=\ref[src];out_toggle_power=1'>Toggle Power</A> <A href='?src=\ref[src];out_set_pressure=1'>Set Pressure</A><BR>"
output += "Command: <A href='?src=\ref[src];out_toggle_power=1'>Toggle Power</A> <A href='?src=\ref[src];out_set_pressure=1'>Set Pressure</A><BR>"
else
output += "<FONT color='red'>ERROR: Can not find output port</FONT> <A href='?src=\ref[src];out_refresh_status=1'>Search</A><BR>"
else
output += "<FONT color='red'>ERROR: Can not find output port</FONT> <A href='?src=\ref[src];out_refresh_status=1'>Search</A><BR>"
output += "Max Output Pressure Set: <A href='?src=\ref[src];adj_pressure=-1000'>-</A> <A href='?src=\ref[src];adj_pressure=-100'>-</A> <A href='?src=\ref[src];adj_pressure=-10'>-</A> <A href='?src=\ref[src];adj_pressure=-1'>-</A> [pressure_setting] kPa <A href='?src=\ref[src];adj_pressure=1'>+</A> <A href='?src=\ref[src];adj_pressure=10'>+</A> <A href='?src=\ref[src];adj_pressure=100'>+</A> <A href='?src=\ref[src];adj_pressure=1000'>+</A><BR>"
output += "Max Output Pressure Set: <A href='?src=\ref[src];adj_pressure=-1000'>-</A> <A href='?src=\ref[src];adj_pressure=-100'>-</A> <A href='?src=\ref[src];adj_pressure=-10'>-</A> <A href='?src=\ref[src];adj_pressure=-1'>-</A> [pressure_setting] kPa <A href='?src=\ref[src];adj_pressure=1'>+</A> <A href='?src=\ref[src];adj_pressure=10'>+</A> <A href='?src=\ref[src];adj_pressure=100'>+</A> <A href='?src=\ref[src];adj_pressure=1000'>+</A><BR>"
return output
return output
receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
/obj/machinery/computer/general_air_control/large_tank_control/receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
var/id_tag = signal.data["tag"]
var/id_tag = signal.data["tag"]
if(input_tag == id_tag)
input_info = signal.data
else if(output_tag == id_tag)
output_info = signal.data
else
..(signal)
if(input_tag == id_tag)
input_info = signal.data
else if(output_tag == id_tag)
output_info = signal.data
else
..(signal)
Topic(href, href_list)
if(..())
return
/obj/machinery/computer/general_air_control/large_tank_control/Topic(href, href_list)
if(..())
return
if(href_list["adj_pressure"])
var/change = text2num(href_list["adj_pressure"])
pressure_setting = between(0, pressure_setting + change, 50*ONE_ATMOSPHERE)
spawn(1)
src.updateUsrDialog()
return
if(href_list["adj_pressure"])
var/change = text2num(href_list["adj_pressure"])
pressure_setting = between(0, pressure_setting + change, 50*ONE_ATMOSPHERE)
spawn(1)
src.updateUsrDialog()
return
if(!radio_connection)
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.source = src
if(href_list["in_refresh_status"])
input_info = null
signal.data = list ("tag" = input_tag, "status")
if(href_list["adj_input_flow_rate"])
var/change = text2num(href_list["adj_input_flow_rate"])
input_flow_setting = between(0, input_flow_setting + change, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors
spawn(1)
src.updateUsrDialog()
return
if(!radio_connection)
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.source = src
if(href_list["in_refresh_status"])
input_info = null
signal.data = list ("tag" = input_tag, "status" = 1)
if(href_list["in_toggle_injector"])
input_info = null
signal.data = list ("tag" = input_tag, "power_toggle")
if(href_list["in_toggle_injector"])
input_info = null
signal.data = list ("tag" = input_tag, "power_toggle" = 1)
if(href_list["out_refresh_status"])
output_info = null
signal.data = list ("tag" = output_tag, "status")
if(href_list["in_set_flowrate"])
input_info = null
signal.data = list ("tag" = input_tag, "set_volume_rate" = "[input_flow_setting]")
if(href_list["out_toggle_power"])
output_info = null
signal.data = list ("tag" = output_tag, "power_toggle")
if(href_list["out_refresh_status"])
output_info = null
signal.data = list ("tag" = output_tag, "status" = 1)
if(href_list["out_set_pressure"])
output_info = null
signal.data = list ("tag" = output_tag, "set_internal_pressure" = "[pressure_setting]")
if(href_list["out_toggle_power"])
output_info = null
signal.data = list ("tag" = output_tag, "power_toggle" = 1)
signal.data["sigtype"]="command"
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
if(href_list["out_set_pressure"])
output_info = null
signal.data = list ("tag" = output_tag, "set_internal_pressure" = "[pressure_setting]")
spawn(5)
src.updateUsrDialog()
signal.data["sigtype"]="command"
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
fuel_injection
icon = 'icons/obj/computer.dmi'
icon_state = "atmos"
spawn(5)
src.updateUsrDialog()
var/device_tag
var/list/device_info
/obj/machinery/computer/general_air_control/supermatter_core
icon = 'icons/obj/computer.dmi'
icon_state = "tank"
var/automation = 0
frequency = 1438
var/input_tag
var/output_tag
var/cutoff_temperature = 2000
var/on_temperature = 1200
circuit = /obj/item/weapon/circuitboard/air_management/injector_control
var/list/input_info
var/list/output_info
process()
if(automation)
if(!radio_connection)
return 0
var/input_flow_setting = 700
var/pressure_setting = 100
circuit = /obj/item/weapon/circuitboard/air_management/supermatter_core
var/injecting = 0
for(var/id_tag in sensor_information)
var/list/data = sensor_information[id_tag]
if(data["temperature"])
if(data["temperature"] >= cutoff_temperature)
injecting = 0
break
if(data["temperature"] <= on_temperature)
injecting = 1
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.source = src
/obj/machinery/computer/general_air_control/supermatter_core/return_text()
var/output = ..()
//if(signal.data)
// input_info = signal.data // Attempting to fix intake control -- TLE
signal.data = list(
"tag" = device_tag,
"power" = injecting,
"sigtype"="command"
)
output += "<B>Core Cooling Control System</B><BR><BR>"
if(input_info)
var/power = (input_info["power"])
var/volume_rate = round(input_info["volume_rate"], 0.1)
output += "<B>Coolant Input</B>: [power?("Injecting"):("On Hold")] <A href='?src=\ref[src];in_refresh_status=1'>Refresh</A><BR>Flow Rate Limit: [volume_rate] L/s<BR>"
output += "Command: <A href='?src=\ref[src];in_toggle_injector=1'>Toggle Power</A> <A href='?src=\ref[src];in_set_flowrate=1'>Set Flow Rate</A><BR>"
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
else
output += "<FONT color='red'>ERROR: Can not find input port</FONT> <A href='?src=\ref[src];in_refresh_status=1'>Search</A><BR>"
output += "Flow Rate Limit: <A href='?src=\ref[src];adj_input_flow_rate=-100'>-</A> <A href='?src=\ref[src];adj_input_flow_rate=-10'>-</A> <A href='?src=\ref[src];adj_input_flow_rate=-1'>-</A> <A href='?src=\ref[src];adj_input_flow_rate=-0.1'>-</A> [round(input_flow_setting, 0.1)] L/s <A href='?src=\ref[src];adj_input_flow_rate=0.1'>+</A> <A href='?src=\ref[src];adj_input_flow_rate=1'>+</A> <A href='?src=\ref[src];adj_input_flow_rate=10'>+</A> <A href='?src=\ref[src];adj_input_flow_rate=100'>+</A><BR>"
..()
output += "<BR>"
return_text()
var/output = ..()
if(output_info)
var/power = (output_info["power"])
var/pressure_limit = output_info["external"]
output += {"<B>Core Outpump</B>: [power?("Open"):("On Hold")] <A href='?src=\ref[src];out_refresh_status=1'>Refresh</A><BR>
Min Core Pressure: [pressure_limit] kPa<BR>"}
output += "Command: <A href='?src=\ref[src];out_toggle_power=1'>Toggle Power</A> <A href='?src=\ref[src];out_set_pressure=1'>Set Pressure</A><BR>"
output += "<B>Fuel Injection System</B><BR>"
if(device_info)
var/power = device_info["power"]
var/volume_rate = device_info["volume_rate"]
output += {"Status: [power?("Injecting"):("On Hold")] <A href='?src=\ref[src];refresh_status=1'>Refresh</A><BR>
else
output += "<FONT color='red'>ERROR: Can not find output port</FONT> <A href='?src=\ref[src];out_refresh_status=1'>Search</A><BR>"
output += "Min Core Pressure Set: <A href='?src=\ref[src];adj_pressure=-100'>-</A> <A href='?src=\ref[src];adj_pressure=-50'>-</A> <A href='?src=\ref[src];adj_pressure=-10'>-</A> <A href='?src=\ref[src];adj_pressure=-1'>-</A> [pressure_setting] kPa <A href='?src=\ref[src];adj_pressure=1'>+</A> <A href='?src=\ref[src];adj_pressure=10'>+</A> <A href='?src=\ref[src];adj_pressure=50'>+</A> <A href='?src=\ref[src];adj_pressure=100'>+</A><BR>"
return output
/obj/machinery/computer/general_air_control/supermatter_core/receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
var/id_tag = signal.data["tag"]
if(input_tag == id_tag)
input_info = signal.data
else if(output_tag == id_tag)
output_info = signal.data
else
..(signal)
/obj/machinery/computer/general_air_control/supermatter_core/Topic(href, href_list)
if(..())
return
if(href_list["adj_pressure"])
var/change = text2num(href_list["adj_pressure"])
pressure_setting = between(0, pressure_setting + change, 10*ONE_ATMOSPHERE)
spawn(1)
src.updateUsrDialog()
return
if(href_list["adj_input_flow_rate"])
var/change = text2num(href_list["adj_input_flow_rate"])
input_flow_setting = between(0, input_flow_setting + change, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors
spawn(1)
src.updateUsrDialog()
return
if(!radio_connection)
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.source = src
if(href_list["in_refresh_status"])
input_info = null
signal.data = list ("tag" = input_tag, "status" = 1)
if(href_list["in_toggle_injector"])
input_info = null
signal.data = list ("tag" = input_tag, "power_toggle" = 1)
if(href_list["in_set_flowrate"])
input_info = null
signal.data = list ("tag" = input_tag, "set_volume_rate" = "[input_flow_setting]")
if(href_list["out_refresh_status"])
output_info = null
signal.data = list ("tag" = output_tag, "status" = 1)
if(href_list["out_toggle_power"])
output_info = null
signal.data = list ("tag" = output_tag, "power_toggle" = 1)
if(href_list["out_set_pressure"])
output_info = null
signal.data = list ("tag" = output_tag, "set_external_pressure" = "[pressure_setting]", "checks" = 1)
signal.data["sigtype"]="command"
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
spawn(5)
src.updateUsrDialog()
/obj/machinery/computer/general_air_control/fuel_injection
icon = 'icons/obj/computer.dmi'
icon_state = "atmos"
var/device_tag
var/list/device_info
var/automation = 0
var/cutoff_temperature = 2000
var/on_temperature = 1200
circuit = /obj/item/weapon/circuitboard/air_management/injector_control
/obj/machinery/computer/general_air_control/fuel_injection/process()
if(automation)
if(!radio_connection)
return 0
var/injecting = 0
for(var/id_tag in sensor_information)
var/list/data = sensor_information[id_tag]
if(data["temperature"])
if(data["temperature"] >= cutoff_temperature)
injecting = 0
break
if(data["temperature"] <= on_temperature)
injecting = 1
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,
"power" = injecting,
"sigtype"="command"
)
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
..()
/obj/machinery/computer/general_air_control/fuel_injection/return_text()
var/output = ..()
output += "<B>Fuel Injection System</B><BR>"
if(device_info)
var/power = device_info["power"]
var/volume_rate = device_info["volume_rate"]
output += {"Status: [power?("Injecting"):("On Hold")] <A href='?src=\ref[src];refresh_status=1'>Refresh</A><BR>
Rate: [volume_rate] L/sec<BR>"}
if(automation)
output += "Automated Fuel Injection: <A href='?src=\ref[src];toggle_automation=1'>Engaged</A><BR>"
output += "Injector Controls Locked Out<BR>"
else
output += "Automated Fuel Injection: <A href='?src=\ref[src];toggle_automation=1'>Disengaged</A><BR>"
output += "Injector: <A href='?src=\ref[src];toggle_injector=1'>Toggle Power</A> <A href='?src=\ref[src];injection=1'>Inject (1 Cycle)</A><BR>"
if(automation)
output += "Automated Fuel Injection: <A href='?src=\ref[src];toggle_automation=1'>Engaged</A><BR>"
output += "Injector Controls Locked Out<BR>"
else
output += "Automated Fuel Injection: <A href='?src=\ref[src];toggle_automation=1'>Disengaged</A><BR>"
output += "Injector: <A href='?src=\ref[src];toggle_injector=1'>Toggle Power</A> <A href='?src=\ref[src];injection=1'>Inject (1 Cycle)</A><BR>"
else
output += "<FONT color='red'>ERROR: Can not find device</FONT> <A href='?src=\ref[src];refresh_status=1'>Search</A><BR>"
else
output += "<FONT color='red'>ERROR: Can not find device</FONT> <A href='?src=\ref[src];refresh_status=1'>Search</A><BR>"
return output
return output
receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
/obj/machinery/computer/general_air_control/fuel_injection/receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
var/id_tag = signal.data["tag"]
var/id_tag = signal.data["tag"]
if(device_tag == id_tag)
device_info = signal.data
else
..(signal)
if(device_tag == id_tag)
device_info = signal.data
else
..(signal)
Topic(href, href_list)
if(..())
return
/obj/machinery/computer/general_air_control/fuel_injection/Topic(href, href_list)
if(..())
return
if(href_list["refresh_status"])
device_info = null
if(!radio_connection)
return 0
if(href_list["refresh_status"])
device_info = null
if(!radio_connection)
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,
"status",
"sigtype"="command"
)
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,
"status" = 1,
"sigtype"="command"
)
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
if(href_list["toggle_automation"])
automation = !automation
if(href_list["toggle_automation"])
automation = !automation
if(href_list["toggle_injector"])
device_info = null
if(!radio_connection)
return 0
if(href_list["toggle_injector"])
device_info = null
if(!radio_connection)
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,
"power_toggle",
"sigtype"="command"
)
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,
"power_toggle" = 1,
"sigtype"="command"
)
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
if(href_list["injection"])
if(!radio_connection)
return 0
if(href_list["injection"])
if(!radio_connection)
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,
"inject",
"sigtype"="command"
)
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.source = src
signal.data = list(
"tag" = device_tag,
"inject" = 1,
"sigtype"="command"
)
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
+2 -1
View File
@@ -49,7 +49,8 @@
icon_state = "grey"
canister_color = "grey"
can_label = 0
/obj/machinery/portable_atmospherics/canister/air/airlock
filled = 0.05
/obj/machinery/portable_atmospherics/canister/empty/oxygen
name = "Canister: \[O2\]"
icon_state = "blue"
+1 -1
View File
@@ -77,7 +77,7 @@
else if(src.target)
var/datum/gas_mixture/environment = target.return_air()
if(environment)
t += "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.temperature,0.01)]&deg;K ([round(environment.temperature-T0C,0.01)]&deg;C)"
t += "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.temperature,0.01)]K ([round(environment.temperature-T0C,0.01)]&deg;C)"
else
t += "The sensor error light is blinking."
else
+12 -1
View File
@@ -373,4 +373,15 @@
tot_rating += MB.rating
storage_capacity["metal"] = tot_rating * 25000
storage_capacity["glass"] = tot_rating * 12500
storage_capacity["glass"] = tot_rating * 12500
/obj/machinery/autolathe/dismantle()
..()
var/list/sheets = list("metal" = /obj/item/stack/sheet/metal, "glass" = /obj/item/stack/sheet/glass)
for(var/mat in stored_material)
var/T = sheets[mat]
var/obj/item/stack/sheet/S = new T
if(stored_material[mat] > S.perunit)
S.amount = round(stored_material[mat] / S.perunit)
S.loc = loc
+2 -2
View File
@@ -79,7 +79,7 @@
var/dat
dat += "<TT><B>Automatic Station Floor Repairer v1.0</B></TT><BR><BR>"
dat += "Status: <A href='?src=\ref[src];operation=start'>[src.on ? "On" : "Off"]</A><BR>"
dat += "Maintenance panel panel is [src.open ? "opened" : "closed"]<BR>"
dat += "Maintenance panel is [src.open ? "opened" : "closed"]<BR>"
dat += "Tiles left: [src.amount]<BR>"
dat += "Behvaiour controls are [src.locked ? "locked" : "unlocked"]<BR>"
if(!src.locked || issilicon(user))
@@ -448,4 +448,4 @@
if (!in_range(src, usr) && src.loc != usr)
return
src.created_name = t
src.created_name = t
+1 -1
View File
@@ -106,7 +106,7 @@
var/dat
dat += "<TT><B>Automatic Medical Unit v1.0</B></TT><BR><BR>"
dat += "Status: <A href='?src=\ref[src];power=1'>[src.on ? "On" : "Off"]</A><BR>"
dat += "Maintenance panel panel is [src.open ? "opened" : "closed"]<BR>"
dat += "Maintenance panel is [src.open ? "opened" : "closed"]<BR>"
dat += "Beaker: "
if (src.reagent_glass)
dat += "<A href='?src=\ref[src];eject=1'>Loaded \[[src.reagent_glass.reagents.total_volume]/[src.reagent_glass.reagents.maximum_volume]\]</a>"
+1 -1
View File
@@ -141,7 +141,7 @@
<TT><B>Automatic Security Unit v[bot_version]</B></TT><BR><BR>
Status: []<BR>
Behaviour controls are [src.locked ? "locked" : "unlocked"]<BR>
Maintenance panel panel is [src.open ? "opened" : "closed"]"},
Maintenance panel is [src.open ? "opened" : "closed"]"},
"<A href='?src=\ref[src];power=1'>[src.on ? "On" : "Off"]</A>" )
+5 -7
View File
@@ -70,13 +70,7 @@
cancelCameraAlarm()
if(can_use())
cameranet.addCamera(src)
for(var/mob/O in mob_list)
if (istype(O.machine, /obj/machinery/computer/security))
var/obj/machinery/computer/security/S = O.machine
if (S.current == src)
O.unset_machine()
O.reset_view(null)
O << "The screen bursts into static."
kick_viewers()
..()
@@ -193,6 +187,10 @@
// now disconnect anyone using the camera
//Apparently, this will disconnect anyone even if the camera was re-activated.
//I guess that doesn't matter since they can't use it anyway?
kick_viewers()
//This might be redundant, because of check_eye()
/obj/machinery/camera/proc/kick_viewers()
for(var/mob/O in player_list)
if (istype(O.machine, /obj/machinery/computer/security))
var/obj/machinery/computer/security/S = O.machine
@@ -9,7 +9,7 @@
matter = list("metal" = 700,"glass" = 300)
// Motion, EMP-Proof, X-Ray
var/list/obj/item/possible_upgrades = list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/phoron, /obj/item/weapon/reagent_containers/food/snacks/grown/carrot)
var/list/obj/item/possible_upgrades = list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/osmium, /obj/item/weapon/stock_parts/scanning_module)
var/list/upgrades = list()
var/state = 0
var/busy = 0
@@ -88,7 +88,8 @@
usr << "No network found please hang up and try your call again."
return
var/temptag = "[get_area(src)] ([rand(1, 999)])"
var/area/camera_area = get_area(src)
var/temptag = "[sanitize(camera_area.name)] ([rand(1, 999)])"
input = strip_html(input(usr, "How would you like to name the camera?", "Set Camera Name", temptag))
state = 4
@@ -125,7 +126,7 @@
// Upgrades!
if(is_type_in_list(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already.
user << "You attach the [W] into the assembly inner circuits."
user << "You attach \the [W] into the assembly inner circuits."
upgrades += W
user.drop_item(W)
W.loc = src
+8 -2
View File
@@ -8,6 +8,8 @@
/obj/machinery/camera/process()
// motion camera event loop
if (stat & (EMPED|NOPOWER))
return
if(!isMotion())
. = PROCESS_KILL
return
@@ -40,16 +42,20 @@
cancelAlarm()
/obj/machinery/camera/proc/cancelAlarm()
if (!status || (stat & NOPOWER))
return 0
if (detectTime == -1)
for (var/mob/living/silicon/aiPlayer in player_list)
if (status) aiPlayer.cancelAlarm("Motion", get_area(src), src)
aiPlayer.cancelAlarm("Motion", get_area(src), src)
detectTime = 0
return 1
/obj/machinery/camera/proc/triggerAlarm()
if (!status || (stat & NOPOWER))
return 0
if (!detectTime) return 0
for (var/mob/living/silicon/aiPlayer in player_list)
if (status) aiPlayer.triggerAlarm("Motion", get_area(src), list(src), src)
aiPlayer.triggerAlarm("Motion", get_area(src), list(src), src)
detectTime = -1
return 1
+19 -6
View File
@@ -53,12 +53,14 @@
// CHECKS
/obj/machinery/camera/proc/isEmpProof()
var/O = locate(/obj/item/stack/sheet/mineral/phoron) in assembly.upgrades
var/O = locate(/obj/item/stack/sheet/mineral/osmium) in assembly.upgrades
return O
/obj/machinery/camera/proc/isXRay()
var/O = locate(/obj/item/weapon/reagent_containers/food/snacks/grown/carrot) in assembly.upgrades
return O
var/obj/item/weapon/stock_parts/scanning_module/O = locate(/obj/item/weapon/stock_parts/scanning_module) in assembly.upgrades
if (O && O.rating >= 2)
return O
return null
/obj/machinery/camera/proc/isMotion()
var/O = locate(/obj/item/device/assembly/prox_sensor) in assembly.upgrades
@@ -67,11 +69,22 @@
// UPGRADE PROCS
/obj/machinery/camera/proc/upgradeEmpProof()
assembly.upgrades.Add(new /obj/item/stack/sheet/mineral/phoron(assembly))
assembly.upgrades.Add(new /obj/item/stack/sheet/mineral/osmium(assembly))
setPowerUsage()
/obj/machinery/camera/proc/upgradeXRay()
assembly.upgrades.Add(new /obj/item/weapon/reagent_containers/food/snacks/grown/carrot(assembly))
assembly.upgrades.Add(new /obj/item/weapon/stock_parts/scanning_module/adv(assembly))
setPowerUsage()
// If you are upgrading Motion, and it isn't in the camera's New(), add it to the machines list.
/obj/machinery/camera/proc/upgradeMotion()
assembly.upgrades.Add(new /obj/item/device/assembly/prox_sensor(assembly))
assembly.upgrades.Add(new /obj/item/device/assembly/prox_sensor(assembly))
setPowerUsage()
/obj/machinery/camera/proc/setPowerUsage()
var/mult = 1
if (isXRay())
mult++
if (isMotion())
mult++
active_power_usage = mult*initial(active_power_usage)
+19 -13
View File
@@ -25,15 +25,16 @@
var/frame_desc = null
var/contain_parts = 1
//Called when the circuitboard is used to contruct a new computer.
/obj/item/weapon/circuitboard/proc/construct_computer(var/obj/machinery/computer/C)
if (istype(C, build_path))
//Called when the circuitboard is used to contruct a new machine.
/obj/item/weapon/circuitboard/proc/construct(var/obj/machinery/M)
if (istype(M, build_path))
return 1
return 0
//Called when a computer is deconstructed to produce a circuitboard
/obj/item/weapon/circuitboard/proc/deconstruct_computer(var/obj/machinery/computer/C)
if (istype(C, build_path))
//Called when a computer is deconstructed to produce a circuitboard.
//Only used by computers, as other machines store their circuitboard instance.
/obj/item/weapon/circuitboard/proc/deconstruct(var/obj/machinery/M)
if (istype(M, build_path))
return 1
return 0
@@ -55,11 +56,11 @@
var/locked = 1
var/emagged = 0
/obj/item/weapon/circuitboard/security/construct_computer(var/obj/machinery/computer/security/C)
/obj/item/weapon/circuitboard/security/construct(var/obj/machinery/computer/security/C)
if (..(C))
C.network = network
/obj/item/weapon/circuitboard/security/deconstruct_computer(var/obj/machinery/computer/security/C)
/obj/item/weapon/circuitboard/security/deconstruct(var/obj/machinery/computer/security/C)
if (..(C))
network = C.network
@@ -132,15 +133,20 @@
/obj/item/weapon/circuitboard/air_management/tank_control
name = "Circuit board (Tank Control)"
build_path = "/obj/machinery/computer/general_air_control/large_tank_control"
frequency = 1441
/obj/item/weapon/circuitboard/air_management/supermatter_core
name = "Circuit board (Core Control)"
build_path = "/obj/machinery/computer/general_air_control/supermatter_core"
frequency = 1438
/obj/item/weapon/circuitboard/air_management/injector_control
name = "Circuit board (Injector Control)"
build_path = "/obj/machinery/computer/general_air_control/fuel_injection"
/obj/item/weapon/circuitboard/air_management/construct_computer(var/obj/machinery/computer/general_air_control/C)
/obj/item/weapon/circuitboard/air_management/construct(var/obj/machinery/computer/general_air_control/C)
if (..(C))
C.frequency = frequency
/obj/item/weapon/circuitboard/air_management/deconstruct_computer(var/obj/machinery/computer/general_air_control/C)
/obj/item/weapon/circuitboard/air_management/deconstruct(var/obj/machinery/computer/general_air_control/C)
if (..(C))
frequency = C.frequency
@@ -216,11 +222,11 @@
origin_tech = "programming=3"
var/contraband_enabled = 0
/obj/item/weapon/circuitboard/supplycomp/construct_computer(var/obj/machinery/computer/supplycomp/SC)
/obj/item/weapon/circuitboard/supplycomp/construct(var/obj/machinery/computer/supplycomp/SC)
if (..(SC))
SC.can_order_contraband = contraband_enabled
/obj/item/weapon/circuitboard/supplycomp/deconstruct_computer(var/obj/machinery/computer/supplycomp/SC)
/obj/item/weapon/circuitboard/supplycomp/deconstruct(var/obj/machinery/computer/supplycomp/SC)
if (..(SC))
contraband_enabled = SC.can_order_contraband
@@ -446,5 +452,5 @@
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
user << "\blue You connect the monitor."
var/B = new src.circuit.build_path ( src.loc )
src.circuit.construct_computer(B)
src.circuit.construct(B)
del(src)
+15 -14
View File
@@ -21,8 +21,10 @@
check_eye(var/mob/user as mob)
if ((get_dist(user, src) > 1 || !( user.canmove ) || user.blinded || !( current ) || !( current.status )) && (!istype(user, /mob/living/silicon)))
if (user.stat || ((get_dist(user, src) > 1 || !( user.canmove ) || user.blinded) && !istype(user, /mob/living/silicon))) //user can't see - not sure why canmove is here.
return null
if ( !current || !current.can_use() ) //camera doesn't work
current = null
user.reset_view(current)
return 1
@@ -46,7 +48,7 @@
D["Cancel"] = "Cancel"
for(var/obj/machinery/camera/C in L)
if(can_access_camera(C))
D[text("[][]", C.c_tag, (C.status ? null : " (Deactivated)"))] = C
D[text("[][]", C.c_tag, (C.can_use() ? null : " (Deactivated)"))] = C
var/t = input(user, "Which camera should you change to?") as null|anything in D
if(!t)
@@ -72,19 +74,18 @@
return 0
proc/switch_to_camera(var/mob/user, var/obj/machinery/camera/C)
if ((get_dist(user, src) > 1 || user.machine != src || user.blinded || !( user.canmove ) || !( C.can_use() )) && (!istype(user, /mob/living/silicon/ai)))
if(!C.can_use() && !isAI(user))
src.current = null
return 0
else
if(isAI(user))
var/mob/living/silicon/ai/A = user
A.eyeobj.setLoc(get_turf(C))
A.client.eye = A.eyeobj
else
src.current = C
use_power(50)
//don't need to check if the camera works for AI because the AI jumps to the camera location and doesn't actually look through cameras.
if(isAI(user))
var/mob/living/silicon/ai/A = user
A.eyeobj.setLoc(get_turf(C))
A.client.eye = A.eyeobj
return 1
if (!C.can_use() || user.stat || (get_dist(user, src) > 1 || user.machine != src || user.blinded || !( user.canmove ) && !istype(user, /mob/living/silicon)))
return 0
src.current = C
use_power(50)
return 1
//Camera control: moving.
proc/jump_on_click(var/mob/user,var/A)
@@ -40,7 +40,7 @@
D["Cancel"] = "Cancel"
for (var/obj/machinery/camera/C in L)
if ( C.network in src.networks )
D[text("[]: [][]", C.network, C.c_tag, (C.status ? null : " (Deactivated)"))] = C
D[text("[]: [][]", C.network, C.c_tag, (C.can_use() ? null : " (Deactivated)"))] = C
var/t = input(user, "Which camera should you change to?") as null|anything in D
+1 -1
View File
@@ -120,7 +120,7 @@
user << "\blue You disconnect the monitor."
A.state = 4
A.icon_state = "4"
M.deconstruct_computer(src)
M.deconstruct(src)
del(src)
else
src.attack_hand(user)
+1 -4
View File
@@ -117,10 +117,7 @@
ui.add_template("mapContent", "crew_monitor_map_content.tmpl")
// adding a template with the key "mapHeader" replaces the map header content
ui.add_template("mapHeader", "crew_monitor_map_header.tmpl")
// we want to show the map by default
ui.set_show_map(1)
ui.set_initial_data(data)
ui.open()
+29 -4
View File
@@ -115,6 +115,7 @@
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
var/obj/machinery/new_machine = new src.circuit.build_path(src.loc)
new_machine.component_parts.Cut()
src.circuit.construct(new_machine)
for(var/obj/O in src)
if(circuit.contain_parts) // things like disposal don't want their parts in them
O.loc = new_machine
@@ -275,10 +276,35 @@ obj/item/weapon/circuitboard/rdserver
"/obj/item/weapon/stock_parts/console_screen" = 1,
"/obj/item/stack/cable_coil" = 2,)
/obj/item/weapon/circuitboard/gas_heater
/obj/item/weapon/circuitboard/unary_atmos
board_type = "machine"
var/machine_dir = SOUTH
var/init_dirs = SOUTH
/obj/item/weapon/circuitboard/unary_atmos/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I,/obj/item/weapon/screwdriver))
machine_dir = turn(machine_dir, 90)
init_dirs = machine_dir
user.visible_message("\blue \The [user] adjusts the jumper on the [src]'s port configuration pins.", "\blue You adjust the jumper on the port configuration pins. Now set to [dir2text(machine_dir)].")
return
/obj/item/weapon/circuitboard/unary_atmos/examine()
..()
usr << "The jumper is connecting the [dir2text(machine_dir)] pins."
/obj/item/weapon/circuitboard/unary_atmos/construct(var/obj/machinery/atmospherics/unary/U)
//TODO: Move this stuff into the relevant constructor when pipe/construction.dm is cleaned up.
U.dir = src.machine_dir
U.initialize_directions = src.init_dirs
U.initialize()
U.build_network()
if (U.node)
U.node.initialize()
U.node.build_network()
/obj/item/weapon/circuitboard/unary_atmos/heater
name = "Circuit Board (Gas Heating System)"
build_path = "/obj/machinery/atmospherics/unary/heater"
board_type = "machine"
origin_tech = "powerstorage=2;engineering=1"
frame_desc = "Requires 5 Pieces of Cable, 1 Matter Bin, and 2 Capacitors."
req_components = list(
@@ -286,10 +312,9 @@ obj/item/weapon/circuitboard/rdserver
"/obj/item/weapon/stock_parts/matter_bin" = 1,
"/obj/item/weapon/stock_parts/capacitor" = 2)
/obj/item/weapon/circuitboard/gas_cooler
/obj/item/weapon/circuitboard/unary_atmos/cooler
name = "Circuit Board (Gas Cooling System)"
build_path = "/obj/machinery/atmospherics/unary/freezer"
board_type = "machine"
origin_tech = "magnets=2;engineering=2"
frame_desc = "Requires 2 Pieces of Cable, 1 Matter Bin, 1 Micro Manipulator, and 2 Capacitors."
req_components = list(
+3 -1
View File
@@ -1,3 +1,5 @@
#define HEAT_CAPACITY_HUMAN 100 //249840 J/K, for a 72 kg person.
/obj/machinery/atmospherics/unary/cryo_cell
name = "cryo cell"
icon = 'icons/obj/cryogenics.dmi'
@@ -10,7 +12,7 @@
use_power = 1
idle_power_usage = 20
active_power_usage = 200
var/temperature_archived
var/mob/living/carbon/occupant = null
var/obj/item/weapon/reagent_containers/glass/beaker = null
+29 -9
View File
@@ -41,6 +41,7 @@ var/global/list/frozen_items = list()
dat += "<hr/><br/><b>Cryogenic Oversight Control</b><br/>"
dat += "<i>Welcome, [user.real_name].</i><br/><br/><hr/>"
dat += "<a href='?src=\ref[src];log=1'>View storage log</a>.<br>"
dat += "<a href='?src=\ref[src];view=1'>View objects</a>.<br>"
dat += "<a href='?src=\ref[src];item=1'>Recover object</a>.<br>"
dat += "<a href='?src=\ref[src];allitems=1'>Recover all objects</a>.<br>"
@@ -65,16 +66,27 @@ var/global/list/frozen_items = list()
user << browse(dat, "window=cryolog")
if(href_list["view"])
var/dat = "<b>Recently stored objects</b><br/><hr/><br/>"
for(var/obj/item/I in frozen_items)
dat += "[I.name]<br/>"
dat += "<hr/>"
user << browse(dat, "window=cryoitems")
else if(href_list["item"])
if(frozen_items.len == 0)
user << "\blue There is nothing to recover from storage."
return
var/obj/item/I = input(usr, "Please choose which object to retrieve.","Object recovery",null) as obj in frozen_items
var/obj/item/I = input(usr, "Please choose which object to retrieve.","Object recovery",null) as null|anything in frozen_items
if(!I)
return
if(!I || frozen_items.len == 0)
user << "\blue There is nothing to recover from storage."
if(!(I in frozen_items))
user << "\blue \The [I] is no longer in storage."
return
visible_message("\blue The console beeps happily as it disgorges \the [I].", 3)
@@ -134,10 +146,10 @@ var/global/list/frozen_items = list()
density = 1
anchored = 1
var/mob/occupant = null // Person waiting to be despawned.
var/orient_right = null // Flips the sprite.
var/time_till_despawn = 9000 // 15 minutes-ish safe period before being despawned.
var/time_entered = 0 // Used to keep track of the safe period.
var/mob/occupant = null // Person waiting to be despawned.
var/orient_right = null // Flips the sprite.
var/time_till_despawn = 18000 // 30 minutes-ish safe period before being despawned.
var/time_entered = 0 // Used to keep track of the safe period.
var/obj/item/device/radio/intercom/announce //
// These items are preserved when the process() despawn proc occurs.
@@ -173,7 +185,6 @@ var/global/list/frozen_items = list()
//Lifted from Unity stasis.dm and refactored. ~Zuhayr
/obj/machinery/cryopod/process()
if(occupant)
//Allow a ten minute gap between entering the pod and actually despawning.
if(world.time - time_entered < time_till_despawn)
return
@@ -187,7 +198,7 @@ var/global/list/frozen_items = list()
if(W.contents.len) //Make sure we catch anything not handled by del() on the items.
for(var/obj/item/O in W.contents)
if(istype(O,/obj/item/weapon/storage/internal)) //Stop eating pockets you fuck!
if(istype(O,/obj/item/weapon/storage/internal)) //Stop eating pockets, you fuck!
continue
O.loc = src
@@ -333,6 +344,7 @@ var/global/list/frozen_items = list()
src.add_fingerprint(M)
/obj/machinery/cryopod/verb/eject()
set name = "Eject Pod"
set category = "Object"
set src in oview(1)
@@ -344,6 +356,14 @@ var/global/list/frozen_items = list()
else
icon_state = "body_scanner_0"
//Eject any items that aren't meant to be in the pod.
var/list/items = src.contents
if(occupant) items -= occupant
if(announce) items -= announce
for(var/obj/item/W in items)
W.loc = get_turf(src)
src.go_out()
add_fingerprint(usr)
return
+2 -1
View File
@@ -28,7 +28,8 @@ obj/machinery/door/airlock/receive_signal(datum/signal/signal)
if(id_tag != signal.data["tag"] || !signal.data["command"]) return
cur_command = signal.data["command"]
execute_current_command()
spawn()
execute_current_command()
obj/machinery/door/airlock/proc/execute_current_command()
if(operating)
+11 -7
View File
@@ -1,4 +1,6 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
#define DOOR_OPEN_LAYER 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6
#define DOOR_CLOSED_LAYER 3.1 //Above most items if closed
/obj/machinery/door
name = "Door"
@@ -8,7 +10,9 @@
anchored = 1
opacity = 1
density = 1
layer = 2.7
layer = DOOR_OPEN_LAYER
var/open_layer = DOOR_OPEN_LAYER
var/closed_layer = DOOR_CLOSED_LAYER
var/secondsElectrified = 0
var/visible = 1
@@ -27,11 +31,11 @@
/obj/machinery/door/New()
. = ..()
if(density)
layer = 3.1 //Above most items if closed
layer = closed_layer
explosion_resistance = initial(explosion_resistance)
update_heat_protection(get_turf(src))
else
layer = 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6
layer = open_layer
explosion_resistance = 0
@@ -142,7 +146,7 @@
user = null
if(!src.requiresID())
user = null
if(src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade)))
if(src.density && ((operable() && istype(I, /obj/item/weapon/card/emag)) || istype(I, /obj/item/weapon/melee/energy/blade)))
flick("door_spark", src)
sleep(6)
open()
@@ -226,7 +230,7 @@
icon_state = "door0"
src.SetOpacity(0)
sleep(10)
src.layer = 2.7
src.layer = open_layer
src.density = 0
explosion_resistance = 0
update_icon()
@@ -250,10 +254,10 @@
if(operating > 0) return
operating = 1
do_animate("closing")
src.density = 1
explosion_resistance = initial(explosion_resistance)
src.layer = 3.1
src.layer = closed_layer
do_animate("closing")
sleep(10)
update_icon()
if(visible && !glass)
+149 -27
View File
@@ -1,5 +1,15 @@
/var/const/OPEN = 1
/var/const/CLOSED = 2
#define FIREDOOR_MAX_PRESSURE_DIFF 25 // kPa
#define FIREDOOR_MAX_TEMP 50 // °C
#define FIREDOOR_MIN_TEMP 0
// Bitflags
#define FIREDOOR_ALERT_HOT 1
#define FIREDOOR_ALERT_COLD 2
// Not used #define FIREDOOR_ALERT_LOWPRESS 4
/obj/machinery/door/firedoor
name = "\improper Emergency Shutter"
desc = "Emergency air-tight shutter, capable of sealing off breached areas."
@@ -8,17 +18,33 @@
req_one_access = list(access_atmospherics, access_engine_equip)
opacity = 0
density = 0
layer = DOOR_OPEN_LAYER - 0.01
open_layer = DOOR_OPEN_LAYER - 0.01 // Just below doors when open
closed_layer = DOOR_CLOSED_LAYER + 0.01 // Just above doors when closed
var/blocked = 0
var/lockdown = 0 // When the door has detected a problem, it locks.
var/pdiff_alert = 0
var/pdiff = 0
var/nextstate = null
var/net_id
var/list/areas_added
var/list/users_to_open
var/list/users_to_open = new
var/next_process_time = 0
power_channel = ENVIRON
use_power = 1
idle_power_usage = 5
var/list/tile_info[4]
var/list/dir_alerts[4] // 4 dirs, bitflags
// MUST be in same order as FIREDOOR_ALERT_*
var/list/ALERT_STATES=list(
"hot",
"cold"
)
/obj/machinery/door/firedoor/New()
. = ..()
for(var/obj/machinery/door/firedoor/F in loc)
@@ -38,7 +64,6 @@
A.all_doors.Add(src)
areas_added += A
/obj/machinery/door/firedoor/Del()
for(var/area/A in areas_added)
A.all_doors.Remove(src)
@@ -48,14 +73,47 @@
/obj/machinery/door/firedoor/examine()
set src in view()
. = ..()
if( islist(users_to_open) && users_to_open.len)
if(get_dist(src, usr) > 1 && !isAI(usr))
return
if(pdiff >= FIREDOOR_MAX_PRESSURE_DIFF)
usr << "<span class='warning'>WARNING: Current pressure differential is [pdiff]kPa! Opening door may result in injury!</span>"
usr << "<b>Sensor readings:</b>"
for(var/index = 1; index <= tile_info.len; index++)
var/o = "&nbsp;&nbsp;"
switch(index)
if(1)
o += "NORTH: "
if(2)
o += "SOUTH: "
if(3)
o += "EAST: "
if(4)
o += "WEST: "
if(tile_info[index] == null)
o += "<span class='warning'>DATA UNAVAILABLE</span>"
usr << o
continue
var/celsius = convert_k2c(tile_info[index][1])
var/pressure = tile_info[index][2]
if(dir_alerts[index] & (FIREDOOR_ALERT_HOT|FIREDOOR_ALERT_COLD))
o += "<span class='warning'>"
else
o += "<span style='color:blue'>"
o += "[celsius]&deg;C</span> "
o += "<span style='color:blue'>"
o += "[pressure]kPa</span></li>"
usr << o
if(islist(users_to_open) && users_to_open.len)
var/users_to_open_string = users_to_open[1]
if(users_to_open.len >= 2)
for(var/i = 2 to users_to_open.len)
users_to_open_string += ", [users_to_open[i]]"
usr << "These people have opened \the [src] during an alert: [users_to_open_string]."
/obj/machinery/door/firedoor/Bumped(atom/AM)
if(p_open || operating)
return
@@ -63,7 +121,7 @@
return ..()
if(istype(AM, /obj/mecha))
var/obj/mecha/mecha = AM
if (mecha.occupant)
if(mecha.occupant)
var/mob/M = mecha.occupant
if(world.time - M.last_bumped <= 10) return //Can bump-open one airlock per second. This is to prevent popup message spam.
M.last_bumped = world.time
@@ -79,12 +137,7 @@
user << "<span class='warning'>\The [src] is welded solid!</span>"
return
if(!allowed(user))
user << "<span class='warning'>Access denied.</span>"
return
var/alarmed = 0
var/alarmed = lockdown
for(var/area/A in areas_added) //Checks if there are fire alarms in any areas associated with that firedoor
if(A.fire || A.air_doors_activated)
alarmed = 1
@@ -100,9 +153,21 @@
user << "\The [src] is not functioning, you'll have to force it open manually."
return
if(alarmed && density && lockdown && !allowed(user))
user << "<span class='warning'>Access denied. Please wait for authorities to arrive, or for the alert to clear.</span>"
return
else
user.visible_message("<span class='notice'>\The [src] [density ? "open" : "close"]s for \the [user].</span>",\
"\The [src] [density ? "open" : "close"]s.",\
"You hear a beep, and a door opening.")
var/needs_to_close = 0
if(density)
if(alarmed)
// Accountability!
users_to_open |= user.name
log_admin("[user]([user.ckey]) has opened an alarming emergency shutter.")
message_admins("<span class='danger'>[user]([user.ckey]) has opened an alarming emergency shutter.</span>")
needs_to_close = 1
spawn()
open()
@@ -128,38 +193,42 @@
var/obj/item/weapon/weldingtool/W = C
if(W.remove_fuel(0, user))
blocked = !blocked
user.visible_message("\red \The [user] [blocked ? "welds" : "unwelds"] \the [src] with \a [W].",\
user.visible_message("<span class='danger'>\The [user] [blocked ? "welds" : "unwelds"] \the [src] with \a [W].</span>",\
"You [blocked ? "weld" : "unweld"] \the [src] with \the [W].",\
"You hear something being welded.")
update_icon()
return
if(blocked)
user << "\red \The [src] is welded solid!"
user << "<span class='danger'>\The [src] is welded solid!</span>"
return
if( istype(C, /obj/item/weapon/crowbar) || ( istype(C,/obj/item/weapon/twohanded/fireaxe) && C:wielded == 1 ) )
if(istype(C, /obj/item/weapon/crowbar) || istype(C,/obj/item/weapon/melee/energy/blade) || istype(C,/obj/item/weapon/twohanded/fireaxe))
if(operating)
return
if( blocked && istype(C, /obj/item/weapon/crowbar) )
user.visible_message("\red \The [user] pries at \the [src] with \a [C], but \the [src] is welded in place!",\
if(blocked && istype(C, /obj/item/weapon/crowbar))
user.visible_message("<span class='danger'>\The [user] pries at \the [src] with \a [C], but \the [src] is welded in place!</span>",\
"You try to pry \the [src] [density ? "open" : "closed"], but it is welded in place!",\
"You hear someone struggle and metal straining.")
return
user.visible_message("\red \The [user] starts to force \the [src] [density ? "open" : "closed"] with \a [C]!",\
if(istype(C,/obj/item/weapon/twohanded/fireaxe))
var/obj/item/weapon/twohanded/fireaxe/F = C
if(!F.wielded)
return
user.visible_message("<span class='danger'>\The [user] starts to force \the [src] [density ? "open" : "closed"] with \a [C]!</span>",\
"You start forcing \the [src] [density ? "open" : "closed"] with \the [C]!",\
"You hear metal strain.")
if(do_after(user,30))
if( istype(C, /obj/item/weapon/crowbar) )
if( stat & (BROKEN|NOPOWER) || !density)
user.visible_message("\red \The [user] forces \the [src] [density ? "open" : "closed"] with \a [C]!",\
if(istype(C, /obj/item/weapon/crowbar))
if(stat & (BROKEN|NOPOWER) || !density)
user.visible_message("<span class='danger'>\The [user] forces \the [src] [density ? "open" : "closed"] with \a [C]!</span>",\
"You force \the [src] [density ? "open" : "closed"] with \the [C]!",\
"You hear metal strain, and a door [density ? "open" : "close"].")
else
user.visible_message("\red \The [user] forces \the [ blocked ? "welded" : "" ] [src] [density ? "open" : "closed"] with \a [C]!",\
user.visible_message("<span class='danger'>\The [user] forces \the [ blocked ? "welded" : "" ] [src] [density ? "open" : "closed"] with \a [C]!</span>",\
"You force \the [ blocked ? "welded" : "" ] [src] [density ? "open" : "closed"] with \the [C]!",\
"You hear metal strain and groan, and a door [density ? "opening" : "closing"].")
if(density)
@@ -170,7 +239,50 @@
close()
return
// CHECK PRESSURE
/obj/machinery/door/firedoor/process()
..()
if(density && next_process_time <= world.time)
next_process_time = world.time + 100 // 10 second delays between process updates
var/changed = 0
lockdown=0
// Pressure alerts
pdiff = getOPressureDifferential(src.loc)
if(pdiff >= FIREDOOR_MAX_PRESSURE_DIFF)
lockdown = 1
if(!pdiff_alert)
pdiff_alert = 1
changed = 1 // update_icon()
else
if(pdiff_alert)
pdiff_alert = 0
changed = 1 // update_icon()
tile_info = getCardinalAirInfo(src.loc,list("temperature","pressure"))
var/old_alerts = dir_alerts
for(var/index = 1; index <= 4; index++)
var/list/tileinfo=tile_info[index]
if(tileinfo==null)
continue // Bad data.
var/celsius = convert_k2c(tileinfo[1])
var/alerts=0
// Temperatures
if(celsius >= FIREDOOR_MAX_TEMP)
alerts |= FIREDOOR_ALERT_HOT
lockdown = 1
else if(celsius <= FIREDOOR_MIN_TEMP)
alerts |= FIREDOOR_ALERT_COLD
lockdown = 1
dir_alerts[index]=alerts
if(dir_alerts != old_alerts)
changed = 1
if(changed)
update_icon()
/obj/machinery/door/firedoor/proc/latetoggle()
if(operating || !nextstate)
@@ -178,6 +290,7 @@
switch(nextstate)
if(OPEN)
nextstate = null
open()
if(CLOSED)
nextstate = null
@@ -189,15 +302,17 @@
return ..()
/obj/machinery/door/firedoor/open(var/forced = 0)
if (!forced)
if (stat & (BROKEN|NOPOWER))
if(!forced)
if(stat & (BROKEN|NOPOWER))
return //needs power to open unless it was forced
else
use_power(360)
else
log_admin("[usr]([usr.ckey]) has forced open an emergency shutter.")
message_admins("<span class='danger'>[usr]([usr.ckey]) has forced open an emergency shutter.</span>")
latetoggle()
return ..()
/obj/machinery/door/firedoor/do_animate(animation)
switch(animation)
if("opening")
@@ -213,6 +328,14 @@
icon_state = "door_closed"
if(blocked)
overlays += "welded"
if(pdiff_alert)
overlays += "palert"
if(dir_alerts)
for(var/d=1;d<=4;d++)
var/cdir = cardinal[d]
for(var/i=1;i<=ALERT_STATES.len;i++)
if(dir_alerts[d] & (1<<(i-1)))
overlays += new/icon(icon,"alert_[ALERT_STATES[i]]", dir=cdir)
else
icon_state = "door_open"
if(blocked)
@@ -220,7 +343,6 @@
return
/obj/machinery/door/firedoor/border_only
//These are playing merry hell on ZAS. Sorry fellas :(
/*
@@ -8,7 +8,8 @@
var/tag_chamber_sensor
var/tag_exterior_sensor
var/tag_interior_sensor
var/tag_mech_sensor
var/tag_airlock_mech_sensor
var/tag_shuttle_mech_sensor
var/tag_secure = 0
/obj/machinery/embedded_controller/radio/airlock/initialize()
@@ -17,7 +17,8 @@
var/tag_chamber_sensor
var/tag_exterior_sensor
var/tag_interior_sensor
var/tag_mech_sensor
var/tag_airlock_mech_sensor
var/tag_shuttle_mech_sensor
var/state = STATE_IDLE
var/target_state = TARGET_NONE
@@ -43,7 +44,8 @@
tag_chamber_sensor = controller.tag_chamber_sensor? controller.tag_chamber_sensor : "[id_tag]_sensor"
tag_exterior_sensor = controller.tag_exterior_sensor
tag_interior_sensor = controller.tag_interior_sensor
tag_mech_sensor = controller.tag_mech_sensor? controller.tag_mech_sensor : "[id_tag]_mech"
tag_airlock_mech_sensor = controller.tag_airlock_mech_sensor? controller.tag_airlock_mech_sensor : "[id_tag]_airlock_mech"
tag_shuttle_mech_sensor = controller.tag_shuttle_mech_sensor? controller.tag_shuttle_mech_sensor : "[id_tag]_shuttle_mech"
memory["secure"] = controller.tag_secure
spawn(10)
@@ -187,7 +189,7 @@
if(memory["purge"])
target_pressure = 0
if(memory["purge"])
target_pressure = 0
@@ -202,7 +204,7 @@
//Check for vacuum - this is set after the pumps so the pumps are aiming for 0
if(!memory["target_pressure"])
memory["target_pressure"] = ONE_ATMOSPHERE * 0.05
if(STATE_PRESSURIZE)
if(memory["chamber_sensor_pressure"] >= memory["target_pressure"] * 0.95)
cycleDoors(target_state)
@@ -303,11 +305,19 @@
signalDoor(tag_exterior_door, command)
signalDoor(tag_interior_door, command)
datum/computer/file/embedded_program/airlock/proc/signal_mech_sensor(var/command, var/sensor)
var/datum/signal/signal = new
signal.data["tag"] = sensor
signal.data["command"] = command
post_signal(signal)
/datum/computer/file/embedded_program/airlock/proc/enable_mech_regulation()
signalDoor(tag_mech_sensor, "enable")
signal_mech_sensor("enable", tag_shuttle_mech_sensor)
signal_mech_sensor("enable", tag_airlock_mech_sensor)
/datum/computer/file/embedded_program/airlock/proc/disable_mech_regulation()
signalDoor(tag_mech_sensor, "disable")
signal_mech_sensor("disable", tag_shuttle_mech_sensor)
signal_mech_sensor("disable", tag_airlock_mech_sensor)
/*----------------------------------------------------------
toggleDoor()
@@ -96,12 +96,13 @@
signal.data["command"] = command
post_signal(signal)
/datum/computer/file/embedded_program/docking/simple/proc/signal_mech_sensor(var/command)
signal_door(command)
///datum/computer/file/embedded_program/docking/simple/proc/signal_mech_sensor(var/command)
// signal_door(command)
// return
/datum/computer/file/embedded_program/docking/simple/proc/open_door()
if(memory["door_status"]["state"] == "closed")
signal_mech_sensor("enable")
//signal_mech_sensor("enable")
signal_door("secure_open")
else if(memory["door_status"]["lock"] == "unlocked")
signal_door("lock")
@@ -109,7 +110,7 @@
/datum/computer/file/embedded_program/docking/simple/proc/close_door()
if(memory["door_status"]["state"] == "open")
signal_door("secure_close")
signal_mech_sensor("disable")
//signal_mech_sensor("disable")
else if(memory["door_status"]["lock"] == "unlocked")
signal_door("lock")
+16 -11
View File
@@ -106,7 +106,7 @@ Class Procs:
var/active_power_usage = 0
var/power_channel = EQUIP
//EQUIP,ENVIRON or LIGHT
var/list/component_parts = null //list of all the parts used to build it, if made from certain kinds of frames.
var/list/component_parts = list() //list of all the parts used to build it, if made from certain kinds of frames.
var/uid
var/manual = 0
var/global/gl_uid = 1
@@ -166,13 +166,12 @@ Class Procs:
use_power = new_use_power
//force area power update
//use_power() forces an area power update on the next tick so have to pass the correct power amount for this tick
if (use_power >= 2)
use_power(active_power_usage)
else if (use_power == 1)
use_power(idle_power_usage)
else
use_power(0)
force_power_update()
/obj/machinery/proc/force_power_update()
var/area/A = get_area(src)
if(A && A.master)
A.master.powerupdate = 1
/obj/machinery/proc/auto_use_power()
if(!powered(power_channel))
@@ -183,9 +182,15 @@ Class Procs:
use_power(active_power_usage,power_channel, 1)
return 1
/obj/machinery/proc/operable(var/additional_flags = 0)
return !inoperable(additional_flags)
/obj/machinery/proc/inoperable(var/additional_flags = 0)
return (stat & (NOPOWER|BROKEN|additional_flags))
/obj/machinery/Topic(href, href_list)
..()
if(stat & (NOPOWER|BROKEN))
if(inoperable())
return 1
if(usr.restrained() || usr.lying || usr.stat)
return 1
@@ -227,7 +232,7 @@ Class Procs:
return src.attack_hand(user)
/obj/machinery/attack_hand(mob/user as mob)
if(stat & (NOPOWER|BROKEN|MAINT))
if(inoperable(MAINT))
return 1
if(user.lying || user.stat)
return 1
@@ -277,7 +282,7 @@ Class Procs:
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
/obj/machinery/proc/shock(mob/user, prb)
if(stat & (BROKEN|NOPOWER))
if(inoperable())
return 0
if(!prob(prb))
return 0
+4 -3
View File
@@ -442,6 +442,7 @@ Buildable meters
var/pipefailtext = "\red There's nothing to connect this pipe section to!" //(with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)"
//TODO: Move all of this stuff into the various pipe constructors.
switch(pipe_type)
if(PIPE_SIMPLE_STRAIGHT, PIPE_SIMPLE_BENT)
var/obj/machinery/atmospherics/pipe/simple/P = new( src.loc )
@@ -522,7 +523,7 @@ Buildable meters
if(PIPE_HE_STRAIGHT, PIPE_HE_BENT)
var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/P = new ( src.loc )
P.dir = src.dir
P.initialize_directions = 0
P.initialize_directions = pipe_dir //this var it's used to know if the pipe is bent or not
P.initialize_directions_he = pipe_dir
//var/turf/T = P.loc
//P.level = T.intact ? 2 : 1
@@ -563,7 +564,7 @@ Buildable meters
M.level = T.intact ? 2 : 1
M.initialize()
if (!M)
usr << "There's nothing to connect this manifold to!" //(with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)"
usr << pipefailtext
return 1
M.build_network()
if (M.node1)
@@ -632,7 +633,7 @@ Buildable meters
M.level = T.intact ? 2 : 1
M.initialize()
if (!M)
usr << "There's nothing to connect this manifold to!" //(with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)"
usr << pipefailtext
return 1
M.build_network()
if (M.node1)
+2 -2
View File
@@ -98,7 +98,7 @@
dat += "<A href='?src=\ref[src];op=temp;val=-5'>-</A>"
dat += " [set_temperature]&deg;C "
dat += " [set_temperature]K ([set_temperature-T0C]&deg;C)"
dat += "<A href='?src=\ref[src];op=temp;val=5'>+</A><BR>"
user.set_machine(src)
@@ -176,7 +176,7 @@
heat_transfer = min(heat_transfer, cop * heating_power) //limit heat transfer by available power
heat_transfer = removed.add_thermal_energy(-heat_transfer) //get the actual heat transfer
var/power_used = abs(heat_transfer)/cop
cell.use(power_used*CELLRATE)
+5 -5
View File
@@ -622,35 +622,35 @@
model_text = "Engineering"
req_access = list(access_construction)
departments = list("Engineering","Atmos")
species = list("Human","Tajaran") //Add Unathi when sprites exist for their suits.
species = list("Human","Tajaran","Skrell","Unathi") //Add Unathi when sprites exist for their suits.
/obj/machinery/suit_cycler/mining
name = "Mining suit cycler"
model_text = "Mining"
req_access = list(access_mining)
departments = list("Mining")
species = list("Human","Tajaran")
species = list("Human","Tajaran","Skrell","Unathi")
/obj/machinery/suit_cycler/security
name = "Security suit cycler"
model_text = "Security"
req_access = list(access_security)
departments = list("Security")
species = list("Human","Tajaran")
species = list("Human","Tajaran","Skrell","Unathi")
/obj/machinery/suit_cycler/medical
name = "Medical suit cycler"
model_text = "Medical"
req_access = list(access_medical)
departments = list("Medical")
species = list("Human","Tajaran")
species = list("Human","Tajaran","Skrell","Unathi")
/obj/machinery/suit_cycler/syndicate
name = "Nonstandard suit cycler"
model_text = "Nonstandard"
req_access = list(access_syndicate)
departments = list("Mercenary")
species = list("Human","Tajaran","Unathi","Skrell")
species = list("Human","Tajaran","Skrell","Unathi")
can_repair = 1
/obj/machinery/suit_cycler/attack_ai(mob/user as mob)
+2 -2
View File
@@ -1298,9 +1298,9 @@
<b>Powercell charge: </b>[isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]<br>
<b>Air source: </b>[use_internal_tank?"Internal Airtank":"Environment"]<br>
<b>Airtank pressure: </b>[tank_pressure]kPa<br>
<b>Airtank temperature: </b>[tank_temperature]&deg;K|[tank_temperature - T0C]&deg;C<br>
<b>Airtank temperature: </b>[tank_temperature]K|[tank_temperature - T0C]&deg;C<br>
<b>Cabin pressure: </b>[cabin_pressure>WARNING_HIGH_PRESSURE ? "<font color='red'>[cabin_pressure]</font>": cabin_pressure]kPa<br>
<b>Cabin temperature: </b> [return_temperature()]&deg;K|[return_temperature() - T0C]&deg;C<br>
<b>Cabin temperature: </b> [return_temperature()]K|[return_temperature() - T0C]&deg;C<br>
<b>Lights: </b>[lights?"on":"off"]<br>
[src.dna?"<b>DNA-locked:</b><br> <span style='font-size:10px;letter-spacing:-1px;'>[src.dna]</span> \[<a href='?src=\ref[src];reset_dna=1'>Reset</a>\]<br>":null]
"}
+1 -8
View File
@@ -49,18 +49,11 @@
var/list/sprite_sheets = null
var/icon_override = null //Used to override hardcoded clothing dmis in human clothing proc.
/* Species-specific sprite sheets for object and inhand sprites
/* Species-specific sprite sheets for inventory sprites
Works similarly to worn sprite_sheets, except the alternate sprites are used when the clothing/refit_for_species() proc is called.
*/
var/list/sprite_sheets_obj = null
//Inhand is not as big a deal as the object sprites, so I'm not sure if these are worth the extra vars.
//Maybe in the future:
//var/list/sprite_sheets_inhand_l = null
//var/list/sprite_sheets_inhand_r = null
//var/icon_l_hand = 'icons/mob/items_lefthand.dmi'
//var/icon_r_hand = 'icons/mob/items_righthand.dmi'
/obj/item/device
icon = 'icons/obj/device.dmi'
@@ -30,6 +30,11 @@
R.uneq_all()
R.hands.icon_state = "nomod"
R.icon_state = "robot"
//world << R.custom_sprite
if(R.custom_sprite == 1)
//world << R.icon_state
icon = 'icons/mob/custom-synthetic.dmi'
R.icon_state = "[R.ckey]-Standard"
del(R.module)
R.module = null
R.camera.network.Remove(list("Engineering","Medical","MINE"))
@@ -251,7 +251,7 @@
singular_name = "phoron glass sheet"
icon_state = "sheet-phoronglass"
matter = list("glass" = 7500)
origin_tech = "materials=3;phoron=2"
origin_tech = "materials=3;phorontech=2"
created_window = /obj/structure/window/phoronbasic
/obj/item/stack/sheet/glass/phoronglass/attack_self(mob/user as mob)
@@ -284,7 +284,7 @@
icon_state = "sheet-phoronrglass"
matter = list("glass" = 7500,"metal" = 1875)
origin_tech = "materials=4;phoron=2"
origin_tech = "materials=4;phorontech=2"
created_window = /obj/structure/window/phoronreinforced
/obj/item/stack/sheet/glass/phoronrglass/attack_self(mob/user as mob)
+51 -172
View File
@@ -4,7 +4,6 @@ RSF
*/
//TODO: WHAT THE FUCK, FIX THIS GARBAGE.
/obj/item/weapon/rsf
name = "\improper Rapid-Service-Fabricator"
desc = "A device used to rapidly deploy service items."
@@ -13,26 +12,29 @@ RSF
opacity = 0
density = 0
anchored = 0.0
var/stored_matter = 0
var/stored_matter = 30
var/mode = 1
flags = TABLEPASS
w_class = 3.0
/obj/item/weapon/rsf/New()
desc = "A RSF. It currently holds [stored_matter]/30 fabrication-units."
return
/obj/item/weapon/rsf/examine()
set src in view(1)
..()
usr << "It currently holds [stored_matter]/30 fabrication-units."
/obj/item/weapon/rsf/attackby(obj/item/weapon/W as obj, mob/user as mob)
..()
if (istype(W, /obj/item/weapon/rcd_ammo))
if ((stored_matter + 10) > 30)
user << "The RSF cant hold any more matter."
user << "The RSF can't hold any more matter."
return
del(W)
stored_matter += 10
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
user << "The RSF now holds [stored_matter]/30 fabrication-units."
desc = "A RSF. It currently holds [stored_matter]/30 fabrication-units."
return
/obj/item/weapon/rsf/attack_self(mob/user as mob)
@@ -64,174 +66,51 @@ RSF
// Change mode
/obj/item/weapon/rsf/afterattack(atom/A, mob/user as mob, proximity)
if(!proximity) return
if (!(istype(A, /obj/structure/table) || istype(A, /turf/simulated/floor)))
if(istype(user,/mob/living/silicon/robot))
var/mob/living/silicon/robot/R = user
if(R.stat || !R.cell || R.cell.charge <= 0)
return
else
if(stored_matter <= 0)
return
if(!istype(A, /obj/structure/table) && !istype(A, /turf/simulated/floor))
return
if (istype(A, /obj/structure/table) && mode == 1)
if (istype(A, /obj/structure/table) && stored_matter >= 1)
user << "Dispensing Dosh..."
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
new /obj/item/weapon/spacecash/c10( A.loc )
if (isrobot(user))
var/mob/living/silicon/robot/engy = user
engy.cell.charge -= 200 //once money becomes useful, I guess changing this to a high ammount, like 500 units a kick, till then, enjoy dosh!
else
stored_matter--
user << "The RSF now holds [stored_matter]/30 fabrication-units."
desc = "A RSF. It currently holds [stored_matter]/30 fabrication-units."
return
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
var/used_energy = 0
var/obj/product
else if (istype(A, /turf/simulated/floor) && mode == 1)
if (istype(A, /turf/simulated/floor) && stored_matter >= 1)
user << "Dispensing Dosh..."
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
new /obj/item/weapon/spacecash/c10( A )
if (isrobot(user))
var/mob/living/silicon/robot/engy = user
engy.cell.charge -= 200 //once money becomes useful, I guess changing this to a high ammount, like 500 units a kick, till then, enjoy dosh!
else
stored_matter--
user << "The RSF now holds [stored_matter]/30 fabrication-units."
desc = "A RSF. It currently holds [stored_matter]/30 fabrication-units."
return
switch(mode)
if(1)
product = new /obj/item/weapon/spacecash/c10()
used_energy = 200
if(2)
product = new /obj/item/weapon/reagent_containers/food/drinks/drinkingglass()
used_energy = 50
if(3)
product = new /obj/item/weapon/paper()
used_energy = 10
if(4)
product = new /obj/item/weapon/pen()
used_energy = 50
if(5)
product = new /obj/item/weapon/storage/pill_bottle/dice()
used_energy = 200
if(6)
product = new /obj/item/clothing/mask/cigarette()
used_energy = 10
else if (istype(A, /obj/structure/table) && mode == 2)
if (istype(A, /obj/structure/table) && stored_matter >= 1)
user << "Dispensing Drinking Glass..."
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
new /obj/item/weapon/reagent_containers/food/drinks/drinkingglass( A.loc )
if (isrobot(user))
var/mob/living/silicon/robot/engy = user
engy.cell.charge -= 50
else
stored_matter--
user << "The RSF now holds [stored_matter]/30 fabrication-units."
desc = "A RSF. It currently holds [stored_matter]/30 fabrication-units."
return
user << "Dispensing [product ? product : "product"]..."
product.loc = get_turf(A)
else if (istype(A, /turf/simulated/floor) && mode == 2)
if (istype(A, /turf/simulated/floor) && stored_matter >= 1)
user << "Dispensing Drinking Glass..."
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
new /obj/item/weapon/reagent_containers/food/drinks/drinkingglass( A )
if (isrobot(user))
var/mob/living/silicon/robot/engy = user
engy.cell.charge -= 50
else
stored_matter--
user << "The RSF now holds [stored_matter]/30 fabrication-units."
desc = "A RSF. It currently holds [stored_matter]/30 fabrication-units."
return
else if (istype(A, /obj/structure/table) && mode == 3)
if (istype(A, /obj/structure/table) && stored_matter >= 1)
user << "Dispensing Paper Sheet..."
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
new /obj/item/weapon/paper( A.loc )
if (isrobot(user))
var/mob/living/silicon/robot/engy = user
engy.cell.charge -= 10
else
stored_matter--
user << "The RSF now holds [stored_matter]/30 fabrication-units."
desc = "A RSF. It currently holds [stored_matter]/30 fabrication-units."
return
else if (istype(A, /turf/simulated/floor) && mode == 3)
if (istype(A, /turf/simulated/floor) && stored_matter >= 1)
user << "Dispensing Paper Sheet..."
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
new /obj/item/weapon/paper( A )
if (isrobot(user))
var/mob/living/silicon/robot/engy = user
engy.cell.charge -= 10
else
stored_matter--
user << "The RSF now holds [stored_matter]/30 fabrication-units."
desc = "A RSF. It currently holds [stored_matter]/30 fabrication-units."
return
else if (istype(A, /obj/structure/table) && mode == 4)
if (istype(A, /obj/structure/table) && stored_matter >= 1)
user << "Dispensing Pen..."
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
new /obj/item/weapon/pen( A.loc )
if (isrobot(user))
var/mob/living/silicon/robot/engy = user
engy.cell.charge -= 50
else
stored_matter--
user << "The RSF now holds [stored_matter]/30 fabrication-units."
desc = "A RSF. It currently holds [stored_matter]/30 fabrication-units."
return
else if (istype(A, /turf/simulated/floor) && mode == 4)
if (istype(A, /turf/simulated/floor) && stored_matter >= 1)
user << "Dispensing Pen..."
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
new /obj/item/weapon/pen( A )
if (isrobot(user))
var/mob/living/silicon/robot/engy = user
engy.cell.charge -= 50
else
stored_matter--
user << "The RSF now holds [stored_matter]/30 fabrication-units."
desc = "A RSF. It currently holds [stored_matter]/30 fabrication-units."
return
else if (istype(A, /obj/structure/table) && mode == 5)
if (istype(A, /obj/structure/table) && stored_matter >= 1)
user << "Dispensing Dice Pack..."
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
new /obj/item/weapon/storage/pill_bottle/dice( A.loc )
if (isrobot(user))
var/mob/living/silicon/robot/engy = user
engy.cell.charge -= 200
else
stored_matter--
user << "The RSF now holds [stored_matter]/30 fabrication-units."
desc = "A RSF. It currently holds [stored_matter]/30 fabrication-units."
return
else if (istype(A, /turf/simulated/floor) && mode == 5)
if (istype(A, /turf/simulated/floor) && stored_matter >= 1)
user << "Dispensing Dice Pack..."
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
new /obj/item/weapon/storage/pill_bottle/dice( A )
if (isrobot(user))
var/mob/living/silicon/robot/engy = user
engy.cell.charge -= 200
else
stored_matter--
user << "The RSF now holds [stored_matter]/30 fabrication-units."
desc = "A RSF. It currently holds [stored_matter]/30 fabrication-units."
return
else if (istype(A, /obj/structure/table) && mode == 6)
if (istype(A, /obj/structure/table) && stored_matter >= 1)
user << "Dispensing Cigarette..."
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
new /obj/item/clothing/mask/cigarette( A.loc )
if (isrobot(user))
var/mob/living/silicon/robot/engy = user
engy.cell.charge -= 10
else
stored_matter--
user << "The RSF now holds [stored_matter]/30 fabrication-units."
desc = "A RSF. It currently holds [stored_matter]/30 fabrication-units."
return
else if (istype(A, /turf/simulated/floor) && mode == 6)
if (istype(A, /turf/simulated/floor) && stored_matter >= 1)
user << "Dispensing Cigarette..."
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
new /obj/item/clothing/mask/cigarette( A )
if (isrobot(user))
var/mob/living/silicon/robot/engy = user
engy.cell.charge -= 10
else
stored_matter--
user << "The RSF now holds [stored_matter]/30 fabrication-units."
desc = "A RSF. It currently holds [stored_matter]/30 fabrication-units."
return
if(isrobot(user))
var/mob/living/silicon/robot/R = user
if(R.cell)
R.cell.use(used_energy)
else
stored_matter--
user << "The RSF now holds [stored_matter]/30 fabrication-units."
+12 -6
View File
@@ -28,7 +28,7 @@
desc = "You can't top the plasma top." //TOTALLY TRADEMARK INFRINGEMENT
origin_tech = "powerstorage=0"
maxcharge = 500
matter = list("glass" = 40)
matter = list("metal" = 700, "glass" = 40)
/obj/item/weapon/cell/crap/empty/New()
..()
@@ -38,18 +38,24 @@
name = "security borg rechargable D battery"
origin_tech = "powerstorage=0"
maxcharge = 600 //600 max charge / 100 charge per shot = six shots
matter = list("glass" = 40)
matter = list("metal" = 700, "glass" = 40)
/obj/item/weapon/cell/secborg/empty/New()
..()
charge = 0
/obj/item/weapon/cell/apc
name = "heavy-duty power cell"
origin_tech = "powerstorage=1"
maxcharge = 5000
matter = list("metal" = 700, "glass" = 50)
/obj/item/weapon/cell/high
name = "high-capacity power cell"
origin_tech = "powerstorage=2"
icon_state = "hcell"
maxcharge = 10000
matter = list("glass" = 60)
matter = list("metal" = 700, "glass" = 60)
/obj/item/weapon/cell/high/empty/New()
..()
@@ -60,7 +66,7 @@
origin_tech = "powerstorage=5"
icon_state = "scell"
maxcharge = 20000
matter = list("glass" = 70)
matter = list("metal" = 700, "glass" = 70)
construction_cost = list("metal"=750,"glass"=100)
/obj/item/weapon/cell/super/empty/New()
@@ -72,7 +78,7 @@
origin_tech = "powerstorage=6"
icon_state = "hpcell"
maxcharge = 30000
matter = list("glass" = 80)
matter = list("metal" = 700, "glass" = 80)
construction_cost = list("metal"=500,"glass"=150,"gold"=200,"silver"=200)
/obj/item/weapon/cell/hyper/empty/New()
@@ -84,7 +90,7 @@
icon_state = "icell"
origin_tech = null
maxcharge = 30000
matter = list("glass"= 80)
matter = list("metal" = 700, "glass" = 80)
use()
return 1
+1 -1
View File
@@ -410,7 +410,7 @@
max_fuel = 40
w_class = 3.0
matter = list("metal" = 70, "glass" = 120)
origin_tech = "engineering=4;phoron=3"
origin_tech = "engineering=4;phorontech=3"
var/last_gen = 0
@@ -115,7 +115,6 @@
new /obj/item/clothing/glasses/sunglasses/sechud(src)
new /obj/item/taperoll/police(src)
new /obj/item/weapon/shield/riot(src)
new /obj/item/weapon/storage/lockbox/loyalty(src)
new /obj/item/weapon/storage/box/flashbangs(src)
new /obj/item/weapon/storage/belt/security(src)
new /obj/item/device/flash(src)
@@ -153,17 +153,23 @@
if(propelled)
var/mob/living/occupant = buckled_mob
unbuckle()
var/def_zone = ran_zone()
var/blocked = occupant.run_armor_check(def_zone, "melee")
occupant.throw_at(A, 3, propelled)
occupant.apply_effect(6, STUN, 0)
occupant.apply_effect(6, WEAKEN, 0)
occupant.apply_effect(6, STUTTER, 0)
occupant.apply_effect(6, STUN, blocked)
occupant.apply_effect(6, WEAKEN, blocked)
occupant.apply_effect(6, STUTTER, blocked)
occupant.apply_damage(10, BRUTE, def_zone, blocked)
playsound(src.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
if(istype(A, /mob/living))
var/mob/living/victim = A
victim.apply_effect(6, STUN, 0)
victim.apply_effect(6, WEAKEN, 0)
victim.apply_effect(6, STUTTER, 0)
victim.take_organ_damage(10)
def_zone = ran_zone()
blocked = victim.run_armor_check(def_zone, "melee")
victim.apply_effect(6, STUN, blocked)
victim.apply_effect(6, WEAKEN, blocked)
victim.apply_effect(6, STUTTER, blocked)
victim.apply_damage(10, BRUTE, def_zone, blocked)
occupant.visible_message("<span class='danger'>[occupant] crashed into \the [A]!</span>")
/obj/structure/stool/bed/chair/office/light
@@ -54,12 +54,27 @@
w_class = 5.0
var/obj/structure/stool/origin = null
/obj/item/weapon/stool/proc/deploy(var/mob/user)
if(!origin)
del src
origin.loc = get_turf(src)
if(user)
user.u_equip(src)
user.visible_message("\blue [user] puts [src] down.", "\blue You put [src] down.")
del src
/obj/item/weapon/stool/dropped(mob/user as mob)
..()
if(istype(loc,/turf/))
deploy(user)
/obj/item/weapon/stool/attack_self(mob/user as mob)
..()
origin.loc = get_turf(src)
user.u_equip(src)
user.visible_message("\blue [user] puts [src] down.", "\blue You put [src] down.")
del src
deploy(user)
/obj/item/weapon/stool/attack(mob/M as mob, mob/user as mob)
if (prob(5) && istype(M,/mob/living))
@@ -147,16 +147,22 @@
else if (propelled)
occupant.throw_at(A, 3, propelled)
occupant.apply_effect(6, STUN, 0)
occupant.apply_effect(6, WEAKEN, 0)
occupant.apply_effect(6, STUTTER, 0)
var/def_zone = ran_zone()
var/blocked = occupant.run_armor_check(def_zone, "melee")
occupant.throw_at(A, 3, propelled)
occupant.apply_effect(6, STUN, blocked)
occupant.apply_effect(6, WEAKEN, blocked)
occupant.apply_effect(6, STUTTER, blocked)
occupant.apply_damage(10, BRUTE, def_zone)
playsound(src.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
if(istype(A, /mob/living))
var/mob/living/victim = A
victim.apply_effect(6, STUN, 0)
victim.apply_effect(6, WEAKEN, 0)
victim.apply_effect(6, STUTTER, 0)
victim.take_organ_damage(10)
def_zone = ran_zone()
blocked = victim.run_armor_check(def_zone, "melee")
victim.apply_effect(6, STUN, blocked)
victim.apply_effect(6, WEAKEN, blocked)
victim.apply_effect(6, STUTTER, blocked)
victim.apply_damage(10, BRUTE, def_zone)
if(pulling)
occupant.visible_message("<span class='danger'>[pulling] has thrusted \the [name] into \the [A], throwing \the [occupant] out of it!</span>")
+3
View File
@@ -55,6 +55,9 @@
heat_capacity = 325000
intact = 0
/turf/simulated/floor/engine/nitrogen
oxygen = 0
/turf/simulated/floor/engine/attackby(obj/item/weapon/C as obj, mob/user as mob)
if(!C)
return
+66 -21
View File
@@ -1492,6 +1492,7 @@
else if(href_list["CentcommFaxReply"])
var/mob/living/carbon/human/H = locate(href_list["CentcommFaxReply"])
var/obj/machinery/faxmachine/fax = locate(href_list["originfax"])
var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use <br> for line breaks.", "Outgoing message from Centcomm", "") as message|null
if(!input) return
@@ -1499,32 +1500,76 @@
var/customname = input(src.owner, "Pick a title for the report", "Title") as text|null
for(var/obj/machinery/faxmachine/F in machines)
if(! (F.stat & (BROKEN|NOPOWER) ) )
if(F == fax)
if(! (F.stat & (BROKEN|NOPOWER) ) )
// animate! it's alive!
flick("faxreceive", F)
// animate! it's alive!
flick("faxreceive", F)
// give the sprite some time to flick
spawn(20)
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( F.loc )
P.name = "[command_name()]- [customname]"
P.info = input
P.update_icon()
// give the sprite some time to flick
spawn(20)
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( F.loc )
P.name = "[command_name()]- [customname]"
P.info = input
P.update_icon()
playsound(F.loc, "sound/items/polaroid1.ogg", 50, 1)
playsound(F.loc, "sound/items/polaroid1.ogg", 50, 1)
// Stamps
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
stampoverlay.icon_state = "paper_stamp-cent"
if(!P.stamped)
P.stamped = new
P.stamped += /obj/item/weapon/stamp
P.overlays += stampoverlay
P.stamps += "<HR><i>This paper has been stamped by the Central Command Quantum Relay.</i>"
// Stamps
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
stampoverlay.icon_state = "paper_stamp-cent"
if(!P.stamped)
P.stamped = new
P.stamped += /obj/item/weapon/stamp
P.overlays += stampoverlay
P.stamps += "<HR><i>This paper has been stamped by the Central Command Quantum Relay.</i>"
src.owner << "Message reply to transmitted successfully."
log_admin("[key_name(src.owner)] replied to a fax message from [key_name(H)]: [input]")
message_admins("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(H)]", 1)
return
src.owner << "/red Unable to locate fax!"
else if(href_list["SolGovFaxReply"])
var/mob/living/carbon/human/H = locate(href_list["SolGovFaxReply"])
var/obj/machinery/faxmachine/fax = locate(href_list["originfax"])
var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use <br> for line breaks.", "Outgoing message from Centcomm", "") as message|null
if(!input) return
var/customname = input(src.owner, "Pick a title for the report", "Title") as text|null
for(var/obj/machinery/faxmachine/F in machines)
if(F == fax)
if(! (F.stat & (BROKEN|NOPOWER) ) )
// animate! it's alive!
flick("faxreceive", F)
// give the sprite some time to flick
spawn(20)
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( F.loc )
P.name = "Sol Government- [customname]"
P.info = input
P.update_icon()
playsound(F.loc, "sound/items/polaroid1.ogg", 50, 1)
// Stamps
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
stampoverlay.icon_state = "paper_stamp-cap"
if(!P.stamped)
P.stamped = new
P.stamped += /obj/item/weapon/stamp
P.overlays += stampoverlay
P.stamps += "<HR><i>This paper has been stamped and encrypted by the Sol Government Quantum Relay.</i>"
src.owner << "Message reply to transmitted successfully."
log_admin("[key_name(src.owner)] replied to a fax message from [key_name(H)]: [input]")
message_admins("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(H)]", 1)
return
src.owner << "/red Unable to locate fax!"
src.owner << "Message reply to transmitted successfully."
log_admin("[key_name(src.owner)] replied to a fax message from [key_name(H)]: [input]")
message_admins("[key_name_admin(src.owner)] replied to a fax message from [key_name_admin(H)]", 1)
else if(href_list["jumpto"])
+8 -4
View File
@@ -125,7 +125,7 @@ var/intercom_range_display_status = 0
feedback_add_details("admin_verb","mIRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
var/list/debug_verbs = list (
/client/proc/do_not_use_these
/client/proc/do_not_use_these
,/client/proc/camera_view
,/client/proc/sec_camera_report
,/client/proc/intercom_view
@@ -158,9 +158,13 @@ var/list/debug_verbs = list (
,/client/proc/ZoneTick
,/client/proc/rebootAirMaster
,/client/proc/hide_debug_verbs
,/client/proc/testZAScolors
,/client/proc/testZAScolors_remove
,/client/proc/setup_supermatter_engine
,/client/proc/testZAScolors
,/client/proc/testZAScolors_remove
,/client/proc/setup_supermatter_engine
,/client/proc/view_power_update_stats_area
,/client/proc/view_power_update_stats_machines
,/client/proc/toggle_power_update_profiling
,/client/proc/atmos_toggle_debug
)
+1 -1
View File
@@ -215,7 +215,7 @@ var/list/forbidden_varedit_object_types = list(
var/list/choices = list("text","num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default")
if(src.holder && src.holder.marked_datum)
choices += "marked datum ([holder.marked_datum.type])"
if(!isnull(default) && default != "num" && !isnull(L[variable]))
if(!isnull(default) && default != "num")
choices += "edit associated variable"
choices += "DELETE FROM LIST"
+2 -1
View File
@@ -1347,7 +1347,8 @@ datum/preferences
organ_data[limb] = "cyborg"
if(second_limb)
organ_data[second_limb] = "cyborg"
if(third_limb && organ_data[third_limb] == "amputated")
organ_data[third_limb] = null
if("organs")
var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Heart", "Eyes")
if(!organ_name) return
+36 -1
View File
@@ -1,6 +1,14 @@
/obj/item/clothing
name = "clothing"
var/list/species_restricted = null //Only these species can wear this kit.
/*
Sprites used when the clothing item is refit. This is done by setting icon_override.
For best results, if this is set then sprite_sheets should be null and vice versa, but that is by no means necessary.
Ideally, sprite_sheets_refit should be used for "hard" clothing items that can't change shape very well to fit the wearer (e.g. helmets, hardsuits),
while sprite_sheets should be used for "flexible" clothing items that do not need to be refitted (e.g. vox wearing jumpsuits).
*/
var/list/sprite_sheets_refit = null
//BS12: Species-restricted clothing check.
/obj/item/clothing/mob_can_equip(M as mob, slot)
@@ -41,6 +49,11 @@
species_restricted = list(target_species)
//Set icon
if (sprite_sheets_refit && (target_species in sprite_sheets_refit))
icon_override = sprite_sheets_refit[target_species]
else
icon_override = initial(icon_override)
if (sprite_sheets_obj && (target_species in sprite_sheets_obj))
icon = sprite_sheets_obj[target_species]
else
@@ -57,12 +70,16 @@
species_restricted = list(target_species)
//Set icon
if (sprite_sheets_refit && (target_species in sprite_sheets_refit))
icon_override = sprite_sheets_refit[target_species]
else
icon_override = initial(icon_override)
if (sprite_sheets_obj && (target_species in sprite_sheets_obj))
icon = sprite_sheets_obj[target_species]
else
icon = initial(icon)
//Ears: headsets, earmuffs and tiny objects
/obj/item/clothing/ears
name = "ears"
@@ -182,6 +199,24 @@ BLIND // can't see anything
/obj/item/clothing/gloves/proc/Touch(var/atom/A, var/proximity)
return 0 // return 1 to cancel attack_hand()
/obj/item/clothing/gloves/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/weapon/scalpel))
if (clipped)
user << "<span class='notice'>The [src] have already been clipped!</span>"
update_icon()
return
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
user.visible_message("\red [user] cuts the fingertips off of the [src].","\red You cut the fingertips off of the [src].")
clipped = 1
name = "mangled [name]"
desc = "[desc]<br>They have had the fingertips cut off of them."
if("exclude" in species_restricted)
species_restricted -= "Unathi"
species_restricted -= "Tajaran"
return
//Head
/obj/item/clothing/head
name = "head"
+6
View File
@@ -4,6 +4,12 @@
icon_state = "boxing"
item_state = "boxing"
/obj/item/clothing/gloves/boxing/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/weapon/scalpel))
user << "<span class='notice'>That won't work.</span>" //Nope
return
..()
/obj/item/clothing/gloves/boxing/green
icon_state = "boxinggreen"
item_state = "boxinggreen"
+8 -5
View File
@@ -86,29 +86,32 @@
item_color = "orange"
var/obj/item/weapon/handcuffs/chained = null
/obj/item/clothing/shoes/orange/proc/attach_cuffs(var/obj/item/weapon/handcuffs/cuffs)
/obj/item/clothing/shoes/orange/proc/attach_cuffs(var/obj/item/weapon/handcuffs/cuffs, mob/user as mob)
if (src.chained) return
user.drop_item()
cuffs.loc = src
src.chained = cuffs
src.slowdown = 15
src.icon_state = "orange1"
/obj/item/clothing/shoes/orange/proc/remove_cuffs()
/obj/item/clothing/shoes/orange/proc/remove_cuffs(mob/user as mob)
if (!src.chained) return
src.chained.loc = get_turf(src)
user.put_in_hands(src.chained)
src.chained.add_fingerprint(user)
src.slowdown = initial(slowdown)
src.icon_state = "orange"
src.chained = null
/obj/item/clothing/shoes/orange/attack_self(mob/user as mob)
..()
remove_cuffs()
remove_cuffs(user)
/obj/item/clothing/shoes/orange/attackby(H as obj, mob/user as mob)
..()
if (istype(H, /obj/item/weapon/handcuffs))
attach_cuffs(H)
attach_cuffs(H, user)
+1 -1
View File
@@ -30,7 +30,7 @@
w_class = 3
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank/emergency_oxygen)
slowdown = 1
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 60)
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 100)
allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/crowbar, \
/obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters, /obj/item/weapon/wrench, /obj/item/device/multitool, \
/obj/item/device/radio, /obj/item/device/analyzer, /obj/item/weapon/gun/energy/laser, /obj/item/weapon/gun/energy/pulse_rifle, \
+14 -18
View File
@@ -15,13 +15,15 @@
//Species-specific stuff.
species_restricted = list("exclude","Unathi","Tajaran","Skrell","Diona","Vox")
sprite_sheets = list(
sprite_sheets_refit = list(
"Unathi" = 'icons/mob/species/unathi/helmet.dmi',
"Tajaran" = 'icons/mob/species/tajaran/helmet.dmi',
"Skrell" = 'icons/mob/species/skrell/helmet.dmi'
"Skrell" = 'icons/mob/species/skrell/helmet.dmi',
)
sprite_sheets_obj = list(
"Unathi" = 'icons/obj/clothing/species/unathi/hats.dmi',
"Tajaran" = 'icons/obj/clothing/species/tajaran/hats.dmi',
"Skrell" = 'icons/obj/clothing/species/skrell/hats.dmi',
)
attack_self(mob/user)
@@ -63,13 +65,15 @@
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
species_restricted = list("exclude","Unathi","Tajaran","Diona","Vox")
sprite_sheets = list(
sprite_sheets_refit = list(
"Unathi" = 'icons/mob/species/unathi/suit.dmi',
"Tajaran" = 'icons/mob/species/tajaran/suit.dmi',
"Skrell" = 'icons/mob/species/skrell/suit.dmi'
"Skrell" = 'icons/mob/species/skrell/suit.dmi',
)
sprite_sheets_obj = list(
"Unathi" = 'icons/obj/clothing/species/unathi/suits.dmi',
"Tajaran" = 'icons/obj/clothing/species/tajaran/suits.dmi',
"Skrell" = 'icons/obj/clothing/species/skrell/suits.dmi',
)
//Breach thresholds, should ideally be inherited by most (if not all) hardsuits.
@@ -322,14 +326,16 @@
icon_state = "rig0-white"
item_state = "ce_helm"
item_color = "white"
sprite_sheets = null
sprite_sheets_refit = null
sprite_sheets_obj = null
/obj/item/clothing/suit/space/rig/engineering/chief
icon_state = "rig-white"
name = "advanced hardsuit"
desc = "An advanced suit that protects against hazardous, low pressure environments. Shines with a high polish."
item_state = "ce_hardsuit"
sprite_sheets = null
sprite_sheets_refit = null
sprite_sheets_obj = null
//Mining rig
/obj/item/clothing/head/helmet/space/rig/mining
@@ -359,11 +365,6 @@
siemens_coefficient = 0.6
var/obj/machinery/camera/camera
species_restricted = list("exclude","Unathi","Tajaran","Skrell","Vox")
sprite_sheets_obj = list(
"Tajaran" = 'icons/obj/clothing/species/tajaran/hats.dmi',
"Unathi" = 'icons/obj/clothing/species/unathi/hats.dmi',
"Skrell" = 'icons/obj/clothing/species/skrell/hats.dmi',
)
/obj/item/clothing/head/helmet/space/rig/syndi/attack_self(mob/user)
@@ -392,11 +393,6 @@
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs)
siemens_coefficient = 0.6
species_restricted = list("exclude","Unathi","Tajaran","Skrell","Vox")
sprite_sheets_obj = list(
"Tajaran" = 'icons/obj/clothing/species/tajaran/suits.dmi',
"Unathi" = 'icons/obj/clothing/species/unathi/suits.dmi',
"Skrell" = 'icons/obj/clothing/species/skrell/suits.dmi',
)
//Wizard Rig
@@ -409,7 +405,7 @@
unacidable = 1 //No longer shall our kind be foiled by lone chemists with spray bottles!
armor = list(melee = 40, bullet = 20, laser = 20,energy = 20, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.7
sprite_sheets = null
sprite_sheets_refit = null
sprite_sheets_obj = null
/obj/item/clothing/suit/space/rig/wizard
@@ -422,7 +418,7 @@
unacidable = 1
armor = list(melee = 40, bullet = 20, laser = 20,energy = 20, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.7
sprite_sheets = null
sprite_sheets_refit = null
sprite_sheets_obj = null
//Medical Rig
+1 -1
View File
@@ -102,7 +102,7 @@
w_class = 4//bulky item
gas_transfer_coefficient = 0.90
permeability_coefficient = 0.50
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS|FEET
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/clothing/head/radiation,/obj/item/clothing/mask/gas)
slowdown = 1.5
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 100)
+42 -22
View File
@@ -7,14 +7,39 @@
icon_state = "evidenceobj"
item_state = ""
w_class = 2
var/obj/item/stored_item = null
/obj/item/weapon/evidencebag/afterattack(obj/item/I, mob/user as mob, proximity)
if(!proximity) return
if(!in_range(I, user))
/obj/item/weapon/evidencebag/MouseDrop(var/obj/item/I as obj)
if (!ishuman(usr))
return
if(!istype(I) || I.anchored == 1)
return ..()
var/mob/living/carbon/human/user = usr
if (!(user.l_hand == src || user.r_hand == src))
return //bag must be in your hands to use
if (isturf(I.loc))
if (!user.Adjacent(I))
return
else
//If it isn't on the floor. Do some checks to see if it's in our hands or a box. Otherwise give up.
if(istype(I.loc,/obj/item/weapon/storage)) //in a container.
var/sdepth = I.storage_depth(user)
if (sdepth == -1 || sdepth > 1)
return //too deeply nested to access
var/obj/item/weapon/storage/U = I.loc
user.client.screen -= I
U.contents.Remove(I)
else if(user.l_hand == I) //in a hand
user.drop_l_hand()
else if(user.r_hand == I) //in a hand
user.drop_r_hand()
else
return
if(!istype(I) || I.anchored)
return
if(istype(I, /obj/item/weapon/evidencebag))
user << "<span class='notice'>You find putting an evidence bag in another evidence bag to be slightly absurd.</span>"
@@ -26,19 +51,7 @@
if(contents.len)
user << "<span class='notice'>[src] already has something inside it.</span>"
return ..()
if(!isturf(I.loc)) //If it isn't on the floor. Do some checks to see if it's in our hands or a box. Otherwise give up.
if(istype(I.loc,/obj/item/weapon/storage)) //in a container.
var/obj/item/weapon/storage/U = I.loc
user.client.screen -= I
U.contents.Remove(I)
else if(user.l_hand == I) //in a hand
user.drop_l_hand()
else if(user.r_hand == I) //in a hand
user.drop_r_hand()
else
return
return
user.visible_message("[user] puts [I] into [src]", "You put [I] inside [src].",\
"You hear a rustle as someone puts something into a plastic bag.")
@@ -55,28 +68,35 @@
overlays += img
overlays += "evidence" //should look nicer for transparent stuff. not really that important, but hey.
desc = "An evidence bag containing [I]. [I.desc]"
desc = "An evidence bag containing [I]."
I.loc = src
stored_item = I
w_class = I.w_class
return
/obj/item/weapon/evidencebag/attack_self(mob/user as mob)
if(contents.len)
var/obj/item/I = contents[1]
var/obj/item/I = stored_item
user.visible_message("[user] takes [I] out of [src]", "You take [I] out of [src].",\
"You hear someone rustle around in a plastic bag, and remove something.")
overlays.Cut() //remove the overlays
user.put_in_hands(I)
w_class = 1
stored_item = null
w_class = initial(w_class)
icon_state = "evidenceobj"
desc = "An empty evidence bag."
else
user << "[src] is empty."
icon_state = "evidenceobj"
return
/obj/item/weapon/evidencebag/examine()
..()
if (stored_item) stored_item.examine()
/obj/item/weapon/storage/box/evidence
name = "evidence bag box"
desc = "A box claiming to contain evidence bags."
+1 -1
View File
@@ -6,7 +6,7 @@
/datum/event/borer_infestation
announceWhen = 400
var/spawncount = 1
var/spawncount = 5
var/successSpawn = 0 //So we don't make a command report if nothing gets spawned.
/datum/event/borer_infestation/setup()
+11 -3
View File
@@ -44,15 +44,23 @@ var/list/event_last_fired = list()
//see:
// Code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events.dm
// Code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events_Mundane.dm
possibleEvents[/datum/event/economic_event] = 300
possibleEvents[/datum/event/trivial_news] = 400
possibleEvents[/datum/event/mundane_news] = 300
if(ticker.mode && ticker.mode.name == "calamity") //Calamity mode messes with some events.
possibleEvents[/datum/event/borer_infestation] = 400
possibleEvents[/datum/event/economic_event] = 25
possibleEvents[/datum/event/trivial_news] = 25
possibleEvents[/datum/event/mundane_news] = 25
else
possibleEvents[/datum/event/economic_event] = 300
possibleEvents[/datum/event/trivial_news] = 400
possibleEvents[/datum/event/mundane_news] = 300
possibleEvents[/datum/event/pda_spam] = max(min(25, player_list.len) * 4, 200)
possibleEvents[/datum/event/money_lotto] = max(min(5, player_list.len), 50)
if(account_hack_attempted)
possibleEvents[/datum/event/money_hacker] = max(min(25, player_list.len) * 4, 200)
possibleEvents[/datum/event/carp_migration] = 20 + 10 * active_with_role["Engineer"]
possibleEvents[/datum/event/brand_intelligence] = 20 + 25 * active_with_role["Janitor"]
+1 -1
View File
@@ -32,7 +32,7 @@ var/scheduledEvent = null
playercount_modifier = 0.8
if(ticker.mode && ticker.mode.name == "calamity") //Calamity mode lowers the time required between events drastically.
playercount_modifier = playercount_modifier * 0.3
playercount_modifier = playercount_modifier * 0.5
var/next_event_delay = rand(eventTimeLower, eventTimeUpper) * playercount_modifier
scheduledEvent = world.timeofday + next_event_delay
+6 -4
View File
@@ -18,7 +18,9 @@
var/datum/seed/grown_seed
var/datum/reagents/grown_reagents
if(istype(target,/obj/item/weapon/reagent_containers/food/snacks/grown))
if(istype(target,/obj/structure/rack) || istype(target,/obj/structure/table))
return ..()
else if(istype(target,/obj/item/weapon/reagent_containers/food/snacks/grown))
var/obj/item/weapon/reagent_containers/food/snacks/grown/G = target
grown_seed = seed_types[G.plantname]
@@ -166,7 +168,7 @@
/obj/item/weapon/plantspray
icon = 'icons/obj/hydroponics.dmi'
item_state = "spray"
flags = TABLEPASS | OPENCONTAINER | FPRINT | NOBLUDGEON
flags = TABLEPASS | FPRINT | NOBLUDGEON
slot_flags = SLOT_BELT
throwforce = 4
w_class = 2.0
@@ -181,13 +183,13 @@
name = "weed-spray"
desc = "It's a toxic mixture, in spray form, to kill small weeds."
icon_state = "weedspray"
weed_kill_str = 2
weed_kill_str = 6
/obj/item/weapon/plantspray/pests
name = "pest-spray"
desc = "It's some pest eliminator spray! <I>Do not inhale!</I>"
icon_state = "pestspray"
pest_kill_str = 2
pest_kill_str = 6
/obj/item/weapon/plantspray/pests/old
name = "bottle of pestkiller"
+51 -32
View File
@@ -7,14 +7,15 @@
density = 1
anchored = 1
flags = OPENCONTAINER
volume = 100
var/draw_warnings = 1 //Set to 0 to stop it from drawing the alert lights.
// Plant maintenance vars.
var/waterlevel = 100 // Water level (max 100)
var/nutrilevel = 10 // Nutrient level (max 10)
var/waterlevel = 100 // Water (max 100)
var/nutrilevel = 100 // Nutrient (max 100)
var/pestlevel = 0 // Pests (max 10)
var/weedlevel = 0 // Weeds (max 10)s
var/weedlevel = 0 // Weeds (max 10)
// Tray state vars.
var/dead = 0 // Is it dead?
@@ -25,6 +26,7 @@
var/yield_mod = 0 // Modifier to yield
var/mutation_mod = 0 // Modifier to mutation chance
var/toxins = 0 // Toxicity in the tray?
var/mutation_level = 0 // When it hits 100, the plant mutates.
// Mechanical concerns.
var/health = 0 // Plant health.
@@ -33,6 +35,7 @@
var/cycledelay = 150 // Delay per cycle.
var/closed_system // If set, the tray will attempt to take atmos from a pipe.
var/force_update // Set this to bypass the cycle time check.
var/obj/temp_chem_holder // Something to hold reagents during process_reagents()
// Seed details/line data.
var/datum/seed/seed = null // The currently planted seed
@@ -104,7 +107,7 @@
"cryoxadone" = list( 3, 0, 0 ),
"ammonia" = list( 0.5, 0, 0 ),
"diethylamine" = list( 1, 0, 0 ),
"nutriment" = list( 0.5, 1, 0 ),
"nutriment" = list( 0.5, 0.1, 0 ),
"radium" = list( -1.5, 0, 0.2 ),
"adminordrazine" = list( 1, 1, 1 ),
"robustharvest" = list( 0, 0.2, 0 ),
@@ -114,12 +117,14 @@
// Mutagen list specifies minimum value for the mutation to take place, rather
// than a bound as the lists above specify.
var/global/list/mutagenic_reagents = list(
"radium" = list(8,3),
"mutagen" = list(3,8)
"radium" = 3,
"mutagen" = 8
)
/obj/machinery/portable_atmospherics/hydroponics/New()
..()
temp_chem_holder = new()
temp_chem_holder.create_reagents(10)
create_reagents(200)
connect()
update_icon()
@@ -162,9 +167,12 @@
return
lastcycle = world.time
// Mutation level drops each main tick.
mutation_level -= rand(2,4)
// Weeds like water and nutrients, there's a chance the weed population will increase.
// Bonus chance if the tray is unoccupied.
if(waterlevel > 10 && nutrilevel > 2 && prob(isnull(seed) ? 6 : 3))
if(waterlevel > 10 && nutrilevel > 2 && prob(isnull(seed) ? 5 : 2))
weedlevel += 1 * HYDRO_SPEED_MULTIPLIER
// There's a chance for a weed explosion to happen if the weeds take over.
@@ -179,13 +187,19 @@
return
// Advance plant age.
if(prob(25)) age += 1 * HYDRO_SPEED_MULTIPLIER
if(prob(30)) age += 1 * HYDRO_SPEED_MULTIPLIER
//Highly mutable plants have a chance of mutating every tick.
if(seed.immutable == -1)
var/mut_prob = rand(1,100)
if(mut_prob <= 5) mutate(mut_prob == 1 ? 2 : 1)
// Other plants also mutate if enough mutagenic compounds have been added.
if(!seed.immutable)
if(prob(min(mutation_level,100)))
mutate((rand(100) < 25) ? 2 : 1)
mutation_level = 0
// Maintain tray nutrient and water levels.
if(seed.nutrient_consumption > 0 && nutrilevel > 0 && prob(25))
nutrilevel -= max(0,seed.nutrient_consumption * HYDRO_SPEED_MULTIPLIER)
@@ -242,7 +256,7 @@
if(seed.exude_gasses && seed.exude_gasses.len)
for(var/gas in seed.exude_gasses)
environment.adjust_gas(gas, max(1,round((seed.exude_gasses[gas]*seed.potency)/seed.exude_gasses.len)))
// If we're attached to a pipenet, then we should let the pipenet know we might have modified some gasses
if (closed_system && connected_port)
update_connected_network()
@@ -291,6 +305,7 @@
// When the plant dies, weeds thrive and pests die off.
if(health <= 0)
dead = 1
mutation_level = 0
harvest = 0
weedlevel += 1 * HYDRO_SPEED_MULTIPLIER
pestlevel = 0
@@ -302,7 +317,7 @@
lastproduce = age
if(prob(3)) // On each tick, there's a chance the pest population will increase
pestlevel += 1 * HYDRO_SPEED_MULTIPLIER
pestlevel += 0.1 * HYDRO_SPEED_MULTIPLIER
check_level_sanity()
update_icon()
@@ -316,19 +331,20 @@
if(reagents.total_volume <= 0)
return
for(var/datum/reagent/R in reagents.reagent_list)
reagents.trans_to(temp_chem_holder, min(reagents.total_volume,rand(1,3)))
for(var/datum/reagent/R in temp_chem_holder.reagents.reagent_list)
var/reagent_total = reagents.get_reagent_amount(R.id)
var/reagent_total = temp_chem_holder.reagents.get_reagent_amount(R.id)
if(seed && !dead)
//Handle some general level adjustments.
if(toxic_reagents[R.id])
toxins += toxic_reagents[R.id] * reagent_total
if(weedkiller_reagents[R.id])
weedlevel += weedkiller_reagents[R.id] * reagent_total
weedlevel -= weedkiller_reagents[R.id] * reagent_total
if(pestkiller_reagents[R.id])
pestlevel += pestkiller_reagents[R.id] * reagent_total
pestlevel -= pestkiller_reagents[R.id] * reagent_total
// Beneficial reagents have a few impacts along with health buffs.
if(beneficial_reagents[R.id])
@@ -338,12 +354,7 @@
// Mutagen is distinct from the previous types and mostly has a chance of proccing a mutation.
if(mutagenic_reagents[R.id])
var/reagent_min_value = mutagenic_reagents[R.id][1]
var/reagent_value = mutagenic_reagents[R.id][2]+mutation_mod
if(reagent_total >= reagent_min_value)
if(prob(min(reagent_total*reagent_value,100)))
mutate(reagent_total > 10 ? 2 : 1)
mutation_level += reagent_total*mutagenic_reagents[R.id]+mutation_mod
// Handle nutrient refilling.
if(nutrient_reagents[R.id])
@@ -356,10 +367,11 @@
water_added += water_input
waterlevel += water_input
// Water dilutes toxin level.
if(water_added > 0)
toxins -= round(water_added/4)
reagents.clear_reagents()
temp_chem_holder.reagents.clear_reagents()
check_level_sanity()
update_icon()
@@ -509,11 +521,12 @@
health = 0
dead = 0
nutrilevel = max(0,min(nutrilevel,10))
waterlevel = max(0,min(waterlevel,100))
pestlevel = max(0,min(pestlevel,10))
weedlevel = max(0,min(weedlevel,10))
toxins = max(0,min(toxins,10))
mutation_level = max(0,min(mutation_level,100))
nutrilevel = max(0,min(nutrilevel,10))
waterlevel = max(0,min(waterlevel,100))
pestlevel = max(0,min(pestlevel,10))
weedlevel = max(0,min(weedlevel,10))
toxins = max(0,min(toxins,10))
/obj/machinery/portable_atmospherics/hydroponics/proc/mutate_species()
@@ -548,10 +561,16 @@
user << "There is nothing to take a sample from in \the [src]."
return
seed.harvest(user,yield_mod,1)
health -= (rand(1,5)*10)
check_level_sanity()
if(dead)
user << "\The plant is dead."
return
// Create a sample.
seed.harvest(user,yield_mod,1)
health -= (rand(3,5)*10)
// Bookkeeping.
check_level_sanity()
force_update = 1
process()
@@ -565,14 +584,14 @@
if(seed)
return ..()
else
user << "There's no plant in the tray to inject."
user << "There's no plant to inject."
return 1
else
if(seed)
//Leaving this in in case we want to extract from plants later.
user << "You can't get any extract out of this plant."
else
user << "There's nothing in the tray to draw something from."
user << "There's nothing to draw something from."
return 1
else if (istype(O, /obj/item/seeds))
@@ -637,7 +656,7 @@
user << "There's nothing in [src] to spray!"
else if (istype(O, /obj/item/weapon/minihoe)) // The minihoe
//var/deweeding
if(weedlevel > 0)
user.visible_message("\red [user] starts uprooting the weeds.", "\red You remove the weeds from the [src].")
weedlevel = 0
+163 -22
View File
@@ -97,6 +97,136 @@ proc/populate_seed_list()
var/flower_icon = "vine_fruit" // Which overlay to use.
var/flower_colour // Which colour to use.
//Creates a random seed. MAKE SURE THE LINE HAS DIVERGED BEFORE THIS IS CALLED.
/datum/seed/proc/randomize()
roundstart = 0
seed_name = "strange plant" // TODO: name generator.
display_name = "strange plants" // TODO: name generator.
seed_noun = pick("spores","nodes","cuttings","seeds")
products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/generic_fruit)
potency = rand(5,30)
//TODO: Finish generalizing the product icons so this can be randomized.
packet_icon = "seed-berry"
plant_icon = "berry"
if(prob(20))
harvest_repeat = 1
if(prob(5))
consume_gasses = list()
var/gas = pick("oxygen","nitrogen","phoron","carbon_dioxide")
consume_gasses[gas] = rand(3,9)
if(prob(5))
exude_gasses = list()
var/gas = pick("oxygen","nitrogen","phoron","carbon_dioxide")
exude_gasses[gas] = rand(3,9)
chems = list()
if(prob(80))
chems["nutriment"] = list(rand(1,10),rand(10,20))
var/additional_chems = rand(0,5)
var/list/possible_chems = list(
"bicaridine",
"hyperzine",
"cryoxadone",
"blood",
"water",
"potassium",
"plasticide",
"slimetoxin",
"aslimetoxin",
"inaprovaline",
"space_drugs",
"paroxetine",
"mercury",
"sugar",
"radium",
"ryetalyn",
"alkysine",
"thermite",
"tramadol",
"cryptobiolin",
"dermaline",
"dexalin",
"phoron",
"synaptizine",
"impedrezene",
"hyronalin",
"peridaxon",
"toxin",
"rezadone",
"ethylredoxrazine",
"slimejelly",
"cyanide",
"mindbreaker",
"stoxin"
)
for(var/x=1;x<=additional_chems;x++)
if(!possible_chems.len)
break
var/new_chem = pick(possible_chems)
possible_chems -= new_chem
chems[new_chem] = list(rand(1,10),rand(10,20))
if(prob(90))
requires_nutrients = 1
nutrient_consumption = rand(100)*0.1
else
requires_nutrients = 0
if(prob(90))
requires_water = 1
water_consumption = rand(10)
else
requires_water = 0
ideal_heat = rand(100,400)
heat_tolerance = rand(10,30)
ideal_light = rand(2,10)
light_tolerance = rand(2,7)
toxins_tolerance = rand(2,7)
pest_tolerance = rand(2,7)
weed_tolerance = rand(2,7)
lowkpa_tolerance = rand(10,50)
highkpa_tolerance = rand(100,300)
if(prob(5))
alter_temp = rand(-5,5)
if(prob(1))
immutable = -1
var/carnivore_prob = rand(100)
if(carnivore_prob < 5)
carnivorous = 2
else if(carnivore_prob < 10)
carnivorous = 1
if(prob(10))
parasite = 1
var/vine_prob = rand(100)
if(vine_prob < 5)
spread = 2
else if(vine_prob < 10)
spread = 1
if(prob(5))
biolum = 1
biolum_colour = "#[pick(list("FF0000","FF7F00","FFFF00","00FF00","0000FF","4B0082","8F00FF"))]"
endurance = rand(60,100)
yield = rand(3,15)
maturation = rand(5,15)
production = maturation + rand(2,5)
lifespan = production + rand(5,10)
//Returns a key corresponding to an entry in the global seed list.
/datum/seed/proc/get_mutant_variant()
if(!mutants || !mutants.len || immutable > 0) return 0
@@ -188,26 +318,35 @@ proc/populate_seed_list()
if(gene.values.len < 6) return
yield = round(yield*0.5)
endurance = round(endurance*0.5)
lifespan = round(lifespan*0.8)
if(yield > 0) yield = max(1,round(yield*0.85))
if(endurance > 0) endurance = max(1,round(endurance*0.85))
if(lifespan > 0) lifespan = max(1,round(lifespan*0.85))
if(!products) products = list()
products |= gene.values[1]
if(!chems) chems = list()
for(var/rid in gene.values[2])
var/existing_chem
for(var/chem in chems)
if(rid == chem)
existing_chem = 1
break
if(existing_chem)
chems[rid][1] = max(1,round((chems[rid][1]+gene.values[2][rid][1])/2))
chems[rid][2] = max(1,round((chems[rid][2]+gene.values[2][rid][2])/2))
var/list/gene_value = gene.values[2]
for(var/rid in gene_value)
var/list/gene_chem = gene_value[rid]
if(chems[rid])
var/list/chem_value = chems[rid]
chems[rid][1] = max(1,round((gene_chem[1] + chem_value[1])/2))
if(gene_chem.len > 1)
if(chem_value > 1)
chems[rid][2] = max(1,round((gene_chem[2] + chem_value[2])/2))
else
chems[rid][2] = gene_chem[2]
else
chems[rid] = gene.values[2][rid]
var/list/new_chem = gene_chem[rid]
chems[rid] = new_chem.Copy()
var/list/new_gasses = gene.values[3]
if(istype(new_gasses))
@@ -353,7 +492,7 @@ proc/populate_seed_list()
if(!isnull(products) && products.len && yield > 0)
got_product = 1
if(!got_product)
if(!got_product && !harvest_sample)
user << "\red You fail to harvest anything useful."
else
user << "You [harvest_sample ? "take a sample" : "harvest"] from the [display_name]."
@@ -370,12 +509,14 @@ proc/populate_seed_list()
seeds.update_seed()
return
var/total_yield
if(isnull(yield_mod) || yield_mod < 1)
yield_mod = 0
total_yield = yield
else
total_yield = max(1,rand(yield_mod,yield_mod+yield))
var/total_yield = 0
if(yield > -1)
if(isnull(yield_mod) || yield_mod < 1)
yield_mod = 0
total_yield = yield
else
total_yield = yield + rand(yield_mod)
total_yield = max(1,total_yield)
currently_querying = list()
for(var/i = 0;i<total_yield;i++)
@@ -417,8 +558,8 @@ proc/populate_seed_list()
if(consume_gasses) new_seed.consume_gasses = consume_gasses.Copy()
if(exude_gasses) new_seed.exude_gasses = exude_gasses.Copy()
new_seed.seed_name = "[(roundstart ? "[(modified ? "modified" : "mutant")] " : " ")][seed_name]"
new_seed.display_name = "[(roundstart ? "[(modified ? "modified" : "mutant")] " : " ")][display_name]"
new_seed.seed_name = "[(roundstart ? "[(modified ? "modified" : "mutant")] " : "")][seed_name]"
new_seed.display_name = "[(roundstart ? "[(modified ? "modified" : "mutant")] " : "")][display_name]"
new_seed.seed_noun = seed_noun
new_seed.requires_nutrients = requires_nutrients
+1 -1
View File
@@ -86,7 +86,7 @@
if(istype(W,/obj/item/seeds))
if(seed)
user << "There is already a seed loaded."
return
var/obj/item/seeds/S =W
if(S.seed && S.seed.immutable > 0)
user << "That seed is not compatible with our genetics technology."
+13
View File
@@ -40,6 +40,19 @@
..()
src.name = "packet of [seed.seed_name] cuttings"
/obj/item/seeds/random
seed_type = null
/obj/item/seeds/random/New()
seed = new()
seed.randomize()
seed.uid = seed_types.len + 1
seed.name = "[seed.uid]"
seed_types[seed.name] = seed
update_seed()
/obj/item/seeds/replicapod
seed_type = "diona"
+1 -1
View File
@@ -240,7 +240,7 @@
del src
/obj/effect/plantsegment/proc/die()
if(seed && harvest)
if(seed && harvest && rand(5))
seed.harvest(src,1)
del(src)
+1 -1
View File
@@ -41,7 +41,7 @@
/obj/structure/bookcase/attack_hand(var/mob/user as mob)
if(contents.len)
var/obj/item/weapon/book/choice = input("Which book would you like to remove from the shelf?") in contents as obj|null
var/obj/item/weapon/book/choice = input("Which book would you like to remove from the shelf?") as null|obj in contents
if(choice)
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
return

Some files were not shown because too many files have changed in this diff Show More