mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-08-29 08:11:11 +01:00
Merge pull request #8879 from VOREStation/master
August 28th 2020 Release
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
# This list auto requests reviews from the specified org members
|
||||
# when a PR that modifies the file in question is opened
|
||||
# This list is alphabetized by User -> Filename KEEP IT THAT WAY
|
||||
# In the event that multiple org members are to be informed of changes
|
||||
# to the same file or dir, add them to the end under Multiple Owners
|
||||
|
||||
# ShadowLarkens
|
||||
/code/__DEFINES/tgui.dm @ShadowLarkens
|
||||
/code/controllers/subsystem/tgui.dm @ShadowLarkens
|
||||
/code/modules/tgui @ShadowLarkens
|
||||
/tgui @ShadowLarkens
|
||||
@@ -103,7 +103,7 @@
|
||||
if(ATM_P)
|
||||
return "phoron"
|
||||
if(ATM_N2O)
|
||||
return "sleeping_agent"
|
||||
return "nitrous_oxide"
|
||||
else
|
||||
return null
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
1: Oxygen: Oxygen ONLY
|
||||
2: Nitrogen: Nitrogen ONLY
|
||||
3: Carbon Dioxide: Carbon Dioxide ONLY
|
||||
4: Sleeping Agent (N2O)
|
||||
4: Nitrous Oxide (Formerly called Sleeping Agent) (N2O)
|
||||
*/
|
||||
var/filter_type = -1
|
||||
var/list/filtered_out = list()
|
||||
@@ -51,7 +51,7 @@
|
||||
if(3) //removing CO2
|
||||
filtered_out = list("carbon_dioxide")
|
||||
if(4)//removing N2O
|
||||
filtered_out = list("sleeping_agent")
|
||||
filtered_out = list("nitrous_oxide")
|
||||
|
||||
air1.volume = ATMOS_DEFAULT_VOLUME_FILTER
|
||||
air2.volume = ATMOS_DEFAULT_VOLUME_FILTER
|
||||
@@ -216,7 +216,7 @@
|
||||
if(3) //removing CO2
|
||||
filtered_out += "carbon_dioxide"
|
||||
if(4)//removing N2O
|
||||
filtered_out += "sleeping_agent"
|
||||
filtered_out += "nitrous_oxide"
|
||||
|
||||
add_fingerprint(usr)
|
||||
update_icon()
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
"filter_n2" = ("nitrogen" in scrubbing_gas),
|
||||
"filter_co2" = ("carbon_dioxide" in scrubbing_gas),
|
||||
"filter_phoron" = ("phoron" in scrubbing_gas),
|
||||
"filter_n2o" = ("sleeping_agent" in scrubbing_gas),
|
||||
"filter_n2o" = ("nitrous_oxide" in scrubbing_gas),
|
||||
"filter_fuel" = ("volatile_fuel" in scrubbing_gas),
|
||||
"sigtype" = "status"
|
||||
)
|
||||
@@ -230,10 +230,10 @@
|
||||
else if(signal.data["toggle_tox_scrub"])
|
||||
toggle += "phoron"
|
||||
|
||||
if(!isnull(signal.data["n2o_scrub"]) && text2num(signal.data["n2o_scrub"]) != ("sleeping_agent" in scrubbing_gas))
|
||||
toggle += "sleeping_agent"
|
||||
if(!isnull(signal.data["n2o_scrub"]) && text2num(signal.data["n2o_scrub"]) != ("nitrous_oxide" in scrubbing_gas))
|
||||
toggle += "nitrous_oxide"
|
||||
else if(signal.data["toggle_n2o_scrub"])
|
||||
toggle += "sleeping_agent"
|
||||
toggle += "nitrous_oxide"
|
||||
|
||||
if(!isnull(signal.data["fuel_scrub"]) && text2num(signal.data["fuel_scrub"]) != ("volatile_fuel" in scrubbing_gas))
|
||||
toggle += "volatile_fuel"
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
air_temporary.volume = volume
|
||||
air_temporary.temperature = T0C
|
||||
|
||||
air_temporary.adjust_gas("sleeping_agent", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
|
||||
air_temporary.adjust_gas("nitrous_oxide", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
|
||||
|
||||
..()
|
||||
icon_state = "n2o"
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/// Module is compatible with Security Cyborg models
|
||||
#define BORG_MODULE_SECURITY (1<<0)
|
||||
/// Module is compatible with Miner Cyborg models
|
||||
#define BORG_MODULE_MINER (1<<1)
|
||||
/// Module is compatible with Janitor Cyborg models
|
||||
#define BORG_MODULE_JANITOR (1<<2)
|
||||
/// Module is compatible with Medical Cyborg models
|
||||
#define BORG_MODULE_MEDICAL (1<<3)
|
||||
/// Module is compatible with Engineering Cyborg models
|
||||
#define BORG_MODULE_ENGINEERING (1<<4)
|
||||
|
||||
/// Module is compatible with Ripley Exosuit models
|
||||
#define EXOSUIT_MODULE_RIPLEY (1<<0)
|
||||
/// Module is compatible with Odyseeus Exosuit models
|
||||
#define EXOSUIT_MODULE_ODYSSEUS (1<<1)
|
||||
/// Module is compatible with Gygax Exosuit models
|
||||
#define EXOSUIT_MODULE_GYGAX (1<<2)
|
||||
/// Module is compatible with Durand Exosuit models
|
||||
#define EXOSUIT_MODULE_DURAND (1<<3)
|
||||
/// Module is compatible with Phazon Exosuit models
|
||||
#define EXOSUIT_MODULE_PHAZON (1<<4)
|
||||
|
||||
/// Module is compatible with "Working" Exosuit models - Ripley
|
||||
#define EXOSUIT_MODULE_WORKING EXOSUIT_MODULE_RIPLEY
|
||||
/// Module is compatible with "Combat" Exosuit models - Gygax, Durand and Phazon
|
||||
#define EXOSUIT_MODULE_COMBAT EXOSUIT_MODULE_GYGAX | EXOSUIT_MODULE_DURAND | EXOSUIT_MODULE_PHAZON
|
||||
/// Module is compatible with "Medical" Exosuit modelsm - Odysseus
|
||||
#define EXOSUIT_MODULE_MEDICAL EXOSUIT_MODULE_ODYSSEUS
|
||||
@@ -463,10 +463,13 @@ var/global/list/##LIST_NAME = list();\
|
||||
|
||||
#define FONT_GIANT(X) "<font size='5'>[X]</font>"
|
||||
|
||||
// Volume Channel Defines
|
||||
|
||||
#define VOLUME_CHANNEL_MASTER "Master"
|
||||
#define VOLUME_CHANNEL_AMBIENCE "Ambience"
|
||||
#define VOLUME_CHANNEL_ALARMS "Alarms"
|
||||
#define VOLUME_CHANNEL_VORE "Vore"
|
||||
#define VOLUME_CHANNEL_DOORS "Doors"
|
||||
|
||||
// Make sure you update this or clients won't be able to adjust the channel
|
||||
GLOBAL_LIST_INIT(all_volume_channels, list(
|
||||
@@ -474,4 +477,5 @@ GLOBAL_LIST_INIT(all_volume_channels, list(
|
||||
VOLUME_CHANNEL_AMBIENCE,
|
||||
VOLUME_CHANNEL_ALARMS,
|
||||
VOLUME_CHANNEL_VORE,
|
||||
VOLUME_CHANNEL_DOORS,
|
||||
))
|
||||
+47
-6
@@ -70,7 +70,9 @@
|
||||
// Restricted, military, or mercenary aligned locations like the armory, the merc ship/base, BSD, etc.
|
||||
#define AMBIENCE_HIGHSEC list(\
|
||||
'sound/ambience/highsec/highsec1.ogg',\
|
||||
'sound/ambience/highsec/highsec2.ogg'\
|
||||
'sound/ambience/highsec/highsec2.ogg',\
|
||||
'sound/ambience/highsec/highsec3.ogg',\
|
||||
'sound/ambience/highsec/highsec4.ogg'\
|
||||
)
|
||||
|
||||
// Ruined structures found on the surface or in the caves.
|
||||
@@ -108,14 +110,19 @@
|
||||
#define AMBIENCE_GENERIC list(\
|
||||
'sound/ambience/generic/generic1.ogg',\
|
||||
'sound/ambience/generic/generic2.ogg',\
|
||||
'sound/ambience/generic/generic3.ogg',\
|
||||
'sound/ambience/generic/generic4.ogg'\
|
||||
'sound/ambience/generic/generic3.ogg'\
|
||||
)
|
||||
// 'sound/ambience/generic/generic4.ogg'\ // VOREStation Edit: Comment out entry 4 as this doesn't fit on Virgo, and we have our own weather system.
|
||||
|
||||
// Sounds of PA announcements, presumably involving shuttles?
|
||||
#define AMBIENCE_ARRIVALS list(\
|
||||
'sound/ambience/arrivals/arrivals1.ogg',\
|
||||
'sound/ambience/arrivals/arrivals2.ogg'\
|
||||
'sound/ambience/arrivals/arrivals2.ogg',\
|
||||
'sound/ambience/arrivals/arrivals3.ogg',\
|
||||
'sound/ambience/arrivals/arrivals4.ogg',\
|
||||
'sound/ambience/arrivals/arrivals5.ogg',\
|
||||
'sound/ambience/arrivals/arrivals6.ogg',\
|
||||
'sound/ambience/arrivals/arrivals7.ogg'\
|
||||
)
|
||||
|
||||
// Sounds suitable for being inside dark, tight corridors in the underbelly of the station.
|
||||
@@ -124,7 +131,11 @@
|
||||
'sound/ambience/maintenance/maintenance2.ogg',\
|
||||
'sound/ambience/maintenance/maintenance3.ogg',\
|
||||
'sound/ambience/maintenance/maintenance4.ogg',\
|
||||
'sound/ambience/maintenance/maintenance5.ogg'\
|
||||
'sound/ambience/maintenance/maintenance5.ogg',\
|
||||
'sound/ambience/maintenance/maintenance6.ogg',\
|
||||
'sound/ambience/maintenance/maintenance7.ogg',\
|
||||
'sound/ambience/maintenance/maintenance8.ogg',\
|
||||
'sound/ambience/maintenance/maintenance9.ogg'\
|
||||
)
|
||||
|
||||
// Life support machinery at work, keeping everyone breathing.
|
||||
@@ -136,7 +147,9 @@
|
||||
|
||||
// Creepy AI/borg stuff.
|
||||
#define AMBIENCE_AI list(\
|
||||
'sound/ambience/ai/ai1.ogg'\
|
||||
'sound/ambience/ai/ai1.ogg',\
|
||||
'sound/ambience/ai/ai2.ogg',\
|
||||
'sound/ambience/ai/ai3.ogg'\
|
||||
)
|
||||
|
||||
// Peaceful sounds when floating in the void.
|
||||
@@ -179,4 +192,32 @@
|
||||
// For the memes.
|
||||
#define AMBIENCE_AESTHETIC list(\
|
||||
'sound/ambience/vaporwave.ogg'\
|
||||
)
|
||||
|
||||
#define AMBIENCE_OUTPOST list(\
|
||||
'sound/ambience/expoutpost/expoutpost1.ogg',\
|
||||
'sound/ambience/expoutpost/expoutpost2.ogg',\
|
||||
'sound/ambience/expoutpost/expoutpost3.ogg',\
|
||||
'sound/ambience/expoutpost/expoutpost4.ogg'\
|
||||
)
|
||||
|
||||
#define AMBIENCE_SUBSTATION list(\
|
||||
'sound/ambience/substation/substation1.ogg',\
|
||||
'sound/ambience/substation/substation2.ogg'\
|
||||
)
|
||||
|
||||
#define AMBIENCE_HANGAR list(\
|
||||
'sound/ambience/hangar/hangar1.ogg',\
|
||||
'sound/ambience/hangar/hangar2.ogg',\
|
||||
'sound/ambience/hangar/hangar3.ogg',\
|
||||
'sound/ambience/hangar/hangar4.ogg',\
|
||||
'sound/ambience/hangar/hangar5.ogg',\
|
||||
'sound/ambience/hangar/hangar6.ogg'\
|
||||
)
|
||||
|
||||
#define AMBIENCE_ATMOS list(\
|
||||
'sound/ambience/engineering/engineering1.ogg',\
|
||||
'sound/ambience/engineering/engineering2.ogg',\
|
||||
'sound/ambience/engineering/engineering3.ogg',\
|
||||
'sound/ambience/atmospherics/atmospherics1.ogg'\
|
||||
)
|
||||
@@ -49,7 +49,9 @@
|
||||
#define LANGUAGE_SIIK "Siik"
|
||||
#define LANGUAGE_SKRELLIAN "Common Skrellian"
|
||||
#define LANGUAGE_TRADEBAND "Tradeband"
|
||||
#define LANGUAGE_GUTTER "Gutter"
|
||||
//VOREStation edit 08/23/20
|
||||
#define LANGUAGE_GUTTER "Gutterband"
|
||||
//VS edit end
|
||||
#define LANGUAGE_SIGN "Sign Language"
|
||||
#define LANGUAGE_SCHECHI "Schechi"
|
||||
#define LANGUAGE_ROOTLOCAL "Local Rootspeak"
|
||||
|
||||
@@ -57,6 +57,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
||||
#define INIT_ORDER_SKYBOX 30
|
||||
#define INIT_ORDER_MAPPING 25
|
||||
#define INIT_ORDER_DECALS 20
|
||||
#define INIT_ORDER_PLANTS 18 // Must initialize before atoms.
|
||||
#define INIT_ORDER_JOB 17
|
||||
#define INIT_ORDER_ALARM 16 // Must initialize before atoms.
|
||||
#define INIT_ORDER_ATOMS 15
|
||||
@@ -87,6 +88,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
||||
#define FIRE_PRIORITY_SHUTTLES 5
|
||||
#define FIRE_PRIORITY_SUPPLY 5
|
||||
#define FIRE_PRIORITY_NIGHTSHIFT 5
|
||||
#define FIRE_PRIORITY_PLANTS 5
|
||||
#define FIRE_PRIORITY_ORBIT 8
|
||||
#define FIRE_PRIORITY_VOTE 9
|
||||
#define FIRE_PRIORITY_AI 10
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#define DIGSITE_TECHNICAL 4
|
||||
#define DIGSITE_TEMPLE 5
|
||||
#define DIGSITE_WAR 6
|
||||
#define DIGSITE_MIDDEN 7
|
||||
|
||||
#define EFFECT_TOUCH 0
|
||||
#define EFFECT_AURA 1
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
clear_fullscreen(category, FALSE)
|
||||
screen = null
|
||||
else if(!severity || severity == screen.severity)
|
||||
return null
|
||||
return screen
|
||||
|
||||
if(!screen)
|
||||
screen = new type()
|
||||
|
||||
@@ -633,3 +633,43 @@
|
||||
/obj/screen/setup_preview/bg/Click(params)
|
||||
pref?.bgstate = next_in_list(pref.bgstate, pref.bgstate_options)
|
||||
pref?.update_preview_icon()
|
||||
|
||||
/obj/screen/splash
|
||||
screen_loc = "1,1"
|
||||
layer = LAYER_HUD_ABOVE
|
||||
plane = PLANE_PLAYER_HUD_ABOVE
|
||||
var/client/holder
|
||||
|
||||
/obj/screen/splash/New(client/C, visible)
|
||||
. = ..()
|
||||
|
||||
holder = C
|
||||
|
||||
if(!visible)
|
||||
alpha = 0
|
||||
|
||||
if(!lobby_image)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
icon = lobby_image.icon
|
||||
icon_state = lobby_image.icon_state
|
||||
|
||||
holder.screen += src
|
||||
|
||||
/obj/screen/splash/proc/Fade(out, qdel_after = TRUE)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
if(out)
|
||||
animate(src, alpha = 0, time = 30)
|
||||
else
|
||||
alpha = 0
|
||||
animate(src, alpha = 255, time = 30)
|
||||
if(qdel_after)
|
||||
QDEL_IN(src, 30)
|
||||
|
||||
/obj/screen/splash/Destroy()
|
||||
if(holder)
|
||||
holder.screen -= src
|
||||
holder = null
|
||||
return ..()
|
||||
|
||||
+1125
-1120
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,6 @@
|
||||
//
|
||||
|
||||
/datum/configuration
|
||||
var/static/list/engine_map // Comma separated list of engines to choose from. Blank means fully random.
|
||||
var/static/time_off = FALSE
|
||||
var/static/pto_job_change = FALSE
|
||||
var/static/limit_interns = -1 //Unlimited by default
|
||||
@@ -42,8 +41,6 @@
|
||||
config.chat_webhook_url = value
|
||||
if ("chat_webhook_key")
|
||||
config.chat_webhook_key = value
|
||||
if ("engine_map")
|
||||
config.engine_map = splittext(value, ",")
|
||||
if ("fax_export_dir")
|
||||
config.fax_export_dir = value
|
||||
if ("items_survive_digestion")
|
||||
|
||||
@@ -6,6 +6,12 @@ SUBSYSTEM_DEF(mapping)
|
||||
|
||||
var/list/map_templates = list()
|
||||
var/dmm_suite/maploader = null
|
||||
var/obj/effect/landmark/engine_loader/engine_loader
|
||||
var/list/shelter_templates = list()
|
||||
|
||||
/datum/controller/subsystem/mapping/Recover()
|
||||
flags |= SS_NO_INIT // Make extra sure we don't initialize twice.
|
||||
shelter_templates = SSmapping.shelter_templates
|
||||
|
||||
/datum/controller/subsystem/mapping/Initialize(timeofday)
|
||||
if(subsystem_initialized)
|
||||
@@ -17,7 +23,15 @@ SUBSYSTEM_DEF(mapping)
|
||||
if(config.generate_map)
|
||||
// Map-gen is still very specific to the map, however putting it here should ensure it loads in the correct order.
|
||||
using_map.perform_map_generation()
|
||||
|
||||
|
||||
loadEngine()
|
||||
preloadShelterTemplates() // VOREStation EDIT: Re-enable Shelter Capsules
|
||||
// Mining generation probably should be here too
|
||||
// TODO - Other stuff related to maps and areas could be moved here too. Look at /tg
|
||||
// Lateload Code related to Expedition areas.
|
||||
if(using_map) // VOREStation Edit: Re-enable this.
|
||||
loadLateMaps()
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/load_map_templates()
|
||||
for(var/T in subtypesof(/datum/map_template))
|
||||
@@ -27,3 +41,84 @@ SUBSYSTEM_DEF(mapping)
|
||||
template = new T()
|
||||
map_templates[template.name] = template
|
||||
return TRUE
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/loadEngine()
|
||||
if(!engine_loader)
|
||||
return // Seems this map doesn't need an engine loaded.
|
||||
|
||||
var/turf/T = get_turf(engine_loader)
|
||||
if(!isturf(T))
|
||||
to_world_log("[log_info_line(engine_loader)] not on a turf! Cannot place engine template.")
|
||||
return
|
||||
|
||||
// Choose an engine type
|
||||
var/datum/map_template/engine/chosen_type = null
|
||||
if (LAZYLEN(config.engine_map))
|
||||
var/chosen_name = pick(config.engine_map)
|
||||
chosen_type = map_templates[chosen_name]
|
||||
if(!istype(chosen_type))
|
||||
error("Configured engine map [chosen_name] is not a valid engine map name!")
|
||||
if(!istype(chosen_type))
|
||||
var/list/engine_types = list()
|
||||
for(var/map in map_templates)
|
||||
var/datum/map_template/engine/MT = map_templates[map]
|
||||
if(istype(MT))
|
||||
engine_types += MT
|
||||
chosen_type = pick(engine_types)
|
||||
to_world_log("Chose Engine Map: [chosen_type.name]")
|
||||
admin_notice("<span class='danger'>Chose Engine Map: [chosen_type.name]</span>", R_DEBUG)
|
||||
|
||||
// Annihilate movable atoms
|
||||
engine_loader.annihilate_bounds()
|
||||
//CHECK_TICK //Don't let anything else happen for now
|
||||
// Actually load it
|
||||
chosen_type.load(T)
|
||||
|
||||
// VOREStation Edit Start: Enable This
|
||||
/datum/controller/subsystem/mapping/proc/loadLateMaps()
|
||||
var/list/deffo_load = using_map.lateload_z_levels
|
||||
var/list/maybe_load = using_map.lateload_single_pick
|
||||
|
||||
for(var/list/maplist in deffo_load)
|
||||
if(!islist(maplist))
|
||||
error("Lateload Z level [maplist] is not a list! Must be in a list!")
|
||||
continue
|
||||
for(var/mapname in maplist)
|
||||
var/datum/map_template/MT = map_templates[mapname]
|
||||
if(!istype(MT))
|
||||
error("Lateload Z level \"[mapname]\" is not a valid map!")
|
||||
continue
|
||||
MT.load_new_z(centered = FALSE)
|
||||
CHECK_TICK
|
||||
|
||||
if(LAZYLEN(maybe_load))
|
||||
var/picklist = pick(maybe_load)
|
||||
|
||||
if(!picklist) //No lateload maps at all
|
||||
return
|
||||
|
||||
if(!islist(picklist)) //So you can have a 'chain' of z-levels that make up one away mission
|
||||
error("Randompick Z level [picklist] is not a list! Must be in a list!")
|
||||
return
|
||||
|
||||
for(var/map in picklist)
|
||||
var/datum/map_template/MT = map_templates[map]
|
||||
if(!istype(MT))
|
||||
error("Randompick Z level \"[map]\" is not a valid map!")
|
||||
else
|
||||
MT.load_new_z(centered = FALSE)
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/preloadShelterTemplates()
|
||||
for(var/item in subtypesof(/datum/map_template/shelter))
|
||||
var/datum/map_template/shelter/shelter_type = item
|
||||
if(!(initial(shelter_type.mappath)))
|
||||
continue
|
||||
var/datum/map_template/shelter/S = new shelter_type()
|
||||
|
||||
shelter_templates[S.shelter_id] = S
|
||||
// VOREStation Edit End: Re-enable this
|
||||
|
||||
/datum/controller/subsystem/mapping/stat_entry(msg)
|
||||
if (!Debug2)
|
||||
return // Only show up in stat panel if debugging is enabled.
|
||||
. = ..()
|
||||
@@ -1,124 +0,0 @@
|
||||
//
|
||||
// Mapping subsystem handles initialization of random map elements at server start
|
||||
// On VOREStation that means loading our random roundstart engine!
|
||||
//
|
||||
SUBSYSTEM_DEF(mapping)
|
||||
name = "Mapping"
|
||||
init_order = INIT_ORDER_MAPPING
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
var/list/map_templates = list()
|
||||
var/dmm_suite/maploader = null
|
||||
var/obj/effect/landmark/engine_loader/engine_loader
|
||||
var/list/shelter_templates = list()
|
||||
|
||||
/datum/controller/subsystem/mapping/Recover()
|
||||
flags |= SS_NO_INIT // Make extra sure we don't initialize twice.
|
||||
shelter_templates = SSmapping.shelter_templates
|
||||
|
||||
/datum/controller/subsystem/mapping/Initialize(timeofday)
|
||||
if(subsystem_initialized)
|
||||
return
|
||||
world.max_z_changed() // This is to set up the player z-level list, maxz hasn't actually changed (probably)
|
||||
maploader = new()
|
||||
load_map_templates()
|
||||
|
||||
if(config.generate_map)
|
||||
// Map-gen is still very specific to the map, however putting it here should ensure it loads in the correct order.
|
||||
using_map.perform_map_generation()
|
||||
|
||||
loadEngine()
|
||||
preloadShelterTemplates()
|
||||
// Mining generation probably should be here too
|
||||
// TODO - Other stuff related to maps and areas could be moved here too. Look at /tg
|
||||
if(using_map)
|
||||
loadLateMaps()
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/load_map_templates()
|
||||
for(var/T in subtypesof(/datum/map_template))
|
||||
var/datum/map_template/template = T
|
||||
if(!(initial(template.mappath))) // If it's missing the actual path its probably a base type or being used for inheritence.
|
||||
continue
|
||||
template = new T()
|
||||
map_templates[template.name] = template
|
||||
return TRUE
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/loadEngine()
|
||||
if(!engine_loader)
|
||||
return // Seems this map doesn't need an engine loaded.
|
||||
|
||||
var/turf/T = get_turf(engine_loader)
|
||||
if(!isturf(T))
|
||||
to_world_log("[log_info_line(engine_loader)] not on a turf! Cannot place engine template.")
|
||||
return
|
||||
|
||||
// Choose an engine type
|
||||
var/datum/map_template/engine/chosen_type = null
|
||||
if (LAZYLEN(config.engine_map))
|
||||
var/chosen_name = pick(config.engine_map)
|
||||
chosen_type = map_templates[chosen_name]
|
||||
if(!istype(chosen_type))
|
||||
error("Configured engine map [chosen_name] is not a valid engine map name!")
|
||||
if(!istype(chosen_type))
|
||||
var/list/engine_types = list()
|
||||
for(var/map in map_templates)
|
||||
var/datum/map_template/engine/MT = map_templates[map]
|
||||
if(istype(MT))
|
||||
engine_types += MT
|
||||
chosen_type = pick(engine_types)
|
||||
to_world_log("Chose Engine Map: [chosen_type.name]")
|
||||
admin_notice("<span class='danger'>Chose Engine Map: [chosen_type.name]</span>", R_DEBUG)
|
||||
|
||||
// Annihilate movable atoms
|
||||
engine_loader.annihilate_bounds()
|
||||
//CHECK_TICK //Don't let anything else happen for now
|
||||
// Actually load it
|
||||
chosen_type.load(T)
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/loadLateMaps()
|
||||
var/list/deffo_load = using_map.lateload_z_levels
|
||||
var/list/maybe_load = using_map.lateload_single_pick
|
||||
|
||||
for(var/list/maplist in deffo_load)
|
||||
if(!islist(maplist))
|
||||
error("Lateload Z level [maplist] is not a list! Must be in a list!")
|
||||
continue
|
||||
for(var/mapname in maplist)
|
||||
var/datum/map_template/MT = map_templates[mapname]
|
||||
if(!istype(MT))
|
||||
error("Lateload Z level \"[mapname]\" is not a valid map!")
|
||||
continue
|
||||
MT.load_new_z(centered = FALSE)
|
||||
CHECK_TICK
|
||||
|
||||
if(LAZYLEN(maybe_load))
|
||||
var/picklist = pick(maybe_load)
|
||||
|
||||
if(!picklist) //No lateload maps at all
|
||||
return
|
||||
|
||||
if(!islist(picklist)) //So you can have a 'chain' of z-levels that make up one away mission
|
||||
error("Randompick Z level [picklist] is not a list! Must be in a list!")
|
||||
return
|
||||
|
||||
for(var/map in picklist)
|
||||
var/datum/map_template/MT = map_templates[map]
|
||||
if(!istype(MT))
|
||||
error("Randompick Z level \"[map]\" is not a valid map!")
|
||||
else
|
||||
MT.load_new_z(centered = FALSE)
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/preloadShelterTemplates()
|
||||
for(var/item in subtypesof(/datum/map_template/shelter))
|
||||
var/datum/map_template/shelter/shelter_type = item
|
||||
if(!(initial(shelter_type.mappath)))
|
||||
continue
|
||||
var/datum/map_template/shelter/S = new shelter_type()
|
||||
|
||||
shelter_templates[S.shelter_id] = S
|
||||
|
||||
/datum/controller/subsystem/mapping/stat_entry(msg)
|
||||
if (!Debug2)
|
||||
return // Only show up in stat panel if debugging is enabled.
|
||||
. = ..()
|
||||
+54
-63
@@ -1,32 +1,12 @@
|
||||
// Attempts to offload processing for the spreading plants from the MC.
|
||||
// Processes vines/spreading plants.
|
||||
|
||||
#define PLANTS_PER_TICK 500 // Cap on number of plant segments processed.
|
||||
#define PLANT_TICK_TIME 75 // Number of ticks between the plant processor cycling.
|
||||
|
||||
// Debug for testing seed genes.
|
||||
/client/proc/show_plant_genes()
|
||||
set category = "Debug"
|
||||
set name = "Show Plant Genes"
|
||||
set desc = "Prints the round's plant gene masks."
|
||||
SUBSYSTEM_DEF(plants)
|
||||
name = "Plants"
|
||||
init_order = INIT_ORDER_PLANTS
|
||||
priority = FIRE_PRIORITY_PLANTS
|
||||
wait = PLANT_TICK_TIME
|
||||
|
||||
if(!holder) return
|
||||
|
||||
if(!plant_controller || !plant_controller.gene_tag_masks)
|
||||
to_chat(usr, "Gene masks not set.")
|
||||
return
|
||||
|
||||
for(var/mask in plant_controller.gene_tag_masks)
|
||||
to_chat(usr, "[mask]: [plant_controller.gene_tag_masks[mask]]")
|
||||
|
||||
var/global/datum/controller/plants/plant_controller // Set in New().
|
||||
|
||||
/datum/controller/plants
|
||||
|
||||
var/plants_per_tick = PLANTS_PER_TICK
|
||||
var/plant_tick_time = PLANT_TICK_TIME
|
||||
var/list/product_descs = list() // Stores generated fruit descs.
|
||||
var/list/plant_queue = list() // All queued plants.
|
||||
var/list/seeds = list() // All seed data stored here.
|
||||
var/list/gene_tag_masks = list() // Gene obfuscation for delicious trial and error goodness.
|
||||
var/list/plant_icon_cache = list() // Stores images of growth, fruits and seeds.
|
||||
@@ -34,24 +14,26 @@ var/global/datum/controller/plants/plant_controller // Set in New().
|
||||
var/list/accessible_plant_sprites = list() // List of all plant sprites allowed to appear in random generation.
|
||||
var/list/plant_product_sprites = list() // List of all harvested product sprites.
|
||||
var/list/accessible_product_sprites = list() // List of all product sprites allowed to appear in random generation.
|
||||
var/processing = 0 // Off/on.
|
||||
var/list/gene_masked_list = list() // Stored gene masked list, rather than recreating it when needed.
|
||||
var/list/plant_gene_datums = list() // Stored datum versions of the gene masked list.
|
||||
|
||||
/datum/controller/plants/New()
|
||||
if(plant_controller && plant_controller != src)
|
||||
log_debug("Rebuilding plant controller.")
|
||||
qdel(plant_controller)
|
||||
plant_controller = src
|
||||
// To be clear, the only thing this processes are spreading plants
|
||||
// Hydro trays and growing food normally just chill in SSobj
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
|
||||
/datum/controller/subsystem/plants/stat_entry()
|
||||
..("P:[processing.len]|S:[seeds.len]")
|
||||
|
||||
/datum/controller/subsystem/plants/Initialize(timeofday)
|
||||
setup()
|
||||
process()
|
||||
return ..()
|
||||
|
||||
// Predefined/roundstart varieties use a string key to make it
|
||||
// easier to grab the new variety when mutating. Post-roundstart
|
||||
// and mutant varieties use their uid converted to a string instead.
|
||||
// Looks like shit but it's sort of necessary.
|
||||
/datum/controller/plants/proc/setup()
|
||||
|
||||
/datum/controller/subsystem/plants/proc/setup()
|
||||
// Build the icon lists.
|
||||
for(var/icostate in cached_icon_states('icons/obj/hydroponics_growing.dmi'))
|
||||
var/split = findtext(icostate,"-")
|
||||
@@ -116,10 +98,10 @@ var/global/datum/controller/plants/plant_controller // Set in New().
|
||||
gene_masked_list.Add(list(list("tag" = gene_tag, "mask" = gene_mask)))
|
||||
|
||||
// Proc for creating a random seed type.
|
||||
/datum/controller/plants/proc/create_random_seed(var/survive_on_station)
|
||||
/datum/controller/subsystem/plants/proc/create_random_seed(var/survive_on_station)
|
||||
var/datum/seed/seed = new()
|
||||
seed.randomize()
|
||||
seed.uid = plant_controller.seeds.len + 1
|
||||
seed.uid = SSplants.seeds.len + 1
|
||||
seed.name = "[seed.uid]"
|
||||
seeds[seed.name] = seed
|
||||
|
||||
@@ -138,32 +120,41 @@ var/global/datum/controller/plants/plant_controller // Set in New().
|
||||
seed.set_trait(TRAIT_HIGHKPA_TOLERANCE,200)
|
||||
return seed
|
||||
|
||||
/datum/controller/plants/process()
|
||||
processing = 1
|
||||
spawn(0)
|
||||
set background = 1
|
||||
var/processed = 0
|
||||
while(1)
|
||||
if(!processing)
|
||||
sleep(plant_tick_time)
|
||||
else
|
||||
processed = 0
|
||||
if(plant_queue.len)
|
||||
var/target_to_process = min(plant_queue.len,plants_per_tick)
|
||||
for(var/x=0;x<target_to_process;x++)
|
||||
if(!plant_queue.len)
|
||||
break
|
||||
var/obj/effect/plant/plant = pick(plant_queue)
|
||||
plant_queue -= plant
|
||||
if(!istype(plant))
|
||||
continue
|
||||
plant.process()
|
||||
processed++
|
||||
sleep(1) // Stagger processing out so previous tick can resolve (overlapping plant segments etc)
|
||||
sleep(max(1,(plant_tick_time-processed)))
|
||||
/datum/controller/subsystem/plants/fire(resumed = 0)
|
||||
if(!resumed)
|
||||
src.currentrun = processing.Copy()
|
||||
|
||||
/datum/controller/plants/proc/add_plant(var/obj/effect/plant/plant)
|
||||
plant_queue |= plant
|
||||
// Caching
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
while(currentrun.len)
|
||||
var/obj/effect/plant/P = currentrun[currentrun.len]
|
||||
--currentrun.len
|
||||
if(!P || QDELETED(P))
|
||||
continue
|
||||
P.process()
|
||||
|
||||
/datum/controller/plants/proc/remove_plant(var/obj/effect/plant/plant)
|
||||
plant_queue -= plant
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/plants/proc/add_plant(var/obj/effect/plant/plant)
|
||||
processing |= plant
|
||||
|
||||
/datum/controller/subsystem/plants/proc/remove_plant(var/obj/effect/plant/plant)
|
||||
processing -= plant
|
||||
|
||||
|
||||
// Debug for testing seed genes.
|
||||
/client/proc/show_plant_genes()
|
||||
set category = "Debug"
|
||||
set name = "Show Plant Genes"
|
||||
set desc = "Prints the round's plant gene masks."
|
||||
|
||||
if(!holder) return
|
||||
|
||||
if(!SSplants || !SSplants.gene_tag_masks)
|
||||
to_chat(usr, "Gene masks not set.")
|
||||
return
|
||||
|
||||
for(var/mask in SSplants.gene_tag_masks)
|
||||
to_chat(usr, "[mask]: [SSplants.gene_tag_masks[mask]]")
|
||||
@@ -78,6 +78,7 @@ var/global/datum/controller/subsystem/ticker/ticker
|
||||
/datum/controller/subsystem/ticker/proc/pregame_welcome()
|
||||
to_world("<span class='boldannounce notice'><em>Welcome to the pregame lobby!</em></span>")
|
||||
to_world("<span class='boldannounce notice'>Please set up your character and select ready. The round will start in [pregame_timeleft] seconds.</span>")
|
||||
world << sound('sound/misc/server-ready.ogg', volume = 100)
|
||||
|
||||
// Called during GAME_STATE_PREGAME (RUNLEVEL_LOBBY)
|
||||
/datum/controller/subsystem/ticker/proc/pregame_tick()
|
||||
@@ -402,20 +403,23 @@ var/global/datum/controller/subsystem/ticker/ticker
|
||||
for(var/mob/new_player/player in player_list)
|
||||
if(player && player.ready && player.mind?.assigned_role)
|
||||
var/datum/job/J = SSjob.get_job(player.mind.assigned_role)
|
||||
|
||||
|
||||
// Snowflakey AI treatment
|
||||
if(J?.mob_type & JOB_SILICON_AI)
|
||||
player.close_spawn_windows()
|
||||
player.AIize(move = TRUE)
|
||||
continue
|
||||
|
||||
|
||||
// Ask their new_player mob to spawn them
|
||||
if(!player.spawn_checks_vr(player.mind.assigned_role)) continue //VOREStation Add
|
||||
var/mob/living/carbon/human/new_char = player.create_character()
|
||||
|
||||
|
||||
// Created their playable character, delete their /mob/new_player
|
||||
if(new_char)
|
||||
qdel(player)
|
||||
if(new_char.client)
|
||||
var/obj/screen/splash/S = new(new_char.client, TRUE)
|
||||
S.Fade(TRUE)
|
||||
|
||||
// If they're a carbon, they can get manifested
|
||||
if(J?.mob_type & JOB_CARBON)
|
||||
@@ -431,7 +435,7 @@ var/global/datum/controller/subsystem/ticker/ticker
|
||||
var/captainless=1
|
||||
for(var/mob/living/carbon/human/player in player_list)
|
||||
if(player && player.mind && player.mind.assigned_role)
|
||||
if(player.mind.assigned_role == "Colony Director")
|
||||
if(player.mind.assigned_role == "Site Manager")
|
||||
captainless=0
|
||||
if(!player_is_antag(player.mind, only_offstation_roles = 1))
|
||||
job_master.EquipRank(player, player.mind.assigned_role, 0)
|
||||
@@ -441,7 +445,7 @@ var/global/datum/controller/subsystem/ticker/ticker
|
||||
if(captainless)
|
||||
for(var/mob/M in player_list)
|
||||
if(!istype(M,/mob/new_player))
|
||||
to_chat(M, "<span class='notice'>Colony Directorship not forced on anyone.</span>")
|
||||
to_chat(M, "<span class='notice'>Site Management is not forced on anyone.</span>")
|
||||
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/declare_completion()
|
||||
|
||||
@@ -97,7 +97,6 @@
|
||||
options["LEGACY: cameranet"] = cameranet
|
||||
options["LEGACY: transfer_controller"] = transfer_controller
|
||||
options["LEGACY: gas_data"] = gas_data
|
||||
options["LEGACY: plant_controller"] = plant_controller
|
||||
|
||||
var/pick = input(mob, "Choose a controller to debug/view variables of.", "VV controller:") as null|anything in options
|
||||
if(!pick)
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
/datum/category_item/autolathe/arms/pistol_5mm
|
||||
name = "pistol magazine (5mm)"
|
||||
path =/obj/item/ammo_magazine/c5mm
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
*/
|
||||
|
||||
@@ -237,93 +237,93 @@
|
||||
/datum/category_item/autolathe/arms/pistol_5mm
|
||||
name = "pistol magazine (5mm)"
|
||||
path =/obj/item/ammo_magazine/c5mm/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/smg_5mm
|
||||
name = "top-mounted SMG magazine (5mm)"
|
||||
path =/obj/item/ammo_magazine/c5mmt/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/pistol_45
|
||||
name = "pistol magazine (.45)"
|
||||
path =/obj/item/ammo_magazine/m45/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
|
||||
/datum/category_item/autolathe/arms/pistol_45uzi
|
||||
name = "uzi magazine (.45)"
|
||||
path =/obj/item/ammo_magazine/m45uzi/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/tommymag
|
||||
name = "Tommy Gun magazine (.45)"
|
||||
path =/obj/item/ammo_magazine/m45tommy/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/tommydrum
|
||||
name = "Tommy Gun drum magazine (.45)"
|
||||
path =/obj/item/ammo_magazine/m45tommydrum/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/pistol_9mm
|
||||
name = "pistol magazine (9mm)"
|
||||
path =/obj/item/ammo_magazine/m9mm/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
|
||||
/datum/category_item/autolathe/arms/smg_9mm
|
||||
name = "top-mounted SMG magazine (9mm)"
|
||||
path =/obj/item/ammo_magazine/m9mmt/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
|
||||
/datum/category_item/autolathe/arms/smg_10mm
|
||||
name = "SMG magazine (10mm)"
|
||||
path =/obj/item/ammo_magazine/m10mm/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/pistol_44
|
||||
name = "pistol magazine (.44)"
|
||||
path =/obj/item/ammo_magazine/m44/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/rifle_545
|
||||
name = "10rnd rifle magazine (5.45mm)"
|
||||
path =/obj/item/ammo_magazine/m545saw/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
|
||||
/datum/category_item/autolathe/arms/rifle_545m
|
||||
name = "20rnd rifle magazine (5.45mm)"
|
||||
path =/obj/item/ammo_magazine/m545sawm/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/rifle_SVD
|
||||
name = "10rnd rifle magazine (7.62mm)"
|
||||
path =/obj/item/ammo_magazine/m762svd/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/rifle_762
|
||||
name = "20rnd rifle magazine (7.62mm)"
|
||||
path =/obj/item/ammo_magazine/m762/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/machinegun_762
|
||||
name = "machinegun box magazine (7.62)"
|
||||
path =/obj/item/ammo_magazine/a762/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/shotgun_magazine
|
||||
name = "24rnd shotgun magazine (12g)"
|
||||
path =/obj/item/ammo_magazine/m12gdrum/empty
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1*/
|
||||
|
||||
///////////////////////////////
|
||||
@@ -357,73 +357,73 @@
|
||||
/*/datum/category_item/autolathe/arms/pistol_clip_45
|
||||
name = "ammo clip (.45)"
|
||||
path =/obj/item/ammo_magazine/clip/c45
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/pistol_clip_45r
|
||||
name = "ammo clip (.45 rubber)"
|
||||
path =/obj/item/ammo_magazine/clip/c45/rubber
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
|
||||
/datum/category_item/autolathe/arms/pistol_clip_45f
|
||||
name = "ammo clip (.45 flash)"
|
||||
path =/obj/item/ammo_magazine/clip/c45/flash
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
|
||||
/datum/category_item/autolathe/arms/pistol_clip_45p
|
||||
name = "ammo clip (.45 practice)"
|
||||
path =/obj/item/ammo_magazine/clip/c45/practice
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
|
||||
/datum/category_item/autolathe/arms/pistol_clip_9mm
|
||||
name = "ammo clip (9mm)"
|
||||
path =/obj/item/ammo_magazine/clip/c9mm
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/pistol_clip_9mmr
|
||||
name = "ammo clip (9mm rubber)"
|
||||
path =/obj/item/ammo_magazine/clip/c9mm/rubber
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
|
||||
/datum/category_item/autolathe/arms/pistol_clip_9mmp
|
||||
name = "ammo clip (9mm practice)"
|
||||
path =/obj/item/ammo_magazine/clip/c9mm/practice
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
|
||||
/datum/category_item/autolathe/arms/pistol_clip_9mmf
|
||||
name = "ammo clip (9mm flash)"
|
||||
path =/obj/item/ammo_magazine/clip/c9mm/flash
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
|
||||
/datum/category_item/autolathe/arms/pistol_clip_5mm
|
||||
name = "ammo clip (5mm)"
|
||||
path =/obj/item/ammo_magazine/clip/c5mm
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/pistol_clip_10mm
|
||||
name = "ammo clip (10mm)"
|
||||
path =/obj/item/ammo_magazine/clip/c10mm
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/pistol_clip_50
|
||||
name = "ammo clip (.44)"
|
||||
path =/obj/item/ammo_magazine/clip/c50
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
*/
|
||||
/datum/category_item/autolathe/arms/rifle_clip_545
|
||||
name = "ammo clip (5.45mm)"
|
||||
path =/obj/item/ammo_magazine/clip/c545
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/rifle_clip_545_practice
|
||||
name = "ammo clip (5.45mm practice)"
|
||||
path =/obj/item/ammo_magazine/clip/c545/practice
|
||||
category = "Arms and Ammunition"
|
||||
category = list("Arms and Ammunition")
|
||||
|
||||
/datum/category_item/autolathe/arms/rifle_clip_762
|
||||
name = "ammo clip (7.62mm)"
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
var/datum/category_collection/autolathe/autolathe_recipes
|
||||
|
||||
/datum/category_item/autolathe/New()
|
||||
..()
|
||||
var/obj/item/I = new path()
|
||||
|
||||
@@ -218,7 +218,7 @@ var/global/list/PDA_Manifest = list()
|
||||
heads[++heads.len] = list("name" = name, "rank" = rank, "active" = isactive)
|
||||
department = 1
|
||||
depthead = 1
|
||||
if(rank=="Colony Director" && heads.len != 1)
|
||||
if(rank=="Site Manager" && heads.len != 1)
|
||||
heads.Swap(1,heads.len)
|
||||
|
||||
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_SECURITY))
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
var/volume = 100
|
||||
var/max_loops
|
||||
var/direct
|
||||
var/vary
|
||||
var/extra_range
|
||||
var/opacity_check
|
||||
var/pref_check
|
||||
|
||||
@@ -89,7 +91,7 @@
|
||||
continue
|
||||
SEND_SOUND(thing, S)
|
||||
else
|
||||
playsound(thing, S, volume, ignore_walls = !opacity_check, preference = pref_check)
|
||||
playsound(thing, S, volume, vary, extra_range, ignore_walls = !opacity_check, preference = pref_check)
|
||||
|
||||
/datum/looping_sound/proc/get_sound(starttime, _mid_sounds)
|
||||
if(!_mid_sounds)
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/looping_sound/supermatter
|
||||
mid_sounds = list('sound/machines/sm/supermatter1.ogg'=1,'sound/machines/sm/supermatter2.ogg'=1,'sound/machines/sm/supermatter3.ogg'=1)
|
||||
mid_length = 10
|
||||
volume = 1
|
||||
mid_sounds = list('sound/machines/sm/loops/calm.ogg'=1)
|
||||
mid_length = 60
|
||||
volume = 40
|
||||
extra_range = 10
|
||||
pref_check = /datum/client_preference/supermatter_hum
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -28,25 +29,74 @@
|
||||
|
||||
|
||||
/datum/looping_sound/deep_fryer
|
||||
start_sound = 'sound/machines/fryer/deep_fryer_immerse.ogg' //my immersions
|
||||
start_sound = 'sound/machines/kitchen/fryer/deep_fryer_immerse.ogg' //my immersions
|
||||
start_length = 10
|
||||
mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1)
|
||||
mid_sounds = list('sound/machines/kitchen/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/kitchen/fryer/deep_fryer_2.ogg' = 1)
|
||||
mid_length = 2
|
||||
end_sound = 'sound/machines/fryer/deep_fryer_emerge.ogg'
|
||||
end_sound = 'sound/machines/kitchen/fryer/deep_fryer_emerge.ogg'
|
||||
volume = 15
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/looping_sound/microwave
|
||||
start_sound = 'sound/machines/microwave/microwave-start.ogg'
|
||||
start_sound = 'sound/machines/kitchen/microwave/microwave-start.ogg'
|
||||
start_length = 10
|
||||
mid_sounds = list('sound/machines/microwave/microwave-mid1.ogg'=10, 'sound/machines/microwave/microwave-mid2.ogg'=1)
|
||||
mid_sounds = list('sound/machines/kitchen/microwave/microwave-mid1.ogg'=10, 'sound/machines/kitchen/microwave/microwave-mid2.ogg'=1)
|
||||
mid_length = 10
|
||||
end_sound = 'sound/machines/microwave/microwave-end.ogg'
|
||||
end_sound = 'sound/machines/kitchen/microwave/microwave-end.ogg'
|
||||
volume = 90
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/looping_sound/oven
|
||||
start_sound = 'sound/machines/kitchen/oven/oven-start.ogg'
|
||||
start_length = 10
|
||||
mid_sounds = list('sound/machines/kitchen/oven/oven-mid1.ogg'=10)
|
||||
mid_length = 40
|
||||
end_sound = 'sound/machines/kitchen/oven/oven-stop.ogg'
|
||||
volume = 50
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/looping_sound/grill
|
||||
start_sound = 'sound/machines/kitchen/grill/grill-start.ogg'
|
||||
start_length = 10
|
||||
mid_sounds = list('sound/machines/kitchen/grill/grill-mid1.ogg'=10)
|
||||
mid_length = 40
|
||||
end_sound = 'sound/machines/kitchen/grill/grill-stop.ogg'
|
||||
volume = 50
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/looping_sound/mixer
|
||||
start_sound = 'sound/machines/kitchen/mixer/mixer-start.ogg'
|
||||
start_length = 10
|
||||
mid_sounds = list('sound/machines/kitchen/mixer/mixer-mid1.ogg'=10)
|
||||
mid_length = 10
|
||||
end_sound = 'sound/machines/kitchen/mixer/mixer-stop.ogg'
|
||||
volume = 50
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/looping_sound/cerealmaker
|
||||
start_sound = 'sound/machines/kitchen/cerealmaker/cerealmaker-start.ogg'
|
||||
start_length = 10
|
||||
mid_sounds = list('sound/machines/kitchen/cerealmaker/cerealmaker-mid1.ogg'=10)
|
||||
mid_length = 60
|
||||
end_sound = 'sound/machines/kitchen/cerealmaker/cerealmaker-stop.ogg'
|
||||
volume = 50
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/looping_sound/candymaker
|
||||
start_sound = 'sound/machines/kitchen/candymaker/candymaker-start.ogg'
|
||||
start_length = 10
|
||||
mid_sounds = list('sound/machines/kitchen/candymaker/candymaker-mid1.ogg'=10)
|
||||
mid_length = 40
|
||||
end_sound = 'sound/machines/kitchen/candymaker/candymaker-stop.ogg'
|
||||
volume = 20
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/datum/looping_sound/air_pump
|
||||
start_sound = 'sound/machines/air_pump/airpumpstart.ogg'
|
||||
start_length = 10
|
||||
|
||||
@@ -50,13 +50,13 @@
|
||||
access = access_atmospherics
|
||||
contains = list(/obj/machinery/portable_atmospherics/canister/phoron)
|
||||
|
||||
/datum/supply_pack/atmos/canister_sleeping_agent
|
||||
/datum/supply_pack/atmos/canister_nitrous_oxide
|
||||
name = "N2O gas canister"
|
||||
cost = 15
|
||||
containername = "N2O gas canister crate"
|
||||
containertype = /obj/structure/closet/crate/secure/large/aether
|
||||
access = access_atmospherics
|
||||
contains = list(/obj/machinery/portable_atmospherics/canister/sleeping_agent)
|
||||
contains = list(/obj/machinery/portable_atmospherics/canister/nitrous_oxide)
|
||||
|
||||
/datum/supply_pack/atmos/canister_carbon_dioxide
|
||||
name = "Carbon dioxide gas canister"
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
/obj/item/clothing/under/lawyer/bluesuit,
|
||||
/obj/item/clothing/under/lawyer/purpsuit,
|
||||
/obj/item/clothing/shoes/black = 2,
|
||||
/obj/item/clothing/shoes/leather,
|
||||
/obj/item/clothing/shoes/laceup/brown,
|
||||
/obj/item/clothing/accessory/wcoat
|
||||
)
|
||||
name = "Formalwear (Suits)"
|
||||
|
||||
@@ -174,7 +174,7 @@
|
||||
/obj/item/clothing/under/pants/chaps,
|
||||
/obj/item/clothing/under/pants/chaps/black,
|
||||
/obj/item/clothing/under/harness,
|
||||
/obj/item/clothing/shoes/leather,
|
||||
/obj/item/clothing/shoes/laceup/brown,
|
||||
/obj/item/clothing/shoes/boots/jungle,
|
||||
/obj/item/clothing/shoes/boots/jackboots,
|
||||
/obj/item/clothing/shoes/boots/cowboy,
|
||||
@@ -261,4 +261,24 @@
|
||||
)
|
||||
cost = 60
|
||||
containertype = /obj/structure/closet/crate
|
||||
containername = "Saddlebags crate"
|
||||
containername = "Saddlebags crate"
|
||||
|
||||
/datum/supply_pack/costumes/knights_gear
|
||||
name = "Knights Gear"
|
||||
contains = list(
|
||||
/obj/item/clothing/suit/storage/hooded/knight_costume,
|
||||
/obj/item/clothing/suit/storage/hooded/knight_costume/galahad,
|
||||
/obj/item/clothing/suit/storage/hooded/knight_costume/lancelot,
|
||||
/obj/item/clothing/suit/storage/hooded/knight_costume/robin,
|
||||
/obj/item/clothing/suit/armor/combat/crusader_costume,
|
||||
/obj/item/clothing/suit/armor/combat/crusader_costume/bedevere,
|
||||
/obj/item/clothing/head/helmet/combat/crusader_costume,
|
||||
/obj/item/clothing/head/helmet/combat/bedevere_costume,
|
||||
/obj/item/clothing/gloves/combat/knight_costume,
|
||||
/obj/item/clothing/gloves/combat/knight_costume/brown,
|
||||
/obj/item/clothing/shoes/knight_costume,
|
||||
/obj/item/clothing/shoes/knight_costume/black
|
||||
)
|
||||
cost = 10
|
||||
containertype = /obj/structure/closet/crate
|
||||
containername = "Knights Gear Crate"
|
||||
@@ -54,19 +54,12 @@
|
||||
containertype = /obj/structure/largecrate
|
||||
containername = "cooking oil tank crate"
|
||||
|
||||
/datum/supply_pack/randomised/hospitality/
|
||||
group = "Hospitality"
|
||||
|
||||
/datum/supply_pack/randomised/hospitality/pizza
|
||||
/datum/supply_pack/hospitality/pizza
|
||||
name = "Surprise pack of five pizzas"
|
||||
contains = list(
|
||||
/obj/random/pizzabox,
|
||||
/obj/random/pizzabox,
|
||||
/obj/random/pizzabox,
|
||||
/obj/random/pizzabox,
|
||||
/obj/random/pizzabox,
|
||||
/obj/random/pizzabox = 5,
|
||||
/obj/item/weapon/material/knife/plastic
|
||||
)
|
||||
name = "Surprise pack of five pizzas"
|
||||
cost = 15
|
||||
containertype = /obj/structure/closet/crate/freezer/centauri
|
||||
containername = "Pizza crate"
|
||||
@@ -83,4 +76,8 @@
|
||||
)
|
||||
cost = 10
|
||||
containertype = /obj/structure/closet/crate/allico
|
||||
containername = "crate of gifts"
|
||||
containername = "crate of gifts"
|
||||
|
||||
/datum/supply_pack/randomised/hospitality/
|
||||
group = "Hospitality"
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
switch(wire)
|
||||
if(WIRE_AUTOLATHE_HACK)
|
||||
A.hacked = !mend
|
||||
A.update_tgui_static_data(usr)
|
||||
if(WIRE_ELECTRIFY)
|
||||
A.shocked = !mend
|
||||
if(WIRE_AUTOLATHE_DISABLE)
|
||||
@@ -38,9 +39,11 @@
|
||||
switch(wire)
|
||||
if(WIRE_AUTOLATHE_HACK)
|
||||
A.hacked = !A.hacked
|
||||
A.update_tgui_static_data(usr)
|
||||
spawn(50)
|
||||
if(A && !is_cut(wire))
|
||||
A.hacked = 0
|
||||
A.update_tgui_static_data(usr)
|
||||
if(WIRE_ELECTRIFY)
|
||||
A.shocked = !A.shocked
|
||||
spawn(50)
|
||||
|
||||
@@ -43,12 +43,12 @@
|
||||
|
||||
flags = XGM_GAS_FUEL
|
||||
|
||||
/decl/xgm_gas/sleeping_agent
|
||||
id = "sleeping_agent"
|
||||
name = "Sleeping Agent"
|
||||
/decl/xgm_gas/nitrous_oxide
|
||||
id = "nitrous_oxide"
|
||||
name = "Nitrous Oxide"
|
||||
specific_heat = 40 // J/(mol*K)
|
||||
molar_mass = 0.044 // kg/mol. N2O
|
||||
|
||||
tile_overlay = "sleeping_agent"
|
||||
tile_overlay = "nitrous_oxide"
|
||||
overlay_limit = 1
|
||||
flags = XGM_GAS_OXIDIZER
|
||||
@@ -97,6 +97,7 @@
|
||||
throw_speed = 1
|
||||
throw_range = 20
|
||||
drop_sound = 'sound/items/drop/rubber.ogg'
|
||||
pickup_sound = 'sound/items/pickup/rubber.ogg'
|
||||
|
||||
afterattack(atom/target as mob|obj|turf|area, mob/user as mob)
|
||||
user.drop_item()
|
||||
|
||||
@@ -79,6 +79,8 @@
|
||||
/obj/item/weapon/disk
|
||||
name = "disk"
|
||||
icon = 'icons/obj/discs_vr.dmi' //VOREStation Edit
|
||||
drop_sound = 'sound/items/drop/disk.ogg'
|
||||
pickup_sound = 'sound/items/pickup/disk.ogg'
|
||||
|
||||
/obj/item/weapon/disk/nuclear
|
||||
name = "nuclear authentication disk"
|
||||
|
||||
@@ -6,7 +6,7 @@ var/datum/antagonist/mutineer/mutineers
|
||||
role_text_plural = "Mutineers"
|
||||
id = MODE_MUTINEER
|
||||
antag_indicator = "mutineer"
|
||||
restricted_jobs = list("Colony Director")
|
||||
restricted_jobs = list("Site Manager")
|
||||
|
||||
/datum/antagonist/mutineer/New(var/no_reference)
|
||||
..()
|
||||
@@ -39,7 +39,7 @@ var/datum/antagonist/mutineer/mutineers
|
||||
proc/get_head_loyalist_candidates()
|
||||
var/list/candidates[0]
|
||||
for(var/mob/loyalist in player_list)
|
||||
if(loyalist.mind && loyalist.mind.assigned_role == "Colony Director")
|
||||
if(loyalist.mind && loyalist.mind.assigned_role == "Site Manager")
|
||||
candidates.Add(loyalist.mind)
|
||||
return candidates
|
||||
|
||||
@@ -47,7 +47,7 @@ var/datum/antagonist/mutineer/mutineers
|
||||
var/list/candidates[0]
|
||||
for(var/mob/mutineer in player_list)
|
||||
if(mutineer.client.prefs.be_special & BE_MUTINEER)
|
||||
for(var/job in command_positions - "Colony Director")
|
||||
for(var/job in command_positions - "Site Manager")
|
||||
if(mutineer.mind && mutineer.mind.assigned_role == job)
|
||||
candidates.Add(mutineer.mind)
|
||||
return candidates
|
||||
|
||||
@@ -14,7 +14,7 @@ var/datum/antagonist/ert/ert
|
||||
and before taking extreme actions, please try to also contact the administration! \
|
||||
Think through your actions and make the roleplay immersive! <b>Please remember all \
|
||||
rules aside from those without explicit exceptions apply to the ERT.</b>"
|
||||
leader_welcome_text = "As leader of the Emergency Response Team, you answer only to the Company, and have authority to override the Colony Director where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the Colony Director where possible, however."
|
||||
leader_welcome_text = "As leader of the Emergency Response Team, you answer only to the Company, and have authority to override the Site Manager where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the Site Manager where possible, however."
|
||||
landmark_id = "Response Team"
|
||||
id_type = /obj/item/weapon/card/id/centcom/ERT
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
bantype = "changeling"
|
||||
feedback_tag = "changeling_objective"
|
||||
avoid_silicons = TRUE
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Colony Director")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Site Manager")
|
||||
welcome_text = "Use say \"#g message\" to communicate with your fellow changelings. Remember: you get all of their absorbed DNA if you absorb them."
|
||||
antag_sound = 'sound/effects/antag_notice/ling_alert.ogg'
|
||||
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
||||
|
||||
@@ -13,8 +13,8 @@ var/datum/antagonist/cultist/cult
|
||||
bantype = "cultist"
|
||||
restricted_jobs = list("Chaplain")
|
||||
avoid_silicons = TRUE
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director")
|
||||
roundstart_restricted = list("Internal Affairs Agent", "Head of Security", "Colony Director")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Site Manager")
|
||||
roundstart_restricted = list("Internal Affairs Agent", "Head of Security", "Site Manager")
|
||||
role_type = BE_CULTIST
|
||||
feedback_tag = "cult_objective"
|
||||
antag_indicator = "cult"
|
||||
|
||||
@@ -11,7 +11,7 @@ var/datum/antagonist/traitor/infiltrator/infiltrators
|
||||
role_text = "Infiltrator"
|
||||
role_text_plural = "Infiltrators"
|
||||
welcome_text = "To speak on your team's private channel, use :t."
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Site Manager")
|
||||
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
||||
can_speak_aooc = TRUE
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ var/datum/antagonist/revolutionary/revs
|
||||
faction_invisible = 1
|
||||
|
||||
avoid_silicons = TRUE
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Colony Director", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer")
|
||||
roundstart_restricted = list("Internal Affairs Agent", "Colony Director", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Site Manager", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer")
|
||||
roundstart_restricted = list("Internal Affairs Agent", "Site Manager", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer")
|
||||
|
||||
/datum/antagonist/revolutionary/New()
|
||||
..()
|
||||
|
||||
@@ -4,7 +4,7 @@ var/datum/antagonist/traitor/traitors
|
||||
/datum/antagonist/traitor
|
||||
id = MODE_TRAITOR
|
||||
antag_sound = 'sound/effects/antag_notice/traitor_alert.ogg'
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Site Manager")
|
||||
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
||||
can_speak_aooc = FALSE // If they want to plot and plan as this sort of traitor, they'll need to do it ICly.
|
||||
|
||||
|
||||
@@ -280,6 +280,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/centcom/bathroom
|
||||
name = "\improper CentCom Bathroom"
|
||||
icon_state = "centcom_crew"
|
||||
sound_env = SMALL_ENCLOSED
|
||||
|
||||
//SYNDICATES
|
||||
|
||||
@@ -736,6 +737,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "Substation"
|
||||
icon_state = "substation"
|
||||
sound_env = SMALL_ENCLOSED
|
||||
ambience = AMBIENCE_SUBSTATION
|
||||
|
||||
/area/maintenance/substation/engineering // Probably will be connected to engineering SMES room, as wires cannot be crossed properly without them sharing powernets.
|
||||
name = "Engineering Substation"
|
||||
@@ -950,7 +952,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
sound_env = MEDIUM_SOFTFLOOR
|
||||
|
||||
/area/crew_quarters/captain
|
||||
name = "\improper Command - Colony Director's Office"
|
||||
name = "\improper Command - Site Manager's Office"
|
||||
icon_state = "captain"
|
||||
sound_env = MEDIUM_SOFTFLOOR
|
||||
|
||||
@@ -1207,6 +1209,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/crew_quarters/recreation_area_restroom
|
||||
name = "\improper Recreation Area Restroom"
|
||||
icon_state = "recreation_area_restroom"
|
||||
sound_env = SMALL_ENCLOSED
|
||||
|
||||
/area/crew_quarters/pool
|
||||
name = "\improper Pool"
|
||||
@@ -1232,6 +1235,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/crew_quarters/barrestroom
|
||||
name = "\improper Cafeteria Restroom"
|
||||
icon_state = "bar"
|
||||
sound_env = SMALL_ENCLOSED
|
||||
|
||||
/area/crew_quarters/theatre
|
||||
name = "\improper Theatre"
|
||||
@@ -1381,6 +1385,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "\improper Atmospherics"
|
||||
icon_state = "atmos"
|
||||
sound_env = LARGE_ENCLOSED
|
||||
ambience = AMBIENCE_ATMOS
|
||||
|
||||
/area/engineering/atmos/monitoring
|
||||
name = "\improper Atmospherics Monitoring Room"
|
||||
@@ -1603,6 +1608,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/crew_quarters/medical_restroom
|
||||
name = "\improper Medbay Restroom"
|
||||
icon_state = "medbay_restroom"
|
||||
sound_env = SMALL_ENCLOSED
|
||||
|
||||
/area/medical/patients_rooms
|
||||
name = "\improper Patient's Rooms"
|
||||
@@ -1796,6 +1802,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/security/security_bathroom
|
||||
name = "\improper Security - Restroom"
|
||||
icon_state = "security_bathroom"
|
||||
sound_env = SMALL_ENCLOSED
|
||||
|
||||
/area/security/security_cell_hallway
|
||||
name = "\improper Security - Cell Hallway"
|
||||
@@ -1944,6 +1951,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/rnd/research_restroom
|
||||
name = "\improper Research Restroom"
|
||||
icon_state = "research_restroom"
|
||||
sound_env = SMALL_ENCLOSED
|
||||
|
||||
/area/rnd/research_storage
|
||||
name = "\improper Research Storage"
|
||||
|
||||
+3
-1
@@ -488,7 +488,7 @@
|
||||
// Use for objects performing visible actions
|
||||
// message is output to anyone who can see, e.g. "The [src] does something!"
|
||||
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
|
||||
/atom/proc/visible_message(var/message, var/blind_message)
|
||||
/atom/proc/visible_message(var/message, var/blind_message, var/list/exclude_mobs = null)
|
||||
|
||||
//VOREStation Edit
|
||||
var/list/see
|
||||
@@ -501,6 +501,8 @@
|
||||
|
||||
var/list/seeing_mobs = see["mobs"]
|
||||
var/list/seeing_objs = see["objs"]
|
||||
if(LAZYLEN(exclude_mobs))
|
||||
seeing_mobs -= exclude_mobs
|
||||
|
||||
for(var/obj in seeing_objs)
|
||||
var/obj/O = obj
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
force = 30
|
||||
throwforce = 10
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
drop_sound = 'sound/items/drop/sword.ogg'
|
||||
pickup_sound = 'sound/items/pickup/sword.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
edge = 1
|
||||
sharp = 1
|
||||
|
||||
@@ -297,9 +297,9 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
|
||||
M.add_ion_law("HUMANS NEED TO EAT [what2pref] [what2] TO SURVIVE")
|
||||
if(5)
|
||||
to_chat(M, "<br>")
|
||||
to_chat(M, "<span class='danger'>THE COLONY DIRECTOR, HOP AND HOS ARE [who2]...LAWS UPDATED</span>")
|
||||
to_chat(M, "<span class='danger'>THE SITE MANAGER, HOP AND HOS ARE [who2]...LAWS UPDATED</span>")
|
||||
to_chat(M, "<br>")
|
||||
M.add_ion_law("THE COLONY DIRECTOR, HOP AND HOS ARE [who2]")
|
||||
M.add_ion_law("THE SITE MANAGER, HOP AND HOS ARE [who2]")
|
||||
if(6)
|
||||
to_chat(M, "<br>")
|
||||
to_chat(M, "<span class='danger'>THE STATION IS BUILT FOR [who2]...LAWS UPDATED</span>")
|
||||
|
||||
@@ -564,7 +564,7 @@ datum
|
||||
|
||||
captainslaser
|
||||
steal_target = /obj/item/weapon/gun/energy/captain
|
||||
explanation_text = "Steal the Colony Director's antique laser gun."
|
||||
explanation_text = "Steal the Site Manager's antique laser gun."
|
||||
weight = 20
|
||||
|
||||
get_points(var/job)
|
||||
|
||||
@@ -427,11 +427,11 @@ datum/objective/steal
|
||||
var/target_name
|
||||
|
||||
var/global/possible_items[] = list(
|
||||
"the Colony Director's antique laser gun" = /obj/item/weapon/gun/energy/captain,
|
||||
"the Site Manager's antique laser gun" = /obj/item/weapon/gun/energy/captain,
|
||||
"a hand teleporter" = /obj/item/weapon/hand_tele,
|
||||
"an RCD" = /obj/item/weapon/rcd,
|
||||
"a jetpack" = /obj/item/weapon/tank/jetpack,
|
||||
"a colony director's jumpsuit" = /obj/item/clothing/under/rank/captain,
|
||||
"a site manager's jumpsuit" = /obj/item/clothing/under/rank/captain,
|
||||
"a functional AI" = /obj/item/device/aicard,
|
||||
"a pair of magboots" = /obj/item/clothing/shoes/magboots,
|
||||
"the station blueprints" = /obj/item/blueprints,
|
||||
@@ -445,7 +445,7 @@ datum/objective/steal
|
||||
"a head of security's jumpsuit" = /obj/item/clothing/under/rank/head_of_security,
|
||||
"a head of personnel's jumpsuit" = /obj/item/clothing/under/rank/head_of_personnel,
|
||||
"the hypospray" = /obj/item/weapon/reagent_containers/hypospray/vial,
|
||||
"the colony director's pinpointer" = /obj/item/weapon/pinpointer,
|
||||
"the site manager's pinpointer" = /obj/item/weapon/pinpointer,
|
||||
"an ablative armor vest" = /obj/item/clothing/suit/armor/laserproof,
|
||||
)
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
/var/const/access_captain = 20
|
||||
/datum/access/captain
|
||||
id = access_captain
|
||||
desc = "Colony Director"
|
||||
desc = "Site Manager"
|
||||
region = ACCESS_REGION_COMMAND
|
||||
|
||||
/var/const/access_all_personal_lockers = 21
|
||||
|
||||
@@ -5,7 +5,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
|
||||
//////////////////////////////////
|
||||
|
||||
/datum/job/captain
|
||||
title = "Colony Director"
|
||||
title = "Site Manager"
|
||||
flag = CAPTAIN
|
||||
departments = list(DEPARTMENT_COMMAND)
|
||||
sorting_order = 3 // Above everyone.
|
||||
@@ -26,11 +26,10 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
|
||||
ideal_character_age = 70 // Old geezer captains ftw
|
||||
|
||||
outfit_type = /decl/hierarchy/outfit/job/captain
|
||||
job_description = "The Colony Director manages the other Command Staff, and through them the rest of the station. Though they have access to everything, \
|
||||
they do not understand everything, and are expected to delegate tasks to the appropriate crew member. The Colony Director is expected to \
|
||||
job_description = "The Site Manager manages the other Command Staff, and through them the rest of the station. Though they have access to everything, \
|
||||
they do not understand everything, and are expected to delegate tasks to the appropriate crew member. The Site Manager is expected to \
|
||||
have an understanding of Standard Operating Procedure, and is subject to it, and legal action, in the same way as every other crew member."
|
||||
alt_titles = list("Site Manager" = /datum/alt_title/site_manager,
|
||||
"Overseer" = /datum/alt_title/overseer)
|
||||
alt_titles = list("Overseer"= /datum/alt_title/overseer)
|
||||
|
||||
/*
|
||||
/datum/job/captain/equip(var/mob/living/carbon/human/H)
|
||||
@@ -44,9 +43,6 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
|
||||
|
||||
|
||||
// Captain Alt Titles
|
||||
/datum/alt_title/site_manager
|
||||
title = "Site Manager"
|
||||
|
||||
/datum/alt_title/overseer
|
||||
title = "Overseer"
|
||||
|
||||
@@ -63,7 +59,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
|
||||
faction = "Station"
|
||||
total_positions = 1
|
||||
spawn_positions = 1
|
||||
supervisors = "the Colony Director"
|
||||
supervisors = "the Site Manager"
|
||||
selection_color = "#1D1D4F"
|
||||
req_admin_notify = 1
|
||||
minimal_player_age = 10
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
faction = "Station"
|
||||
total_positions = 1
|
||||
spawn_positions = 1
|
||||
supervisors = "the Colony Director"
|
||||
supervisors = "the Site Manager"
|
||||
selection_color = "#7F6E2C"
|
||||
req_admin_notify = 1
|
||||
economic_modifier = 10
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
faction = "Station"
|
||||
total_positions = 1
|
||||
spawn_positions = 1
|
||||
supervisors = "the Colony Director"
|
||||
supervisors = "the Site Manager"
|
||||
selection_color = "#026865"
|
||||
req_admin_notify = 1
|
||||
economic_modifier = 10
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
faction = "Station"
|
||||
total_positions = 1
|
||||
spawn_positions = 1
|
||||
supervisors = "the Colony Director"
|
||||
supervisors = "the Site Manager"
|
||||
selection_color = "#AD6BAD"
|
||||
req_admin_notify = 1
|
||||
economic_modifier = 15
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
alt_titles = list("Xenoarchaeologist" = /datum/alt_title/xenoarch, "Anomalist" = /datum/alt_title/anomalist, \
|
||||
"Phoron Researcher" = /datum/alt_title/phoron_research, "Circuit Designer" = /datum/alt_title/circuit_designer)
|
||||
|
||||
|
||||
access = list(access_robotics, access_tox, access_tox_storage, access_research, access_xenobiology, access_xenoarch, access_xenobotany)
|
||||
minimal_access = list(access_tox, access_tox_storage, access_research, access_xenoarch) // Unchanged (for now?), mostly here for reference
|
||||
|
||||
|
||||
/datum/alt_title/circuit_designer
|
||||
title = "Circuit Designer"
|
||||
title_blurb = "A Circuit Designer is a Scientist whose expertise is working with integrated circuits. They are familar with the workings and programming of those devices. \
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
faction = "Station"
|
||||
total_positions = 1
|
||||
spawn_positions = 1
|
||||
supervisors = "the Colony Director"
|
||||
supervisors = "the Site Manager"
|
||||
selection_color = "#8E2929"
|
||||
req_admin_notify = 1
|
||||
economic_modifier = 10
|
||||
|
||||
@@ -394,7 +394,7 @@ var/global/datum/controller/occupations/job_master
|
||||
var/datum/gear/G = gear_datums[thing]
|
||||
if(!G) //Not a real gear datum (maybe removed, as this is loaded from their savefile)
|
||||
continue
|
||||
|
||||
|
||||
var/permitted
|
||||
// Check if it is restricted to certain roles
|
||||
if(G.allowed_roles)
|
||||
@@ -435,13 +435,13 @@ var/global/datum/controller/occupations/job_master
|
||||
|
||||
// Set up their account
|
||||
job.setup_account(H)
|
||||
|
||||
|
||||
// Equip job items.
|
||||
job.equip(H, H.mind ? H.mind.role_alt_title : "")
|
||||
|
||||
|
||||
// Stick their fingerprints on literally everything
|
||||
job.apply_fingerprints(H)
|
||||
|
||||
|
||||
// Only non-silicons get post-job-equip equipment
|
||||
if(!(job.mob_type & JOB_SILICON))
|
||||
H.equip_post_job()
|
||||
@@ -487,11 +487,11 @@ var/global/datum/controller/occupations/job_master
|
||||
return H.Robotize()
|
||||
if(job.mob_type & JOB_SILICON_AI)
|
||||
return H
|
||||
|
||||
|
||||
// TWEET PEEP
|
||||
if(rank == "Colony Director")
|
||||
if(rank == "Site Manager")
|
||||
var/sound/announce_sound = (ticker.current_state <= GAME_STATE_SETTING_UP) ? null : sound('sound/misc/boatswain.ogg', volume=20)
|
||||
captain_announcement.Announce("All hands, [alt_title ? alt_title : "Colony Director"] [H.real_name] on deck!", new_sound = announce_sound, zlevel = H.z)
|
||||
captain_announcement.Announce("All hands, [alt_title ? alt_title : "Site Manager"] [H.real_name] on deck!", new_sound = announce_sound, zlevel = H.z)
|
||||
|
||||
//Deferred item spawning.
|
||||
if(spawn_in_storage && spawn_in_storage.len)
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
M.forceMove(src)
|
||||
occupant = M
|
||||
update_icon() //icon_state = "body_scanner_1" //VOREStation Edit - Health display for consoles with light and such.
|
||||
playsound(src, 'sound/machines/medbayscanner1.ogg', 50) // Beepboop you're being scanned. <3
|
||||
add_fingerprint(user)
|
||||
qdel(G)
|
||||
SStgui.update_uis(src)
|
||||
@@ -101,6 +102,7 @@
|
||||
O.forceMove(src)
|
||||
occupant = O
|
||||
update_icon() //icon_state = "body_scanner_1" //VOREStation Edit - Health display for consoles with light and such.
|
||||
playsound(src, 'sound/machines/medbayscanner1.ogg', 50) // Beepboop you're being scanned. <3
|
||||
add_fingerprint(user)
|
||||
SStgui.update_uis(src)
|
||||
|
||||
@@ -332,6 +334,7 @@
|
||||
if("print_p")
|
||||
var/atom/target = console ? console : src
|
||||
visible_message("<span class='notice'>[target] rattles and prints out a sheet of paper.</span>")
|
||||
playsound(src, 'sound/machines/printer.ogg', 50, 1)
|
||||
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(target))
|
||||
var/name = occupant ? occupant.name : "Unknown"
|
||||
P.info = "<CENTER><B>Body Scan - [name]</B></CENTER><BR>"
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
var/list/TLV = list()
|
||||
var/list/trace_gas = list("sleeping_agent", "volatile_fuel") //list of other gases that this air alarm is able to detect
|
||||
var/list/trace_gas = list("nitrous_oxide", "volatile_fuel") //list of other gases that this air alarm is able to detect
|
||||
|
||||
var/danger_level = 0
|
||||
var/pressure_dangerlevel = 0
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
/obj/machinery/portable_atmospherics/canister/drain_power()
|
||||
return -1
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/sleeping_agent
|
||||
/obj/machinery/portable_atmospherics/canister/nitrous_oxide
|
||||
name = "Canister: \[N2O\]"
|
||||
icon_state = "redws"
|
||||
canister_color = "redws"
|
||||
@@ -88,7 +88,7 @@
|
||||
name = "Canister \[CO2\]"
|
||||
icon_state = "black"
|
||||
canister_color = "black"
|
||||
/obj/machinery/portable_atmospherics/canister/empty/sleeping_agent
|
||||
/obj/machinery/portable_atmospherics/canister/empty/nitrous_oxide
|
||||
name = "Canister \[N2O\]"
|
||||
icon_state = "redws"
|
||||
canister_color = "redws"
|
||||
@@ -390,17 +390,17 @@ update_flag
|
||||
src.update_icon()
|
||||
return 1
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/sleeping_agent/New()
|
||||
/obj/machinery/portable_atmospherics/canister/nitrous_oxide/New()
|
||||
..()
|
||||
|
||||
air_contents.adjust_gas("sleeping_agent", MolesForPressure())
|
||||
air_contents.adjust_gas("nitrous_oxide", MolesForPressure())
|
||||
src.update_icon()
|
||||
return 1
|
||||
|
||||
//Dirty way to fill room with gas. However it is a bit easier to do than creating some floor/engine/n2o -rastaf0
|
||||
/obj/machinery/portable_atmospherics/canister/sleeping_agent/roomfiller/Initialize()
|
||||
/obj/machinery/portable_atmospherics/canister/nitrous_oxide/roomfiller/Initialize()
|
||||
. = ..()
|
||||
air_contents.gas["sleeping_agent"] = 9*4000
|
||||
air_contents.gas["nitrous_oxide"] = 9*4000
|
||||
var/turf/simulated/location = src.loc
|
||||
if (istype(src.loc))
|
||||
location.assume_air(air_contents)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
var/minrate = 0
|
||||
var/maxrate = 10 * ONE_ATMOSPHERE
|
||||
|
||||
var/list/scrubbing_gas = list("phoron", "carbon_dioxide", "sleeping_agent", "volatile_fuel")
|
||||
var/list/scrubbing_gas = list("phoron", "carbon_dioxide", "nitrous_oxide", "volatile_fuel")
|
||||
|
||||
/obj/machinery/portable_atmospherics/powered/scrubber/New()
|
||||
..()
|
||||
|
||||
+142
-147
@@ -11,10 +11,10 @@
|
||||
clickvol = 30
|
||||
|
||||
circuit = /obj/item/weapon/circuitboard/autolathe
|
||||
var/datum/category_collection/autolathe/machine_recipes
|
||||
|
||||
var/static/datum/category_collection/autolathe/autolathe_recipes
|
||||
var/list/stored_material = list(DEFAULT_WALL_MATERIAL = 0, MAT_GLASS = 0, MAT_PLASTEEL = 0, MAT_PLASTIC = 0)
|
||||
var/list/storage_capacity = list(DEFAULT_WALL_MATERIAL = 0, MAT_GLASS = 0, MAT_PLASTEEL = 0, MAT_PLASTIC = 0)
|
||||
var/datum/category_group/autolathe/current_category
|
||||
|
||||
var/hacked = 0
|
||||
var/disabled = 0
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
/obj/machinery/autolathe/Initialize()
|
||||
. = ..()
|
||||
if(!autolathe_recipes)
|
||||
autolathe_recipes = new()
|
||||
wires = new(src)
|
||||
default_apply_parts()
|
||||
RefreshParts()
|
||||
@@ -42,87 +44,77 @@
|
||||
wires = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/autolathe/proc/update_recipe_list()
|
||||
if(!machine_recipes)
|
||||
if(!autolathe_recipes)
|
||||
autolathe_recipes = new()
|
||||
machine_recipes = autolathe_recipes
|
||||
current_category = machine_recipes.categories[1]
|
||||
/obj/machinery/autolathe/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Autolathe", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/autolathe/interact(mob/user as mob)
|
||||
update_recipe_list()
|
||||
/obj/machinery/autolathe/tgui_status(mob/user)
|
||||
if(disabled)
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
|
||||
if(..() || (disabled && !panel_open))
|
||||
/obj/machinery/autolathe/tgui_static_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
var/list/categories = list()
|
||||
var/list/recipes = list()
|
||||
for(var/datum/category_group/autolathe/A in autolathe_recipes.categories)
|
||||
categories += A.name
|
||||
for(var/datum/category_item/autolathe/M in A.items)
|
||||
if(M.hidden && !hacked)
|
||||
continue
|
||||
if(M.man_rating > man_rating)
|
||||
continue
|
||||
recipes.Add(list(list(
|
||||
"category" = A.name,
|
||||
"name" = M.name,
|
||||
"ref" = REF(M),
|
||||
"requirements" = M.resources,
|
||||
"hidden" = M.hidden,
|
||||
"coeff_applies" = !M.no_scale,
|
||||
)))
|
||||
data["recipes"] = recipes
|
||||
data["categories"] = categories
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/autolathe/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/spritesheet/sheetmaterials)
|
||||
)
|
||||
|
||||
/obj/machinery/autolathe/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
var/list/material_data = list()
|
||||
for(var/mat_id in stored_material)
|
||||
var/amount = stored_material[mat_id]
|
||||
var/list/material_info = list(
|
||||
"name" = mat_id,
|
||||
"amount" = amount,
|
||||
"sheets" = round(amount / SHEET_MATERIAL_AMOUNT),
|
||||
"removable" = amount >= SHEET_MATERIAL_AMOUNT
|
||||
)
|
||||
material_data += list(material_info)
|
||||
data["busy"] = busy
|
||||
data["materials"] = material_data
|
||||
data["mat_efficiency"] = mat_efficiency
|
||||
return data
|
||||
|
||||
/obj/machinery/autolathe/interact(mob/user)
|
||||
if(panel_open)
|
||||
return wires.Interact(user)
|
||||
|
||||
if(disabled)
|
||||
to_chat(user, "<span class='danger'>\The [src] is disabled!</span>")
|
||||
return
|
||||
|
||||
if(shocked)
|
||||
shock(user, 50)
|
||||
var/list/dat = list()
|
||||
dat += "<center><h1>Autolathe Control Panel</h1><hr/>"
|
||||
|
||||
if(!disabled)
|
||||
dat += "<table width = '100%'>"
|
||||
var/list/material_top = list("<tr>")
|
||||
var/list/material_bottom = list("<tr>")
|
||||
|
||||
for(var/material in stored_material)
|
||||
if(material != DEFAULT_WALL_MATERIAL && material != MAT_GLASS) // Don't show the Extras unless people care enough to put them in.
|
||||
if(stored_material[material] <= 0)
|
||||
continue
|
||||
material_top += "<td width = '25%' align = center><b>[material]</b></td>"
|
||||
material_bottom += "<td width = '25%' align = center>[stored_material[material]]<b>/[storage_capacity[material]]</b></td>"
|
||||
|
||||
dat += "[material_top.Join()]</tr>[material_bottom.Join()]</tr></table><hr>"
|
||||
dat += "<b>Filter:</b> <a href='?src=\ref[src];setfilter=1'>[filtertext ? filtertext : "None Set"]</a><br>"
|
||||
dat += "<h2>Printable Designs</h2><h3>Showing: <a href='?src=\ref[src];change_category=1'>[current_category]</a>.</h3></center><table width = '100%'>"
|
||||
|
||||
for(var/datum/category_item/autolathe/R in current_category.items)
|
||||
if(R.hidden && !hacked) // Illegal or nonstandard.
|
||||
continue
|
||||
if(R.man_rating > man_rating) // Advanced parts.
|
||||
continue
|
||||
if(filtertext && findtext(R.name, filtertext) == 0)
|
||||
continue
|
||||
var/can_make = 1
|
||||
var/list/material_string = list()
|
||||
var/list/multiplier_string = list()
|
||||
var/max_sheets
|
||||
var/comma
|
||||
if(!R.resources || !R.resources.len)
|
||||
material_string += "No resources required.</td>"
|
||||
else
|
||||
//Make sure it's buildable and list requires resources.
|
||||
for(var/material in R.resources)
|
||||
var/coeff = (R.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient
|
||||
var/sheets = round(stored_material[material]/round(R.resources[material]*coeff))
|
||||
if(isnull(max_sheets) || max_sheets > sheets)
|
||||
max_sheets = sheets
|
||||
if(!isnull(stored_material[material]) && stored_material[material] < round(R.resources[material]*coeff))
|
||||
can_make = 0
|
||||
if(!comma)
|
||||
comma = 1
|
||||
else
|
||||
material_string += ", "
|
||||
material_string += "[round(R.resources[material] * coeff)] [material]"
|
||||
material_string += ".<br></td>"
|
||||
//Build list of multipliers for sheets.
|
||||
if(R.is_stack)
|
||||
if(max_sheets && max_sheets > 0)
|
||||
max_sheets = min(max_sheets, R.max_stack) // Limit to the max allowed by stack type.
|
||||
multiplier_string += "<br>"
|
||||
for(var/i = 5;i<max_sheets;i*=2) //5,10,20,40...
|
||||
multiplier_string += "<a href='?src=\ref[src];make=\ref[R];multiplier=[i]'>\[x[i]\]</a>"
|
||||
multiplier_string += "<a href='?src=\ref[src];make=\ref[R];multiplier=[max_sheets]'>\[x[max_sheets]\]</a>"
|
||||
|
||||
dat += "<tr><td width = 180>[R.hidden ? "<font color = 'red'>*</font>" : ""]<b>[can_make ? "<a href='?src=\ref[src];make=\ref[R];multiplier=1'>" : "<span class='linkOff'>"][R.name][can_make ? "</a>" : "</span>"]</b>[R.hidden ? "<font color = 'red'>*</font>" : ""][multiplier_string.Join()]</td><td align = right>[material_string.Join()]</tr>"
|
||||
|
||||
dat += "</table><hr>"
|
||||
|
||||
dat = jointext(dat, null)
|
||||
var/datum/browser/popup = new(user, "autolathe", "Autolathe Production Menu", 550, 700)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/autolathe/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(busy)
|
||||
@@ -130,7 +122,7 @@
|
||||
return
|
||||
|
||||
if(default_deconstruction_screwdriver(user, O))
|
||||
updateUsrDialog()
|
||||
interact(user)
|
||||
return
|
||||
if(default_deconstruction_crowbar(user, O))
|
||||
return
|
||||
@@ -155,18 +147,6 @@
|
||||
if(istype(O,/obj/item/ammo_magazine/clip) || istype(O,/obj/item/ammo_magazine/s357) || istype(O,/obj/item/ammo_magazine/s38) || istype (O,/obj/item/ammo_magazine/s44)/* VOREstation Edit*/) // Prevents ammo recycling exploit with speedloaders.
|
||||
to_chat(user, "\The [O] is too hazardous to recycle with the autolathe!")
|
||||
return
|
||||
/* ToDo: Make this actually check for ammo and change the value of the magazine if it's empty. -Spades
|
||||
var/obj/item/ammo_magazine/speedloader = O
|
||||
if(speedloader.stored_ammo)
|
||||
to_chat(user, "\The [speedloader] is too hazardous to put back into the autolathe while there's ammunition inside of it!")
|
||||
return
|
||||
else
|
||||
speedloader.matter = list(DEFAULT_WALL_MATERIAL = 75) // It's just a hunk of scrap metal now.
|
||||
if(istype(O,/obj/item/ammo_magazine)) // This was just for immersion consistency with above.
|
||||
var/obj/item/ammo_magazine/mag = O
|
||||
if(mag.stored_ammo)
|
||||
to_chat(user, "\The [mag] is too hazardous to put back into the autolathe while there's ammunition inside of it!")
|
||||
return*/
|
||||
|
||||
//Resources are being loaded.
|
||||
var/obj/item/eating = O
|
||||
@@ -227,9 +207,9 @@
|
||||
user.set_machine(src)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/autolathe/Topic(href, href_list)
|
||||
/obj/machinery/autolathe/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return
|
||||
return TRUE
|
||||
|
||||
usr.set_machine(src)
|
||||
add_fingerprint(usr)
|
||||
@@ -237,72 +217,69 @@
|
||||
if(busy)
|
||||
to_chat(usr, "<span class='notice'>The autolathe is busy. Please wait for completion of previous operation.</span>")
|
||||
return
|
||||
switch(action)
|
||||
if("make")
|
||||
var/datum/category_item/autolathe/making = locate(params["make"])
|
||||
if(!istype(making))
|
||||
return
|
||||
if(making.hidden && !hacked)
|
||||
return
|
||||
|
||||
else if(href_list["setfilter"])
|
||||
var/filterstring = input(usr, "Input a filter string, or blank to not filter:", "Design Filter", filtertext) as null|text
|
||||
if(!Adjacent(usr))
|
||||
return
|
||||
if(isnull(filterstring)) //Clicked Cancel
|
||||
return
|
||||
if(filterstring == "") //Cleared value
|
||||
filtertext = null
|
||||
filtertext = sanitize(filterstring, 25)
|
||||
var/multiplier = 1
|
||||
|
||||
if(href_list["change_category"])
|
||||
if(making.is_stack)
|
||||
var/max_sheets
|
||||
for(var/material in making.resources)
|
||||
var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient
|
||||
var/sheets = round(stored_material[material]/round(making.resources[material]*coeff))
|
||||
if(isnull(max_sheets) || max_sheets > sheets)
|
||||
max_sheets = sheets
|
||||
if(!isnull(stored_material[material]) && stored_material[material] < round(making.resources[material]*coeff))
|
||||
max_sheets = 0
|
||||
//Build list of multipliers for sheets.
|
||||
multiplier = input(usr, "How many do you want to print? (0-[max_sheets])") as num|null
|
||||
if(!multiplier || multiplier <= 0 || multiplier > max_sheets || tgui_status(usr, state) != STATUS_INTERACTIVE)
|
||||
return FALSE
|
||||
|
||||
var/choice = input("Which category do you wish to display?") as null|anything in machine_recipes.categories
|
||||
if(!choice) return
|
||||
current_category = choice
|
||||
busy = making.name
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
|
||||
if(href_list["make"] && machine_recipes)
|
||||
var/multiplier = text2num(href_list["multiplier"])
|
||||
var/datum/category_item/autolathe/making = locate(href_list["make"]) in current_category.items
|
||||
//Check if we still have the materials.
|
||||
var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient
|
||||
for(var/material in making.resources)
|
||||
if(!isnull(stored_material[material]))
|
||||
if(stored_material[material] < round(making.resources[material] * coeff) * multiplier)
|
||||
return
|
||||
|
||||
//Exploit detection, not sure if necessary after rewrite.
|
||||
if(!making || multiplier < 0 || multiplier > 100)
|
||||
var/turf/exploit_loc = get_turf(usr)
|
||||
message_admins("[key_name_admin(usr)] tried to exploit an autolathe to duplicate an item! ([exploit_loc ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[exploit_loc.x];Y=[exploit_loc.y];Z=[exploit_loc.z]'>JMP</a>" : "null"])", 0)
|
||||
log_admin("EXPLOIT : [key_name(usr)] tried to exploit an autolathe to duplicate an item!")
|
||||
return
|
||||
//Consume materials.
|
||||
for(var/material in making.resources)
|
||||
if(!isnull(stored_material[material]))
|
||||
stored_material[material] = max(0, stored_material[material] - round(making.resources[material] * coeff) * multiplier)
|
||||
|
||||
busy = 1
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
update_icon() // So lid closes
|
||||
|
||||
//Check if we still have the materials.
|
||||
var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient
|
||||
for(var/material in making.resources)
|
||||
if(!isnull(stored_material[material]))
|
||||
if(stored_material[material] < round(making.resources[material] * coeff) * multiplier)
|
||||
return
|
||||
sleep(build_time)
|
||||
|
||||
//Consume materials.
|
||||
for(var/material in making.resources)
|
||||
if(!isnull(stored_material[material]))
|
||||
stored_material[material] = max(0, stored_material[material] - round(making.resources[material] * coeff) * multiplier)
|
||||
busy = 0
|
||||
update_use_power(USE_POWER_IDLE)
|
||||
update_icon() // So lid opens
|
||||
|
||||
update_icon() // So lid closes
|
||||
//Sanity check.
|
||||
if(!making || !src)
|
||||
return
|
||||
|
||||
sleep(build_time)
|
||||
|
||||
busy = 0
|
||||
update_use_power(USE_POWER_IDLE)
|
||||
update_icon() // So lid opens
|
||||
|
||||
//Sanity check.
|
||||
if(!making || !src) return
|
||||
|
||||
//Create the desired item.
|
||||
var/obj/item/I = new making.path(src.loc)
|
||||
flick("[initial(icon_state)]_finish", src)
|
||||
if(multiplier > 1)
|
||||
if(istype(I, /obj/item/stack))
|
||||
var/obj/item/stack/S = I
|
||||
S.amount = multiplier
|
||||
else
|
||||
for(multiplier; multiplier > 1; --multiplier) // Create multiple items if it's not a stack.
|
||||
new making.path(src.loc)
|
||||
|
||||
updateUsrDialog()
|
||||
//Create the desired item.
|
||||
var/obj/item/I = new making.path(src.loc)
|
||||
flick("[initial(icon_state)]_finish", src)
|
||||
if(multiplier > 1)
|
||||
if(istype(I, /obj/item/stack))
|
||||
var/obj/item/stack/S = I
|
||||
S.amount = multiplier
|
||||
else
|
||||
for(multiplier; multiplier > 1; --multiplier) // Create multiple items if it's not a stack.
|
||||
new making.path(src.loc)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/autolathe/update_icon()
|
||||
overlays.Cut()
|
||||
@@ -332,6 +309,7 @@
|
||||
storage_capacity["glass"] = mb_rating * 12500
|
||||
build_time = 50 / man_rating
|
||||
mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.6. Maximum rating of parts is 5
|
||||
update_tgui_static_data(usr)
|
||||
|
||||
/obj/machinery/autolathe/dismantle()
|
||||
for(var/mat in stored_material)
|
||||
@@ -345,3 +323,20 @@
|
||||
qdel(S)
|
||||
..()
|
||||
return 1
|
||||
|
||||
/obj/machinery/autolathe/proc/eject_materials(var/material, var/amount) // 0 amount = 0 means ejecting a full stack; -1 means eject everything
|
||||
var/recursive = amount == -1 ? 1 : 0
|
||||
var/matstring = lowertext(material)
|
||||
var/material/M = get_material_by_name(matstring)
|
||||
|
||||
var/obj/item/stack/material/S = M.place_sheet(get_turf(src))
|
||||
if(amount <= 0)
|
||||
amount = S.max_amount
|
||||
var/ejected = min(round(stored_material[matstring] / S.perunit), amount)
|
||||
S.amount = min(ejected, amount)
|
||||
if(S.amount <= 0)
|
||||
qdel(S)
|
||||
return
|
||||
stored_material[matstring] -= ejected * S.perunit
|
||||
if(recursive && stored_material[matstring] >= S.perunit)
|
||||
eject_materials(matstring, -1)
|
||||
|
||||
+178
-185
@@ -1,3 +1,17 @@
|
||||
// Use this define to register something as a creatable!
|
||||
// * n - The proper name of the purchasable
|
||||
// * o - The object type path of the purchasable to spawn
|
||||
// * r - The amount to dispense
|
||||
// * p - The price of the purchasable in biomass
|
||||
#define BIOGEN_ITEM(n, o, r, p) n = new /datum/data/biogenerator_item(n, o, r, p)
|
||||
|
||||
// Use this define to register something as dispensable
|
||||
// * n - The proper name of the purchasable
|
||||
// * o - The reagent ID
|
||||
// * r - The amount of reagent to dispense
|
||||
// * p - The price of the purchasable in biomass
|
||||
#define BIOGEN_REAGENT(n, o, r, p) n = new /datum/data/biogenerator_reagent(n, o, r, p)
|
||||
|
||||
/obj/machinery/biogenerator
|
||||
name = "biogenerator"
|
||||
desc = "Converts plants into biomass, which can be used for fertilizer and sort-of-synthetic products."
|
||||
@@ -11,10 +25,34 @@
|
||||
var/processing = 0
|
||||
var/obj/item/weapon/reagent_containers/glass/beaker = null
|
||||
var/points = 0
|
||||
var/menustat = "menu"
|
||||
var/build_eff = 1
|
||||
var/eat_eff = 1
|
||||
|
||||
var/list/item_list
|
||||
|
||||
|
||||
/datum/data/biogenerator_item
|
||||
var/equipment_path = null
|
||||
var/equipment_amt = 1
|
||||
var/cost = 0
|
||||
|
||||
/datum/data/biogenerator_item/New(name, path, amt, cost)
|
||||
src.name = name
|
||||
src.equipment_path = path
|
||||
src.equipment_amt = amt
|
||||
src.cost = cost
|
||||
|
||||
/datum/data/biogenerator_reagent
|
||||
var/reagent_id = null
|
||||
var/reagent_amt = 0
|
||||
var/cost = 0
|
||||
|
||||
/datum/data/biogenerator_reagent/New(name, id, amt, cost)
|
||||
src.name = name
|
||||
src.reagent_id = id
|
||||
src.reagent_amt = amt
|
||||
src.cost = cost
|
||||
|
||||
/obj/machinery/biogenerator/Initialize()
|
||||
. = ..()
|
||||
var/datum/reagents/R = new/datum/reagents(1000)
|
||||
@@ -24,6 +62,139 @@
|
||||
beaker = new /obj/item/weapon/reagent_containers/glass/bottle(src)
|
||||
default_apply_parts()
|
||||
|
||||
item_list = list()
|
||||
item_list["Food Items"] = list(
|
||||
BIOGEN_REAGENT("10 milk", "milk", 10, 20),
|
||||
BIOGEN_REAGENT("50 milk", "milk", 50, 95),
|
||||
BIOGEN_REAGENT("10 Cream", "cream", 10, 30),
|
||||
BIOGEN_REAGENT("50 Cream", "cream", 50, 120),
|
||||
BIOGEN_ITEM("Slab of meat", /obj/item/weapon/reagent_containers/food/snacks/meat, 1, 50),
|
||||
BIOGEN_ITEM("5 slabs of meat", /obj/item/weapon/reagent_containers/food/snacks/meat, 5, 250),
|
||||
)
|
||||
item_list["Cooking Ingredients"] = list(
|
||||
BIOGEN_REAGENT("10 Universal Enzyme", "enzyme", 10, 30),
|
||||
BIOGEN_REAGENT("50 Universal Enzyme", "enzyme", 50, 120),
|
||||
BIOGEN_ITEM("Nutri-spread", /obj/item/weapon/reagent_containers/food/snacks/spreads, 1, 30),
|
||||
BIOGEN_ITEM("5 nutri-spread", /obj/item/weapon/reagent_containers/food/snacks/spreads, 5, 120),
|
||||
)
|
||||
item_list["Gardening Nutrients"] = list(
|
||||
BIOGEN_ITEM("E-Z-Nutrient", /obj/item/weapon/reagent_containers/glass/bottle/eznutrient, 1, 60),
|
||||
BIOGEN_ITEM("5 E-Z-Nutrient", /obj/item/weapon/reagent_containers/glass/bottle/eznutrient, 5, 300),
|
||||
BIOGEN_ITEM("Left 4 Zed", /obj/item/weapon/reagent_containers/glass/bottle/left4zed, 1, 120),
|
||||
BIOGEN_ITEM("5 Left 4 Zed", /obj/item/weapon/reagent_containers/glass/bottle/left4zed, 5, 600),
|
||||
BIOGEN_ITEM("Robust Harvest", /obj/item/weapon/reagent_containers/glass/bottle/robustharvest, 1, 150),
|
||||
BIOGEN_ITEM("5 Robust Harvest", /obj/item/weapon/reagent_containers/glass/bottle/robustharvest, 5, 750),
|
||||
)
|
||||
item_list["Leather Products"] = list(
|
||||
BIOGEN_ITEM("Wallet", /obj/item/weapon/storage/wallet, 1, 100),
|
||||
BIOGEN_ITEM("Botanical gloves", /obj/item/clothing/gloves/botanic_leather, 1, 250),
|
||||
BIOGEN_ITEM("Plant bag", /obj/item/weapon/storage/bag/plants, 1, 320),
|
||||
BIOGEN_ITEM("Large plant bag", /obj/item/weapon/storage/bag/plants/large, 1, 640),
|
||||
BIOGEN_ITEM("Utility belt", /obj/item/weapon/storage/belt/utility, 1, 300),
|
||||
BIOGEN_ITEM("Leather Satchel", /obj/item/weapon/storage/backpack/satchel, 1, 400),
|
||||
BIOGEN_ITEM("Cash Bag", /obj/item/weapon/storage/bag/cash, 1, 400),
|
||||
BIOGEN_ITEM("Chemistry Bag", /obj/item/weapon/storage/bag/chemistry, 1, 400),
|
||||
BIOGEN_ITEM("Workboots", /obj/item/clothing/shoes/boots/workboots, 1, 400),
|
||||
BIOGEN_ITEM("Leather Chaps", /obj/item/clothing/under/pants/chaps, 1, 400),
|
||||
BIOGEN_ITEM("Leather Coat", /obj/item/clothing/suit/leathercoat, 1, 500),
|
||||
BIOGEN_ITEM("Leather Jacket", /obj/item/clothing/suit/storage/toggle/brown_jacket, 1, 500),
|
||||
BIOGEN_ITEM("Winter Coat", /obj/item/clothing/suit/storage/hooded/wintercoat, 1, 500),
|
||||
//VOREStation Edit - Algae for oxygen generator
|
||||
BIOGEN_ITEM("4 Algae Sheets", /obj/item/stack/material/algae, 4, 400),
|
||||
)
|
||||
|
||||
/obj/machinery/biogenerator/tgui_static_data(mob/user)
|
||||
var/list/static_data[0]
|
||||
|
||||
// Available items - in static data because we don't wanna compute this list every time! It hardly changes.
|
||||
static_data["items"] = list()
|
||||
for(var/cat in item_list)
|
||||
var/list/cat_items = list()
|
||||
for(var/prize_name in item_list[cat])
|
||||
var/datum/data/biogenerator_reagent/prize = item_list[cat][prize_name]
|
||||
cat_items[prize_name] = list("name" = prize_name, "price" = prize.cost, "reagent" = istype(prize))
|
||||
static_data["items"][cat] = cat_items
|
||||
|
||||
return static_data
|
||||
|
||||
/obj/machinery/biogenerator/tgui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
data["build_eff"] = build_eff
|
||||
data["points"] = points
|
||||
data["processing"] = processing
|
||||
data["beaker"] = !!beaker
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/biogenerator/tgui_interact(mob/user, datum/tgui/ui = null)
|
||||
// Open the window
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Biogenerator", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/biogenerator/tgui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("activate")
|
||||
INVOKE_ASYNC(src, .proc/activate)
|
||||
return TRUE
|
||||
if("detach")
|
||||
if(beaker)
|
||||
beaker.forceMove(loc)
|
||||
beaker = null
|
||||
update_icon()
|
||||
return TRUE
|
||||
if("purchase")
|
||||
var/category = params["cat"] // meow
|
||||
var/name = params["name"]
|
||||
|
||||
if(!(category in item_list) || !(name in item_list[category])) // Not trying something that's not in the list, are you?
|
||||
return
|
||||
|
||||
var/datum/data/biogenerator_item/bi = item_list[category][name]
|
||||
if(!istype(bi))
|
||||
var/datum/data/biogenerator_reagent/br = item_list[category][name]
|
||||
if(!istype(br))
|
||||
return
|
||||
if(!beaker)
|
||||
return
|
||||
var/cost = round(br.cost / build_eff)
|
||||
if(cost > points)
|
||||
to_chat(usr, "<span class='danger'>Insufficient biomass.</span>")
|
||||
return
|
||||
var/amt_to_actually_dispense = round(min(beaker.reagents.get_free_space(), br.reagent_amt))
|
||||
if(amt_to_actually_dispense <= 0)
|
||||
to_chat(usr, "<span class='danger'>The loaded beaker is full!</span>")
|
||||
return
|
||||
points -= (cost * (amt_to_actually_dispense / br.reagent_amt))
|
||||
beaker.reagents.add_reagent(br.reagent_id, amt_to_actually_dispense)
|
||||
playsound(src, 'sound/machines/reagent_dispense.ogg', 25, 1)
|
||||
return
|
||||
|
||||
var/cost = round(bi.cost / build_eff)
|
||||
if(cost > points)
|
||||
to_chat(usr, "<span class='danger'>Insufficient biomass.</span>")
|
||||
return
|
||||
|
||||
points -= cost
|
||||
if(ispath(bi.equipment_path, /obj/item/stack))
|
||||
var/obj/item/stack/S = new bi.equipment_path(loc)
|
||||
S.amount = bi.equipment_amt
|
||||
playsound(src, 'sound/machines/vending/vending_drop.ogg', 100, 1)
|
||||
return TRUE
|
||||
|
||||
for(var/i in 1 to bi.equipment_amt)
|
||||
new bi.equipment_path(loc)
|
||||
playsound(src, 'sound/machines/vending/vending_drop.ogg', 100, 1)
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/biogenerator/on_reagent_change() //When the reagents change, change the icon as well.
|
||||
update_icon()
|
||||
|
||||
@@ -87,68 +258,10 @@
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/biogenerator/interact(mob/user as mob)
|
||||
/obj/machinery/biogenerator/attack_hand(mob/user as mob)
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<TITLE>Biogenerator</TITLE>Biogenerator:<BR>"
|
||||
if(processing)
|
||||
dat += "<FONT COLOR=red>Biogenerator is processing! Please wait...</FONT>"
|
||||
else
|
||||
dat += "Biomass: [points] points.<HR>"
|
||||
switch(menustat)
|
||||
if("menu")
|
||||
if(beaker)
|
||||
dat += "<A href='?src=\ref[src];action=activate'>Activate Biogenerator!</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=detach'>Detach Container</A><BR><BR>"
|
||||
dat += "Food Items:<BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=milk;cost=20'>10 milk</A> <FONT COLOR=blue>([round(20/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=milk5;cost=95'>x5</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=cream;cost=30'>10 cream</A> <FONT COLOR=blue>([round(20/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=cream5;cost=120'>x5</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=meat;cost=50'>Slab of meat</A> <FONT COLOR=blue>([round(50/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=meat5;cost=250'>x5</A><BR>"
|
||||
dat += "Cooking Ingredient:<BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=unizyme;cost=30'>Universal Enzyme</A> <FONT COLOR=yellow>([round(30/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=unizyme50;cost=120'>x5</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=nutrispread;cost=30'>Nutri-Spread</A> <FONT COLOR=yellow>([round(30/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=nutrispread5;cost=120'>x5</A><BR>"
|
||||
// dat += "<A href='?src=\ref[src];action=create;item=unizyme;cost=50'>Universal Enzyme</A> <FONT COLOR=yellow>([round(30/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=unizyme;cost=180'>x5</A><BR>"
|
||||
// dat += "<A href='?src=\ref[src];action=create;item=unizyme;cost=50'>Universal Enzyme</A> <FONT COLOR=yellow>([round(30/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=unizyme;cost=180'>x5</A><BR>"
|
||||
dat += "Gardening Nutrients:<BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=ez;cost=60'>E-Z-Nutrient</A> <FONT COLOR=green>([round(60/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=ez5;cost=300'>x5</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=l4z;cost=120'>Left 4 Zed</A> <FONT COLOR=green>([round(120/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=l4z5;cost=600'>x5</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=rh;cost=150'>Robust Harvest</A> <FONT COLOR=green>([round(150/build_eff)])</FONT> | <A href='?src=\ref[src];action=create;item=rh5;cost=750'>x5</A><BR>"
|
||||
dat += "Leather Products:<BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=wallet;cost=100'>Wallet</A> <FONT COLOR=brown>([round(100/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=gloves;cost=250'>Botanical gloves</A> <FONT COLOR=green>([round(250/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=plantbag;cost=320'>Plant bag</A> <FONT COLOR=green>([round(250/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=plantbaglarge;cost=640'>Large plant bag</A> <FONT COLOR=green>([round(250/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=tbelt;cost=300'>Utility belt</A> <FONT COLOR=brown>([round(300/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=satchel;cost=400'>Leather Satchel</A> <FONT COLOR=brown>([round(400/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=cashbag;cost=400'>Cash Bag</A> <FONT COLOR=brown>([round(400/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=chembag;cost=400'>Chemistry Bag</A> <FONT COLOR=green>([round(400/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=workboots;cost=400'>Workboots</A> <FONT COLOR=brown>([round(400/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=leathershoes;cost=400'>Leather Shoes</A> <FONT COLOR=brown>([round(400/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=leatherchaps;cost=400'>Leather Chaps</A> <FONT COLOR=brown>([round(400/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=leathercoat;cost=500'>Leather Coat</A> <FONT COLOR=brown>([round(500/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=leatherjacket;cost=500'>Leather Jacket</A> <FONT COLOR=brown>([round(500/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=wintercoat;cost=500'>Winter Coat</A> <FONT COLOR=brown>([round(500/build_eff)])</FONT><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=create;item=algae;cost=400'>4 Algae Sheets</A> <FONT COLOR=green>([round(400/build_eff)])</FONT><BR>" //VOREStation Edit - Algae for oxygen generator
|
||||
//dat += "Other<BR>"
|
||||
//dat += "<A href='?src=\ref[src];action=create;item=monkey;cost=500'>Monkey</A> <FONT COLOR=blue>(500)</FONT><BR>"
|
||||
else
|
||||
dat += "<BR><FONT COLOR=red>No beaker inside. Please insert a beaker.</FONT><BR>"
|
||||
if("nopoints")
|
||||
dat += "You do not have biomass to create products.<BR>Please, put growns into reactor and activate it.<BR>"
|
||||
dat += "<A href='?src=\ref[src];action=menu'>Return to menu</A>"
|
||||
if("complete")
|
||||
dat += "Operation complete.<BR>"
|
||||
dat += "<A href='?src=\ref[src];action=menu'>Return to menu</A>"
|
||||
if("void")
|
||||
dat += "<FONT COLOR=red>Error: No growns inside.</FONT><BR>Please, put growns into reactor.<BR>"
|
||||
dat += "<A href='?src=\ref[src];action=menu'>Return to menu</A>"
|
||||
user << browse(dat, "window=biogenerator")
|
||||
onclose(user, "biogenerator")
|
||||
return
|
||||
|
||||
/obj/machinery/biogenerator/attack_hand(mob/user as mob)
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/biogenerator/proc/activate()
|
||||
if(usr.stat)
|
||||
@@ -168,139 +281,17 @@
|
||||
if(S)
|
||||
processing = 1
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
playsound(src, 'sound/machines/blender.ogg', 40, 1)
|
||||
use_power(S * 30)
|
||||
sleep((S + 15) / eat_eff)
|
||||
processing = 0
|
||||
SStgui.update_uis(src)
|
||||
playsound(src, 'sound/machines/biogenerator_end.ogg', 40, 1)
|
||||
update_icon()
|
||||
else
|
||||
menustat = "void"
|
||||
to_chat(usr, "<span class='warning'>Error: No growns inside. Please insert growns.</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/biogenerator/proc/create_product(var/item, var/cost)
|
||||
cost = round(cost/build_eff)
|
||||
if(cost > points)
|
||||
menustat = "nopoints"
|
||||
return 0
|
||||
processing = 1
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
points -= cost
|
||||
sleep(30)
|
||||
switch(item)
|
||||
if("milk")
|
||||
beaker.reagents.add_reagent("milk", 10)
|
||||
if("milk5")
|
||||
beaker.reagents.add_reagent("milk", 50)
|
||||
if("cream")
|
||||
beaker.reagents.add_reagent("cream", 10)
|
||||
if("cream5")
|
||||
beaker.reagents.add_reagent("cream", 50)
|
||||
if("meat")
|
||||
new/obj/item/weapon/reagent_containers/food/snacks/meat(loc)
|
||||
if("meat5")
|
||||
new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) //This is ugly.
|
||||
new/obj/item/weapon/reagent_containers/food/snacks/meat(loc)
|
||||
new/obj/item/weapon/reagent_containers/food/snacks/meat(loc)
|
||||
new/obj/item/weapon/reagent_containers/food/snacks/meat(loc)
|
||||
new/obj/item/weapon/reagent_containers/food/snacks/meat(loc)
|
||||
if("unizyme")
|
||||
beaker.reagents.add_reagent("enzyme", 10)
|
||||
if("unizyme50")
|
||||
beaker.reagents.add_reagent("enzyme", 50)
|
||||
if("nutrispread")
|
||||
new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc)
|
||||
if("nutrispread5")
|
||||
new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc)
|
||||
new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc)
|
||||
new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc)
|
||||
new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc)
|
||||
new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc)
|
||||
if("ez")
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc)
|
||||
if("l4z")
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc)
|
||||
if("rh")
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc)
|
||||
if("ez5") //It's not an elegant method, but it's safe and easy. -Cheridan
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc)
|
||||
if("l4z5")
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/left4zed(loc)
|
||||
if("rh5")
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc)
|
||||
new/obj/item/weapon/reagent_containers/glass/bottle/robustharvest(loc)
|
||||
if("wallet")
|
||||
new/obj/item/weapon/storage/wallet(loc)
|
||||
if("gloves")
|
||||
new/obj/item/clothing/gloves/botanic_leather(loc)
|
||||
if("plantbag")
|
||||
new/obj/item/weapon/storage/bag/plants(loc)
|
||||
if("plantbaglarge")
|
||||
new/obj/item/weapon/storage/bag/plants/large(loc)
|
||||
if("tbelt")
|
||||
new/obj/item/weapon/storage/belt/utility(loc)
|
||||
if("satchel")
|
||||
new/obj/item/weapon/storage/backpack/satchel(loc)
|
||||
if("cashbag")
|
||||
new/obj/item/weapon/storage/bag/cash(loc)
|
||||
if("chembag")
|
||||
new/obj/item/weapon/storage/bag/chemistry(loc)
|
||||
if("monkey")
|
||||
new/mob/living/carbon/human/monkey(loc)
|
||||
if("workboots")
|
||||
new/obj/item/clothing/shoes/boots/workboots(loc)
|
||||
if("leathershoes")
|
||||
new/obj/item/clothing/shoes/leather(loc)
|
||||
if("leatherchaps")
|
||||
new/obj/item/clothing/under/pants/chaps
|
||||
if("leathercoat")
|
||||
new/obj/item/clothing/suit/leathercoat(loc)
|
||||
if("leatherjacket")
|
||||
new/obj/item/clothing/suit/storage/toggle/brown_jacket(loc)
|
||||
if("wintercoat")
|
||||
new/obj/item/clothing/suit/storage/hooded/wintercoat(loc)
|
||||
if("algae") //VOREStation Edit - Algae for oxygen generator
|
||||
var/obj/item/stack/material/algae/A = new(loc)
|
||||
A.amount = 4 //VOREStation Edit End
|
||||
processing = 0
|
||||
menustat = "complete"
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/machinery/biogenerator/Topic(href, href_list)
|
||||
if(stat & BROKEN) return
|
||||
if(usr.stat || usr.restrained()) return
|
||||
if(!in_range(src, usr)) return
|
||||
|
||||
usr.set_machine(src)
|
||||
|
||||
switch(href_list["action"])
|
||||
if("activate")
|
||||
activate()
|
||||
if("detach")
|
||||
if(beaker)
|
||||
beaker.loc = src.loc
|
||||
beaker = null
|
||||
update_icon()
|
||||
if("create")
|
||||
create_product(href_list["item"], text2num(href_list["cost"]))
|
||||
if("menu")
|
||||
menustat = "menu"
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/biogenerator/RefreshParts()
|
||||
..()
|
||||
var/man_rating = 0
|
||||
@@ -314,3 +305,5 @@
|
||||
|
||||
build_eff = man_rating
|
||||
eat_eff = bin_rating
|
||||
|
||||
#undef BIOGENITEM
|
||||
|
||||
@@ -101,137 +101,128 @@
|
||||
else
|
||||
tank2 = I
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
SStgui.update_uis(src)
|
||||
to_chat(user, "<span class='notice'>You connect \the [I] to \the [src]'s [I==tank1 ? "primary" : "secondary"] slot.</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/machinery/bomb_tester/attack_hand(var/mob/user)
|
||||
add_fingerprint(user)
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/bomb_tester/interact(var/mob/user)
|
||||
if(stat & NOPOWER)
|
||||
return
|
||||
/obj/machinery/bomb_tester/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "BombTester", name)
|
||||
ui.open()
|
||||
|
||||
var/dat = "<HEAD><TITLE>Bomb Tester</TITLE></HEAD>"
|
||||
/obj/machinery/bomb_tester/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["simulating"] = simulating
|
||||
if(!simulating)
|
||||
data["mode"] = sim_mode
|
||||
data["tank1"] = tank1
|
||||
data["tank1ref"] = REF(tank1)
|
||||
data["tank2"] = tank2
|
||||
data["tank2ref"] = REF(tank2)
|
||||
data["canister"] = test_canister
|
||||
data["sim_canister_output"] = sim_canister_output
|
||||
|
||||
return data
|
||||
|
||||
dat += "<font face='terminal' size ='3'>Virtual Explosive Simulator v1.03</font>"
|
||||
dat += "<br>"
|
||||
|
||||
if(simulating)
|
||||
dat += "<br><center>Simulation in progress! Please wait for results.</center>"
|
||||
|
||||
else
|
||||
dat += "<br><center>Mode: [sim_mode==MODE_SINGLE?"Single Tank":"<A href='?src=\ref[src];set_mode=1'>Single Tank</a>"] -- [sim_mode==MODE_DOUBLE?"Transfer Valve":"<A href='?src=\ref[src];set_mode=2'>Transfer Valve</a>"] -- [sim_mode==MODE_CANISTER?"Canister":"<A href='?src=\ref[src];set_mode=3'>Canister</a>"]</center>"
|
||||
dat += "<br>"
|
||||
dat += "<br><center><u>Gas Sources</u></center>"
|
||||
dat += "<br><center><A href='?src=\ref[src];tank=1'>[tank1?"\[[tank1.name]\]":"\[Primary Slot\]"]</a> -- <A href='?src=\ref[src];tank=2'>[tank2?"\[[tank2.name]\]":"\[Secondary Slot\]"]</a></center>"
|
||||
dat += "<br><center>Connected Canister: [test_canister?"[test_canister.name] -- ":"None -- "]<A href='?src=\ref[src];canister_scan=1'>[test_canister?"\[Rescan\]":"\[Scan for canister\]"]</a></center>"
|
||||
if(test_canister)
|
||||
dat += "<br><center>Canister Release Pressure: [sim_canister_output] Kilopascals</center>"
|
||||
|
||||
dat += "<br><center>"
|
||||
dat += "<A href='?src=\ref[src];set_can_pressure=-1000'>-1000</a>|"
|
||||
dat += "<A href='?src=\ref[src];set_can_pressure=-100'>-100</a>|"
|
||||
dat += "<A href='?src=\ref[src];set_can_pressure=-10'>-10</a>|"
|
||||
dat += "<A href='?src=\ref[src];set_can_pressure=-1'>-1</a> ||| "
|
||||
|
||||
dat += "<A href='?src=\ref[src];set_can_pressure=1'>+1</a>|"
|
||||
dat += "<A href='?src=\ref[src];set_can_pressure=10'>+10</a>|"
|
||||
dat += "<A href='?src=\ref[src];set_can_pressure=100'>+100</a>|"
|
||||
dat += "<A href='?src=\ref[src];set_can_pressure=1000'>+1000</a>"
|
||||
dat += "</center>"
|
||||
|
||||
dat += "<br><br>"
|
||||
dat += "<br><center><font size='6'><b><A href='?src=\ref[src];start_sim=1'>BEGIN SIMULATION</a></b></font></center>"
|
||||
|
||||
user.set_machine(src)
|
||||
user << browse(dat, "window=bomb_tester")
|
||||
onclose(user, "bomb_tester")
|
||||
|
||||
/obj/machinery/bomb_tester/Topic(href, href_list)
|
||||
/obj/machinery/bomb_tester/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return
|
||||
if(stat & NOPOWER)
|
||||
return
|
||||
if(!usr.Adjacent(src))
|
||||
usr << browse(null, "window=bomb_tester")
|
||||
usr.unset_machine()
|
||||
return
|
||||
return TRUE
|
||||
|
||||
if(simulating)
|
||||
return
|
||||
|
||||
if(href_list["set_mode"])
|
||||
sim_mode = text2num(href_list["set_mode"])
|
||||
var/text_mode
|
||||
switch(sim_mode)
|
||||
if(MODE_SINGLE)
|
||||
text_mode = "single gas tank detonation"
|
||||
if(MODE_DOUBLE)
|
||||
text_mode = "tank transfer valve detonation"
|
||||
if(MODE_CANISTER)
|
||||
text_mode = "canister-assisted single gas tank detonation"
|
||||
to_chat(usr, "<span class='notice'>[src] set to simulate a [text_mode].</span>")
|
||||
|
||||
if(href_list["tank"])
|
||||
var/tankvar = "tank[href_list["tank"]]"
|
||||
var/obj/item/weapon/tank/T
|
||||
if(vars[tankvar])
|
||||
T = vars[tankvar]
|
||||
T.forceMove(get_turf(src))
|
||||
vars[tankvar] = null
|
||||
else if(istype(usr.get_active_hand(),/obj/item/weapon/tank))
|
||||
T = usr.get_active_hand()
|
||||
usr.drop_item(T)
|
||||
T.forceMove(src)
|
||||
vars[tankvar] = T
|
||||
update_icon()
|
||||
|
||||
if(href_list["canister_scan"])
|
||||
for(var/obj/machinery/portable_atmospherics/canister/C in orange(1,src))
|
||||
if(C && C == test_canister)
|
||||
continue
|
||||
else if(C)
|
||||
test_canister = C
|
||||
break
|
||||
switch(action)
|
||||
if("set_mode")
|
||||
sim_mode = clamp(text2num(params["mode"]), MODE_SINGLE, MODE_CANISTER)
|
||||
var/text_mode
|
||||
switch(sim_mode)
|
||||
if(MODE_SINGLE)
|
||||
text_mode = "single gas tank detonation"
|
||||
if(MODE_DOUBLE)
|
||||
text_mode = "tank transfer valve detonation"
|
||||
if(MODE_CANISTER)
|
||||
text_mode = "canister-assisted single gas tank detonation"
|
||||
to_chat(usr, "<span class='notice'>[src] set to simulate a [text_mode].</span>")
|
||||
return TRUE
|
||||
|
||||
if("add_tank")
|
||||
if(istype(usr.get_active_hand(), /obj/item/weapon/tank))
|
||||
var/obj/item/weapon/tank/T = usr.get_active_hand()
|
||||
var/slot = params["slot"]
|
||||
if(slot == 1 && !tank1)
|
||||
tank1 = T
|
||||
else if(slot == 2 && !tank2)
|
||||
tank2 = T
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Slot [slot] is full.</span>")
|
||||
return
|
||||
|
||||
usr.drop_item(T)
|
||||
T.forceMove(src)
|
||||
return TRUE
|
||||
else
|
||||
test_canister = null
|
||||
to_chat(usr, "<span class='warning'>You must be wielding a tank to insert it!</span>")
|
||||
|
||||
if(href_list["set_can_pressure"])
|
||||
var/change = text2num(href_list["set_can_pressure"])
|
||||
sim_canister_output = CLAMP(sim_canister_output+change, ONE_ATMOSPHERE/10, ONE_ATMOSPHERE*10)
|
||||
if("remove_tank")
|
||||
var/obj/item/weapon/tank/T = locate(params["ref"]) in list(tank1, tank2)
|
||||
if(istype(T))
|
||||
if(T == tank1)
|
||||
tank1 = null
|
||||
if(T == tank2)
|
||||
tank2 = null
|
||||
T.forceMove(get_turf(src))
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
if(href_list["start_sim"])
|
||||
start_simulating()
|
||||
if("canister_scan")
|
||||
for(var/obj/machinery/portable_atmospherics/canister/C in orange(1,src))
|
||||
if(C && C == test_canister)
|
||||
continue
|
||||
else if(C)
|
||||
test_canister = C
|
||||
break
|
||||
else
|
||||
test_canister = null
|
||||
return TRUE
|
||||
|
||||
updateUsrDialog()
|
||||
if("set_can_pressure")
|
||||
sim_canister_output = CLAMP(text2num(params["pressure"]), ONE_ATMOSPHERE/10, ONE_ATMOSPHERE*10)
|
||||
return TRUE
|
||||
|
||||
if("start_sim")
|
||||
start_simulating()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/bomb_tester/proc/start_simulating()
|
||||
if(!tank1 || (sim_mode == MODE_DOUBLE && !tank2) || (sim_mode == MODE_CANISTER && !test_canister))
|
||||
simulation_results = "Error"
|
||||
simulation_finish()
|
||||
return
|
||||
if((tank1?.air_contents.return_pressure() > TANK_RUPTURE_PRESSURE) || (tank2?.air_contents.return_pressure() > TANK_RUPTURE_PRESSURE))
|
||||
simulation_results = "Unstable"
|
||||
simulation_finish()
|
||||
return
|
||||
simulating = 1
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
simulation_started = world.time
|
||||
update_icon()
|
||||
switch(sim_mode)
|
||||
if(MODE_SINGLE)
|
||||
if(!tank1)
|
||||
simulation_results = "Error"
|
||||
return
|
||||
spawn()
|
||||
single_tank_sim()
|
||||
|
||||
if(MODE_DOUBLE)
|
||||
if(!tank1 || !tank2)
|
||||
simulation_results = "Error"
|
||||
return
|
||||
spawn()
|
||||
ttv_sim()
|
||||
|
||||
if(MODE_CANISTER)
|
||||
if(!tank1 || !test_canister)
|
||||
simulation_results = "Error"
|
||||
return
|
||||
spawn()
|
||||
canister_sim()
|
||||
|
||||
@@ -361,9 +352,12 @@
|
||||
if(simulation_results == "Error")
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
state("Invalid parameters.")
|
||||
else if(simulation_results == "Unstable")
|
||||
playsound(src, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
state("Tank instability detected. Please step away from the device.")
|
||||
else
|
||||
ping("Simulation complete!")
|
||||
playsound(src, "sound/effects/printer.ogg", 50, 1)
|
||||
playsound(src, "sound/machines/printer.ogg", 50, 1)
|
||||
var/obj/item/weapon/paper/P = new(get_turf(src))
|
||||
P.name = "Explosive Simulator printout"
|
||||
P.info = simulation_results
|
||||
@@ -383,4 +377,4 @@
|
||||
|
||||
#undef MODE_SINGLE
|
||||
#undef MODE_DOUBLE
|
||||
#undef MODE_CANISTER
|
||||
#undef MODE_CANISTER
|
||||
|
||||
@@ -205,7 +205,7 @@
|
||||
return
|
||||
|
||||
else if((occupant.health >= heal_level || occupant.health == occupant.getMaxHealth()) && (!eject_wait))
|
||||
playsound(src, 'sound/machines/ding.ogg', 50, 1)
|
||||
playsound(src, 'sound/machines/medbayscanner1.ogg', 50, 1)
|
||||
audible_message("\The [src] signals that the cloning process is complete.")
|
||||
connected_message("Cloning Process Complete.")
|
||||
locked = 0
|
||||
|
||||
@@ -342,6 +342,7 @@
|
||||
cloneresult = pod.growclone(C)
|
||||
if(cloneresult)
|
||||
set_temp("Initiating cloning cycle...", "success")
|
||||
playsound(src, 'sound/machines/medbayscanner1.ogg', 100, 1)
|
||||
records.Remove(C)
|
||||
qdel(C)
|
||||
menu = MENU_MAIN
|
||||
|
||||
@@ -6,162 +6,225 @@
|
||||
light_color = "#a97faa"
|
||||
req_access = list(access_robotics)
|
||||
circuit = /obj/item/weapon/circuitboard/robotics
|
||||
var/safety = 1
|
||||
|
||||
/obj/machinery/computer/robotics/attack_ai(var/mob/user as mob)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/robotics/attack_hand(var/mob/user as mob)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/robotics/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
data["robots"] = get_cyborgs(user)
|
||||
data["is_ai"] = issilicon(user)
|
||||
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "robot_control.tmpl", "Robotic Control Console", 400, 500)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/computer/robotics/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
var/mob/user = usr
|
||||
if(!src.allowed(user))
|
||||
to_chat(user, "Access Denied")
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
tgui_interact(user)
|
||||
|
||||
// Locks or unlocks the cyborg
|
||||
if (href_list["lockdown"])
|
||||
var/mob/living/silicon/robot/target = get_cyborg_by_name(href_list["lockdown"])
|
||||
var/failmsg = ""
|
||||
if(!target || !istype(target))
|
||||
return
|
||||
/obj/machinery/computer/robotics/proc/is_authenticated(mob/user)
|
||||
if(!istype(user))
|
||||
return FALSE
|
||||
if(isobserver(user))
|
||||
var/mob/observer/dead/D = user
|
||||
if(D.can_admin_interact())
|
||||
return TRUE
|
||||
if(allowed(user))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
if(isAI(user) && (target.connected_ai != user))
|
||||
to_chat(user, "Access Denied. This robot is not linked to you.")
|
||||
return
|
||||
/**
|
||||
* Does this borg show up in the console
|
||||
*
|
||||
* Returns TRUE if a robot will show up in the console
|
||||
* Returns FALSE if a robot will not show up in the console
|
||||
* Arguments:
|
||||
* * R - The [mob/living/silicon/robot] to be checked
|
||||
*/
|
||||
/obj/machinery/computer/robotics/proc/console_shows(mob/living/silicon/robot/R)
|
||||
if(!istype(R))
|
||||
return FALSE
|
||||
if(istype(R, /mob/living/silicon/robot/drone))
|
||||
return FALSE
|
||||
if(R.scrambledcodes)
|
||||
return FALSE
|
||||
if(!AreConnectedZLevels(get_z(src), get_z(R)))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
if(isrobot(user))
|
||||
to_chat(user, "Access Denied.")
|
||||
return
|
||||
/**
|
||||
* Check if a user can send a lockdown/detonate command to a specific borg
|
||||
*
|
||||
* Returns TRUE if a user can send the command (does not guarantee it will work)
|
||||
* Returns FALSE if a user cannot
|
||||
* Arguments:
|
||||
* * user - The [mob/user] to be checked
|
||||
* * R - The [mob/living/silicon/robot] to be checked
|
||||
* * telluserwhy - Bool of whether the user should be sent a to_chat message if they don't have access
|
||||
*/
|
||||
/obj/machinery/computer/robotics/proc/can_control(mob/user, mob/living/silicon/robot/R, telluserwhy = FALSE)
|
||||
if(!istype(user))
|
||||
return FALSE
|
||||
if(!console_shows(R))
|
||||
return FALSE
|
||||
if(isAI(user))
|
||||
if(R.connected_ai != user)
|
||||
if(telluserwhy)
|
||||
to_chat(user, "<span class='warning'>AIs can only control cyborgs which are linked to them.</span>")
|
||||
return FALSE
|
||||
if(isrobot(user))
|
||||
if(R != user)
|
||||
if(telluserwhy)
|
||||
to_chat(user, "<span class='warning'>Cyborgs cannot control other cyborgs.</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
var/choice = input("Really [target.lockcharge ? "unlock" : "lockdown"] [target.name] ?") in list ("Yes", "No")
|
||||
if(choice != "Yes")
|
||||
return
|
||||
/**
|
||||
* Check if the user is the right kind of entity to be able to hack borgs
|
||||
*
|
||||
* Returns TRUE if a user is a traitor AI, or aghost
|
||||
* Returns FALSE otherwise
|
||||
* Arguments:
|
||||
* * user - The [mob/user] to be checked
|
||||
*/
|
||||
/obj/machinery/computer/robotics/proc/can_hack_any(mob/user)
|
||||
if(!istype(user))
|
||||
return FALSE
|
||||
if(isobserver(user))
|
||||
var/mob/observer/dead/D = user
|
||||
if(D.can_admin_interact())
|
||||
return TRUE
|
||||
if(!isAI(user))
|
||||
return FALSE
|
||||
return (user.mind.special_role && user.mind.original == user)
|
||||
|
||||
if(!target || !istype(target))
|
||||
return
|
||||
|
||||
var/istraitor = target.mind.special_role
|
||||
if (istraitor)
|
||||
failmsg = "failed (target is traitor) "
|
||||
target.lockcharge = !target.lockcharge
|
||||
if (target.lockcharge)
|
||||
to_chat(target, "Someone tried to lock you down!")
|
||||
else
|
||||
to_chat(target, "Someone tried to lift your lockdown!")
|
||||
else if (target.emagged)
|
||||
failmsg = "failed (target is hacked) "
|
||||
target.lockcharge = !target.lockcharge
|
||||
if (target.lockcharge)
|
||||
to_chat(target, "Someone tried to lock you down!")
|
||||
else
|
||||
to_chat(target, "Someone tried to lift your lockdown!")
|
||||
else
|
||||
target.canmove = !target.canmove
|
||||
target.lockcharge = !target.canmove //when canmove is 1, lockcharge should be 0
|
||||
target.lockdown = !target.canmove
|
||||
if (target.lockcharge)
|
||||
to_chat(target, "You have been locked down!")
|
||||
else
|
||||
to_chat(target, "Your lockdown has been lifted!")
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] [failmsg][target.lockcharge ? "lockdown" : "release"] on [target.name]!</span>")
|
||||
log_game("[key_name(usr)] attempted to [target.lockcharge ? "lockdown" : "release"] [target.name] on the robotics console!")
|
||||
/**
|
||||
* Check if the user is allowed to hack a specific borg
|
||||
*
|
||||
* Returns TRUE if a user can hack the specific cyborg
|
||||
* Returns FALSE if a user cannot
|
||||
* Arguments:
|
||||
* * user - The [mob/user] to be checked
|
||||
* * R - The [mob/living/silicon/robot] to be checked
|
||||
*/
|
||||
/obj/machinery/computer/robotics/proc/can_hack(mob/user, mob/living/silicon/robot/R)
|
||||
if(!can_hack_any(user))
|
||||
return FALSE
|
||||
if(!istype(R))
|
||||
return FALSE
|
||||
if(R.emagged)
|
||||
return FALSE
|
||||
if(R.connected_ai != user)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
// Remotely hacks the cyborg. Only antag AIs can do this and only to linked cyborgs.
|
||||
else if (href_list["hack"])
|
||||
var/mob/living/silicon/robot/target = get_cyborg_by_name(href_list["hack"])
|
||||
if(!target || !istype(target))
|
||||
return
|
||||
|
||||
// Antag synthetic checks
|
||||
if(!istype(user, /mob/living/silicon) || !(user.mind.special_role && user.mind.original == user))
|
||||
to_chat(user, "Access Denied")
|
||||
return
|
||||
|
||||
if(target.emagged)
|
||||
to_chat(user, "Robot is already hacked.")
|
||||
return
|
||||
|
||||
var/choice = input("Really hack [target.name]? This cannot be undone.") in list("Yes", "No")
|
||||
if(choice != "Yes")
|
||||
return
|
||||
|
||||
if(!target || !istype(target))
|
||||
return
|
||||
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] emagged [target.name] using the robotic console!</span>")
|
||||
log_game("[key_name(usr)] emagged [target.name] using robotic console!")
|
||||
target.emagged = 1
|
||||
to_chat(target, "<span class='notice'>Failsafe protocols overriden. New tools available.</span>")
|
||||
|
||||
|
||||
// Proc: get_cyborgs()
|
||||
// Parameters: 1 (operator - mob which is operating the console.)
|
||||
// Description: Returns NanoUI-friendly list of accessible cyborgs.
|
||||
/obj/machinery/computer/robotics/proc/get_cyborgs(var/mob/operator)
|
||||
var/list/robots = list()
|
||||
/obj/machinery/computer/robotics/tgui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "RoboticsControlConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/robotics/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["auth"] = is_authenticated(user)
|
||||
data["can_hack"] = can_hack_any(user)
|
||||
data["cyborgs"] = list()
|
||||
data["safety"] = safety
|
||||
for(var/mob/living/silicon/robot/R in mob_list)
|
||||
// Ignore drones
|
||||
if(istype(R, /mob/living/silicon/robot/drone))
|
||||
continue
|
||||
// Ignore antagonistic cyborgs
|
||||
if(R.scrambledcodes)
|
||||
if(!console_shows(R))
|
||||
continue
|
||||
var/area/A = get_area(R)
|
||||
var/turf/T = get_turf(R)
|
||||
var/list/cyborg_data = list(
|
||||
name = R.name,
|
||||
ref = REF(R),
|
||||
locked_down = R.lockcharge,
|
||||
locstring = "[A.name] ([T.x], [T.y])",
|
||||
status = R.stat,
|
||||
health = round(R.health * 100 / R.maxHealth, 0.1),
|
||||
charge = R.cell ? round(R.cell.percent()) : null,
|
||||
cell_capacity = R.cell ? R.cell.maxcharge : null,
|
||||
module = R.module ? R.module.name : "No Module Detected",
|
||||
synchronization = R.connected_ai,
|
||||
is_hacked = R.connected_ai && R.emagged,
|
||||
hackable = can_hack(user, R),
|
||||
)
|
||||
data["cyborgs"] += list(cyborg_data)
|
||||
data["show_detonate_all"] = (data["auth"] && length(data["cyborgs"]) > 0 && ishuman(user))
|
||||
return data
|
||||
|
||||
var/list/robot = list()
|
||||
robot["name"] = R.name
|
||||
if(R.stat)
|
||||
robot["status"] = "Not Responding"
|
||||
else if (R.lockcharge)
|
||||
robot["status"] = "Lockdown"
|
||||
else
|
||||
robot["status"] = "Operational"
|
||||
|
||||
if(R.cell)
|
||||
robot["cell"] = 1
|
||||
robot["cell_capacity"] = R.cell.maxcharge
|
||||
robot["cell_current"] = R.cell.charge
|
||||
robot["cell_percentage"] = round(R.cell.percent())
|
||||
else
|
||||
robot["cell"] = 0
|
||||
|
||||
robot["module"] = R.module ? R.module.name : "None"
|
||||
robot["master_ai"] = R.connected_ai ? R.connected_ai.name : "None"
|
||||
robot["hackable"] = 0
|
||||
//Antag synths should be able to hack themselves and see their hacked status.
|
||||
if(operator && isrobot(operator) && (operator.mind.special_role && operator.mind.original == operator) && (operator == R))
|
||||
robot["hacked"] = R.emagged ? 1 : 0
|
||||
robot["hackable"] = R.emagged? 0 : 1
|
||||
// Antag AIs know whether linked cyborgs are hacked or not.
|
||||
if(operator && isAI(operator) && (R.connected_ai == operator) && (operator.mind.special_role && operator.mind.original == operator))
|
||||
robot["hacked"] = R.emagged ? 1 : 0
|
||||
robot["hackable"] = R.emagged? 0 : 1
|
||||
robots.Add(list(robot))
|
||||
return robots
|
||||
|
||||
// Proc: get_cyborg_by_name()
|
||||
// Parameters: 1 (name - Cyborg we are trying to find)
|
||||
// Description: Helper proc for finding cyborg by name
|
||||
/obj/machinery/computer/robotics/proc/get_cyborg_by_name(var/name)
|
||||
if (!name)
|
||||
/obj/machinery/computer/robotics/tgui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
for(var/mob/living/silicon/robot/R in mob_list)
|
||||
if(R.name == name)
|
||||
return R
|
||||
. = FALSE
|
||||
if(!is_authenticated(usr))
|
||||
to_chat(usr, "<span class='warning'>Access denied.</span>")
|
||||
return
|
||||
switch(action)
|
||||
if("arm") // Arms the emergency self-destruct system
|
||||
if(issilicon(usr))
|
||||
to_chat(usr, "<span class='danger'>Access Denied (silicon detected)</span>")
|
||||
return
|
||||
safety = !safety
|
||||
to_chat(usr, "<span class='notice'>You [safety ? "disarm" : "arm"] the emergency self destruct.</span>")
|
||||
. = TRUE
|
||||
if("nuke") // Destroys all accessible cyborgs if safety is disabled
|
||||
if(issilicon(usr))
|
||||
to_chat(usr, "<span class='danger'>Access Denied (silicon detected)</span>")
|
||||
return
|
||||
if(safety)
|
||||
to_chat(usr, "<span class='danger'>Self-destruct aborted - safety active</span>")
|
||||
return
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] detonated all cyborgs!</span>")
|
||||
log_game("\<span class='notice'>[key_name(usr)] detonated all cyborgs!</span>")
|
||||
for(var/mob/living/silicon/robot/R in mob_list)
|
||||
if(istype(R, /mob/living/silicon/robot/drone))
|
||||
continue
|
||||
// Ignore antagonistic cyborgs
|
||||
if(R.scrambledcodes)
|
||||
continue
|
||||
to_chat(R, "<span class='danger'>Self-destruct command received.</span>")
|
||||
if(R.connected_ai)
|
||||
to_chat(R.connected_ai, "<br><br><span class='alert'>ALERT - Cyborg detonation detected: [R.name]</span><br>")
|
||||
R.self_destruct()
|
||||
. = TRUE
|
||||
if("killbot") // destroys one specific cyborg
|
||||
var/mob/living/silicon/robot/R = locate(params["ref"])
|
||||
if(!can_control(usr, R, TRUE))
|
||||
return
|
||||
if(R.mind && R.mind.special_role && R.emagged)
|
||||
to_chat(R, "<span class='userdanger'>Extreme danger! Termination codes detected. Scrambling security codes and automatic AI unlink triggered.</span>")
|
||||
R.ResetSecurityCodes()
|
||||
. = TRUE
|
||||
return
|
||||
var/turf/T = get_turf(R)
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] detonated [key_name_admin(R)] ([ADMIN_COORDJMP(T)])!</span>")
|
||||
log_game("\<span class='notice'>[key_name(usr)] detonated [key_name(R)]!</span>")
|
||||
to_chat(R, "<span class='danger'>Self-destruct command received.</span>")
|
||||
if(R.connected_ai)
|
||||
to_chat(R.connected_ai, "<br><br><span class='alert'>ALERT - Cyborg detonation detected: [R.name]</span><br>")
|
||||
R.self_destruct()
|
||||
. = TRUE
|
||||
if("stopbot") // lock or unlock the borg
|
||||
if(isrobot(usr))
|
||||
to_chat(usr, "<span class='danger'>Access Denied.</span>")
|
||||
return
|
||||
var/mob/living/silicon/robot/R = locate(params["ref"])
|
||||
if(!can_control(usr, R, TRUE))
|
||||
return
|
||||
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] [!R.lockcharge ? "locked down" : "released"] [ADMIN_LOOKUPFLW(R)]!</span>")
|
||||
log_game("[key_name(usr)] [!R.lockcharge ? "locked down" : "released"] [key_name(R)]!")
|
||||
R.SetLockdown(!R.lockcharge)
|
||||
to_chat(R, "[!R.lockcharge ? "<span class='notice'>Your lockdown has been lifted!" : "<span class='alert'>You have been locked down!"]</span>")
|
||||
if(R.connected_ai)
|
||||
to_chat(R.connected_ai, "[!R.lockcharge ? "<span class='notice'>NOTICE - Cyborg lockdown lifted</span>" : "<span class='alert'>ALERT - Cyborg lockdown detected</span>"]: <a href='?src=[REF(R.connected_ai)];track=[html_encode(R.name)]'>[R.name]</a></span><br>")
|
||||
. = TRUE
|
||||
if("hackbot") // AIs hacking/emagging a borg
|
||||
var/mob/living/silicon/robot/R = locate(params["ref"])
|
||||
if(!can_hack(usr, R))
|
||||
return
|
||||
var/choice = input("Really hack [R.name]? This cannot be undone.") in list("Yes", "No")
|
||||
if(choice != "Yes")
|
||||
return
|
||||
log_game("[key_name(usr)] emagged [key_name(R)] using robotic console!")
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] emagged [key_name_admin(R)] using robotic console!</span>")
|
||||
R.emagged = TRUE
|
||||
to_chat(R, "<span class='notice'>Failsafe protocols overriden. New tools available.</span>")
|
||||
. = TRUE
|
||||
|
||||
@@ -509,4 +509,4 @@
|
||||
/obj/machinery/computer/secure_data/detective_computer
|
||||
icon_state = "messyfiles"
|
||||
|
||||
#undef FIELD
|
||||
#undef FIELD
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
if(..())
|
||||
return
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='warning'>You don't have the required access to use this console.</span>")
|
||||
return
|
||||
user.set_machine(src)
|
||||
tgui_interact(user)
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
var jobs_all = ""
|
||||
jobs_all += "<table><tr><td></td><td><b>Command</b></td>"
|
||||
|
||||
jobs_all += "</tr><tr height='20'><td><b>Special</b></td>"//Colony Director in special because he is head of heads ~Intercross21
|
||||
jobs_all += "<td weight='100'><a href='?src=\ref[src];;assign=Colony Director'>Colony Director</a></td>"
|
||||
jobs_all += "</tr><tr height='20'><td><b>Special</b></td>"//Site Manager in special because he is head of heads ~Intercross21
|
||||
jobs_all += "<td weight='100'><a href='?src=\ref[src];;assign=Site Manager'>Site Manager</a></td>"
|
||||
jobs_all += "<td weight='100'><a href='?src=\ref[src];;assign=Custom'>Custom</a></td>"
|
||||
|
||||
counter = 0
|
||||
|
||||
@@ -39,9 +39,9 @@
|
||||
var/secured_wires = 0
|
||||
var/datum/wires/airlock/wires = null
|
||||
|
||||
var/open_sound_powered = 'sound/machines/airlock.ogg'
|
||||
var/open_sound_powered = 'sound/machines/door/covert1o.ogg'
|
||||
var/open_sound_unpowered = 'sound/machines/airlockforced.ogg'
|
||||
var/close_sound_powered = 'sound/machines/airlockclose.ogg'
|
||||
var/close_sound_powered = 'sound/machines/door/covert1c.ogg'
|
||||
var/denied_sound = 'sound/machines/deniedbeep.ogg'
|
||||
var/bolt_up_sound = 'sound/machines/boltsup.ogg'
|
||||
var/bolt_down_sound = 'sound/machines/boltsdown.ogg'
|
||||
@@ -81,7 +81,7 @@
|
||||
if(do_after(user,5 SECONDS,src))
|
||||
visible_message("<span class='danger'>\The [user] forces \the [src] open, sparks flying from its electronics!</span>")
|
||||
src.do_animate("spark")
|
||||
playsound(src, 'sound/machines/airlock_creaking.ogg', 100, 1)
|
||||
playsound(src, 'sound/machines/airlock_creaking.ogg', 100, 1, volume_channel = VOLUME_CHANNEL_DOORS)
|
||||
src.locked = 0
|
||||
src.welded = 0
|
||||
update_icon()
|
||||
@@ -90,7 +90,7 @@
|
||||
else if(src.density)
|
||||
visible_message("<span class='alium'>\The [user] begins forcing \the [src] open!</span>")
|
||||
if(do_after(user, 5 SECONDS,src))
|
||||
playsound(src, 'sound/machines/airlock_creaking.ogg', 100, 1)
|
||||
playsound(src, 'sound/machines/airlock_creaking.ogg', 100, 1, volume_channel = VOLUME_CHANNEL_DOORS)
|
||||
visible_message("<span class='danger'>\The [user] forces \the [src] open!</span>")
|
||||
open(1)
|
||||
else
|
||||
@@ -112,40 +112,54 @@
|
||||
icon = 'icons/obj/doors/Doorcom.dmi'
|
||||
req_one_access = list(access_heads)
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_com
|
||||
open_sound_powered = 'sound/machines/door/cmd3o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/cmd3c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/security
|
||||
name = "Security Airlock"
|
||||
icon = 'icons/obj/doors/Doorsec.dmi'
|
||||
req_one_access = list(access_security)
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_sec
|
||||
open_sound_powered = 'sound/machines/door/sec1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/sec1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/engineering
|
||||
name = "Engineering Airlock"
|
||||
icon = 'icons/obj/doors/Dooreng.dmi'
|
||||
req_one_access = list(access_engine)
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_eng
|
||||
open_sound_powered = 'sound/machines/door/eng1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/eng1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/engineeringatmos
|
||||
name = "Atmospherics Airlock"
|
||||
icon = 'icons/obj/doors/Doorengatmos.dmi'
|
||||
req_one_access = list(access_atmospherics)
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_eat
|
||||
open_sound_powered = 'sound/machines/door/eng1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/eng1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/medical
|
||||
name = "Medical Airlock"
|
||||
icon = 'icons/obj/doors/Doormed.dmi'
|
||||
req_one_access = list(access_medical)
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_med
|
||||
open_sound_powered = 'sound/machines/door/med1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/med1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/maintenance
|
||||
name = "Maintenance Access"
|
||||
icon = 'icons/obj/doors/Doormaint.dmi'
|
||||
//req_one_access = list(access_maint_tunnels) //VOREStation Edit - Maintenance is open access
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_mai
|
||||
open_sound_powered = 'sound/machines/door/door2o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/door2c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/maintenance/cargo
|
||||
icon = 'icons/obj/doors/Doormaint_cargo.dmi'
|
||||
req_one_access = list(access_cargo)
|
||||
open_sound_powered = 'sound/machines/door/door2o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/door2c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/maintenance/command
|
||||
icon = 'icons/obj/doors/Doormaint_command.dmi'
|
||||
@@ -153,6 +167,8 @@
|
||||
|
||||
/obj/machinery/door/airlock/maintenance/common
|
||||
icon = 'icons/obj/doors/Doormaint_common.dmi'
|
||||
open_sound_powered = 'sound/machines/door/hall3o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/hall3c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/maintenance/engi
|
||||
icon = 'icons/obj/doors/Doormaint_engi.dmi'
|
||||
@@ -177,6 +193,8 @@
|
||||
name = "External Airlock"
|
||||
icon = 'icons/obj/doors/Doorext.dmi'
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_ext
|
||||
open_sound_powered = 'sound/machines/door/space1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/space1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/external/glass/bolted
|
||||
icon_state = "door_locked" // So it looks visibly bolted in map editor
|
||||
@@ -193,12 +211,15 @@
|
||||
opacity = 0
|
||||
glass = 1
|
||||
req_one_access = list(access_external_airlocks)
|
||||
open_sound_powered = 'sound/machines/door/space1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/space1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/glass
|
||||
name = "Glass Airlock"
|
||||
icon = 'icons/obj/doors/Doorglass.dmi'
|
||||
hitsound = 'sound/effects/Glasshit.ogg'
|
||||
open_sound_powered = 'sound/machines/windowdoor.ogg'
|
||||
open_sound_powered = 'sound/machines/door/hall1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/hall1c.ogg'
|
||||
maxhealth = 300
|
||||
explosion_resistance = 5
|
||||
opacity = 0
|
||||
@@ -209,12 +230,16 @@
|
||||
icon = 'icons/obj/doors/Doorele.dmi'
|
||||
req_one_access = list(access_cent_general)
|
||||
opacity = 1
|
||||
open_sound_powered = 'sound/machines/door/cmd3o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/cmd3c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/glass_centcom
|
||||
name = "Airlock"
|
||||
icon = 'icons/obj/doors/Dooreleglass.dmi'
|
||||
opacity = 0
|
||||
glass = 1
|
||||
open_sound_powered = 'sound/machines/door/cmd3o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/cmd3c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/vault
|
||||
name = "Vault"
|
||||
@@ -224,6 +249,8 @@
|
||||
secured_wires = 1
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity //Until somebody makes better sprites.
|
||||
req_one_access = list(access_heads_vault)
|
||||
open_sound_powered = 'sound/machines/door/vault1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/vault1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/vault/bolted
|
||||
icon_state = "door_locked"
|
||||
@@ -242,6 +269,9 @@
|
||||
opacity = 1
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_hatch
|
||||
req_one_access = list(access_maint_tunnels)
|
||||
open_sound_powered = 'sound/machines/door/hatchopen.ogg'
|
||||
close_sound_powered = 'sound/machines/door/hatchclose.ogg'
|
||||
open_sound_unpowered = 'sound/machines/door/hatchforced.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/maintenance_hatch
|
||||
name = "Maintenance Hatch"
|
||||
@@ -250,6 +280,9 @@
|
||||
opacity = 1
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_mhatch
|
||||
req_one_access = list(access_maint_tunnels)
|
||||
open_sound_powered = 'sound/machines/door/hatchopen.ogg'
|
||||
close_sound_powered = 'sound/machines/door/hatchclose.ogg'
|
||||
open_sound_unpowered = 'sound/machines/door/hatchforced.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/glass_command
|
||||
name = "Command Airlock"
|
||||
@@ -261,6 +294,8 @@
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_com
|
||||
glass = 1
|
||||
req_one_access = list(access_heads)
|
||||
open_sound_powered = 'sound/machines/door/cmd1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/cmd1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/glass_engineering
|
||||
name = "Engineering Airlock"
|
||||
@@ -272,6 +307,8 @@
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_eng
|
||||
glass = 1
|
||||
req_one_access = list(access_engine)
|
||||
open_sound_powered = 'sound/machines/door/eng1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/eng1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/glass_engineeringatmos
|
||||
name = "Atmospherics Airlock"
|
||||
@@ -283,6 +320,8 @@
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_eat
|
||||
glass = 1
|
||||
req_one_access = list(access_atmospherics)
|
||||
open_sound_powered = 'sound/machines/door/eng1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/eng1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/glass_security
|
||||
name = "Security Airlock"
|
||||
@@ -294,6 +333,8 @@
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_sec
|
||||
glass = 1
|
||||
req_one_access = list(access_security)
|
||||
open_sound_powered = 'sound/machines/door/sec1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/sec1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/glass_medical
|
||||
name = "Medical Airlock"
|
||||
@@ -305,23 +346,31 @@
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_med
|
||||
glass = 1
|
||||
req_one_access = list(access_medical)
|
||||
open_sound_powered = 'sound/machines/door/med1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/med1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/mining
|
||||
name = "Mining Airlock"
|
||||
icon = 'icons/obj/doors/Doormining.dmi'
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_min
|
||||
req_one_access = list(access_mining)
|
||||
open_sound_powered = 'sound/machines/door/cgo1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/cgo1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/atmos
|
||||
name = "Atmospherics Airlock"
|
||||
icon = 'icons/obj/doors/Dooratmo.dmi'
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_atmo
|
||||
req_one_access = list(access_atmospherics)
|
||||
open_sound_powered = 'sound/machines/door/eng1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/eng1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/research
|
||||
name = "Research Airlock"
|
||||
icon = 'icons/obj/doors/Doorresearch.dmi'
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_research
|
||||
open_sound_powered = 'sound/machines/door/sci1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/sci1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/glass_research
|
||||
name = "Research Airlock"
|
||||
@@ -333,6 +382,8 @@
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_research
|
||||
glass = 1
|
||||
req_one_access = list(access_research)
|
||||
open_sound_powered = 'sound/machines/door/sci1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/sci1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/glass_mining
|
||||
name = "Mining Airlock"
|
||||
@@ -344,6 +395,8 @@
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_min
|
||||
glass = 1
|
||||
req_one_access = list(access_mining)
|
||||
open_sound_powered = 'sound/machines/door/cgo1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/cgo1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/glass_atmos
|
||||
name = "Atmospherics Airlock"
|
||||
@@ -355,6 +408,8 @@
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_atmo
|
||||
glass = 1
|
||||
req_one_access = list(access_atmospherics)
|
||||
open_sound_powered = 'sound/machines/door/eng1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/eng1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/gold
|
||||
name = "Gold Airlock"
|
||||
@@ -435,6 +490,8 @@
|
||||
icon = 'icons/obj/doors/Doorsci.dmi'
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_science
|
||||
req_one_access = list(access_research)
|
||||
open_sound_powered = 'sound/machines/door/sci1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/sci1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/glass_science
|
||||
name = "Glass Airlocks"
|
||||
@@ -443,6 +500,8 @@
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_science
|
||||
glass = 1
|
||||
req_one_access = list(access_research)
|
||||
open_sound_powered = 'sound/machines/door/sci1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/sci1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/highsecurity
|
||||
name = "Secure Airlock"
|
||||
@@ -451,6 +510,8 @@
|
||||
secured_wires = 1
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity
|
||||
req_one_access = list(access_heads_vault)
|
||||
open_sound_powered = 'sound/machines/door/secure1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/secure1c.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/voidcraft
|
||||
name = "voidcraft hatch"
|
||||
@@ -460,11 +521,15 @@
|
||||
opacity = 0
|
||||
glass = 1
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft
|
||||
open_sound_powered = 'sound/machines/door/shuttle1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/shuttle1c.ogg'
|
||||
|
||||
// Airlock opens from top-bottom instead of left-right.
|
||||
/obj/machinery/door/airlock/voidcraft/vertical
|
||||
icon = 'icons/obj/doors/shuttledoors_vertical.dmi'
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft/vertical
|
||||
open_sound_powered = 'sound/machines/door/shuttle1o.ogg'
|
||||
close_sound_powered = 'sound/machines/door/shuttle1c.ogg'
|
||||
|
||||
|
||||
/datum/category_item/catalogue/anomalous/precursor_a/alien_airlock
|
||||
@@ -1108,9 +1173,9 @@ About the new airlock wires panel:
|
||||
|
||||
//if the door is unpowered then it doesn't make sense to hear the woosh of a pneumatic actuator
|
||||
if(arePowerSystemsOn())
|
||||
playsound(src, open_sound_powered, 50, 1)
|
||||
playsound(src, open_sound_powered, 50, 1, volume_channel = VOLUME_CHANNEL_DOORS)
|
||||
else
|
||||
playsound(src, open_sound_unpowered, 75, 1)
|
||||
playsound(src, open_sound_unpowered, 75, 1, volume_channel = VOLUME_CHANNEL_DOORS)
|
||||
|
||||
if(src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density)
|
||||
src.closeOther.close()
|
||||
@@ -1206,9 +1271,9 @@ About the new airlock wires panel:
|
||||
use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people
|
||||
has_beeped = 0
|
||||
if(arePowerSystemsOn())
|
||||
playsound(src, close_sound_powered, 50, 1)
|
||||
playsound(src, close_sound_powered, 50, 1, volume_channel = VOLUME_CHANNEL_DOORS)
|
||||
else
|
||||
playsound(src, open_sound_unpowered, 75, 1)
|
||||
playsound(src, open_sound_unpowered, 75, 1, volume_channel = VOLUME_CHANNEL_DOORS)
|
||||
for(var/turf/turf in locs)
|
||||
var/obj/structure/window/killthis = (locate(/obj/structure/window) in turf)
|
||||
if(killthis)
|
||||
@@ -1222,7 +1287,7 @@ About the new airlock wires panel:
|
||||
if (operating && !forced) return 0
|
||||
|
||||
src.locked = 1
|
||||
playsound(src, bolt_down_sound, 30, 0, 3)
|
||||
playsound(src, bolt_down_sound, 30, 0, 3, volume_channel = VOLUME_CHANNEL_DOORS)
|
||||
for(var/mob/M in range(1,src))
|
||||
M.show_message("You hear a click from the bottom of the door.", 2)
|
||||
update_icon()
|
||||
@@ -1236,7 +1301,7 @@ About the new airlock wires panel:
|
||||
if(operating || !src.arePowerSystemsOn() || wires.is_cut(WIRE_DOOR_BOLTS)) return
|
||||
|
||||
src.locked = 0
|
||||
playsound(src, bolt_up_sound, 30, 0, 3)
|
||||
playsound(src, bolt_up_sound, 30, 0, 3, volume_channel = VOLUME_CHANNEL_DOORS)
|
||||
for(var/mob/M in range(1,src))
|
||||
M.show_message("You hear a click from the bottom of the door.", 2)
|
||||
update_icon()
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
appearance_flags = 0
|
||||
var/obj/machinery/filler_object/filler1
|
||||
var/obj/machinery/filler_object/filler2
|
||||
open_sound_powered = 'sound/machines/door/WideOpen.ogg'
|
||||
close_sound_powered = 'sound/machines/door/WideClose.ogg'
|
||||
|
||||
/obj/machinery/door/airlock/multi_tile/New()
|
||||
..()
|
||||
|
||||
@@ -68,6 +68,11 @@
|
||||
var/flash_time = strength
|
||||
if(istype(O, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = O
|
||||
//VOREStation Edit Start
|
||||
if(H.nif && H.nif.flag_check(NIF_V_FLASHPROT,NIF_FLAGS_VISION))
|
||||
H.nif.notify("High intensity light detected, and blocked!",TRUE)
|
||||
continue
|
||||
//VOREStation Edit End
|
||||
if(!H.eyecheck() <= 0)
|
||||
continue
|
||||
flash_time *= H.species.flash_mod
|
||||
|
||||
@@ -810,6 +810,7 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster)
|
||||
var/scribble=""
|
||||
var/scribble_page = null
|
||||
drop_sound = 'sound/items/drop/wrapper.ogg'
|
||||
pickup_sound = 'sound/items/pickup/wrapper.ogg'
|
||||
|
||||
obj/item/weapon/newspaper/attack_self(mob/user as mob)
|
||||
if(ishuman(user))
|
||||
|
||||
@@ -234,116 +234,123 @@
|
||||
if(..())
|
||||
return
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/partslathe/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
user.set_machine(src)
|
||||
/obj/machinery/partslathe/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/spritesheet/sheetmaterials)
|
||||
)
|
||||
|
||||
var/data[0]
|
||||
/obj/machinery/partslathe/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "PartsLathe", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/partslathe/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
data["panelOpen"] = panel_open
|
||||
|
||||
var/materials_ui[0]
|
||||
var/list/materials_ui = list()
|
||||
for(var/M in materials)
|
||||
materials_ui[++materials_ui.len] = list(
|
||||
"name" = M,
|
||||
"display" = material_display_name(M),
|
||||
"qty" = materials[M],
|
||||
"max" = storage_capacity[M],
|
||||
"percent" = (materials[M] / storage_capacity[M] * 100))
|
||||
materials_ui.Add(list(list(
|
||||
"name" = M,
|
||||
"amount" = materials[M],
|
||||
"sheets" = round(materials[M] / SHEET_MATERIAL_AMOUNT),
|
||||
"removable" = materials[M] >= SHEET_MATERIAL_AMOUNT,
|
||||
)))
|
||||
data["materials"] = materials_ui
|
||||
|
||||
data["copyBoard"] = null
|
||||
data["copyBoardReqComponents"] = null
|
||||
if(istype(copy_board))
|
||||
data["copyBoard"] = copy_board.name
|
||||
var/req_components_ui[0]
|
||||
var/list/req_components_ui = list()
|
||||
for(var/CP in (copy_board.req_components || list()))
|
||||
var/obj/comp_path = CP
|
||||
var/comp_amt = copy_board.req_components[comp_path]
|
||||
if(comp_amt && (comp_path in partslathe_recipies))
|
||||
req_components_ui[++req_components_ui.len] = list("name" = initial(comp_path.name), "qty" = comp_amt)
|
||||
req_components_ui.Add(list(list("name" = initial(comp_path.name), "qty" = comp_amt)))
|
||||
data["copyBoardReqComponents"] = req_components_ui
|
||||
|
||||
data["queue"] = list()
|
||||
for(var/datum/category_item/partslathe/Q in queue)
|
||||
data["queue"] += Q.name
|
||||
|
||||
data["building"] = null
|
||||
data["buildPercent"] = null
|
||||
if(busy && queue.len > 0)
|
||||
var/datum/category_item/partslathe/current = queue[1]
|
||||
data["building"] = current.name
|
||||
data["buildProgress"] = progress
|
||||
data["buildTime"] = current.time
|
||||
data["buildPercent"] = (progress / current.time * 100)
|
||||
|
||||
data["error"] = null
|
||||
if(queue.len > 0 && !canBuild(queue[1]))
|
||||
data["error"] = getLackingMaterials(queue[1])
|
||||
|
||||
var/recipies_ui[0]
|
||||
var/list/recipies_ui = list()
|
||||
for(var/T in partslathe_recipies)
|
||||
var/datum/category_item/partslathe/R = partslathe_recipies[T]
|
||||
recipies_ui[++recipies_ui.len] = list("name" = R.name, "type" = "[T]")
|
||||
recipies_ui.Add(list(list("name" = R.name, "type" = "[T]")))
|
||||
data["recipies"] = recipies_ui
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "partslathe.tmpl", "Parts Lathe UI", 500, 450)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(5)
|
||||
return data
|
||||
|
||||
/obj/machinery/partslathe/Topic(href, href_list)
|
||||
/obj/machinery/partslathe/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return 1
|
||||
usr.set_machine(src)
|
||||
return TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
// Queue management can be done even while busy
|
||||
if(href_list["queue"])
|
||||
var/type_to_build = text2path(href_list["queue"])
|
||||
var/datum/category_item/partslathe/to_build = partslathe_recipies[type_to_build]
|
||||
if(to_build)
|
||||
addToQueue(to_build)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
if(href_list["queueBoard"])
|
||||
if(!istype(copy_board) || !copy_board.req_components)
|
||||
return
|
||||
for(var/comp_path in copy_board.req_components)
|
||||
var/comp_amt = copy_board.req_components[comp_path]
|
||||
if(!comp_amt)
|
||||
continue
|
||||
var/datum/category_item/partslathe/to_build = partslathe_recipies[comp_path]
|
||||
if(!to_build)
|
||||
continue // We don't support building whatever this is
|
||||
for(var/i in 1 to comp_amt)
|
||||
switch(action)
|
||||
// Queue management can be done even while busy
|
||||
if("queue")
|
||||
var/type_to_build = text2path(params["queue"])
|
||||
var/datum/category_item/partslathe/to_build = partslathe_recipies[type_to_build]
|
||||
if(to_build)
|
||||
addToQueue(to_build)
|
||||
return
|
||||
return TRUE
|
||||
|
||||
if(href_list["cancel"])
|
||||
var/index = text2num(href_list["cancel"])
|
||||
if(index < 1 || index > queue.len)
|
||||
return
|
||||
if(busy && index == 1)
|
||||
return
|
||||
removeFromQueue(index)
|
||||
return
|
||||
if("queueBoard")
|
||||
if(!istype(copy_board) || !copy_board.req_components)
|
||||
return
|
||||
for(var/comp_path in copy_board.req_components)
|
||||
var/comp_amt = copy_board.req_components[comp_path]
|
||||
if(!comp_amt)
|
||||
continue
|
||||
var/datum/category_item/partslathe/to_build = partslathe_recipies[comp_path]
|
||||
if(!to_build)
|
||||
continue // We don't support building whatever this is
|
||||
for(var/i in 1 to comp_amt)
|
||||
addToQueue(to_build)
|
||||
return TRUE
|
||||
|
||||
if("cancel")
|
||||
var/index = text2num(params["cancel"])
|
||||
if(index < 1 || index > queue.len)
|
||||
return
|
||||
if(busy && index == 1)
|
||||
return
|
||||
removeFromQueue(index)
|
||||
return TRUE
|
||||
|
||||
if(busy)
|
||||
to_chat(usr, "<span class='notice'>\The [src]is busy. Please wait for completion of previous operation.</span>")
|
||||
to_chat(usr, "<span class='notice'>[src] is busy. Please wait for completion of previous operation.</span>")
|
||||
return
|
||||
|
||||
if(href_list["ejectBoard"])
|
||||
if(copy_board)
|
||||
visible_message("<span class='notice'>\The [copy_board] is ejected from \the [src]'s circuit reader</span>.")
|
||||
copy_board.forceMove(src.loc)
|
||||
copy_board = null
|
||||
updateUsrDialog()
|
||||
return
|
||||
switch(action)
|
||||
if("ejectBoard")
|
||||
if(copy_board)
|
||||
visible_message("<span class='notice'>[copy_board] is ejected from [src]'s circuit reader</span>.")
|
||||
copy_board.forceMove(src.loc)
|
||||
copy_board = null
|
||||
return TRUE
|
||||
|
||||
if(href_list["ejectMaterial"])
|
||||
var/matName = href_list["ejectMaterial"]
|
||||
if(!(matName in materials))
|
||||
if("remove_mat")
|
||||
// Remove a material from the fab
|
||||
var/mat_id = params["id"]
|
||||
var/amount = text2num(params["amount"])
|
||||
eject_materials(mat_id, amount)
|
||||
return
|
||||
eject_materials(matName, 0)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
/** Build list of recipies to include all tech level 1 stock parts. */
|
||||
/obj/machinery/partslathe/proc/update_recipe_list()
|
||||
|
||||
@@ -16,10 +16,10 @@ obj/machinery/seed_extractor/attackby(var/obj/item/O as obj, var/mob/user as mob
|
||||
var/datum/seed/new_seed_type
|
||||
if(istype(O, /obj/item/weapon/grown))
|
||||
var/obj/item/weapon/grown/F = O
|
||||
new_seed_type = plant_controller.seeds[F.plantname]
|
||||
new_seed_type = SSplants.seeds[F.plantname]
|
||||
else
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/grown/F = O
|
||||
new_seed_type = plant_controller.seeds[F.plantname]
|
||||
new_seed_type = SSplants.seeds[F.plantname]
|
||||
|
||||
if(new_seed_type)
|
||||
to_chat(user, "<span class='notice'>You extract some seeds from [O].</span>")
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
if("door")
|
||||
toggle_open(usr)
|
||||
. = TRUE
|
||||
if("dispense")
|
||||
if("dispense")
|
||||
switch(params["item"])
|
||||
if("helmet")
|
||||
dispense_helmet(usr)
|
||||
@@ -653,12 +653,12 @@
|
||||
name = "Vintage Pilot suit cycler"
|
||||
model_text = "Vintage Pilot"
|
||||
departments = list("Vintage Pilot (Bubble Helm)","Vintage Pilot (Closed Helm)")
|
||||
|
||||
|
||||
/obj/machinery/suit_cycler/vintage/medsci
|
||||
name = "Vintage MedSci suit cycler"
|
||||
model_text = "Vintage MedSci"
|
||||
departments = list("Vintage Medical (Bubble Helm)","Vintage Medical (Closed Helm)","Vintage Research (Bubble Helm)","Vintage Research (Closed Helm)")
|
||||
|
||||
|
||||
/obj/machinery/suit_cycler/vintage/rugged
|
||||
name = "Vintage Ruggedized suit cycler"
|
||||
model_text = "Vintage Ruggedized"
|
||||
@@ -751,7 +751,7 @@
|
||||
if(istype(I,/obj/item/clothing/head/helmet/space/void/autolok))
|
||||
to_chat(user, "You cannot refit an autolok helmet. In fact you shouldn't even be able to remove it in the first place. Inform an admin!")
|
||||
return
|
||||
|
||||
|
||||
//Ditto the Mk7
|
||||
if(istype(I,/obj/item/clothing/head/helmet/space/void/responseteam))
|
||||
to_chat(user, "The cycler indicates that the Mark VII Emergency Response Helmet is not compatible with the refitting system. How did you manage to detach it anyway? Inform an admin!")
|
||||
@@ -791,13 +791,13 @@
|
||||
if(istype(I,/obj/item/clothing/suit/space/void/autolok))
|
||||
to_chat(user, "You cannot refit an autolok suit.")
|
||||
return
|
||||
|
||||
|
||||
//Ditto the Mk7
|
||||
if(istype(I,/obj/item/clothing/suit/space/void/responseteam))
|
||||
to_chat(user, "The cycler indicates that the Mark VII Emergency Response Suit is not compatible with the refitting system.")
|
||||
return
|
||||
//VOREStation Edit ENDS
|
||||
|
||||
|
||||
to_chat(user, "You fit \the [I] into the suit cycler.")
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
@@ -886,7 +886,7 @@
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("dispense")
|
||||
if("dispense")
|
||||
switch(params["item"])
|
||||
if("helmet")
|
||||
helmet.forceMove(get_turf(src))
|
||||
@@ -895,23 +895,23 @@
|
||||
suit.forceMove(get_turf(src))
|
||||
suit = null
|
||||
. = TRUE
|
||||
|
||||
|
||||
if("department")
|
||||
var/choice = params["department"]
|
||||
if(choice in departments)
|
||||
target_department = choice
|
||||
. = TRUE
|
||||
|
||||
|
||||
if("species")
|
||||
var/choice = params["species"]
|
||||
if(choice in species)
|
||||
target_species = choice
|
||||
. = TRUE
|
||||
|
||||
|
||||
if("radlevel")
|
||||
radiation_level = clamp(params["radlevel"], 1, emagged ? 5 : 3)
|
||||
. = TRUE
|
||||
|
||||
|
||||
if("repair_suit")
|
||||
if(!suit || !can_repair)
|
||||
return
|
||||
@@ -1055,7 +1055,7 @@
|
||||
|
||||
if(target_species)
|
||||
if(helmet) helmet.refit_for_species(target_species)
|
||||
if(suit)
|
||||
if(suit)
|
||||
suit.refit_for_species(target_species)
|
||||
if(suit.helmet)
|
||||
suit.helmet.refit_for_species(target_species)
|
||||
@@ -1176,7 +1176,7 @@
|
||||
parent_suit = /obj/item/clothing/suit/space/void/refurb/mercenary
|
||||
//BEGIN: Space for additional downstream variants
|
||||
//VOREStation Addition Start
|
||||
if("Director")
|
||||
if("Manager")
|
||||
parent_helmet = /obj/item/clothing/head/helmet/space/void/captain
|
||||
parent_suit = /obj/item/clothing/suit/space/void/captain
|
||||
if("Prototype")
|
||||
@@ -1217,7 +1217,7 @@
|
||||
parent_suit = /obj/item/clothing/suit/space/void/refurb/mercenary/talon
|
||||
//VOREStation Addition End
|
||||
//END: downstream variant space
|
||||
|
||||
|
||||
//look at this! isn't it beautiful? -KK (well ok not beautiful but it's a lot cleaner)
|
||||
if(helmet && target_department != "No Change")
|
||||
var/obj/item/clothing/H = new parent_helmet
|
||||
@@ -1235,9 +1235,9 @@
|
||||
suit.desc = initial(parent_suit.desc)
|
||||
suit.icon_state = initial(parent_suit.icon_state)
|
||||
suit.item_state = initial(parent_suit.item_state)
|
||||
suit.item_state_slots = S.item_state_slots
|
||||
suit.item_state_slots = S.item_state_slots
|
||||
qdel(S)
|
||||
|
||||
|
||||
//can't believe I forgot to fix this- now helmets will properly cycle if they're attached to a suit -KK
|
||||
if(suit.helmet && target_department != "No Change")
|
||||
var/obj/item/clothing/AH = new parent_helmet
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/machinery/suit_cycler
|
||||
departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard","Emergency Medical Response","Crowd Control","Exploration","Pilot Blue","Pilot","Director","Prototype")
|
||||
departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard","Emergency Medical Response","Crowd Control","Exploration","Pilot Blue","Pilot","Manager","Prototype")
|
||||
species = list(SPECIES_HUMAN, SPECIES_SKRELL, SPECIES_UNATHI, SPECIES_TAJ, SPECIES_TESHARI, SPECIES_AKULA, SPECIES_SERGAL, SPECIES_VULPKANIN)
|
||||
|
||||
// Old Exploration is too WIP to use right now
|
||||
@@ -11,10 +11,10 @@
|
||||
req_access = list(access_pilot)
|
||||
|
||||
/obj/machinery/suit_cycler/captain
|
||||
name = "Director suit cycler"
|
||||
model_text = "Director"
|
||||
name = "Manager suit cycler"
|
||||
model_text = "Manager"
|
||||
req_access = list(access_captain)
|
||||
departments = list("Director")
|
||||
departments = list("Manager")
|
||||
|
||||
/obj/machinery/suit_cycler/captain/Initialize() //No Teshari Sprites
|
||||
species -= SPECIES_TESHARI
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
/obj/item/clothing/shoes/brown = 5,
|
||||
/obj/item/clothing/shoes/laceup = 5,
|
||||
/obj/item/clothing/shoes/green = 5,
|
||||
/obj/item/clothing/shoes/leather = 5,
|
||||
/obj/item/clothing/shoes/laceup/brown = 5,
|
||||
/obj/item/clothing/shoes/orange = 5,
|
||||
/obj/item/clothing/shoes/purple = 5,
|
||||
/obj/item/clothing/shoes/red = 5,
|
||||
@@ -228,7 +228,7 @@
|
||||
/obj/item/clothing/shoes/brown = 50,
|
||||
/obj/item/clothing/shoes/laceup = 50,
|
||||
/obj/item/clothing/shoes/green = 50,
|
||||
/obj/item/clothing/shoes/leather = 50,
|
||||
/obj/item/clothing/shoes/laceup/brown = 50,
|
||||
/obj/item/clothing/shoes/orange = 50,
|
||||
/obj/item/clothing/shoes/purple = 50,
|
||||
/obj/item/clothing/shoes/red = 50,
|
||||
@@ -1172,7 +1172,19 @@
|
||||
/obj/item/clothing/mask/gas/sexyclown = 3,
|
||||
/obj/item/clothing/under/sexyclown = 3,
|
||||
/obj/item/clothing/mask/gas/sexymime = 3,
|
||||
/obj/item/clothing/under/sexymime = 3)
|
||||
/obj/item/clothing/under/sexymime = 3,
|
||||
/obj/item/clothing/suit/storage/hooded/knight_costume = 3,
|
||||
/obj/item/clothing/suit/storage/hooded/knight_costume/galahad = 3,
|
||||
/obj/item/clothing/suit/storage/hooded/knight_costume/lancelot = 3,
|
||||
/obj/item/clothing/suit/storage/hooded/knight_costume/robin = 3,
|
||||
/obj/item/clothing/suit/armor/combat/crusader_costume = 3,
|
||||
/obj/item/clothing/suit/armor/combat/crusader_costume/bedevere = 3,
|
||||
/obj/item/clothing/head/helmet/combat/crusader_costume = 3,
|
||||
/obj/item/clothing/head/helmet/combat/bedevere_costume = 3,
|
||||
/obj/item/clothing/gloves/combat/knight_costume = 3,
|
||||
/obj/item/clothing/gloves/combat/knight_costume/brown = 3,
|
||||
/obj/item/clothing/shoes/knight_costume = 3,
|
||||
/obj/item/clothing/shoes/knight_costume/black = 3)
|
||||
prices = list(/obj/item/clothing/suit/storage/hooded/carp_costume = 200,
|
||||
/obj/item/clothing/suit/storage/hooded/carp_costume = 200,
|
||||
/obj/item/clothing/suit/chickensuit = 200,
|
||||
@@ -1225,7 +1237,19 @@
|
||||
/obj/item/clothing/mask/gas/sexyclown = 600,
|
||||
/obj/item/clothing/under/sexyclown = 200,
|
||||
/obj/item/clothing/mask/gas/sexymime = 600,
|
||||
/obj/item/clothing/under/sexymime = 200)
|
||||
/obj/item/clothing/under/sexymime = 200,
|
||||
/obj/item/clothing/suit/storage/hooded/knight_costume = 200,
|
||||
/obj/item/clothing/suit/storage/hooded/knight_costume/galahad = 200,
|
||||
/obj/item/clothing/suit/storage/hooded/knight_costume/lancelot = 200,
|
||||
/obj/item/clothing/suit/storage/hooded/knight_costume/robin = 200,
|
||||
/obj/item/clothing/suit/armor/combat/crusader_costume = 200,
|
||||
/obj/item/clothing/suit/armor/combat/crusader_costume/bedevere = 200,
|
||||
/obj/item/clothing/head/helmet/combat/crusader_costume = 200,
|
||||
/obj/item/clothing/head/helmet/combat/bedevere_costume = 200,
|
||||
/obj/item/clothing/gloves/combat/knight_costume = 200,
|
||||
/obj/item/clothing/gloves/combat/knight_costume/brown = 200,
|
||||
/obj/item/clothing/shoes/knight_costume = 200,
|
||||
/obj/item/clothing/shoes/knight_costume/black = 200)
|
||||
premium = list(/obj/item/clothing/suit/imperium_monk = 3,
|
||||
/obj/item/clothing/suit/barding/agatha = 2,
|
||||
/obj/item/clothing/suit/barding/alt_agatha = 2,
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
var/energy_drain = 0
|
||||
var/obj/mecha/chassis = null
|
||||
var/range = MELEE //bitflags
|
||||
/// Bitflag. Used by exosuit fabricator to assign sub-categories based on which exosuits can equip this.
|
||||
var/mech_flags = NONE
|
||||
var/salvageable = 1
|
||||
var/required_type = /obj/mecha //may be either a type or a list of allowed types
|
||||
var/equip_type = null //mechaequip2
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/extinguisher
|
||||
name = "extinguisher"
|
||||
desc = "Exosuit-mounted extinguisher (Can be attached to: Engineering exosuits)"
|
||||
mech_flags = EXOSUIT_MODULE_WORKING | EXOSUIT_MODULE_COMBAT
|
||||
icon_state = "mecha_exting"
|
||||
equip_cooldown = 5
|
||||
energy_drain = 0
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/rcd
|
||||
name = "mounted RCD"
|
||||
desc = "An exosuit-mounted Rapid Construction Device. (Can be attached to: Any exosuit)"
|
||||
mech_flags = EXOSUIT_MODULE_WORKING|EXOSUIT_MODULE_COMBAT|EXOSUIT_MODULE_MEDICAL
|
||||
icon_state = "mecha_rcd"
|
||||
origin_tech = list(TECH_MATERIAL = 4, TECH_BLUESPACE = 3, TECH_MAGNET = 4, TECH_POWER = 4)
|
||||
equip_cooldown = 10
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
energy_drain = 20
|
||||
range = MELEE
|
||||
equip_cooldown = 30
|
||||
mech_flags = EXOSUIT_MODULE_MEDICAL
|
||||
var/mob/living/carbon/human/occupant = null
|
||||
var/datum/global_iterator/pr_mech_sleeper
|
||||
var/inject_amount = 5
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun
|
||||
name = "syringe gun"
|
||||
desc = "Exosuit-mounted chem synthesizer with syringe gun. Reagents inside are held in stasis, so no reactions will occur. (Can be attached to: Medical Exosuits)"
|
||||
mech_flags = EXOSUIT_MODULE_MEDICAL
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
icon_state = "syringegun"
|
||||
var/list/syringes
|
||||
|
||||
@@ -4,9 +4,6 @@
|
||||
|
||||
step_delay = 0.5
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/Fire(atom/movable/AM, atom/target, turf/aimloc)
|
||||
AM.throw_at(target,missile_range, missile_speed, chassis)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flare
|
||||
name = "\improper BNI Flare Launcher"
|
||||
desc = "A flare-gun, but bigger."
|
||||
@@ -34,51 +31,19 @@
|
||||
name = "\improper SRM-8 missile rack"
|
||||
desc = "A missile battery that holds eight missiles."
|
||||
icon_state = "mecha_missilerack"
|
||||
projectile = /obj/item/missile
|
||||
projectile = /obj/item/projectile/bullet/srmrocket
|
||||
fire_sound = 'sound/weapons/rpg.ogg'
|
||||
projectiles = 8
|
||||
projectile_energy_cost = 1000
|
||||
equip_cooldown = 60
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive/Fire(atom/movable/AM, atom/target)
|
||||
var/obj/item/missile/M = AM
|
||||
M.primed = 1
|
||||
..()
|
||||
|
||||
/obj/item/missile
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "missile"
|
||||
var/primed = null
|
||||
throwforce = 15
|
||||
catchable = 0
|
||||
var/devastation = 0
|
||||
var/heavy_blast = 1
|
||||
var/light_blast = 2
|
||||
var/flash_blast = 4
|
||||
does_spin = FALSE // No fun corkscrew missiles.
|
||||
|
||||
/obj/item/missile/proc/warhead_special(var/target)
|
||||
explosion(target, devastation, heavy_blast, light_blast, flash_blast)
|
||||
return
|
||||
|
||||
/obj/item/missile/throw_impact(atom/hit_atom)
|
||||
if(primed)
|
||||
warhead_special(hit_atom)
|
||||
qdel(src)
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/missile/light
|
||||
throwforce = 10
|
||||
heavy_blast = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive/rigged
|
||||
name = "jury-rigged rocket pod"
|
||||
desc = "A series of pipes, tubes, and cables that resembles a rocket pod."
|
||||
icon_state = "mecha_missilerack-rig"
|
||||
projectile = /obj/item/missile/light
|
||||
projectile = /obj/item/projectile/bullet/srmrocket/weak
|
||||
projectiles = 3
|
||||
projectile_energy_cost = 800
|
||||
|
||||
equip_type = EQUIP_UTILITY
|
||||
equip_type = EQUIP_UTILITY
|
||||
|
||||
+553
-182
@@ -11,47 +11,80 @@
|
||||
req_access = list(access_robotics)
|
||||
circuit = /obj/item/weapon/circuitboard/mechfab
|
||||
|
||||
var/speed = 1
|
||||
var/mat_efficiency = 1
|
||||
var/list/materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, "plastic" = 0, MAT_GRAPHITE = 0, MAT_PLASTEEL = 0, "gold" = 0, "silver" = 0, MAT_LEAD = 0, "osmium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, "phoron" = 0, "uranium" = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0, MAT_METALHYDROGEN = 0, MAT_SUPERMATTER = 0)
|
||||
var/list/hidden_materials = list(MAT_PLASTEEL, MAT_DURASTEEL, MAT_GRAPHITE, MAT_VERDANTIUM, MAT_MORPHIUM, MAT_METALHYDROGEN, MAT_SUPERMATTER)
|
||||
/// Current items in the build queue.
|
||||
var/list/queue = list()
|
||||
/// Whether or not the machine is building the entire queue automagically.
|
||||
var/process_queue = FALSE
|
||||
|
||||
/// The current design datum that the machine is building.
|
||||
var/datum/design/being_built
|
||||
/// World time when the build will finish.
|
||||
var/build_finish = 0
|
||||
/// World time when the build started.
|
||||
var/build_start = 0
|
||||
/// Reference to all materials used in the creation of the item being_built.
|
||||
var/list/build_materials
|
||||
/// Part currently stored in the Exofab.
|
||||
var/obj/item/stored_part
|
||||
|
||||
/// Coefficient for the speed of item building. Based on the installed parts.
|
||||
var/time_coeff = 1
|
||||
/// Coefficient for the efficiency of material usage in item building. Based on the installed parts.
|
||||
var/component_coeff = 1
|
||||
|
||||
var/loading_icon_state = "mechfab-idle"
|
||||
|
||||
var/list/materials = list(
|
||||
DEFAULT_WALL_MATERIAL = 0,
|
||||
"glass" = 0,
|
||||
"plastic" = 0,
|
||||
MAT_GRAPHITE = 0,
|
||||
MAT_PLASTEEL = 0,
|
||||
"gold" = 0,
|
||||
"silver" = 0,
|
||||
MAT_LEAD = 0,
|
||||
"osmium" = 0,
|
||||
"diamond" = 0,
|
||||
MAT_DURASTEEL = 0,
|
||||
"phoron" = 0,
|
||||
"uranium" = 0,
|
||||
MAT_VERDANTIUM = 0,
|
||||
MAT_MORPHIUM = 0,
|
||||
MAT_METALHYDROGEN = 0,
|
||||
MAT_SUPERMATTER = 0)
|
||||
var/res_max_amount = 200000
|
||||
|
||||
var/datum/research/files
|
||||
var/list/datum/design/queue = list()
|
||||
var/progress = 0
|
||||
var/busy = 0
|
||||
|
||||
var/list/categories = list()
|
||||
var/category = null
|
||||
var/sync_message = ""
|
||||
var/valid_buildtype = MECHFAB
|
||||
/// A list of categories that valid MECHFAB design datums will broadly categorise themselves under.
|
||||
var/list/part_sets = list(
|
||||
"Cyborg",
|
||||
"Ripley",
|
||||
"Odysseus",
|
||||
"Gygax",
|
||||
"Durand",
|
||||
"Janus",
|
||||
"Vehicle",
|
||||
"Rigsuit",
|
||||
"Phazon",
|
||||
"Gopher", // VOREStation Add
|
||||
"Polecat", // VOREStation Add
|
||||
"Weasel", // VOREStation Add
|
||||
"Exosuit Equipment",
|
||||
"Exosuit Internals",
|
||||
"Exosuit Ammunition",
|
||||
"Cyborg Upgrade Modules",
|
||||
"Cybernetics",
|
||||
"Implants",
|
||||
"Control Interfaces",
|
||||
"Other",
|
||||
"Misc",
|
||||
)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/Initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
files = new /datum/research(src) //Setup the research data holder.
|
||||
update_categories()
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/process()
|
||||
..()
|
||||
if(stat)
|
||||
return
|
||||
if(busy)
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
progress += speed
|
||||
check_build()
|
||||
else
|
||||
update_use_power(USE_POWER_IDLE)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/update_icon()
|
||||
overlays.Cut()
|
||||
if(panel_open)
|
||||
icon_state = "mechfab-o"
|
||||
else
|
||||
icon_state = "mechfab-idle"
|
||||
if(busy)
|
||||
overlays += "mechfab-active"
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/dismantle()
|
||||
for(var/f in materials)
|
||||
@@ -65,67 +98,507 @@
|
||||
var/T = 0
|
||||
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
|
||||
T += M.rating
|
||||
mat_efficiency = max(1 - (T - 1) / 4, 0.2) // 1 -> 0.2
|
||||
for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts) // Not resetting T is intended; speed is affected by both
|
||||
component_coeff = max(1 - (T - 1) / 4, 0.2) // 1 -> 0.2
|
||||
for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts) // Not resetting T is intended; time_coeff is affected by both
|
||||
T += M.rating
|
||||
speed = T / 2 // 1 -> 3
|
||||
time_coeff = T / 2 // 1 -> 3
|
||||
update_tgui_static_data(usr)
|
||||
|
||||
|
||||
/**
|
||||
* Generates an info list for a given part.
|
||||
*
|
||||
* Returns a list of part information.
|
||||
* * D - Design datum to get information on.
|
||||
* * categories - Boolean, whether or not to parse snowflake categories into the part information list.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/output_part_info(datum/design/D, var/categories = FALSE)
|
||||
var/cost = list()
|
||||
for(var/c in D.materials)
|
||||
cost[c] = get_resource_cost_w_coeff(D, D.materials[c])
|
||||
|
||||
var/obj/built_item = D.build_path
|
||||
|
||||
var/list/category_override = null
|
||||
var/list/sub_category = null
|
||||
|
||||
if(categories)
|
||||
// Handle some special cases to build up sub-categories for the fab interface.
|
||||
// Start with checking if this design builds a cyborg module.
|
||||
if(built_item in typesof(/obj/item/borg/upgrade))
|
||||
var/obj/item/borg/upgrade/U = built_item
|
||||
var/module_types = initial(U.module_flags)
|
||||
sub_category = list()
|
||||
if(module_types)
|
||||
if(module_types & BORG_MODULE_SECURITY)
|
||||
sub_category += "Security"
|
||||
if(module_types & BORG_MODULE_MINER)
|
||||
sub_category += "Mining"
|
||||
if(module_types & BORG_MODULE_JANITOR)
|
||||
sub_category += "Janitor"
|
||||
if(module_types & BORG_MODULE_MEDICAL)
|
||||
sub_category += "Medical"
|
||||
if(module_types & BORG_MODULE_ENGINEERING)
|
||||
sub_category += "Engineering"
|
||||
else
|
||||
sub_category += "All Cyborgs"
|
||||
// Else check if this design builds a piece of exosuit equipment.
|
||||
else if(built_item in typesof(/obj/item/mecha_parts/mecha_equipment))
|
||||
var/obj/item/mecha_parts/mecha_equipment/E = built_item
|
||||
var/mech_types = initial(E.mech_flags)
|
||||
sub_category = "Equipment"
|
||||
if(mech_types)
|
||||
category_override = list()
|
||||
if(mech_types & EXOSUIT_MODULE_RIPLEY)
|
||||
category_override += "Ripley"
|
||||
if(mech_types & EXOSUIT_MODULE_ODYSSEUS)
|
||||
category_override += "Odysseus"
|
||||
if(mech_types & EXOSUIT_MODULE_GYGAX)
|
||||
category_override += "Gygax"
|
||||
if(mech_types & EXOSUIT_MODULE_DURAND)
|
||||
category_override += "Durand"
|
||||
if(mech_types & EXOSUIT_MODULE_PHAZON)
|
||||
category_override += "Phazon"
|
||||
|
||||
var/list/part = list(
|
||||
"name" = D.name,
|
||||
"desc" = initial(built_item.desc),
|
||||
"printTime" = get_construction_time_w_coeff(initial(D.time))/10,
|
||||
"cost" = cost,
|
||||
"id" = D.id,
|
||||
"subCategory" = sub_category,
|
||||
"categoryOverride" = category_override,
|
||||
"searchMeta" = D.search_metadata
|
||||
)
|
||||
|
||||
return part
|
||||
|
||||
|
||||
/**
|
||||
* Generates a list of resources / materials available to this Exosuit Fab
|
||||
*
|
||||
* Returns null if there is no material container available.
|
||||
* List format is list(material_name = list(amount = ..., ref = ..., etc.))
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/output_available_resources()
|
||||
var/list/material_data = list()
|
||||
|
||||
for(var/mat_id in materials)
|
||||
var/amount = materials[mat_id]
|
||||
var/list/material_info = list(
|
||||
"name" = mat_id,
|
||||
"amount" = amount,
|
||||
"sheets" = round(amount / SHEET_MATERIAL_AMOUNT),
|
||||
"removable" = amount >= SHEET_MATERIAL_AMOUNT
|
||||
)
|
||||
|
||||
material_data += list(material_info)
|
||||
|
||||
return material_data
|
||||
|
||||
/**
|
||||
* Intended to be called when an item starts printing.
|
||||
*
|
||||
* Adds the overlay to show the fab working and sets active power usage settings.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/on_start_printing()
|
||||
add_overlay("fab-active")
|
||||
use_power = USE_POWER_ACTIVE
|
||||
|
||||
/**
|
||||
* Intended to be called when the exofab has stopped working and is no longer printing items.
|
||||
*
|
||||
* Removes the overlay to show the fab working and sets idle power usage settings. Additionally resets the description and turns off queue processing.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/on_finish_printing()
|
||||
cut_overlay("fab-active")
|
||||
use_power = USE_POWER_IDLE
|
||||
desc = initial(desc)
|
||||
process_queue = FALSE
|
||||
|
||||
/**
|
||||
* Calculates resource/material costs for printing an item based on the machine's resource coefficient.
|
||||
*
|
||||
* Returns a list of k,v resources with their amounts.
|
||||
* * D - Design datum to calculate the modified resource cost of.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/get_resources_w_coeff(datum/design/D)
|
||||
var/list/resources = list()
|
||||
for(var/mat_id in D.materials)
|
||||
resources[mat_id] = get_resource_cost_w_coeff(D, D.materials[mat_id])
|
||||
return resources
|
||||
|
||||
/**
|
||||
* Checks if the Exofab has enough resources to print a given item.
|
||||
*
|
||||
* Returns FALSE if the design has no reagents used in its construction (?) or if there are insufficient resources.
|
||||
* Returns TRUE if there are sufficient resources to print the item.
|
||||
* * D - Design datum to calculate the modified resource cost of.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/check_resources(datum/design/D)
|
||||
if(length(D.chemicals)) // No reagents storage - no reagent designs.
|
||||
return FALSE
|
||||
. = TRUE
|
||||
var/list/coeff_required = get_resources_w_coeff(D)
|
||||
for(var/mat_id in coeff_required)
|
||||
if(materials[mat_id] < coeff_required[mat_id])
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Attempts to build the next item in the build queue.
|
||||
*
|
||||
* Returns FALSE if either there are no more parts to build or the next part is not buildable.
|
||||
* Returns TRUE if the next part has started building.
|
||||
* * verbose - Whether the machine should use say() procs. Set to FALSE to disable the machine saying reasons for failure to build.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/build_next_in_queue(verbose = TRUE)
|
||||
if(!length(queue))
|
||||
return FALSE
|
||||
|
||||
var/datum/design/D = queue[1]
|
||||
if(build_part(D, verbose))
|
||||
remove_from_queue(1)
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Starts the build process for a given design datum.
|
||||
*
|
||||
* Returns FALSE if the procedure fails. Returns TRUE when being_built is set.
|
||||
* Uses materials.
|
||||
* * D - Design datum to attempt to print.
|
||||
* * verbose - Whether the machine should use say() procs. Set to FALSE to disable the machine saying reasons for failure to build.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/build_part(datum/design/D, verbose = TRUE)
|
||||
if(!D)
|
||||
return FALSE
|
||||
|
||||
if(!check_resources(D))
|
||||
if(verbose)
|
||||
atom_say("Not enough resources. Processing stopped.")
|
||||
return FALSE
|
||||
|
||||
build_materials = get_resources_w_coeff(D)
|
||||
for(var/mat_id in build_materials)
|
||||
materials[mat_id] -= build_materials[mat_id]
|
||||
|
||||
being_built = D
|
||||
build_finish = world.time + get_construction_time_w_coeff(initial(D.time))
|
||||
build_start = world.time
|
||||
desc = "It's building \a [D.name]."
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/process()
|
||||
..()
|
||||
// If there's a stored part to dispense due to an obstruction, try to dispense it.
|
||||
if(stored_part)
|
||||
var/turf/exit = get_step(src,(dir))
|
||||
if(exit.density)
|
||||
return TRUE
|
||||
|
||||
atom_say("Obstruction cleared. \The [stored_part] is complete.")
|
||||
stored_part.forceMove(exit)
|
||||
stored_part = null
|
||||
|
||||
// If there's nothing being built, try to build something
|
||||
if(!being_built)
|
||||
// If we're not processing the queue anymore or there's nothing to build, end processing.
|
||||
if(!process_queue || !build_next_in_queue())
|
||||
on_finish_printing()
|
||||
return PROCESS_KILL
|
||||
on_start_printing()
|
||||
|
||||
// If there's an item being built, check if it is complete.
|
||||
if(being_built && (build_finish < world.time))
|
||||
// Then attempt to dispense it and if appropriate build the next item.
|
||||
dispense_built_part(being_built)
|
||||
if(process_queue)
|
||||
build_next_in_queue(FALSE)
|
||||
return TRUE
|
||||
|
||||
|
||||
/**
|
||||
* Dispenses a part to the tile infront of the Exosuit Fab.
|
||||
*
|
||||
* Returns FALSE is the machine cannot dispense the part on the appropriate turf.
|
||||
* Return TRUE if the part was successfully dispensed.
|
||||
* * D - Design datum to attempt to dispense.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/dispense_built_part(datum/design/D)
|
||||
var/obj/item/I = D.Fabricate(src, src)
|
||||
// I.material_flags |= MATERIAL_NO_EFFECTS //Find a better way to do this.
|
||||
// I.set_custom_materials(build_materials)
|
||||
|
||||
being_built = null
|
||||
|
||||
var/turf/exit = get_step(src,(dir))
|
||||
if(exit.density)
|
||||
atom_say("Error! Part outlet is obstructed.")
|
||||
desc = "It's trying to dispense \a [D.name], but the part outlet is obstructed."
|
||||
stored_part = I
|
||||
return FALSE
|
||||
|
||||
atom_say("\The [I] is complete.")
|
||||
I.forceMove(exit)
|
||||
return I
|
||||
|
||||
/**
|
||||
* Adds a list of datum designs to the build queue.
|
||||
*
|
||||
* Will only add designs that are in this machine's stored techweb.
|
||||
* Does final checks for datum IDs and makes sure this machine can build the designs.
|
||||
* * part_list - List of datum design ids for designs to add to the queue.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/add_part_set_to_queue(list/part_list)
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if((D.build_type & valid_buildtype) && (D.id in part_list))
|
||||
add_to_queue(D)
|
||||
|
||||
/**
|
||||
* Adds a datum design to the build queue.
|
||||
*
|
||||
* Returns TRUE if successful and FALSE if the design was not added to the queue.
|
||||
* * D - Datum design to add to the queue.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/add_to_queue(datum/design/D)
|
||||
if(!istype(queue))
|
||||
queue = list()
|
||||
if(D)
|
||||
queue[++queue.len] = D
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Removes datum design from the build queue based on index.
|
||||
*
|
||||
* Returns TRUE if successful and FALSE if a design was not removed from the queue.
|
||||
* * index - Index in the build queue of the element to remove.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/remove_from_queue(index)
|
||||
if(!isnum(index) || !ISINTEGER(index) || !istype(queue) || (index<1 || index>length(queue)))
|
||||
return FALSE
|
||||
queue.Cut(index,++index)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Generates a list of parts formatted for tgui based on the current build queue.
|
||||
*
|
||||
* Returns a formatted list of lists containing formatted part information for every part in the build queue.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/list_queue()
|
||||
if(!istype(queue) || !length(queue))
|
||||
return null
|
||||
|
||||
var/list/queued_parts = list()
|
||||
for(var/datum/design/D in queue)
|
||||
var/list/part = output_part_info(D)
|
||||
queued_parts += list(part)
|
||||
return queued_parts
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/sync()
|
||||
for(var/obj/machinery/computer/rdconsole/RDC in get_area_all_atoms(get_area(src)))
|
||||
if(!RDC.sync)
|
||||
continue
|
||||
for(var/datum/tech/T in RDC.files.known_tech)
|
||||
files.AddTech2Known(T)
|
||||
for(var/datum/design/D in RDC.files.known_designs)
|
||||
files.AddDesign2Known(D)
|
||||
files.RefreshResearch()
|
||||
update_tgui_static_data(usr)
|
||||
atom_say("Successfully synchronized with R&D server.")
|
||||
return
|
||||
|
||||
atom_say("Unable to connect to local R&D server.")
|
||||
return
|
||||
|
||||
/**
|
||||
* Calculates the coefficient-modified resource cost of a single material component of a design's recipe.
|
||||
*
|
||||
* Returns coefficient-modified resource cost for the given material component.
|
||||
* * D - Design datum to pull the resource cost from.
|
||||
* * resource - Material datum reference to the resource to calculate the cost of.
|
||||
* * roundto - Rounding value for round() proc
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/get_resource_cost_w_coeff(datum/design/D, var/amt, roundto = 1)
|
||||
return round(amt * component_coeff, roundto)
|
||||
|
||||
/**
|
||||
* Calculates the coefficient-modified build time of a design.
|
||||
*
|
||||
* Returns coefficient-modified build time of a given design.
|
||||
* * D - Design datum to calculate the modified build time of.
|
||||
* * roundto - Rounding value for round() proc
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/get_construction_time_w_coeff(construction_time, roundto = 1) //aran
|
||||
return round(construction_time * time_coeff, roundto)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/spritesheet/sheetmaterials)
|
||||
)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/attack_hand(var/mob/user)
|
||||
if(..())
|
||||
return
|
||||
if(!allowed(user))
|
||||
return
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/ui_interact(var/mob/user, var/ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
|
||||
var/datum/design/current = queue.len ? queue[1] : null
|
||||
if(current)
|
||||
data["current"] = current.name
|
||||
data["queue"] = get_queue_names()
|
||||
data["buildable"] = get_build_options()
|
||||
data["category"] = category
|
||||
data["categories"] = categories
|
||||
data["materials"] = get_materials()
|
||||
data["maxres"] = res_max_amount
|
||||
data["sync"] = sync_message
|
||||
if(current)
|
||||
data["builtperc"] = round((progress / current.time) * 100)
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
/obj/machinery/mecha_part_fabricator/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "mechfab.tmpl", "Exosuit Fabricator UI", 800, 600)
|
||||
ui.set_initial_data(data)
|
||||
ui = new(user, src, "ExosuitFabricator", name)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
/obj/machinery/mecha_part_fabricator/tgui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
if(href_list["build"])
|
||||
add_to_queue(text2num(href_list["build"]))
|
||||
var/list/final_sets = list()
|
||||
var/list/buildable_parts = list()
|
||||
|
||||
if(href_list["remove"])
|
||||
remove_from_queue(text2num(href_list["remove"]))
|
||||
for(var/part_set in part_sets)
|
||||
final_sets += part_set
|
||||
|
||||
if(href_list["category"])
|
||||
if(href_list["category"] in categories)
|
||||
category = href_list["category"]
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if((D.build_type & valid_buildtype) && D.id != "id") // bugfix for weird null entries
|
||||
// This is for us.
|
||||
var/list/part = output_part_info(D, TRUE)
|
||||
|
||||
if(href_list["eject"])
|
||||
eject_materials(href_list["eject"], text2num(href_list["amount"]))
|
||||
if(part["categoryOverride"])
|
||||
for(var/cat in part["categoryOverride"])
|
||||
buildable_parts[cat] += list(part)
|
||||
if(!(cat in part_sets))
|
||||
final_sets += cat
|
||||
continue
|
||||
|
||||
if(href_list["sync"])
|
||||
sync()
|
||||
for(var/cat in part_sets)
|
||||
// Find all matching categories.
|
||||
if(!(cat in D.category))
|
||||
continue
|
||||
|
||||
buildable_parts[cat] += list(part)
|
||||
|
||||
data["partSets"] = final_sets
|
||||
data["buildableParts"] = buildable_parts
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["materials"] = output_available_resources()
|
||||
|
||||
if(being_built)
|
||||
var/list/part = list(
|
||||
"name" = being_built.name,
|
||||
"duration" = build_finish - world.time,
|
||||
"printTime" = get_construction_time_w_coeff(initial(being_built.time))
|
||||
)
|
||||
data["buildingPart"] = part
|
||||
else
|
||||
sync_message = ""
|
||||
data["buildingPart"] = null
|
||||
|
||||
return 1
|
||||
data["queue"] = list_queue()
|
||||
|
||||
if(stored_part)
|
||||
data["storedPart"] = stored_part.name
|
||||
else
|
||||
data["storedPart"] = null
|
||||
|
||||
data["isProcessingQueue"] = process_queue
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/tgui_act(action, var/list/params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
. = TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
usr.set_machine(src)
|
||||
|
||||
switch(action)
|
||||
if("sync_rnd")
|
||||
// Sync with R&D Servers
|
||||
sync()
|
||||
return
|
||||
if("add_queue_set")
|
||||
// Add all parts of a set to queue
|
||||
var/part_list = params["part_list"]
|
||||
add_part_set_to_queue(part_list)
|
||||
return
|
||||
if("add_queue_part")
|
||||
// Add a specific part to queue
|
||||
var/T = params["id"]
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if((D.build_type & valid_buildtype) && (D.id == T))
|
||||
add_to_queue(D)
|
||||
break
|
||||
return
|
||||
if("del_queue_part")
|
||||
// Delete a specific from from the queue
|
||||
var/index = text2num(params["index"])
|
||||
remove_from_queue(index)
|
||||
return
|
||||
if("clear_queue")
|
||||
// Delete everything from queue
|
||||
queue.Cut()
|
||||
return
|
||||
if("build_queue")
|
||||
// Build everything in queue
|
||||
if(process_queue)
|
||||
return
|
||||
process_queue = TRUE
|
||||
|
||||
if(!being_built)
|
||||
START_PROCESSING(SSobj, src)
|
||||
return
|
||||
if("stop_queue")
|
||||
// Pause queue building. Also known as stop.
|
||||
process_queue = FALSE
|
||||
return
|
||||
if("build_part")
|
||||
// Build a single part
|
||||
if(being_built || process_queue)
|
||||
return
|
||||
|
||||
var/id = params["id"]
|
||||
var/datum/design/D = null
|
||||
for(var/datum/design/D_new in files.known_designs)
|
||||
if((D_new.build_type == valid_buildtype) && (D_new.id == id))
|
||||
D = D_new
|
||||
break
|
||||
|
||||
if(!D)
|
||||
return
|
||||
|
||||
if(build_part(D))
|
||||
on_start_printing()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
return
|
||||
if("move_queue_part")
|
||||
// Moves a part up or down in the queue.
|
||||
var/index = text2num(params["index"])
|
||||
var/new_index = index + text2num(params["newindex"])
|
||||
if(isnum(index) && isnum(new_index) && ISINTEGER(index) && ISINTEGER(new_index))
|
||||
if(ISINRANGE(new_index,1,length(queue)))
|
||||
queue.Swap(index,new_index)
|
||||
return
|
||||
if("remove_mat")
|
||||
// Remove a material from the fab
|
||||
var/mat_id = params["id"]
|
||||
var/amount = text2num(params["amount"])
|
||||
eject_materials(mat_id, amount)
|
||||
return
|
||||
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/attackby(var/obj/item/I, var/mob/user)
|
||||
if(busy)
|
||||
if(being_built)
|
||||
to_chat(user, "<span class='notice'>\The [src] is busy. Please wait for completion of previous operation.</span>")
|
||||
return 1
|
||||
if(default_deconstruction_screwdriver(user, I))
|
||||
@@ -146,15 +619,17 @@
|
||||
if(materials[S.material.name] + amnt <= res_max_amount)
|
||||
if(S && S.get_amount() >= 1)
|
||||
var/count = 0
|
||||
overlays += "mechfab-load-metal"
|
||||
spawn(10)
|
||||
overlays -= "mechfab-load-metal"
|
||||
flick("[loading_icon_state]", src)
|
||||
// yess hacky but whatever
|
||||
if(loading_icon_state == "mechfab-idle")
|
||||
overlays += "mechfab-load-metal"
|
||||
spawn(10)
|
||||
overlays -= "mechfab-load-metal"
|
||||
while(materials[S.material.name] + amnt <= res_max_amount && S.get_amount() >= 1)
|
||||
materials[S.material.name] += amnt
|
||||
S.use(1)
|
||||
count++
|
||||
to_chat(user, "You insert [count] [sname] into the fabricator.")
|
||||
update_busy()
|
||||
else
|
||||
to_chat(user, "The fabricator cannot hold more [sname].")
|
||||
|
||||
@@ -181,96 +656,6 @@
|
||||
if(1)
|
||||
visible_message("[bicon(src)] <b>[src]</b> beeps: \"No records in User DB\"")
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/update_busy()
|
||||
if(queue.len)
|
||||
if(can_build(queue[1]))
|
||||
busy = 1
|
||||
else
|
||||
busy = 0
|
||||
else
|
||||
busy = 0
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/add_to_queue(var/index)
|
||||
var/datum/design/D = files.known_designs[index]
|
||||
queue += D
|
||||
update_busy()
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/remove_from_queue(var/index)
|
||||
if(index == 1)
|
||||
progress = 0
|
||||
queue.Cut(index, index + 1)
|
||||
update_busy()
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/can_build(var/datum/design/D)
|
||||
for(var/M in D.materials)
|
||||
if(materials[M] < (D.materials[M] * mat_efficiency))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/check_build()
|
||||
if(!queue.len)
|
||||
progress = 0
|
||||
return
|
||||
var/datum/design/D = queue[1]
|
||||
if(!can_build(D))
|
||||
progress = 0
|
||||
return
|
||||
if(D.time > progress)
|
||||
return
|
||||
for(var/M in D.materials)
|
||||
materials[M] = max(0, materials[M] - D.materials[M] * mat_efficiency)
|
||||
if(D.build_path)
|
||||
var/obj/new_item = D.Fabricate(get_step(get_turf(src), src.dir), src)
|
||||
visible_message("\The [src] pings, indicating that \the [D] is complete.", "You hear a ping.")
|
||||
if(mat_efficiency != 1)
|
||||
if(new_item.matter && new_item.matter.len > 0)
|
||||
for(var/i in new_item.matter)
|
||||
new_item.matter[i] = new_item.matter[i] * mat_efficiency
|
||||
remove_from_queue(1)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/get_queue_names()
|
||||
. = list()
|
||||
for(var/i = 2 to queue.len)
|
||||
var/datum/design/D = queue[i]
|
||||
. += D.name
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/get_build_options()
|
||||
. = list()
|
||||
for(var/i = 1 to files.known_designs.len)
|
||||
var/datum/design/D = files.known_designs[i]
|
||||
if(!D.build_path || !(D.build_type & MECHFAB))
|
||||
continue
|
||||
. += list(list("name" = D.name, "id" = i, "category" = D.category, "resourses" = get_design_resourses(D), "time" = get_design_time(D)))
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/get_design_resourses(var/datum/design/D)
|
||||
var/list/F = list()
|
||||
for(var/T in D.materials)
|
||||
F += "[capitalize(T)]: [D.materials[T] * mat_efficiency]"
|
||||
return english_list(F, and_text = ", ")
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/get_design_time(var/datum/design/D)
|
||||
return time2text(round(10 * D.time / speed), "mm:ss")
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/update_categories()
|
||||
categories = list()
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(!D.build_path || !(D.build_type & MECHFAB))
|
||||
continue
|
||||
categories |= D.category
|
||||
if(!category || !(category in categories))
|
||||
category = categories[1]
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/get_materials()
|
||||
. = list()
|
||||
for(var/T in materials)
|
||||
var/hidden_mat = FALSE
|
||||
for(var/HM in hidden_materials) // Direct list contents comparison was failing.
|
||||
if(T == HM && materials[T] == 0)
|
||||
hidden_mat = TRUE
|
||||
continue
|
||||
if(!hidden_mat)
|
||||
. += list(list("mat" = capitalize(T), "amt" = materials[T]))
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/eject_materials(var/material, var/amount) // 0 amount = 0 means ejecting a full stack; -1 means eject everything
|
||||
var/recursive = amount == -1 ? 1 : 0
|
||||
var/matstring = lowertext(material)
|
||||
@@ -287,17 +672,3 @@
|
||||
materials[matstring] -= ejected * S.perunit
|
||||
if(recursive && materials[matstring] >= S.perunit)
|
||||
eject_materials(matstring, -1)
|
||||
update_busy()
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/sync()
|
||||
sync_message = "Error: no console found."
|
||||
for(var/obj/machinery/computer/rdconsole/RDC in get_area_all_atoms(get_area(src)))
|
||||
if(!RDC.sync)
|
||||
continue
|
||||
for(var/datum/tech/T in RDC.files.known_tech)
|
||||
files.AddTech2Known(T)
|
||||
for(var/datum/design/D in RDC.files.known_designs)
|
||||
files.AddDesign2Known(D)
|
||||
files.RefreshResearch()
|
||||
sync_message = "Sync complete."
|
||||
update_categories()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/machinery/pros_fabricator
|
||||
/obj/machinery/mecha_part_fabricator/pros
|
||||
icon = 'icons/obj/robotics.dmi'
|
||||
icon_state = "prosfab"
|
||||
name = "Prosthetics Fabricator"
|
||||
@@ -11,158 +11,126 @@
|
||||
req_access = list(access_robotics)
|
||||
circuit = /obj/item/weapon/circuitboard/prosthetics
|
||||
|
||||
var/speed = 1
|
||||
var/mat_efficiency = 1
|
||||
var/list/materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, "plastic" = 0, MAT_GRAPHITE = 0, MAT_PLASTEEL = 0, "gold" = 0, "silver" = 0, MAT_LEAD = 0, "osmium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, "phoron" = 0, "uranium" = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0)
|
||||
var/list/hidden_materials = list(MAT_DURASTEEL, MAT_GRAPHITE, MAT_VERDANTIUM, MAT_MORPHIUM)
|
||||
var/res_max_amount = 200000
|
||||
|
||||
var/datum/research/files
|
||||
var/list/datum/design/queue = list()
|
||||
var/progress = 0
|
||||
var/busy = 0
|
||||
|
||||
var/list/categories = list()
|
||||
var/category = null
|
||||
// Prosfab specific stuff
|
||||
var/manufacturer = null
|
||||
var/species_types = list("Human")
|
||||
var/species = "Human"
|
||||
var/sync_message = ""
|
||||
|
||||
/obj/machinery/pros_fabricator/Initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
loading_icon_state = "prosfab_loading"
|
||||
|
||||
files = new /datum/research(src) //Setup the research data holder.
|
||||
materials = list(
|
||||
DEFAULT_WALL_MATERIAL = 0,
|
||||
"glass" = 0,
|
||||
"plastic" = 0,
|
||||
MAT_GRAPHITE = 0,
|
||||
MAT_PLASTEEL = 0,
|
||||
"gold" = 0,
|
||||
"silver" = 0,
|
||||
MAT_LEAD = 0,
|
||||
"osmium" = 0,
|
||||
"diamond" = 0,
|
||||
MAT_DURASTEEL = 0,
|
||||
"phoron" = 0,
|
||||
"uranium" = 0,
|
||||
MAT_VERDANTIUM = 0,
|
||||
MAT_MORPHIUM = 0)
|
||||
res_max_amount = 200000
|
||||
|
||||
/obj/machinery/pros_fabricator/Initialize()
|
||||
valid_buildtype = PROSFAB
|
||||
/// A list of categories that valid PROSFAB design datums will broadly categorise themselves under.
|
||||
part_sets = list(
|
||||
"Cyborg",
|
||||
"Ripley",
|
||||
"Odysseus",
|
||||
"Gygax",
|
||||
"Durand",
|
||||
"Janus",
|
||||
"Vehicle",
|
||||
"Rigsuit",
|
||||
"Phazon",
|
||||
"Gopher", // VOREStation Add
|
||||
"Polecat", // VOREStation Add
|
||||
"Weasel", // VOREStation Add
|
||||
"Exosuit Equipment",
|
||||
"Exosuit Internals",
|
||||
"Exosuit Ammunition",
|
||||
"Cyborg Modules",
|
||||
"Prosthetics",
|
||||
"Prosthetics, Internal",
|
||||
"Cyborg Parts",
|
||||
"Cyborg Internals",
|
||||
"Cybernetics",
|
||||
"Implants",
|
||||
"Control Interfaces",
|
||||
"Other",
|
||||
"Misc",
|
||||
)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/pros/Initialize()
|
||||
. = ..()
|
||||
manufacturer = basic_robolimb.company
|
||||
update_categories()
|
||||
|
||||
/obj/machinery/pros_fabricator/process()
|
||||
..()
|
||||
if(stat)
|
||||
return
|
||||
if(busy)
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
progress += speed
|
||||
check_build()
|
||||
else
|
||||
update_use_power(USE_POWER_IDLE)
|
||||
update_icon()
|
||||
/obj/machinery/mecha_part_fabricator/pros/dispense_built_part(datum/design/D)
|
||||
var/obj/item/I = ..()
|
||||
if(isobj(I) && I.matter && I.matter.len > 0)
|
||||
for(var/i in I.matter)
|
||||
I.matter[i] = I.matter[i] * component_coeff
|
||||
|
||||
/obj/machinery/pros_fabricator/update_icon()
|
||||
overlays.Cut()
|
||||
icon_state = initial(icon_state)
|
||||
/obj/machinery/mecha_part_fabricator/pros/tgui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
if(panel_open)
|
||||
overlays.Add(image(icon, "[icon_state]_panel"))
|
||||
if(stat & NOPOWER)
|
||||
return
|
||||
if(busy)
|
||||
icon_state = "[icon_state]_work"
|
||||
|
||||
/obj/machinery/pros_fabricator/dismantle()
|
||||
for(var/f in materials)
|
||||
eject_materials(f, -1)
|
||||
..()
|
||||
|
||||
/obj/machinery/pros_fabricator/RefreshParts()
|
||||
res_max_amount = 0
|
||||
for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts)
|
||||
res_max_amount += M.rating * 100000 // 200k -> 600k
|
||||
var/T = 0
|
||||
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
|
||||
T += M.rating
|
||||
mat_efficiency = max(0.2, 1 - (T - 1) / 4) // 1 -> 0.2
|
||||
for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts) // Not resetting T is intended; speed is affected by both
|
||||
T += M.rating
|
||||
speed = T / 2 // 1 -> 3
|
||||
|
||||
/obj/machinery/pros_fabricator/attack_hand(var/mob/user)
|
||||
if(..())
|
||||
return
|
||||
if(!allowed(user))
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/pros_fabricator/ui_interact(var/mob/user, var/ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
|
||||
var/datum/design/current = queue.len ? queue[1] : null
|
||||
if(current)
|
||||
data["current"] = current.name
|
||||
data["queue"] = get_queue_names()
|
||||
data["buildable"] = get_build_options()
|
||||
data["category"] = category
|
||||
data["categories"] = categories
|
||||
data["species_types"] = species_types
|
||||
data["species"] = species
|
||||
|
||||
if(all_robolimbs)
|
||||
var/list/T = list()
|
||||
for(var/A in all_robolimbs)
|
||||
var/datum/robolimb/R = all_robolimbs[A]
|
||||
if(R.unavailable_to_build) continue
|
||||
if(species in R.species_cannot_use) continue
|
||||
if(R.unavailable_to_build)
|
||||
continue
|
||||
if(species in R.species_cannot_use)
|
||||
continue
|
||||
T += list(list("id" = A, "company" = R.company))
|
||||
data["manufacturers"] = T
|
||||
data["manufacturer"] = manufacturer
|
||||
data["materials"] = get_materials()
|
||||
data["maxres"] = res_max_amount
|
||||
data["sync"] = sync_message
|
||||
if(current)
|
||||
data["builtperc"] = round((progress / current.time) * 100)
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "mechfab.tmpl", "Prosthetics Fab UI", 800, 600)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
data["manufacturer"] = manufacturer
|
||||
|
||||
/obj/machinery/pros_fabricator/Topic(href, href_list)
|
||||
return data
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/pros/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return
|
||||
return TRUE
|
||||
|
||||
if(href_list["build"])
|
||||
add_to_queue(text2num(href_list["build"]))
|
||||
. = TRUE
|
||||
|
||||
if(href_list["remove"])
|
||||
remove_from_queue(text2num(href_list["remove"]))
|
||||
add_fingerprint(usr)
|
||||
usr.set_machine(src)
|
||||
|
||||
if(href_list["category"])
|
||||
if(href_list["category"] in categories)
|
||||
category = href_list["category"]
|
||||
switch(action)
|
||||
if("species")
|
||||
var/new_species = input(usr, "Select a new species", "Prosfab Species Selection", "Human") as null|anything in species_types
|
||||
if(new_species && tgui_status(usr, state) == STATUS_INTERACTIVE)
|
||||
species = new_species
|
||||
return
|
||||
if("manufacturer")
|
||||
var/list/new_manufacturers = list()
|
||||
for(var/A in all_robolimbs)
|
||||
var/datum/robolimb/R = all_robolimbs[A]
|
||||
if(R.unavailable_to_build)
|
||||
continue
|
||||
if(species in R.species_cannot_use)
|
||||
continue
|
||||
new_manufacturers += A
|
||||
|
||||
if(href_list["species"])
|
||||
if(href_list["species"] in species_types)
|
||||
species = href_list["species"]
|
||||
var/new_manufacturer = input(usr, "Select a new manufacturer", "Prosfab Species Selection", "Unbranded") as null|anything in new_manufacturers
|
||||
if(new_manufacturer && tgui_status(usr, state) == STATUS_INTERACTIVE)
|
||||
manufacturer = new_manufacturer
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if(href_list["manufacturer"])
|
||||
if(href_list["manufacturer"] in all_robolimbs)
|
||||
manufacturer = href_list["manufacturer"]
|
||||
|
||||
if(href_list["eject"])
|
||||
eject_materials(href_list["eject"], text2num(href_list["amount"]))
|
||||
|
||||
if(href_list["sync"])
|
||||
sync()
|
||||
else
|
||||
sync_message = ""
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/pros_fabricator/attackby(var/obj/item/I, var/mob/user)
|
||||
if(busy)
|
||||
to_chat(user, "<span class='notice'>\The [src] is busy. Please wait for completion of previous operation.</span>")
|
||||
/obj/machinery/mecha_part_fabricator/pros/attackby(var/obj/item/I, var/mob/user)
|
||||
if(..())
|
||||
return 1
|
||||
if(default_deconstruction_screwdriver(user, I))
|
||||
return
|
||||
if(default_deconstruction_crowbar(user, I))
|
||||
return
|
||||
if(default_part_replacement(user, I))
|
||||
return
|
||||
|
||||
if(istype(I,/obj/item/weapon/disk/limb))
|
||||
var/obj/item/weapon/disk/limb/D = I
|
||||
@@ -188,168 +156,3 @@
|
||||
to_chat(user, "<span class='notice'>Uploaded [D.species] files!</span>")
|
||||
qdel(I)
|
||||
return
|
||||
|
||||
if(istype(I,/obj/item/stack/material))
|
||||
var/obj/item/stack/material/S = I
|
||||
if(!(S.material.name in materials))
|
||||
to_chat(user, "<span class='warning'>The [src] doesn't accept [S.material]!</span>")
|
||||
return
|
||||
|
||||
var/sname = "[S.name]"
|
||||
var/amnt = S.perunit
|
||||
if(materials[S.material.name] + amnt <= res_max_amount)
|
||||
if(S && S.get_amount() >= 1)
|
||||
var/count = 0
|
||||
flick("[initial(icon_state)]_loading", src)
|
||||
while(materials[S.material.name] + amnt <= res_max_amount && S.get_amount() >= 1)
|
||||
materials[S.material.name] += amnt
|
||||
S.use(1)
|
||||
count++
|
||||
to_chat(user, "You insert [count] [sname] into the fabricator.")
|
||||
update_busy()
|
||||
else
|
||||
to_chat(user, "The fabricator cannot hold more [sname].")
|
||||
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
/obj/machinery/pros_fabricator/emag_act(var/remaining_charges, var/mob/user)
|
||||
switch(emagged)
|
||||
if(0)
|
||||
emagged = 0.5
|
||||
visible_message("[bicon(src)] <b>[src]</b> beeps: \"DB error \[Code 0x00F1\]\"")
|
||||
sleep(10)
|
||||
visible_message("[bicon(src)] <b>[src]</b> beeps: \"Attempting auto-repair\"")
|
||||
sleep(15)
|
||||
visible_message("[bicon(src)] <b>[src]</b> beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"")
|
||||
sleep(30)
|
||||
visible_message("[bicon(src)] <b>[src]</b> beeps: \"User DB truncated. Please contact your [using_map.company_name] system operator for future assistance.\"")
|
||||
req_access = null
|
||||
emagged = 1
|
||||
return 1
|
||||
if(0.5)
|
||||
visible_message("[bicon(src)] <b>[src]</b> beeps: \"DB not responding \[Code 0x0003\]...\"")
|
||||
if(1)
|
||||
visible_message("[bicon(src)] <b>[src]</b> beeps: \"No records in User DB\"")
|
||||
|
||||
/obj/machinery/pros_fabricator/proc/update_busy()
|
||||
if(queue.len)
|
||||
if(can_build(queue[1]))
|
||||
busy = 1
|
||||
else
|
||||
busy = 0
|
||||
else
|
||||
busy = 0
|
||||
|
||||
/obj/machinery/pros_fabricator/proc/add_to_queue(var/index)
|
||||
var/datum/design/D = files.known_designs[index]
|
||||
queue += D
|
||||
update_busy()
|
||||
|
||||
/obj/machinery/pros_fabricator/proc/remove_from_queue(var/index)
|
||||
if(index == 1)
|
||||
progress = 0
|
||||
queue.Cut(index, index + 1)
|
||||
update_busy()
|
||||
|
||||
/obj/machinery/pros_fabricator/proc/can_build(var/datum/design/D)
|
||||
for(var/M in D.materials)
|
||||
if(materials[M] < (D.materials[M] * mat_efficiency))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/pros_fabricator/proc/check_build()
|
||||
if(!queue.len)
|
||||
progress = 0
|
||||
return
|
||||
var/datum/design/D = queue[1]
|
||||
if(!can_build(D))
|
||||
progress = 0
|
||||
return
|
||||
if(D.time > progress)
|
||||
return
|
||||
for(var/M in D.materials)
|
||||
materials[M] = max(0, materials[M] - D.materials[M] * mat_efficiency)
|
||||
if(D.build_path)
|
||||
var/obj/new_item = D.Fabricate(get_step(get_turf(src), src.dir), src) // Sometimes returns a mob. Beware!
|
||||
flick("[initial(icon_state)]_finish", src)
|
||||
visible_message("\The [src] pings, indicating that \the [D] is complete.", "You hear a ping.")
|
||||
if(mat_efficiency != 1)
|
||||
if(istype(new_item, /obj/) && new_item.matter && new_item.matter.len > 0)
|
||||
for(var/i in new_item.matter)
|
||||
new_item.matter[i] = new_item.matter[i] * mat_efficiency
|
||||
remove_from_queue(1)
|
||||
|
||||
/obj/machinery/pros_fabricator/proc/get_queue_names()
|
||||
. = list()
|
||||
for(var/i = 2 to queue.len)
|
||||
var/datum/design/D = queue[i]
|
||||
. += D.name
|
||||
|
||||
/obj/machinery/pros_fabricator/proc/get_build_options()
|
||||
. = list()
|
||||
for(var/i = 1 to files.known_designs.len)
|
||||
var/datum/design/D = files.known_designs[i]
|
||||
if(D.build_path && (D.build_type & PROSFAB))
|
||||
. += list(list("name" = D.name, "id" = i, "category" = D.category, "resourses" = get_design_resourses(D), "time" = get_design_time(D)))
|
||||
|
||||
/obj/machinery/pros_fabricator/proc/get_design_resourses(var/datum/design/D)
|
||||
var/list/F = list()
|
||||
for(var/T in D.materials)
|
||||
F += "[capitalize(T)]: [D.materials[T] * mat_efficiency]"
|
||||
return english_list(F, and_text = ", ")
|
||||
|
||||
/obj/machinery/pros_fabricator/proc/get_design_time(var/datum/design/D)
|
||||
return time2text(round(10 * D.time / speed), "mm:ss")
|
||||
|
||||
/obj/machinery/pros_fabricator/proc/update_categories()
|
||||
categories = list()
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(!D.build_path || !(D.build_type & PROSFAB))
|
||||
continue
|
||||
categories |= D.category
|
||||
if(!category || !(category in categories))
|
||||
category = categories[1]
|
||||
|
||||
/obj/machinery/pros_fabricator/proc/get_materials()
|
||||
. = list()
|
||||
for(var/T in materials)
|
||||
var/hidden_mat = FALSE
|
||||
for(var/HM in hidden_materials) // Direct list contents comparison was failing.
|
||||
if(T == HM && materials[T] == 0)
|
||||
hidden_mat = TRUE
|
||||
continue
|
||||
if(!hidden_mat)
|
||||
. += list(list("mat" = capitalize(T), "amt" = materials[T]))
|
||||
|
||||
/obj/machinery/pros_fabricator/proc/eject_materials(var/material, var/amount) // 0 amount = 0 means ejecting a full stack; -1 means eject everything
|
||||
var/recursive = amount == -1 ? 1 : 0
|
||||
var/matstring = lowertext(material)
|
||||
var/material/M = get_material_by_name(matstring)
|
||||
|
||||
var/obj/item/stack/material/S = M.place_sheet(get_turf(src))
|
||||
if(amount <= 0)
|
||||
amount = S.max_amount
|
||||
var/ejected = min(round(materials[matstring] / S.perunit), amount)
|
||||
S.amount = min(ejected, amount)
|
||||
if(S.amount <= 0)
|
||||
qdel(S)
|
||||
return
|
||||
materials[matstring] -= ejected * S.perunit
|
||||
if(recursive && materials[matstring] >= S.perunit)
|
||||
eject_materials(matstring, -1)
|
||||
update_busy()
|
||||
|
||||
/obj/machinery/pros_fabricator/proc/sync()
|
||||
sync_message = "Error: no console found."
|
||||
for(var/obj/machinery/computer/rdconsole/RDC in get_area_all_atoms(get_area(src)))
|
||||
if(!RDC.sync)
|
||||
continue
|
||||
for(var/datum/tech/T in RDC.files.known_tech)
|
||||
files.AddTech2Known(T)
|
||||
for(var/datum/design/D in RDC.files.known_designs)
|
||||
files.AddDesign2Known(D)
|
||||
files.RefreshResearch()
|
||||
sync_message = "Sync complete."
|
||||
update_categories()
|
||||
|
||||
@@ -2243,6 +2243,16 @@
|
||||
output += "</body></html>"
|
||||
return output
|
||||
|
||||
/obj/mecha/proc/get_log_tgui()
|
||||
var/list/data = list()
|
||||
for(var/list/entry in log)
|
||||
data.Add(list(list(
|
||||
"time" = time2text(entry["time"], "DDD MMM DD hh:mm:ss"),
|
||||
"year" = game_year,
|
||||
"message" = entry["message"],
|
||||
)))
|
||||
return data
|
||||
|
||||
|
||||
/obj/mecha/proc/output_access_dialog(obj/item/weapon/card/id/id_card, mob/user)
|
||||
if(!id_card || !user) return
|
||||
|
||||
@@ -8,61 +8,65 @@
|
||||
circuit = /obj/item/weapon/circuitboard/mecha_control
|
||||
var/list/located = list()
|
||||
var/screen = 0
|
||||
var/stored_data
|
||||
var/list/stored_data
|
||||
|
||||
attack_ai(var/mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
/obj/machinery/computer/mecha/attack_ai(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
attack_hand(var/mob/user as mob)
|
||||
if(..())
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<html><head><title>[src.name]</title><style>h3 {margin: 0px; padding: 0px;}</style></head><body>"
|
||||
if(screen == 0)
|
||||
dat += "<h3>Tracking beacons data</h3>"
|
||||
for(var/obj/item/mecha_parts/mecha_tracking/TR in world)
|
||||
var/answer = TR.get_mecha_info()
|
||||
if(answer)
|
||||
dat += {"<hr>[answer]<br/>
|
||||
<a href='?src=\ref[src];send_message=\ref[TR]'>Send message</a><br/>
|
||||
<a href='?src=\ref[src];get_log=\ref[TR]'>Show exosuit log</a> | <a style='color: #f00;' href='?src=\ref[src];shock=\ref[TR]'>(EMP pulse)</a><br>"}
|
||||
|
||||
if(screen==1)
|
||||
dat += "<h3>Log contents</h3>"
|
||||
dat += "<a href='?src=\ref[src];return=1'>Return</a><hr>"
|
||||
dat += "[stored_data]"
|
||||
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>(Refresh)</A><BR>"
|
||||
dat += "</body></html>"
|
||||
|
||||
user << browse(dat, "window=computer;size=400x500")
|
||||
onclose(user, "computer")
|
||||
/obj/machinery/computer/mecha/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
tgui_interact(user)
|
||||
|
||||
Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
var/datum/topic_input/top_filter = new /datum/topic_input(href,href_list)
|
||||
if(href_list["send_message"])
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = top_filter.getObj("send_message")
|
||||
var/message = sanitize(input(usr,"Input message","Transmit message") as text)
|
||||
var/obj/mecha/M = MT.in_mecha()
|
||||
if(message && M)
|
||||
M.occupant_message(message)
|
||||
return
|
||||
if(href_list["shock"])
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = top_filter.getObj("shock")
|
||||
MT.shock()
|
||||
if(href_list["get_log"])
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = top_filter.getObj("get_log")
|
||||
stored_data = MT.get_mecha_log()
|
||||
screen = 1
|
||||
if(href_list["return"])
|
||||
screen = 0
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
/obj/machinery/computer/mecha/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "MechaControlConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/mecha/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["beacons"] = list()
|
||||
for(var/obj/item/mecha_parts/mecha_tracking/TR in world)
|
||||
var/list/tr_data = TR.tgui_data(user)
|
||||
if(tr_data)
|
||||
data["beacons"].Add(list(tr_data))
|
||||
|
||||
LAZYINITLIST(stored_data)
|
||||
data["stored_data"] = stored_data
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/mecha/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("send_message")
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = locate(params["mt"])
|
||||
if(istype(MT))
|
||||
var/message = sanitize(input(usr, "Input message", "Transmit message") as text)
|
||||
var/obj/mecha/M = MT.in_mecha()
|
||||
if(message && M)
|
||||
M.occupant_message(message)
|
||||
return TRUE
|
||||
|
||||
if("shock")
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = locate(params["mt"])
|
||||
if(istype(MT))
|
||||
MT.shock()
|
||||
return TRUE
|
||||
|
||||
if("get_log")
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = locate(params["mt"])
|
||||
if(istype(MT))
|
||||
stored_data = MT.get_mecha_log()
|
||||
return TRUE
|
||||
|
||||
if("clear_log")
|
||||
stored_data = null
|
||||
return TRUE
|
||||
|
||||
/obj/item/mecha_parts/mecha_tracking
|
||||
name = "Exosuit tracking beacon"
|
||||
@@ -71,58 +75,67 @@
|
||||
icon_state = "motion2"
|
||||
origin_tech = list(TECH_DATA = 2, TECH_MAGNET = 2)
|
||||
|
||||
proc/get_mecha_info()
|
||||
if(!in_mecha())
|
||||
return 0
|
||||
var/obj/mecha/M = src.loc
|
||||
var/cell_charge = M.get_charge()
|
||||
var/answer = {"<b>Name:</b> [M.name]<br>
|
||||
<b>Integrity:</b> [M.health/initial(M.health)*100]%<br>
|
||||
<b>Cell charge:</b> [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]<br>
|
||||
<b>Airtank:</b> [M.return_pressure()]kPa<br>
|
||||
<b>Pilot:</b> [M.occupant||"None"]<br>
|
||||
<b>Location:</b> [get_area(M)||"Unknown"]<br>
|
||||
<b>Active equipment:</b> [M.selected||"None"]"}
|
||||
if(istype(M, /obj/mecha/working/ripley))
|
||||
var/obj/mecha/working/ripley/RM = M
|
||||
answer += "<b>Used cargo space:</b> [RM.cargo.len/RM.cargo_capacity*100]%<br>"
|
||||
/obj/item/mecha_parts/mecha_tracking/tgui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
if(!in_mecha())
|
||||
return FALSE
|
||||
|
||||
return answer
|
||||
var/obj/mecha/M = loc
|
||||
data["ref"] = REF(src)
|
||||
data["charge"] = M.get_charge()
|
||||
data["name"] = M.name
|
||||
data["health"] = M.health
|
||||
data["maxHealth"] = initial(M.health)
|
||||
data["cell"] = M.cell
|
||||
if(M.cell)
|
||||
data["cellCharge"] = M.cell.charge
|
||||
data["cellMaxCharge"] = M.cell.charge
|
||||
data["airtank"] = M.return_pressure()
|
||||
data["pilot"] = M.occupant
|
||||
data["location"] = get_area(M)
|
||||
data["active"] = M.selected
|
||||
if(istype(M, /obj/mecha/working/ripley))
|
||||
var/obj/mecha/working/ripley/RM = M
|
||||
data["cargoUsed"] = RM.cargo.len
|
||||
data["cargoMax"] = RM.cargo_capacity
|
||||
|
||||
emp_act()
|
||||
qdel(src)
|
||||
return
|
||||
return data
|
||||
|
||||
ex_act()
|
||||
qdel(src)
|
||||
return
|
||||
/obj/item/mecha_parts/mecha_tracking/emp_act()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
proc/in_mecha()
|
||||
if(istype(src.loc, /obj/mecha))
|
||||
return src.loc
|
||||
return 0
|
||||
/obj/item/mecha_parts/mecha_tracking/ex_act()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
proc/shock()
|
||||
var/obj/mecha/M = in_mecha()
|
||||
if(M)
|
||||
M.emp_act(4)
|
||||
qdel(src)
|
||||
/obj/item/mecha_parts/mecha_tracking/proc/in_mecha()
|
||||
if(istype(loc, /obj/mecha))
|
||||
return loc
|
||||
return 0
|
||||
|
||||
proc/get_mecha_log()
|
||||
if(!src.in_mecha())
|
||||
return 0
|
||||
var/obj/mecha/M = src.loc
|
||||
return M.get_log_html()
|
||||
/obj/item/mecha_parts/mecha_tracking/proc/shock()
|
||||
var/obj/mecha/M = in_mecha()
|
||||
if(M)
|
||||
M.emp_act(4)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log()
|
||||
if(!in_mecha())
|
||||
return list()
|
||||
var/obj/mecha/M = loc
|
||||
return M.get_log_tgui()
|
||||
|
||||
|
||||
/obj/item/weapon/storage/box/mechabeacons
|
||||
name = "Exosuit Tracking Beacons"
|
||||
New()
|
||||
..()
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
|
||||
/obj/item/weapon/storage/box/mechabeacons/New()
|
||||
..()
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/design/item/mechfab/gopher
|
||||
category = "Gopher"
|
||||
category = list("Gopher")
|
||||
time = 5
|
||||
|
||||
/datum/design/item/mechfab/gopher/chassis
|
||||
@@ -55,7 +55,7 @@
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 2500)
|
||||
|
||||
/datum/design/item/mechfab/polecat
|
||||
category = "Polecat"
|
||||
category = list("Polecat")
|
||||
time = 10
|
||||
|
||||
/datum/design/item/mechfab/polecat/chassis
|
||||
@@ -134,7 +134,7 @@
|
||||
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/microshotgun
|
||||
|
||||
/datum/design/item/mechfab/weasel
|
||||
category = "Weasel"
|
||||
category = list("Weasel")
|
||||
time = 5
|
||||
|
||||
/datum/design/item/mechfab/weasel/chassis
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
name = "rolled-up poster"
|
||||
desc = "The poster comes with its own automatic adhesive mechanism, for easy pinning to any vertical surface."
|
||||
icon_state = "rolled_poster"
|
||||
drop_sound = 'sound/items/drop/wrapper.ogg'
|
||||
pickup_sound = 'sound/items/pickup/wrapper.ogg'
|
||||
var/serial_number = null
|
||||
|
||||
var/poster_type = /obj/structure/sign/poster
|
||||
|
||||
@@ -9,6 +9,11 @@ Portals do have some specific requirements when mapping them in;
|
||||
- There must by one, and only one `/obj/effect/map_effect/portal/master` for each side of a portal.
|
||||
- Both sides need to have matching `portal_id`s in order to link to each other.
|
||||
- Each side must face opposite directions, e.g. if side A faces SOUTH, side B must face NORTH.
|
||||
- Clarification on the above - you will be moved in the direction that the portal faces.
|
||||
If Side A faces south, you will be moved south. Dirs are 1/2/4/8, 1: NORTH, 2: SOUTH, 4: EAST, 8: WEST.
|
||||
To further explain: If your cave entrance is on the NORTH side of the map on ENTRY side, and SOUTH side on EXIT side:
|
||||
You will need to set the ENTRY side's dir to 2, IE SOUTH, as that's the direction you will moving coming FROM the EXIT side.
|
||||
IE: Directions should be set based on the direction of travel.
|
||||
- Each side must have the same orientation, e.g. horizontal on both sides, or vertical on both sides.
|
||||
- Portals can be made to be longer than 1x1 with `/obj/effect/map_effect/portal/line`s,
|
||||
but both sides must have the same length.
|
||||
@@ -341,4 +346,4 @@ when portals are shortly lived, or when portals are made to be obvious with spec
|
||||
|
||||
/obj/effect/map_effect/portal/line/side_b
|
||||
name = "portal line B"
|
||||
icon_state = "portal_line_side_b"
|
||||
icon_state = "portal_line_side_b"
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
triggered = 1
|
||||
for (var/turf/simulated/floor/target in range(1,src))
|
||||
if(!target.blocks_air)
|
||||
target.assume_gas("sleeping_agent", 30)
|
||||
target.assume_gas("nitrous_oxide", 30)
|
||||
visible_message("\The [src.name] detonates!")
|
||||
spawn(0)
|
||||
qdel(src)
|
||||
|
||||
@@ -91,8 +91,16 @@
|
||||
|
||||
var/icon/default_worn_icon //Default on-mob icon
|
||||
var/worn_layer //Default on-mob layer
|
||||
|
||||
var/drop_sound = 'sound/items/drop/device.ogg' // drop sound - this is the default
|
||||
|
||||
// Pickup/Drop/Equip/Throw Sounds
|
||||
///Used when thrown into a mob
|
||||
var/mob_throw_hit_sound
|
||||
// Sound used when equipping the items into a valid slot.
|
||||
var/equip_sound
|
||||
// pickup sound - this is the default
|
||||
var/pickup_sound = 'sound/items/pickup/device.ogg'
|
||||
// drop sound - this is the default
|
||||
var/drop_sound = 'sound/items/drop/device.ogg'
|
||||
|
||||
var/tip_timer // reference to timer id for a tooltip we might open soon
|
||||
|
||||
@@ -278,10 +286,29 @@
|
||||
/obj/item/proc/moved(mob/user as mob, old_loc as turf)
|
||||
return
|
||||
|
||||
/obj/item/proc/get_volume_by_throwforce_and_or_w_class() // This is used for figuring out how loud our sounds are for throwing.
|
||||
if(throwforce && w_class)
|
||||
return CLAMP((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100
|
||||
else if(w_class)
|
||||
return CLAMP(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/item/throw_impact(atom/hit_atom)
|
||||
..()
|
||||
if(drop_sound)
|
||||
playsound(src, drop_sound, 50, 0, preference = /datum/client_preference/drop_sounds)
|
||||
if(isliving(hit_atom)) //Living mobs handle hit sounds differently.
|
||||
var/volume = get_volume_by_throwforce_and_or_w_class()
|
||||
if (throwforce > 0)
|
||||
if (mob_throw_hit_sound)
|
||||
playsound(hit_atom, mob_throw_hit_sound, volume, TRUE, -1)
|
||||
else if(hitsound)
|
||||
playsound(hit_atom, hitsound, volume, TRUE, -1)
|
||||
else
|
||||
playsound(hit_atom, 'sound/weapons/genhit.ogg', volume, TRUE, -1)
|
||||
else
|
||||
playsound(hit_atom, 'sound/weapons/throwtap.ogg', 1, volume, -1)
|
||||
else
|
||||
playsound(src, drop_sound, 30, preference = /datum/client_preference/drop_sounds)
|
||||
|
||||
// apparently called whenever an item is removed from a slot, container, or anything else.
|
||||
/obj/item/proc/dropped(mob/user as mob)
|
||||
@@ -318,6 +345,13 @@
|
||||
user.position_hud_item(src,slot)
|
||||
if(user.client) user.client.screen |= src
|
||||
if(user.pulling == src) user.stop_pulling()
|
||||
if((slot_flags & slot))
|
||||
if(equip_sound)
|
||||
playsound(src, equip_sound, 30)
|
||||
else
|
||||
playsound(src, drop_sound, 30)
|
||||
else if(slot == slot_l_hand || slot == slot_r_hand)
|
||||
playsound(src, pickup_sound, 20, preference = /datum/client_preference/pickup_sounds)
|
||||
return
|
||||
|
||||
//Defines which slots correspond to which slot flags
|
||||
|
||||
@@ -51,6 +51,8 @@ var/list/civilian_cartridges = list(
|
||||
icon_state = "cart"
|
||||
item_state = "electronic"
|
||||
w_class = ITEMSIZE_TINY
|
||||
drop_sound = 'sound/items/drop/component.ogg'
|
||||
pickup_sound = 'sound/items/pickup/component.ogg'
|
||||
|
||||
var/obj/item/radio/integrated/radio = null
|
||||
var/access_security = 0
|
||||
|
||||
@@ -239,6 +239,8 @@
|
||||
desc = "A pen-sized light, used by medical staff."
|
||||
icon_state = "penlight"
|
||||
item_state = "pen"
|
||||
drop_sound = 'sound/items/drop/accessory.ogg'
|
||||
pickup_sound = 'sound/items/pickup/accessory.ogg'
|
||||
slot_flags = SLOT_EARS
|
||||
brightness_on = 2
|
||||
w_class = ITEMSIZE_TINY
|
||||
@@ -330,6 +332,8 @@
|
||||
var/on_damage = 7
|
||||
var/produce_heat = 1500
|
||||
power_use = 0
|
||||
drop_sound = 'sound/items/drop/gloves.ogg'
|
||||
pickup_sound = 'sound/items/pickup/gloves.ogg'
|
||||
|
||||
/obj/item/device/flashlight/flare/New()
|
||||
fuel = rand(800, 1000) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds.
|
||||
|
||||
@@ -7,13 +7,15 @@
|
||||
/obj/item/device/multitool
|
||||
name = "multitool"
|
||||
desc = "Used for pulsing wires to test which to cut. Not recommended by doctors."
|
||||
description_info = "You can use this on airlocks or APCs to try to hack them without cutting wires."
|
||||
icon_state = "multitool"
|
||||
force = 5.0
|
||||
w_class = ITEMSIZE_SMALL
|
||||
throwforce = 5.0
|
||||
throw_range = 15
|
||||
throw_speed = 3
|
||||
desc = "You can use this on airlocks or APCs to try to hack them without cutting wires."
|
||||
drop_sound = 'sound/items/drop/multitool.ogg'
|
||||
pickup_sound = 'sound/items/pickup/multitool.ogg'
|
||||
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20)
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
channels = list("Command" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/heads/captain
|
||||
name = "colony director's encryption key"
|
||||
name = "site manager's encryption key"
|
||||
icon_state = "cap_cypherkey"
|
||||
channels = list("Command" = 1, "Security" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1, "Service" = 1)
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
channels = list("Command" = 1, "Security" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1, "Service" = 1, "AI Private" = 1, "Explorer" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/heads/captain
|
||||
name = "colony director's encryption key"
|
||||
name = "site manager's encryption key"
|
||||
icon_state = "cap_cypherkey"
|
||||
channels = list("Command" = 1, "Security" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1, "Service" = 1, "Explorer" = 1)
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
var/obj/item/device/encryptionkey/keyslot2 = null
|
||||
var/ks1type = null
|
||||
var/ks2type = null
|
||||
|
||||
drop_sound = 'sound/items/drop/component.ogg'
|
||||
pickup_sound = 'sound/items/pickup/component.ogg'
|
||||
|
||||
/obj/item/device/radio/headset/New()
|
||||
..()
|
||||
@@ -77,6 +80,9 @@
|
||||
|
||||
return "[..()][append]"
|
||||
|
||||
/obj/item/device/radio/headset/tgui_state(mob/user)
|
||||
return GLOB.tgui_inventory_state
|
||||
|
||||
/obj/item/device/radio/headset/syndicate
|
||||
origin_tech = list(TECH_ILLEGAL = 3)
|
||||
syndie = 1
|
||||
@@ -170,13 +176,13 @@
|
||||
|
||||
|
||||
/obj/item/device/radio/headset/heads/captain
|
||||
name = "colony director's headset"
|
||||
name = "site manager's headset"
|
||||
desc = "The headset of the boss."
|
||||
icon_state = "com_headset"
|
||||
ks2type = /obj/item/device/encryptionkey/heads/captain
|
||||
|
||||
/obj/item/device/radio/headset/heads/captain/alt
|
||||
name = "colony director's bowman headset"
|
||||
name = "site manager's bowman headset"
|
||||
desc = "The headset of the boss."
|
||||
icon_state = "com_headset_alt"
|
||||
ks2type = /obj/item/device/encryptionkey/heads/captain
|
||||
@@ -252,13 +258,13 @@
|
||||
|
||||
/obj/item/device/radio/headset/heads/hop
|
||||
name = "head of personnel's headset"
|
||||
desc = "The headset of the guy who will one day be Colony Director."
|
||||
desc = "The headset of the guy who will one day be Site Manager."
|
||||
icon_state = "com_headset"
|
||||
ks2type = /obj/item/device/encryptionkey/heads/hop
|
||||
|
||||
/obj/item/device/radio/headset/heads/hop/alt
|
||||
name = "head of personnel's bowman headset"
|
||||
desc = "The headset of the guy who will one day be Colony Director."
|
||||
desc = "The headset of the guy who will one day be Site Manager."
|
||||
icon_state = "com_headset_alt"
|
||||
ks2type = /obj/item/device/encryptionkey/heads/hop
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ var/global/list/default_medbay_channels = list(
|
||||
/obj/item/device/radio/tgui_data(mob/user)
|
||||
var/data[0]
|
||||
|
||||
data["rawfreq"] = num2text(frequency)
|
||||
data["rawfreq"] = frequency
|
||||
data["listening"] = listening
|
||||
data["broadcasting"] = broadcasting
|
||||
data["subspace"] = subspace_transmission
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
icon_state = "valve_1"
|
||||
var/obj/item/weapon/tank/tank_one
|
||||
var/obj/item/weapon/tank/tank_two
|
||||
var/obj/item/device/attached_device
|
||||
var/obj/item/device/assembly/attached_device
|
||||
var/mob/attacher = null
|
||||
var/valve_open = 0
|
||||
var/toggle = 1
|
||||
@@ -20,18 +20,18 @@
|
||||
if(!tank_one)
|
||||
tank_one = item
|
||||
user.drop_item()
|
||||
item.loc = src
|
||||
item.forceMove(src)
|
||||
to_chat(user, "<span class='notice'>You attach the tank to the transfer valve.</span>")
|
||||
else if(!tank_two)
|
||||
tank_two = item
|
||||
user.drop_item()
|
||||
item.loc = src
|
||||
item.forceMove(src)
|
||||
to_chat(user, "<span class='notice'>You attach the tank to the transfer valve.</span>")
|
||||
message_admins("[key_name_admin(user)] attached both tanks to a transfer valve. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[location.x];Y=[location.y];Z=[location.z]'>JMP</a>)")
|
||||
log_game("[key_name_admin(user)] attached both tanks to a transfer valve.")
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src) // update all UIs attached to src
|
||||
SStgui.update_uis(src) // update all UIs attached to src
|
||||
//TODO: Have this take an assemblyholder
|
||||
else if(isassembly(item))
|
||||
var/obj/item/device/assembly/A = item
|
||||
@@ -43,7 +43,7 @@
|
||||
return
|
||||
user.remove_from_mob(item)
|
||||
attached_device = A
|
||||
A.loc = src
|
||||
A.forceMove(src)
|
||||
to_chat(user, "<span class='notice'>You attach the [item] to the valve controls and secure it.</span>")
|
||||
A.holder = src
|
||||
A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb).
|
||||
@@ -52,7 +52,7 @@
|
||||
message_admins("[key_name_admin(user)] attached a [item] to a transfer valve. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[location.x];Y=[location.y];Z=[location.z]'>JMP</a>)")
|
||||
log_game("[key_name_admin(user)] attached a [item] to a transfer valve.")
|
||||
attacher = user
|
||||
SSnanoui.update_uis(src) // update all UIs attached to src
|
||||
SStgui.update_uis(src) // update all UIs attached to src
|
||||
return
|
||||
|
||||
|
||||
@@ -66,53 +66,51 @@
|
||||
if(isturf(loc))
|
||||
sense_proximity(callback = .HasProximity)
|
||||
|
||||
/obj/item/device/transfer_valve/attack_self(mob/user as mob)
|
||||
ui_interact(user)
|
||||
/obj/item/device/transfer_valve/attack_self(mob/user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/item/device/transfer_valve/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
/obj/item/device/transfer_valve/tgui_state(mob/user)
|
||||
return GLOB.tgui_inventory_state
|
||||
|
||||
// this is the data which will be sent to the ui
|
||||
var/data[0]
|
||||
data["attachmentOne"] = tank_one ? tank_one.name : null
|
||||
data["attachmentTwo"] = tank_two ? tank_two.name : null
|
||||
data["valveAttachment"] = attached_device ? attached_device.name : null
|
||||
data["valveOpen"] = valve_open ? 1 : 0
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
ui = new(user, src, ui_key, "transfer_valve.tmpl", "Tank Transfer Valve", 460, 280)
|
||||
// when the ui is first opened this is the data it will use
|
||||
ui.set_initial_data(data)
|
||||
// open the new ui window
|
||||
/obj/item/device/transfer_valve/tgui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "TransferValve", name) // 460, 320
|
||||
ui.open()
|
||||
// auto update every Master Controller tick
|
||||
//ui.set_auto_update(1)
|
||||
|
||||
/obj/item/device/transfer_valve/Topic(href, href_list)
|
||||
..()
|
||||
if ( usr.stat || usr.restrained() )
|
||||
return 0
|
||||
if (src.loc != usr)
|
||||
return 0
|
||||
if(tank_one && href_list["tankone"])
|
||||
remove_tank(tank_one)
|
||||
else if(tank_two && href_list["tanktwo"])
|
||||
remove_tank(tank_two)
|
||||
else if(href_list["open"])
|
||||
toggle_valve()
|
||||
else if(attached_device)
|
||||
if(href_list["rem_device"])
|
||||
attached_device.loc = get_turf(src)
|
||||
attached_device:holder = null
|
||||
attached_device = null
|
||||
update_icon()
|
||||
if(href_list["device"])
|
||||
attached_device.attack_self(usr)
|
||||
src.add_fingerprint(usr)
|
||||
return 1 // Returning 1 sends an update to attached UIs
|
||||
/obj/item/device/transfer_valve/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["tank_one"] = tank_one ? tank_one.name : null
|
||||
data["tank_two"] = tank_two ? tank_two.name : null
|
||||
data["attached_device"] = attached_device ? attached_device.name : null
|
||||
data["valve"] = valve_open
|
||||
return data
|
||||
|
||||
/obj/item/device/transfer_valve/tgui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("tankone")
|
||||
remove_tank(tank_one)
|
||||
if("tanktwo")
|
||||
remove_tank(tank_two)
|
||||
if("toggle")
|
||||
toggle_valve()
|
||||
if("device")
|
||||
if(attached_device)
|
||||
attached_device.attack_self(usr)
|
||||
if("remove_device")
|
||||
if(attached_device)
|
||||
attached_device.forceMove(get_turf(src))
|
||||
attached_device.holder = null
|
||||
attached_device = null
|
||||
update_icon()
|
||||
else
|
||||
. = FALSE
|
||||
if(.)
|
||||
update_icon()
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/item/device/transfer_valve/proc/process_activation(var/obj/item/device/D)
|
||||
if(toggle)
|
||||
@@ -148,7 +146,7 @@
|
||||
else
|
||||
return
|
||||
|
||||
T.loc = get_turf(src)
|
||||
T.forceMove(get_turf(src))
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/transfer_valve/proc/merge_gases()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user