mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-18 11:36:24 +01:00
Merge branch 'master' of https://github.com/tgstation/-tg-station into VisionUpdateRefactor
Conflicts: code/_onclick/hud/alien.dm code/_onclick/hud/alien_larva.dm code/_onclick/hud/hud.dm code/_onclick/hud/human.dm code/_onclick/hud/monkey.dm code/_onclick/hud/other_mobs.dm code/_onclick/hud/robot.dm code/game/machinery/Sleeper.dm code/modules/mob/living/carbon/alien/larva/death.dm code/modules/mob/living/carbon/brain/death.dm code/modules/mob/living/carbon/human/death.dm code/modules/mob/living/carbon/human/life.dm code/modules/mob/living/carbon/human/species.dm code/modules/mob/living/carbon/life.dm code/modules/mob/living/carbon/monkey/death.dm code/modules/mob/living/death.dm code/modules/mob/living/life.dm code/modules/mob/living/silicon/ai/death.dm code/modules/mob/living/silicon/ai/life.dm code/modules/mob/living/silicon/ai/login.dm code/modules/mob/living/silicon/pai/death.dm code/modules/mob/living/silicon/robot/death.dm code/modules/mob/living/silicon/robot/robot.dm code/modules/mob/mob_defines.dm
This commit is contained in:
@@ -177,7 +177,7 @@ var/list/admin_ranks = list() //list of all admin_rank datums
|
||||
continue
|
||||
|
||||
//Split the line at every "="
|
||||
var/list/List = text2list(line, "=")
|
||||
var/list/List = splittext(line, "=")
|
||||
if(!List.len)
|
||||
continue
|
||||
|
||||
|
||||
@@ -596,7 +596,7 @@ var/list/admin_verbs_hideable = list(
|
||||
//load text from file
|
||||
var/list/Lines = file2list("config/admins.txt")
|
||||
for(var/line in Lines)
|
||||
var/list/splitline = text2list(line, " = ")
|
||||
var/list/splitline = splittext(line, " = ")
|
||||
if(ckey(splitline[1]) == ckey)
|
||||
if(splitline.len >= 2)
|
||||
rank = ckeyEx(splitline[2])
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/datum/admins/proc/create_mob(mob/user)
|
||||
if (!create_mob_html)
|
||||
var/mobjs = null
|
||||
mobjs = list2text(typesof(/mob), ";")
|
||||
mobjs = jointext(typesof(/mob), ";")
|
||||
create_mob_html = file2text('html/create_object.html')
|
||||
create_mob_html = replacetext(create_mob_html, "null /* object types */", "\"[mobjs]\"")
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ var/list/create_object_forms = list(
|
||||
/datum/admins/proc/create_object(mob/user)
|
||||
if (!create_object_html)
|
||||
var/objectjs = null
|
||||
objectjs = list2text(typesof(/obj), ";")
|
||||
objectjs = jointext(typesof(/obj), ";")
|
||||
create_object_html = file2text('html/create_object.html')
|
||||
create_object_html = replacetext(create_object_html, "null /* object types */", "\"[objectjs]\"")
|
||||
|
||||
@@ -19,7 +19,7 @@ var/list/create_object_forms = list(
|
||||
var/html_form = create_object_forms[path]
|
||||
|
||||
if (!html_form)
|
||||
var/objectjs = list2text(typesof(path), ";")
|
||||
var/objectjs = jointext(typesof(path), ";")
|
||||
html_form = file2text('html/create_object.html')
|
||||
html_form = replacetext(html_form, "null /* object types */", "\"[objectjs]\"")
|
||||
create_object_forms[path] = html_form
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/datum/admins/proc/create_turf(mob/user)
|
||||
if (!create_turf_html)
|
||||
var/turfjs = null
|
||||
turfjs = list2text(typesof(/turf), ";")
|
||||
turfjs = jointext(typesof(/turf), ";")
|
||||
create_turf_html = file2text('html/create_object.html')
|
||||
create_turf_html = replacetext(create_turf_html, "null /* object types */", "\"[turfjs]\"")
|
||||
|
||||
|
||||
@@ -169,9 +169,6 @@
|
||||
output += ruler
|
||||
usr << browse(output, "window=show_notes;size=900x500")
|
||||
|
||||
/proc/regex_note_sql_extract(str, exp)
|
||||
return new /datum/regex(str, exp, call(LIBREGEX_LIBRARY, "regEx_find")(str, exp))
|
||||
|
||||
#define NOTESFILE "data/player_notes.sav"
|
||||
//if the AUTOCONVERT_NOTES is turned on, anytime a player connects this will be run to try and add all their notes to the databas
|
||||
/proc/convert_notes_sql(ckey)
|
||||
@@ -184,13 +181,13 @@
|
||||
var/notetext
|
||||
notesfile >> notetext
|
||||
var/server
|
||||
if (config && config.server_name)
|
||||
if(config && config.server_name)
|
||||
server = config.server_name
|
||||
var/regex = "^(\\d{2}-\\w{3}-\\d{4}) \\| (.+) ~(\\w+)$"
|
||||
var/datum/regex/results = regex_note_sql_extract(notetext, regex)
|
||||
var/timestamp = results.str(2)
|
||||
notetext = results.str(3)
|
||||
var/adminckey = results.str(4)
|
||||
var/regex/note = new("^(\\d{2}-\\w{3}-\\d{4}) \\| (.+) ~(\\w+)$", "i")
|
||||
note.Find(notetext)
|
||||
var/timestamp = note.group[2]
|
||||
notetext = note.group[3]
|
||||
var/adminckey = note.group[4]
|
||||
var/DBQuery/query_convert_time = dbcon.NewQuery("SELECT ADDTIME(STR_TO_DATE('[timestamp]','%d-%b-%Y'), '0')")
|
||||
if(!query_convert_time.Execute())
|
||||
var/err = query_convert_time.ErrorMsg()
|
||||
@@ -217,4 +214,4 @@ this proc can take several minutes to execute fully if converting and cause DD t
|
||||
world << "Deleting NOTESFILE"
|
||||
fdel(NOTESFILE)
|
||||
world << "Finished mass note conversion, remember to turn off AUTOCONVERT_NOTES"*/
|
||||
#undef NOTESFILE
|
||||
#undef NOTESFILE
|
||||
@@ -175,10 +175,10 @@
|
||||
if (!ban)
|
||||
return null
|
||||
. = params2list(ban)
|
||||
.["keys"] = text2list(.["keys"], ",")
|
||||
.["type"] = text2list(.["type"], ",")
|
||||
.["IP"] = text2list(.["IP"], ",")
|
||||
.["computer_id"] = text2list(.["computer_id"], ",")
|
||||
.["keys"] = splittext(.["keys"], ",")
|
||||
.["type"] = splittext(.["type"], ",")
|
||||
.["IP"] = splittext(.["IP"], ",")
|
||||
.["computer_id"] = splittext(.["computer_id"], ",")
|
||||
|
||||
|
||||
/proc/list2stickyban(var/list/ban)
|
||||
@@ -186,13 +186,13 @@
|
||||
return null
|
||||
. = ban.Copy()
|
||||
if (.["keys"])
|
||||
.["keys"] = list2text(.["keys"], ",")
|
||||
.["keys"] = jointext(.["keys"], ",")
|
||||
if (.["type"])
|
||||
.["type"] = list2text(.["type"], ",")
|
||||
.["type"] = jointext(.["type"], ",")
|
||||
if (.["IP"])
|
||||
.["IP"] = list2text(.["IP"], ",")
|
||||
.["IP"] = jointext(.["IP"], ",")
|
||||
if (.["computer_id"])
|
||||
.["computer_id"] = list2text(.["computer_id"], ",")
|
||||
.["computer_id"] = jointext(.["computer_id"], ",")
|
||||
. = list2params(.)
|
||||
|
||||
|
||||
|
||||
@@ -1882,7 +1882,7 @@
|
||||
alert("Select fewer object types, (max 5)")
|
||||
return
|
||||
|
||||
var/list/offset = text2list(href_list["offset"],",")
|
||||
var/list/offset = splittext(href_list["offset"],",")
|
||||
var/number = Clamp(text2num(href_list["object_count"]), 1, 100)
|
||||
var/X = offset.len > 0 ? text2num(offset[1]) : 0
|
||||
var/Y = offset.len > 1 ? text2num(offset[2]) : 0
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","alien","as", "i")
|
||||
|
||||
//explode the input msg into a list
|
||||
var/list/msglist = text2list(msg, " ")
|
||||
var/list/msglist = splittext(msg, " ")
|
||||
|
||||
//generate keywords lookup
|
||||
var/list/surnames = list()
|
||||
@@ -16,7 +16,7 @@
|
||||
indexing += M.mind.name
|
||||
|
||||
for(var/string in indexing)
|
||||
var/list/L = text2list(string, " ")
|
||||
var/list/L = splittext(string, " ")
|
||||
var/surname_found = 0
|
||||
//surnames
|
||||
for(var/i=L.len, i>=1, i--)
|
||||
|
||||
@@ -688,19 +688,19 @@ var/global/list/g_fancy_list_of_types = null
|
||||
|
||||
switch(input("Which list?") in list("Players","Admins","Mobs","Living Mobs","Dead Mobs","Clients","Joined Clients"))
|
||||
if("Players")
|
||||
usr << list2text(player_list,",")
|
||||
usr << jointext(player_list,",")
|
||||
if("Admins")
|
||||
usr << list2text(admins,",")
|
||||
usr << jointext(admins,",")
|
||||
if("Mobs")
|
||||
usr << list2text(mob_list,",")
|
||||
usr << jointext(mob_list,",")
|
||||
if("Living Mobs")
|
||||
usr << list2text(living_mob_list,",")
|
||||
usr << jointext(living_mob_list,",")
|
||||
if("Dead Mobs")
|
||||
usr << list2text(dead_mob_list,",")
|
||||
usr << jointext(dead_mob_list,",")
|
||||
if("Clients")
|
||||
usr << list2text(clients,",")
|
||||
usr << jointext(clients,",")
|
||||
if("Joined Clients")
|
||||
usr << list2text(joined_player_list,",")
|
||||
usr << jointext(joined_player_list,",")
|
||||
|
||||
/client/proc/cmd_display_del_log()
|
||||
set category = "Debug"
|
||||
|
||||
@@ -8,91 +8,92 @@ What are the archived variables for?
|
||||
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
|
||||
|
||||
var/list/meta_gas_info = meta_gas_list() //see ATMOSPHERICS/gas_types.dm
|
||||
var/list/cached_gases_list = null
|
||||
|
||||
/proc/gaslist(gasid)
|
||||
if(!cached_gases_list)
|
||||
cached_gases_list = new /list(meta_gas_info.len)
|
||||
var/list/gaslist_cache = null
|
||||
/proc/gaslist(id)
|
||||
var/list/cached_gas
|
||||
|
||||
if(!cached_gases_list[gasid])
|
||||
if(!meta_gas_info[gasid])
|
||||
CRASH("Error: no such gas type! Type : [gasid]")
|
||||
if(!gaslist_cache)
|
||||
gaslist_cache = new(meta_gas_info.len)
|
||||
|
||||
var/list/new_gas_list = new(3)
|
||||
new_gas_list[MOLES] = 0
|
||||
new_gas_list[ARCHIVE] = 0
|
||||
new_gas_list[GAS_META] = meta_gas_info[gasid]
|
||||
cached_gases_list[gasid] = new_gas_list
|
||||
if(!gaslist_cache[id])
|
||||
if(!meta_gas_info[id])
|
||||
CRASH("Gas [id] does not exist!")
|
||||
cached_gas = new(3)
|
||||
gaslist_cache[id] = cached_gas
|
||||
|
||||
var/list/gas = cached_gases_list[gasid]
|
||||
. = gas.Copy()
|
||||
cached_gas[MOLES] = 0
|
||||
cached_gas[ARCHIVE] = 0
|
||||
cached_gas[GAS_META] = meta_gas_info[id]
|
||||
else
|
||||
cached_gas = gaslist_cache[id]
|
||||
return cached_gas.Copy()
|
||||
|
||||
/datum/gas_mixture
|
||||
var/list/gases
|
||||
var/temperature //in Kelvin
|
||||
var/temperature // degrees Kelvin
|
||||
var/tmp/temperature_archived
|
||||
var/volume
|
||||
var/last_share
|
||||
var/tmp/fuel_burnt
|
||||
|
||||
/datum/gas_mixture/New(Volume = CELL_VOLUME)
|
||||
. = ..()
|
||||
/datum/gas_mixture/New(volume = CELL_VOLUME)
|
||||
..()
|
||||
gases = new
|
||||
temperature = 0
|
||||
temperature_archived = 0
|
||||
volume = Volume
|
||||
src.volume = volume
|
||||
last_share = 0
|
||||
fuel_burnt = 0
|
||||
|
||||
//listmos procs
|
||||
//listmos procs
|
||||
|
||||
//assert_gas(gas_id) - used to guarantee that the gas list for this id exists.
|
||||
//Must be used before adding to a gas. May be used before reading from a gas.
|
||||
//assert_gas(gas_id) - used to guarantee that the gas list for this id exists.
|
||||
//Must be used before adding to a gas. May be used before reading from a gas.
|
||||
/datum/gas_mixture/proc/assert_gas(gas_id)
|
||||
var/cached_gases = gases
|
||||
if(cached_gases[gas_id])
|
||||
return
|
||||
cached_gases[gas_id] = gaslist(gas_id) //see ATMOSPHERICS/gas_types.dm
|
||||
|
||||
//assert_gases(args) - shorthand for calling assert_gas() once for each gas type.
|
||||
//assert_gases(args) - shorthand for calling assert_gas() once for each gas type.
|
||||
/datum/gas_mixture/proc/assert_gases()
|
||||
for(var/id in args)
|
||||
assert_gas(id)
|
||||
|
||||
//add_gas(gas_id) - similar to assert_gas(), but does not check for an existing
|
||||
//gas list for this id.
|
||||
//Used instead of assert_gas() when you know the gas does not exist. Faster than assert_gas().
|
||||
//add_gas(gas_id) - similar to assert_gas(), but does not check for an existing
|
||||
//gas list for this id. This can clobber existing gases.
|
||||
//Used instead of assert_gas() when you know the gas does not exist. Faster than assert_gas().
|
||||
/datum/gas_mixture/proc/add_gas(gas_id)
|
||||
gases[gas_id] = gaslist(gas_id)
|
||||
|
||||
//add_gases(args) - shorthand for calling add_gas() once for each gas_type.
|
||||
//add_gases(args) - shorthand for calling add_gas() once for each gas_type.
|
||||
/datum/gas_mixture/proc/add_gases()
|
||||
for(var/id in args)
|
||||
add_gas(id)
|
||||
|
||||
//garbage_collect() - removes any gas list which is empty.
|
||||
//Must be used after subtracting from a gas. Must be used after assert_gas()
|
||||
//if assert_gas() was called only to read from the gas.
|
||||
//By removing empty gases, processing speed is increased.
|
||||
//garbage_collect() - removes any gas list which is empty.
|
||||
//Must be used after subtracting from a gas. Must be used after assert_gas()
|
||||
//if assert_gas() was called only to read from the gas.
|
||||
//By removing empty gases, processing speed is increased.
|
||||
/datum/gas_mixture/proc/garbage_collect()
|
||||
var/list/cached_gases = gases
|
||||
for(var/id in cached_gases)
|
||||
var/gas = cached_gases[id]
|
||||
if(QUANTIZE(gas[MOLES]) <= 0 && QUANTIZE(gas[ARCHIVE]) <= 0)
|
||||
if(cached_gases[id][MOLES] <= 0 && cached_gases[id][ARCHIVE] <= 0)
|
||||
cached_gases -= id
|
||||
|
||||
//PV=nRT - related procedures
|
||||
//PV = nRT
|
||||
/datum/gas_mixture/proc/heat_capacity()
|
||||
var/list/cached_gases = gases
|
||||
. = 0
|
||||
for(var/id in cached_gases)
|
||||
. += cached_gases[id][MOLES]*cached_gases[id][GAS_META][META_GAS_SPECIFIC_HEAT]
|
||||
. += cached_gases[id][MOLES] * cached_gases[id][GAS_META][META_GAS_SPECIFIC_HEAT]
|
||||
|
||||
/datum/gas_mixture/proc/heat_capacity_archived()
|
||||
var/list/cached_gases = gases
|
||||
. = 0
|
||||
for(var/id in cached_gases)
|
||||
. += cached_gases[id][ARCHIVE]*cached_gases[id][GAS_META][META_GAS_SPECIFIC_HEAT]
|
||||
. += cached_gases[id][ARCHIVE] * cached_gases[id][GAS_META][META_GAS_SPECIFIC_HEAT]
|
||||
|
||||
/datum/gas_mixture/proc/total_moles()
|
||||
var/list/cached_gases = gases
|
||||
@@ -101,40 +102,38 @@ var/list/cached_gases_list = null
|
||||
. += cached_gases[id][MOLES]
|
||||
|
||||
/datum/gas_mixture/proc/return_pressure()
|
||||
if(volume>0)
|
||||
return total_moles()*R_IDEAL_GAS_EQUATION*temperature/volume
|
||||
if(volume > 0) // to prevent division by zero
|
||||
return total_moles() * R_IDEAL_GAS_EQUATION * temperature / volume
|
||||
return 0
|
||||
|
||||
/datum/gas_mixture/proc/return_temperature()
|
||||
return temperature
|
||||
|
||||
|
||||
/datum/gas_mixture/proc/return_volume()
|
||||
return max(0, volume)
|
||||
|
||||
|
||||
/datum/gas_mixture/proc/thermal_energy()
|
||||
return temperature*heat_capacity()
|
||||
|
||||
return temperature * heat_capacity()
|
||||
|
||||
//Procedures used for very specific events
|
||||
|
||||
|
||||
/datum/gas_mixture/proc/react(atom/dump_location)
|
||||
var/list/procgases = gases //this speeds things up because >byond
|
||||
var/list/cached_gases = gases //this speeds things up because >byond
|
||||
var/reacting = 0 //set to 1 if a notable reaction occured (used by pipe_network)
|
||||
|
||||
if(temperature < TCMB)
|
||||
temperature = TCMB
|
||||
if(procgases["agent_b"] && temperature > 900 && procgases["plasma"] && procgases["co2"])
|
||||
if(procgases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY && procgases["co2"][MOLES] > MINIMUM_HEAT_CAPACITY)
|
||||
var/reaction_rate = min(procgases["co2"][MOLES]*0.75, procgases["plasma"][MOLES]*0.25, procgases["agent_b"][MOLES]*0.05)
|
||||
|
||||
procgases["co2"][MOLES] -= reaction_rate
|
||||
if(cached_gases["agent_b"] && temperature > 900 && cached_gases["plasma"] && cached_gases["co2"])
|
||||
if(cached_gases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY && cached_gases["co2"][MOLES] > MINIMUM_HEAT_CAPACITY)
|
||||
var/reaction_rate = min(cached_gases["co2"][MOLES]*0.75, cached_gases["plasma"][MOLES]*0.25, cached_gases["agent_b"][MOLES]*0.05)
|
||||
|
||||
cached_gases["co2"][MOLES] -= reaction_rate
|
||||
|
||||
assert_gas("o2") //only need to assert oxygen, as this reaction doesn't occur without the other gases existing
|
||||
procgases["o2"][MOLES] += reaction_rate
|
||||
cached_gases["o2"][MOLES] += reaction_rate
|
||||
|
||||
procgases["agent_b"][MOLES] -= reaction_rate*0.05
|
||||
cached_gases["agent_b"][MOLES] -= reaction_rate*0.05
|
||||
|
||||
temperature -= (reaction_rate*20000)/heat_capacity()
|
||||
|
||||
@@ -143,26 +142,26 @@ var/list/cached_gases_list = null
|
||||
reacting = 1
|
||||
/*
|
||||
if(thermal_energy() > (PLASMA_BINDING_ENERGY*10))
|
||||
if(procgases["plasma"] && procgases["co2"] && procgases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY && procgases["co2"][MOLES] > MINIMUM_HEAT_CAPACITY && (procgases["plasma"][MOLES]+procgases["co2"][MOLES])/total_moles() >= FUSION_PURITY_THRESHOLD)//Fusion wont occur if the level of impurities is too high.
|
||||
//world << "pre [temperature, [procgases["plasma"][MOLES]], [procgases["co2"][MOLES]]
|
||||
if(cached_gases["plasma"] && cached_gases["co2"] && cached_gases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY && cached_gases["co2"][MOLES] > MINIMUM_HEAT_CAPACITY && (cached_gases["plasma"][MOLES]+cached_gases["co2"][MOLES])/total_moles() >= FUSION_PURITY_THRESHOLD)//Fusion wont occur if the level of impurities is too high.
|
||||
//world << "pre [temperature, [cached_gases["plasma"][MOLES]], [cached_gases["co2"][MOLES]]
|
||||
var/old_heat_capacity = heat_capacity()
|
||||
var/carbon_efficency = min(procgases["plasma"][MOLES]/procgases["co2"][MOLES],MAX_CARBON_EFFICENCY)
|
||||
var/carbon_efficency = min(cached_gases["plasma"][MOLES]/cached_gases["co2"][MOLES],MAX_CARBON_EFFICENCY)
|
||||
var/reaction_energy = thermal_energy()
|
||||
var/moles_impurities = total_moles()-(procgases["plasma"][MOLES]+procgases["co2"][MOLES])
|
||||
var/moles_impurities = total_moles()-(cached_gases["plasma"][MOLES]+cached_gases["co2"][MOLES])
|
||||
|
||||
var/plasma_fused = (PLASMA_FUSED_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY)
|
||||
var/carbon_catalyzed = (CARBON_CATALYST_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY)
|
||||
var/oxygen_added = carbon_catalyzed
|
||||
var/nitrogen_added = (plasma_fused-oxygen_added)-(thermal_energy()/PLASMA_BINDING_ENERGY)
|
||||
|
||||
reaction_energy = max(reaction_energy+((carbon_efficency*procgases["plasma"][MOLES])/((moles_impurities/carbon_efficency)+2)*10)+((plasma_fused/(moles_impurities/carbon_efficency))*PLASMA_BINDING_ENERGY),0)
|
||||
reaction_energy = max(reaction_energy+((carbon_efficency*cached_gases["plasma"][MOLES])/((moles_impurities/carbon_efficency)+2)*10)+((plasma_fused/(moles_impurities/carbon_efficency))*PLASMA_BINDING_ENERGY),0)
|
||||
|
||||
assert_gases("o2", "n2")
|
||||
|
||||
procgases["plasma"][MOLES] -= plasma_fused
|
||||
procgases["co2"][MOLES] -= carbon_catalyzed
|
||||
procgases["o2"][MOLES] += oxygen_added
|
||||
procgases["n2"][MOLES] += nitrogen_added
|
||||
cached_gases["plasma"][MOLES] -= plasma_fused
|
||||
cached_gases["co2"][MOLES] -= carbon_catalyzed
|
||||
cached_gases["o2"][MOLES] += oxygen_added
|
||||
cached_gases["n2"][MOLES] += nitrogen_added
|
||||
|
||||
garbage_collect()
|
||||
|
||||
@@ -172,45 +171,46 @@ var/list/cached_gases_list = null
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
temperature = max(((temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB)
|
||||
//Prevents whatever mechanism is causing it to hit negative temperatures.
|
||||
//world << "post [temperature], [procgases["plasma"][MOLES]], [procgases["co2"][MOLES]]
|
||||
//world << "post [temperature], [cached_gases["plasma"][MOLES]], [cached_gases["co2"][MOLES]]
|
||||
*/
|
||||
fuel_burnt = 0
|
||||
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
|
||||
//world << "pre [temperature], [procgases["o2"][MOLES]], [procgases["plasma"][MOLES]]"
|
||||
//world << "pre [temperature], [cached_gases["o2"][MOLES]], [cached_gases["plasma"][MOLES]]"
|
||||
if(fire())
|
||||
reacting = 1
|
||||
//world << "post [temperature], [procgases["o2"][MOLES]], [procgases["plasma"][MOLES]]"
|
||||
//world << "post [temperature], [cached_gases["o2"][MOLES]], [cached_gases["plasma"][MOLES]]"
|
||||
|
||||
return reacting
|
||||
|
||||
/datum/gas_mixture/proc/fire()
|
||||
var/energy_released = 0
|
||||
var/old_heat_capacity = heat_capacity()
|
||||
var/list/procgases = gases //this speeds things up because accessing datum vars is slow
|
||||
var/list/cached_gases = gases //this speeds things up because accessing datum vars is slow
|
||||
|
||||
if(procgases["v_fuel"] && procgases["v_fuel"][MOLES]) //General volatile gas burn
|
||||
//General volatile gas burn
|
||||
if(cached_gases["v_fuel"] && cached_gases["v_fuel"][MOLES])
|
||||
var/burned_fuel
|
||||
|
||||
if(!procgases["o2"])
|
||||
if(!cached_gases["o2"])
|
||||
burned_fuel = 0
|
||||
else if(procgases["o2"][MOLES] < procgases["v_fuel"][MOLES])
|
||||
burned_fuel = procgases["o2"][MOLES]
|
||||
procgases["v_fuel"][MOLES] -= burned_fuel
|
||||
procgases["o2"][MOLES] = 0
|
||||
else if(cached_gases["o2"][MOLES] < cached_gases["v_fuel"][MOLES])
|
||||
burned_fuel = cached_gases["o2"][MOLES]
|
||||
cached_gases["v_fuel"][MOLES] -= burned_fuel
|
||||
cached_gases["o2"][MOLES] = 0
|
||||
else
|
||||
burned_fuel = procgases["v_fuel"][MOLES]
|
||||
procgases["o2"][MOLES] -= procgases["v_fuel"][MOLES]
|
||||
burned_fuel = cached_gases["v_fuel"][MOLES]
|
||||
cached_gases["o2"][MOLES] -= cached_gases["v_fuel"][MOLES]
|
||||
|
||||
if(burned_fuel)
|
||||
energy_released += FIRE_CARBON_ENERGY_RELEASED * burned_fuel
|
||||
|
||||
assert_gas("co2")
|
||||
procgases["co2"][MOLES] += burned_fuel
|
||||
cached_gases["co2"][MOLES] += burned_fuel
|
||||
|
||||
fuel_burnt += burned_fuel
|
||||
|
||||
//Handle plasma burning
|
||||
if(procgases["plasma"] && procgases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY)
|
||||
if(cached_gases["plasma"] && cached_gases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY)
|
||||
var/plasma_burn_rate = 0
|
||||
var/oxygen_burn_rate = 0
|
||||
//more plasma released at higher temperatures
|
||||
@@ -221,16 +221,16 @@ var/list/cached_gases_list = null
|
||||
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
|
||||
if(temperature_scale > 0)
|
||||
assert_gas("o2")
|
||||
assert_gas("co2")
|
||||
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale
|
||||
if(procgases["o2"][MOLES] > procgases["plasma"][MOLES]*PLASMA_OXYGEN_FULLBURN)
|
||||
plasma_burn_rate = (procgases["plasma"][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA
|
||||
if(cached_gases["o2"][MOLES] > cached_gases["plasma"][MOLES]*PLASMA_OXYGEN_FULLBURN)
|
||||
plasma_burn_rate = (cached_gases["plasma"][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA
|
||||
else
|
||||
plasma_burn_rate = (temperature_scale*(procgases["o2"][MOLES]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
|
||||
plasma_burn_rate = (temperature_scale*(cached_gases["o2"][MOLES]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
|
||||
if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
|
||||
procgases["plasma"][MOLES] -= plasma_burn_rate
|
||||
procgases["o2"][MOLES] -= plasma_burn_rate*oxygen_burn_rate
|
||||
procgases["co2"][MOLES] += plasma_burn_rate
|
||||
assert_gas("co2")
|
||||
cached_gases["plasma"][MOLES] = QUANTIZE(cached_gases["plasma"][MOLES] - plasma_burn_rate)
|
||||
cached_gases["o2"][MOLES] = QUANTIZE(cached_gases["o2"][MOLES] - (plasma_burn_rate * oxygen_burn_rate))
|
||||
cached_gases["co2"][MOLES] += plasma_burn_rate
|
||||
|
||||
energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
|
||||
|
||||
@@ -260,12 +260,20 @@ var/list/cached_gases_list = null
|
||||
//Proportionally removes amount of gas from the gas_mixture
|
||||
//Returns: gas_mixture with the gases removed
|
||||
|
||||
/datum/gas_mixture/proc/copy()
|
||||
//Creates new, identical gas mixture
|
||||
//Returns: duplicate gas mixture
|
||||
|
||||
/datum/gas_mixture/proc/copy_from(datum/gas_mixture/sample)
|
||||
//Copies variables from sample
|
||||
|
||||
/datum/gas_mixture/proc/copy_from_turf(turf/model)
|
||||
//Copies all gas info from the turf into the gas list along with temperature
|
||||
|
||||
/datum/gas_mixture/proc/share(datum/gas_mixture/sharer)
|
||||
//Performs air sharing calculations between two gas_mixtures assuming only 1 boundary length
|
||||
//Return: amount of gas exchanged (+ if sharer received)
|
||||
|
||||
/datum/gas_mixture/proc/mimic(turf/model)
|
||||
//Similar to share(...), except the model is not modified
|
||||
//Return: amount of gas exchanged
|
||||
@@ -283,138 +291,148 @@ var/list/cached_gases_list = null
|
||||
//Compares sample to self to see if within acceptable ranges that group processing may be enabled
|
||||
//returns: a string indicating what check failed, or "" if check passes
|
||||
|
||||
/datum/gas_mixture/proc/copy_from_turf(turf/model)
|
||||
//Copies all gas info from the turf into the gas list along with copying temperature, then archives
|
||||
|
||||
/datum/gas_mixture/archive()
|
||||
var/list/cached_gases = gases
|
||||
|
||||
temperature_archived = temperature
|
||||
for(var/id in cached_gases)
|
||||
cached_gases[id][ARCHIVE] = cached_gases[id][MOLES]
|
||||
temperature_archived = temperature
|
||||
. = 1
|
||||
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/merge(datum/gas_mixture/giver)
|
||||
if(!giver)
|
||||
return 0
|
||||
|
||||
if(abs(temperature-giver.temperature)>MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
if(abs(temperature - giver.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity()
|
||||
var/giver_heat_capacity = giver.heat_capacity()
|
||||
var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity
|
||||
if(combined_heat_capacity)
|
||||
temperature = (giver.temperature*giver_heat_capacity + temperature*self_heat_capacity)/combined_heat_capacity
|
||||
temperature = (giver.temperature * giver_heat_capacity + temperature * self_heat_capacity) / combined_heat_capacity
|
||||
|
||||
var/list/cached_gases = gases //accessing datum vars is slower than proc vars
|
||||
var/list/giver_gases = giver.gases
|
||||
for(var/giver_id in giver_gases)
|
||||
assert_gas(giver_id)
|
||||
cached_gases[giver_id][MOLES] += giver_gases[giver_id][MOLES]
|
||||
|
||||
. = 1
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/remove(amount)
|
||||
|
||||
var/sum = total_moles()
|
||||
amount = min(amount,sum) //Can not take more air than tile has!
|
||||
|
||||
amount = min(amount, sum) //Can not take more air than tile has!
|
||||
if(amount <= 0)
|
||||
return null
|
||||
|
||||
var/list/cached_gases = gases
|
||||
var/datum/gas_mixture/removed = new
|
||||
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
|
||||
var/list/cached_gases = gases
|
||||
|
||||
for(var/id in cached_gases)
|
||||
removed.assert_gas(id)
|
||||
removed_gases[id][MOLES] = QUANTIZE((cached_gases[id][MOLES]/sum)*amount)
|
||||
cached_gases[id][MOLES] -= removed_gases[id][MOLES]
|
||||
|
||||
removed.temperature = temperature
|
||||
|
||||
for(var/id in cached_gases)
|
||||
removed.add_gas(id)
|
||||
removed_gases[id][MOLES] = QUANTIZE((cached_gases[id][MOLES] / sum) * amount)
|
||||
cached_gases[id][MOLES] -= removed_gases[id][MOLES]
|
||||
garbage_collect()
|
||||
|
||||
. = removed
|
||||
return removed
|
||||
|
||||
/datum/gas_mixture/remove_ratio(ratio)
|
||||
if(ratio <= 0)
|
||||
return null
|
||||
|
||||
ratio = min(ratio, 1)
|
||||
|
||||
var/list/cached_gases = gases
|
||||
var/datum/gas_mixture/removed = new
|
||||
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
|
||||
var/list/cached_gases = gases
|
||||
|
||||
for(var/id in cached_gases)
|
||||
removed.assert_gas(id)
|
||||
removed_gases[id][MOLES] = QUANTIZE(cached_gases[id][MOLES]*ratio)
|
||||
cached_gases[id][MOLES] -= removed_gases[id][MOLES]
|
||||
|
||||
removed.temperature = temperature
|
||||
|
||||
for(var/id in cached_gases)
|
||||
removed.add_gas(id)
|
||||
removed_gases[id][MOLES] = QUANTIZE(cached_gases[id][MOLES] * ratio)
|
||||
cached_gases[id][MOLES] -= removed_gases[id][MOLES]
|
||||
garbage_collect()
|
||||
|
||||
. = removed
|
||||
return removed
|
||||
|
||||
/datum/gas_mixture/copy()
|
||||
var/list/cached_gases = gases
|
||||
var/datum/gas_mixture/copy = new
|
||||
var/list/copy_gases = copy.gases
|
||||
|
||||
copy.temperature = temperature
|
||||
for(var/id in cached_gases)
|
||||
add_gas(id)
|
||||
copy_gases[id][MOLES] = cached_gases[id][MOLES]
|
||||
|
||||
return copy
|
||||
|
||||
/datum/gas_mixture/copy_from(datum/gas_mixture/sample)
|
||||
var/list/cached_gases = gases //accessing datum vars is slower than proc vars
|
||||
var/list/sample_gases = sample.gases
|
||||
var/list/copied_gases = list()
|
||||
for(var/sample_id in sample_gases)
|
||||
assert_gas(sample_id)
|
||||
cached_gases[sample_id][MOLES] = sample_gases[sample_id][MOLES]
|
||||
copied_gases += sample_id
|
||||
for(var/id in cached_gases-copied_gases)
|
||||
assert_gas(id)
|
||||
cached_gases[id][MOLES] = 0
|
||||
|
||||
garbage_collect()
|
||||
|
||||
temperature = sample.temperature
|
||||
for(var/id in sample_gases)
|
||||
assert_gas(id)
|
||||
cached_gases[id][MOLES] = sample_gases[id][MOLES]
|
||||
cached_gases &= sample_gases
|
||||
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/copy_from_turf(turf/model)
|
||||
var/list/cached_gases = gases
|
||||
|
||||
temperature = model.temperature
|
||||
assert_gases(arglist(hardcoded_gases))
|
||||
cached_gases["o2"][MOLES] = model.oxygen
|
||||
cached_gases["n2"][MOLES] = model.nitrogen
|
||||
cached_gases["plasma"][MOLES] = model.toxins
|
||||
cached_gases["co2"][MOLES] = model.carbon_dioxide
|
||||
cached_gases &= hardcoded_gases
|
||||
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/check_turf(turf/model, atmos_adjacent_turfs = 4)
|
||||
var/datum/gas_mixture/copied = new
|
||||
copied.copy_from_turf(model)
|
||||
. = compare(copied, datatype = ARCHIVE, adjacents = atmos_adjacent_turfs)
|
||||
return compare(copied, datatype = ARCHIVE, adjacents = atmos_adjacent_turfs)
|
||||
|
||||
/datum/gas_mixture/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
|
||||
. = 0
|
||||
if(!sharer)
|
||||
return
|
||||
return 0
|
||||
|
||||
var/moved_moles = 0
|
||||
var/abs_moved_moles = 0
|
||||
//make this local to the proc for sanic speed
|
||||
var/list/sharercache = sharer.gases
|
||||
var/list/selfcache = gases
|
||||
var/list/cached_gases = gases
|
||||
var/list/sharer_gases = sharer.gases
|
||||
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
|
||||
var/temperature_delta = temperature_archived - sharer.temperature_archived
|
||||
var/abs_temperature_delta = abs(temperature_delta)
|
||||
|
||||
var/old_self_heat_capacity = 0
|
||||
var/old_sharer_heat_capacity = 0
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
if(abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
old_self_heat_capacity = heat_capacity()
|
||||
old_sharer_heat_capacity = sharer.heat_capacity()
|
||||
|
||||
var/heat_capacity_self_to_sharer = 0 //heat capacity of the moles transferred from us to the sharer
|
||||
var/heat_capacity_sharer_to_self = 0 //heat capacity of the moles transferred from the sharer to us
|
||||
|
||||
for(var/sharer_id in sharercache-selfcache)
|
||||
add_gas(sharer_id) //we can use add_gas() because we're looping only through the IDs not in our cache
|
||||
var/moved_moles = 0
|
||||
var/abs_moved_moles = 0
|
||||
|
||||
//GAS TRANSFER
|
||||
for(var/id in selfcache)
|
||||
if(!sharercache[id]) //checking here prevents an uneeded proc call if the check fails.
|
||||
for(var/id in sharer_gases - cached_gases) // create gases not in our cache
|
||||
add_gas(id)
|
||||
for(var/id in cached_gases) // transfer gases
|
||||
if(!sharer_gases[id]) //checking here prevents an uneeded proc call if the check fails.
|
||||
sharer.add_gas(id)
|
||||
|
||||
var/gas = selfcache[id]
|
||||
var/sharergas = sharercache[id]
|
||||
var/gas = cached_gases[id]
|
||||
var/sharergas = sharer_gases[id]
|
||||
|
||||
var/delta = QUANTIZE(gas[ARCHIVE] - sharergas[ARCHIVE])/(atmos_adjacent_turfs+1) //the amount of gas that gets moved between the mixtures
|
||||
|
||||
if(delta && abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
if(delta && abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/gas_heat_capacity = delta * gas[GAS_META][META_GAS_SPECIFIC_HEAT]
|
||||
if(delta > 0)
|
||||
heat_capacity_self_to_sharer += gas_heat_capacity
|
||||
@@ -429,7 +447,7 @@ var/list/cached_gases_list = null
|
||||
last_share = abs_moved_moles
|
||||
|
||||
//THERMAL ENERGY TRANSFER
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
if(abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/new_self_heat_capacity = old_self_heat_capacity + heat_capacity_sharer_to_self - heat_capacity_self_to_sharer
|
||||
var/new_sharer_heat_capacity = old_sharer_heat_capacity + heat_capacity_self_to_sharer - heat_capacity_sharer_to_self
|
||||
|
||||
@@ -445,9 +463,9 @@ var/list/cached_gases_list = null
|
||||
if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.10) // <10% change in sharer heat capacity
|
||||
temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT)
|
||||
|
||||
if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
if(temperature_delta > MINIMUM_TEMPERATURE_TO_MOVE || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - sharer.temperature_archived*(sharer.total_moles() - moved_moles)
|
||||
. = delta_pressure*R_IDEAL_GAS_EQUATION/volume
|
||||
. = delta_pressure * R_IDEAL_GAS_EQUATION / volume
|
||||
|
||||
garbage_collect()
|
||||
sharer.garbage_collect()
|
||||
@@ -455,17 +473,17 @@ var/list/cached_gases_list = null
|
||||
/datum/gas_mixture/mimic(turf/model, atmos_adjacent_turfs = 4)
|
||||
var/datum/gas_mixture/copied = new
|
||||
copied.copy_from_turf(model)
|
||||
. = share(copied, atmos_adjacent_turfs)
|
||||
return share(copied, atmos_adjacent_turfs)
|
||||
|
||||
/datum/gas_mixture/temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
|
||||
//transfer of thermal energy (via conduction) between self and sharer
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/temperature_delta = temperature_archived - sharer.temperature_archived
|
||||
if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity_archived()
|
||||
var/sharer_heat_capacity = sharer.heat_capacity_archived()
|
||||
|
||||
if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
var/heat = conduction_coefficient*temperature_delta* \
|
||||
(self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
|
||||
|
||||
temperature = max(temperature - heat/self_heat_capacity, TCMB)
|
||||
@@ -473,39 +491,38 @@ var/list/cached_gases_list = null
|
||||
//thermal energy of the system (self and sharer) is unchanged
|
||||
|
||||
/datum/gas_mixture/temperature_mimic(turf/model, conduction_coefficient)
|
||||
var/delta_temperature = (temperature - model.temperature)
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/temperature_delta = temperature - model.temperature
|
||||
if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity()
|
||||
|
||||
if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
var/heat = conduction_coefficient*temperature_delta* \
|
||||
(self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity))
|
||||
|
||||
temperature = max(temperature - heat/self_heat_capacity, TCMB)
|
||||
|
||||
/datum/gas_mixture/temperature_turf_share(turf/simulated/sharer, conduction_coefficient)
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature)
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/temperature_delta = temperature_archived - sharer.temperature
|
||||
if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity()
|
||||
|
||||
if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
var/heat = conduction_coefficient*temperature_delta* \
|
||||
(self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity))
|
||||
|
||||
temperature = max(temperature - heat/self_heat_capacity, TCMB)
|
||||
sharer.temperature = max(sharer.temperature + heat/sharer.heat_capacity, TCMB)
|
||||
|
||||
/datum/gas_mixture/compare(datum/gas_mixture/sample, datatype = MOLES, adjacents = 0)
|
||||
. = ""
|
||||
var/list/sample_gases = sample.gases //accessing datum vars is slower than proc vars
|
||||
var/list/cached_gases = gases
|
||||
|
||||
for(var/id in cached_gases|sample_gases)
|
||||
for(var/id in cached_gases | sample_gases) // compare gases from either mixture
|
||||
var/gas_moles = cached_gases[id] ? cached_gases[id][datatype] : 0
|
||||
var/sample_moles = sample_gases[id] ? sample_gases[id][datatype] : 0
|
||||
var/delta = abs(gas_moles - sample_moles)/(adjacents+1)
|
||||
if(delta > MINIMUM_AIR_TO_SUSPEND && \
|
||||
delta > gas_moles*MINIMUM_AIR_RATIO_TO_SUSPEND)
|
||||
delta > gas_moles * MINIMUM_AIR_RATIO_TO_SUSPEND)
|
||||
return id
|
||||
|
||||
if(total_moles() > MINIMUM_AIR_TO_SUSPEND)
|
||||
@@ -520,50 +537,30 @@ var/list/cached_gases_list = null
|
||||
temp = temperature_archived
|
||||
sample_temp = sample.temperature_archived
|
||||
|
||||
var/delta_temperature = abs(temp-sample_temp)
|
||||
if((delta_temperature > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \
|
||||
delta_temperature > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND*temp)
|
||||
var/temperature_delta = abs(temp - sample_temp)
|
||||
if((temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \
|
||||
temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND * temp)
|
||||
return "temp"
|
||||
|
||||
/datum/gas_mixture/copy_from_turf(turf/model)
|
||||
assert_gases(arglist(hardcoded_gases))
|
||||
var/list/cached_gases = gases
|
||||
return ""
|
||||
|
||||
cached_gases["o2"][MOLES] = model.oxygen
|
||||
cached_gases["n2"][MOLES] = model.nitrogen
|
||||
cached_gases["plasma"][MOLES] = model.toxins
|
||||
cached_gases["co2"][MOLES] = model.carbon_dioxide
|
||||
|
||||
for(var/id in cached_gases-hardcoded_gases)
|
||||
cached_gases[id][MOLES] = 0 //turfs don't account for anything other than the four old hardcoded gases
|
||||
|
||||
temperature = model.temperature
|
||||
|
||||
garbage_collect()
|
||||
//Takes the amount of the gas you want to PP as an argument
|
||||
//So I don't have to do some hacky switches/defines/magic strings
|
||||
|
||||
//eg:
|
||||
//Tox_PP = get_partial_pressure(gas_mixture.toxins)
|
||||
//O2_PP = get_partial_pressure(gas_mixture.oxygen)
|
||||
|
||||
//Does handle trace gases!
|
||||
|
||||
/datum/gas_mixture/proc/get_breath_partial_pressure(gas_pressure)
|
||||
return (gas_pressure*R_IDEAL_GAS_EQUATION*temperature)/BREATH_VOLUME
|
||||
|
||||
|
||||
//Reverse of the above
|
||||
/datum/gas_mixture/proc/get_true_breath_pressure(breath_pp)
|
||||
return (breath_pp*BREATH_VOLUME)/(R_IDEAL_GAS_EQUATION*temperature)
|
||||
return (gas_pressure * R_IDEAL_GAS_EQUATION * temperature) / BREATH_VOLUME
|
||||
//inverse
|
||||
/datum/gas_mixture/proc/get_true_breath_pressure(partial_pressure)
|
||||
return (partial_pressure * BREATH_VOLUME) / (R_IDEAL_GAS_EQUATION * temperature)
|
||||
|
||||
//Mathematical proofs:
|
||||
/*
|
||||
|
||||
get_breath_partial_pressure(gas_pp) --> gas_pp/total_moles()*breath_pp = pp
|
||||
get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles()
|
||||
|
||||
10/20*5 = 2.5
|
||||
10 = 2.5/5*20
|
||||
|
||||
*/
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
var/list/hardcoded_gases = list("o2","n2","co2","plasma") //the main four gases, which were at one time hardcoded
|
||||
|
||||
/proc/meta_gas_list()
|
||||
var/meta_list = new /list
|
||||
. = new /list
|
||||
for(var/gas_path in subtypesof(/datum/gas))
|
||||
var/list/gas_info = new(4)
|
||||
var/datum/gas/g = gas_path
|
||||
var/datum/gas/gas = gas_path
|
||||
|
||||
gas_info[META_GAS_SPECIFIC_HEAT] = initial(g.specific_heat)
|
||||
gas_info[META_GAS_NAME] = initial(g.name)
|
||||
gas_info[META_GAS_MOLES_VISIBLE] = initial(g.moles_visible)
|
||||
if(gas_info[META_GAS_MOLES_VISIBLE] != null)
|
||||
gas_info[META_GAS_OVERLAY] = new /obj/effect/overlay/gas(initial(g.gas_overlay))
|
||||
|
||||
meta_list[initial(g.id)] = gas_info
|
||||
. = meta_list
|
||||
gas_info[META_GAS_SPECIFIC_HEAT] = initial(gas.specific_heat)
|
||||
gas_info[META_GAS_NAME] = initial(gas.name)
|
||||
gas_info[META_GAS_MOLES_VISIBLE] = initial(gas.moles_visible)
|
||||
if(initial(gas.moles_visible) != null)
|
||||
gas_info[META_GAS_OVERLAY] = new /obj/effect/overlay/gas(initial(gas.gas_overlay))
|
||||
.[initial(gas.id)] = gas_info
|
||||
|
||||
/*||||||||||||||/----------\||||||||||||||*\
|
||||
||||||||||||||||[GAS DATUMS]||||||||||||||||
|
||||
|
||||
@@ -42,12 +42,6 @@
|
||||
#define AALARM_MODE_CONTAMINATED 8 //Turns on all filtering and widenet scrubbing.
|
||||
#define AALARM_MODE_REFILL 9 //just like normal, but with triple the air output
|
||||
|
||||
#define AALARM_SCREEN_MAIN 1
|
||||
#define AALARM_SCREEN_VENT 2
|
||||
#define AALARM_SCREEN_SCRUB 3
|
||||
#define AALARM_SCREEN_MODE 4
|
||||
#define AALARM_SCREEN_SENSORS 5
|
||||
|
||||
#define AALARM_REPORT_TIMEOUT 100
|
||||
|
||||
/obj/machinery/airalarm
|
||||
@@ -74,7 +68,6 @@
|
||||
|
||||
var/mode = AALARM_MODE_SCRUBBING
|
||||
|
||||
var/screen = AALARM_SCREEN_MAIN
|
||||
var/area_uid
|
||||
var/area/alarm_area
|
||||
var/danger_level = 0
|
||||
@@ -179,148 +172,126 @@
|
||||
ui = new(user, src, ui_key, "airalarm", name, 440, 650, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/airalarm/get_ui_data(mob/user)
|
||||
/obj/machinery/airalarm/ui_data(mob/user)
|
||||
var/data = list(
|
||||
"locked" = locked,
|
||||
"siliconUser" = user.has_unlimited_silicon_privilege,
|
||||
"screen" = screen,
|
||||
"emagged" = emagged
|
||||
"emagged" = emagged,
|
||||
"atmos_alarm" = alarm_area.atmosalm,
|
||||
"fire_alarm" = alarm_area.fire,
|
||||
"danger_level" = danger_level,
|
||||
)
|
||||
populate_status(data)
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
var/datum/tlv/cur_tlv
|
||||
|
||||
data["environment_data"] = list()
|
||||
var/pressure = environment.return_pressure()
|
||||
cur_tlv = TLV["pressure"]
|
||||
data["environment_data"] += list(list(
|
||||
"name" = "Pressure",
|
||||
"value" = pressure,
|
||||
"unit" = "kPa",
|
||||
"danger_level" = cur_tlv.get_danger_level(pressure)
|
||||
))
|
||||
var/temperature = environment.temperature
|
||||
cur_tlv = TLV["temperature"]
|
||||
data["environment_data"] += list(list(
|
||||
"name" = "Temperature",
|
||||
"value" = temperature,
|
||||
"unit" = "K ([round(temperature - T0C, 0.1)]C)",
|
||||
"danger_level" = cur_tlv.get_danger_level(temperature)
|
||||
))
|
||||
var/total_moles = environment.total_moles()
|
||||
var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume
|
||||
for(var/gas_id in environment.gases)
|
||||
if(!(gas_id in TLV)) // We're not interested in this gas, it seems.
|
||||
continue
|
||||
cur_tlv = TLV[gas_id]
|
||||
data["environment_data"] += list(list(
|
||||
"name" = environment.gases[gas_id][GAS_META][META_GAS_NAME],
|
||||
"value" = environment.gases[gas_id][MOLES] / total_moles * 100,
|
||||
"unit" = "%",
|
||||
"danger_level" = cur_tlv.get_danger_level(environment.gases[gas_id][MOLES] * partial_pressure)
|
||||
))
|
||||
|
||||
if(!locked || user.has_unlimited_silicon_privilege)
|
||||
populate_controls(data)
|
||||
return data
|
||||
data["vents"] = list()
|
||||
for(var/id_tag in alarm_area.air_vent_names)
|
||||
var/long_name = alarm_area.air_vent_names[id_tag]
|
||||
var/list/info = alarm_area.air_vent_info[id_tag]
|
||||
if(!info || info["frequency"] != frequency)
|
||||
continue
|
||||
data["vents"] += list(list(
|
||||
"id_tag" = id_tag,
|
||||
"long_name" = sanitize(long_name),
|
||||
"power" = info["power"],
|
||||
"checks" = info["checks"],
|
||||
"excheck" = info["checks"]&1,
|
||||
"incheck" = info["checks"]&2,
|
||||
"direction" = info["direction"],
|
||||
"external" = info["external"],
|
||||
"extdefault"= (info["external"] == ONE_ATMOSPHERE)
|
||||
))
|
||||
data["scrubbers"] = list()
|
||||
for(var/id_tag in alarm_area.air_scrub_names)
|
||||
var/long_name = alarm_area.air_scrub_names[id_tag]
|
||||
var/list/info = alarm_area.air_scrub_info[id_tag]
|
||||
if(!info || info["frequency"] != frequency)
|
||||
continue
|
||||
data["scrubbers"] += list(list(
|
||||
"id_tag" = id_tag,
|
||||
"long_name" = sanitize(long_name),
|
||||
"power" = info["power"],
|
||||
"scrubbing" = info["scrubbing"],
|
||||
"widenet" = info["widenet"],
|
||||
"filter_co2" = info["filter_co2"],
|
||||
"filter_toxins" = info["filter_toxins"],
|
||||
"filter_n2o" = info["filter_n2o"]
|
||||
))
|
||||
data["mode"] = mode
|
||||
data["modes"] = list()
|
||||
data["modes"] += list(list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0))
|
||||
data["modes"] += list(list("name" = "Contaminated - Scrubs out ALL contaminants quickly","mode" = AALARM_MODE_CONTAMINATED, "selected" = mode == AALARM_MODE_CONTAMINATED, "danger" = 0))
|
||||
data["modes"] += list(list("name" = "Draught - Siphons out air while replacing", "mode" = AALARM_MODE_VENTING, "selected" = mode == AALARM_MODE_VENTING, "danger" = 0))
|
||||
data["modes"] += list(list("name" = "Refill - Triple vent output", "mode" = AALARM_MODE_REFILL, "selected" = mode == AALARM_MODE_REFILL, "danger" = 0))
|
||||
data["modes"] += list(list("name" = "Cycle - Siphons air before replacing", "mode" = AALARM_MODE_REPLACEMENT, "selected" = mode == AALARM_MODE_REPLACEMENT, "danger" = 1))
|
||||
data["modes"] += list(list("name" = "Siphon - Siphons air out of the room", "mode" = AALARM_MODE_SIPHON, "selected" = mode == AALARM_MODE_SIPHON, "danger" = 1))
|
||||
data["modes"] += list(list("name" = "Panic Siphon - Siphons air out of the room quickly","mode" = AALARM_MODE_PANIC, "selected" = mode == AALARM_MODE_PANIC, "danger" = 1))
|
||||
data["modes"] += list(list("name" = "Off - Shuts off vents and scrubbers", "mode" = AALARM_MODE_OFF, "selected" = mode == AALARM_MODE_OFF, "danger" = 0))
|
||||
if(emagged)
|
||||
data["modes"] += list(list("name" = "Flood - Shuts off scrubbers and opens vents", "mode" = AALARM_MODE_FLOOD, "selected" = mode == AALARM_MODE_FLOOD, "danger" = 1))
|
||||
|
||||
/obj/machinery/airalarm/proc/populate_status(list/data)
|
||||
var/turf/location = get_turf(src)
|
||||
if(!location)
|
||||
return
|
||||
var/datum/gas_mixture/environment = location.return_air()
|
||||
var/list/env_gases = environment.gases
|
||||
var/total = environment.total_moles()
|
||||
var/datum/tlv/selected
|
||||
var/list/thresholds = list()
|
||||
|
||||
var/list/environment_data = list()
|
||||
data["atmos_alarm"] = alarm_area.atmosalm
|
||||
data["fire_alarm"] = (alarm_area.fire != null && alarm_area.fire)
|
||||
data["danger_level"] = danger_level
|
||||
if(total)
|
||||
var/datum/tlv/cur_tlv
|
||||
selected = TLV["pressure"]
|
||||
thresholds += list(list("name" = "Pressure", "settings" = list()))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "min2", "selected" = selected.min2))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "min1", "selected" = selected.min1))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max1", "selected" = selected.max1))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max2", "selected" = selected.max2))
|
||||
|
||||
var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume
|
||||
selected = TLV["temperature"]
|
||||
thresholds += list(list("name" = "Temperature", "settings" = list()))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "min2", "selected" = selected.min2))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "min1", "selected" = selected.min1))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max1", "selected" = selected.max1))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max2", "selected" = selected.max2))
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
cur_tlv = TLV["pressure"]
|
||||
environment_data += list(list(
|
||||
"name" = "Pressure",
|
||||
"value" = pressure,
|
||||
"unit" = "kPa",
|
||||
"danger_level" = cur_tlv.get_danger_level(pressure)
|
||||
))
|
||||
|
||||
var/temperature = environment.temperature
|
||||
cur_tlv = TLV["temperature"]
|
||||
environment_data += list(list(
|
||||
"name" = "Temperature",
|
||||
"value" = temperature,
|
||||
"unit" = "K ([round(temperature - T0C, 0.1)]C)",
|
||||
"danger_level" = cur_tlv.get_danger_level(temperature)
|
||||
))
|
||||
|
||||
for(var/gas_id in env_gases)
|
||||
for(var/gas_id in meta_gas_info)
|
||||
if(!(gas_id in TLV)) // We're not interested in this gas, it seems.
|
||||
continue
|
||||
cur_tlv = TLV[gas_id]
|
||||
environment_data += list(list(
|
||||
"name" = env_gases[gas_id][GAS_META][META_GAS_NAME],
|
||||
"value" = env_gases[gas_id][MOLES] / total * 100,
|
||||
"unit" = "%",
|
||||
"danger_level" = cur_tlv.get_danger_level(env_gases[gas_id][MOLES] * partial_pressure)
|
||||
))
|
||||
selected = TLV[gas_id]
|
||||
thresholds += list(list("name" = meta_gas_info[gas_id][META_GAS_NAME], "settings" = list()))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min2", "selected" = selected.min2))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min1", "selected" = selected.min1))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max1", "selected" = selected.max1))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max2", "selected" = selected.max2))
|
||||
|
||||
|
||||
data["environment_data"] = environment_data
|
||||
|
||||
/obj/machinery/airalarm/proc/populate_controls(list/data)
|
||||
switch(screen)
|
||||
if(AALARM_SCREEN_MAIN)
|
||||
data["mode"] = mode
|
||||
if(AALARM_SCREEN_VENT)
|
||||
data["vents"] = list()
|
||||
for(var/id_tag in alarm_area.air_vent_names)
|
||||
var/long_name = alarm_area.air_vent_names[id_tag]
|
||||
var/list/info = alarm_area.air_vent_info[id_tag]
|
||||
if(!info || info["frequency"] != frequency)
|
||||
continue
|
||||
data["vents"] += list(list(
|
||||
"id_tag" = id_tag,
|
||||
"long_name" = sanitize(long_name),
|
||||
"power" = info["power"],
|
||||
"checks" = info["checks"],
|
||||
"excheck" = info["checks"]&1,
|
||||
"incheck" = info["checks"]&2,
|
||||
"direction" = info["direction"],
|
||||
"external" = info["external"],
|
||||
"extdefault"= (info["external"] == ONE_ATMOSPHERE)
|
||||
))
|
||||
if(AALARM_SCREEN_SCRUB)
|
||||
data["scrubbers"] = list()
|
||||
for(var/id_tag in alarm_area.air_scrub_names)
|
||||
var/long_name = alarm_area.air_scrub_names[id_tag]
|
||||
var/list/info = alarm_area.air_scrub_info[id_tag]
|
||||
if(!info || info["frequency"] != frequency)
|
||||
continue
|
||||
data["scrubbers"] += list(list(
|
||||
"id_tag" = id_tag,
|
||||
"long_name" = sanitize(long_name),
|
||||
"power" = info["power"],
|
||||
"scrubbing" = info["scrubbing"],
|
||||
"widenet" = info["widenet"],
|
||||
"filter_co2" = info["filter_co2"],
|
||||
"filter_toxins" = info["filter_toxins"],
|
||||
"filter_n2o" = info["filter_n2o"]
|
||||
))
|
||||
if(AALARM_SCREEN_MODE)
|
||||
data["mode"] = mode
|
||||
data["modes"] = list()
|
||||
data["modes"] += list(list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0))
|
||||
data["modes"] += list(list("name" = "Contaminated - Scrubs out ALL contaminants quickly","mode" = AALARM_MODE_CONTAMINATED, "selected" = mode == AALARM_MODE_CONTAMINATED, "danger" = 0))
|
||||
data["modes"] += list(list("name" = "Draught - Siphons out air while replacing", "mode" = AALARM_MODE_VENTING, "selected" = mode == AALARM_MODE_VENTING, "danger" = 0))
|
||||
data["modes"] += list(list("name" = "Refill - Triple vent output", "mode" = AALARM_MODE_REFILL, "selected" = mode == AALARM_MODE_REFILL, "danger" = 0))
|
||||
data["modes"] += list(list("name" = "Cycle - Siphons air before replacing", "mode" = AALARM_MODE_REPLACEMENT, "selected" = mode == AALARM_MODE_REPLACEMENT, "danger" = 1))
|
||||
data["modes"] += list(list("name" = "Siphon - Siphons air out of the room", "mode" = AALARM_MODE_SIPHON, "selected" = mode == AALARM_MODE_SIPHON, "danger" = 1))
|
||||
data["modes"] += list(list("name" = "Panic Siphon - Siphons air out of the room quickly","mode" = AALARM_MODE_PANIC, "selected" = mode == AALARM_MODE_PANIC, "danger" = 1))
|
||||
data["modes"] += list(list("name" = "Off - Shuts off vents and scrubbers", "mode" = AALARM_MODE_OFF, "selected" = mode == AALARM_MODE_OFF, "danger" = 0))
|
||||
if (src.emagged)
|
||||
data["modes"] += list(list("name" = "Flood - Shuts off scrubbers and opens vents", "mode" = AALARM_MODE_FLOOD, "selected" = mode == AALARM_MODE_FLOOD, "danger" = 1))
|
||||
if(AALARM_SCREEN_SENSORS)
|
||||
var/datum/tlv/selected
|
||||
var/list/thresholds = list()
|
||||
|
||||
selected = TLV["pressure"]
|
||||
thresholds += list(list("name" = "Pressure", "settings" = list()))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "min2", "selected" = selected.min2))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "min1", "selected" = selected.min1))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max1", "selected" = selected.max1))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = "max2", "selected" = selected.max2))
|
||||
|
||||
selected = TLV["temperature"]
|
||||
thresholds += list(list("name" = "Temperature", "settings" = list()))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "min2", "selected" = selected.min2))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "min1", "selected" = selected.min1))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max1", "selected" = selected.max1))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max2", "selected" = selected.max2))
|
||||
|
||||
for (var/gas_id in meta_gas_info)
|
||||
if(!(gas_id in TLV)) // We're not interested in this gas, it seems.
|
||||
continue
|
||||
selected = TLV[gas_id]
|
||||
thresholds += list(list("name" = meta_gas_info[gas_id][META_GAS_NAME], "settings" = list()))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min2", "selected" = selected.min2))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min1", "selected" = selected.min1))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max1", "selected" = selected.max1))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max2", "selected" = selected.max2))
|
||||
|
||||
data["thresholds"] = thresholds
|
||||
data["thresholds"] = thresholds
|
||||
return data
|
||||
|
||||
/obj/machinery/airalarm/ui_act(action, params)
|
||||
if(..() || buildstage != 2)
|
||||
@@ -363,9 +334,6 @@
|
||||
else
|
||||
tlv.vars[name] = round(value, 0.01)
|
||||
. = TRUE
|
||||
if("screen")
|
||||
screen = text2num(params["screen"])
|
||||
. = TRUE
|
||||
if("mode")
|
||||
mode = text2num(params["mode"])
|
||||
apply_mode()
|
||||
@@ -667,7 +635,6 @@
|
||||
if(src.allowed(usr) && !wires.is_cut(WIRE_IDSCAN))
|
||||
locked = !locked
|
||||
user << "<span class='notice'>You [ locked ? "lock" : "unlock"] the air alarm interface.</span>"
|
||||
src.updateUsrDialog()
|
||||
else
|
||||
user << "<span class='danger'>Access denied.</span>"
|
||||
return
|
||||
@@ -727,19 +694,12 @@
|
||||
return ..()
|
||||
|
||||
/obj/machinery/airalarm/power_change()
|
||||
if(powered(power_channel))
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
stat |= NOPOWER
|
||||
spawn(rand(0,15))
|
||||
if(loc)
|
||||
update_icon()
|
||||
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/airalarm/emag_act(mob/user)
|
||||
if(!emagged)
|
||||
src.emagged = 1
|
||||
if(user)
|
||||
user.visible_message("<span class='warning'>Sparks fly out of the [src]!</span>", "<span class='notice'>You emag the [src], disabling its safeties.</span>")
|
||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 50, 1)
|
||||
if(emagged)
|
||||
return
|
||||
emagged = TRUE
|
||||
visible_message("<span class='warning'>Sparks fly out of the [src]!</span>", "<span class='notice'>You emag the [src], disabling its safeties.</span>")
|
||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 50, 1)
|
||||
@@ -27,10 +27,11 @@ Pipelines + Other Objects -> Pipe network
|
||||
var/device_type = 0
|
||||
var/list/obj/machinery/atmospherics/nodes = list()
|
||||
|
||||
/obj/machinery/atmospherics/New()
|
||||
/obj/machinery/atmospherics/New(process = TRUE)
|
||||
nodes.len = device_type
|
||||
..()
|
||||
SSair.atmos_machinery += src
|
||||
if(process)
|
||||
SSair.atmos_machinery += src
|
||||
SetInitDirections()
|
||||
if(can_unwrench)
|
||||
stored = new(src, make_from=src)
|
||||
|
||||
@@ -99,7 +99,7 @@ Passive gate is similar to the regular pump except:
|
||||
ui = new(user, src, ui_key, "atmos_pump", name, 335, 115, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/get_ui_data()
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/ui_data()
|
||||
var/data = list()
|
||||
data["on"] = on
|
||||
data["pressure"] = round(target_pressure)
|
||||
|
||||
@@ -26,14 +26,15 @@ Thus, the two variables affect pump operation are set in New():
|
||||
var/id = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/on
|
||||
on = 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/Destroy()
|
||||
if(SSradio)
|
||||
SSradio.remove_object(src,frequency)
|
||||
if(radio_connection)
|
||||
radio_connection = null
|
||||
return ..()
|
||||
/obj/machinery/atmospherics/components/binary/pump/on
|
||||
on = 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/update_icon_nopipes()
|
||||
if(stat & NOPOWER)
|
||||
@@ -105,7 +106,7 @@ Thus, the two variables affect pump operation are set in New():
|
||||
ui = new(user, src, ui_key, "atmos_pump", name, 335, 115, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/get_ui_data()
|
||||
/obj/machinery/atmospherics/components/binary/pump/ui_data()
|
||||
var/data = list()
|
||||
data["on"] = on
|
||||
data["pressure"] = round(target_pressure)
|
||||
|
||||
@@ -101,7 +101,7 @@ Thus, the two variables affect pump operation are set in New():
|
||||
ui = new(user, src, ui_key, "atmos_pump", name, 310, 115, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/get_ui_data()
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/ui_data()
|
||||
var/data = list()
|
||||
data["on"] = on
|
||||
data["rate"] = round(transfer_rate)
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
ui = new(user, src, ui_key, "atmos_filter", name, 470, 140, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/get_ui_data()
|
||||
/obj/machinery/atmospherics/components/trinary/filter/ui_data()
|
||||
var/data = list()
|
||||
data["on"] = on
|
||||
data["pressure"] = round(target_pressure)
|
||||
@@ -146,10 +146,10 @@
|
||||
if("filter")
|
||||
filter_type = ""
|
||||
var/filter_name = "nothing"
|
||||
var/mode = params["mode"]
|
||||
if(mode in meta_gas_info)
|
||||
filter_type = mode
|
||||
filter_name = meta_gas_info[mode][META_GAS_NAME]
|
||||
var/gas = params["mode"]
|
||||
if(gas in meta_gas_info)
|
||||
filter_type = gas
|
||||
filter_name = meta_gas_info[gas][META_GAS_NAME]
|
||||
investigate_log("was set to filter [filter_name] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
update_icon()
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
ui = new(user, src, ui_key, "atmos_mixer", name, 370, 165, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/get_ui_data()
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/ui_data()
|
||||
var/data = list()
|
||||
data["on"] = on
|
||||
data["set_pressure"] = round(target_pressure)
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
user << "[src] seems empty."
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/MouseDrop_T(mob/target, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !Adjacent(target))
|
||||
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target))
|
||||
return
|
||||
close_machine(target)
|
||||
|
||||
@@ -198,7 +198,7 @@
|
||||
ui = new(user, src, ui_key, "cryo", name, 400, 550, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/get_ui_data()
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_data()
|
||||
var/list/data = list()
|
||||
data["isOperating"] = on
|
||||
data["hasOccupant"] = occupant ? 1 : 0
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
ui = new(user, src, ui_key, "thermomachine", name, 400, 240, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/get_ui_data(mob/user)
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["on"] = on
|
||||
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
/obj/machinery/computer/area_atmos
|
||||
name = "area air control computer"
|
||||
desc = "A computer used to control the stationary scrubbers and pumps in the area."
|
||||
icon_screen = "area_atmos"
|
||||
icon_keyboard = "atmos_key"
|
||||
circuit = "/obj/item/weapon/circuitboard/area_atmos"
|
||||
|
||||
var/list/connectedscrubbers = new()
|
||||
var/status = ""
|
||||
|
||||
var/range = 25
|
||||
|
||||
//Simple variable to prevent me from doing attack_hand in both this and the child computer
|
||||
var/zone = "This computer is working on a wireless range, the range is currently limited to 25 meters."
|
||||
|
||||
/obj/machinery/computer/area_atmos/New()
|
||||
..()
|
||||
//So the scrubbers have time to spawn
|
||||
spawn(10)
|
||||
scanscrubbers()
|
||||
|
||||
/obj/machinery/computer/area_atmos/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
src.add_fingerprint(usr)
|
||||
var/dat = {"
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
a.green:link
|
||||
{
|
||||
color:#00CC00;
|
||||
}
|
||||
a.green:visited
|
||||
{
|
||||
color:#00CC00;
|
||||
}
|
||||
a.green:hover
|
||||
{
|
||||
color:#00CC00;
|
||||
}
|
||||
a.green:active
|
||||
{
|
||||
color:#00CC00;
|
||||
}
|
||||
a.red:link
|
||||
{
|
||||
color:#FF0000;
|
||||
}
|
||||
a.red:visited
|
||||
{
|
||||
color:#FF0000;
|
||||
}
|
||||
a.red:hover
|
||||
{
|
||||
color:#FF0000;
|
||||
}
|
||||
a.red:active
|
||||
{
|
||||
color:#FF0000;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<center><h1>Area Air Control</h1></center>
|
||||
<font color="red">[status]</font><br>
|
||||
<a href="?src=\ref[src];scan=1">Scan</a>
|
||||
<table border="1" width="90%">"}
|
||||
for(var/obj/machinery/portable_atmospherics/scrubber/huge/scrubber in connectedscrubbers)
|
||||
dat += {"
|
||||
<tr>
|
||||
<td>[scrubber.name]</td>
|
||||
<td width="150"><a class="green" href="?src=\ref[src];scrub=\ref[scrubber];toggle=1">Turn On</a> <a class="red" href="?src=\ref[src];scrub=\ref[scrubber];toggle=0">Turn Off</a></td>
|
||||
</tr>"}
|
||||
|
||||
dat += {"
|
||||
</table><br>
|
||||
<i>[zone]</i>
|
||||
</body>
|
||||
</html>"}
|
||||
user << browse("[dat]", "window=miningshuttle;size=400x400")
|
||||
status = ""
|
||||
|
||||
/obj/machinery/computer/area_atmos/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
|
||||
|
||||
if(href_list["scan"])
|
||||
scanscrubbers()
|
||||
else if(href_list["toggle"])
|
||||
var/obj/machinery/portable_atmospherics/scrubber/huge/scrubber = locate(href_list["scrub"])
|
||||
|
||||
if(!validscrubber(scrubber))
|
||||
spawn(20)
|
||||
status = "ERROR: Couldn't connect to scrubber! (timeout)"
|
||||
connectedscrubbers -= scrubber
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
scrubber.on = text2num(href_list["toggle"])
|
||||
scrubber.update_icon()
|
||||
|
||||
/obj/machinery/computer/area_atmos/proc/validscrubber( obj/machinery/portable_atmospherics/scrubber/huge/scrubber )
|
||||
if(!isobj(scrubber) || get_dist(scrubber.loc, src.loc) > src.range || scrubber.loc.z != src.loc.z)
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/area_atmos/proc/scanscrubbers()
|
||||
connectedscrubbers = new()
|
||||
|
||||
var/found = 0
|
||||
for(var/obj/machinery/portable_atmospherics/scrubber/huge/scrubber in ultra_range(range, src.loc))
|
||||
if(istype(scrubber))
|
||||
found = 1
|
||||
connectedscrubbers += scrubber
|
||||
|
||||
if(!found)
|
||||
status = "ERROR: No scrubber found!"
|
||||
|
||||
src.updateUsrDialog()
|
||||
|
||||
|
||||
/obj/machinery/computer/area_atmos/area
|
||||
zone = "This computer is working in a wired network limited to this area."
|
||||
|
||||
validscrubber( obj/machinery/portable_atmospherics/scrubber/huge/scrubber )
|
||||
if(!isobj(scrubber))
|
||||
return 0
|
||||
|
||||
/*
|
||||
wow this is stupid, someone help me
|
||||
*/
|
||||
var/turf/T_src = get_turf(src)
|
||||
if(!T_src.loc) return 0
|
||||
var/area/A_src = T_src.loc
|
||||
if (A_src.master)
|
||||
A_src = A_src.master
|
||||
|
||||
var/turf/T_scrub = get_turf(scrubber)
|
||||
if(!T_scrub.loc) return 0
|
||||
var/area/A_scrub = T_scrub.loc
|
||||
if (A_scrub.master)
|
||||
A_scrub = A_scrub.master
|
||||
|
||||
if(A_scrub != A_src)
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/area_atmos/area/scanscrubbers()
|
||||
connectedscrubbers = new()
|
||||
|
||||
var/found = 0
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T.loc) return
|
||||
var/area/A = T.loc
|
||||
if (A.master)
|
||||
A = A.master
|
||||
for(var/obj/machinery/portable_atmospherics/scrubber/huge/scrubber in machines )
|
||||
var/turf/T2 = get_turf(scrubber)
|
||||
if(T2 && T2.loc)
|
||||
var/area/A2 = T2.loc
|
||||
if(istype(A2) && A2.master && A2.master == A )
|
||||
connectedscrubbers += scrubber
|
||||
found = 1
|
||||
|
||||
|
||||
if(!found)
|
||||
status = "ERROR: No scrubber found!"
|
||||
|
||||
src.updateUsrDialog()
|
||||
@@ -1,25 +1,27 @@
|
||||
#define CAN_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*10)
|
||||
#define CAN_MIN_RELEASE_PRESSURE (ONE_ATMOSPHERE/10)
|
||||
#define CAN_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE * 10)
|
||||
#define CAN_MIN_RELEASE_PRESSURE (ONE_ATMOSPHERE / 10)
|
||||
#define CAN_DEFAULT_RELEASE_PRESSURE (ONE_ATMOSPHERE)
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister
|
||||
name = "canister"
|
||||
desc = "A canister for the storage of gas."
|
||||
icon = 'icons/obj/atmos.dmi'
|
||||
icon_state = "yellow"
|
||||
density = 1
|
||||
var/health = 100
|
||||
var/valve_open = 0
|
||||
var/release_pressure = ONE_ATMOSPHERE
|
||||
var/canister_color = "yellow"
|
||||
var/filled = 0.5
|
||||
pressure_resistance = 7*ONE_ATMOSPHERE
|
||||
var/temperature_resistance = 1000 + T0C
|
||||
volume = 1000
|
||||
use_power = 0
|
||||
|
||||
var/valve_open = FALSE
|
||||
var/obj/machinery/atmospherics/components/binary/pump/pump
|
||||
var/release_log = ""
|
||||
var/update_flag = 0
|
||||
|
||||
volume = 1000
|
||||
var/filled = 0.5
|
||||
var/gas_type = ""
|
||||
var/release_pressure = ONE_ATMOSPHERE
|
||||
|
||||
var/health = 100
|
||||
pressure_resistance = 7 * ONE_ATMOSPHERE
|
||||
var/temperature_resistance = 1000 + T0C
|
||||
|
||||
var/update = 0
|
||||
var/static/list/label2types = list(
|
||||
"n2" = /obj/machinery/portable_atmospherics/canister/nitrogen,
|
||||
"o2" = /obj/machinery/portable_atmospherics/canister/oxygen,
|
||||
@@ -34,25 +36,21 @@
|
||||
name = "n2 canister"
|
||||
desc = "Nitrogen gas. Reportedly useful for something."
|
||||
icon_state = "red"
|
||||
canister_color = "red"
|
||||
gas_type = "n2"
|
||||
/obj/machinery/portable_atmospherics/canister/oxygen
|
||||
name = "o2 canister"
|
||||
desc = "Oxygen. Necessary for human life."
|
||||
icon_state = "blue"
|
||||
canister_color = "blue"
|
||||
gas_type = "o2"
|
||||
/obj/machinery/portable_atmospherics/canister/carbon_dioxide
|
||||
name = "co2 canister"
|
||||
desc = "Carbon dioxide. What the fuck is carbon dioxide?"
|
||||
icon_state = "black"
|
||||
canister_color = "black"
|
||||
gas_type = "co2"
|
||||
/obj/machinery/portable_atmospherics/canister/toxins
|
||||
name = "plasma canister"
|
||||
desc = "Plasma gas. The reason YOU are here. Highly toxic."
|
||||
icon_state = "orange"
|
||||
canister_color = "orange"
|
||||
gas_type = "plasma"
|
||||
/obj/machinery/portable_atmospherics/canister/agent_b
|
||||
name = "agent b canister"
|
||||
@@ -62,75 +60,87 @@
|
||||
name = "n2o canister"
|
||||
desc = "Nitrous oxide gas. Known to cause drowsiness."
|
||||
icon_state = "redws"
|
||||
canister_color = "redws"
|
||||
gas_type = "n2o"
|
||||
/obj/machinery/portable_atmospherics/canister/air
|
||||
name = "air canister"
|
||||
desc = "Pre-mixed air."
|
||||
icon_state = "grey"
|
||||
canister_color = "grey"
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/proc/check_change()
|
||||
var/old_flag = update_flag
|
||||
update_flag = 0
|
||||
if(holding)
|
||||
update_flag |= 1
|
||||
if(connected_port)
|
||||
update_flag |= 2
|
||||
/obj/machinery/portable_atmospherics/canister/New(loc)
|
||||
..()
|
||||
create_gas()
|
||||
pump = new(src, FALSE)
|
||||
pump.on = TRUE
|
||||
pump.stat = 0
|
||||
pump.build_network()
|
||||
update_icon()
|
||||
|
||||
var/tank_pressure = air_contents.return_pressure()
|
||||
if(tank_pressure < 10)
|
||||
update_flag |= 4
|
||||
else if(tank_pressure < ONE_ATMOSPHERE)
|
||||
update_flag |= 8
|
||||
else if(tank_pressure < 15*ONE_ATMOSPHERE)
|
||||
update_flag |= 16
|
||||
else
|
||||
update_flag |= 32
|
||||
/obj/machinery/portable_atmospherics/canister/Destroy()
|
||||
qdel(pump)
|
||||
pump = null
|
||||
return ..()
|
||||
|
||||
if(update_flag == old_flag)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
/obj/machinery/portable_atmospherics/canister/proc/create_gas()
|
||||
if(gas_type)
|
||||
air_contents.assert_gas(gas_type)
|
||||
air_contents.gases[gas_type][MOLES] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/air/create_gas()
|
||||
air_contents.assert_gases("o2","n2")
|
||||
air_contents.gases["o2"][MOLES] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
|
||||
air_contents.gases["n2"][MOLES] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
|
||||
|
||||
#define HOLDING 1
|
||||
#define CONNECTED 2
|
||||
#define EMPTY 4
|
||||
#define LOW 8
|
||||
#define FULL 16
|
||||
#define DANGER 32
|
||||
/obj/machinery/portable_atmospherics/canister/update_icon()
|
||||
/*
|
||||
update_flag
|
||||
1 = holding
|
||||
2 = connected_port
|
||||
4 = tank_pressure < 10
|
||||
8 = tank_pressure < ONE_ATMOS
|
||||
16 = tank_pressure < 15*ONE_ATMOS
|
||||
32 = tank_pressure go boom.
|
||||
*/
|
||||
|
||||
if (destroyed)
|
||||
overlays = 0
|
||||
icon_state = text("[]-1", canister_color)
|
||||
if(destroyed)
|
||||
overlays.Cut()
|
||||
icon_state = "[initial(icon_state)]-1"
|
||||
return
|
||||
|
||||
if(icon_state != "[canister_color]")
|
||||
icon_state = "[canister_color]"
|
||||
var/last_update = update
|
||||
update = 0
|
||||
|
||||
if(check_change()) //Returns 1 if no change needed to icons.
|
||||
if(holding)
|
||||
update |= HOLDING
|
||||
if(connected_port)
|
||||
update |= CONNECTED
|
||||
var/pressure = air_contents.return_pressure()
|
||||
if(pressure < 10)
|
||||
update |= EMPTY
|
||||
else if(pressure < ONE_ATMOSPHERE)
|
||||
update |= LOW
|
||||
else if(pressure < 15 * ONE_ATMOSPHERE)
|
||||
update |= FULL
|
||||
else
|
||||
update |= DANGER
|
||||
|
||||
if(update == last_update)
|
||||
return
|
||||
|
||||
src.overlays = 0
|
||||
|
||||
if(update_flag & 1)
|
||||
overlays.Cut()
|
||||
if(update & HOLDING)
|
||||
overlays += "can-open"
|
||||
if(update_flag & 2)
|
||||
if(update & CONNECTED)
|
||||
overlays += "can-connector"
|
||||
if(update_flag & 4)
|
||||
if(update & EMPTY)
|
||||
overlays += "can-o0"
|
||||
if(update_flag & 8)
|
||||
else if(update & LOW)
|
||||
overlays += "can-o1"
|
||||
else if(update_flag & 16)
|
||||
else if(update & FULL)
|
||||
overlays += "can-o2"
|
||||
else if(update_flag & 32)
|
||||
else if(update & DANGER)
|
||||
overlays += "can-o3"
|
||||
return
|
||||
|
||||
#undef HOLDING
|
||||
#undef CONNECTED
|
||||
#undef EMPTY
|
||||
#undef LOW
|
||||
#undef FULL
|
||||
#undef DANGER
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > temperature_resistance)
|
||||
@@ -139,86 +149,47 @@ update_flag
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/proc/healthcheck()
|
||||
if(destroyed)
|
||||
return 1
|
||||
return
|
||||
|
||||
if (src.health <= 10)
|
||||
var/atom/location = src.loc
|
||||
location.assume_air(air_contents)
|
||||
if(health <= 10)
|
||||
var/turf/T = get_turf(src)
|
||||
T.assume_air(air_contents)
|
||||
air_update_turf()
|
||||
|
||||
src.destroyed = 1
|
||||
destroyed = TRUE
|
||||
density = 0
|
||||
playsound(src.loc, 'sound/effects/spray.ogg', 10, 1, -3)
|
||||
src.density = 0
|
||||
update_icon()
|
||||
investigate_log("was destroyed by heat/gunfire.", "atmos")
|
||||
investigate_log("was destroyed.", "atmos")
|
||||
|
||||
if (src.holding)
|
||||
src.holding.loc = src.loc
|
||||
src.holding = null
|
||||
|
||||
return 1
|
||||
else
|
||||
return 1
|
||||
if(holding)
|
||||
holding.loc = T
|
||||
holding = null
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/process_atmos()
|
||||
if (destroyed)
|
||||
if(destroyed)
|
||||
return PROCESS_KILL
|
||||
if(!valve_open)
|
||||
return
|
||||
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
pump.AIR1 = air_contents
|
||||
pump.AIR2 = holding ? holding.air_contents : T.return_air()
|
||||
pump.target_pressure = release_pressure
|
||||
|
||||
if(valve_open)
|
||||
var/datum/gas_mixture/environment
|
||||
if(holding)
|
||||
environment = holding.air_contents
|
||||
else
|
||||
environment = loc.return_air()
|
||||
|
||||
var/env_pressure = environment.return_pressure()
|
||||
var/pressure_delta = min(release_pressure - env_pressure, (air_contents.return_pressure() - env_pressure)/2)
|
||||
//Can not have a pressure delta that would cause environment pressure > tank pressure
|
||||
|
||||
var/transfer_moles = 0
|
||||
if((air_contents.temperature > 0) && (pressure_delta > 0))
|
||||
transfer_moles = pressure_delta*environment.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
//Actually transfer the gas
|
||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
||||
|
||||
if(holding)
|
||||
environment.merge(removed)
|
||||
else
|
||||
loc.assume_air(removed)
|
||||
air_update_turf()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/process()
|
||||
src.updateDialog()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/return_air()
|
||||
return air_contents
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/proc/return_temperature()
|
||||
var/datum/gas_mixture/GM = src.return_air()
|
||||
if(GM && GM.volume>0)
|
||||
return GM.temperature
|
||||
return 0
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/proc/return_pressure()
|
||||
var/datum/gas_mixture/GM = src.return_air()
|
||||
if(GM && GM.volume>0)
|
||||
return GM.return_pressure()
|
||||
return 0
|
||||
pump.process_atmos() // Pump gas.
|
||||
if(!holding)
|
||||
air_update_turf() // Update the environment if needed.
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/blob_act()
|
||||
src.health -= 200
|
||||
health = 0
|
||||
healthcheck()
|
||||
return
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/bullet_act(obj/item/projectile/Proj)
|
||||
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
if(Proj.damage)
|
||||
src.health -= round(Proj.damage / 2)
|
||||
/obj/machinery/portable_atmospherics/canister/bullet_act(obj/item/projectile/P)
|
||||
if((P.damage_type == BRUTE || P.damage_type == BURN))
|
||||
if(P.damage)
|
||||
health -= round(P.damage / 2)
|
||||
healthcheck()
|
||||
..()
|
||||
|
||||
@@ -227,55 +198,37 @@ update_flag
|
||||
if(1)
|
||||
if(destroyed || prob(30))
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
src.health = 0
|
||||
healthcheck()
|
||||
return
|
||||
health = 0
|
||||
if(2)
|
||||
if(destroyed)
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
src.health -= rand(40, 100)
|
||||
healthcheck()
|
||||
return
|
||||
health -= rand(40, 100)
|
||||
if(3)
|
||||
src.health -= rand(15,40)
|
||||
healthcheck()
|
||||
return
|
||||
return
|
||||
health -= rand(15, 40)
|
||||
healthcheck()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(!istype(W, /obj/item/weapon/wrench) && !istype(W, /obj/item/weapon/tank) && !istype(W, /obj/item/device/analyzer) && !istype(W, /obj/item/device/pda))
|
||||
investigate_log("was smacked with \a [W] by [key_name(user)]", "atmos")
|
||||
investigate_log("was smacked with \a [W] by [key_name(user)].", "atmos")
|
||||
health -= W.force
|
||||
add_fingerprint(user)
|
||||
healthcheck()
|
||||
|
||||
if(istype(user, /mob/living/silicon/robot) && istype(W, /obj/item/weapon/tank/jetpack))
|
||||
var/datum/gas_mixture/thejetpack = W:air_contents
|
||||
var/env_pressure = thejetpack.return_pressure()
|
||||
var/pressure_delta = min(10*ONE_ATMOSPHERE - env_pressure, (air_contents.return_pressure() - env_pressure)/2)
|
||||
//Can not have a pressure delta that would cause environment pressure > tank pressure
|
||||
var/transfer_moles = 0
|
||||
if((air_contents.temperature > 0) && (pressure_delta > 0))
|
||||
transfer_moles = pressure_delta*thejetpack.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION)//Actually transfer the gas
|
||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
||||
thejetpack.merge(removed)
|
||||
user << "<span class='notice'>You pulse-pressurize your jetpack from the tank.</span>"
|
||||
return
|
||||
|
||||
..()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "canister", name, 415, 405, master_ui, state)
|
||||
ui = new(user, src, ui_key, "canister", name, 420, 405, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/get_ui_data()
|
||||
/obj/machinery/portable_atmospherics/canister/ui_data()
|
||||
var/data = list()
|
||||
data["name"] = name
|
||||
data["portConnected"] = connected_port ? 1 : 0
|
||||
data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
|
||||
data["releasePressure"] = round(release_pressure ? release_pressure : 0)
|
||||
@@ -302,7 +255,6 @@ update_flag
|
||||
if(newtype)
|
||||
var/obj/machinery/portable_atmospherics/canister/replacement = new newtype(loc)
|
||||
replacement.air_contents.copy_from(air_contents)
|
||||
replacement.update_icon()
|
||||
replacement.interact(usr)
|
||||
qdel(src)
|
||||
if("pressure")
|
||||
@@ -325,7 +277,7 @@ update_flag
|
||||
. = TRUE
|
||||
if(.)
|
||||
release_pressure = Clamp(round(pressure), CAN_MIN_RELEASE_PRESSURE, CAN_MAX_RELEASE_PRESSURE)
|
||||
investigate_log("was set to [release_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
investigate_log("was set to [release_pressure] kPa by [key_name(usr)].", "atmos")
|
||||
if("valve")
|
||||
var/logmsg
|
||||
valve_open = !valve_open
|
||||
@@ -346,25 +298,7 @@ update_flag
|
||||
if(holding)
|
||||
if(valve_open)
|
||||
investigate_log("[key_name(usr)] removed the [holding], leaving the valve open and transfering into the <span class='boldannounce'>air</span><br>", "atmos")
|
||||
holding.loc = loc
|
||||
holding.loc = get_turf(src)
|
||||
holding = null
|
||||
. = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/New(loc)
|
||||
..()
|
||||
|
||||
create_gas()
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/proc/create_gas()
|
||||
if(gas_type)
|
||||
air_contents.assert_gas(gas_type)
|
||||
air_contents.gases[gas_type][MOLES] = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/air/create_gas()
|
||||
air_contents.assert_gases("o2","n2")
|
||||
// PV = nRT
|
||||
air_contents.gases["o2"][MOLES] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
|
||||
air_contents.gases["n2"][MOLES] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
/obj/machinery/portable_atmospherics
|
||||
name = "atmoalter"
|
||||
name = "portable_atmospherics"
|
||||
icon = 'icons/obj/atmos.dmi'
|
||||
use_power = 0
|
||||
var/datum/gas_mixture/air_contents = new
|
||||
|
||||
var/datum/gas_mixture/air_contents = new
|
||||
var/obj/machinery/atmospherics/components/unary/portables_connector/connected_port
|
||||
var/obj/item/weapon/tank/holding
|
||||
|
||||
var/volume = 0
|
||||
var/destroyed = 0
|
||||
|
||||
var/maximum_pressure = 90*ONE_ATMOSPHERE
|
||||
var/lastupdate = 0
|
||||
var/maximum_pressure = 90 * ONE_ATMOSPHERE
|
||||
|
||||
/obj/machinery/portable_atmospherics/New()
|
||||
..()
|
||||
@@ -20,20 +20,19 @@
|
||||
return 1
|
||||
|
||||
/obj/machinery/portable_atmospherics/process_atmos()
|
||||
if(!connected_port) //only react when pipe_network will not it do it for you
|
||||
//Allow for reactions
|
||||
if(!connected_port) // Pipe network handles reactions if connected.
|
||||
air_contents.react()
|
||||
else
|
||||
update_icon()
|
||||
/obj/machinery/portable_atmospherics/process()
|
||||
return
|
||||
|
||||
/obj/machinery/portable_atmospherics/Destroy()
|
||||
qdel(air_contents)
|
||||
air_contents = null
|
||||
SSair.atmos_machinery -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/portable_atmospherics/update_icon()
|
||||
return null
|
||||
/obj/machinery/portable_atmospherics/return_air()
|
||||
return air_contents
|
||||
|
||||
/obj/machinery/portable_atmospherics/proc/connect(obj/machinery/atmospherics/components/unary/portables_connector/new_port)
|
||||
//Make sure not already connected to something else
|
||||
@@ -65,19 +64,14 @@
|
||||
return air_contents
|
||||
|
||||
/obj/machinery/portable_atmospherics/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if ((istype(W, /obj/item/weapon/tank) && !( src.destroyed )))
|
||||
if (src.holding)
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
|
||||
if((istype(W, /obj/item/weapon/tank) && !destroyed))
|
||||
var/obj/item/weapon/tank/T = W
|
||||
if(holding || !user.drop_item())
|
||||
return
|
||||
T.loc = src
|
||||
src.holding = T
|
||||
holding = T
|
||||
update_icon()
|
||||
return
|
||||
|
||||
else if (istype(W, /obj/item/weapon/wrench))
|
||||
else if(istype(W, /obj/item/weapon/wrench))
|
||||
if(connected_port)
|
||||
disconnect()
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
@@ -89,24 +83,19 @@
|
||||
return
|
||||
else
|
||||
var/obj/machinery/atmospherics/components/unary/portables_connector/possible_port = locate(/obj/machinery/atmospherics/components/unary/portables_connector) in loc
|
||||
if(possible_port)
|
||||
if(connect(possible_port))
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user.visible_message( \
|
||||
"[user] connects [src].", \
|
||||
"<span class='notice'>You fasten [src] to the port.</span>", \
|
||||
"<span class='italics'>You hear a ratchet.</span>")
|
||||
update_icon()
|
||||
return
|
||||
else
|
||||
user << "<span class='notice'>[name] failed to connect to the port.</span>"
|
||||
return
|
||||
else
|
||||
if(!possible_port)
|
||||
user << "<span class='notice'>Nothing happens.</span>"
|
||||
return
|
||||
|
||||
else if ((istype(W, /obj/item/device/analyzer)) && get_dist(user, src) <= 1)
|
||||
if(!connect(possible_port))
|
||||
user << "<span class='notice'>[name] failed to connect to the port.</span>"
|
||||
return
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user.visible_message( \
|
||||
"[user] connects [src].", \
|
||||
"<span class='notice'>You fasten [src] to the port.</span>", \
|
||||
"<span class='italics'>You hear a ratchet.</span>")
|
||||
update_icon()
|
||||
else if((istype(W, /obj/item/device/analyzer)) && Adjacent(user))
|
||||
atmosanalyzer_scan(air_contents, user)
|
||||
|
||||
else
|
||||
..()
|
||||
@@ -1,157 +1,139 @@
|
||||
#define PUMP_OUT "out"
|
||||
#define PUMP_IN "in"
|
||||
#define PUMP_MAX_PRESSURE (ONE_ATMOSPHERE * 10)
|
||||
#define PUMP_MIN_PRESSURE (ONE_ATMOSPHERE / 10)
|
||||
#define PUMP_DEFAULT_PRESSURE (ONE_ATMOSPHERE)
|
||||
|
||||
/obj/machinery/portable_atmospherics/pump
|
||||
name = "portable air pump"
|
||||
|
||||
icon = 'icons/obj/atmos.dmi'
|
||||
icon_state = "psiphon:0"
|
||||
density = 1
|
||||
|
||||
var/on = 0
|
||||
var/direction_out = 0 //0 = siphoning, 1 = releasing
|
||||
var/target_pressure = 100
|
||||
var/on = FALSE
|
||||
var/direction = PUMP_OUT
|
||||
var/obj/machinery/atmospherics/components/binary/pump/pump
|
||||
|
||||
volume = 1000
|
||||
|
||||
/obj/machinery/portable_atmospherics/pump/New()
|
||||
..()
|
||||
pump = new(src, FALSE)
|
||||
pump.on = TRUE
|
||||
pump.stat = 0
|
||||
pump.build_network()
|
||||
|
||||
/obj/machinery/portable_atmospherics/pump/Destroy()
|
||||
var/turf/T = get_turf(src)
|
||||
T.assume_air(air_contents)
|
||||
air_update_turf()
|
||||
qdel(pump)
|
||||
pump = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/portable_atmospherics/pump/update_icon()
|
||||
src.overlays = 0
|
||||
|
||||
if(on)
|
||||
icon_state = "psiphon:1"
|
||||
else
|
||||
icon_state = "psiphon:0"
|
||||
icon_state = "psiphon:[on]"
|
||||
|
||||
overlays.Cut()
|
||||
if(holding)
|
||||
overlays += "siphon-open"
|
||||
|
||||
if(connected_port)
|
||||
overlays += "siphon-connector"
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/portable_atmospherics/pump/emp_act(severity)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
..(severity)
|
||||
return
|
||||
|
||||
if(prob(50/severity))
|
||||
on = !on
|
||||
|
||||
if(prob(100/severity))
|
||||
direction_out = !direction_out
|
||||
|
||||
target_pressure = rand(0,1300)
|
||||
update_icon()
|
||||
|
||||
..(severity)
|
||||
|
||||
/obj/machinery/portable_atmospherics/pump/process_atmos()
|
||||
..()
|
||||
if(on)
|
||||
var/datum/gas_mixture/environment
|
||||
if(holding)
|
||||
environment = holding.air_contents
|
||||
else
|
||||
environment = loc.return_air()
|
||||
if(direction_out)
|
||||
var/pressure_delta = target_pressure - environment.return_pressure()
|
||||
//Can not have a pressure delta that would cause environment pressure > tank pressure
|
||||
if(!on)
|
||||
return
|
||||
|
||||
var/transfer_moles = 0
|
||||
if(air_contents.temperature > 0)
|
||||
transfer_moles = pressure_delta*environment.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
|
||||
var/turf/T = get_turf(src)
|
||||
if(direction == PUMP_OUT) // Hook up the internal pump.
|
||||
pump.AIR1 = holding ? holding.air_contents : air_contents
|
||||
pump.AIR2 = holding ? air_contents : T.return_air()
|
||||
else
|
||||
pump.AIR1 = holding ? air_contents : T.return_air()
|
||||
pump.AIR2 = holding ? holding.air_contents : air_contents
|
||||
|
||||
//Actually transfer the gas
|
||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
||||
pump.process_atmos() // Pump gas.
|
||||
if(!holding)
|
||||
air_update_turf() // Update the environment if needed.
|
||||
|
||||
if(holding)
|
||||
environment.merge(removed)
|
||||
else
|
||||
loc.assume_air(removed)
|
||||
air_update_turf()
|
||||
else
|
||||
var/pressure_delta = target_pressure - air_contents.return_pressure()
|
||||
//Can not have a pressure delta that would cause environment pressure > tank pressure
|
||||
|
||||
var/transfer_moles = 0
|
||||
if(environment.temperature > 0)
|
||||
transfer_moles = pressure_delta*air_contents.volume/(environment.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
//Actually transfer the gas
|
||||
var/datum/gas_mixture/removed
|
||||
if(holding)
|
||||
removed = environment.remove(transfer_moles)
|
||||
else
|
||||
removed = loc.remove_air(transfer_moles)
|
||||
air_update_turf()
|
||||
|
||||
air_contents.merge(removed)
|
||||
//src.update_icon()
|
||||
/obj/machinery/portable_atmospherics/pump/process()
|
||||
/obj/machinery/portable_atmospherics/pump/emp_act(severity)
|
||||
if(is_operational())
|
||||
if(prob(50 / severity))
|
||||
on = !on
|
||||
if(prob(100 / severity))
|
||||
direction = PUMP_OUT
|
||||
pump.target_pressure = rand(0, 100 * ONE_ATMOSPHERE)
|
||||
update_icon()
|
||||
..()
|
||||
src.updateDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/portable_atmospherics/pump/return_air()
|
||||
return air_contents
|
||||
|
||||
/obj/machinery/portable_atmospherics/pump/attack_ai(mob/user)
|
||||
return src.attack_hand(user)
|
||||
/obj/machinery/portable_atmospherics/pump/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "portable_pump", name, 420, 415, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/portable_atmospherics/pump/attack_paw(mob/user)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/portable_atmospherics/pump/attack_hand(mob/user)
|
||||
|
||||
user.set_machine(src)
|
||||
var/holding_text
|
||||
/obj/machinery/portable_atmospherics/pump/ui_data()
|
||||
var/data = list()
|
||||
data["on"] = on
|
||||
data["direction"] = direction
|
||||
data["connected"] = connected_port ? 1 : 0
|
||||
data["pressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
|
||||
data["target_pressure"] = round(pump.target_pressure ? pump.target_pressure : 0)
|
||||
data["default_pressure"] = round(PUMP_DEFAULT_PRESSURE)
|
||||
data["min_pressure"] = round(PUMP_MIN_PRESSURE)
|
||||
data["max_pressure"] = round(PUMP_MAX_PRESSURE)
|
||||
|
||||
if(holding)
|
||||
holding_text = {"<BR><B>Tank Pressure</B>: [holding.air_contents.return_pressure()] KPa<BR>
|
||||
<A href='?src=\ref[src];remove_tank=1'>Remove Tank</A><BR>
|
||||
"}
|
||||
var/output_text = {"<TT><B>[name]</B><BR>
|
||||
Pressure: [air_contents.return_pressure()] KPa<BR>
|
||||
Port Status: [(connected_port)?("Connected"):("Disconnected")]
|
||||
[holding_text]
|
||||
<BR>
|
||||
Power Switch: <A href='?src=\ref[src];power=1'>[on?("On"):("Off")]</A><BR>
|
||||
Pump Direction: <A href='?src=\ref[src];direction=1'>[direction_out?("Out"):("In")]</A><BR>
|
||||
Target Pressure: <A href='?src=\ref[src];pressure_adj=-1000'>-</A> <A href='?src=\ref[src];pressure_adj=-100'>-</A> <A href='?src=\ref[src];pressure_adj=-10'>-</A> <A href='?src=\ref[src];pressure_adj=-1'>-</A> [target_pressure] <A href='?src=\ref[src];pressure_adj=1'>+</A> <A href='?src=\ref[src];pressure_adj=10'>+</A> <A href='?src=\ref[src];pressure_adj=100'>+</A> <A href='?src=\ref[src];pressure_adj=1000'>+</A><BR>
|
||||
<HR>
|
||||
<A href='?src=\ref[user];mach_close=pump'>Close</A><BR>
|
||||
"}
|
||||
data["holding"] = list()
|
||||
data["holding"]["name"] = holding.name
|
||||
data["holding"]["pressure"] = round(holding.air_contents.return_pressure())
|
||||
return data
|
||||
|
||||
user << browse(output_text, "window=pump;size=600x300")
|
||||
onclose(user, "pump")
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/portable_atmospherics/pump/Topic(href, href_list)
|
||||
..()
|
||||
if (usr.stat || usr.restrained())
|
||||
/obj/machinery/portable_atmospherics/pump/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if (((get_dist(src, usr) <= 1) && istype(src.loc, /turf)))
|
||||
usr.set_machine(src)
|
||||
|
||||
if(href_list["power"])
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
|
||||
if(href_list["direction"])
|
||||
direction_out = !direction_out
|
||||
|
||||
if (href_list["remove_tank"])
|
||||
if(on && !holding)
|
||||
var/plasma = air_contents.gases["plasma"]
|
||||
var/n2o = air_contents.gases["n2o"]
|
||||
if(n2o || plasma)
|
||||
message_admins("[key_name_admin(usr)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[usr]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""]! (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
log_admin("[key_name(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [x], [y], [z]")
|
||||
. = TRUE
|
||||
if("direction")
|
||||
if(direction == PUMP_OUT)
|
||||
direction = PUMP_IN
|
||||
else
|
||||
direction = PUMP_OUT
|
||||
. = TRUE
|
||||
if("pressure")
|
||||
var/pressure = params["pressure"]
|
||||
if(pressure == "reset")
|
||||
pressure = PUMP_DEFAULT_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "min")
|
||||
pressure = PUMP_MIN_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "max")
|
||||
pressure = PUMP_MAX_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "input")
|
||||
pressure = input("New release pressure ([PUMP_MIN_PRESSURE]-[PUMP_MAX_PRESSURE] kPa):", name, pump.target_pressure) as num|null
|
||||
if(!isnull(pressure) && !..())
|
||||
. = TRUE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
pump.target_pressure = Clamp(round(pressure), PUMP_MIN_PRESSURE, PUMP_MAX_PRESSURE)
|
||||
investigate_log("was set to [pump.target_pressure] kPa by [key_name(usr)].", "atmos")
|
||||
if("eject")
|
||||
if(holding)
|
||||
holding.loc = loc
|
||||
holding.loc = get_turf(src)
|
||||
holding = null
|
||||
|
||||
if (href_list["pressure_adj"])
|
||||
var/diff = text2num(href_list["pressure_adj"])
|
||||
target_pressure = min(10*ONE_ATMOSPHERE, max(0, target_pressure+diff))
|
||||
|
||||
src.updateUsrDialog()
|
||||
src.add_fingerprint(usr)
|
||||
update_icon()
|
||||
else
|
||||
usr << browse(null, "window=pump")
|
||||
return
|
||||
return
|
||||
. = TRUE
|
||||
update_icon()
|
||||
@@ -1,214 +1,134 @@
|
||||
/obj/machinery/portable_atmospherics/scrubber
|
||||
name = "portable air scrubber"
|
||||
|
||||
icon = 'icons/obj/atmos.dmi'
|
||||
icon_state = "pscrubber:0"
|
||||
density = 1
|
||||
|
||||
var/on = 0
|
||||
var/volume_rate = 800
|
||||
var/widenet = 0 //is this scrubber acting on the 3x3 area around it.
|
||||
var/on = FALSE
|
||||
var/volume_rate = 1000
|
||||
volume = 1000
|
||||
|
||||
volume = 750
|
||||
|
||||
var/list/gases_to_scrub = list("plasma", "co2", "agent_b", "n2o") //datum var so we can VV it and maybe even change it in the future
|
||||
|
||||
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/emp_act(severity)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
..(severity)
|
||||
return
|
||||
|
||||
if(prob(50/severity))
|
||||
on = !on
|
||||
update_icon()
|
||||
|
||||
..(severity)
|
||||
var/list/scrubbing = list("plasma", "co2", "n2o", "agent_b")
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/Destroy()
|
||||
var/turf/T = get_turf(src)
|
||||
T.assume_air(air_contents)
|
||||
air_update_turf()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/update_icon()
|
||||
src.overlays = 0
|
||||
|
||||
if(on)
|
||||
icon_state = "pscrubber:1"
|
||||
else
|
||||
icon_state = "pscrubber:0"
|
||||
icon_state = "pscrubber:[on]"
|
||||
|
||||
overlays.Cut()
|
||||
if(holding)
|
||||
overlays += "scrubber-open"
|
||||
|
||||
if(connected_port)
|
||||
overlays += "scrubber-connector"
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/process_atmos()
|
||||
..()
|
||||
|
||||
if(!on)
|
||||
return
|
||||
scrub(loc)
|
||||
if (widenet)
|
||||
var/turf/T = loc
|
||||
if (istype(T))
|
||||
for (var/turf/simulated/tile in T.GetAtmosAdjacentTurfs(alldir=1))
|
||||
scrub(tile)
|
||||
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/proc/scrub(var/turf/simulated/tile)
|
||||
var/datum/gas_mixture/environment
|
||||
if(holding)
|
||||
environment = holding.air_contents
|
||||
scrub(holding.air_contents)
|
||||
else
|
||||
environment = tile.return_air()
|
||||
var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles()
|
||||
var/turf/T = get_turf(src)
|
||||
scrub(T.return_air())
|
||||
|
||||
//Take a gas sample
|
||||
var/datum/gas_mixture/removed
|
||||
if(holding)
|
||||
removed = environment.remove(transfer_moles)
|
||||
else
|
||||
removed = tile.remove_air(transfer_moles)
|
||||
/obj/machinery/portable_atmospherics/scrubber/proc/scrub(var/datum/gas_mixture/mixture)
|
||||
var/transfer_moles = min(1, volume_rate / mixture.volume) * mixture.total_moles()
|
||||
|
||||
//Filter it
|
||||
if (removed)
|
||||
var/datum/gas_mixture/filtered_out = new
|
||||
var/list/filtered_gases = filtered_out.gases
|
||||
var/list/removed_gases = removed.gases
|
||||
|
||||
for(var/id in removed_gases & gases_to_scrub)
|
||||
filtered_out.assert_gas(id)
|
||||
filtered_gases[id][MOLES] = removed_gases[id][MOLES]
|
||||
removed_gases[id][MOLES] = 0
|
||||
|
||||
filtered_out.temperature = removed.temperature
|
||||
removed.garbage_collect()
|
||||
|
||||
//Remix the resulting gases
|
||||
air_contents.merge(filtered_out)
|
||||
|
||||
if(holding)
|
||||
environment.merge(removed)
|
||||
else
|
||||
tile.assume_air(removed)
|
||||
tile.air_update_turf()
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/process()
|
||||
..()
|
||||
src.updateDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/return_air()
|
||||
return air_contents
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/attack_ai(mob/user)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/attack_paw(mob/user)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/attack_hand(mob/user)
|
||||
|
||||
user.set_machine(src)
|
||||
var/holding_text
|
||||
|
||||
if(holding)
|
||||
holding_text = {"<BR><B>Tank Pressure</B>: [holding.air_contents.return_pressure()] KPa<BR>
|
||||
<A href='?src=\ref[src];remove_tank=1'>Remove Tank</A><BR>
|
||||
"}
|
||||
var/output_text = {"<TT><B>[name]</B><BR>
|
||||
Pressure: [air_contents.return_pressure()] KPa<BR>
|
||||
Port Status: [(connected_port)?("Connected"):("Disconnected")]
|
||||
[holding_text]
|
||||
<BR>
|
||||
Power Switch: <A href='?src=\ref[src];power=1'>[on?("On"):("Off")]</A><BR>
|
||||
Power regulator: <A href='?src=\ref[src];volume_adj=-1000'>-</A> <A href='?src=\ref[src];volume_adj=-100'>-</A> <A href='?src=\ref[src];volume_adj=-10'>-</A> <A href='?src=\ref[src];volume_adj=-1'>-</A> [volume_rate] <A href='?src=\ref[src];volume_adj=1'>+</A> <A href='?src=\ref[src];volume_adj=10'>+</A> <A href='?src=\ref[src];volume_adj=100'>+</A> <A href='?src=\ref[src];volume_adj=1000'>+</A><BR>
|
||||
|
||||
<HR>
|
||||
<A href='?src=\ref[user];mach_close=scrubber'>Close</A><BR>
|
||||
"}
|
||||
|
||||
user << browse(output_text, "window=scrubber;size=600x300")
|
||||
onclose(user, "scrubber")
|
||||
return
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/Topic(href, href_list)
|
||||
..()
|
||||
if (usr.stat || usr.restrained())
|
||||
var/datum/gas_mixture/filtering = mixture.remove(transfer_moles) // Remove part of the mixture to filter.
|
||||
var/datum/gas_mixture/filtered = new
|
||||
if(!filtering)
|
||||
return
|
||||
|
||||
if (((get_dist(src, usr) <= 1) && istype(src.loc, /turf)))
|
||||
usr.set_machine(src)
|
||||
filtered.temperature = filtering.temperature
|
||||
for(var/gas in filtering.gases & scrubbing)
|
||||
filtered.assert_gas(gas)
|
||||
filtered.gases[gas][MOLES] = filtering.gases[gas][MOLES] // Shuffle the "bad" gasses to the filtered mixture.
|
||||
filtering.gases[gas][MOLES] = 0
|
||||
filtering.garbage_collect() // Now that the gasses are set to 0, clean up the mixture.
|
||||
|
||||
if(href_list["power"])
|
||||
air_contents.merge(filtered) // Store filtered out gasses.
|
||||
mixture.merge(filtering) // Returned the cleaned gas.
|
||||
if(!holding)
|
||||
air_update_turf()
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/emp_act(severity)
|
||||
if(is_operational())
|
||||
if(prob(50 / severity))
|
||||
on = !on
|
||||
|
||||
if (href_list["remove_tank"])
|
||||
if(holding)
|
||||
holding.loc = loc
|
||||
holding = null
|
||||
|
||||
if (href_list["volume_adj"])
|
||||
var/diff = text2num(href_list["volume_adj"])
|
||||
volume_rate = min(10*ONE_ATMOSPHERE, max(0, volume_rate+diff))
|
||||
|
||||
src.updateUsrDialog()
|
||||
src.add_fingerprint(usr)
|
||||
update_icon()
|
||||
else
|
||||
usr << browse(null, "window=scrubber")
|
||||
..()
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "portable_scrubber", name, 420, 335, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/ui_data()
|
||||
var/data = list()
|
||||
data["on"] = on
|
||||
data["connected"] = connected_port ? 1 : 0
|
||||
data["pressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
|
||||
|
||||
if(holding)
|
||||
data["holding"] = list()
|
||||
data["holding"]["name"] = holding.name
|
||||
data["holding"]["pressure"] = round(holding.air_contents.return_pressure())
|
||||
return data
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
. = TRUE
|
||||
if("eject")
|
||||
if(holding)
|
||||
holding.loc = get_turf(src)
|
||||
holding = null
|
||||
. = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/huge
|
||||
name = "huge air scrubber"
|
||||
icon_state = "scrubber:0"
|
||||
anchored = 1
|
||||
anchored = TRUE
|
||||
active_power_usage = 500
|
||||
idle_power_usage = 10
|
||||
|
||||
volume_rate = 1500
|
||||
volume = 50000
|
||||
widenet = 1
|
||||
|
||||
var/static/gid = 1
|
||||
var/id = 0
|
||||
var/stationary = 0
|
||||
var/movable = FALSE
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/huge/New()
|
||||
..()
|
||||
id = gid
|
||||
gid++
|
||||
|
||||
name = "[name] (ID [id])"
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/huge/attack_hand(var/mob/user as mob)
|
||||
usr << "<span class='warning'>You can't directly interact with this machine! Use the area atmos computer.</span>"
|
||||
/obj/machinery/portable_atmospherics/scrubber/huge/movable
|
||||
movable = TRUE
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/huge/update_icon()
|
||||
src.overlays = 0
|
||||
icon_state = "scrubber:[on]"
|
||||
|
||||
if(on)
|
||||
icon_state = "scrubber:1"
|
||||
else
|
||||
icon_state = "scrubber:0"
|
||||
/obj/machinery/portable_atmospherics/scrubber/huge/process_atmos()
|
||||
if((!anchored && !movable) || !is_operational())
|
||||
on = FALSE
|
||||
update_icon()
|
||||
use_power = 1 + on
|
||||
if(!on)
|
||||
return
|
||||
|
||||
..()
|
||||
if(!holding)
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/turf/simulated/AT in T.GetAtmosAdjacentTurfs(alldir = TRUE))
|
||||
scrub(AT.return_air())
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/huge/attackby(obj/item/weapon/W, mob/user)
|
||||
if(istype(W, /obj/item/weapon/wrench))
|
||||
if(stationary)
|
||||
user << "<span class='warning'>The bolts are too tight for you to unscrew!</span>"
|
||||
return
|
||||
if(on)
|
||||
user << "<span class='warning'>Turn it off first!</span>"
|
||||
return
|
||||
|
||||
anchored = !anchored
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "<span class='notice'>You [anchored ? "wrench" : "unwrench"] \the [src].</span>"
|
||||
|
||||
else if ((istype(W, /obj/item/device/analyzer)) && get_dist(user, src) <= 1)
|
||||
atmosanalyzer_scan(air_contents, user)
|
||||
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/huge/stationary
|
||||
name = "stationary air scrubber"
|
||||
stationary = 0
|
||||
if(default_unfasten_wrench(user, W))
|
||||
if(!movable)
|
||||
on = FALSE
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -151,7 +151,7 @@ var/global/dmm_suite/preloader/_preloader = null
|
||||
var/variables_start = findtext(full_def,"{")
|
||||
if(variables_start)//if there's any variable
|
||||
full_def = copytext(full_def,variables_start+1,length(full_def))//removing the last '}'
|
||||
fields = text2list(full_def,";")
|
||||
fields = readlist(full_def, ";")
|
||||
|
||||
//then fill the members_attributes list with the corresponding variables
|
||||
members_attributes.len++
|
||||
@@ -258,7 +258,7 @@ var/global/dmm_suite/preloader/_preloader = null
|
||||
|
||||
//build a list from variables in text form (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7))
|
||||
//return the filled list
|
||||
/dmm_suite/proc/text2list(text as text,delimiter=",")
|
||||
/dmm_suite/proc/readlist(text as text, delimiter=",")
|
||||
|
||||
var/list/to_return = list()
|
||||
|
||||
@@ -292,7 +292,7 @@ var/global/dmm_suite/preloader/_preloader = null
|
||||
|
||||
//Check for list
|
||||
else if(copytext(trim_right,1,5) == "list")
|
||||
trim_right = text2list(copytext(trim_right,6,length(trim_right)))
|
||||
trim_right = readlist(copytext(trim_right,6,length(trim_right)))
|
||||
|
||||
//Check for file
|
||||
else if(copytext(trim_right,1,2) == "'")
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
/obj/machinery/computer/cargo
|
||||
name = "supply console"
|
||||
desc = "Used to order supplies, approve requests, and control the shuttle."
|
||||
icon_screen = "supply"
|
||||
circuit = /obj/item/weapon/circuitboard/cargo
|
||||
var/requestonly = FALSE
|
||||
var/contraband = FALSE
|
||||
|
||||
/obj/machinery/computer/cargo/request
|
||||
name = "supply request console"
|
||||
desc = "Used to request supplies from cargo."
|
||||
icon_screen = "request"
|
||||
circuit = /obj/item/weapon/circuitboard/cargo/request
|
||||
requestonly = TRUE
|
||||
|
||||
/obj/machinery/computer/cargo/New()
|
||||
..()
|
||||
var/obj/item/weapon/circuitboard/cargo/board = circuit
|
||||
contraband = board.contraband
|
||||
|
||||
/obj/machinery/computer/cargo/emag_act(mob/user)
|
||||
if(!emagged)
|
||||
user << "<span class='notice'>Special supplies unlocked.</span>"
|
||||
emagged = TRUE
|
||||
|
||||
/obj/machinery/computer/cargo/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "cargo", name, 1000, 800, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/cargo/ui_data()
|
||||
var/list/data = list()
|
||||
data["requestonly"] = requestonly
|
||||
data["location"] = SSshuttle.supply.getStatusText()
|
||||
data["points"] = SSshuttle.points
|
||||
data["away"] = SSshuttle.supply.getDockedId() == "supply_away"
|
||||
data["docked"] = SSshuttle.supply.mode == SHUTTLE_IDLE
|
||||
data["loan"] = !!SSshuttle.shuttle_loan
|
||||
data["loan_dispatched"] = SSshuttle.shuttle_loan && SSshuttle.shuttle_loan.dispatched
|
||||
data["message"] = SSshuttle.centcom_message || "Remember to stamp and send back the supply manifests."
|
||||
|
||||
var/list/supplies = list()
|
||||
supplies.len = all_supply_groups.len
|
||||
for(var/group in all_supply_groups)
|
||||
supplies[group] = list(
|
||||
"name" = get_supply_group_name(group),
|
||||
"packs" = list()
|
||||
)
|
||||
for(var/pack in SSshuttle.supply_packs)
|
||||
var/datum/supply_packs/P = SSshuttle.supply_packs[pack]
|
||||
if((P.hidden && !emagged) || (P.contraband && !contraband))
|
||||
continue
|
||||
supplies[P.group]["packs"] += list(list(
|
||||
"name" = P.name,
|
||||
"cost" = P.cost,
|
||||
"id" = pack
|
||||
))
|
||||
data["supplies"] = supplies
|
||||
|
||||
data["cart"] = list()
|
||||
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
|
||||
data["cart"] += list(list(
|
||||
"object" = SO.object.name,
|
||||
"cost" = SO.object.cost,
|
||||
"id" = SO.ordernum
|
||||
))
|
||||
|
||||
data["requests"] = list()
|
||||
for(var/datum/supply_order/SO in SSshuttle.requestlist)
|
||||
data["requests"] += list(list(
|
||||
"object" = SO.object.name,
|
||||
"cost" = SO.object.cost,
|
||||
"orderedby" = SO.orderedby,
|
||||
"comment" = SO.comment,
|
||||
"id" = SO.ordernum
|
||||
))
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/cargo/ui_act(action, params, datum/tgui/ui)
|
||||
if(..())
|
||||
return
|
||||
if(action != "add" && requestonly)
|
||||
return
|
||||
switch(action)
|
||||
if("send")
|
||||
if(SSshuttle.supply.canMove())
|
||||
say("For safety reasons the automated supply shuttle cannot transport live organisms, classified nuclear weaponry or homing beacons.")
|
||||
return
|
||||
if(SSshuttle.supply.getDockedId() == "supply_home")
|
||||
SSshuttle.moveShuttle("supply", "supply_away", TRUE)
|
||||
say("The supply shuttle has departed.")
|
||||
investigate_log("[key_name(usr)] has sent the supply shuttle away. Points: [SSshuttle.points]. Contents: [SSshuttle.sold_atoms].", "cargo")
|
||||
else
|
||||
investigate_log("[key_name(usr)] has called the supply shuttle. Points: [SSshuttle.points].", "cargo") // TODO: more robust logging here
|
||||
say("The supply shuttle has been called and will arrive in [SSshuttle.supply.timeLeft(600)] minutes.")
|
||||
SSshuttle.moveShuttle("supply", "supply_home", TRUE)
|
||||
. = TRUE
|
||||
if("loan")
|
||||
if(!SSshuttle.shuttle_loan)
|
||||
return
|
||||
else if(SSshuttle.supply.mode == SHUTTLE_IDLE)
|
||||
SSshuttle.shuttle_loan.loan_shuttle()
|
||||
say("The supply shuttle has been loaned to Centcom.")
|
||||
. = TRUE
|
||||
if("add")
|
||||
var/id = params["id"]
|
||||
if(!SSshuttle.supply_packs[id])
|
||||
return
|
||||
|
||||
var/name = "*None Provided*"
|
||||
var/rank = "*None Provided*"
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
name = H.get_authentification_name()
|
||||
rank = H.get_assignment()
|
||||
else if(issilicon(usr))
|
||||
name = usr.real_name
|
||||
rank = "Silicon"
|
||||
|
||||
var/reason = ""
|
||||
if(requestonly)
|
||||
reason = input("Reason:", name, "") as text|null
|
||||
if(isnull(reason) || ..())
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
var/datum/supply_order/SO = SSshuttle.generateSupplyOrder(id, name, rank, reason)
|
||||
SO.generateRequisition(T)
|
||||
if(requestonly)
|
||||
SSshuttle.requestlist += SO
|
||||
else
|
||||
SSshuttle.shoppinglist += SO
|
||||
. = TRUE
|
||||
if("remove")
|
||||
var/id = text2num(params["id"])
|
||||
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
|
||||
if(SO.ordernum == id)
|
||||
SSshuttle.shoppinglist -= SO
|
||||
. = TRUE
|
||||
break
|
||||
if("clear")
|
||||
SSshuttle.shoppinglist.Cut()
|
||||
. = TRUE
|
||||
if("approve")
|
||||
var/id = text2num(params["id"])
|
||||
for(var/datum/supply_order/SO in SSshuttle.requestlist)
|
||||
if(SO.ordernum == id)
|
||||
SSshuttle.requestlist -= SO
|
||||
SSshuttle.shoppinglist += SO
|
||||
. = TRUE
|
||||
break
|
||||
if("deny")
|
||||
var/id = text2num(params["id"])
|
||||
for(var/datum/supply_order/SO in SSshuttle.requestlist)
|
||||
if(SO.ordernum == id)
|
||||
SSshuttle.requestlist -= SO
|
||||
. = TRUE
|
||||
break
|
||||
if("denyall")
|
||||
SSshuttle.requestlist.Cut()
|
||||
. = TRUE
|
||||
if(.)
|
||||
post_signal("supply")
|
||||
|
||||
/obj/machinery/computer/cargo/proc/post_signal(command)
|
||||
|
||||
var/datum/radio_frequency/frequency = SSradio.return_frequency(1435)
|
||||
|
||||
if(!frequency)
|
||||
return
|
||||
|
||||
var/datum/signal/status_signal = new
|
||||
status_signal.source = src
|
||||
status_signal.transmission_method = 1
|
||||
status_signal.data["command"] = command
|
||||
|
||||
frequency.post_signal(src, status_signal)
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
|
||||
/datum/supply_order
|
||||
var/ordernum
|
||||
var/datum/supply_packs/object = null
|
||||
var/orderedby = null
|
||||
var/orderedbyRank
|
||||
var/comment = null
|
||||
|
||||
/datum/supply_order/proc/generateRequisition(atom/_loc)
|
||||
if(!object)
|
||||
return
|
||||
|
||||
var/obj/item/weapon/paper/reqform = new /obj/item/weapon/paper(_loc)
|
||||
reqform.name = "requisition form - [object.name]"
|
||||
reqform.info += "<h3>[station_name] Supply Requisition Form</h3><hr>"
|
||||
reqform.info += "INDEX: #[ordernum]<br>"
|
||||
reqform.info += "REQUESTED BY: [orderedby]<br>"
|
||||
reqform.info += "RANK: [orderedbyRank]<br>"
|
||||
reqform.info += "REASON: [comment]<br>"
|
||||
reqform.info += "SUPPLY CRATE TYPE: [object.name]<br>"
|
||||
reqform.info += "ACCESS RESTRICTION: [get_access_desc(object.access)]<br>"
|
||||
reqform.info += "CONTENTS:<br>"
|
||||
reqform.info += object.manifest
|
||||
reqform.info += "<hr>"
|
||||
reqform.info += "STAMP BELOW TO APPROVE THIS REQUISITION:<br>"
|
||||
|
||||
reqform.update_icon() //Fix for appearing blank when printed.
|
||||
|
||||
return reqform
|
||||
|
||||
/datum/supply_order/proc/createObject(atom/_loc, errors=0)
|
||||
if(!object)
|
||||
return
|
||||
|
||||
//create the crate
|
||||
var/atom/Crate = new object.containertype(_loc)
|
||||
Crate.name = "[object.containername] [comment ? "([comment])":"" ]"
|
||||
if(object.access)
|
||||
Crate:req_access = list(text2num(object.access))
|
||||
|
||||
//create the manifest slip
|
||||
var/obj/item/weapon/paper/manifest/slip = new /obj/item/weapon/paper/manifest()
|
||||
slip.erroneous = errors
|
||||
slip.points = object.cost
|
||||
slip.ordernumber = ordernum
|
||||
|
||||
var/stationName = (errors & MANIFEST_ERROR_NAME) ? new_station_name() : station_name()
|
||||
var/packagesAmt = SSshuttle.shoppinglist.len + ((errors & MANIFEST_ERROR_COUNT) ? rand(1,2) : 0)
|
||||
|
||||
slip.info = "<h3>[command_name()] Shipping Manifest</h3><hr><br>"
|
||||
slip.info +="Order #[ordernum]<br>"
|
||||
slip.info +="Destination: [stationName]<br>"
|
||||
slip.info +="[packagesAmt] PACKAGES IN THIS SHIPMENT<br>"
|
||||
slip.info +="CONTENTS:<br><ul>"
|
||||
|
||||
//we now create the actual contents
|
||||
var/list/contains
|
||||
if(istype(object, /datum/supply_packs/misc/randomised))
|
||||
var/datum/supply_packs/misc/randomised/SO = object
|
||||
contains = list()
|
||||
if(object.contains.len)
|
||||
for(var/j=1, j<=SO.num_contained, j++)
|
||||
contains += pick(object.contains)
|
||||
else
|
||||
contains = object.contains
|
||||
|
||||
for(var/typepath in contains)
|
||||
if(!typepath)
|
||||
continue
|
||||
var/atom/A = new typepath(Crate)
|
||||
if(object.amount && A.vars.Find("amount") && A:amount)
|
||||
A:amount = object.amount
|
||||
slip.info += "<li>[A.name]</li>" //add the item to the manifest (even if it was misplaced)
|
||||
|
||||
if(istype(Crate, /obj/structure/closet/critter)) // critter crates do not actually spawn mobs yet and have no contains var, but the manifest still needs to list them
|
||||
var/obj/structure/closet/critter/CritCrate = Crate
|
||||
if(CritCrate.content_mob)
|
||||
var/mob/crittername = CritCrate.content_mob
|
||||
slip.info += "<li>[initial(crittername.name)]</li>"
|
||||
|
||||
if((errors & MANIFEST_ERROR_ITEM))
|
||||
//secure and large crates cannot lose items
|
||||
if(findtext("[object.containertype]", "/secure/") || findtext("[object.containertype]","/largecrate/"))
|
||||
errors &= ~MANIFEST_ERROR_ITEM
|
||||
else
|
||||
var/lostAmt = max(round(Crate.contents.len/10), 1)
|
||||
//lose some of the items
|
||||
while(--lostAmt >= 0)
|
||||
qdel(pick(Crate.contents))
|
||||
|
||||
//manifest finalisation
|
||||
slip.info += "</ul><br>"
|
||||
slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS<hr>" // And now this is actually meaningful.
|
||||
slip.loc = Crate
|
||||
if(istype(Crate, /obj/structure/closet/crate))
|
||||
var/obj/structure/closet/crate/CR = Crate
|
||||
CR.manifest = slip
|
||||
CR.update_icon()
|
||||
if(istype(Crate, /obj/structure/largecrate))
|
||||
var/obj/structure/largecrate/LC = Crate
|
||||
LC.manifest = slip
|
||||
LC.update_icon()
|
||||
|
||||
return Crate
|
||||
|
||||
/datum/subsystem/shuttle/proc/generateSupplyOrder(packId, _orderedby, _orderedbyRank, _comment)
|
||||
if(!packId)
|
||||
return
|
||||
var/datum/supply_packs/P = supply_packs[packId]
|
||||
if(!P)
|
||||
return
|
||||
|
||||
var/datum/supply_order/O = new()
|
||||
O.ordernum = ordernum++
|
||||
O.object = P
|
||||
O.orderedby = _orderedby
|
||||
O.orderedbyRank = _orderedbyRank
|
||||
O.comment = _comment
|
||||
|
||||
return O
|
||||
|
||||
@@ -201,12 +201,12 @@ var/next_external_rsc = 0
|
||||
else
|
||||
winset(src, "infowindow.changelog", "font-style=bold")
|
||||
|
||||
if (ckey in clientmessages)
|
||||
for (var/message in clientmessages[ckey])
|
||||
if(ckey in clientmessages)
|
||||
for(var/message in clientmessages[ckey])
|
||||
src << message
|
||||
clientmessages.Remove(ckey)
|
||||
|
||||
if (config && config.autoconvert_notes)
|
||||
if(config && config.autoconvert_notes)
|
||||
convert_notes_sql(ckey)
|
||||
|
||||
if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them.
|
||||
|
||||
@@ -27,6 +27,7 @@ var/list/preferences_datums = list()
|
||||
|
||||
|
||||
var/UI_style = "Midnight"
|
||||
var/hotkeys = FALSE
|
||||
var/tgui_fancy = TRUE
|
||||
var/tgui_lock = TRUE
|
||||
var/toggles = TOGGLES_DEFAULT
|
||||
@@ -328,6 +329,7 @@ var/list/preferences_datums = list()
|
||||
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
|
||||
dat += "<h2>General Settings</h2>"
|
||||
dat += "<b>UI Style:</b> <a href='?_src_=prefs;preference=ui'>[UI_style]</a><br>"
|
||||
dat += "<b>Keybindings:</b> <a href='?_src_=prefs;preference=hotkeys'>[(hotkeys) ? "Hotkeys" : "Default"]</a><br>"
|
||||
dat += "<b>tgui Style:</b> <a href='?_src_=prefs;preference=tgui_fancy'>[(tgui_fancy) ? "Fancy" : "No Frills"]</a><br>"
|
||||
dat += "<b>tgui Monitors:</b> <a href='?_src_=prefs;preference=tgui_lock'>[(tgui_lock) ? "Primary" : "All"]</a><br>"
|
||||
dat += "<b>Play admin midis:</b> <a href='?_src_=prefs;preference=hear_midis'>[(toggles & SOUND_MIDI) ? "Yes" : "No"]</a><br>"
|
||||
@@ -1021,6 +1023,9 @@ var/list/preferences_datums = list()
|
||||
else
|
||||
UI_style = "Midnight"
|
||||
|
||||
if("hotkeys")
|
||||
hotkeys = !hotkeys
|
||||
|
||||
if("tgui_fancy")
|
||||
tgui_fancy = !tgui_fancy
|
||||
if("tgui_lock")
|
||||
|
||||
@@ -194,6 +194,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["ooccolor"] >> ooccolor
|
||||
S["lastchangelog"] >> lastchangelog
|
||||
S["UI_style"] >> UI_style
|
||||
S["hotkeys"] >> hotkeys
|
||||
S["tgui_fancy"] >> tgui_fancy
|
||||
S["tgui_lock"] >> tgui_lock
|
||||
|
||||
@@ -222,6 +223,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
ooccolor = sanitize_ooccolor(sanitize_hexcolor(ooccolor, 6, 1, initial(ooccolor)))
|
||||
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
|
||||
UI_style = sanitize_inlist(UI_style, list("Midnight", "Plasmafire", "Retro", "Slimecore", "Operative"), initial(UI_style))
|
||||
hotkeys = sanitize_integer(hotkeys, 0, 1, initial(hotkeys))
|
||||
tgui_fancy = sanitize_integer(tgui_fancy, 0, 1, initial(tgui_fancy))
|
||||
tgui_lock = sanitize_integer(tgui_lock, 0, 1, initial(tgui_lock))
|
||||
default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot))
|
||||
@@ -245,6 +247,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["ooccolor"] << ooccolor
|
||||
S["lastchangelog"] << lastchangelog
|
||||
S["UI_style"] << UI_style
|
||||
S["hotkeys"] << hotkeys
|
||||
S["tgui_fancy"] << tgui_fancy
|
||||
S["tgui_lock"] << tgui_lock
|
||||
S["be_special"] << be_special
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
var/obj/item/weapon/paper/P = new(get_turf(src))
|
||||
P.name = "paper- 'Scanner Report'"
|
||||
P.info = "<center><font size='6'><B>Scanner Report</B></font></center><HR><BR>"
|
||||
P.info += list2text(log, "<BR>")
|
||||
P.info += jointext(log, "<BR>")
|
||||
P.info += "<HR><B>Notes:</B><BR>"
|
||||
P.info_links = P.info
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/proc/NewStutter(phrase,stunned)
|
||||
phrase = html_decode(phrase)
|
||||
|
||||
var/list/split_phrase = text2list(phrase," ") //Split it up into words.
|
||||
var/list/split_phrase = splittext(phrase," ") //Split it up into words.
|
||||
|
||||
var/list/unstuttered_words = split_phrase.Copy()
|
||||
var/i = rand(1,3)
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
split_phrase[index] = word
|
||||
|
||||
return sanitize(list2text(split_phrase," "))
|
||||
return sanitize(jointext(split_phrase," "))
|
||||
|
||||
/proc/Stagger(mob/M,d) //Technically not a filter, but it relates to drunkenness.
|
||||
step(M, pick(d,turn(d,90),turn(d,-90)))
|
||||
@@ -45,7 +45,7 @@
|
||||
if(chance >= 100) return original_msg
|
||||
|
||||
var/list
|
||||
words = text2list(original_msg," ")
|
||||
words = splittext(original_msg," ")
|
||||
new_words = list()
|
||||
|
||||
var/new_msg = ""
|
||||
@@ -57,6 +57,6 @@
|
||||
continue
|
||||
new_words += w
|
||||
|
||||
new_msg = list2text(new_words," ")
|
||||
new_msg = jointext(new_words," ")
|
||||
|
||||
return new_msg
|
||||
|
||||
@@ -150,29 +150,25 @@
|
||||
/obj/machinery/computer/holodeck/Topic(href, list/href_list)
|
||||
if(..())
|
||||
return
|
||||
if(Adjacent(usr) || istype(usr, /mob/living/silicon))
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
if(href_list["loadarea"])
|
||||
var/typepath = text2path(href_list["loadarea"])
|
||||
if(ispath(typepath,/area))
|
||||
var/area/target = locate(typepath)
|
||||
if(istype(target))
|
||||
load_program(target)
|
||||
else
|
||||
world.log << "area not ready: [typepath]"
|
||||
else
|
||||
world.log << "bad area argument: [href_list["loadarea"]]"
|
||||
else if("safety" in href_list)
|
||||
var/oe = emagged
|
||||
emagged = !text2num(href_list["safety"])
|
||||
if(oe == emagged) return
|
||||
if(program && !stat)
|
||||
if(!emagged && program.restricted)
|
||||
load_program(offline_program)
|
||||
else
|
||||
nerf(!emagged)
|
||||
src.updateUsrDialog()
|
||||
if(!Adjacent(usr) && !istype(usr, /mob/living/silicon))
|
||||
return
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
if(href_list["loadarea"])
|
||||
var/areapath = text2path(href_list["loadarea"])
|
||||
if(!ispath(areapath, /area/holodeck))
|
||||
return
|
||||
var/area/holodeck/area = locate(areapath)
|
||||
if(!istype(area))
|
||||
return
|
||||
if((area in program_cache) || (emagged && (area in emag_programs)))
|
||||
load_program(area)
|
||||
else if("safety" in href_list)
|
||||
var/safe = text2num(href_list["safety"])
|
||||
if(!program)
|
||||
return
|
||||
nerf(safe)
|
||||
src.updateUsrDialog()
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/nerf(active)
|
||||
for(var/obj/item/I in spawned)
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
if(!src.req_access)
|
||||
src.req_access = list()
|
||||
if(src.req_access_txt)
|
||||
var/list/req_access_str = text2list(req_access_txt,";")
|
||||
var/list/req_access_str = splittext(req_access_txt,";")
|
||||
for(var/x in req_access_str)
|
||||
var/n = text2num(x)
|
||||
if(n)
|
||||
@@ -133,7 +133,7 @@
|
||||
if(!src.req_one_access)
|
||||
src.req_one_access = list()
|
||||
if(src.req_one_access_txt)
|
||||
var/list/req_one_access_str = text2list(req_one_access_txt,";")
|
||||
var/list/req_one_access_str = splittext(req_one_access_txt,";")
|
||||
for(var/x in req_one_access_str)
|
||||
var/n = text2num(x)
|
||||
if(n)
|
||||
|
||||
@@ -15,8 +15,8 @@ Chaplain
|
||||
|
||||
outfit = /datum/outfit/job/chaplain
|
||||
|
||||
access = list(access_morgue, access_chapel_office, access_crematorium)
|
||||
minimal_access = list(access_morgue, access_chapel_office, access_crematorium)
|
||||
access = list(access_morgue, access_chapel_office, access_crematorium, access_theatre)
|
||||
minimal_access = list(access_morgue, access_chapel_office, access_crematorium, access_theatre)
|
||||
|
||||
/datum/outfit/job/chaplain
|
||||
name = "Chaplain"
|
||||
|
||||
@@ -1,284 +0,0 @@
|
||||
/* Usage:
|
||||
JSON.stringify(obj) - Converts lists and values into a JSON string.
|
||||
JSON.parse(json) - Converts a JSON string into lists and values.
|
||||
*/
|
||||
|
||||
/var/datum/jsonHelper/JSON = new // A namespace for procs.
|
||||
|
||||
// ************************************ WRITER ************************************
|
||||
/datum/jsonHelper/proc/stringify(value)
|
||||
return list2text(WriteValue(list(), value))
|
||||
|
||||
/datum/jsonHelper/proc/WriteValue(list/json, value)
|
||||
. = json
|
||||
if(isnum(value))
|
||||
json += value // Consider num2text(value, 20) for maximum accuracy.
|
||||
else if(isnull(value))
|
||||
json += "null"
|
||||
else if(istext(value))
|
||||
WriteString(json, value)
|
||||
else if(istype(value, /list))
|
||||
WriteList(json, value)
|
||||
else
|
||||
throw EXCEPTION("Datums cannot be converted to JSON.")
|
||||
|
||||
/datum/jsonHelper/proc/WriteString(list/json, str)
|
||||
. = json
|
||||
var/quotePos = findtextEx(str, "\"")
|
||||
var/bsPos = findtextEx(str, "\\")
|
||||
if (quotePos == 0 && bsPos == 0)
|
||||
json.Add("\"", str, "\"")
|
||||
else
|
||||
json += "\""
|
||||
var/lastStop = 1
|
||||
while(quotePos != 0 || bsPos != 0)
|
||||
var/escPos
|
||||
if(quotePos < bsPos && quotePos != 0 || bsPos == 0)
|
||||
escPos = quotePos
|
||||
else
|
||||
escPos = bsPos
|
||||
json.Add(copytext(str, lastStop, escPos), "\\")
|
||||
lastStop = escPos
|
||||
if(escPos == quotePos)
|
||||
quotePos = findtextEx(str, "\"", escPos + 1)
|
||||
else if(escPos == bsPos)
|
||||
bsPos = findtextEx(str, "\\", escPos + 1)
|
||||
json.Add(copytext(str, lastStop), "\"")
|
||||
|
||||
/datum/jsonHelper/proc/WriteList(list/json, list/listVal)
|
||||
. = json
|
||||
#define Either 0
|
||||
#define CannotBeArray 1
|
||||
#define CannotBeObject 2
|
||||
#define BadList (CannotBeArray | CannotBeObject)
|
||||
var/listType = Either
|
||||
for(var/key in listVal)
|
||||
if(istext(key))
|
||||
if(!isnull(listVal[key]))
|
||||
listType |= CannotBeArray
|
||||
else
|
||||
if(!isnum(key) && !isnull(listVal[key]))
|
||||
listType = BadList
|
||||
else
|
||||
listType |= CannotBeObject
|
||||
|
||||
if(listType == BadList)
|
||||
throw EXCEPTION("The given list cannot be converted to JSON.")
|
||||
|
||||
if(listType == CannotBeArray)
|
||||
json += "{"
|
||||
var/addComma
|
||||
for(var/key in listVal)
|
||||
if(addComma)
|
||||
json += ","
|
||||
else
|
||||
addComma = TRUE
|
||||
WriteString(json, key)
|
||||
json += ":"
|
||||
WriteValue(json, listVal[key])
|
||||
json += "}"
|
||||
else
|
||||
json += "\["
|
||||
var/addComma
|
||||
for(var/key in listVal)
|
||||
if(addComma)
|
||||
json += ","
|
||||
else
|
||||
addComma = TRUE
|
||||
WriteValue(json, key)
|
||||
json += "]"
|
||||
#undef Either
|
||||
#undef CannotBeFlat
|
||||
#undef CannotBeAssoc
|
||||
#undef BadList
|
||||
|
||||
// ************************************ READER ************************************
|
||||
#define aBackspace 0x08
|
||||
#define aTab 0x09
|
||||
#define aLineBreak 0x0A
|
||||
#define aVertTab 0x0B
|
||||
#define aFormFeed 0x0C
|
||||
#define aCarriageReturn 0x0D
|
||||
#define aSpace 0x20
|
||||
#define aZero 0x30
|
||||
#define aNonBreakSpace 0xA0
|
||||
|
||||
#define Advance if(++readPos > jsonLen) { curAscii = 0; curChar = "" } else { curAscii = text2ascii(json, readPos); curChar = ascii2text(curAscii) } // Deal with it.
|
||||
#define SkipWhitespace while(curAscii in whitespace) Advance
|
||||
#define AdvanceWS Advance; SkipWhitespace
|
||||
|
||||
/datum/jsonHelper/var
|
||||
readPos
|
||||
jsonLen
|
||||
json
|
||||
curAscii
|
||||
curChar
|
||||
static/list/whitespace = list(aTab, aLineBreak, aVertTab, aFormFeed, aCarriageReturn, aSpace, aNonBreakSpace)
|
||||
|
||||
/datum/jsonHelper/proc/parse(json)
|
||||
readPos = 0
|
||||
jsonLen = length(json)
|
||||
src.json = json
|
||||
curAscii = 0
|
||||
curChar = ""
|
||||
AdvanceWS
|
||||
var/value = ParseValue()
|
||||
if(readPos < jsonLen)
|
||||
throw EXCEPTION("Expected: End of JSON")
|
||||
return value
|
||||
|
||||
/datum/jsonHelper/proc/ParseValue()
|
||||
if(curChar == "\"")
|
||||
return ParseString()
|
||||
else if(curChar == "-" || (curAscii >= aZero && curAscii <= aZero + 9))
|
||||
return ParseNumber()
|
||||
else if(curChar == "{")
|
||||
return ParseObject()
|
||||
else if(curChar == "\[")
|
||||
return ParseArray()
|
||||
else if(curChar == "t")
|
||||
if(copytext(json, readPos, readPos+4) == "true")
|
||||
readPos += 3
|
||||
AdvanceWS
|
||||
return TRUE
|
||||
else
|
||||
throw EXCEPTION("Expected: 'true'")
|
||||
else if(curChar == "f")
|
||||
if(copytext(json, readPos, readPos+5) == "false")
|
||||
readPos += 4
|
||||
AdvanceWS
|
||||
return FALSE
|
||||
else
|
||||
throw EXCEPTION("Expected: 'false'")
|
||||
else if(curChar == "n")
|
||||
if(copytext(json, readPos, readPos+4) == "null")
|
||||
readPos += 3
|
||||
AdvanceWS
|
||||
return null
|
||||
else
|
||||
throw EXCEPTION("Expected: 'null'")
|
||||
else if(curChar == "")
|
||||
throw EXCEPTION("Unexpected: End of JSON")
|
||||
else
|
||||
throw EXCEPTION("Unexpected: '[curChar]'")
|
||||
|
||||
|
||||
|
||||
/datum/jsonHelper/proc/ParseString()
|
||||
ASSERT(curChar == "\"")
|
||||
Advance
|
||||
var/list/chars = list()
|
||||
while(readPos <= jsonLen)
|
||||
if(curChar == "\"")
|
||||
AdvanceWS
|
||||
return list2text(chars)
|
||||
else if(curChar == "\\")
|
||||
Advance
|
||||
switch(curChar)
|
||||
if("\"", "\\", "/")
|
||||
chars += ascii2text(curAscii)
|
||||
if("b")
|
||||
chars += ascii2text(aBackspace)
|
||||
if("f")
|
||||
chars += ascii2text(aFormFeed)
|
||||
if("n")
|
||||
chars += "\n"
|
||||
if("r")
|
||||
chars += ascii2text(aCarriageReturn) // Should we ignore these?
|
||||
if("t")
|
||||
chars += "\t"
|
||||
if("u")
|
||||
throw EXCEPTION("JSON \\uXXXX escape sequence not supported")
|
||||
else
|
||||
throw EXCEPTION("Invalid escape sequence")
|
||||
Advance
|
||||
else
|
||||
chars += ascii2text(curAscii)
|
||||
Advance
|
||||
throw EXCEPTION("Unterminated string")
|
||||
|
||||
/datum/jsonHelper/proc/ParseNumber()
|
||||
var/firstPos = readPos
|
||||
if(curChar == "-")
|
||||
Advance
|
||||
if(curAscii >= aZero + 1 && curAscii <= aZero + 9)
|
||||
do
|
||||
Advance
|
||||
while(curAscii >= aZero && curAscii <= aZero + 9)
|
||||
else if(curAscii == aZero)
|
||||
Advance
|
||||
else
|
||||
throw EXCEPTION("Expected: digit")
|
||||
|
||||
if(curChar == ".")
|
||||
Advance
|
||||
var/found = FALSE
|
||||
while(curAscii >= aZero && curAscii <= aZero + 9)
|
||||
found = TRUE
|
||||
Advance
|
||||
if(!found)
|
||||
throw EXCEPTION("Expected: digit")
|
||||
|
||||
if(curChar == "E" || curChar == "e")
|
||||
Advance
|
||||
var/found = FALSE
|
||||
if(curChar == "-")
|
||||
Advance
|
||||
else if(curChar == "+")
|
||||
Advance
|
||||
while(curAscii >= aZero && curAscii <= aZero + 9)
|
||||
found = TRUE
|
||||
Advance
|
||||
if(!found)
|
||||
throw EXCEPTION("Expected: digit")
|
||||
|
||||
SkipWhitespace
|
||||
return text2num(copytext(json, firstPos, readPos))
|
||||
|
||||
/datum/jsonHelper/proc/ParseObject()
|
||||
ASSERT(curChar == "{")
|
||||
var/list/object = list()
|
||||
AdvanceWS
|
||||
while(curChar == "\"")
|
||||
var/key = ParseString()
|
||||
if(curChar != ":")
|
||||
throw EXCEPTION("Expected: ':'")
|
||||
AdvanceWS
|
||||
object[key] = ParseValue()
|
||||
if(curChar == ",")
|
||||
AdvanceWS
|
||||
else
|
||||
break
|
||||
if(curChar != "}")
|
||||
throw EXCEPTION("Expected: string or '}'")
|
||||
AdvanceWS
|
||||
return object
|
||||
|
||||
/datum/jsonHelper/proc/ParseArray()
|
||||
ASSERT(curChar == "\[")
|
||||
var/list/array = list()
|
||||
AdvanceWS
|
||||
while(curChar != "]")
|
||||
array += list(ParseValue()) // Wrapped in a list in case ParseValue() returns a list.
|
||||
if(curChar == ",")
|
||||
AdvanceWS
|
||||
else
|
||||
break
|
||||
if(curChar != "]")
|
||||
throw EXCEPTION("Expected: ']'")
|
||||
AdvanceWS
|
||||
return array
|
||||
|
||||
#undef aBackspace
|
||||
#undef aTab
|
||||
#undef aLineBreak
|
||||
#undef aVertTab
|
||||
#undef aFormFeed
|
||||
#undef aCarriageReturn
|
||||
#undef aSpace
|
||||
#undef aZero
|
||||
#undef aNonBreakSpace
|
||||
|
||||
#undef Advance
|
||||
#undef SkipWhitespace
|
||||
#undef AdvanceWS
|
||||
@@ -167,9 +167,11 @@
|
||||
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
/mob/living/carbon/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
|
||||
/mob/living/carbon/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
|
||||
var/damage = intensity - check_eye_prot()
|
||||
if(..()) // we've been flashed
|
||||
if(visual)
|
||||
return
|
||||
if(weakeyes)
|
||||
Stun(2)
|
||||
switch(damage)
|
||||
@@ -200,7 +202,6 @@
|
||||
else
|
||||
src << "<span class='warning'>Your eyes are really starting to hurt. This can't be good for you!</span>"
|
||||
return 1
|
||||
|
||||
else if(damage == 0) // just enough protection
|
||||
if(prob(20))
|
||||
src << "<span class='notice'>Something bright flashes in the corner of your vision!</span>"
|
||||
@@ -583,31 +584,44 @@ var/const/GALOSHES_DONT_HELP = 4
|
||||
|
||||
add_abilities_to_panel()
|
||||
|
||||
/mob/living/carbon/proc/vomit(var/lost_nutrition = 10, var/blood)
|
||||
/mob/living/carbon/proc/vomit(var/lost_nutrition = 10, var/blood = 0, var/stun = 1, var/distance = 0, var/message = 1)
|
||||
if(src.is_muzzled())
|
||||
src << "<span class='warning'>The muzzle prevents you from vomiting!</span>"
|
||||
if(message)
|
||||
src << "<span class='warning'>The muzzle prevents you from vomiting!</span>"
|
||||
return 0
|
||||
Stun(4)
|
||||
if(stun)
|
||||
Stun(4)
|
||||
if(nutrition < 100 && !blood)
|
||||
visible_message("<span class='warning'>[src] dry heaves!</span>", \
|
||||
"<span class='userdanger'>You try to throw up, but there's nothing your stomach!</span>")
|
||||
Weaken(10)
|
||||
if(message)
|
||||
visible_message("<span class='warning'>[src] dry heaves!</span>", \
|
||||
"<span class='userdanger'>You try to throw up, but there's nothing your stomach!</span>")
|
||||
if(stun)
|
||||
Weaken(10)
|
||||
else
|
||||
visible_message("<span class='danger'>[src] throws up!</span>", \
|
||||
"<span class='userdanger'>You throw up!</span>")
|
||||
if(message)
|
||||
visible_message("<span class='danger'>[src] throws up!</span>", \
|
||||
"<span class='userdanger'>You throw up!</span>")
|
||||
playsound(get_turf(src), 'sound/effects/splat.ogg', 50, 1)
|
||||
var/turf/T = get_turf(src)
|
||||
if(blood)
|
||||
if(T)
|
||||
T.add_blood_floor(src)
|
||||
adjustBruteLoss(3)
|
||||
else
|
||||
if(T)
|
||||
T.add_vomit_floor(src)
|
||||
nutrition -= lost_nutrition
|
||||
adjustToxLoss(-3)
|
||||
for(var/i=0 to distance)
|
||||
if(blood)
|
||||
if(T)
|
||||
T.add_blood_floor(src)
|
||||
if(stun)
|
||||
adjustBruteLoss(3)
|
||||
else
|
||||
if(T)
|
||||
T.add_vomit_floor(src)
|
||||
nutrition -= lost_nutrition
|
||||
if(stun)
|
||||
adjustToxLoss(-3)
|
||||
T = get_step(T, dir)
|
||||
if (is_blocked_turf(T))
|
||||
break
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/fully_replace_character_name(oldname,newname)
|
||||
..()
|
||||
if(dna)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
if(!gibbed)
|
||||
emote("deathgasp") //let the world KNOW WE ARE DEAD
|
||||
|
||||
dna.species.spec_death(gibbed,src)
|
||||
dna.species.spec_death(gibbed, src)
|
||||
|
||||
if(ticker && ticker.mode)
|
||||
sql_report_death(src)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
message = dna.species.handle_speech(message,src)
|
||||
if(viruses.len)
|
||||
for(var/datum/disease/pierrot_throat/D in viruses)
|
||||
var/list/temp_message = text2list(message, " ") //List each word in the message
|
||||
var/list/temp_message = splittext(message, " ") //List each word in the message
|
||||
var/list/pick_list = list()
|
||||
for(var/i = 1, i <= temp_message.len, i++) //Create a second list for excluding words down the line
|
||||
pick_list += i
|
||||
@@ -22,7 +22,7 @@
|
||||
if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue
|
||||
temp_message[H] = "HONK"
|
||||
pick_list -= H //Make sure that you dont HONK the same word twice
|
||||
message = list2text(temp_message, " ")
|
||||
message = jointext(temp_message, " ")
|
||||
message = ..(message)
|
||||
message = dna.mutations_say_mods(message)
|
||||
return message
|
||||
|
||||
@@ -74,14 +74,12 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
|
||||
return randname
|
||||
|
||||
var/regex/lizard_hiss = new("s+", "g")
|
||||
var/regex/lizard_hiSS = new("S+", "g")
|
||||
/datum/species/lizard/handle_speech(message)
|
||||
|
||||
if(copytext(message, 1, 2) != "*")
|
||||
message = regEx_replaceall(message, "(?<!s)s(?!s)", "sss") //(?<!s) Not s before. (?!s) not s after. That way it only triples a single s instead of double ss.
|
||||
message = regEx_replaceall(message, "(?<!s)ss(?!s)", "ssss")
|
||||
message = regEx_replaceall(message, "(?<!S)S(?!S)", "SSS")
|
||||
message = regEx_replaceall(message, "(?<!S)SS(?!S)", "SSSS")
|
||||
|
||||
message = lizard_hiss.Replace(message, "sss")
|
||||
message = lizard_hiSS.Replace(message, "SSS")
|
||||
return message
|
||||
|
||||
//I wag in death
|
||||
@@ -414,7 +412,7 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
specflags = list(NOBREATH,HEATRES,COLDRES,NOBLOOD,RADIMMUNE)
|
||||
|
||||
/datum/species/zombie/handle_speech(message)
|
||||
var/list/message_list = text2list(message, " ")
|
||||
var/list/message_list = splittext(message, " ")
|
||||
var/maxchanges = max(round(message_list.len / 1.5), 2)
|
||||
|
||||
for(var/i = rand(maxchanges / 2, maxchanges), i > 0, i--)
|
||||
@@ -427,7 +425,7 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(prob(20) && message_list.len > 3)
|
||||
message_list.Insert(insertpos, "[pick("BRAINS", "Brains", "Braaaiinnnsss", "BRAAAIIINNSSS")]...")
|
||||
|
||||
return list2text(message_list, " ")
|
||||
return jointext(message_list, " ")
|
||||
|
||||
/datum/species/cosmetic_zombie
|
||||
name = "Human"
|
||||
|
||||
@@ -56,9 +56,9 @@
|
||||
sleeping = 0
|
||||
update_sight()
|
||||
update_vision_overlays()
|
||||
clear_fullscreens()
|
||||
update_damage_hud()
|
||||
update_health_hud()
|
||||
|
||||
update_canmove()
|
||||
|
||||
|
||||
|
||||
@@ -193,8 +193,7 @@ Sorry Giacom. Please don't be mad :(
|
||||
|
||||
/mob/living/ex_act(severity, target)
|
||||
..()
|
||||
if(client && !eye_blind)
|
||||
flick("flash", src.flash)
|
||||
flash_eyes()
|
||||
|
||||
/mob/living/proc/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
@@ -720,9 +719,10 @@ Sorry Giacom. Please don't be mad :(
|
||||
floating = 0
|
||||
|
||||
//called when the mob receives a bright flash
|
||||
/mob/living/proc/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
|
||||
/mob/living/proc/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash)
|
||||
if(check_eye_prot() < intensity && (override_blindness_check || !(disabilities & BLIND)))
|
||||
flick("e_flash", flash)
|
||||
overlay_fullscreen("flash", type)
|
||||
addtimer(src, "clear_fullscreen", 25, FALSE, "flash", 25)
|
||||
return 1
|
||||
|
||||
//this returns the mob's protection against eye damage (number between -1 and 2)
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
anchored = 0 //unbolt floorbolts
|
||||
update_canmove()
|
||||
if(src.eyeobj)
|
||||
src.eyeobj.setLoc(get_turf(src))
|
||||
if(eyeobj)
|
||||
eyeobj.setLoc(get_turf(src))
|
||||
|
||||
shuttle_caller_list -= src
|
||||
SSshuttle.autoEvac()
|
||||
@@ -42,7 +42,7 @@
|
||||
for(var/obj/machinery/ai_status_display/O in world) //change status
|
||||
if(src.key)
|
||||
O.mode = 2
|
||||
if (istype(loc, /obj/item/device/aicard))
|
||||
if(istype(loc, /obj/item/device/aicard))
|
||||
loc.icon_state = "aicard-404"
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -109,7 +109,7 @@ var/const/VOX_DELAY = 600
|
||||
src << "<span class='notice'>Wireless interface disabled, unable to interact with announcement PA.</span>"
|
||||
return
|
||||
|
||||
var/list/words = text2list(trim(message), " ")
|
||||
var/list/words = splittext(trim(message), " ")
|
||||
var/list/incorrect_words = list()
|
||||
|
||||
if(words.len > 30)
|
||||
|
||||
@@ -8,6 +8,4 @@
|
||||
ticker.mode.remove_gangster(mind,1,remove_bosses=1)
|
||||
ticker.mode.remove_thrall(mind,0)
|
||||
ticker.mode.remove_shadowling(mind)
|
||||
ticker.mode.remove_hog_follower(mind, 0)
|
||||
|
||||
winset(src, null, "mainwindow.macro=robot-default")
|
||||
ticker.mode.remove_hog_follower(mind, 0)
|
||||
@@ -5,6 +5,8 @@
|
||||
icon_state = "robot"
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
macro_default = "robot-default"
|
||||
macro_hotkeys = "robot-hotkeys"
|
||||
bubble_icon = "robot"
|
||||
var/sight_mode = 0
|
||||
var/custom_name = ""
|
||||
@@ -676,7 +678,7 @@
|
||||
|
||||
/mob/living/silicon/robot/attack_slime(mob/living/simple_animal/slime/M)
|
||||
if(..()) //successful slime shock
|
||||
flick("noise", flash)
|
||||
flash_eyes()
|
||||
var/stunprob = M.powerlevel * 7 + 10
|
||||
if(prob(stunprob) && M.powerlevel >= 8)
|
||||
adjustBruteLoss(M.powerlevel * rand(6,10))
|
||||
|
||||
@@ -99,11 +99,13 @@
|
||||
var/obj/item/weapon/melee/baton/B = I
|
||||
if(B.bcell)
|
||||
B.bcell.charge = B.bcell.maxcharge
|
||||
if(istype(I, /obj/item/weapon/tank/jetpack))
|
||||
var/obj/item/weapon/tank/jetpack/J = I
|
||||
J.air_contents.assert_gas("co2")
|
||||
J.air_contents.gases["co2"][MOLES] = (6 * ONE_ATMOSPHERE) * J.volume / (R_IDEAL_GAS_EQUATION * T20C)
|
||||
|
||||
R.toner = R.tonermax
|
||||
|
||||
return
|
||||
|
||||
/obj/item/weapon/robot_module/proc/rebuild()//Rebuilds the list so it's possible to add/remove items from the module
|
||||
var/list/temp_list = modules
|
||||
modules = list()
|
||||
|
||||
@@ -136,9 +136,9 @@
|
||||
src.take_organ_damage(20)
|
||||
if(2)
|
||||
src.take_organ_damage(10)
|
||||
flick("noise", src:flash)
|
||||
src << "<span class='userdanger'>*BZZZT*</span>"
|
||||
src << "<span class='danger'>Warning: Electromagnetic pulse detected.</span>"
|
||||
flash_eyes(affect_silicon = 1)
|
||||
..()
|
||||
|
||||
/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = 0)
|
||||
@@ -394,7 +394,7 @@
|
||||
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed at [src]!</span>")
|
||||
if(prob(8))
|
||||
flick("noise", flash)
|
||||
flash_eyes(affect_silicon = 1)
|
||||
add_logs(M, src, "attacked")
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
@@ -467,7 +467,7 @@
|
||||
/mob/living/silicon/grabbedby(mob/living/user)
|
||||
return
|
||||
|
||||
/mob/living/silicon/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
|
||||
/mob/living/silicon/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash/noise)
|
||||
if(affect_silicon)
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
speak_emote = list("states")
|
||||
bubble_icon = "machine"
|
||||
|
||||
faction = list("neutral, silicon")
|
||||
|
||||
var/obj/machinery/bot_core/bot_core = null
|
||||
var/bot_core_type = /obj/machinery/bot_core
|
||||
var/list/users = list() //for dialog updates
|
||||
@@ -252,6 +254,7 @@
|
||||
src << "<span class='notice'>You sense your form change as you are uploaded into [src].</span>"
|
||||
bot_name = name
|
||||
name = paicard.pai.name
|
||||
faction = user.faction
|
||||
add_logs(user, paicard.pai, "uploaded to [src.bot_name],")
|
||||
else
|
||||
user << "<span class='warning'>[W] is inactive.</span>"
|
||||
@@ -857,6 +860,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
paicard.pai << "<span class='notice'>You feel your control fade as [paicard] ejects from [bot_name].</span>"
|
||||
paicard = null
|
||||
name = bot_name
|
||||
faction = initial(faction)
|
||||
|
||||
/mob/living/simple_animal/bot/proc/ejectpairemote(mob/user)
|
||||
if(bot_core.allowed(user) && paicard)
|
||||
@@ -881,3 +885,6 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
..()
|
||||
if(paicard && (!client || stat == DEAD))
|
||||
ejectpai(0)
|
||||
|
||||
/mob/living/simple_animal/bot/sentience_act()
|
||||
faction -= "silicon"
|
||||
@@ -171,7 +171,7 @@ var/global/mulebot_count = 0
|
||||
ui = new(user, src, ui_key, "mulebot", name, 600, 375, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/get_ui_data(mob/user)
|
||||
/mob/living/simple_animal/bot/mulebot/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["on"] = on
|
||||
data["locked"] = locked
|
||||
|
||||
@@ -274,13 +274,13 @@
|
||||
/mob/living/simple_animal/attack_animal(mob/living/simple_animal/M)
|
||||
if(..())
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
attack_threshold_check(damage,M.melee_damage_type)
|
||||
apply_damage(damage, M.melee_damage_type, threshold_check = 1, threshold_message = 1)
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/bullet_act(obj/item/projectile/Proj)
|
||||
if(!Proj)
|
||||
return
|
||||
apply_damage(Proj.damage, Proj.damage_type)
|
||||
apply_damage(Proj.damage, Proj.damage_type, threshold_message = 1)
|
||||
Proj.on_hit(src)
|
||||
return 0
|
||||
|
||||
@@ -330,7 +330,7 @@
|
||||
M.do_attack_animation(src)
|
||||
visible_message("<span class='danger'>[M] [response_harm] [src]!</span>")
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
attack_threshold_check(harm_intent_damage)
|
||||
apply_damage(harm_intent_damage, threshold_check = 1, threshold_message = 1)
|
||||
add_logs(M, src, "attacked")
|
||||
updatehealth()
|
||||
return 1
|
||||
@@ -339,7 +339,7 @@
|
||||
if(..()) //successful monkey bite.
|
||||
if(stat != DEAD)
|
||||
var/damage = rand(1, 3)
|
||||
attack_threshold_check(damage)
|
||||
apply_damage(damage, threshold_check = 1, threshold_message = 1)
|
||||
return 1
|
||||
if (M.a_intent == "help")
|
||||
if (health > 0)
|
||||
@@ -360,7 +360,7 @@
|
||||
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed at [src]!</span>")
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
attack_threshold_check(damage)
|
||||
apply_damage(damage, threshold_check = 1, threshold_message = 1)
|
||||
add_logs(M, src, "attacked")
|
||||
return 1
|
||||
|
||||
@@ -369,7 +369,7 @@
|
||||
var/damage = rand(5, 10)
|
||||
if(stat != DEAD)
|
||||
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
|
||||
attack_threshold_check(damage)
|
||||
apply_damage(damage, threshold_check = 1, threshold_message = 1)
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/attack_slime(mob/living/simple_animal/slime/M)
|
||||
@@ -377,15 +377,16 @@
|
||||
var/damage = rand(15, 25)
|
||||
if(M.is_adult)
|
||||
damage = rand(20, 35)
|
||||
attack_threshold_check(damage)
|
||||
apply_damage(damage, threshold_check = 1, threshold_message = 1)
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/proc/attack_threshold_check(damage, damagetype = BRUTE)
|
||||
if(damage <= force_threshold || !damage_coeff[damagetype])
|
||||
visible_message("<span class='warning'>[src] looks unharmed.</span>")
|
||||
/mob/living/simple_animal/apply_damage(damage = 0, damagetype = BRUTE, threshold_check = 0, threshold_message = 0)
|
||||
if(!damage_coeff[damagetype] || threshold_check && damage <= force_threshold)
|
||||
if(threshold_message)
|
||||
visible_message("<span class='warning'>[src] looks unharmed.</span>")
|
||||
return 0
|
||||
else
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/attackby(obj/item/O, mob/living/user, params) //Marker -Agouri
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
return
|
||||
|
||||
if(buckled)
|
||||
Feedstop(silent=1) //releases ourselves from the mob we fed on.
|
||||
Feedstop(silent = 1) //releases ourselves from the mob we fed on.
|
||||
|
||||
stat = DEAD
|
||||
overlays.len = 0
|
||||
|
||||
@@ -57,4 +57,7 @@
|
||||
|
||||
sync_mind()
|
||||
|
||||
winset(src, null, "mainwindow.macro=default")
|
||||
if(client.prefs.hotkeys)
|
||||
winset(src, null, "mainwindow.macro=[macro_hotkeys] mapwindow.map.focus=true input.background-color=#e0e0e0")
|
||||
else
|
||||
winset(src, null, "mainwindow.macro=[macro_default] input.focus=true input.background-color=#d3b5b5")
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
|
||||
var/stat = 0 //Whether a mob is alive or dead. TODO: Move this to living - Nodrak
|
||||
|
||||
var/obj/screen/flash = null
|
||||
|
||||
var/obj/screen/hands = null
|
||||
var/obj/screen/damageoverlay = null
|
||||
/*A bunch of this stuff really needs to go under their own defines instead of being globally attached to mob.
|
||||
A variable should only be globally attached to turfs/objects/whatever, when it is in fact needed as such.
|
||||
The current method unnecessarily clusters up the variable list, especially for humans (although rearranging won't really clean it up a lot but the difference will be noticable for other mobs).
|
||||
@@ -21,6 +20,9 @@
|
||||
*/
|
||||
var/zone_selected = null
|
||||
|
||||
var/macro_default = "default"
|
||||
var/macro_hotkeys = "hotkeys"
|
||||
|
||||
var/damageoverlaytemp = 0
|
||||
var/computer_id = null
|
||||
var/lastattacker = null
|
||||
|
||||
@@ -21,7 +21,7 @@ Contents:
|
||||
/obj/item/clothing/mask/gas/voice/space_ninja/speechModification(message)
|
||||
if(voice == "Unknown")
|
||||
if(copytext(message, 1, 2) != "*")
|
||||
var/list/temp_message = text2list(message, " ")
|
||||
var/list/temp_message = splittext(message, " ")
|
||||
var/list/pick_list = list()
|
||||
for(var/i = 1, i <= temp_message.len, i++)
|
||||
pick_list += i
|
||||
@@ -30,7 +30,7 @@ Contents:
|
||||
if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue
|
||||
temp_message[H] = ninjaspeak(temp_message[H])
|
||||
pick_list -= H
|
||||
message = list2text(temp_message, " ")
|
||||
message = jointext(temp_message, " ")
|
||||
|
||||
//The Alternate speech mod is now the main one.
|
||||
message = replacetext(message, "l", "r")
|
||||
|
||||
@@ -617,7 +617,7 @@
|
||||
ui = new(user, src, ui_key, "apc", name, 535, 515, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/power/apc/get_ui_data(mob/user)
|
||||
/obj/machinery/power/apc/ui_data(mob/user)
|
||||
var/list/data = list(
|
||||
"locked" = locked,
|
||||
"isOperating" = operating,
|
||||
@@ -625,7 +625,7 @@
|
||||
"powerCellStatus" = cell ? cell.percent() : null,
|
||||
"chargeMode" = chargemode,
|
||||
"chargingStatus" = charging,
|
||||
"totalLoad" = lastused_equip + lastused_light + lastused_environ,
|
||||
"totalLoad" = lastused_total,
|
||||
"coverLocked" = coverlocked,
|
||||
"siliconUser" = user.has_unlimited_silicon_privilege,
|
||||
"malfStatus" = get_malf_status(user),
|
||||
|
||||
@@ -114,11 +114,6 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
else
|
||||
icon_state = "[d1]-[d2]"
|
||||
|
||||
|
||||
// returns the powernet this cable belongs to
|
||||
/obj/structure/cable/proc/get_powernet() //TODO: remove this as it is obsolete
|
||||
return powernet
|
||||
|
||||
//Telekinesis has no effect on a cable
|
||||
/obj/structure/cable/attack_tk(mob/user)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/obj/machinery/computer/monitor
|
||||
name = "power monitoring console"
|
||||
desc = "It monitors power levels across the station."
|
||||
icon_screen = "power"
|
||||
icon_keyboard = "power_key"
|
||||
use_power = 2
|
||||
idle_power_usage = 20
|
||||
active_power_usage = 100
|
||||
circuit = /obj/item/weapon/circuitboard/powermonitor
|
||||
|
||||
var/obj/structure/cable/attached
|
||||
|
||||
var/list/history = list()
|
||||
var/record_size = 60
|
||||
var/record_interval = 50
|
||||
var/next_record = 0
|
||||
|
||||
/obj/machinery/computer/monitor/New()
|
||||
..()
|
||||
search()
|
||||
history["supply"] = list()
|
||||
history["demand"] = list()
|
||||
|
||||
/obj/machinery/computer/monitor/process()
|
||||
if(!attached)
|
||||
use_power = 1
|
||||
search()
|
||||
else
|
||||
use_power = 2
|
||||
record()
|
||||
|
||||
/obj/machinery/computer/monitor/proc/search()
|
||||
var/turf/T = get_turf(src)
|
||||
attached = locate() in T
|
||||
|
||||
/obj/machinery/computer/monitor/proc/record()
|
||||
if(world.time >= next_record)
|
||||
next_record = world.time + record_interval
|
||||
|
||||
var/list/supply = history["supply"]
|
||||
supply += attached.powernet.viewavail
|
||||
if(supply.len > record_size)
|
||||
supply.Cut(1, 2)
|
||||
|
||||
var/list/demand = history["demand"]
|
||||
demand += attached.powernet.viewload
|
||||
if(demand.len > record_size)
|
||||
demand.Cut(1, 2)
|
||||
|
||||
/obj/machinery/computer/monitor/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "power_monitor", name, 1200, 1000, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/monitor/ui_data()
|
||||
var/list/data = list()
|
||||
data["stored"] = record_size
|
||||
data["interval"] = record_interval / 10
|
||||
data["attached"] = attached ? TRUE : FALSE
|
||||
if(attached)
|
||||
data["supply"] = attached.powernet.viewavail
|
||||
data["demand"] = attached.powernet.viewload
|
||||
data["history"] = history
|
||||
|
||||
data["areas"] = list()
|
||||
for(var/obj/machinery/power/terminal/term in attached.powernet.nodes)
|
||||
var/obj/machinery/power/apc/A = term.master
|
||||
if(istype(A))
|
||||
data["areas"] += list(list(
|
||||
"name" = A.area.name,
|
||||
"charge" = A.cell.percent(),
|
||||
"load" = A.lastused_total,
|
||||
"charging" = A.charging,
|
||||
"eqp" = A.equipment,
|
||||
"lgt" = A.lighting,
|
||||
"env" = A.environ
|
||||
))
|
||||
|
||||
return data
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
/obj/machinery/power/proc/surplus()
|
||||
if(powernet)
|
||||
return powernet.avail-powernet.load
|
||||
return powernet.avail - powernet.load
|
||||
else
|
||||
return 0
|
||||
|
||||
@@ -50,10 +50,8 @@
|
||||
// returns true if the area has power on given channel (or doesn't require power).
|
||||
// defaults to power_channel
|
||||
/obj/machinery/proc/powered(var/chan = -1) // defaults to power_channel
|
||||
|
||||
if(!src.loc)
|
||||
if(!loc)
|
||||
return 0
|
||||
|
||||
if(!use_power)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -3,14 +3,15 @@
|
||||
// each contiguous network of cables & nodes
|
||||
/////////////////////////////////////
|
||||
/datum/powernet
|
||||
var/number // unique id
|
||||
var/list/cables = list() // all cables & junctions
|
||||
var/list/nodes = list() // all connected machines
|
||||
|
||||
var/load = 0 // the current load on the powernet, increased by each machine at processing
|
||||
var/newavail = 0 // what available power was gathered last tick, then becomes...
|
||||
var/avail = 0 //...the current available power in the powernet
|
||||
var/viewavail = 0 // the available power as it appears on the power console (gradually updated)
|
||||
var/viewload = 0 // the load as it appears on the power console (gradually updated)
|
||||
var/number = 0 // Unused //TODEL
|
||||
var/netexcess = 0 // excess power on the powernet (typically avail-load)///////
|
||||
|
||||
/datum/powernet/New()
|
||||
@@ -75,7 +76,6 @@
|
||||
//handles the power changes in the powernet
|
||||
//called every ticks by the powernet controller
|
||||
/datum/powernet/proc/reset()
|
||||
|
||||
//see if there's a surplus of power remaining in the powernet and stores unused power in the SMES
|
||||
netexcess = avail - load
|
||||
|
||||
@@ -83,11 +83,11 @@
|
||||
for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network
|
||||
S.restore() // and restore some of the power that was used
|
||||
|
||||
//updates the viewed load (as seen on power computers)
|
||||
viewload = 0.8*viewload + 0.2*load
|
||||
viewload = round(viewload)
|
||||
// update power consoles
|
||||
viewavail = round(0.8 * viewavail + 0.2 * avail)
|
||||
viewload = round(0.8 * viewload + 0.2 * load)
|
||||
|
||||
//reset the powernet
|
||||
// reset the powernet
|
||||
load = 0
|
||||
avail = newavail
|
||||
newavail = 0
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/smes(null)
|
||||
for(var/i in 1 to 5)
|
||||
component_parts += new /obj/item/weapon/stock_parts/cell/high(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/cell/high/empty(null)
|
||||
component_parts += new /obj/item/stack/cable_coil(null, 5)
|
||||
component_parts += new /obj/item/weapon/stock_parts/capacitor(null)
|
||||
RefreshParts()
|
||||
@@ -78,7 +78,7 @@
|
||||
MC += PC.maxcharge
|
||||
C += PC.charge
|
||||
capacity = MC / (15000) * 1e6
|
||||
if(!initial(charge))
|
||||
if(!initial(charge) && !charge)
|
||||
charge = C / 15000 * 1e6
|
||||
|
||||
/obj/machinery/power/smes/attackby(obj/item/I, mob/user, params)
|
||||
@@ -333,7 +333,7 @@
|
||||
ui = new(user, src, ui_key, "smes", name, 340, 440, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/power/smes/get_ui_data()
|
||||
/obj/machinery/power/smes/ui_data()
|
||||
var/list/data = list(
|
||||
"capacityPercent" = round(100*charge/capacity, 0.1),
|
||||
"capacity" = capacity,
|
||||
|
||||
@@ -363,7 +363,7 @@
|
||||
ui = new(user, src, ui_key, "solar_control", name, 500, 400, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/power/solar_control/get_ui_data()
|
||||
/obj/machinery/power/solar_control/ui_data()
|
||||
var/data = list()
|
||||
|
||||
data["generated"] = round(lastgen)
|
||||
|
||||
@@ -155,8 +155,8 @@
|
||||
src << "Missing Input"
|
||||
return
|
||||
|
||||
var/list/startCoords = text2list(startInput, ";")
|
||||
var/list/endCoords = text2list(endInput, ";")
|
||||
var/list/startCoords = splittext(startInput, ";")
|
||||
var/list/endCoords = splittext(endInput, ";")
|
||||
if(!startCoords || !endCoords)
|
||||
src << "Invalid Coords"
|
||||
src << "Start Input: [startInput]"
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
caliber = "357"
|
||||
projectile_type = /obj/item/projectile/bullet
|
||||
|
||||
/obj/item/ammo_casing/a762
|
||||
desc = "A 7.62 bullet casing."
|
||||
icon_state = "762-casing"
|
||||
caliber = "a762"
|
||||
projectile_type = /obj/item/projectile/bullet
|
||||
|
||||
/obj/item/ammo_casing/a50
|
||||
desc = "A .50AE bullet casing."
|
||||
caliber = ".50"
|
||||
@@ -142,6 +148,12 @@
|
||||
icon_state = "mshell"
|
||||
projectile_type = /obj/item/projectile/bullet/meteorshot
|
||||
|
||||
/obj/item/ammo_casing/shotgun/breaching
|
||||
name = "breaching shell"
|
||||
desc = "An economic version of the meteorshot, utilizing similar technologies. Great for busting down doors."
|
||||
icon_state = "mshell"
|
||||
projectile_type = /obj/item/projectile/bullet/meteorshot/weak
|
||||
|
||||
/obj/item/ammo_casing/shotgun/pulseslug
|
||||
name = "pulse slug"
|
||||
desc = "A delicate device which can be loaded into a shotgun. The primer acts as a button which triggers the gain medium and fires a powerful \
|
||||
|
||||
@@ -166,3 +166,14 @@ obj/item/ammo_casing/energy/net
|
||||
/obj/item/ammo_casing/energy/trap
|
||||
projectile_type = /obj/item/projectile/energy/trap
|
||||
select_name = "snare"
|
||||
|
||||
/obj/item/ammo_casing/energy/instakill
|
||||
projectile_type = /obj/item/projectile/beam/instakill
|
||||
e_cost = 0
|
||||
select_name = "DESTROY"
|
||||
|
||||
/obj/item/ammo_casing/energy/instakill/blue
|
||||
projectile_type = /obj/item/projectile/beam/instakill/blue
|
||||
|
||||
/obj/item/ammo_casing/energy/instakill/red
|
||||
projectile_type = /obj/item/projectile/beam/instakill/red
|
||||
|
||||
@@ -304,6 +304,11 @@ obj/item/ammo_box/magazine/tommygunm45
|
||||
icon_state = "m12gt"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/dart/bioterror
|
||||
|
||||
/obj/item/ammo_box/magazine/m12g/breach
|
||||
name = "shotgun magazine (12g breacher slugs)"
|
||||
icon_state = "m12gbc"
|
||||
ammo_type = /obj/item/projectile/bullet/meteorshot/weak
|
||||
|
||||
/obj/item/ammo_box/magazine/toy
|
||||
name = "foam force META magazine"
|
||||
ammo_type = /obj/item/ammo_casing/caseless/foam_dart
|
||||
|
||||
@@ -284,3 +284,27 @@
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/temp, /obj/item/ammo_casing/energy/temp/hot)
|
||||
cell_type = "/obj/item/weapon/stock_parts/cell/high"
|
||||
pin = null
|
||||
|
||||
/obj/item/weapon/gun/energy/laser/instakill
|
||||
name = "instakill rifle"
|
||||
icon_state = "instagib"
|
||||
item_state = "instagib"
|
||||
desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit."
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/instakill)
|
||||
force = 60
|
||||
origin_tech = null
|
||||
|
||||
/obj/item/weapon/gun/energy/laser/instakill/red
|
||||
desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a red design."
|
||||
icon_state = "instagibred"
|
||||
item_state = "instagibred"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/instakill/red)
|
||||
|
||||
/obj/item/weapon/gun/energy/laser/instakill/blue
|
||||
desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a blue design."
|
||||
icon_state = "instagibblue"
|
||||
item_state = "instagibblue"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/instakill/blue)
|
||||
|
||||
/obj/item/weapon/gun/energy/laser/instagib/emp_act() //implying you could stop the instagib
|
||||
return
|
||||
@@ -1,12 +1,12 @@
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw
|
||||
name = "\improper L6 SAW"
|
||||
desc = "A heavily modified 7.62 light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the receiver below the designation."
|
||||
desc = "A heavily modified 5.56x45mm light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the receiver below the designation."
|
||||
icon_state = "l6closed100"
|
||||
item_state = "l6closedmag"
|
||||
w_class = 5
|
||||
slot_flags = 0
|
||||
origin_tech = "combat=5;materials=1;syndicate=2"
|
||||
mag_type = /obj/item/ammo_box/magazine/m762
|
||||
mag_type = /obj/item/ammo_box/magazine/mm556x45
|
||||
heavy_weapon = 1
|
||||
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
|
||||
var/cover_open = 0
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw/update_icon()
|
||||
icon_state = "l6[cover_open ? "open" : "closed"][magazine ? Ceiling(get_ammo(0)/12.5)*25 : "-empty"]"
|
||||
item_state = "l6[cover_open ? "openmag" : "closedmag"]"
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params) //what I tried to do here is just add a check to see if the cover is open or not and add an icon_state change because I can't figure out how c-20rs do it with overlays
|
||||
@@ -64,70 +65,77 @@
|
||||
|
||||
|
||||
/obj/item/projectile/bullet/saw
|
||||
damage = 35
|
||||
damage = 45
|
||||
armour_penetration = 5
|
||||
|
||||
/obj/item/projectile/bullet/saw/bleeding
|
||||
damage = 15
|
||||
damage = 20
|
||||
armour_penetration = 0
|
||||
|
||||
/obj/item/projectile/bullet/saw/bleeding/on_hit(atom/target, blocked = 0, hit_zone)
|
||||
if((blocked != 100) && istype(target, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = target
|
||||
H.drip(25)
|
||||
H.drip(35)
|
||||
|
||||
/obj/item/projectile/bullet/saw/hollow
|
||||
damage = 45
|
||||
armour_penetration = 0
|
||||
damage = 60
|
||||
armour_penetration = -10
|
||||
|
||||
/obj/item/projectile/bullet/saw/ap
|
||||
damage = 30
|
||||
armour_penetration = 35
|
||||
damage = 40
|
||||
armour_penetration = 75
|
||||
|
||||
/obj/item/projectile/bullet/saw/incen
|
||||
damage = 5
|
||||
damage = 7
|
||||
armour_penetration = 0
|
||||
|
||||
obj/item/projectile/bullet/saw/incen/Move()
|
||||
..()
|
||||
var/turf/location = get_turf(src)
|
||||
if(location)
|
||||
PoolOrNew(/obj/effect/hotspot, location)
|
||||
location.hotspot_expose(700, 50, 1)
|
||||
|
||||
/obj/item/projectile/bullet/saw/incen/on_hit(atom/target, blocked = 0)
|
||||
. = ..()
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/M = target
|
||||
M.adjust_fire_stacks(1)
|
||||
M.adjust_fire_stacks(3)
|
||||
M.IgniteMob()
|
||||
|
||||
|
||||
//magazines//
|
||||
|
||||
|
||||
/obj/item/ammo_box/magazine/m762
|
||||
name = "box magazine (7.62mm)"
|
||||
/obj/item/ammo_box/magazine/mm556x45
|
||||
name = "box magazine (5.56x45mm)"
|
||||
icon_state = "a762-50"
|
||||
origin_tech = "combat=2"
|
||||
ammo_type = /obj/item/ammo_casing/a762
|
||||
caliber = "a762"
|
||||
ammo_type = /obj/item/ammo_casing/mm556x45
|
||||
caliber = "mm55645"
|
||||
max_ammo = 50
|
||||
|
||||
/obj/item/ammo_box/magazine/m762/bleeding
|
||||
name = "box magazine (Bleeding 7.62mm)"
|
||||
/obj/item/ammo_box/magazine/mm556x45/bleeding
|
||||
name = "box magazine (Bleeding 5.56x45mm)"
|
||||
origin_tech = "combat=3"
|
||||
ammo_type = /obj/item/ammo_casing/a762/bleeding
|
||||
ammo_type = /obj/item/ammo_casing/mm556x45/bleeding
|
||||
|
||||
/obj/item/ammo_box/magazine/m762/hollow
|
||||
name = "box magazine (Hollow-Point 7.62mm)"
|
||||
/obj/item/ammo_box/magazine/mm556x45/hollow
|
||||
name = "box magazine (Hollow-Point 5.56x45mm)"
|
||||
origin_tech = "combat=3"
|
||||
ammo_type = /obj/item/ammo_casing/a762/hollow
|
||||
ammo_type = /obj/item/ammo_casing/mm556x45/hollow
|
||||
|
||||
/obj/item/ammo_box/magazine/m762/ap
|
||||
name = "box magazine (Armor Penetrating 7.62mm)"
|
||||
/obj/item/ammo_box/magazine/mm556x45/ap
|
||||
name = "box magazine (Armor Penetrating 5.56x45mm)"
|
||||
origin_tech = "combat=4"
|
||||
ammo_type = /obj/item/ammo_casing/a762/ap
|
||||
ammo_type = /obj/item/ammo_casing/mm556x45/ap
|
||||
|
||||
/obj/item/ammo_box/magazine/m762/incen
|
||||
name = "box magazine (Incendiary 7.62mm)"
|
||||
/obj/item/ammo_box/magazine/mm556x45/incen
|
||||
name = "box magazine (Incendiary 5.56x45mm)"
|
||||
origin_tech = "combat=4"
|
||||
ammo_type = /obj/item/ammo_casing/a762/incen
|
||||
ammo_type = /obj/item/ammo_casing/mm556x45/incen
|
||||
|
||||
/obj/item/ammo_box/magazine/m762/update_icon()
|
||||
/obj/item/ammo_box/magazine/mm556x45/update_icon()
|
||||
..()
|
||||
icon_state = "a762-[round(ammo_count(),10)]"
|
||||
|
||||
@@ -135,28 +143,27 @@
|
||||
//casings//
|
||||
|
||||
|
||||
/obj/item/ammo_casing/a762
|
||||
desc = "A 7.62mm bullet casing."
|
||||
/obj/item/ammo_casing/mm556x45
|
||||
desc = "A 556x45mm bullet casing."
|
||||
icon_state = "762-casing"
|
||||
caliber = "a762"
|
||||
caliber = "mm55645"
|
||||
projectile_type = /obj/item/projectile/bullet/saw
|
||||
|
||||
/obj/item/ammo_casing/a762/bleeding
|
||||
desc = "A 7.62mm bullet casing with specialized inner-casing, that when it makes contact with a target, release tiny shrapnel to induce internal bleeding."
|
||||
/obj/item/ammo_casing/mm556x45/bleeding
|
||||
desc = "A 556x45mm bullet casing with specialized inner-casing, that when it makes contact with a target, release tiny shrapnel to induce internal bleeding."
|
||||
icon_state = "762-casing"
|
||||
caliber = "a762"
|
||||
projectile_type = /obj/item/projectile/bullet/saw/bleeding
|
||||
|
||||
/obj/item/ammo_casing/a762/hollow
|
||||
desc = "A 7.62mm bullet casing designed to cause more damage to unarmored targets."
|
||||
/obj/item/ammo_casing/mm556x45/hollow
|
||||
desc = "A 556x45mm bullet casing designed to cause more damage to unarmored targets."
|
||||
projectile_type = /obj/item/projectile/bullet/saw/hollow
|
||||
|
||||
/obj/item/ammo_casing/a762/ap
|
||||
desc = "A 7.62mm bullet casing designed with a hardened-tipped core to help penetrate armored targets."
|
||||
/obj/item/ammo_casing/mm556x45/ap
|
||||
desc = "A 556x45mm bullet casing designed with a hardened-tipped core to help penetrate armored targets."
|
||||
projectile_type = /obj/item/projectile/bullet/saw/ap
|
||||
|
||||
/obj/item/ammo_casing/a762/incen
|
||||
desc = "A 7.62mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames. "
|
||||
/obj/item/ammo_casing/mm556x45/incen
|
||||
desc = "A 556x45mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames. "
|
||||
projectile_type = /obj/item/projectile/bullet/saw/incen
|
||||
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@
|
||||
item_state = "bulldog"
|
||||
w_class = 3
|
||||
origin_tech = "combat=5;materials=4;syndicate=6"
|
||||
mag_type = /obj/item/ammo_box/magazine/m12g
|
||||
mag_type = /obj/item/ammo_box/magazine/m12g/stun
|
||||
fire_sound = 'sound/weapons/Gunshot.ogg'
|
||||
can_suppress = 0
|
||||
burst_size = 1
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
/obj/item/projectile/beam/practice
|
||||
name = "practice laser"
|
||||
damage = 0
|
||||
hitsound = null
|
||||
nodamage = 1
|
||||
|
||||
/obj/item/projectile/beam/scatter
|
||||
@@ -92,3 +91,22 @@
|
||||
/obj/item/projectile/beam/lasertag/bluetag
|
||||
icon_state = "bluelaser"
|
||||
suit_types = list(/obj/item/clothing/suit/redtag)
|
||||
|
||||
/obj/item/projectile/beam/instakill
|
||||
name = "instagib laser"
|
||||
icon_state = "purple_laser"
|
||||
damage = 200
|
||||
damage_type = BURN
|
||||
|
||||
/obj/item/projectile/beam/instakill/blue
|
||||
icon_state = "blue_laser"
|
||||
|
||||
/obj/item/projectile/beam/instakill/red
|
||||
icon_state = "red_laser"
|
||||
|
||||
/obj/item/projectile/beam/instakill/on_hit(atom/target)
|
||||
. = ..()
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/M = target
|
||||
M.visible_message("<span class='danger'>[M] explodes into a shower of gibs!</span>")
|
||||
M.gib()
|
||||
@@ -72,7 +72,7 @@
|
||||
. = ..()
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/M = target
|
||||
M.adjust_fire_stacks(1)
|
||||
M.adjust_fire_stacks(4)
|
||||
M.IgniteMob()
|
||||
|
||||
|
||||
@@ -101,6 +101,11 @@
|
||||
stun = 8
|
||||
hitsound = 'sound/effects/meteorimpact.ogg'
|
||||
|
||||
/obj/item/projectile/bullet/meteorshot/weak
|
||||
damage = 10
|
||||
weaken = 4
|
||||
stun = 4
|
||||
|
||||
/obj/item/projectile/bullet/meteorshot/on_hit(atom/target, blocked = 0)
|
||||
. = ..()
|
||||
if(istype(target, /atom/movable))
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
ui = new(user, src, ui_key, "chem_dispenser", name, 550, 550, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/chem_dispenser/get_ui_data()
|
||||
/obj/machinery/chem_dispenser/ui_data()
|
||||
var/data = list()
|
||||
data["amount"] = amount
|
||||
data["energy"] = energy
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
ui = new(user, src, ui_key, "chem_heater", name, 275, 400, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/chem_heater/get_ui_data()
|
||||
/obj/machinery/chem_heater/ui_data()
|
||||
var/data = list()
|
||||
data["targetTemp"] = target_temperature
|
||||
data["isActive"] = on
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/datum/reagent/blob
|
||||
name = "Unknown"
|
||||
description = "shouldn't exist and you should adminhelp immediately."
|
||||
color = "#FFFFFF"
|
||||
var/shortdesc = null //just damage and on_mob effects, doesn't include special, blob-tile only effects
|
||||
var/blobbernaut_message = "slams" //blobbernaut attack verb
|
||||
var/message = "The blob strikes you" //message sent to any mob hit by the blob
|
||||
@@ -16,7 +17,7 @@
|
||||
/datum/reagent/blob/proc/death_reaction(obj/effect/blob/B, cause) //when a blob dies, do this
|
||||
return
|
||||
|
||||
/datum/reagent/blob/proc/expand_reaction(obj/effect/blob/B, turf/T) //when the blob expands, do this
|
||||
/datum/reagent/blob/proc/expand_reaction(obj/effect/blob/B, obj/effect/blob/newB, turf/T) //when the blob expands, do this
|
||||
return
|
||||
|
||||
//does brute and a little stamina damage
|
||||
@@ -24,7 +25,7 @@
|
||||
name = "Ripping Tendrils"
|
||||
id = "ripping_tendrils"
|
||||
description = "will do medium brute and stamina damage."
|
||||
color = "#890000"
|
||||
color = "#991010"
|
||||
blobbernaut_message = "rips"
|
||||
message_living = ", and you feel your skin ripping and tearing off"
|
||||
|
||||
@@ -60,12 +61,12 @@
|
||||
B.overmind.blob_mobs.Add(BS)
|
||||
return ..()
|
||||
|
||||
/datum/reagent/blob/sporing_pods/expand_reaction(obj/effect/blob/B, turf/T)
|
||||
/datum/reagent/blob/sporing_pods/expand_reaction(obj/effect/blob/B, obj/effect/blob/newB, turf/T)
|
||||
if(prob(10))
|
||||
var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(T)
|
||||
BS.overmind = B.overmind
|
||||
BS.update_icons()
|
||||
B.overmind.blob_mobs.Add(BS)
|
||||
newB.overmind.blob_mobs.Add(BS)
|
||||
|
||||
//does brute damage but can replicate when damaged and has a chance of expanding again
|
||||
/datum/reagent/blob/replicating_foam
|
||||
@@ -82,15 +83,15 @@
|
||||
|
||||
/datum/reagent/blob/replicating_foam/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
||||
if(damage > 0 && original_health - damage > 0)
|
||||
var/obj/effect/blob/newB = B.expand()
|
||||
var/obj/effect/blob/newB = B.expand(null, 0)
|
||||
if(newB)
|
||||
newB.health = original_health - damage
|
||||
newB.check_health(cause)
|
||||
newB.update_icon()
|
||||
return ..()
|
||||
|
||||
/datum/reagent/blob/replicating_foam/expand_reaction(obj/effect/blob/B, turf/T)
|
||||
B.expand() //do it again!
|
||||
/datum/reagent/blob/replicating_foam/expand_reaction(obj/effect/blob/B, obj/effect/blob/newB, turf/T)
|
||||
newB.expand() //do it again!
|
||||
|
||||
//does low burn and a lot of stamina damage, reacts to stamina damage
|
||||
/datum/reagent/blob/energized_fibers
|
||||
@@ -98,7 +99,7 @@
|
||||
id = "energized_fibers"
|
||||
description = "will do low burn and high stamina damage, and react to stamina damage."
|
||||
shortdesc = "will do low burn and high stamina damage."
|
||||
color = "#FFDC73"
|
||||
color = "#EFD65A"
|
||||
blobbernaut_message = "shocks"
|
||||
message_living = ", and you feel a strong tingling sensation"
|
||||
|
||||
@@ -229,6 +230,29 @@
|
||||
if(M)
|
||||
M.adjustStaminaLoss(0.4*reac_volume)
|
||||
|
||||
//does burn damage and EMPs, slightly fragile
|
||||
/datum/reagent/blob/electromagnetic_web
|
||||
name = "Electromagnetic Web"
|
||||
id = "electromagnetic_web"
|
||||
description = "will do low burn damage and EMP targets, but is somewhat fragile."
|
||||
color = "#83ECEC"
|
||||
blobbernaut_message = "lashes"
|
||||
message = "The blob lashes you"
|
||||
message_living = ", and you hear a faint buzzing"
|
||||
|
||||
/datum/reagent/blob/electromagnetic_web/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
|
||||
reac_volume = ..()
|
||||
M.emp_act(2)
|
||||
if(M)
|
||||
M.apply_damage(0.6*reac_volume, BURN)
|
||||
|
||||
/datum/reagent/blob/electromagnetic_web/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
|
||||
return damage * 1.2 //a laser will do 24 damage, which will kill any recently-made normal blob
|
||||
|
||||
/datum/reagent/blob/electromagnetic_web/death_reaction(obj/effect/blob/B, cause)
|
||||
if(!isnull(cause))
|
||||
empulse(B.loc, 2, 3) //less than screen range, so you can stand out of range to avoid it
|
||||
|
||||
//does brute damage, bonus damage for each nearby blob, and spreads damage out
|
||||
/datum/reagent/blob/synchronous_mesh
|
||||
name = "Synchronous Mesh"
|
||||
@@ -261,9 +285,9 @@
|
||||
for(var/obj/effect/blob/C in orange(1, B))
|
||||
if(C.overmind && C.overmind.blob_reagent_datum == B.overmind.blob_reagent_datum && !istype(C, /obj/effect/blob/core)) //only hurt blobs that have the same overmind chemical and aren't cores
|
||||
C.take_damage(damage/damagesplit, CLONE, B, 0)
|
||||
return damage/damagesplit
|
||||
return damage / damagesplit
|
||||
else
|
||||
return damage*1.25
|
||||
return damage * 1.25
|
||||
|
||||
//does low brute damage, oxygen damage, and stamina damage and wets tiles when damaged
|
||||
/datum/reagent/blob/pressurized_slime
|
||||
|
||||
@@ -241,24 +241,24 @@
|
||||
build_path = /obj/item/weapon/circuitboard/rdconsole
|
||||
category = list("Computer Boards")
|
||||
|
||||
/datum/design/ordercomp
|
||||
name = "Computer Design (Supply ordering console)"
|
||||
desc = "Allows for the construction of circuit boards used to build a Supply ordering console."
|
||||
id = "ordercomp"
|
||||
req_tech = list("programming" = 2)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 1000, "sacid" = 20)
|
||||
build_path = /obj/item/weapon/circuitboard/ordercomp
|
||||
category = list("Computer Boards")
|
||||
|
||||
/datum/design/supplycomp
|
||||
name = "Computer Design (Supply shuttle console)"
|
||||
desc = "Allows for the construction of circuit boards used to build a Supply shuttle console."
|
||||
id = "supplycomp"
|
||||
/datum/design/cargo
|
||||
name = "Computer Design (Supply Console)"
|
||||
desc = "Allows for the construction of circuit boards used to build a Supply Console."
|
||||
id = "cargo"
|
||||
req_tech = list("programming" = 3)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 1000, "sacid" = 20)
|
||||
build_path = /obj/item/weapon/circuitboard/supplycomp
|
||||
build_path = /obj/item/weapon/circuitboard/cargo
|
||||
category = list("Computer Boards")
|
||||
|
||||
/datum/design/cargorequest
|
||||
name = "Computer Design (Supply Request Console)"
|
||||
desc = "Allows for the construction of circuit boards used to build a Supply Request Console."
|
||||
id = "cargorequest"
|
||||
req_tech = list("programming" = 2)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 1000, "sacid" = 20)
|
||||
build_path = /obj/item/weapon/circuitboard/cargo/request
|
||||
category = list("Computer Boards")
|
||||
|
||||
/datum/design/mining
|
||||
|
||||
@@ -39,12 +39,12 @@
|
||||
var/list/temp_list
|
||||
if(!id_with_upload.len)
|
||||
temp_list = list()
|
||||
temp_list = text2list(id_with_upload_string, ";")
|
||||
temp_list = splittext(id_with_upload_string, ";")
|
||||
for(var/N in temp_list)
|
||||
id_with_upload += text2num(N)
|
||||
if(!id_with_download.len)
|
||||
temp_list = list()
|
||||
temp_list = text2list(id_with_download_string, ";")
|
||||
temp_list = splittext(id_with_download_string, ";")
|
||||
for(var/N in temp_list)
|
||||
id_with_download += text2num(N)
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ var/datum/events/keycard_events = new()
|
||||
ui = new(user, src, ui_key, "keycard_auth", name, 375, 125, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/keycard_auth/get_ui_data()
|
||||
/obj/machinery/keycard_auth/ui_data()
|
||||
var/list/data = list()
|
||||
data["waiting"] = waiting
|
||||
data["auth_required"] = event_source ? event_source.event : 0
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/obj/machinery/computer/shuttle
|
||||
name = "Shuttle Console"
|
||||
icon_screen = "shuttle"
|
||||
icon_keyboard = "tech_key"
|
||||
req_access = list( )
|
||||
circuit = /obj/item/weapon/circuitboard/shuttle
|
||||
var/shuttleId
|
||||
var/possible_destinations = ""
|
||||
var/admin_controlled
|
||||
var/no_destination_swap = 0
|
||||
|
||||
/obj/machinery/computer/shuttle/New(location, obj/item/weapon/circuitboard/shuttle/C)
|
||||
..()
|
||||
if(istype(C))
|
||||
possible_destinations = C.possible_destinations
|
||||
shuttleId = C.shuttleId
|
||||
|
||||
/obj/machinery/computer/shuttle/attack_hand(mob/user)
|
||||
if(..(user))
|
||||
return
|
||||
src.add_fingerprint(usr)
|
||||
|
||||
var/list/options = params2list(possible_destinations)
|
||||
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
|
||||
var/dat = "Status: [M ? M.getStatusText() : "*Missing*"]<br><br>"
|
||||
if(M)
|
||||
var/destination_found
|
||||
for(var/obj/docking_port/stationary/S in SSshuttle.stationary)
|
||||
if(!options.Find(S.id))
|
||||
continue
|
||||
if(M.canDock(S))
|
||||
continue
|
||||
destination_found = 1
|
||||
dat += "<A href='?src=\ref[src];move=[S.id]'>Send to [S.name]</A><br>"
|
||||
if(!destination_found)
|
||||
dat += "<B>Shuttle Locked</B><br>"
|
||||
if(admin_controlled)
|
||||
dat += "Authorized personnel only<br>"
|
||||
dat += "<A href='?src=\ref[src];request=1]'>Request Authorization</A><br>"
|
||||
dat += "<a href='?src=\ref[user];mach_close=computer'>Close</a>"
|
||||
|
||||
var/datum/browser/popup = new(user, "computer", M ? M.name : "shuttle", 300, 200)
|
||||
popup.set_content("<center>[dat]</center>")
|
||||
popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/computer/shuttle/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
if(!allowed(usr))
|
||||
usr << "<span class='danger'>Access denied.</span>"
|
||||
return
|
||||
|
||||
if(href_list["move"])
|
||||
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
|
||||
if(M.launch_status == ENDGAME_LAUNCHED)
|
||||
usr << "<span class='warning'>You've already escaped. Never going back to that place again!</span>"
|
||||
return
|
||||
if(no_destination_swap)
|
||||
if(M.mode != SHUTTLE_IDLE)
|
||||
usr << "<span class='warning'>Shuttle already in transit.</span>"
|
||||
return
|
||||
switch(SSshuttle.moveShuttle(shuttleId, href_list["move"], 1))
|
||||
if(0)
|
||||
usr << "<span class='notice'>Shuttle received message and will be sent shortly.</span>"
|
||||
if(1)
|
||||
usr << "<span class='warning'>Invalid shuttle requested.</span>"
|
||||
else
|
||||
usr << "<span class='notice'>Unable to comply.</span>"
|
||||
|
||||
/obj/machinery/computer/shuttle/emag_act(mob/user)
|
||||
if(!emagged)
|
||||
src.req_access = list()
|
||||
emagged = 1
|
||||
user << "<span class='notice'>You fried the consoles ID checking system.</span>"
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/obj/machinery/computer/emergency_shuttle
|
||||
name = "emergency shuttle console"
|
||||
desc = "For shuttle control."
|
||||
icon_screen = "shuttle"
|
||||
icon_keyboard = "tech_key"
|
||||
var/auth_need = 3
|
||||
var/list/authorized = list()
|
||||
|
||||
|
||||
/obj/machinery/computer/emergency_shuttle/attackby(obj/item/weapon/card/W, mob/user, params)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
if(!istype(W, /obj/item/weapon/card))
|
||||
return
|
||||
if(SSshuttle.emergency.mode != SHUTTLE_DOCKED)
|
||||
return
|
||||
if(!user)
|
||||
return
|
||||
if(SSshuttle.emergency.timeLeft() < 11)
|
||||
return
|
||||
if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
|
||||
if (istype(W, /obj/item/device/pda))
|
||||
var/obj/item/device/pda/pda = W
|
||||
W = pda.id
|
||||
if (!W:access) //no access
|
||||
user << "The access level of [W:registered_name]\'s card is not high enough. "
|
||||
return
|
||||
|
||||
var/list/cardaccess = W:access
|
||||
if(!istype(cardaccess, /list) || !cardaccess.len) //no access
|
||||
user << "The access level of [W:registered_name]\'s card is not high enough. "
|
||||
return
|
||||
|
||||
if(!(access_heads in W:access)) //doesn't have this access
|
||||
user << "The access level of [W:registered_name]\'s card is not high enough. "
|
||||
return 0
|
||||
|
||||
var/choice = alert(user, text("Would you like to (un)authorize a shortened launch time? [] authorization\s are still needed. Use abort to cancel all authorizations.", src.auth_need - src.authorized.len), "Shuttle Launch", "Authorize", "Repeal", "Abort")
|
||||
if(SSshuttle.emergency.mode != SHUTTLE_DOCKED || user.get_active_hand() != W)
|
||||
return 0
|
||||
|
||||
var/seconds = SSshuttle.emergency.timeLeft()
|
||||
if(seconds <= 10)
|
||||
return 0
|
||||
|
||||
switch(choice)
|
||||
if("Authorize")
|
||||
if(!authorized.Find(W:registered_name))
|
||||
authorized += W:registered_name
|
||||
if(auth_need - authorized.len > 0)
|
||||
message_admins("[key_name_admin(user.client)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) has authorized early shuttle launch ",0,1)
|
||||
log_game("[key_name(user)] has authorized early shuttle launch in ([x],[y],[z])")
|
||||
minor_announce("[auth_need - authorized.len] more authorization(s) needed until shuttle is launched early",null,1)
|
||||
else
|
||||
message_admins("[key_name_admin(user.client)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) has launched the emergency shuttle [seconds] seconds before launch.",0,1)
|
||||
log_game("[key_name(user)] has launched the emergency shuttle in ([x],[y],[z]) [seconds] seconds before launch.")
|
||||
minor_announce("The emergency shuttle will launch in 10 seconds",null,1)
|
||||
SSshuttle.emergency.setTimer(100)
|
||||
|
||||
if("Repeal")
|
||||
if(authorized.Remove(W:registered_name))
|
||||
minor_announce("[auth_need - authorized.len] authorizations needed until shuttle is launched early")
|
||||
|
||||
if("Abort")
|
||||
if(authorized.len)
|
||||
minor_announce("All authorizations to launch the shuttle early have been revoked.")
|
||||
authorized.Cut()
|
||||
|
||||
/obj/machinery/computer/emergency_shuttle/emag_act(mob/user)
|
||||
if(!emagged && SSshuttle.emergency.mode == SHUTTLE_DOCKED)
|
||||
var/time = SSshuttle.emergency.timeLeft()
|
||||
message_admins("[key_name_admin(user.client)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) has emagged the emergency shuttle [time] seconds before launch.",0,1)
|
||||
log_game("[key_name(user)] has emagged the emergency shuttle in ([x],[y],[z]) [time] seconds before launch.")
|
||||
minor_announce("The emergency shuttle will launch in 10 seconds", "SYSTEM ERROR:",null,1)
|
||||
SSshuttle.emergency.setTimer(100)
|
||||
emagged = 1
|
||||
@@ -0,0 +1,24 @@
|
||||
/obj/machinery/computer/shuttle/ferry
|
||||
name = "transport ferry console"
|
||||
circuit = /obj/item/weapon/circuitboard/ferry
|
||||
shuttleId = "ferry"
|
||||
possible_destinations = "ferry_home;ferry_away"
|
||||
|
||||
|
||||
/obj/machinery/computer/shuttle/ferry/request
|
||||
name = "ferry console"
|
||||
circuit = /obj/item/weapon/circuitboard/ferry/request
|
||||
var/cooldown //prevents spamming admins
|
||||
possible_destinations = "ferry_home"
|
||||
admin_controlled = 1
|
||||
|
||||
/obj/machinery/computer/shuttle/ferry/request/Topic(href, href_list)
|
||||
..()
|
||||
if(href_list["request"])
|
||||
if(cooldown)
|
||||
return
|
||||
cooldown = 1
|
||||
usr << "<span class='notice'>Your request has been recieved by Centcom.</span>"
|
||||
admins << "<b>FERRY: <font color='blue'>[key_name_admin(usr)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[usr]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) (<A HREF='?_src_=holder;secrets=moveferry'>Move Ferry</a>)</b> is requesting to move the transport ferry to Centcom.</font>"
|
||||
spawn(600) //One minute cooldown
|
||||
cooldown = 0
|
||||
@@ -294,8 +294,6 @@
|
||||
pixel_x = oldPY
|
||||
pixel_y = (oldPX*(-1))
|
||||
|
||||
|
||||
|
||||
//this is the main proc. It instantly moves our mobile port to stationary port S1
|
||||
//it handles all the generic behaviour, such as sanity checks, closing doors on the shuttle, stunning mobs, etc
|
||||
/obj/docking_port/mobile/proc/dock(obj/docking_port/stationary/S1)
|
||||
@@ -330,8 +328,6 @@
|
||||
rotation += (rotation % 90) //diagonal rotations not allowed, round up
|
||||
rotation = SimplifyDegrees(rotation)
|
||||
|
||||
|
||||
|
||||
//remove area surrounding docking port
|
||||
if(areaInstance.contents.len)
|
||||
var/area/A0 = locate("[area_type]")
|
||||
@@ -363,7 +359,7 @@
|
||||
for(var/atom/movable/AM in T0)
|
||||
AM.onShuttleMove(T1, rotation)
|
||||
|
||||
if (rotation)
|
||||
if(rotation)
|
||||
T1.shuttleRotate(rotation)
|
||||
|
||||
//lighting stuff
|
||||
@@ -529,112 +525,7 @@
|
||||
dst = previous
|
||||
else
|
||||
dst = destination
|
||||
. += " towards [dst ? dst.name : "unknown location"] ([timeLeft(600)]mins)"
|
||||
|
||||
/obj/machinery/computer/shuttle
|
||||
name = "Shuttle Console"
|
||||
icon_screen = "shuttle"
|
||||
icon_keyboard = "tech_key"
|
||||
req_access = list( )
|
||||
circuit = /obj/item/weapon/circuitboard/shuttle
|
||||
var/shuttleId
|
||||
var/possible_destinations = ""
|
||||
var/admin_controlled
|
||||
var/no_destination_swap = 0
|
||||
|
||||
/obj/machinery/computer/shuttle/New(location, obj/item/weapon/circuitboard/shuttle/C)
|
||||
..()
|
||||
if(istype(C))
|
||||
possible_destinations = C.possible_destinations
|
||||
shuttleId = C.shuttleId
|
||||
|
||||
/obj/machinery/computer/shuttle/attack_hand(mob/user)
|
||||
if(..(user))
|
||||
return
|
||||
src.add_fingerprint(usr)
|
||||
|
||||
var/list/options = params2list(possible_destinations)
|
||||
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
|
||||
var/dat = "Status: [M ? M.getStatusText() : "*Missing*"]<br><br>"
|
||||
if(M)
|
||||
var/destination_found
|
||||
for(var/obj/docking_port/stationary/S in SSshuttle.stationary)
|
||||
if(!options.Find(S.id))
|
||||
continue
|
||||
if(M.canDock(S))
|
||||
continue
|
||||
destination_found = 1
|
||||
dat += "<A href='?src=\ref[src];move=[S.id]'>Send to [S.name]</A><br>"
|
||||
if(!destination_found)
|
||||
dat += "<B>Shuttle Locked</B><br>"
|
||||
if(admin_controlled)
|
||||
dat += "Authorized personnel only<br>"
|
||||
dat += "<A href='?src=\ref[src];request=1]'>Request Authorization</A><br>"
|
||||
dat += "<a href='?src=\ref[user];mach_close=computer'>Close</a>"
|
||||
|
||||
var/datum/browser/popup = new(user, "computer", M ? M.name : "shuttle", 300, 200)
|
||||
popup.set_content("<center>[dat]</center>")
|
||||
popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/computer/shuttle/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
if(!allowed(usr))
|
||||
usr << "<span class='danger'>Access denied.</span>"
|
||||
return
|
||||
|
||||
if(href_list["move"])
|
||||
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
|
||||
if(M.launch_status == ENDGAME_LAUNCHED)
|
||||
usr << "<span class='warning'>You've already escaped. Never going back to that place again!</span>"
|
||||
return
|
||||
if(no_destination_swap)
|
||||
if(M.mode != SHUTTLE_IDLE)
|
||||
usr << "<span class='warning'>Shuttle already in transit.</span>"
|
||||
return
|
||||
switch(SSshuttle.moveShuttle(shuttleId, href_list["move"], 1))
|
||||
if(0)
|
||||
usr << "<span class='notice'>Shuttle received message and will be sent shortly.</span>"
|
||||
if(1)
|
||||
usr << "<span class='warning'>Invalid shuttle requested.</span>"
|
||||
else
|
||||
usr << "<span class='notice'>Unable to comply.</span>"
|
||||
|
||||
/obj/machinery/computer/shuttle/emag_act(mob/user)
|
||||
if(!emagged)
|
||||
src.req_access = list()
|
||||
emagged = 1
|
||||
user << "<span class='notice'>You fried the consoles ID checking system.</span>"
|
||||
|
||||
/obj/machinery/computer/shuttle/ferry
|
||||
name = "transport ferry console"
|
||||
circuit = /obj/item/weapon/circuitboard/ferry
|
||||
shuttleId = "ferry"
|
||||
possible_destinations = "ferry_home;ferry_away"
|
||||
|
||||
|
||||
/obj/machinery/computer/shuttle/ferry/request
|
||||
name = "ferry console"
|
||||
circuit = /obj/item/weapon/circuitboard/ferry/request
|
||||
var/cooldown //prevents spamming admins
|
||||
possible_destinations = "ferry_home"
|
||||
admin_controlled = 1
|
||||
|
||||
/obj/machinery/computer/shuttle/ferry/request/Topic(href, href_list)
|
||||
..()
|
||||
if(href_list["request"])
|
||||
if(cooldown)
|
||||
return
|
||||
cooldown = 1
|
||||
usr << "<span class='notice'>Your request has been recieved by Centcom.</span>"
|
||||
admins << "<b>FERRY: <font color='blue'>[key_name_admin(usr)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[usr]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) (<A HREF='?_src_=holder;secrets=moveferry'>Move Ferry</a>)</b> is requesting to move the transport ferry to Centcom.</font>"
|
||||
spawn(600) //One minute cooldown
|
||||
cooldown = 0
|
||||
|
||||
|
||||
. += " towards [dst ? dst.name : "unknown location"] ([timeLeft(600)] minutes)"
|
||||
#undef DOCKING_PORT_HIGHLIGHT
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#define SYNDICATE_CHALLENGE_TIMER 12000 //20 minutes
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate
|
||||
name = "syndicate shuttle terminal"
|
||||
icon_screen = "syndishuttle"
|
||||
icon_keyboard = "syndie_key"
|
||||
req_access = list(access_syndicate)
|
||||
shuttleId = "syndicate"
|
||||
possible_destinations = "syndicate_away;syndicate_z5;syndicate_ne;syndicate_nw;syndicate_n;syndicate_se;syndicate_sw;syndicate_s"
|
||||
var/challenge = FALSE
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate/recall
|
||||
name = "syndicate shuttle recall terminal"
|
||||
possible_destinations = "syndicate_away"
|
||||
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate/Topic(href, href_list)
|
||||
if(href_list["move"])
|
||||
if(challenge && world.time < SYNDICATE_CHALLENGE_TIMER)
|
||||
usr << "<span class='warning'>You've issued a combat challenge to the station! You've got to give them at least [round(((SYNDICATE_CHALLENGE_TIMER - world.time) / 10) / 60)] more minutes to allow them to prepare.</span>"
|
||||
return 0
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate/drop_pod
|
||||
name = "syndicate assault pod control"
|
||||
icon = 'icons/obj/terminals.dmi'
|
||||
icon_state = "dorm_available"
|
||||
req_access = list(access_syndicate)
|
||||
shuttleId = "steel_rain"
|
||||
possible_destinations = null
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate/drop_pod/Topic(href, href_list)
|
||||
if(href_list["move"])
|
||||
if(z != ZLEVEL_CENTCOM)
|
||||
usr << "<span class='warning'>Pods are one way!</span>"
|
||||
return 0
|
||||
..()
|
||||
|
||||
|
||||
#undef SYNDICATE_CHALLENGE_TIMER
|
||||
@@ -0,0 +1,6 @@
|
||||
/obj/machinery/computer/shuttle/white_ship
|
||||
name = "White Ship Console"
|
||||
desc = "Used to control the White Ship."
|
||||
circuit = /obj/item/weapon/circuitboard/white_ship
|
||||
shuttleId = "whiteship"
|
||||
possible_destinations = "whiteship_away;whiteship_home;whiteship_z4"
|
||||
@@ -47,4 +47,4 @@
|
||||
target.equip_to_slot_if_possible(magichead, slot_wear_mask, 1, 1)
|
||||
playsound(get_turf(target), mSounds[randM], 50, 1)
|
||||
|
||||
flick("e_flash", target.flash)
|
||||
target.flash_eyes()
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
*
|
||||
* return list Data to be sent to the UI.
|
||||
**/
|
||||
/datum/proc/get_ui_data(mob/user)
|
||||
/datum/proc/ui_data(mob/user)
|
||||
return list() // Not implemented.
|
||||
|
||||
|
||||
@@ -60,6 +60,13 @@
|
||||
/datum/proc/ui_host()
|
||||
return src // Default src.
|
||||
|
||||
/**
|
||||
* global
|
||||
*
|
||||
* Used to track the current screen.
|
||||
**/
|
||||
/datum/var/ui_screen = "home"
|
||||
|
||||
/**
|
||||
* global
|
||||
*
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
/datum/ui_state/proc/can_use_topic(src_object, mob/user)
|
||||
return UI_CLOSE // Don't allow interaction by default.
|
||||
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
@@ -48,22 +47,21 @@
|
||||
* return UI_state The state of the UI.
|
||||
**/
|
||||
/mob/proc/shared_ui_interaction(src_object)
|
||||
if(!client || stat) // Close UIs if mindless or dead/unconcious.
|
||||
if(!client) // Close UIs if mindless.
|
||||
return UI_CLOSE
|
||||
// Update UIs if incapicitated but concious.
|
||||
else if(incapacitated() || lying)
|
||||
else if(stat) // Disable UIs if unconcious.
|
||||
return UI_DISABLED
|
||||
else if(incapacitated() || lying) // Update UIs if incapicitated but concious.
|
||||
return UI_UPDATE
|
||||
return UI_INTERACTIVE
|
||||
|
||||
/mob/living/silicon/ai/shared_ui_interaction(src_object)
|
||||
if(lacks_power()) // Close UIs if the AI is unpowered.
|
||||
return UI_CLOSE
|
||||
if(lacks_power()) // Disable UIs if the AI is unpowered.
|
||||
return UI_DISABLED
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/shared_ui_interaction(src_object)
|
||||
if(cell.charge <= 0) // Close UIs if the Borg is unpowered.
|
||||
return UI_CLOSE
|
||||
if(lockcharge) // Disable UIs if the Borg is locked.
|
||||
if(cell.charge <= 0 || lockcharge) // Disable UIs if the Borg is unpowered or locked.
|
||||
return UI_DISABLED
|
||||
return ..()
|
||||
|
||||
@@ -92,7 +90,7 @@
|
||||
* return UI_state The state of the UI.
|
||||
**/
|
||||
/mob/living/proc/shared_living_ui_distance(atom/movable/src_object)
|
||||
if(!(src_object in view(4, src))) // If the object is out of view, close it.
|
||||
if(!(src_object in view(src))) // If the object is obscured, close it.
|
||||
return UI_CLOSE
|
||||
|
||||
var/dist = get_dist(src_object, src)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
return
|
||||
|
||||
// Robots can interact with anything they can see.
|
||||
if(get_dist(src, src_object) <= src.client.view)
|
||||
if(get_dist(src, src_object) <= client.view)
|
||||
return UI_INTERACTIVE
|
||||
return UI_DISABLED // Otherwise they can keep the UI open.
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
return
|
||||
|
||||
// The AI can interact with anything it can see nearby, or with cameras.
|
||||
if((get_dist(src, src_object) <= src.client.view) || cameranet.checkTurfVis(get_turf_pixel(src_object)))
|
||||
if((get_dist(src, src_object) <= client.view) || cameranet.checkTurfVis(get_turf_pixel(src_object)))
|
||||
return UI_INTERACTIVE
|
||||
return UI_CLOSE
|
||||
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
/datum/ui_state/z_state/can_use_topic(src_object, mob/user)
|
||||
var/turf/turf_obj = get_turf(src_object)
|
||||
var/turf/turf_usr = get_turf(user)
|
||||
if(!turf_obj || !turf_usr || !(turf_obj.z == turf_usr.z))
|
||||
return UI_CLOSE
|
||||
return UI_INTERACTIVE
|
||||
if(turf_obj && turf_usr && turf_obj.z == turf_usr.z)
|
||||
return UI_INTERACTIVE
|
||||
return UI_CLOSE
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
ui = get_open_ui(user, src_object, ui_key)
|
||||
|
||||
if(!isnull(ui))
|
||||
var/data = src_object.get_ui_data(user) // Get data from the src_object.
|
||||
var/data = src_object.ui_data(user) // Get data from the src_object.
|
||||
if(!force_open) // UI is already open; update it.
|
||||
ui.push_data(data)
|
||||
else // Re-open it anyways.
|
||||
|
||||
+16
-17
@@ -31,7 +31,7 @@
|
||||
var/list/initial_data // The data (and datastructure) used to initialize the UI.
|
||||
var/status = UI_INTERACTIVE // The status/visibility of the UI.
|
||||
var/datum/ui_state/state = null // Topic state used to determine status/interactability.
|
||||
var/datum/tgui/master_ui // The parent UI.
|
||||
var/datum/tgui/master_ui // The parent UI.
|
||||
var/list/datum/tgui/children = list() // Children of this UI.
|
||||
|
||||
/**
|
||||
@@ -80,16 +80,15 @@
|
||||
* Open this UI (and initialize it with data).
|
||||
**/
|
||||
/datum/tgui/proc/open()
|
||||
set waitfor = 0 // Don't wait on sleep()s.
|
||||
if(!user.client)
|
||||
return // Bail if there is no client.
|
||||
|
||||
update_status(push = 0) // Update the window status.
|
||||
if(status == UI_CLOSE)
|
||||
if(status < UI_UPDATE)
|
||||
return // Bail if we're not supposed to open.
|
||||
|
||||
if(!initial_data)
|
||||
set_initial_data(src_object.get_ui_data(user)) // Get the UI data.
|
||||
set_initial_data(src_object.ui_data(user)) // Get the UI data.
|
||||
|
||||
var/window_size = ""
|
||||
if(width && height) // If we have a width and height, use them.
|
||||
@@ -129,6 +128,7 @@
|
||||
children.Cut()
|
||||
state = null
|
||||
master_ui = null
|
||||
qdel(src)
|
||||
|
||||
/**
|
||||
* public
|
||||
@@ -212,6 +212,7 @@
|
||||
var/list/config_data = list(
|
||||
"title" = title,
|
||||
"status" = status,
|
||||
"screen" = src_object.ui_screen,
|
||||
"style" = style,
|
||||
"interface" = interface,
|
||||
"fancy" = user.client.prefs.tgui_fancy,
|
||||
@@ -245,10 +246,10 @@
|
||||
json_data["data"] = data
|
||||
|
||||
// Generate the JSON.
|
||||
var/json = JSON.stringify(json_data)
|
||||
var/json = json_encode(json_data)
|
||||
// Strip #255/improper.
|
||||
json = regex_replaceall(json, "\improper", "")
|
||||
json = regex_replaceall(json, "\proper", "")
|
||||
json = replacetext(json, "\proper", "")
|
||||
json = replacetext(json, "\improper", "")
|
||||
return json
|
||||
|
||||
/**
|
||||
@@ -265,26 +266,24 @@
|
||||
var/action = href_list["action"]
|
||||
var/params = href_list; params -= "action"
|
||||
|
||||
// Handle any special actions.
|
||||
switch(action)
|
||||
if("tgui:initialize")
|
||||
user << output(url_encode(get_json(initial_data)), "[window_id].browser:initialize")
|
||||
initialized = TRUE
|
||||
return
|
||||
if("tgui:view")
|
||||
if(params["screen"])
|
||||
src_object.ui_screen = params["screen"]
|
||||
SStgui.update_uis(src_object)
|
||||
if("tgui:link")
|
||||
user << link(params["url"])
|
||||
return
|
||||
if("tgui:fancy")
|
||||
user.client.prefs.tgui_fancy = TRUE
|
||||
return
|
||||
if("tgui:nofrills")
|
||||
user.client.prefs.tgui_fancy = FALSE
|
||||
return
|
||||
|
||||
update_status(push = 0) // Update the window state.
|
||||
var/update = src_object.ui_act(action, params, src, state) // Call ui_act() on the src_object.
|
||||
if(src_object && update)
|
||||
SStgui.update_uis(src_object) // If we have a src_object and its ui_act() told us to update.
|
||||
else
|
||||
update_status(push = 0) // Update the window state.
|
||||
if(src_object.ui_act(action, params, src, state)) // Call ui_act() on the src_object.
|
||||
SStgui.update_uis(src_object) // Update if the object requested it.
|
||||
|
||||
/**
|
||||
* private
|
||||
|
||||
@@ -40,13 +40,13 @@ var/global/list/uplinks = list()
|
||||
ui.set_style("syndicate")
|
||||
ui.open()
|
||||
|
||||
/obj/item/device/uplink/get_ui_data(mob/user)
|
||||
/obj/item/device/uplink/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["telecrystals"] = telecrystals
|
||||
data["lockable"] = lockable
|
||||
|
||||
var/list/uplink_items = get_uplink_items(gamemode)
|
||||
data["buyable"] = list()
|
||||
data["categories"] = list()
|
||||
for(var/category in uplink_items)
|
||||
var/list/cat = list(
|
||||
"name" = category,
|
||||
@@ -56,11 +56,10 @@ var/global/list/uplinks = list()
|
||||
var/datum/uplink_item/I = uplink_items[category][item]
|
||||
cat["items"] += list(list(
|
||||
"name" = I.name,
|
||||
"category" = I.category,
|
||||
"cost" = I.cost,
|
||||
"desc" = I.desc,
|
||||
))
|
||||
data["buyable"] += list(cat)
|
||||
data["categories"] += list(cat)
|
||||
return data
|
||||
|
||||
/obj/item/device/uplink/ui_act(action, params)
|
||||
@@ -69,16 +68,20 @@ var/global/list/uplinks = list()
|
||||
|
||||
switch(action)
|
||||
if("buy")
|
||||
var/list/uplink_items = get_uplink_items(gamemode)
|
||||
var/category = params["category"]
|
||||
var/item = params["item"]
|
||||
var/datum/uplink_item/I = uplink_items[category][item]
|
||||
if(I)
|
||||
|
||||
var/list/uplink_items = get_uplink_items(gamemode)
|
||||
var/list/buyable_items = list()
|
||||
for(var/category in uplink_items)
|
||||
buyable_items += uplink_items[category]
|
||||
|
||||
if(item in buyable_items)
|
||||
var/datum/uplink_item/I = buyable_items[item]
|
||||
I.buy(usr, src)
|
||||
. = TRUE
|
||||
if("lock")
|
||||
active = FALSE
|
||||
SStgui.close_uis(src)
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/device/uplink/ui_host()
|
||||
@@ -97,6 +100,7 @@ var/global/list/uplinks = list()
|
||||
user << "<span class='notice'>[I] refunded.</span>"
|
||||
qdel(I)
|
||||
return
|
||||
..()
|
||||
|
||||
// A collection of pre-set uplinks, for admin spawns.
|
||||
/obj/item/device/radio/uplink/New()
|
||||
|
||||
@@ -190,9 +190,9 @@ var/list/uplink_items = list() // Global list so we only initialize this once.
|
||||
/datum/uplink_item/dangerous/machinegun
|
||||
name = "L6 Squad Automatic Weapon"
|
||||
desc = "A fully-loaded Aussec Armoury belt-fed machine gun. \
|
||||
This deadly weapon has a massive 50-round magazine of devastating 7.62x51mm ammunition."
|
||||
This deadly weapon has a massive 50-round magazine of devastating 5.56x45mm ammunition."
|
||||
item = /obj/item/weapon/gun/projectile/automatic/l6_saw
|
||||
cost = 23
|
||||
cost = 18
|
||||
surplus = 0
|
||||
include_modes = list(/datum/game_mode/nuclear)
|
||||
|
||||
@@ -394,14 +394,14 @@ var/list/uplink_items = list() // Global list so we only initialize this once.
|
||||
name = "12g Slug Drum"
|
||||
desc = "An additional 8-round slug magazine for use with the Bulldog shotgun. \
|
||||
Now 8 times less likely to shoot your pals."
|
||||
cost = 3
|
||||
item = /obj/item/ammo_box/magazine/m12g
|
||||
|
||||
/datum/uplink_item/ammo/shotgun/slug
|
||||
name = "12 Stun Slug Drum"
|
||||
/datum/uplink_item/ammo/shotgun/stun
|
||||
name = "12g Stun Slug Drum"
|
||||
desc = "An alternative 8-round stun slug magazine for use with the Bulldog shotgun. \
|
||||
Saying that they're completely non-lethal would be lying."
|
||||
item = /obj/item/ammo_box/magazine/m12g/stun
|
||||
cost = 3
|
||||
include_modes = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/ammo/shotgun/dragon
|
||||
@@ -411,6 +411,13 @@ var/list/uplink_items = list() // Global list so we only initialize this once.
|
||||
item = /obj/item/ammo_box/magazine/m12g/dragon
|
||||
include_modes = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/ammo/shotgun/breach
|
||||
name = "12g Breaching Shells"
|
||||
desc = "An economic variant of the CMC meteorshot slugs, not as effective for knocking \
|
||||
down targets, but still great for blasting airlocks off their frames."
|
||||
item = /obj/item/ammo_box/magazine/m12g/breach
|
||||
include_modes = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/ammo/shotgun/bag
|
||||
name = "12g Ammo Duffelbag"
|
||||
desc = "A duffelbag filled with enough 12g ammo to supply an entire team, at a discounted price."
|
||||
@@ -454,34 +461,34 @@ var/list/uplink_items = list() // Global list so we only initialize this once.
|
||||
include_modes = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/ammo/machinegun/basic
|
||||
name = "7.62x51mm Box Magazine"
|
||||
desc = "A 50-round magazine of 7.62x51mm ammunition for use with the L6 SAW. \
|
||||
name = "5.56x45mm Box Magazine"
|
||||
desc = "A 50-round magazine of 5.56x45mm ammunition for use with the L6 SAW. \
|
||||
By the time you need to use this, you'll already be on a pile of corpses."
|
||||
item = /obj/item/ammo_box/magazine/m762
|
||||
item = /obj/item/ammo_box/magazine/mm556x45
|
||||
|
||||
/datum/uplink_item/ammo/machinegun/bleeding
|
||||
name = "7.62x51mm (Bleeding) Box Magazine"
|
||||
desc = "A 50-round magazine of 7.62x51mm ammunition for use in the L6 SAW; equipped with special properties \
|
||||
name = "5.56x45mm (Bleeding) Box Magazine"
|
||||
desc = "A 50-round magazine of 5.56x45mm ammunition for use in the L6 SAW; equipped with special properties \
|
||||
to induce internal bleeding on targets."
|
||||
item = /obj/item/ammo_box/magazine/m762/bleeding
|
||||
item = /obj/item/ammo_box/magazine/mm556x45/bleeding
|
||||
|
||||
/datum/uplink_item/ammo/machinegun/hollow
|
||||
name = "7.62x51mm (Hollow-Point) Box Magazine"
|
||||
desc = "A 50-round magazine of 7.62x51mm ammunition for use in the L6 SAW; equipped with hollow-point tips to help \
|
||||
name = "5.56x45mm (Hollow-Point) Box Magazine"
|
||||
desc = "A 50-round magazine of 5.56x45mm ammunition for use in the L6 SAW; equipped with hollow-point tips to help \
|
||||
with the unarmored masses of crew."
|
||||
item = /obj/item/ammo_box/magazine/m762/hollow
|
||||
item = /obj/item/ammo_box/magazine/mm556x45/hollow
|
||||
|
||||
/datum/uplink_item/ammo/machinegun/ap
|
||||
name = "7.62x51mm (Armor Penetrating) Box Magazine"
|
||||
desc = "A 50-round magazine of 7.62x51mm ammunition for use in the L6 SAW; equipped with special properties \
|
||||
name = "5.56x45mm (Armor Penetrating) Box Magazine"
|
||||
desc = "A 50-round magazine of 5.56x45mm ammunition for use in the L6 SAW; equipped with special properties \
|
||||
to puncture even the most durable armor."
|
||||
item = /obj/item/ammo_box/magazine/m762/ap
|
||||
item = /obj/item/ammo_box/magazine/mm556x45/ap
|
||||
|
||||
/datum/uplink_item/ammo/machinegun/incen
|
||||
name = "7.62x51mm (Incendiary) Box Magazine"
|
||||
desc = "A 50-round magazine of 7.62x51mm ammunition for use in the L6 SAW; tipped with a special flammable \
|
||||
name = "5.56x45mm (Incendiary) Box Magazine"
|
||||
desc = "A 50-round magazine of 5.56x45mm ammunition for use in the L6 SAW; tipped with a special flammable \
|
||||
mixture that'll ignite anyone struck by the bullet. Some men just want to watch the world burn."
|
||||
item = /obj/item/ammo_box/magazine/m762/incen
|
||||
item = /obj/item/ammo_box/magazine/mm556x45/incen
|
||||
|
||||
/datum/uplink_item/ammo/sniper
|
||||
cost = 4
|
||||
|
||||
Reference in New Issue
Block a user