mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-18 18:46:24 +01:00
TGUI Research
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
|
||||
+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]]")
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
+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)
|
||||
|
||||
+179
-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,140 @@
|
||||
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 Shoes", /obj/item/clothing/shoes/leather, 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 +259,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 +282,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 +306,5 @@
|
||||
|
||||
build_eff = man_rating
|
||||
eat_eff = bin_rating
|
||||
|
||||
#undef BIOGENITEM
|
||||
@@ -101,112 +101,104 @@
|
||||
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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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
|
||||
|
||||
+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
|
||||
|
||||
@@ -77,6 +77,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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
desc = "Protected by FRM."
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "cyborg_upgrade"
|
||||
/// Bitflags listing module compatibility. Used in the exosuit fabricator for creating sub-categories.
|
||||
var/list/module_flags = NONE
|
||||
var/locked = 0
|
||||
var/require_module = 0
|
||||
var/installed = 0
|
||||
@@ -95,6 +97,7 @@
|
||||
desc = "Used to cool a mounted taser, increasing the potential current in it and thus its recharge rate."
|
||||
icon_state = "cyborg_upgrade3"
|
||||
item_state = "cyborg_upgrade"
|
||||
module_flags = BORG_MODULE_SECURITY
|
||||
require_module = 1
|
||||
|
||||
|
||||
|
||||
@@ -77,6 +77,9 @@
|
||||
get_asset_datum(/datum/asset/spritesheet/pipes),
|
||||
)
|
||||
|
||||
/obj/item/weapon/pipe_dispenser/tgui_state(mob/user)
|
||||
return GLOB.tgui_inventory_state
|
||||
|
||||
/obj/item/weapon/pipe_dispenser/tgui_interact(mob/user, datum/tgui/ui)
|
||||
SetupPipes()
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
|
||||
@@ -78,7 +78,7 @@ obj/item/weapon/circuitboard/rdserver/attackby(obj/item/I as obj, mob/user as mo
|
||||
|
||||
/obj/item/weapon/circuitboard/prosthetics
|
||||
name = "Circuit board (Prosthetics Fabricator)"
|
||||
build_path = /obj/machinery/pros_fabricator
|
||||
build_path = /obj/machinery/mecha_part_fabricator/pros
|
||||
board_type = new /datum/frame/frame_types/machine
|
||||
origin_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3)
|
||||
req_components = list(
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
/obj/item/weapon/card/id/proc/prevent_tracking()
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/card/id/tgui_state(mob/user)
|
||||
return GLOB.tgui_deep_inventory_state
|
||||
|
||||
/obj/item/weapon/card/id/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
|
||||
@@ -223,6 +223,8 @@ var/list/global/tank_gauge_cache = list()
|
||||
if (src.proxyassembly.assembly)
|
||||
src.proxyassembly.assembly.attack_self(user)
|
||||
|
||||
/obj/item/weapon/tank/tgui_state(mob/user)
|
||||
return GLOB.tgui_deep_inventory_state
|
||||
|
||||
/obj/item/weapon/tank/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
|
||||
@@ -45,9 +45,6 @@
|
||||
log_unit_test("If you did not intend to enable this please check code/__defines/unit_testing.dm")
|
||||
#endif
|
||||
|
||||
// Set up roundstart seed list.
|
||||
plant_controller = new()
|
||||
|
||||
// This is kinda important. Set up details of what the hell things are made of.
|
||||
populate_material_list()
|
||||
|
||||
|
||||
@@ -1082,18 +1082,18 @@ var/datum/announcement/minor/admin_min_announcer = new
|
||||
|
||||
return 0
|
||||
|
||||
/datum/admins/proc/spawn_fruit(seedtype in plant_controller.seeds)
|
||||
/datum/admins/proc/spawn_fruit(seedtype in SSplants.seeds)
|
||||
set category = "Debug"
|
||||
set desc = "Spawn the product of a seed."
|
||||
set name = "Spawn Fruit"
|
||||
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
if(!seedtype || !plant_controller.seeds[seedtype])
|
||||
if(!seedtype || !SSplants.seeds[seedtype])
|
||||
return
|
||||
var/amount = input("Amount of fruit to spawn", "Fruit Amount", 1) as null|num
|
||||
if(!isnull(amount))
|
||||
var/datum/seed/S = plant_controller.seeds[seedtype]
|
||||
var/datum/seed/S = SSplants.seeds[seedtype]
|
||||
S.harvest(usr,0,0,amount)
|
||||
log_admin("[key_name(usr)] spawned [seedtype] fruit at ([usr.x],[usr.y],[usr.z])")
|
||||
|
||||
@@ -1137,16 +1137,16 @@ var/datum/announcement/minor/admin_min_announcer = new
|
||||
for(var/datum/custom_item/item in current_items)
|
||||
to_chat(usr, "- name: [item.name] icon: [item.item_icon] path: [item.item_path] desc: [item.item_desc]")
|
||||
|
||||
/datum/admins/proc/spawn_plant(seedtype in plant_controller.seeds)
|
||||
/datum/admins/proc/spawn_plant(seedtype in SSplants.seeds)
|
||||
set category = "Debug"
|
||||
set desc = "Spawn a spreading plant effect."
|
||||
set name = "Spawn Plant"
|
||||
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
if(!seedtype || !plant_controller.seeds[seedtype])
|
||||
if(!seedtype || !SSplants.seeds[seedtype])
|
||||
return
|
||||
new /obj/effect/plant(get_turf(usr), plant_controller.seeds[seedtype])
|
||||
new /obj/effect/plant(get_turf(usr), SSplants.seeds[seedtype])
|
||||
log_admin("[key_name(usr)] spawned [seedtype] vines at ([usr.x],[usr.y],[usr.z])")
|
||||
|
||||
/datum/admins/proc/spawn_atom(var/object as text)
|
||||
|
||||
@@ -88,15 +88,19 @@
|
||||
. += "\The [src] can be attached!"
|
||||
|
||||
/obj/item/device/assembly/attack_self(mob/user as mob)
|
||||
if(!user) return 0
|
||||
if(!user)
|
||||
return 0
|
||||
user.set_machine(src)
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
return 1
|
||||
|
||||
/obj/item/device/assembly/interact(mob/user as mob)
|
||||
return //HTML MENU FOR WIRES GOES HERE
|
||||
/obj/item/device/assembly/tgui_state(mob/user)
|
||||
return GLOB.tgui_deep_inventory_state
|
||||
|
||||
/obj/item/device/assembly/nano_host()
|
||||
if(istype(loc, /obj/item/device/assembly_holder))
|
||||
return loc.nano_host()
|
||||
return ..()
|
||||
/obj/item/device/assembly/tgui_interact(mob/user, datum/tgui/ui)
|
||||
return // tgui goes here
|
||||
|
||||
/obj/item/device/assembly/tgui_host()
|
||||
if(istype(loc, /obj/item/device/assembly_holder))
|
||||
return loc.tgui_host()
|
||||
return ..()
|
||||
|
||||
@@ -100,41 +100,38 @@
|
||||
if(!holder)
|
||||
visible_message("[bicon(src)] *beep* *beep*")
|
||||
|
||||
/obj/item/device/assembly/infra/interact(mob/user as mob)//TODO: change this this to the wire control panel
|
||||
/obj/item/device/assembly/infra/tgui_interact(mob/user, datum/tgui/ui)
|
||||
if(!secured)
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = text("<TT><B>Infrared Laser</B>\n<B>Status</B>: []<BR>\n<B>Visibility</B>: []<BR>\n</TT>", (on ? text("<A href='?src=\ref[];state=0'>On</A>", src) : text("<A href='?src=\ref[];state=1'>Off</A>", src)), (src.visible ? text("<A href='?src=\ref[];visible=0'>Visible</A>", src) : text("<A href='?src=\ref[];visible=1'>Invisible</A>", src)))
|
||||
dat += "<BR><BR><A href='?src=\ref[src];refresh=1'>Refresh</A>"
|
||||
dat += "<BR><BR><A href='?src=\ref[src];close=1'>Close</A>"
|
||||
user << browse(dat, "window=infra")
|
||||
onclose(user, "infra")
|
||||
to_chat(user, "<span class='warning'>[src] is unsecured!</span>")
|
||||
return FALSE
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "AssemblyInfrared", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/device/assembly/infra/Topic(href, href_list, state = deep_inventory_state)
|
||||
/obj/item/device/assembly/infra/tgui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
data["on"] = on
|
||||
data["visible"] = visible
|
||||
|
||||
return data
|
||||
|
||||
/obj/item/device/assembly/infra/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
|
||||
usr << browse(null, "window=infra")
|
||||
onclose(usr, "infra")
|
||||
return
|
||||
return TRUE
|
||||
|
||||
if(href_list["state"])
|
||||
toggle_state()
|
||||
|
||||
if(href_list["visible"])
|
||||
visible = !(visible)
|
||||
for(var/ibeam in i_beams)
|
||||
var/obj/effect/beam/i_beam/I = ibeam
|
||||
I.visible = visible
|
||||
CHECK_TICK
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=infra")
|
||||
return
|
||||
|
||||
if(usr)
|
||||
attack_self(usr)
|
||||
switch(action)
|
||||
if("state")
|
||||
toggle_state()
|
||||
return TRUE
|
||||
if("visible")
|
||||
visible = !visible
|
||||
for(var/ibeam in i_beams)
|
||||
var/obj/effect/beam/i_beam/I = ibeam
|
||||
I.visible = visible
|
||||
CHECK_TICK
|
||||
return TRUE
|
||||
|
||||
/obj/item/device/assembly/infra/verb/rotate_clockwise()
|
||||
set name = "Rotate Infrared Laser Clockwise"
|
||||
|
||||
@@ -95,49 +95,49 @@
|
||||
sense_proximity(range = range, callback = .HasProximity)
|
||||
sense()
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/interact(mob/user as mob)//TODO: Change this to the wires thingy
|
||||
/obj/item/device/assembly/prox_sensor/tgui_interact(mob/user, datum/tgui/ui)
|
||||
if(!secured)
|
||||
user.show_message("<font color='red'>The [name] is unsecured!</font>")
|
||||
return 0
|
||||
var/second = time % 60
|
||||
var/minute = (time - second) / 60
|
||||
var/dat = text("<TT><B>Proximity Sensor</B>\n[] []:[]\n<A href='?src=\ref[];tp=-30'>-</A> <A href='?src=\ref[];tp=-1'>-</A> <A href='?src=\ref[];tp=1'>+</A> <A href='?src=\ref[];tp=30'>+</A>\n</TT>", (timing ? text("<A href='?src=\ref[];time=0'>Arming</A>", src) : text("<A href='?src=\ref[];time=1'>Not Arming</A>", src)), minute, second, src, src, src, src)
|
||||
dat += text("<BR>Range: <A href='?src=\ref[];range=-1'>-</A> [] <A href='?src=\ref[];range=1'>+</A>", src, range, src)
|
||||
dat += "<BR><A href='?src=\ref[src];scanning=1'>[scanning?"Armed":"Unarmed"]</A> (Movement sensor active when armed!)"
|
||||
dat += "<BR><BR><A href='?src=\ref[src];refresh=1'>Refresh</A>"
|
||||
dat += "<BR><BR><A href='?src=\ref[src];close=1'>Close</A>"
|
||||
user << browse(dat, "window=prox")
|
||||
onclose(user, "prox")
|
||||
to_chat(user, "<span class='warning'>[src] is unsecured!</span>")
|
||||
return FALSE
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "AssemblyProx", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/Topic(href, href_list, state = deep_inventory_state)
|
||||
/obj/item/device/assembly/prox_sensor/tgui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
data["time"] = time * 10
|
||||
data["timing"] = timing
|
||||
data["range"] = range
|
||||
data["maxRange"] = 5
|
||||
data["scanning"] = scanning
|
||||
|
||||
return data
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
|
||||
usr << browse(null, "window=prox")
|
||||
onclose(usr, "prox")
|
||||
return
|
||||
|
||||
if(href_list["scanning"])
|
||||
toggle_scan()
|
||||
|
||||
if(href_list["time"])
|
||||
timing = text2num(href_list["time"])
|
||||
update_icon()
|
||||
|
||||
if(href_list["tp"])
|
||||
var/tp = text2num(href_list["tp"])
|
||||
time += tp
|
||||
time = min(max(round(time), 0), 600)
|
||||
|
||||
if(href_list["range"])
|
||||
var/r = text2num(href_list["range"])
|
||||
range += r
|
||||
range = min(max(range, 1), 5)
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=prox")
|
||||
return
|
||||
|
||||
if(usr)
|
||||
attack_self(usr)
|
||||
switch(action)
|
||||
if("scanning")
|
||||
toggle_scan()
|
||||
return TRUE
|
||||
if("timing")
|
||||
timing = !timing
|
||||
update_icon()
|
||||
return TRUE
|
||||
if("set_time")
|
||||
var/real_new_time = 0
|
||||
var/new_time = params["time"]
|
||||
var/list/L = splittext(new_time, ":")
|
||||
if(LAZYLEN(L))
|
||||
for(var/i in 1 to LAZYLEN(L))
|
||||
real_new_time += text2num(L[i]) * (60 ** (LAZYLEN(L) - i))
|
||||
else
|
||||
real_new_time = text2num(new_time)
|
||||
time = clamp(real_new_time, 0, 600)
|
||||
return TRUE
|
||||
if("range")
|
||||
range = clamp(params["range"], 1, 5)
|
||||
return TRUE
|
||||
|
||||
@@ -31,14 +31,6 @@
|
||||
if(holder)
|
||||
holder.update_icon()
|
||||
|
||||
/obj/item/device/assembly/signaler/interact(mob/user)
|
||||
if(..())
|
||||
return TRUE
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/item/device/assembly/signaler/tgui_state(mob/user)
|
||||
return GLOB.tgui_deep_inventory_state
|
||||
|
||||
/obj/item/device/assembly/signaler/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
|
||||
@@ -62,43 +62,38 @@
|
||||
holder.update_icon()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/assembly/timer/interact(mob/user as mob)//TODO: Have this use the wires
|
||||
/obj/item/device/assembly/timer/tgui_interact(mob/user, datum/tgui/ui)
|
||||
if(!secured)
|
||||
user.show_message("<font color='red'>The [name] is unsecured!</font>")
|
||||
return 0
|
||||
var/second = time % 60
|
||||
var/minute = (time - second) / 60
|
||||
var/dat = text("<TT><B>Timing Unit</B>\n[] []:[]\n<A href='?src=\ref[];tp=-30'>-</A> <A href='?src=\ref[];tp=-1'>-</A> <A href='?src=\ref[];tp=1'>+</A> <A href='?src=\ref[];tp=30'>+</A>\n</TT>", (timing ? text("<A href='?src=\ref[];time=0'>Timing</A>", src) : text("<A href='?src=\ref[];time=1'>Not Timing</A>", src)), minute, second, src, src, src, src)
|
||||
dat += "<BR><BR><A href='?src=\ref[src];refresh=1'>Refresh</A>"
|
||||
dat += "<BR><BR><A href='?src=\ref[src];close=1'>Close</A>"
|
||||
user << browse(dat, "window=timer")
|
||||
onclose(user, "timer")
|
||||
return
|
||||
to_chat(user, "<span class='warning'>[src] is unsecured!</span>")
|
||||
return FALSE
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "AssemblyTimer", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/device/assembly/timer/tgui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
data["time"] = time * 10
|
||||
data["timing"] = timing
|
||||
return data
|
||||
|
||||
/obj/item/device/assembly/timer/Topic(href, href_list, state = deep_inventory_state)
|
||||
if(..()) return 1
|
||||
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
|
||||
usr << browse(null, "window=timer")
|
||||
onclose(usr, "timer")
|
||||
return
|
||||
/obj/item/device/assembly/timer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
if(href_list["time"])
|
||||
var/new_timing = text2num(href_list["time"])
|
||||
set_state(new_timing)
|
||||
update_icon()
|
||||
|
||||
if(href_list["tp"])
|
||||
var/tp = text2num(href_list["tp"])
|
||||
time += tp
|
||||
time = min(max(round(time), 0), 600)
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=timer")
|
||||
return
|
||||
|
||||
if(usr)
|
||||
attack_self(usr)
|
||||
|
||||
return
|
||||
switch(action)
|
||||
if("timing")
|
||||
timing = !timing
|
||||
update_icon()
|
||||
return TRUE
|
||||
if("set_time")
|
||||
var/real_new_time = 0
|
||||
var/new_time = params["time"]
|
||||
var/list/L = splittext(new_time, ":")
|
||||
if(LAZYLEN(L))
|
||||
for(var/i in 1 to LAZYLEN(L))
|
||||
real_new_time += text2num(L[i]) * (60 ** (LAZYLEN(L) - i))
|
||||
else
|
||||
real_new_time = text2num(new_time)
|
||||
time = clamp(real_new_time, 0, 600)
|
||||
return TRUE
|
||||
|
||||
@@ -498,4 +498,11 @@
|
||||
assets["synthprinter_working.gif"] = icon('icons/obj/machines/synthpod.dmi', "pod_1")
|
||||
for(var/asset_name in assets)
|
||||
register_asset(asset_name, assets[asset_name])
|
||||
// VOREStation Add End
|
||||
// VOREStation Add End
|
||||
|
||||
/datum/asset/spritesheet/sheetmaterials
|
||||
name = "sheetmaterials"
|
||||
|
||||
/datum/asset/spritesheet/sheetmaterials/register()
|
||||
InsertAll("", 'icons/obj/stacks.dmi')
|
||||
..()
|
||||
@@ -30,7 +30,7 @@
|
||||
log_debug("Plantname not provided and and [src] requires it at [x],[y],[z]")
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
seed = plant_controller.seeds[plantname]
|
||||
seed = SSplants.seeds[plantname]
|
||||
|
||||
if(!seed)
|
||||
log_debug("Plant name '[plantname]' does not exist and [src] requires it at [x],[y],[z]")
|
||||
@@ -62,18 +62,11 @@
|
||||
force = 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/proc/update_desc()
|
||||
|
||||
if(!seed)
|
||||
return
|
||||
if(!plant_controller)
|
||||
sleep(250) // ugly hack, should mean roundstart plants are fine.
|
||||
if(!plant_controller)
|
||||
to_world("<span class='danger'>Plant controller does not exist and [src] requires it. Aborting.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(plant_controller.product_descs["[seed.uid]"])
|
||||
desc = plant_controller.product_descs["[seed.uid]"]
|
||||
if(SSplants.product_descs["[seed.uid]"])
|
||||
desc = SSplants.product_descs["[seed.uid]"]
|
||||
else
|
||||
var/list/descriptors = list()
|
||||
if(reagents.has_reagent("sugar") || reagents.has_reagent("cherryjelly") || reagents.has_reagent("honey") || reagents.has_reagent("berryjuice"))
|
||||
@@ -125,17 +118,17 @@
|
||||
desc += " mushroom"
|
||||
else
|
||||
desc += " fruit"
|
||||
plant_controller.product_descs["[seed.uid]"] = desc
|
||||
SSplants.product_descs["[seed.uid]"] = desc
|
||||
desc += ". Delicious! Probably."
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/update_icon()
|
||||
if(!seed || !plant_controller || !plant_controller.plant_icon_cache)
|
||||
if(!seed || !SSplants || !SSplants.plant_icon_cache)
|
||||
return
|
||||
overlays.Cut()
|
||||
var/image/plant_icon
|
||||
var/icon_key = "fruit-[seed.get_trait(TRAIT_PRODUCT_ICON)]-[seed.get_trait(TRAIT_PRODUCT_COLOUR)]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"
|
||||
if(plant_controller.plant_icon_cache[icon_key])
|
||||
plant_icon = plant_controller.plant_icon_cache[icon_key]
|
||||
if(SSplants.plant_icon_cache[icon_key])
|
||||
plant_icon = SSplants.plant_icon_cache[icon_key]
|
||||
else
|
||||
plant_icon = image('icons/obj/hydroponics_products.dmi',"blank")
|
||||
var/image/fruit_base = image('icons/obj/hydroponics_products.dmi',"[seed.get_trait(TRAIT_PRODUCT_ICON)]-product")
|
||||
@@ -145,7 +138,7 @@
|
||||
var/image/fruit_leaves = image('icons/obj/hydroponics_products.dmi',"[seed.get_trait(TRAIT_PRODUCT_ICON)]-leaf")
|
||||
fruit_leaves.color = "[seed.get_trait(TRAIT_PLANT_COLOUR)]"
|
||||
plant_icon.overlays |= fruit_leaves
|
||||
plant_controller.plant_icon_cache[icon_key] = plant_icon
|
||||
SSplants.plant_icon_cache[icon_key] = plant_icon
|
||||
overlays |= plant_icon
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/Crossed(var/mob/living/M)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
//Handle some post-spawn var stuff.
|
||||
if(planttype)
|
||||
plantname = planttype
|
||||
var/datum/seed/S = plant_controller.seeds[plantname]
|
||||
var/datum/seed/S = SSplants.seeds[plantname]
|
||||
if(!S || !S.chems)
|
||||
return
|
||||
|
||||
|
||||
@@ -410,8 +410,8 @@
|
||||
seed_noun = pick("spores","nodes","cuttings","seeds")
|
||||
|
||||
set_trait(TRAIT_POTENCY,rand(5,30),200,0)
|
||||
set_trait(TRAIT_PRODUCT_ICON,pick(plant_controller.accessible_product_sprites))
|
||||
set_trait(TRAIT_PLANT_ICON,pick(plant_controller.accessible_plant_sprites))
|
||||
set_trait(TRAIT_PRODUCT_ICON,pick(SSplants.accessible_product_sprites))
|
||||
set_trait(TRAIT_PLANT_ICON,pick(SSplants.accessible_plant_sprites))
|
||||
set_trait(TRAIT_PLANT_COLOUR,"#[get_random_colour(0,75,190)]")
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#[get_random_colour(0,75,190)]")
|
||||
update_growth_stages()
|
||||
@@ -788,10 +788,10 @@
|
||||
to_chat(user, "You [harvest_sample ? "take a sample" : "harvest"] from the [display_name].")
|
||||
|
||||
//This may be a new line. Update the global if it is.
|
||||
if(name == "new line" || !(name in plant_controller.seeds))
|
||||
uid = plant_controller.seeds.len + 1
|
||||
if(name == "new line" || !(name in SSplants.seeds))
|
||||
uid = SSplants.seeds.len + 1
|
||||
name = "[uid]"
|
||||
plant_controller.seeds[name] = src
|
||||
SSplants.seeds[name] = src
|
||||
|
||||
if(harvest_sample)
|
||||
var/obj/item/seeds/seeds = new(get_turf(user))
|
||||
@@ -877,6 +877,6 @@
|
||||
|
||||
/datum/seed/proc/update_growth_stages()
|
||||
if(get_trait(TRAIT_PLANT_ICON))
|
||||
growth_stages = plant_controller.plant_sprites[get_trait(TRAIT_PLANT_ICON)]
|
||||
growth_stages = SSplants.plant_sprites[get_trait(TRAIT_PLANT_ICON)]
|
||||
else
|
||||
growth_stages = 0
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/botany/attack_hand(mob/user as mob)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/botany/proc/finished_task()
|
||||
active = 0
|
||||
@@ -136,14 +136,16 @@
|
||||
var/datum/seed/genetics // Currently scanned seed genetic structure.
|
||||
var/degradation = 0 // Increments with each scan, stops allowing gene mods after a certain point.
|
||||
|
||||
/obj/machinery/botany/extractor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
/obj/machinery/botany/extractor/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "BotanyIsolator", name)
|
||||
ui.open()
|
||||
|
||||
if(!user)
|
||||
return
|
||||
/obj/machinery/botany/extractor/tgui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
var/list/data = list()
|
||||
|
||||
var/list/geneMasks = plant_controller.gene_masked_list
|
||||
var/list/geneMasks = SSplants.gene_masked_list
|
||||
data["geneMasks"] = geneMasks
|
||||
|
||||
data["activity"] = active
|
||||
@@ -168,95 +170,93 @@
|
||||
data["hasGenetics"] = 0
|
||||
data["sourceName"] = 0
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "botany_isolator.tmpl", "Lysis-isolation Centrifuge UI", 470, 450)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/botany/Topic(href, href_list)
|
||||
return data
|
||||
|
||||
/obj/machinery/botany/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["eject_packet"])
|
||||
if(!seed) return
|
||||
seed.loc = get_turf(src)
|
||||
|
||||
if(seed.seed.name == "new line" || isnull(plant_controller.seeds[seed.seed.name]))
|
||||
seed.seed.uid = plant_controller.seeds.len + 1
|
||||
seed.seed.name = "[seed.seed.uid]"
|
||||
plant_controller.seeds[seed.seed.name] = seed.seed
|
||||
|
||||
seed.update_seed()
|
||||
visible_message("[bicon(src)] [src] beeps and spits out [seed].")
|
||||
|
||||
seed = null
|
||||
|
||||
if(href_list["eject_disk"])
|
||||
if(!loaded_disk) return
|
||||
loaded_disk.loc = get_turf(src)
|
||||
visible_message("[bicon(src)] [src] beeps and spits out [loaded_disk].")
|
||||
loaded_disk = null
|
||||
return TRUE
|
||||
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/machinery/botany/extractor/Topic(href, href_list)
|
||||
switch(action)
|
||||
if("eject_packet")
|
||||
if(!seed)
|
||||
return
|
||||
seed.forceMove(get_turf(src))
|
||||
|
||||
if(seed.seed.name == "new line" || isnull(SSplants.seeds[seed.seed.name]))
|
||||
seed.seed.uid = SSplants.seeds.len + 1
|
||||
seed.seed.name = "[seed.seed.uid]"
|
||||
SSplants.seeds[seed.seed.name] = seed.seed
|
||||
|
||||
seed.update_seed()
|
||||
visible_message("[bicon(src)] [src] beeps and spits out [seed].")
|
||||
|
||||
seed = null
|
||||
return TRUE
|
||||
|
||||
if("eject_disk")
|
||||
if(!loaded_disk)
|
||||
return
|
||||
loaded_disk.forceMove(get_turf(src))
|
||||
visible_message("[bicon(src)] [src] beeps and spits out [loaded_disk].")
|
||||
loaded_disk = null
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/botany/extractor/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
switch(action)
|
||||
if("scan_genome")
|
||||
if(!seed)
|
||||
return
|
||||
|
||||
if(href_list["scan_genome"])
|
||||
last_action = world.time
|
||||
active = 1
|
||||
|
||||
if(!seed) return
|
||||
if(seed && seed.seed)
|
||||
genetics = seed.seed
|
||||
degradation = 0
|
||||
|
||||
last_action = world.time
|
||||
active = 1
|
||||
qdel(seed)
|
||||
seed = null
|
||||
return TRUE
|
||||
|
||||
if(seed && seed.seed)
|
||||
genetics = seed.seed
|
||||
degradation = 0
|
||||
if("get_gene")
|
||||
if(!genetics || !loaded_disk)
|
||||
return
|
||||
|
||||
qdel(seed)
|
||||
seed = null
|
||||
last_action = world.time
|
||||
active = 1
|
||||
|
||||
if(href_list["get_gene"])
|
||||
var/datum/plantgene/P = genetics.get_gene(params["get_gene"])
|
||||
if(!P)
|
||||
return
|
||||
loaded_disk.genes += P
|
||||
|
||||
if(!genetics || !loaded_disk) return
|
||||
loaded_disk.genesource = "[genetics.display_name]"
|
||||
if(!genetics.roundstart)
|
||||
loaded_disk.genesource += " (variety #[genetics.uid])"
|
||||
|
||||
last_action = world.time
|
||||
active = 1
|
||||
loaded_disk.name += " ([SSplants.gene_tag_masks[params["get_gene"]]], #[genetics.uid])"
|
||||
loaded_disk.desc += " The label reads \'gene [SSplants.gene_tag_masks[params["get_gene"]]], sampled from [genetics.display_name]\'."
|
||||
eject_disk = 1
|
||||
|
||||
var/datum/plantgene/P = genetics.get_gene(href_list["get_gene"])
|
||||
if(!P) return
|
||||
loaded_disk.genes += P
|
||||
degradation += rand(20,60)
|
||||
if(degradation >= 100)
|
||||
failed_task = 1
|
||||
genetics = null
|
||||
degradation = 0
|
||||
return TRUE
|
||||
|
||||
loaded_disk.genesource = "[genetics.display_name]"
|
||||
if(!genetics.roundstart)
|
||||
loaded_disk.genesource += " (variety #[genetics.uid])"
|
||||
|
||||
loaded_disk.name += " ([plant_controller.gene_tag_masks[href_list["get_gene"]]], #[genetics.uid])"
|
||||
loaded_disk.desc += " The label reads \'gene [plant_controller.gene_tag_masks[href_list["get_gene"]]], sampled from [genetics.display_name]\'."
|
||||
eject_disk = 1
|
||||
|
||||
degradation += rand(20,60)
|
||||
if(degradation >= 100)
|
||||
failed_task = 1
|
||||
if("clear_buffer")
|
||||
if(!genetics)
|
||||
return
|
||||
genetics = null
|
||||
degradation = 0
|
||||
|
||||
if(href_list["clear_buffer"])
|
||||
if(!genetics) return
|
||||
genetics = null
|
||||
degradation = 0
|
||||
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
return TRUE
|
||||
|
||||
// Fires an extracted trait into another packet of seeds with a chance
|
||||
// of destroying it based on the size/complexity of the plasmid.
|
||||
@@ -265,13 +265,15 @@
|
||||
icon_state = "traitgun"
|
||||
disk_needs_genes = 1
|
||||
|
||||
/obj/machinery/botany/editor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
|
||||
if(!user)
|
||||
return
|
||||
|
||||
var/list/data = list()
|
||||
/obj/machinery/botany/editor/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "BotanyEditor", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/botany/editor/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["activity"] = active
|
||||
|
||||
if(seed)
|
||||
@@ -286,7 +288,7 @@
|
||||
|
||||
for(var/datum/plantgene/P in loaded_disk.genes)
|
||||
if(data["locus"] != "") data["locus"] += ", "
|
||||
data["locus"] += "[plant_controller.gene_tag_masks[P.genetype]]"
|
||||
data["locus"] += "[SSplants.gene_tag_masks[P.genetype]]"
|
||||
|
||||
else
|
||||
data["disk"] = 0
|
||||
@@ -298,36 +300,30 @@
|
||||
else
|
||||
data["loaded"] = 0
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "botany_editor.tmpl", "Bioballistic Delivery UI", 470, 450)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/botany/editor/Topic(href, href_list)
|
||||
return data
|
||||
|
||||
/obj/machinery/botany/editor/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if(href_list["apply_gene"])
|
||||
if(!loaded_disk || !seed) return
|
||||
switch(action)
|
||||
if("apply_gene")
|
||||
if(!loaded_disk || !seed)
|
||||
return
|
||||
|
||||
last_action = world.time
|
||||
active = 1
|
||||
last_action = world.time
|
||||
active = 1
|
||||
|
||||
if(!isnull(plant_controller.seeds[seed.seed.name]))
|
||||
seed.seed = seed.seed.diverge(1)
|
||||
seed.seed_type = seed.seed.name
|
||||
seed.update_seed()
|
||||
if(!isnull(SSplants.seeds[seed.seed.name]))
|
||||
seed.seed = seed.seed.diverge(1)
|
||||
seed.seed_type = seed.seed.name
|
||||
seed.update_seed()
|
||||
|
||||
if(prob(seed.modified))
|
||||
failed_task = 1
|
||||
seed.modified = 101
|
||||
if(prob(seed.modified))
|
||||
failed_task = 1
|
||||
seed.modified = 101
|
||||
|
||||
for(var/datum/plantgene/gene in loaded_disk.genes)
|
||||
seed.seed.apply_gene(gene)
|
||||
seed.modified += rand(5,10)
|
||||
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
for(var/datum/plantgene/gene in loaded_disk.genes)
|
||||
seed.seed.apply_gene(gene)
|
||||
seed.modified += rand(5,10)
|
||||
return TRUE
|
||||
|
||||
@@ -19,8 +19,8 @@ GLOBAL_LIST_BOILERPLATE(all_seed_packs, /obj/item/seeds)
|
||||
|
||||
//Grabs the appropriate seed datum from the global list.
|
||||
/obj/item/seeds/proc/update_seed()
|
||||
if(!seed && seed_type && !isnull(plant_controller.seeds) && plant_controller.seeds[seed_type])
|
||||
seed = plant_controller.seeds[seed_type]
|
||||
if(!seed && seed_type && !isnull(SSplants.seeds) && SSplants.seeds[seed_type])
|
||||
seed = SSplants.seeds[seed_type]
|
||||
update_appearance()
|
||||
|
||||
//Updates strings and icon appropriately based on seed datum.
|
||||
@@ -76,7 +76,7 @@ GLOBAL_LIST_BOILERPLATE(all_seed_packs, /obj/item/seeds)
|
||||
seed_type = null
|
||||
|
||||
/obj/item/seeds/random/Initialize()
|
||||
seed = plant_controller.create_random_seed()
|
||||
seed = SSplants.create_random_seed()
|
||||
seed_type = seed.name
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -211,23 +211,15 @@
|
||||
if(lockdown)
|
||||
return
|
||||
user.set_machine(src)
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/seed_storage/interact(mob/user as mob)
|
||||
if (..())
|
||||
return
|
||||
|
||||
if(smart)
|
||||
scanner = list("stats", "produce", "soil", "temperature", "light", "pressure")
|
||||
else
|
||||
scanner = initial(scanner)
|
||||
|
||||
if (!seeds_initialized)
|
||||
/obj/machinery/seed_storage/tgui_interact(mob/user, datum/tgui/ui)
|
||||
if(!seeds_initialized)
|
||||
for(var/typepath in starting_seeds)
|
||||
var/amount = starting_seeds[typepath]
|
||||
if(isnull(amount)) amount = 1
|
||||
|
||||
for (var/i = 1 to amount)
|
||||
for(var/i = 1 to amount)
|
||||
var/O = new typepath
|
||||
add(O)
|
||||
for(var/typepath in contraband_seeds)
|
||||
@@ -239,251 +231,153 @@
|
||||
add(O, 1)
|
||||
seeds_initialized = 1
|
||||
|
||||
var/dat = "<center><h1>Seed storage contents</h1></center>"
|
||||
if (piles.len == 0)
|
||||
dat += "<font color='red'>No seeds</font>"
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "SeedStorage", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/seed_storage/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
if(smart)
|
||||
scanner = list("stats", "produce", "soil", "temperature", "light", "pressure")
|
||||
else
|
||||
dat += "<table style='text-align:center;border-style:solid;border-width:1px;padding:4px'><tr><td>Name</td>"
|
||||
dat += "<td>Variety</td>"
|
||||
if ("stats" in scanner)
|
||||
dat += "<td>E</td><td>Y</td><td>M</td><td>Pr</td><td>Pt</td><td>Harvest</td>"
|
||||
scanner = initial(scanner)
|
||||
|
||||
data["scanner"] = scanner
|
||||
|
||||
var/list/piles_to_check = piles
|
||||
if(hacked || emagged)
|
||||
piles_to_check = piles + piles_contra
|
||||
|
||||
var/list/seeds = list()
|
||||
for(var/datum/seed_pile/S in piles_to_check)
|
||||
var/datum/seed/seed = S.seed_type
|
||||
if(!seed)
|
||||
continue
|
||||
var/list/seedinfo = list(
|
||||
"name" = seed.seed_name,
|
||||
"uid" = seed.uid,
|
||||
"amount" = S.amount,
|
||||
"id" = S.ID,
|
||||
)
|
||||
|
||||
seedinfo["traits"] = list()
|
||||
if("stats" in scanner)
|
||||
seedinfo["traits"]["Endurance"] = seed.get_trait(TRAIT_ENDURANCE)
|
||||
seedinfo["traits"]["Yield"] = seed.get_trait(TRAIT_YIELD)
|
||||
seedinfo["traits"]["Production"] = seed.get_trait(TRAIT_PRODUCTION)
|
||||
seedinfo["traits"]["Potency"] = seed.get_trait(TRAIT_POTENCY)
|
||||
seedinfo["traits"]["Repeat Harvest"] = seed.get_trait(TRAIT_HARVEST_REPEAT)
|
||||
if("temperature" in scanner)
|
||||
seedinfo["traits"]["Ideal Heat"] = seed.get_trait(TRAIT_IDEAL_HEAT)
|
||||
if("light" in scanner)
|
||||
seedinfo["traits"]["Ideal Light"] = seed.get_trait(TRAIT_IDEAL_LIGHT)
|
||||
if("soil" in scanner)
|
||||
if(seed.get_trait(TRAIT_REQUIRES_NUTRIENTS))
|
||||
if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) < 0.05)
|
||||
seedinfo["traits"]["Nutrient Consumption"] = "Low"
|
||||
else if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) > 0.2)
|
||||
seedinfo["traits"]["Nutrient Consumption"] = "High"
|
||||
else
|
||||
seedinfo["traits"]["Nutrient Consumption"] = "Norm"
|
||||
else
|
||||
seedinfo["traits"]["Nutrient Consumption"] = "No"
|
||||
if(seed.get_trait(TRAIT_REQUIRES_WATER))
|
||||
if(seed.get_trait(TRAIT_WATER_CONSUMPTION) < 1)
|
||||
seedinfo["traits"]["Water Consumption"] = "Low"
|
||||
else if(seed.get_trait(TRAIT_WATER_CONSUMPTION) > 5)
|
||||
seedinfo["traits"]["Water Consumption"] = "High"
|
||||
else
|
||||
seedinfo["traits"]["Water Consumption"] = "Norm"
|
||||
else
|
||||
seedinfo["traits"]["Water Consumption"] = "No"
|
||||
|
||||
seedinfo["traits"]["notes"] = ""
|
||||
switch(seed.get_trait(TRAIT_CARNIVOROUS))
|
||||
if(1)
|
||||
seedinfo["traits"]["notes"] += "CARN "
|
||||
if(2)
|
||||
seedinfo["traits"]["notes"] += "FASTCARN"
|
||||
switch(seed.get_trait(TRAIT_SPREAD))
|
||||
if(1)
|
||||
seedinfo["traits"]["notes"] += "VINE "
|
||||
if(2)
|
||||
seedinfo["traits"]["notes"] += "FASTVINE"
|
||||
if ("pressure" in scanner)
|
||||
if(seed.get_trait(TRAIT_LOWKPA_TOLERANCE) < 20)
|
||||
seedinfo["traits"]["notes"] += "LP "
|
||||
if(seed.get_trait(TRAIT_HIGHKPA_TOLERANCE) > 220)
|
||||
seedinfo["traits"]["notes"] += "HP "
|
||||
if ("temperature" in scanner)
|
||||
dat += "<td>Temp</td>"
|
||||
if(seed.get_trait(TRAIT_HEAT_TOLERANCE) > 30)
|
||||
seedinfo["traits"]["notes"] += "TEMRES "
|
||||
else if(seed.get_trait(TRAIT_HEAT_TOLERANCE) < 10)
|
||||
seedinfo["traits"]["notes"] += "TEMSEN "
|
||||
if ("light" in scanner)
|
||||
dat += "<td>Light</td>"
|
||||
if ("soil" in scanner)
|
||||
dat += "<td>Nutri</td><td>Water</td>"
|
||||
dat += "<td>Notes</td><td>Amount</td><td></td></tr>"
|
||||
for (var/datum/seed_pile/S in piles)
|
||||
var/datum/seed/seed = S.seed_type
|
||||
if(!seed)
|
||||
continue
|
||||
dat += "<tr>"
|
||||
dat += "<td>[seed.seed_name]</td>"
|
||||
dat += "<td>#[seed.uid]</td>"
|
||||
if ("stats" in scanner)
|
||||
dat += "<td>[seed.get_trait(TRAIT_ENDURANCE)]</td><td>[seed.get_trait(TRAIT_YIELD)]</td><td>[seed.get_trait(TRAIT_MATURATION)]</td><td>[seed.get_trait(TRAIT_PRODUCTION)]</td><td>[seed.get_trait(TRAIT_POTENCY)]</td>"
|
||||
if(seed.get_trait(TRAIT_HARVEST_REPEAT))
|
||||
dat += "<td>Multiple</td>"
|
||||
else
|
||||
dat += "<td>Single</td>"
|
||||
if ("temperature" in scanner)
|
||||
dat += "<td>[seed.get_trait(TRAIT_IDEAL_HEAT)] K</td>"
|
||||
if ("light" in scanner)
|
||||
dat += "<td>[seed.get_trait(TRAIT_IDEAL_LIGHT)] L</td>"
|
||||
if ("soil" in scanner)
|
||||
if(seed.get_trait(TRAIT_REQUIRES_NUTRIENTS))
|
||||
if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) < 0.05)
|
||||
dat += "<td>Low</td>"
|
||||
else if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) > 0.2)
|
||||
dat += "<td>High</td>"
|
||||
else
|
||||
dat += "<td>Norm</td>"
|
||||
else
|
||||
dat += "<td>No</td>"
|
||||
if(seed.get_trait(TRAIT_REQUIRES_WATER))
|
||||
if(seed.get_trait(TRAIT_WATER_CONSUMPTION) < 1)
|
||||
dat += "<td>Low</td>"
|
||||
else if(seed.get_trait(TRAIT_WATER_CONSUMPTION) > 5)
|
||||
dat += "<td>High</td>"
|
||||
else
|
||||
dat += "<td>Norm</td>"
|
||||
else
|
||||
dat += "<td>No</td>"
|
||||
if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) > 10)
|
||||
seedinfo["traits"]["notes"] += "LIGRES "
|
||||
else if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) < 3)
|
||||
seedinfo["traits"]["notes"] += "LIGSEN "
|
||||
if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) < 3)
|
||||
seedinfo["traits"]["notes"] += "TOXSEN "
|
||||
else if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) > 6)
|
||||
seedinfo["traits"]["notes"] += "TOXRES "
|
||||
if(seed.get_trait(TRAIT_PEST_TOLERANCE) < 3)
|
||||
seedinfo["traits"]["notes"] += "PESTSEN "
|
||||
else if(seed.get_trait(TRAIT_PEST_TOLERANCE) > 6)
|
||||
seedinfo["traits"]["notes"] += "PESTRES "
|
||||
if(seed.get_trait(TRAIT_WEED_TOLERANCE) < 3)
|
||||
seedinfo["traits"]["notes"] += "WEEDSEN "
|
||||
else if(seed.get_trait(TRAIT_WEED_TOLERANCE) > 6)
|
||||
seedinfo["traits"]["notes"] += "WEEDRES "
|
||||
if(seed.get_trait(TRAIT_PARASITE))
|
||||
seedinfo["traits"]["notes"] += "PAR "
|
||||
if ("temperature" in scanner)
|
||||
if(seed.get_trait(TRAIT_ALTER_TEMP) > 0)
|
||||
seedinfo["traits"]["notes"] += "TEMP+ "
|
||||
if(seed.get_trait(TRAIT_ALTER_TEMP) < 0)
|
||||
seedinfo["traits"]["notes"] += "TEMP- "
|
||||
if(seed.get_trait(TRAIT_BIOLUM))
|
||||
seedinfo["traits"]["notes"] += "LUM "
|
||||
|
||||
dat += "<td>"
|
||||
switch(seed.get_trait(TRAIT_CARNIVOROUS))
|
||||
if(1)
|
||||
dat += "CARN "
|
||||
if(2)
|
||||
dat += "<font color='red'>CARN </font>"
|
||||
switch(seed.get_trait(TRAIT_SPREAD))
|
||||
if(1)
|
||||
dat += "VINE "
|
||||
if(2)
|
||||
dat += "<font color='red'>VINE </font>"
|
||||
if ("pressure" in scanner)
|
||||
if(seed.get_trait(TRAIT_LOWKPA_TOLERANCE) < 20)
|
||||
dat += "LP "
|
||||
if(seed.get_trait(TRAIT_HIGHKPA_TOLERANCE) > 220)
|
||||
dat += "HP "
|
||||
if ("temperature" in scanner)
|
||||
if(seed.get_trait(TRAIT_HEAT_TOLERANCE) > 30)
|
||||
dat += "TEMRES "
|
||||
else if(seed.get_trait(TRAIT_HEAT_TOLERANCE) < 10)
|
||||
dat += "TEMSEN "
|
||||
if ("light" in scanner)
|
||||
if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) > 10)
|
||||
dat += "LIGRES "
|
||||
else if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) < 3)
|
||||
dat += "LIGSEN "
|
||||
if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) < 3)
|
||||
dat += "TOXSEN "
|
||||
else if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) > 6)
|
||||
dat += "TOXRES "
|
||||
if(seed.get_trait(TRAIT_PEST_TOLERANCE) < 3)
|
||||
dat += "PESTSEN "
|
||||
else if(seed.get_trait(TRAIT_PEST_TOLERANCE) > 6)
|
||||
dat += "PESTRES "
|
||||
if(seed.get_trait(TRAIT_WEED_TOLERANCE) < 3)
|
||||
dat += "WEEDSEN "
|
||||
else if(seed.get_trait(TRAIT_WEED_TOLERANCE) > 6)
|
||||
dat += "WEEDRES "
|
||||
if(seed.get_trait(TRAIT_PARASITE))
|
||||
dat += "PAR "
|
||||
if ("temperature" in scanner)
|
||||
if(seed.get_trait(TRAIT_ALTER_TEMP) > 0)
|
||||
dat += "TEMP+ "
|
||||
if(seed.get_trait(TRAIT_ALTER_TEMP) < 0)
|
||||
dat += "TEMP- "
|
||||
if(seed.get_trait(TRAIT_BIOLUM))
|
||||
dat += "LUM "
|
||||
dat += "</td>"
|
||||
dat += "<td>[S.amount]</td>"
|
||||
dat += "<td><a href='byond://?src=\ref[src];task=vend;id=[S.ID]'>Vend</a> <a href='byond://?src=\ref[src];task=purge;id=[S.ID]'>Purge</a></td>"
|
||||
dat += "</tr>"
|
||||
if(hacked || emagged)
|
||||
for (var/datum/seed_pile/S in piles_contra)
|
||||
var/datum/seed/seed = S.seed_type
|
||||
if(!seed)
|
||||
continue
|
||||
dat += "<tr>"
|
||||
dat += "<td>[seed.seed_name]</td>"
|
||||
dat += "<td>#[seed.uid]</td>"
|
||||
if ("stats" in scanner)
|
||||
dat += "<td>[seed.get_trait(TRAIT_ENDURANCE)]</td><td>[seed.get_trait(TRAIT_YIELD)]</td><td>[seed.get_trait(TRAIT_MATURATION)]</td><td>[seed.get_trait(TRAIT_PRODUCTION)]</td><td>[seed.get_trait(TRAIT_POTENCY)]</td>"
|
||||
if(seed.get_trait(TRAIT_HARVEST_REPEAT))
|
||||
dat += "<td>Multiple</td>"
|
||||
else
|
||||
dat += "<td>Single</td>"
|
||||
if ("temperature" in scanner)
|
||||
dat += "<td>[seed.get_trait(TRAIT_IDEAL_HEAT)] K</td>"
|
||||
if ("light" in scanner)
|
||||
dat += "<td>[seed.get_trait(TRAIT_IDEAL_LIGHT)] L</td>"
|
||||
if ("soil" in scanner)
|
||||
if(seed.get_trait(TRAIT_REQUIRES_NUTRIENTS))
|
||||
if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) < 0.05)
|
||||
dat += "<td>Low</td>"
|
||||
else if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) > 0.2)
|
||||
dat += "<td>High</td>"
|
||||
else
|
||||
dat += "<td>Norm</td>"
|
||||
else
|
||||
dat += "<td>No</td>"
|
||||
if(seed.get_trait(TRAIT_REQUIRES_WATER))
|
||||
if(seed.get_trait(TRAIT_WATER_CONSUMPTION) < 1)
|
||||
dat += "<td>Low</td>"
|
||||
else if(seed.get_trait(TRAIT_WATER_CONSUMPTION) > 5)
|
||||
dat += "<td>High</td>"
|
||||
else
|
||||
dat += "<td>Norm</td>"
|
||||
else
|
||||
dat += "<td>No</td>"
|
||||
seeds.Add(list(seedinfo))
|
||||
|
||||
dat += "<td>"
|
||||
switch(seed.get_trait(TRAIT_CARNIVOROUS))
|
||||
if(1)
|
||||
dat += "CARN "
|
||||
if(2)
|
||||
dat += "<font color='red'>CARN </font>"
|
||||
switch(seed.get_trait(TRAIT_SPREAD))
|
||||
if(1)
|
||||
dat += "VINE "
|
||||
if(2)
|
||||
dat += "<font color='red'>VINE </font>"
|
||||
if ("pressure" in scanner)
|
||||
if(seed.get_trait(TRAIT_LOWKPA_TOLERANCE) < 20)
|
||||
dat += "LP "
|
||||
if(seed.get_trait(TRAIT_HIGHKPA_TOLERANCE) > 220)
|
||||
dat += "HP "
|
||||
if ("temperature" in scanner)
|
||||
if(seed.get_trait(TRAIT_HEAT_TOLERANCE) > 30)
|
||||
dat += "TEMRES "
|
||||
else if(seed.get_trait(TRAIT_HEAT_TOLERANCE) < 10)
|
||||
dat += "TEMSEN "
|
||||
if ("light" in scanner)
|
||||
if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) > 10)
|
||||
dat += "LIGRES "
|
||||
else if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) < 3)
|
||||
dat += "LIGSEN "
|
||||
if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) < 3)
|
||||
dat += "TOXSEN "
|
||||
else if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) > 6)
|
||||
dat += "TOXRES "
|
||||
if(seed.get_trait(TRAIT_PEST_TOLERANCE) < 3)
|
||||
dat += "PESTSEN "
|
||||
else if(seed.get_trait(TRAIT_PEST_TOLERANCE) > 6)
|
||||
dat += "PESTRES "
|
||||
if(seed.get_trait(TRAIT_WEED_TOLERANCE) < 3)
|
||||
dat += "WEEDSEN "
|
||||
else if(seed.get_trait(TRAIT_WEED_TOLERANCE) > 6)
|
||||
dat += "WEEDRES "
|
||||
if(seed.get_trait(TRAIT_PARASITE))
|
||||
dat += "PAR "
|
||||
if ("temperature" in scanner)
|
||||
if(seed.get_trait(TRAIT_ALTER_TEMP) > 0)
|
||||
dat += "TEMP+ "
|
||||
if(seed.get_trait(TRAIT_ALTER_TEMP) < 0)
|
||||
dat += "TEMP- "
|
||||
if(seed.get_trait(TRAIT_BIOLUM))
|
||||
dat += "LUM "
|
||||
dat += "</td>"
|
||||
dat += "<td>[S.amount]</td>"
|
||||
dat += "<td><a href='byond://?src=\ref[src];task=vend;id=[S.ID]'>Vend</a> <a href='byond://?src=\ref[src];task=purge;id=[S.ID]'>Purge</a></td>"
|
||||
dat += "</tr>"
|
||||
dat += "</table>"
|
||||
data["seeds"] = seeds
|
||||
|
||||
user << browse(dat, "window=seedstorage")
|
||||
onclose(user, "seedstorage")
|
||||
return data
|
||||
|
||||
/obj/machinery/seed_storage/Topic(var/href, var/list/href_list)
|
||||
if (..())
|
||||
return
|
||||
var/task = href_list["task"]
|
||||
var/ID = text2num(href_list["id"])
|
||||
/obj/machinery/seed_storage/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
var/ID = text2num(params["id"])
|
||||
|
||||
for (var/datum/seed_pile/N in piles)
|
||||
if (N.ID == ID)
|
||||
if (task == "vend")
|
||||
var/list/piles_to_check = piles
|
||||
if(hacked || emagged)
|
||||
piles_to_check = piles + piles_contra
|
||||
|
||||
for(var/datum/seed_pile/N in piles_to_check)
|
||||
if(N.ID == ID)
|
||||
if(action == "vend")
|
||||
var/obj/O = pick(N.seeds)
|
||||
if (O)
|
||||
if(O)
|
||||
--N.amount
|
||||
N.seeds -= O
|
||||
if (N.amount <= 0 || N.seeds.len <= 0)
|
||||
if(N.amount <= 0 || N.seeds.len <= 0)
|
||||
piles -= N
|
||||
qdel(N)
|
||||
O.loc = src.loc
|
||||
else
|
||||
piles -= N
|
||||
qdel(N)
|
||||
else if (task == "purge")
|
||||
for (var/obj/O in N.seeds)
|
||||
return TRUE
|
||||
else if(action == "purge")
|
||||
for(var/obj/O in N.seeds)
|
||||
qdel(O)
|
||||
piles -= N
|
||||
qdel(N)
|
||||
return TRUE
|
||||
break
|
||||
if(hacked || emagged)
|
||||
for (var/datum/seed_pile/N in piles_contra)
|
||||
if (N.ID == ID)
|
||||
if (task == "vend")
|
||||
var/obj/O = pick(N.seeds)
|
||||
if (O)
|
||||
--N.amount
|
||||
N.seeds -= O
|
||||
if (N.amount <= 0 || N.seeds.len <= 0)
|
||||
piles_contra -= N
|
||||
qdel(N)
|
||||
O.loc = src.loc
|
||||
else
|
||||
piles_contra -= N
|
||||
qdel(N)
|
||||
else if (task == "purge")
|
||||
for (var/obj/O in N.seeds)
|
||||
qdel(O)
|
||||
piles_contra -= N
|
||||
qdel(N)
|
||||
break
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/seed_storage/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if (istype(O, /obj/item/seeds) && !lockdown)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
if(turfs.len) //Pick a turf to spawn at if we can
|
||||
var/turf/simulated/floor/T = pick(turfs)
|
||||
var/datum/seed/seed = plant_controller.create_random_seed(1)
|
||||
var/datum/seed/seed = SSplants.create_random_seed(1)
|
||||
seed.set_trait(TRAIT_SPREAD,2) // So it will function properly as vines.
|
||||
seed.set_trait(TRAIT_POTENCY,rand(potency_min, potency_max)) // 70-100 potency will help guarantee a wide spread and powerful effects.
|
||||
seed.set_trait(TRAIT_MATURATION,rand(maturation_min, maturation_max))
|
||||
@@ -74,9 +74,9 @@
|
||||
/obj/effect/plant/Destroy()
|
||||
if(seed.get_trait(TRAIT_SPREAD)==2)
|
||||
unsense_proximity(callback = .HasProximity, center = get_turf(src))
|
||||
plant_controller.remove_plant(src)
|
||||
SSplants.remove_plant(src)
|
||||
for(var/obj/effect/plant/neighbor in range(1,src))
|
||||
plant_controller.add_plant(neighbor)
|
||||
SSplants.add_plant(neighbor)
|
||||
return ..()
|
||||
|
||||
/obj/effect/plant/single
|
||||
@@ -90,15 +90,15 @@
|
||||
else
|
||||
parent = newparent
|
||||
|
||||
if(!plant_controller)
|
||||
if(!SSplants)
|
||||
sleep(250) // ugly hack, should mean roundstart plants are fine. TODO initialize perhaps?
|
||||
if(!plant_controller)
|
||||
if(!SSplants)
|
||||
to_world("<span class='danger'>Plant controller does not exist and [src] requires it. Aborting.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(!istype(newseed))
|
||||
newseed = plant_controller.seeds[DEFAULT_SEED]
|
||||
newseed = SSplants.seeds[DEFAULT_SEED]
|
||||
seed = newseed
|
||||
if(!seed)
|
||||
qdel(src)
|
||||
@@ -135,7 +135,7 @@
|
||||
/obj/effect/plant/proc/finish_spreading()
|
||||
set_dir(calc_dir())
|
||||
update_icon()
|
||||
plant_controller.add_plant(src)
|
||||
SSplants.add_plant(src)
|
||||
//Some plants eat through plating.
|
||||
if(islist(seed.chems) && !isnull(seed.chems["pacid"]))
|
||||
var/turf/T = get_turf(src)
|
||||
@@ -240,7 +240,7 @@
|
||||
/obj/effect/plant/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
|
||||
user.setClickCooldown(user.get_attack_speed(W))
|
||||
plant_controller.add_plant(src)
|
||||
SSplants.add_plant(src)
|
||||
|
||||
if(W.is_wirecutter() || istype(W, /obj/item/weapon/surgical/scalpel))
|
||||
if(sampled)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
neighbors |= floor
|
||||
|
||||
if(neighbors.len)
|
||||
plant_controller.add_plant(src) //if we have neighbours again, start processing
|
||||
SSplants.add_plant(src) //if we have neighbours again, start processing
|
||||
|
||||
// Update all of our friends.
|
||||
var/turf/T = get_turf(src)
|
||||
@@ -110,7 +110,7 @@
|
||||
// We shouldn't have spawned if the controller doesn't exist.
|
||||
check_health()
|
||||
if(has_buckled_mobs() || neighbors.len)
|
||||
plant_controller.add_plant(src)
|
||||
SSplants.add_plant(src)
|
||||
|
||||
//spreading vines aren't created on their final turf.
|
||||
//Instead, they are created at their parent and then move to their destination.
|
||||
@@ -160,7 +160,7 @@
|
||||
continue
|
||||
for(var/obj/effect/plant/neighbor in check_turf.contents)
|
||||
neighbor.neighbors |= check_turf
|
||||
plant_controller.add_plant(neighbor)
|
||||
SSplants.add_plant(neighbor)
|
||||
spawn(1) if(src) qdel(src)
|
||||
|
||||
#undef NEIGHBOR_REFRESH_TIME
|
||||
@@ -366,7 +366,7 @@
|
||||
|
||||
//Remove the seed if something is already planted.
|
||||
if(seed) seed = null
|
||||
seed = plant_controller.seeds[pick(list("reishi","nettle","amanita","mushrooms","plumphelmet","towercap","harebells","weeds"))]
|
||||
seed = SSplants.seeds[pick(list("reishi","nettle","amanita","mushrooms","plumphelmet","towercap","harebells","weeds"))]
|
||||
if(!seed) return //Weed does not exist, someone fucked up.
|
||||
|
||||
dead = 0
|
||||
@@ -396,7 +396,7 @@
|
||||
// We need to make sure we're not modifying one of the global seed datums.
|
||||
// If it's not in the global list, then no products of the line have been
|
||||
// harvested yet and it's safe to assume it's restricted to this tray.
|
||||
if(!isnull(plant_controller.seeds[seed.name]))
|
||||
if(!isnull(SSplants.seeds[seed.name]))
|
||||
seed = seed.diverge()
|
||||
seed.mutate(severity,get_turf(src))
|
||||
|
||||
@@ -452,8 +452,8 @@
|
||||
|
||||
var/previous_plant = seed.display_name
|
||||
var/newseed = seed.get_mutant_variant()
|
||||
if(newseed in plant_controller.seeds)
|
||||
seed = plant_controller.seeds[newseed]
|
||||
if(newseed in SSplants.seeds)
|
||||
seed = SSplants.seeds[newseed]
|
||||
else
|
||||
return
|
||||
|
||||
|
||||
@@ -16,42 +16,50 @@
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "hydro"
|
||||
item_state = "analyzer"
|
||||
var/form_title
|
||||
var/last_data
|
||||
var/datum/seed/last_seed
|
||||
var/list/last_reagents
|
||||
|
||||
/obj/item/device/analyzer/plant_analyzer/proc/print_report_verb()
|
||||
set name = "Print Plant Report"
|
||||
set category = "Object"
|
||||
set src = usr
|
||||
/obj/item/device/analyzer/plant_analyzer/attack_self(mob/user)
|
||||
tgui_interact(user)
|
||||
|
||||
if(usr.stat || usr.restrained() || usr.lying)
|
||||
return
|
||||
print_report(usr)
|
||||
/obj/item/device/analyzer/plant_analyzer/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "PlantAnalyzer", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/device/analyzer/plant_analyzer/tgui_state(mob/user)
|
||||
return GLOB.tgui_inventory_state
|
||||
|
||||
/obj/item/device/analyzer/plant_analyzer/Topic(href, href_list)
|
||||
/obj/item/device/analyzer/plant_analyzer/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
var/datum/seed/grown_seed = locate(last_seed)
|
||||
if(!istype(grown_seed))
|
||||
return list("no_seed" = TRUE)
|
||||
|
||||
data["no_seed"] = FALSE
|
||||
data["seed"] = grown_seed.get_tgui_analyzer_data(user)
|
||||
data["reagents"] = last_reagents
|
||||
|
||||
return data
|
||||
|
||||
/obj/item/device/analyzer/plant_analyzer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return
|
||||
if(href_list["print"])
|
||||
print_report(usr)
|
||||
|
||||
/obj/item/device/analyzer/plant_analyzer/proc/print_report(var/mob/living/user)
|
||||
if(!last_data)
|
||||
to_chat(user, "There is no scan data to print.")
|
||||
return
|
||||
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(src))
|
||||
P.name = "paper - [form_title]"
|
||||
P.info = "[last_data]"
|
||||
if(istype(user,/mob/living/carbon/human))
|
||||
user.put_in_hands(P)
|
||||
user.visible_message("\The [src] spits out a piece of paper.")
|
||||
return
|
||||
|
||||
/obj/item/device/analyzer/plant_analyzer/attack_self(mob/user as mob)
|
||||
print_report(user)
|
||||
return 0
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("print")
|
||||
print_report(usr)
|
||||
return TRUE
|
||||
if("close")
|
||||
last_seed = null
|
||||
last_reagents = null
|
||||
return TRUE
|
||||
|
||||
/obj/item/device/analyzer/plant_analyzer/afterattack(obj/target, mob/user, flag)
|
||||
if(!flag) return
|
||||
if(!flag)
|
||||
return
|
||||
|
||||
var/datum/seed/grown_seed
|
||||
var/datum/reagents/grown_reagents
|
||||
@@ -60,13 +68,13 @@
|
||||
else if(istype(target,/obj/item/weapon/reagent_containers/food/snacks/grown))
|
||||
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/grown/G = target
|
||||
grown_seed = plant_controller.seeds[G.plantname]
|
||||
grown_seed = SSplants.seeds[G.plantname]
|
||||
grown_reagents = G.reagents
|
||||
|
||||
else if(istype(target,/obj/item/weapon/grown))
|
||||
|
||||
var/obj/item/weapon/grown/G = target
|
||||
grown_seed = plant_controller.seeds[G.plantname]
|
||||
grown_seed = SSplants.seeds[G.plantname]
|
||||
grown_reagents = G.reagents
|
||||
|
||||
else if(istype(target,/obj/item/seeds))
|
||||
@@ -87,12 +95,38 @@
|
||||
to_chat(user, "<span class='danger'>[src] can tell you nothing about \the [target].</span>")
|
||||
return
|
||||
|
||||
form_title = "[grown_seed.seed_name] (#[grown_seed.uid])"
|
||||
var/dat = "<h3>Plant data for [form_title]</h3>"
|
||||
last_seed = REF(grown_seed)
|
||||
|
||||
user.visible_message("<span class='notice'>[user] runs the scanner over \the [target].</span>")
|
||||
|
||||
dat += "<h2>General Data</h2>"
|
||||
last_reagents = list()
|
||||
if(grown_reagents && grown_reagents.reagent_list && grown_reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in grown_reagents.reagent_list)
|
||||
last_reagents.Add(list(list(
|
||||
"name" = R.name,
|
||||
"volume" = grown_reagents.get_reagent_amount(R.id),
|
||||
)))
|
||||
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/item/device/analyzer/plant_analyzer/proc/print_report_verb()
|
||||
set name = "Print Plant Report"
|
||||
set category = "Object"
|
||||
set src = usr
|
||||
|
||||
if(usr.stat || usr.restrained() || usr.lying)
|
||||
return
|
||||
print_report(usr)
|
||||
|
||||
/obj/item/device/analyzer/plant_analyzer/proc/print_report(var/mob/living/user)
|
||||
var/datum/seed/grown_seed = locate(last_seed)
|
||||
if(!istype(grown_seed))
|
||||
to_chat(user, "<span class='warning'>There is no scan data to print.</span>")
|
||||
return
|
||||
|
||||
var/form_title = "[grown_seed.seed_name] (#[grown_seed.uid])"
|
||||
var/dat = "<h3>Plant data for [form_title]</h3>"
|
||||
dat += "<h2>General Data</h2>"
|
||||
dat += "<table>"
|
||||
dat += "<tr><td><b>Endurance</b></td><td>[grown_seed.get_trait(TRAIT_ENDURANCE)]</td></tr>"
|
||||
dat += "<tr><td><b>Yield</b></td><td>[grown_seed.get_trait(TRAIT_YIELD)]</td></tr>"
|
||||
@@ -101,138 +135,156 @@
|
||||
dat += "<tr><td><b>Potency</b></td><td>[grown_seed.get_trait(TRAIT_POTENCY)]</td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
if(grown_reagents && grown_reagents.reagent_list && grown_reagents.reagent_list.len)
|
||||
if(LAZYLEN(last_reagents))
|
||||
dat += "<h2>Reagent Data</h2>"
|
||||
|
||||
dat += "<br>This sample contains: "
|
||||
for(var/datum/reagent/R in grown_reagents.reagent_list)
|
||||
dat += "<br>- [R.name], [grown_reagents.get_reagent_amount(R.id)] unit(s)"
|
||||
for(var/i in 1 to LAZYLEN(last_reagents))
|
||||
dat += "<br>- [last_reagents[i]["name"]], [last_reagents[i]["volume"]] unit(s)"
|
||||
|
||||
dat += "<h2>Other Data</h2>"
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_HARVEST_REPEAT))
|
||||
dat += "This plant can be harvested repeatedly.<br>"
|
||||
var/list/tgui_data = grown_seed.get_tgui_analyzer_data()
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_IMMUTABLE) == -1)
|
||||
dat += "This plant is highly mutable.<br>"
|
||||
else if(grown_seed.get_trait(TRAIT_IMMUTABLE) > 0)
|
||||
dat += "This plant does not possess genetics that are alterable.<br>"
|
||||
dat += jointext(tgui_data["trait_info"], "<br>\n")
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_REQUIRES_NUTRIENTS))
|
||||
if(grown_seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) < 0.05)
|
||||
dat += "It consumes a small amount of nutrient fluid.<br>"
|
||||
else if(grown_seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) > 0.2)
|
||||
dat += "It requires a heavy supply of nutrient fluid.<br>"
|
||||
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(src))
|
||||
P.name = "paper - [form_title]"
|
||||
P.info = "[dat]"
|
||||
if(istype(user,/mob/living/carbon/human))
|
||||
user.put_in_hands(P)
|
||||
user.visible_message("\The [src] spits out a piece of paper.")
|
||||
return
|
||||
|
||||
/datum/seed/proc/get_tgui_analyzer_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["name"] = seed_name
|
||||
data["uid"] = uid
|
||||
data["endurance"] = get_trait(TRAIT_ENDURANCE)
|
||||
data["yield"] = get_trait(TRAIT_YIELD)
|
||||
data["maturation_time"] = get_trait(TRAIT_MATURATION)
|
||||
data["production_time"] = get_trait(TRAIT_PRODUCTION)
|
||||
data["potency"] = get_trait(TRAIT_POTENCY)
|
||||
|
||||
data["trait_info"] = list()
|
||||
if(get_trait(TRAIT_HARVEST_REPEAT))
|
||||
data["trait_info"] += "This plant can be harvested repeatedly."
|
||||
|
||||
if(get_trait(TRAIT_IMMUTABLE) == -1)
|
||||
data["trait_info"] += "This plant is highly mutable."
|
||||
else if(get_trait(TRAIT_IMMUTABLE) > 0)
|
||||
data["trait_info"] += "This plant does not possess genetics that are alterable."
|
||||
|
||||
if(get_trait(TRAIT_REQUIRES_NUTRIENTS))
|
||||
if(get_trait(TRAIT_NUTRIENT_CONSUMPTION) < 0.05)
|
||||
data["trait_info"] += "It consumes a small amount of nutrient fluid."
|
||||
else if(get_trait(TRAIT_NUTRIENT_CONSUMPTION) > 0.2)
|
||||
data["trait_info"] += "It requires a heavy supply of nutrient fluid."
|
||||
else
|
||||
dat += "It requires a supply of nutrient fluid.<br>"
|
||||
data["trait_info"] += "It requires a supply of nutrient fluid."
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_REQUIRES_WATER))
|
||||
if(grown_seed.get_trait(TRAIT_WATER_CONSUMPTION) < 1)
|
||||
dat += "It requires very little water.<br>"
|
||||
else if(grown_seed.get_trait(TRAIT_WATER_CONSUMPTION) > 5)
|
||||
dat += "It requires a large amount of water.<br>"
|
||||
if(get_trait(TRAIT_REQUIRES_WATER))
|
||||
if(get_trait(TRAIT_WATER_CONSUMPTION) < 1)
|
||||
data["trait_info"] += "It requires very little water."
|
||||
else if(get_trait(TRAIT_WATER_CONSUMPTION) > 5)
|
||||
data["trait_info"] += "It requires a large amount of water."
|
||||
else
|
||||
dat += "It requires a stable supply of water.<br>"
|
||||
data["trait_info"] += "It requires a stable supply of water."
|
||||
|
||||
if(grown_seed.mutants && grown_seed.mutants.len)
|
||||
dat += "It exhibits a high degree of potential subspecies shift.<br>"
|
||||
if(mutants && mutants.len)
|
||||
data["trait_info"] += "It exhibits a high degree of potential subspecies shift."
|
||||
|
||||
dat += "It thrives in a temperature of [grown_seed.get_trait(TRAIT_IDEAL_HEAT)] Kelvin."
|
||||
data["trait_info"] += "It thrives in a temperature of [get_trait(TRAIT_IDEAL_HEAT)] Kelvin."
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_LOWKPA_TOLERANCE) < 20)
|
||||
dat += "<br>It is well adapted to low pressure levels."
|
||||
if(grown_seed.get_trait(TRAIT_HIGHKPA_TOLERANCE) > 220)
|
||||
dat += "<br>It is well adapted to high pressure levels."
|
||||
if(get_trait(TRAIT_LOWKPA_TOLERANCE) < 20)
|
||||
data["trait_info"] += "It is well adapted to low pressure levels."
|
||||
if(get_trait(TRAIT_HIGHKPA_TOLERANCE) > 220)
|
||||
data["trait_info"] += "It is well adapted to high pressure levels."
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_HEAT_TOLERANCE) > 30)
|
||||
dat += "<br>It is well adapted to a range of temperatures."
|
||||
else if(grown_seed.get_trait(TRAIT_HEAT_TOLERANCE) < 10)
|
||||
dat += "<br>It is very sensitive to temperature shifts."
|
||||
if(get_trait(TRAIT_HEAT_TOLERANCE) > 30)
|
||||
data["trait_info"] += "It is well adapted to a range of temperatures."
|
||||
else if(get_trait(TRAIT_HEAT_TOLERANCE) < 10)
|
||||
data["trait_info"] += "It is very sensitive to temperature shifts."
|
||||
|
||||
dat += "<br>It thrives in a light level of [grown_seed.get_trait(TRAIT_IDEAL_LIGHT)] lumen[grown_seed.get_trait(TRAIT_IDEAL_LIGHT) == 1 ? "" : "s"]."
|
||||
data["trait_info"] += "It thrives in a light level of [get_trait(TRAIT_IDEAL_LIGHT)] lumen[get_trait(TRAIT_IDEAL_LIGHT) == 1 ? "" : "s"]."
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_LIGHT_TOLERANCE) > 10)
|
||||
dat += "<br>It is well adapted to a range of light levels."
|
||||
else if(grown_seed.get_trait(TRAIT_LIGHT_TOLERANCE) < 3)
|
||||
dat += "<br>It is very sensitive to light level shifts."
|
||||
if(get_trait(TRAIT_LIGHT_TOLERANCE) > 10)
|
||||
data["trait_info"] += "It is well adapted to a range of light levels."
|
||||
else if(get_trait(TRAIT_LIGHT_TOLERANCE) < 3)
|
||||
data["trait_info"] += "It is very sensitive to light level shifts."
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_TOXINS_TOLERANCE) < 3)
|
||||
dat += "<br>It is highly sensitive to toxins."
|
||||
else if(grown_seed.get_trait(TRAIT_TOXINS_TOLERANCE) > 6)
|
||||
dat += "<br>It is remarkably resistant to toxins."
|
||||
if(get_trait(TRAIT_TOXINS_TOLERANCE) < 3)
|
||||
data["trait_info"] += "It is highly sensitive to toxins."
|
||||
else if(get_trait(TRAIT_TOXINS_TOLERANCE) > 6)
|
||||
data["trait_info"] += "It is remarkably resistant to toxins."
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_PEST_TOLERANCE) < 3)
|
||||
dat += "<br>It is highly sensitive to pests."
|
||||
else if(grown_seed.get_trait(TRAIT_PEST_TOLERANCE) > 6)
|
||||
dat += "<br>It is remarkably resistant to pests."
|
||||
if(get_trait(TRAIT_PEST_TOLERANCE) < 3)
|
||||
data["trait_info"] += "It is highly sensitive to pests."
|
||||
else if(get_trait(TRAIT_PEST_TOLERANCE) > 6)
|
||||
data["trait_info"] += "It is remarkably resistant to pests."
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_WEED_TOLERANCE) < 3)
|
||||
dat += "<br>It is highly sensitive to weeds."
|
||||
else if(grown_seed.get_trait(TRAIT_WEED_TOLERANCE) > 6)
|
||||
dat += "<br>It is remarkably resistant to weeds."
|
||||
if(get_trait(TRAIT_WEED_TOLERANCE) < 3)
|
||||
data["trait_info"] += "It is highly sensitive to weeds."
|
||||
else if(get_trait(TRAIT_WEED_TOLERANCE) > 6)
|
||||
data["trait_info"] += "It is remarkably resistant to weeds."
|
||||
|
||||
switch(grown_seed.get_trait(TRAIT_SPREAD))
|
||||
switch(get_trait(TRAIT_SPREAD))
|
||||
if(1)
|
||||
dat += "<br>It is able to be planted outside of a tray."
|
||||
data["trait_info"] += "It is able to be planted outside of a tray."
|
||||
if(2)
|
||||
dat += "<br>It is a robust and vigorous vine that will spread rapidly."
|
||||
data["trait_info"] += "It is a robust and vigorous vine that will spread rapidly."
|
||||
|
||||
switch(grown_seed.get_trait(TRAIT_CARNIVOROUS))
|
||||
switch(get_trait(TRAIT_CARNIVOROUS))
|
||||
if(1)
|
||||
dat += "<br>It is carnivorous and will eat tray pests for sustenance."
|
||||
data["trait_info"] += "It is carnivorous and will eat tray pests for sustenance."
|
||||
if(2)
|
||||
dat += "<br>It is carnivorous and poses a significant threat to living things around it."
|
||||
data["trait_info"] += "It is carnivorous and poses a significant threat to living things around it."
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_PARASITE))
|
||||
dat += "<br>It is capable of parisitizing and gaining sustenance from tray weeds."
|
||||
if(get_trait(TRAIT_PARASITE))
|
||||
data["trait_info"] += "It is capable of parisitizing and gaining sustenance from tray weeds."
|
||||
|
||||
/*
|
||||
There's currently no code that actually changes the temperature of the local environment, so let's not show it until there is.
|
||||
if(grown_seed.get_trait(TRAIT_ALTER_TEMP))
|
||||
dat += "<br>It will periodically alter the local temperature by [grown_seed.get_trait(TRAIT_ALTER_TEMP)] degrees Kelvin."
|
||||
if(get_trait(TRAIT_ALTER_TEMP))
|
||||
data["trait_info"] += "It will periodically alter the local temperature by [get_trait(TRAIT_ALTER_TEMP)] degrees Kelvin."
|
||||
*/
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_BIOLUM))
|
||||
dat += "<br>It is [grown_seed.get_trait(TRAIT_BIOLUM_COLOUR) ? "<font color='[grown_seed.get_trait(TRAIT_BIOLUM_COLOUR)]'>bio-luminescent</font>" : "bio-luminescent"]."
|
||||
if(get_trait(TRAIT_BIOLUM))
|
||||
data["trait_info"] += "It is [get_trait(TRAIT_BIOLUM_COLOUR) ? "<font color='[get_trait(TRAIT_BIOLUM_COLOUR)]'>bio-luminescent</font>" : "bio-luminescent"]."
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_PRODUCES_POWER))
|
||||
dat += "<br>The fruit will function as a battery if prepared appropriately."
|
||||
if(get_trait(TRAIT_PRODUCES_POWER))
|
||||
data["trait_info"] += "The fruit will function as a battery if prepared appropriately."
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_STINGS))
|
||||
dat += "<br>The fruit is covered in stinging spines."
|
||||
if(get_trait(TRAIT_STINGS))
|
||||
data["trait_info"] += "The fruit is covered in stinging spines."
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_JUICY) == 1)
|
||||
dat += "<br>The fruit is soft-skinned and juicy."
|
||||
else if(grown_seed.get_trait(TRAIT_JUICY) == 2)
|
||||
dat += "<br>The fruit is excessively juicy."
|
||||
if(get_trait(TRAIT_JUICY) == 1)
|
||||
data["trait_info"] += "The fruit is soft-skinned and juicy."
|
||||
else if(get_trait(TRAIT_JUICY) == 2)
|
||||
data["trait_info"] += "The fruit is excessively juicy."
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_EXPLOSIVE))
|
||||
dat += "<br>The fruit is internally unstable."
|
||||
if(get_trait(TRAIT_EXPLOSIVE))
|
||||
data["trait_info"] += "The fruit is internally unstable."
|
||||
|
||||
if(grown_seed.get_trait(TRAIT_TELEPORTING))
|
||||
dat += "<br>The fruit is temporal/spatially unstable."
|
||||
if(get_trait(TRAIT_TELEPORTING))
|
||||
data["trait_info"] += "The fruit is temporal/spatially unstable."
|
||||
|
||||
if(grown_seed.exude_gasses && grown_seed.exude_gasses.len)
|
||||
for(var/gas in grown_seed.exude_gasses)
|
||||
if(exude_gasses && exude_gasses.len)
|
||||
for(var/gas in exude_gasses)
|
||||
var/amount = ""
|
||||
if (grown_seed.exude_gasses[gas] > 7)
|
||||
if (exude_gasses[gas] > 7)
|
||||
amount = "large amounts of "
|
||||
else if (grown_seed.exude_gasses[gas] < 5)
|
||||
else if (exude_gasses[gas] < 5)
|
||||
amount = "small amounts of "
|
||||
dat += "<br>It will release [amount][gas_data.name[gas]] into the environment."
|
||||
data["trait_info"] += "It will release [amount][gas_data.name[gas]] into the environment."
|
||||
|
||||
if(grown_seed.consume_gasses && grown_seed.consume_gasses.len)
|
||||
for(var/gas in grown_seed.consume_gasses)
|
||||
if(consume_gasses && consume_gasses.len)
|
||||
for(var/gas in consume_gasses)
|
||||
var/amount = ""
|
||||
if (grown_seed.consume_gasses[gas] > 7)
|
||||
if (consume_gasses[gas] > 7)
|
||||
amount = "large amounts of "
|
||||
else if (grown_seed.consume_gasses[gas] < 5)
|
||||
else if (consume_gasses[gas] < 5)
|
||||
amount = "small amounts of "
|
||||
dat += "<br>It will consume [amount][gas_data.name[gas]] from the environment."
|
||||
data["trait_info"] += "It will consume [amount][gas_data.name[gas]] from the environment."
|
||||
|
||||
if(dat)
|
||||
last_data = dat
|
||||
dat += "<br><br>\[<a href='?src=\ref[src];print=1'>print report</a>\]"
|
||||
user << browse(dat,"window=plant_analyzer")
|
||||
|
||||
return
|
||||
return data
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
if(dead)
|
||||
var/ikey = "[seed.get_trait(TRAIT_PLANT_ICON)]-dead"
|
||||
var/image/dead_overlay = plant_controller.plant_icon_cache["[ikey]"]
|
||||
var/image/dead_overlay = SSplants.plant_icon_cache["[ikey]"]
|
||||
if(!dead_overlay)
|
||||
dead_overlay = image('icons/obj/hydroponics_growing.dmi', "[ikey]")
|
||||
dead_overlay.color = DEAD_PLANT_COLOUR
|
||||
@@ -55,23 +55,23 @@
|
||||
maturation = 1
|
||||
overlay_stage = maturation ? max(1,round(age/maturation)) : 1
|
||||
var/ikey = "[seed.get_trait(TRAIT_PLANT_ICON)]-[overlay_stage]"
|
||||
var/image/plant_overlay = plant_controller.plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"]
|
||||
var/image/plant_overlay = SSplants.plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"]
|
||||
if(frozen == 1)
|
||||
plant_overlay = image('icons/obj/hydroponics_growing.dmi', "[ikey]")
|
||||
plant_overlay.color = FROZEN_PLANT_COLOUR
|
||||
if(!plant_overlay)
|
||||
plant_overlay = image('icons/obj/hydroponics_growing.dmi', "[ikey]")
|
||||
plant_overlay.color = seed.get_trait(TRAIT_PLANT_COLOUR)
|
||||
plant_controller.plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] = plant_overlay
|
||||
SSplants.plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] = plant_overlay
|
||||
add_overlay(plant_overlay)
|
||||
|
||||
if(harvest && overlay_stage == seed.growth_stages)
|
||||
ikey = "[seed.get_trait(TRAIT_PRODUCT_ICON)]"
|
||||
var/image/harvest_overlay = plant_controller.plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"]
|
||||
var/image/harvest_overlay = SSplants.plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"]
|
||||
if(!harvest_overlay)
|
||||
harvest_overlay = image('icons/obj/hydroponics_products.dmi', "[ikey]")
|
||||
harvest_overlay.color = seed.get_trait(TRAIT_PRODUCT_COLOUR)
|
||||
plant_controller.plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PRODUCT_COLOUR)]"] = harvest_overlay
|
||||
SSplants.plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PRODUCT_COLOUR)]"] = harvest_overlay
|
||||
add_overlay(harvest_overlay)
|
||||
|
||||
|
||||
|
||||
@@ -47,87 +47,125 @@
|
||||
IC.power_fail()
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/resolve_nano_host()
|
||||
return src
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/check_interactivity(mob/user)
|
||||
if(!CanInteract(user, physical_state))
|
||||
return 0
|
||||
return 1
|
||||
return tgui_status(user, GLOB.tgui_physical_state) == STATUS_INTERACTIVE
|
||||
|
||||
/obj/item/device/electronic_assembly/get_cell()
|
||||
return battery
|
||||
|
||||
/obj/item/device/electronic_assembly/interact(mob/user)
|
||||
if(!check_interactivity(user))
|
||||
return
|
||||
// TGUI
|
||||
/obj/item/device/electronic_assembly/tgui_state(mob/user)
|
||||
return GLOB.tgui_physical_state
|
||||
|
||||
/obj/item/device/electronic_assembly/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, "ICAssembly", name, parent_ui)
|
||||
ui.open()
|
||||
|
||||
/obj/item/device/electronic_assembly/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
var/total_parts = 0
|
||||
var/total_complexity = 0
|
||||
for(var/obj/item/integrated_circuit/part in contents)
|
||||
total_parts += part.size
|
||||
total_complexity = total_complexity + part.complexity
|
||||
var/HTML = list()
|
||||
|
||||
HTML += "<html><head><title>[src.name]</title></head><body>"
|
||||
HTML += "<br><a href='?src=\ref[src]'>\[Refresh\]</a> | "
|
||||
HTML += "<a href='?src=\ref[src];rename=1'>\[Rename\]</a><br>"
|
||||
HTML += "[total_parts]/[max_components] ([round((total_parts / max_components) * 100, 0.1)]%) space taken up in the assembly.<br>"
|
||||
HTML += "[total_complexity]/[max_complexity] ([round((total_complexity / max_complexity) * 100, 0.1)]%) maximum complexity.<br>"
|
||||
if(battery)
|
||||
HTML += "[round(battery.charge, 0.1)]/[battery.maxcharge] ([round(battery.percent(), 0.1)]%) cell charge. <a href='?src=\ref[src];remove_cell=1'>\[Remove\]</a><br>"
|
||||
HTML += "Net energy: [format_SI(net_power / CELLRATE, "W")]."
|
||||
else
|
||||
HTML += "<span class='danger'>No powercell detected!</span>"
|
||||
HTML += "<br><br>"
|
||||
HTML += "Components:<hr>"
|
||||
HTML += "Built in:<br>"
|
||||
data["total_parts"] = total_parts
|
||||
data["max_components"] = max_components
|
||||
data["total_complexity"] = total_complexity
|
||||
data["max_complexity"] = max_complexity
|
||||
|
||||
data["battery_charge"] = round(battery?.charge, 0.1)
|
||||
data["battery_max"] = round(battery?.maxcharge, 0.1)
|
||||
data["net_power"] = net_power / CELLRATE
|
||||
|
||||
//Put removable circuits in separate categories from non-removable
|
||||
// This works because lists are always passed by reference in BYOND, so modifying unremovable_circuits
|
||||
// after setting data["unremovable_circuits"] = unremovable_circuits also modifies data["unremovable_circuits"]
|
||||
// Same for the removable one
|
||||
var/list/unremovable_circuits = list()
|
||||
data["unremovable_circuits"] = unremovable_circuits
|
||||
var/list/removable_circuits = list()
|
||||
data["removable_circuits"] = removable_circuits
|
||||
for(var/obj/item/integrated_circuit/circuit in contents)
|
||||
if(!circuit.removable)
|
||||
HTML += "<a href=?src=\ref[circuit];examine=1;from_assembly=1>[circuit.displayed_name]</a> | "
|
||||
HTML += "<a href=?src=\ref[circuit];rename=1;from_assembly=1>\[Rename\]</a> | "
|
||||
HTML += "<a href=?src=\ref[circuit];scan=1;from_assembly=1>\[Scan with Debugger\]</a> | "
|
||||
HTML += "<a href=?src=\ref[circuit];bottom=\ref[circuit];from_assembly=1>\[Move to Bottom\]</a>"
|
||||
HTML += "<br>"
|
||||
var/list/target = circuit.removable ? removable_circuits : unremovable_circuits
|
||||
target.Add(list(list(
|
||||
"name" = circuit.displayed_name,
|
||||
"ref" = REF(circuit),
|
||||
)))
|
||||
|
||||
HTML += "<hr>"
|
||||
HTML += "Removable:<br>"
|
||||
return data
|
||||
|
||||
for(var/obj/item/integrated_circuit/circuit in contents)
|
||||
if(circuit.removable)
|
||||
HTML += "<a href=?src=\ref[circuit];examine=1;from_assembly=1>[circuit.displayed_name]</a> | "
|
||||
HTML += "<a href=?src=\ref[circuit];rename=1;from_assembly=1>\[Rename\]</a> | "
|
||||
HTML += "<a href=?src=\ref[circuit];scan=1;from_assembly=1>\[Scan with Debugger\]</a> | "
|
||||
HTML += "<a href=?src=\ref[circuit];remove=1;from_assembly=1>\[Remove\]</a> | "
|
||||
HTML += "<a href=?src=\ref[circuit];bottom=\ref[circuit];from_assembly=1>\[Move to Bottom\]</a>"
|
||||
HTML += "<br>"
|
||||
|
||||
HTML += "</body></html>"
|
||||
user << browse(jointext(HTML,null), "window=assembly-\ref[src];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
|
||||
/obj/item/device/electronic_assembly/Topic(href, href_list[])
|
||||
/obj/item/device/electronic_assembly/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if(href_list["rename"])
|
||||
rename(usr)
|
||||
var/obj/held_item = usr.get_active_hand()
|
||||
|
||||
if(href_list["remove_cell"])
|
||||
if(!battery)
|
||||
to_chat(usr, "<span class='warning'>There's no power cell to remove from \the [src].</span>")
|
||||
else
|
||||
switch(action)
|
||||
// Actual assembly actions
|
||||
if("rename")
|
||||
rename(usr)
|
||||
return TRUE
|
||||
|
||||
if("remove_cell")
|
||||
if(!battery)
|
||||
to_chat(usr, "<span class='warning'>There's no power cell to remove from \the [src].</span>")
|
||||
return FALSE
|
||||
var/turf/T = get_turf(src)
|
||||
battery.forceMove(T)
|
||||
playsound(T, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
to_chat(usr, "<span class='notice'>You pull \the [battery] out of \the [src]'s power supplier.</span>")
|
||||
battery = null
|
||||
return TRUE
|
||||
|
||||
interact(usr) // To refresh the UI.
|
||||
// Circuit actions
|
||||
if("open_circuit")
|
||||
var/obj/item/integrated_circuit/C = locate(params["ref"]) in contents
|
||||
if(!istype(C))
|
||||
return
|
||||
C.tgui_interact(usr, null, ui)
|
||||
return TRUE
|
||||
|
||||
if("rename_circuit")
|
||||
var/obj/item/integrated_circuit/C = locate(params["ref"]) in contents
|
||||
if(!istype(C))
|
||||
return
|
||||
C.rename_component(usr)
|
||||
return TRUE
|
||||
|
||||
if("scan_circuit")
|
||||
var/obj/item/integrated_circuit/C = locate(params["ref"]) in contents
|
||||
if(!istype(C))
|
||||
return
|
||||
if(istype(held_item, /obj/item/device/integrated_electronics/debugger))
|
||||
var/obj/item/device/integrated_electronics/debugger/D = held_item
|
||||
if(D.accepting_refs)
|
||||
D.afterattack(C, usr, TRUE)
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>The Debugger's 'ref scanner' needs to be on.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You need a multitool/debugger set to 'ref' mode to do that.</span>")
|
||||
return TRUE
|
||||
|
||||
if("remove_circuit")
|
||||
var/obj/item/integrated_circuit/C = locate(params["ref"]) in contents
|
||||
if(!istype(C))
|
||||
return
|
||||
C.remove(usr)
|
||||
return TRUE
|
||||
|
||||
if("bottom_circuit")
|
||||
var/obj/item/integrated_circuit/C = locate(params["ref"]) in contents
|
||||
if(!istype(C))
|
||||
return
|
||||
// Puts it at the bottom of our contents
|
||||
// Note, this intentionally does *not* use forceMove, because forceMove will stop if it detects the same loc
|
||||
C.loc = null
|
||||
C.loc = src
|
||||
return FALSE
|
||||
// End TGUI
|
||||
|
||||
/obj/item/device/electronic_assembly/verb/rename()
|
||||
set name = "Rename Circuit"
|
||||
@@ -177,7 +215,7 @@
|
||||
for(var/obj/item/integrated_circuit/IC in contents)
|
||||
. += IC.external_examine(user)
|
||||
if(opened)
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/get_part_complexity()
|
||||
. = 0
|
||||
@@ -249,7 +287,7 @@
|
||||
if(add_circuit(I, user))
|
||||
to_chat(user, "<span class='notice'>You slide \the [I] inside \the [src].</span>")
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
return TRUE
|
||||
|
||||
else if(I.is_crowbar())
|
||||
@@ -261,7 +299,7 @@
|
||||
|
||||
else if(istype(I, /obj/item/device/integrated_electronics/wirer) || istype(I, /obj/item/device/integrated_electronics/debugger) || I.is_screwdriver())
|
||||
if(opened)
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src] isn't opened, so you can't fiddle with the internal components. \
|
||||
@@ -286,7 +324,7 @@
|
||||
battery = cell
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
to_chat(user, "<span class='notice'>You slot \the [cell] inside \the [src]'s power supplier.</span>")
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
return TRUE
|
||||
|
||||
else
|
||||
@@ -296,7 +334,7 @@
|
||||
if(!check_interactivity(user))
|
||||
return
|
||||
if(opened)
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
var/list/input_selection = list()
|
||||
var/list/available_inputs = list()
|
||||
|
||||
@@ -12,11 +12,8 @@
|
||||
max_complexity = IC_COMPLEXITY_BASE
|
||||
var/obj/item/clothing/clothing = null
|
||||
|
||||
/obj/item/device/electronic_assembly/clothing/nano_host()
|
||||
return clothing
|
||||
|
||||
/obj/item/device/electronic_assembly/clothing/resolve_nano_host()
|
||||
return clothing
|
||||
/obj/item/device/electronic_assembly/clothing/tgui_host()
|
||||
return clothing.tgui_host()
|
||||
|
||||
/obj/item/device/electronic_assembly/clothing/update_icon()
|
||||
..()
|
||||
|
||||
@@ -10,11 +10,8 @@
|
||||
max_complexity = IC_COMPLEXITY_BASE / 2
|
||||
var/obj/item/weapon/implant/integrated_circuit/implant = null
|
||||
|
||||
/obj/item/device/electronic_assembly/implant/nano_host()
|
||||
return implant
|
||||
|
||||
/obj/item/device/electronic_assembly/implant/resolve_nano_host()
|
||||
return implant
|
||||
/obj/item/device/electronic_assembly/implant/tgui_host()
|
||||
return implant.tgui_host()
|
||||
|
||||
/obj/item/device/electronic_assembly/implant/update_icon()
|
||||
..()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
w_class = ITEMSIZE_SMALL
|
||||
var/detail_color = COLOR_ASSEMBLY_WHITE
|
||||
var/list/color_list = list(
|
||||
"black" = COLOR_ASSEMBLY_BLACK,
|
||||
"dark gray" = COLOR_ASSEMBLY_BLACK,
|
||||
"machine gray" = COLOR_ASSEMBLY_BGRAY,
|
||||
"white" = COLOR_ASSEMBLY_WHITE,
|
||||
"red" = COLOR_ASSEMBLY_RED,
|
||||
@@ -35,11 +35,42 @@
|
||||
detail_overlay.color = detail_color
|
||||
add_overlay(detail_overlay)
|
||||
|
||||
/obj/item/device/integrated_electronics/detailer/tgui_state(mob/user)
|
||||
return GLOB.tgui_inventory_state
|
||||
|
||||
/obj/item/device/integrated_electronics/detailer/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, "ICDetailer", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/device/integrated_electronics/detailer/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
data["detail_color"] = detail_color
|
||||
data["color_list"] = color_list
|
||||
return data
|
||||
|
||||
/obj/item/device/integrated_electronics/detailer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("change_color")
|
||||
if(!(params["color"] in color_list))
|
||||
return // to prevent href exploits causing runtimes
|
||||
detail_color = color_list[params["color"]]
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/item/device/integrated_electronics/detailer/attack_self(mob/user)
|
||||
var/color_choice = input(user, "Select color.", "Assembly Detailer", detail_color) as null|anything in color_list
|
||||
if(!color_list[color_choice])
|
||||
return
|
||||
if(!in_range(src, user))
|
||||
return
|
||||
detail_color = color_list[color_choice]
|
||||
update_icon()
|
||||
tgui_interact(user)
|
||||
|
||||
// Leaving this commented out in case someone decides that this would be better as an "any color" selection system
|
||||
// Just uncomment this and get rid of all of the TGUI bullshit lol
|
||||
// if(!in_range(user, src))
|
||||
// return
|
||||
// var/new_color = input(user, "Pick a color", "Color Selection", detail_color) as color|null
|
||||
// if(!new_color)
|
||||
// return
|
||||
// detail_color = new_color
|
||||
// update_icon()
|
||||
@@ -6,7 +6,7 @@ a creative player the means to solve many problems. Circuits are held inside an
|
||||
/obj/item/integrated_circuit/examine(mob/user)
|
||||
. = ..()
|
||||
. += external_examine(user)
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
// This should be used when someone is examining while the case is opened.
|
||||
/obj/item/integrated_circuit/proc/internal_examine(mob/user)
|
||||
@@ -22,7 +22,7 @@ a creative player the means to solve many problems. Circuits are held inside an
|
||||
if(A.linked.len)
|
||||
. += "The '[A]' is connected to [A.get_linked_to_desc()]."
|
||||
. += any_examine(user)
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
// This should be used when someone is examining from an 'outside' perspective, e.g. reading a screen or LED.
|
||||
/obj/item/integrated_circuit/proc/external_examine(mob/user)
|
||||
@@ -52,22 +52,12 @@ a creative player the means to solve many problems. Circuits are held inside an
|
||||
qdel(A)
|
||||
. = ..()
|
||||
|
||||
/obj/item/integrated_circuit/nano_host()
|
||||
if(istype(src.loc, /obj/item/device/electronic_assembly))
|
||||
var/obj/item/device/electronic_assembly/assembly = loc
|
||||
return assembly.resolve_nano_host()
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/emp_act(severity)
|
||||
for(var/datum/integrated_io/io in inputs + outputs + activators)
|
||||
io.scramble()
|
||||
|
||||
/obj/item/integrated_circuit/proc/check_interactivity(mob/user)
|
||||
if(assembly)
|
||||
return assembly.check_interactivity(user)
|
||||
else if(!CanInteract(user, physical_state))
|
||||
return 0
|
||||
return 1
|
||||
return tgui_status(user, GLOB.tgui_physical_state) == STATUS_INTERACTIVE
|
||||
|
||||
/obj/item/integrated_circuit/verb/rename_component()
|
||||
set name = "Rename Circuit"
|
||||
@@ -83,274 +73,169 @@ a creative player the means to solve many problems. Circuits are held inside an
|
||||
to_chat(M, "<span class='notice'>The circuit '[src.name]' is now labeled '[input]'.</span>")
|
||||
displayed_name = input
|
||||
|
||||
/obj/item/integrated_circuit/interact(mob/user)
|
||||
if(!check_interactivity(user))
|
||||
return
|
||||
// if(!assembly)
|
||||
// return
|
||||
/obj/item/integrated_circuit/tgui_state(mob/user)
|
||||
return GLOB.tgui_physical_state
|
||||
|
||||
var/window_height = 350
|
||||
var/window_width = 600
|
||||
/obj/item/integrated_circuit/tgui_host(mob/user)
|
||||
if(istype(loc, /obj/item/device/electronic_assembly))
|
||||
return loc.tgui_host()
|
||||
return ..()
|
||||
|
||||
//var/table_edge_width = "[(window_width - window_width * 0.1) / 4]px"
|
||||
//var/table_middle_width = "[(window_width - window_width * 0.1) - (table_edge_width * 2)]px"
|
||||
var/table_edge_width = "30%"
|
||||
var/table_middle_width = "40%"
|
||||
/obj/item/integrated_circuit/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, "ICCircuit", name, parent_ui)
|
||||
ui.open()
|
||||
|
||||
var/HTML = list()
|
||||
HTML += "<html><head><title>[src.displayed_name]</title></head><body>"
|
||||
HTML += "<div align='center'>"
|
||||
HTML += "<table border='1' style='undefined;table-layout: fixed; width: 80%'>"
|
||||
/obj/item/integrated_circuit/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
HTML += "<br><a href='?src=\ref[src];return=1'>\[Return to Assembly\]</a>"
|
||||
data["name"] = name
|
||||
data["desc"] = desc
|
||||
data["displayed_name"] = displayed_name
|
||||
data["removable"] = removable
|
||||
|
||||
HTML += "<br><a href='?src=\ref[src];'>\[Refresh\]</a> | "
|
||||
HTML += "<a href='?src=\ref[src];rename=1'>\[Rename\]</a> | "
|
||||
HTML += "<a href='?src=\ref[src];scan=1'>\[Scan with Device\]</a> | "
|
||||
if(src.removable)
|
||||
HTML += "<a href='?src=\ref[src];remove=1'>\[Remove\]</a><br>"
|
||||
data["complexity"] = complexity
|
||||
data["power_draw_idle"] = power_draw_idle
|
||||
data["power_draw_per_use"] = power_draw_per_use
|
||||
data["extended_desc"] = extended_desc
|
||||
|
||||
HTML += "<colgroup>"
|
||||
HTML += "<col style='width: [table_edge_width]'>"
|
||||
HTML += "<col style='width: [table_middle_width]'>"
|
||||
HTML += "<col style='width: [table_edge_width]'>"
|
||||
HTML += "</colgroup>"
|
||||
data["inputs"] = list()
|
||||
for(var/datum/integrated_io/io in inputs)
|
||||
data["inputs"].Add(list(tgui_pin_data(io)))
|
||||
|
||||
var/column_width = 3
|
||||
var/row_height = max(inputs.len, outputs.len, 1)
|
||||
data["outputs"] = list()
|
||||
for(var/datum/integrated_io/io in outputs)
|
||||
data["outputs"].Add(list(tgui_pin_data(io)))
|
||||
|
||||
for(var/i = 1 to row_height)
|
||||
HTML += "<tr>"
|
||||
for(var/j = 1 to column_width)
|
||||
var/datum/integrated_io/io = null
|
||||
var/words = list()
|
||||
var/height = 1
|
||||
switch(j)
|
||||
if(1)
|
||||
io = get_pin_ref(IC_INPUT, i)
|
||||
if(io)
|
||||
words += "<b><a href=?src=\ref[src];pin_name=1;pin=\ref[io]>[io.display_pin_type()] [io.name]</a> <a href=?src=\ref[src];pin_data=1;pin=\ref[io]>[io.display_data(io.data)]</a></b><br>"
|
||||
if(io.linked.len)
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
// words += "<a href=?src=\ref[linked.holder];pin_name=1;pin=\ref[linked];link=\ref[io]>\[[linked.name]\]</a>
|
||||
words += "<a href=?src=\ref[src];pin_unwire=1;pin=\ref[io];link=\ref[linked]>[linked.name]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;>[linked.holder.displayed_name]</a><br>"
|
||||
data["activators"] = list()
|
||||
for(var/datum/integrated_io/io in activators)
|
||||
var/list/activator = list(
|
||||
"ref" = REF(io),
|
||||
"name" = io.name,
|
||||
"pulse_out" = io.data,
|
||||
"linked" = list()
|
||||
)
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
activator["linked"].Add(list(list(
|
||||
"ref" = REF(linked),
|
||||
"name" = linked.name,
|
||||
"holder_ref" = REF(linked.holder),
|
||||
"holder_name" = linked.holder.displayed_name,
|
||||
)))
|
||||
|
||||
if(outputs.len > inputs.len)
|
||||
height = 1
|
||||
if(2)
|
||||
if(i == 1)
|
||||
words += "[src.displayed_name]<br>[src.name != src.displayed_name ? "([src.name])":""]<hr>[src.desc]"
|
||||
height = row_height
|
||||
else
|
||||
continue
|
||||
if(3)
|
||||
io = get_pin_ref(IC_OUTPUT, i)
|
||||
if(io)
|
||||
words += "<b><a href=?src=\ref[src];pin_name=1;pin=\ref[io]>[io.display_pin_type()] [io.name]</a> <a href=?src=\ref[src];pin_data=1;pin=\ref[io]>[io.display_data(io.data)]</a></b><br>"
|
||||
if(io.linked.len)
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
// words += "<a href=?src=\ref[linked.holder];pin_name=1;pin=\ref[linked];link=\ref[io]>\[[linked.name]\]</a>
|
||||
words += "<a href=?src=\ref[src];pin_unwire=1;pin=\ref[io];link=\ref[linked]>[linked.name]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;>[linked.holder.displayed_name]</a><br>"
|
||||
data["activators"].Add(list(activator))
|
||||
|
||||
if(inputs.len > outputs.len)
|
||||
height = 1
|
||||
HTML += "<td align='center' rowspan='[height]'>[jointext(words, null)]</td>"
|
||||
HTML += "</tr>"
|
||||
return data
|
||||
|
||||
for(var/activator in activators)
|
||||
var/datum/integrated_io/io = activator
|
||||
var/words = list()
|
||||
/obj/item/integrated_circuit/proc/tgui_pin_data(datum/integrated_io/io)
|
||||
if(!istype(io))
|
||||
return list()
|
||||
var/list/pindata = list()
|
||||
pindata["type"] = io.display_pin_type()
|
||||
pindata["name"] = io.name
|
||||
pindata["data"] = io.display_data(io.data)
|
||||
pindata["ref"] = REF(io)
|
||||
pindata["linked"] = list()
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
pindata["linked"].Add(list(list(
|
||||
"ref" = REF(linked),
|
||||
"name" = linked.name,
|
||||
"holder_ref" = REF(linked.holder),
|
||||
"holder_name" = linked.holder.displayed_name,
|
||||
)))
|
||||
return pindata
|
||||
|
||||
words += "<b><a href=?src=\ref[src];pin_name=1;pin=\ref[io]><font color='FF0000'>[io.name]</font></a> <a href=?src=\ref[src];pin_data=1;pin=\ref[io]><font color='FF0000'>[io.data?"\<PULSE OUT\>":"\<PULSE IN\>"]</font></a></b><br>"
|
||||
if(io.linked.len)
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
// words += "<a href=?src=\ref[linked.holder];pin_name=1;pin=\ref[linked];link=\ref[io]>\[[linked.name]\]</a>
|
||||
words += "<a href=?src=\ref[src];pin_unwire=1;pin=\ref[io];link=\ref[linked]><font color='FF0000'>[linked.name]</font></a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;><font color='FF0000'>[linked.holder.displayed_name]</font></a><br>"
|
||||
|
||||
HTML += "<tr>"
|
||||
HTML += "<td colspan='3' align='center'>[jointext(words, null)]</td>"
|
||||
HTML += "</tr>"
|
||||
|
||||
HTML += "</table>"
|
||||
HTML += "</div>"
|
||||
|
||||
// HTML += "<br><font color='33CC33'>Meta Variables;</font>" // If more meta vars get introduced, uncomment this.
|
||||
// HTML += "<br>"
|
||||
|
||||
HTML += "<br><font color='0000AA'>Complexity: [complexity]</font>"
|
||||
if(power_draw_idle)
|
||||
HTML += "<br><font color='0000AA'>Power Draw: [power_draw_idle] W (Idle)</font>"
|
||||
if(power_draw_per_use)
|
||||
HTML += "<br><font color='0000AA'>Power Draw: [power_draw_per_use] W (Active)</font>" // Borgcode says that powercells' checked_use() takes joules as input.
|
||||
HTML += "<br><font color='0000AA'>[extended_desc]</font>"
|
||||
|
||||
HTML += "</body></html>"
|
||||
if(src.assembly)
|
||||
user << browse(jointext(HTML, null), "window=assembly-\ref[src.assembly];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
else
|
||||
user << browse(jointext(HTML, null), "window=circuit-\ref[src];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
|
||||
onclose(user, "assembly-\ref[src.assembly]")
|
||||
|
||||
/obj/item/integrated_circuit/Topic(href, href_list, state = interactive_state)
|
||||
if(!check_interactivity(usr))
|
||||
return
|
||||
/obj/item/integrated_circuit/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
var/update = 1
|
||||
var/obj/item/device/electronic_assembly/A = src.assembly
|
||||
var/update_to_assembly = 0
|
||||
var/datum/integrated_io/pin = locate(href_list["pin"]) in inputs + outputs + activators
|
||||
var/datum/integrated_io/pin = locate(params["pin"]) in inputs + outputs + activators
|
||||
var/datum/integrated_io/linked = null
|
||||
if(href_list["link"])
|
||||
linked = locate(href_list["link"]) in pin.linked
|
||||
|
||||
if(params["link"])
|
||||
linked = locate(params["link"]) in pin.linked
|
||||
|
||||
var/obj/held_item = usr.get_active_hand()
|
||||
|
||||
if(href_list["rename"])
|
||||
rename_component(usr)
|
||||
if(href_list["from_assembly"])
|
||||
update = 0
|
||||
var/obj/item/device/electronic_assembly/ea = loc
|
||||
if(istype(ea))
|
||||
ea.interact(usr)
|
||||
|
||||
if(href_list["pin_name"])
|
||||
if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool)
|
||||
href_list["wire"] = 1
|
||||
else
|
||||
var/obj/item/device/multitool/M = held_item
|
||||
M.wire(pin,usr)
|
||||
|
||||
|
||||
|
||||
if(href_list["pin_data"])
|
||||
if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool)
|
||||
href_list["wire"] = 1
|
||||
|
||||
else
|
||||
var/datum/integrated_io/io = pin
|
||||
io.ask_for_pin_data(usr, held_item) // The pins themselves will determine how to ask for data, and will validate the data.
|
||||
/*
|
||||
if(io.io_type == DATA_CHANNEL)
|
||||
|
||||
var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number", "null")
|
||||
if(!check_interactivity(usr))
|
||||
return
|
||||
|
||||
var/new_data = null
|
||||
switch(type_to_use)
|
||||
if("string")
|
||||
new_data = input("Now type in a string.","[src] string writing") as null|text
|
||||
to_chat(usr, "<span class='notice'>You input [new_data] into the pin.</span>")
|
||||
//to_chat(user, "<span class='notice'>You write '[new_data]' to the '[io]' pin of \the [io.holder].</span>")
|
||||
if("number")
|
||||
new_data = input("Now type in a number.","[src] number writing") as null|num
|
||||
if(isnum(new_data) && check_interactivity(usr) )
|
||||
to_chat(usr, "<span class='notice'>You input [new_data] into the pin.</span>")
|
||||
if("null")
|
||||
if(check_interactivity(usr))
|
||||
to_chat(usr, "<span class='notice'>You clear the pin's memory.</span>")
|
||||
|
||||
io.write_data_to_pin(new_data)
|
||||
|
||||
else if(io.io_type == PULSE_CHANNEL)
|
||||
io.holder.check_then_do_work(ignore_power = TRUE)
|
||||
to_chat(usr, "<span class='notice'>You pulse \the [io.holder]'s [io] pin.</span>")
|
||||
*/
|
||||
|
||||
|
||||
if(href_list["pin_unwire"])
|
||||
if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool)
|
||||
href_list["wire"] = 1
|
||||
else
|
||||
var/obj/item/device/multitool/M = held_item
|
||||
M.unwire(pin, linked, usr)
|
||||
|
||||
if(href_list["wire"])
|
||||
if(istype(held_item, /obj/item/device/integrated_electronics/wirer))
|
||||
var/obj/item/device/integrated_electronics/wirer/wirer = held_item
|
||||
if(linked)
|
||||
wirer.wire(linked, usr)
|
||||
else if(pin)
|
||||
wirer.wire(pin, usr)
|
||||
|
||||
else if(istype(held_item, /obj/item/device/integrated_electronics/debugger))
|
||||
var/obj/item/device/integrated_electronics/debugger/debugger = held_item
|
||||
if(pin)
|
||||
debugger.write_data(pin, usr)
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You can't do a whole lot without the proper tools.</span>")
|
||||
|
||||
if(href_list["examine"])
|
||||
var/obj/item/integrated_circuit/examined
|
||||
if(href_list["examined"])
|
||||
examined = href_list["examined"]
|
||||
else
|
||||
examined = src
|
||||
examined.interact(usr)
|
||||
update = 0
|
||||
|
||||
if(href_list["bottom"])
|
||||
var/obj/item/integrated_circuit/circuit = locate(href_list["bottom"]) in src.assembly.contents
|
||||
var/assy = circuit.assembly
|
||||
if(!circuit)
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("rename")
|
||||
rename_component(usr)
|
||||
return
|
||||
circuit.loc = null
|
||||
circuit.loc = assy
|
||||
. = 1
|
||||
update_to_assembly = 1
|
||||
|
||||
if(href_list["scan"])
|
||||
if(istype(held_item, /obj/item/device/integrated_electronics/debugger))
|
||||
var/obj/item/device/integrated_electronics/debugger/D = held_item
|
||||
if(D.accepting_refs)
|
||||
D.afterattack(src, usr, TRUE)
|
||||
if("wire", "pin_name", "pin_data", "pin_unwire")
|
||||
if(istype(held_item, /obj/item/device/multitool) && allow_multitool)
|
||||
var/obj/item/device/multitool/M = held_item
|
||||
switch(action)
|
||||
if("pin_name")
|
||||
M.wire(pin, usr)
|
||||
if("pin_data")
|
||||
var/datum/integrated_io/io = pin
|
||||
io.ask_for_pin_data(usr, held_item) // The pins themselves will determine how to ask for data, and will validate the data.
|
||||
if("pin_unwire")
|
||||
M.unwire(pin, linked, usr)
|
||||
|
||||
else if(istype(held_item, /obj/item/device/integrated_electronics/wirer))
|
||||
var/obj/item/device/integrated_electronics/wirer/wirer = held_item
|
||||
if(linked)
|
||||
wirer.wire(linked, usr)
|
||||
else if(pin)
|
||||
wirer.wire(pin, usr)
|
||||
|
||||
else if(istype(held_item, /obj/item/device/integrated_electronics/debugger))
|
||||
var/obj/item/device/integrated_electronics/debugger/debugger = held_item
|
||||
if(pin)
|
||||
debugger.write_data(pin, usr)
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>The Debugger's 'ref scanner' needs to be on.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You need a multitool/debugger set to 'ref' mode to do that.</span>")
|
||||
|
||||
if(href_list["return"])
|
||||
if(A)
|
||||
update_to_assembly = 1
|
||||
usr << browse(null, "window=circuit-\ref[src];border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>This circuit is not in an assembly!</span>")
|
||||
|
||||
|
||||
if(href_list["remove"])
|
||||
if(!A)
|
||||
to_chat(usr, "<span class='warning'>This circuit is not in an assembly!</span>")
|
||||
to_chat(usr, "<span class='warning'>You can't do a whole lot without the proper tools.</span>")
|
||||
return
|
||||
if(!removable)
|
||||
to_chat(usr, "<span class='warning'>\The [src] seems to be permanently attached to the case.</span>")
|
||||
return
|
||||
var/obj/item/device/electronic_assembly/ea = loc
|
||||
power_fail()
|
||||
disconnect_all()
|
||||
var/turf/T = get_turf(src)
|
||||
forceMove(T)
|
||||
assembly = null
|
||||
playsound(T, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
to_chat(usr, "<span class='notice'>You pop \the [src] out of the case, and slide it out.</span>")
|
||||
|
||||
if(istype(ea))
|
||||
ea.interact(usr)
|
||||
update = 0
|
||||
if("scan")
|
||||
if(istype(held_item, /obj/item/device/integrated_electronics/debugger))
|
||||
var/obj/item/device/integrated_electronics/debugger/D = held_item
|
||||
if(D.accepting_refs)
|
||||
D.afterattack(src, usr, TRUE)
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>The Debugger's 'ref scanner' needs to be on.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You need a multitool/debugger set to 'ref' mode to do that.</span>")
|
||||
return
|
||||
|
||||
|
||||
if("examine")
|
||||
var/obj/item/integrated_circuit/examined = locate(params["ref"])
|
||||
if(istype(examined) && (examined.loc == loc))
|
||||
if(ui.parent_ui)
|
||||
examined.tgui_interact(usr, null, ui.parent_ui)
|
||||
else
|
||||
examined.tgui_interact(usr)
|
||||
|
||||
if("remove")
|
||||
remove(usr)
|
||||
return
|
||||
return FALSE
|
||||
|
||||
/obj/item/integrated_circuit/proc/remove(mob/user)
|
||||
var/obj/item/device/electronic_assembly/A = assembly
|
||||
if(!A)
|
||||
to_chat(user, "<span class='warning'>This circuit is not in an assembly!</span>")
|
||||
return
|
||||
if(!removable)
|
||||
to_chat(user, "<span class='warning'>\The [src] seems to be permanently attached to the case.</span>")
|
||||
return
|
||||
var/obj/item/device/electronic_assembly/ea = loc
|
||||
|
||||
if(update)
|
||||
if(A && istype(A) && update_to_assembly)
|
||||
A.interact(usr)
|
||||
else
|
||||
interact(usr) // To refresh the UI.
|
||||
|
||||
power_fail()
|
||||
disconnect_all()
|
||||
var/turf/T = get_turf(src)
|
||||
forceMove(T)
|
||||
assembly = null
|
||||
playsound(T, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
to_chat(user, "<span class='notice'>You pop \the [src] out of the case, and slide it out.</span>")
|
||||
|
||||
if(istype(ea))
|
||||
ea.tgui_interact(user)
|
||||
|
||||
/obj/item/integrated_circuit/proc/push_data()
|
||||
for(var/datum/integrated_io/O in outputs)
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
var/upgraded = FALSE // When hit with an upgrade disk, will turn true, allowing it to print the higher tier circuits.
|
||||
var/can_clone = FALSE // Same for above, but will allow the printer to duplicate a specific assembly. (Not implemented)
|
||||
// var/static/list/recipe_list = list()
|
||||
var/current_category = null
|
||||
var/obj/item/device/electronic_assembly/assembly_to_clone = null
|
||||
var/obj/item/device/electronic_assembly/assembly_to_clone = null // Not implemented x3
|
||||
var/dirty_items = FALSE
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/upgraded
|
||||
upgraded = TRUE
|
||||
@@ -47,7 +47,7 @@
|
||||
if(stack.use(max(1, round(num)))) // We don't want to create stacks that aren't whole numbers
|
||||
to_chat(user, span("notice", "You add [num] sheet\s to \the [src]."))
|
||||
metal += num * metal_per_sheet
|
||||
interact(user)
|
||||
attack_self(user)
|
||||
return TRUE
|
||||
|
||||
if(istype(O,/obj/item/integrated_circuit))
|
||||
@@ -55,7 +55,7 @@
|
||||
user.unEquip(O)
|
||||
metal = min(metal + O.w_class, max_metal)
|
||||
qdel(O)
|
||||
interact(user)
|
||||
attack_self(user)
|
||||
return TRUE
|
||||
|
||||
if(istype(O,/obj/item/weapon/disk/integrated_circuit/upgrade/advanced))
|
||||
@@ -64,7 +64,8 @@
|
||||
return TRUE
|
||||
to_chat(user, span("notice", "You install \the [O] into \the [src]."))
|
||||
upgraded = TRUE
|
||||
interact(user)
|
||||
dirty_items = TRUE
|
||||
attack_self(user)
|
||||
return TRUE
|
||||
|
||||
if(istype(O,/obj/item/weapon/disk/integrated_circuit/upgrade/clone))
|
||||
@@ -73,98 +74,126 @@
|
||||
return TRUE
|
||||
to_chat(user, span("notice", "You install \the [O] into \the [src]."))
|
||||
can_clone = TRUE
|
||||
interact(user)
|
||||
attack_self(user)
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/vv_edit_var(var_name, var_value)
|
||||
// Gotta update the static data in case an admin VV's the upgraded var for some reason..!
|
||||
if(var_name == "upgraded")
|
||||
dirty_items = TRUE
|
||||
return ..()
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/attack_self(var/mob/user)
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/interact(mob/user)
|
||||
var/window_height = 600
|
||||
var/window_width = 500
|
||||
/obj/item/device/integrated_circuit_printer/tgui_state(mob/user)
|
||||
return GLOB.tgui_inventory_state
|
||||
|
||||
if(isnull(current_category))
|
||||
current_category = SScircuit.circuit_fabricator_recipe_list[1]
|
||||
/obj/item/device/integrated_circuit_printer/tgui_interact(mob/user, datum/tgui/ui)
|
||||
if(dirty_items)
|
||||
update_tgui_static_data(user, ui)
|
||||
dirty_items = FALSE
|
||||
|
||||
var/HTML = "<center><h2>Integrated Circuit Printer</h2></center><br>"
|
||||
if(!debug)
|
||||
HTML += "Metal: [metal/metal_per_sheet]/[max_metal/metal_per_sheet] sheets.<br>"
|
||||
else
|
||||
HTML += "Metal: INFINITY.<br>"
|
||||
HTML += "Circuits available: [upgraded ? "Advanced":"Regular"].<br>"
|
||||
HTML += "Assembly Cloning: [can_clone ? "Available": "Unavailable"].<br>"
|
||||
if(assembly_to_clone)
|
||||
HTML += "Assembly '[assembly_to_clone.name]' loaded.<br>"
|
||||
HTML += "Crossed out circuits mean that the printer is not sufficentally upgraded to create that circuit.<br>"
|
||||
HTML += "<hr>"
|
||||
HTML += "Categories:"
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "ICPrinter", name) // 500, 600
|
||||
ui.open()
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/tgui_static_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
var/list/categories = list()
|
||||
for(var/category in SScircuit.circuit_fabricator_recipe_list)
|
||||
if(category != current_category)
|
||||
HTML += " <a href='?src=\ref[src];category=[category]'>\[[category]\]</a> "
|
||||
else // Bold the button if it's already selected.
|
||||
HTML += " <b>\[[category]\]</b> "
|
||||
HTML += "<hr>"
|
||||
HTML += "<center><h4>[current_category]</h4></center>"
|
||||
var/list/cat_obj = list(
|
||||
"name" = category,
|
||||
"items" = list()
|
||||
)
|
||||
var/list/circuit_list = SScircuit.circuit_fabricator_recipe_list[category]
|
||||
for(var/path in circuit_list)
|
||||
var/obj/O = path
|
||||
var/can_build = TRUE
|
||||
if(ispath(path, /obj/item/integrated_circuit))
|
||||
var/obj/item/integrated_circuit/IC = path
|
||||
if((initial(IC.spawn_flags) & IC_SPAWN_RESEARCH) && (!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT)) && !upgraded)
|
||||
can_build = FALSE
|
||||
|
||||
var/list/current_list = SScircuit.circuit_fabricator_recipe_list[current_category]
|
||||
for(var/path in current_list)
|
||||
var/obj/O = path
|
||||
var/can_build = TRUE
|
||||
if(ispath(path, /obj/item/integrated_circuit))
|
||||
var/obj/item/integrated_circuit/IC = path
|
||||
if((initial(IC.spawn_flags) & IC_SPAWN_RESEARCH) && (!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT)) && !upgraded)
|
||||
can_build = FALSE
|
||||
if(can_build)
|
||||
HTML += "<A href='?src=\ref[src];build=[path]'>\[[initial(O.name)]\]</A>: [initial(O.desc)]<br>"
|
||||
else
|
||||
HTML += "<s>\[[initial(O.name)]\]</s>: [initial(O.desc)]<br>"
|
||||
var/cost = 1
|
||||
if(ispath(path, /obj/item/device/electronic_assembly))
|
||||
var/obj/item/device/electronic_assembly/E = path
|
||||
cost = round((initial(E.max_complexity) + initial(E.max_components)) / 4)
|
||||
else
|
||||
var/obj/item/I = path
|
||||
cost = initial(I.w_class)
|
||||
|
||||
user << browse(jointext(HTML, null), "window=integrated_printer;size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
cat_obj["items"].Add(list(list(
|
||||
"name" = initial(O.name),
|
||||
"desc" = initial(O.desc),
|
||||
"can_build" = can_build,
|
||||
"cost" = cost,
|
||||
"path" = path,
|
||||
)))
|
||||
categories.Add(list(cat_obj))
|
||||
data["categories"] = categories
|
||||
|
||||
return data
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/Topic(href, href_list)
|
||||
/obj/item/device/integrated_circuit_printer/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["metal"] = metal
|
||||
data["max_metal"] = max_metal
|
||||
data["metal_per_sheet"] = metal_per_sheet
|
||||
data["debug"] = debug
|
||||
data["upgraded"] = upgraded
|
||||
data["can_clone"] = can_clone
|
||||
data["assembly_to_clone"] = assembly_to_clone
|
||||
|
||||
return data
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
if(href_list["category"])
|
||||
current_category = href_list["category"]
|
||||
|
||||
if(href_list["build"])
|
||||
var/build_type = text2path(href_list["build"])
|
||||
if(!build_type || !ispath(build_type))
|
||||
return 1
|
||||
|
||||
var/cost = 1
|
||||
|
||||
if(isnull(current_category))
|
||||
current_category = SScircuit.circuit_fabricator_recipe_list[1]
|
||||
if(ispath(build_type, /obj/item/device/electronic_assembly))
|
||||
var/obj/item/device/electronic_assembly/E = build_type
|
||||
cost = round( (initial(E.max_complexity) + initial(E.max_components) ) / 4)
|
||||
else
|
||||
var/obj/item/I = build_type
|
||||
cost = initial(I.w_class)
|
||||
if(!(build_type in SScircuit.circuit_fabricator_recipe_list[current_category]))
|
||||
return
|
||||
|
||||
if(!debug)
|
||||
if(!Adjacent(usr))
|
||||
to_chat(usr, "<span class='notice'>You are too far away from \the [src].</span>")
|
||||
if(metal - cost < 0)
|
||||
to_chat(usr, "<span class='warning'>You need [cost] metal to build that!.</span>")
|
||||
switch(action)
|
||||
if("build")
|
||||
var/build_type = text2path(params["build"])
|
||||
if(!build_type || !ispath(build_type))
|
||||
return 1
|
||||
metal -= cost
|
||||
var/obj/item/built = new build_type(get_turf(loc))
|
||||
usr.put_in_hands(built)
|
||||
to_chat(usr, "<span class='notice'>[capitalize(built.name)] printed.</span>")
|
||||
playsound(src, 'sound/items/jaws_pry.ogg', 50, TRUE)
|
||||
|
||||
interact(usr)
|
||||
var/cost = 1
|
||||
|
||||
if(ispath(build_type, /obj/item/device/electronic_assembly))
|
||||
var/obj/item/device/electronic_assembly/E = build_type
|
||||
cost = round( (initial(E.max_complexity) + initial(E.max_components) ) / 4)
|
||||
else
|
||||
var/obj/item/I = build_type
|
||||
cost = initial(I.w_class)
|
||||
|
||||
var/in_some_category = FALSE
|
||||
for(var/category in SScircuit.circuit_fabricator_recipe_list)
|
||||
if(build_type in SScircuit.circuit_fabricator_recipe_list[category])
|
||||
in_some_category = TRUE
|
||||
break
|
||||
if(!in_some_category)
|
||||
return
|
||||
|
||||
if(!debug)
|
||||
if(!Adjacent(usr))
|
||||
to_chat(usr, "<span class='notice'>You are too far away from \the [src].</span>")
|
||||
if(metal - cost < 0)
|
||||
to_chat(usr, "<span class='warning'>You need [cost] metal to build that!.</span>")
|
||||
return 1
|
||||
metal -= cost
|
||||
var/obj/item/built = new build_type(get_turf(loc))
|
||||
usr.put_in_hands(built)
|
||||
to_chat(usr, "<span class='notice'>[capitalize(built.name)] printed.</span>")
|
||||
playsound(src, 'sound/items/jaws_pry.ogg', 50, TRUE)
|
||||
return TRUE
|
||||
|
||||
// FUKKEN UPGRADE DISKS
|
||||
/obj/item/weapon/disk/integrated_circuit/upgrade
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
min_target_dist = 0
|
||||
|
||||
var/cleaning = 0
|
||||
var/screwloose = 0
|
||||
var/oddbutton = 0
|
||||
var/wet_floors = 0
|
||||
var/spray_blood = 0
|
||||
var/blood = 1
|
||||
var/list/target_types = list()
|
||||
|
||||
@@ -25,16 +25,16 @@
|
||||
return ..()
|
||||
|
||||
/mob/living/bot/cleanbot/handleIdle()
|
||||
if(!screwloose && !oddbutton && prob(2))
|
||||
if(!wet_floors && !spray_blood && prob(2))
|
||||
custom_emote(2, "makes an excited booping sound!")
|
||||
playsound(src, 'sound/machines/synth_yes.ogg', 50, 0)
|
||||
|
||||
if(screwloose && prob(5)) // Make a mess
|
||||
if(wet_floors && prob(5)) // Make a mess
|
||||
if(istype(loc, /turf/simulated))
|
||||
var/turf/simulated/T = loc
|
||||
T.wet_floor()
|
||||
|
||||
if(oddbutton && prob(5)) // Make a big mess
|
||||
if(spray_blood && prob(5)) // Make a big mess
|
||||
visible_message("Something flies out of [src]. It seems to be acting oddly.")
|
||||
var/obj/effect/decal/cleanable/blood/gibs/gib = new /obj/effect/decal/cleanable/blood/gibs(loc)
|
||||
// TODO - I have a feeling weakrefs will not work in ignore_list, verify this ~Leshana
|
||||
@@ -149,56 +149,65 @@
|
||||
icon_state = "cleanbot[on]"
|
||||
|
||||
/mob/living/bot/cleanbot/attack_hand(var/mob/user)
|
||||
var/dat
|
||||
dat += "<TT><B>Automatic Station Cleaner v1.0</B></TT><BR><BR>"
|
||||
dat += "Status: <A href='?src=\ref[src];operation=start'>[on ? "On" : "Off"]</A><BR>"
|
||||
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
|
||||
dat += "Maintenance panel is [open ? "opened" : "closed"]"
|
||||
if(!locked || issilicon(user))
|
||||
dat += "<BR>Cleans Blood: <A href='?src=\ref[src];operation=blood'>[blood ? "Yes" : "No"]</A><BR>"
|
||||
if(using_map.bot_patrolling)
|
||||
dat += "<BR>Patrol station: <A href='?src=\ref[src];operation=patrol'>[will_patrol ? "Yes" : "No"]</A><BR>"
|
||||
if(open && !locked)
|
||||
dat += "Odd looking screw twiddled: <A href='?src=\ref[src];operation=screw'>[screwloose ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Weird button pressed: <A href='?src=\ref[src];operation=oddbutton'>[oddbutton ? "Yes" : "No"]</A>"
|
||||
tgui_interact(user)
|
||||
|
||||
user << browse("<HEAD><TITLE>Cleaner v1.0 controls</TITLE></HEAD>[dat]", "window=autocleaner")
|
||||
onclose(user, "autocleaner")
|
||||
return
|
||||
/mob/living/bot/cleanbot/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Cleanbot", name)
|
||||
ui.open()
|
||||
|
||||
/mob/living/bot/cleanbot/Topic(href, href_list)
|
||||
/mob/living/bot/cleanbot/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
data["on"] = on
|
||||
data["open"] = open
|
||||
data["locked"] = locked
|
||||
|
||||
data["blood"] = blood
|
||||
data["patrol"] = will_patrol
|
||||
|
||||
data["wet_floors"] = wet_floors
|
||||
data["spray_blood"] = spray_blood
|
||||
data["version"] = "v2.0"
|
||||
return data
|
||||
|
||||
/mob/living/bot/cleanbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return
|
||||
return TRUE
|
||||
usr.set_machine(src)
|
||||
add_fingerprint(usr)
|
||||
switch(href_list["operation"])
|
||||
switch(action)
|
||||
if("start")
|
||||
if(on)
|
||||
turn_off()
|
||||
else
|
||||
turn_on()
|
||||
. = TRUE
|
||||
if("blood")
|
||||
blood = !blood
|
||||
get_targets()
|
||||
. = TRUE
|
||||
if("patrol")
|
||||
will_patrol = !will_patrol
|
||||
patrol_path = null
|
||||
if("screw")
|
||||
screwloose = !screwloose
|
||||
. = TRUE
|
||||
if("wet_floors")
|
||||
wet_floors = !wet_floors
|
||||
to_chat(usr, "<span class='notice'>You twiddle the screw.</span>")
|
||||
if("oddbutton")
|
||||
oddbutton = !oddbutton
|
||||
. = TRUE
|
||||
if("spray_blood")
|
||||
spray_blood = !spray_blood
|
||||
to_chat(usr, "<span class='notice'>You press the weird button.</span>")
|
||||
attack_hand(usr)
|
||||
. = TRUE
|
||||
|
||||
/mob/living/bot/cleanbot/emag_act(var/remaining_uses, var/mob/user)
|
||||
. = ..()
|
||||
if(!screwloose || !oddbutton)
|
||||
if(!wet_floors || !spray_blood)
|
||||
if(user)
|
||||
to_chat(user, "<span class='notice'>The [src] buzzes and beeps.</span>")
|
||||
playsound(src, 'sound/machines/buzzbeep.ogg', 50, 0)
|
||||
oddbutton = 1
|
||||
screwloose = 1
|
||||
spray_blood = 1
|
||||
wet_floors = 1
|
||||
return 1
|
||||
|
||||
/mob/living/bot/cleanbot/proc/get_targets()
|
||||
|
||||
@@ -71,53 +71,31 @@
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/mob/living/bot/cleanbot/edCLN/attack_hand(var/mob/user)
|
||||
var/dat
|
||||
usr.set_machine(src)
|
||||
add_fingerprint(usr)
|
||||
/mob/living/bot/cleanbot/edCLN/tgui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
data["version"] = "v3.0"
|
||||
data["rgbpanel"] = TRUE
|
||||
data["red_switch"] = red_switch
|
||||
data["green_switch"] = green_switch
|
||||
data["blue_switch"] = blue_switch
|
||||
return data
|
||||
|
||||
dat += "<TT><B>Automatic Station Cleaner v2.0</B></TT><BR><BR>"
|
||||
dat += "Status: <A href='?src=\ref[src];operation=start'>[on ? "On" : "Off"]</A><BR>"
|
||||
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
|
||||
dat += "Maintenance panel is [open ? "opened" : "closed"]"
|
||||
if(!locked || issilicon(user))
|
||||
dat += "<BR>Cleans Blood: <A href='?src=\ref[src];operation=blood'>[blood ? "Yes" : "No"]</A><BR>"
|
||||
if(using_map.bot_patrolling)
|
||||
dat += "<BR>Patrol station: <A href='?src=\ref[src];operation=patrol'>[will_patrol ? "Yes" : "No"]</A><BR>"
|
||||
if(open && !locked)
|
||||
dat += "<BR>Red Switch: <A href='?src=\ref[src];operation=red_switch'>[red_switch ? "On" : "Off"]</A><BR>"
|
||||
dat += "<BR>Green Switch: <A href='?src=\ref[src];operation=green_switch'>[green_switch ? "On" : "Off"]</A><BR>"
|
||||
dat += "<BR>Blue Switch: <A href='?src=\ref[src];operation=blue_switch'>[blue_switch ? "On" : "Off"]</A>"
|
||||
|
||||
user << browse("<HEAD><TITLE>Cleaner v2.0 controls</TITLE></HEAD>[dat]", "window=autocleaner")
|
||||
onclose(user, "autocleaner")
|
||||
return
|
||||
|
||||
/mob/living/bot/cleanbot/edCLN/Topic(href, href_list)
|
||||
usr.set_machine(src)
|
||||
add_fingerprint(usr)
|
||||
switch(href_list["operation"])
|
||||
if("start")
|
||||
if(on)
|
||||
turn_off()
|
||||
else
|
||||
turn_on()
|
||||
if("blood")
|
||||
blood = !blood
|
||||
get_targets()
|
||||
if("patrol")
|
||||
will_patrol = !will_patrol
|
||||
patrol_path = null
|
||||
/mob/living/bot/cleanbot/edCLN/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
switch(action)
|
||||
if("red_switch")
|
||||
red_switch = !red_switch
|
||||
to_chat(usr, "<span class='notice'>You flip the red switch [red_switch ? "on" : "off"].</span>")
|
||||
. = TRUE
|
||||
if("green_switch")
|
||||
green_switch = !blue_switch
|
||||
green_switch = !green_switch
|
||||
to_chat(usr, "<span class='notice'>You flip the green switch [green_switch ? "on" : "off"].</span>")
|
||||
. = TRUE
|
||||
if("blue_switch")
|
||||
blue_switch = !blue_switch
|
||||
to_chat(usr, "<span class='notice'>You flip the blue switch [blue_switch ? "on" : "off"].</span>")
|
||||
attack_hand(usr)
|
||||
. = TRUE
|
||||
|
||||
/mob/living/bot/cleanbot/edCLN/emag_act(var/remaining_uses, var/mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -30,38 +30,45 @@
|
||||
tank = newTank
|
||||
tank.forceMove(src)
|
||||
|
||||
/mob/living/bot/farmbot/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Farmbot", name)
|
||||
ui.open()
|
||||
|
||||
/mob/living/bot/farmbot/attack_hand(var/mob/user as mob)
|
||||
/mob/living/bot/farmbot/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["on"] = on
|
||||
data["tank"] = !!tank
|
||||
if(tank)
|
||||
data["tankVolume"] = tank.reagents.total_volume
|
||||
data["tankMaxVolume"] = tank.reagents.maximum_volume
|
||||
data["locked"] = locked
|
||||
|
||||
data["waters_trays"] = null
|
||||
data["refills_water"] = null
|
||||
data["uproots_weeds"] = null
|
||||
data["replaces_nutriment"] = null
|
||||
data["collects_produce"] = null
|
||||
data["removes_dead"] = null
|
||||
|
||||
if(!locked)
|
||||
data["waters_trays"] = waters_trays
|
||||
data["refills_water"] = refills_water
|
||||
data["uproots_weeds"] = uproots_weeds
|
||||
data["replaces_nutriment"] = replaces_nutriment
|
||||
data["collects_produce"] = collects_produce
|
||||
data["removes_dead"] = removes_dead
|
||||
|
||||
return data
|
||||
|
||||
|
||||
/mob/living/bot/farmbot/attack_hand(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
var/dat = ""
|
||||
dat += "<TT><B>Automatic Hyrdoponic Assisting Unit v1.0</B></TT><BR><BR>"
|
||||
dat += "Status: <A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A><BR>"
|
||||
dat += "Water Tank: "
|
||||
if (tank)
|
||||
dat += "[tank.reagents.total_volume]/[tank.reagents.maximum_volume]"
|
||||
else
|
||||
dat += "Error: Watertank not found"
|
||||
dat += "<br>Behaviour controls are [locked ? "locked" : "unlocked"]<hr>"
|
||||
if(!locked)
|
||||
dat += "<TT>Watering controls:<br>"
|
||||
dat += "Water plants : <A href='?src=\ref[src];water=1'>[waters_trays ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Refill watertank : <A href='?src=\ref[src];refill=1'>[refills_water ? "Yes" : "No"]</A><BR>"
|
||||
dat += "<br>Weeding controls:<br>"
|
||||
dat += "Weed plants: <A href='?src=\ref[src];weed=1'>[uproots_weeds ? "Yes" : "No"]</A><BR>"
|
||||
dat += "<br>Nutriment controls:<br>"
|
||||
dat += "Replace fertilizer: <A href='?src=\ref[src];replacenutri=1'>[replaces_nutriment ? "Yes" : "No"]</A><BR>"
|
||||
/* VOREStation Removal - No whole-job lag-bot automation.
|
||||
dat += "<br>Plant controls:<br>"
|
||||
dat += "Collect produce: <A href='?src=\ref[src];collect=1'>[collects_produce ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Remove dead plants: <A href='?src=\ref[src];removedead=1'>[removes_dead ? "Yes" : "No"]</A><BR>"
|
||||
*/
|
||||
dat += "</TT>"
|
||||
|
||||
user << browse("<HEAD><TITLE>Farmbot v1.0 controls</TITLE></HEAD>[dat]", "window=autofarm")
|
||||
onclose(user, "autofarm")
|
||||
return
|
||||
tgui_interact(user)
|
||||
|
||||
/mob/living/bot/farmbot/emag_act(var/remaining_charges, var/mob/user)
|
||||
. = ..()
|
||||
@@ -73,35 +80,47 @@
|
||||
emagged = 1
|
||||
return 1
|
||||
|
||||
/mob/living/bot/farmbot/Topic(href, href_list)
|
||||
/mob/living/bot/farmbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return
|
||||
usr.machine = src
|
||||
return TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
if((href_list["power"]) && (access_scanner.allowed(usr)))
|
||||
if(on)
|
||||
turn_off()
|
||||
else
|
||||
turn_on()
|
||||
|
||||
switch(action)
|
||||
if("power")
|
||||
if(!access_scanner.allowed(usr))
|
||||
return FALSE
|
||||
if(on)
|
||||
turn_off()
|
||||
else
|
||||
turn_on()
|
||||
. = TRUE
|
||||
|
||||
if(locked)
|
||||
return
|
||||
return TRUE
|
||||
|
||||
if(href_list["water"])
|
||||
waters_trays = !waters_trays
|
||||
else if(href_list["refill"])
|
||||
refills_water = !refills_water
|
||||
else if(href_list["weed"])
|
||||
uproots_weeds = !uproots_weeds
|
||||
else if(href_list["replacenutri"])
|
||||
replaces_nutriment = !replaces_nutriment
|
||||
else if(href_list["collect"])
|
||||
collects_produce = !collects_produce
|
||||
else if(href_list["removedead"])
|
||||
removes_dead = !removes_dead
|
||||
switch(action)
|
||||
if("water")
|
||||
waters_trays = !waters_trays
|
||||
. = TRUE
|
||||
if("refill")
|
||||
refills_water = !refills_water
|
||||
. = TRUE
|
||||
if("weed")
|
||||
uproots_weeds = !uproots_weeds
|
||||
. = TRUE
|
||||
if("replacenutri")
|
||||
replaces_nutriment = !replaces_nutriment
|
||||
. = TRUE
|
||||
// VOREStation Edit: No automatic hydroponics
|
||||
// if("collect")
|
||||
// collects_produce = !collects_produce
|
||||
// . = TRUE
|
||||
// if("removedead")
|
||||
// removes_dead = !removes_dead
|
||||
// . = TRUE
|
||||
// VOREStation Edit End
|
||||
|
||||
attack_hand(usr)
|
||||
return
|
||||
|
||||
/mob/living/bot/farmbot/update_icons()
|
||||
if(on && action)
|
||||
@@ -109,13 +128,10 @@
|
||||
else
|
||||
icon_state = "farmbot[on]"
|
||||
|
||||
|
||||
/mob/living/bot/farmbot/handleRegular()
|
||||
if(emagged && prob(1))
|
||||
flick("farmbot_broke", src)
|
||||
|
||||
|
||||
|
||||
/mob/living/bot/farmbot/handleAdjacentTarget()
|
||||
UnarmedAttack(target)
|
||||
|
||||
@@ -137,6 +153,7 @@
|
||||
times_idle = 0 //VOREStation Add - Idle shutoff time
|
||||
return
|
||||
if(++times_idle == 150) turn_off() //VOREStation Add - Idle shutoff time
|
||||
|
||||
/mob/living/bot/farmbot/calcTargetPath() // We need to land NEXT to the tray, because the tray itself is impassable
|
||||
for(var/trayDir in list(NORTH, SOUTH, EAST, WEST))
|
||||
target_path = AStar(get_turf(loc), get_step(get_turf(target), trayDir), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, max_target_dist, id = botcard)
|
||||
|
||||
@@ -29,28 +29,38 @@
|
||||
else
|
||||
icon_state = "floorbot[on]e"
|
||||
|
||||
/mob/living/bot/floorbot/attack_hand(var/mob/user)
|
||||
user.set_machine(src)
|
||||
var/list/dat = list()
|
||||
dat += "<TT><B>Automatic Station Floor Repairer v1.0</B></TT><BR><BR>"
|
||||
dat += "Status: <A href='?src=\ref[src];operation=start'>[src.on ? "On" : "Off"]</A><BR>"
|
||||
dat += "Maintenance panel is [open ? "opened" : "closed"]<BR>"
|
||||
dat += "Tiles left: [amount]<BR>"
|
||||
dat += "Behvaiour controls are [locked ? "locked" : "unlocked"]<BR>"
|
||||
/mob/living/bot/floorbot/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Floorbot", name)
|
||||
ui.open()
|
||||
|
||||
/mob/living/bot/floorbot/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["on"] = on
|
||||
data["open"] = open
|
||||
data["locked"] = locked
|
||||
|
||||
data["amount"] = amount
|
||||
|
||||
data["possible_bmode"] = list("NORTH", "EAST", "SOUTH", "WEST")
|
||||
|
||||
data["improvefloors"] = null
|
||||
data["eattiles"] = null
|
||||
data["maketiles"] = null
|
||||
data["bmode"] = null
|
||||
|
||||
if(!locked || issilicon(user))
|
||||
dat += "Improves floors: <A href='?src=\ref[src];operation=improve'>[improvefloors ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Finds tiles: <A href='?src=\ref[src];operation=tiles'>[eattiles ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Make singles pieces of metal into tiles when empty: <A href='?src=\ref[src];operation=make'>[maketiles ? "Yes" : "No"]</A><BR>"
|
||||
var/bmode
|
||||
if(targetdirection)
|
||||
bmode = dir2text(targetdirection)
|
||||
else
|
||||
bmode = "Disabled"
|
||||
dat += "<BR><BR>Bridge Mode : <A href='?src=\ref[src];operation=bridgemode'>[bmode]</A><BR>"
|
||||
var/datum/browser/popup = new(user, "autorepair", "Repairbot v1.1 controls")
|
||||
popup.set_content(jointext(dat,null))
|
||||
popup.open()
|
||||
return
|
||||
data["improvefloors"] = improvefloors
|
||||
data["eattiles"] = eattiles
|
||||
data["maketiles"] = maketiles
|
||||
data["bmode"] = dir2text(targetdirection)
|
||||
|
||||
return data
|
||||
|
||||
/mob/living/bot/floorbot/attack_hand(var/mob/user)
|
||||
tgui_interact(user)
|
||||
|
||||
/mob/living/bot/floorbot/emag_act(var/remaining_charges, var/mob/user)
|
||||
. = ..()
|
||||
@@ -61,38 +71,36 @@
|
||||
playsound(src, 'sound/machines/buzzbeep.ogg', 50, 0)
|
||||
return 1
|
||||
|
||||
/mob/living/bot/floorbot/Topic(href, href_list)
|
||||
/mob/living/bot/floorbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return
|
||||
usr.set_machine(src)
|
||||
return TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
switch(href_list["operation"])
|
||||
|
||||
switch(action)
|
||||
if("start")
|
||||
if (on)
|
||||
if(on)
|
||||
turn_off()
|
||||
else
|
||||
turn_on()
|
||||
. = TRUE
|
||||
|
||||
if(locked && !issilicon(usr))
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("improve")
|
||||
improvefloors = !improvefloors
|
||||
. = TRUE
|
||||
if("tiles")
|
||||
eattiles = !eattiles
|
||||
. = TRUE
|
||||
if("make")
|
||||
maketiles = !maketiles
|
||||
. = TRUE
|
||||
if("bridgemode")
|
||||
switch(targetdirection)
|
||||
if(null)
|
||||
targetdirection = 1
|
||||
if(1)
|
||||
targetdirection = 2
|
||||
if(2)
|
||||
targetdirection = 4
|
||||
if(4)
|
||||
targetdirection = 8
|
||||
if(8)
|
||||
targetdirection = null
|
||||
else
|
||||
targetdirection = null
|
||||
attack_hand(usr)
|
||||
targetdirection = text2dir(params["dir"])
|
||||
. = TRUE
|
||||
|
||||
/mob/living/bot/floorbot/handleRegular()
|
||||
++tilemake
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
#define MEDBOT_PANIC_ENDING 90
|
||||
#define MEDBOT_PANIC_END 100
|
||||
|
||||
#define MEDBOT_MIN_INJECTION 5
|
||||
#define MEDBOT_MAX_INJECTION 15
|
||||
#define MEDBOT_MIN_HEAL 0.1
|
||||
#define MEDBOT_MAX_HEAL 75
|
||||
|
||||
/mob/living/bot/medbot
|
||||
name = "Medibot"
|
||||
desc = "A little medical robot. He looks somewhat underwhelmed."
|
||||
@@ -209,45 +214,39 @@
|
||||
if(do_after(H, 3 SECONDS, target=src))
|
||||
set_right(H)
|
||||
else
|
||||
interact(H)
|
||||
|
||||
tgui_interact(H)
|
||||
|
||||
/mob/living/bot/medbot/proc/interact(mob/user)
|
||||
var/dat
|
||||
dat += "<TT><B>Automatic Medical Unit v1.0</B></TT><BR><BR>"
|
||||
dat += "Status: <A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A><BR>"
|
||||
dat += "Maintenance panel is [open ? "opened" : "closed"]<BR>"
|
||||
dat += "Beaker: "
|
||||
if (reagent_glass)
|
||||
dat += "<A href='?src=\ref[src];eject=1'>Loaded \[[reagent_glass.reagents.total_volume]/[reagent_glass.reagents.maximum_volume]\]</a>"
|
||||
else
|
||||
dat += "None Loaded"
|
||||
dat += "<br>Behaviour controls are [locked ? "locked" : "unlocked"]<hr>"
|
||||
/mob/living/bot/medbot/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
data["on"] = on
|
||||
data["open"] = open
|
||||
data["beaker"] = FALSE
|
||||
if(reagent_glass)
|
||||
data["beaker"] = TRUE
|
||||
data["beaker_total"] = reagent_glass.reagents.total_volume
|
||||
data["beaker_max"] = reagent_glass.reagents.maximum_volume
|
||||
data["locked"] = locked
|
||||
data["heal_threshold"] = null
|
||||
data["heal_threshold_max"] = MEDBOT_MAX_HEAL
|
||||
data["injection_amount_min"] = MEDBOT_MIN_INJECTION
|
||||
data["injection_amount"] = null
|
||||
data["injection_amount_max"] = MEDBOT_MAX_INJECTION
|
||||
data["use_beaker"] = null
|
||||
data["declare_treatment"] = null
|
||||
data["vocal"] = null
|
||||
if(!locked || issilicon(user))
|
||||
dat += "<TT>Healing Threshold: "
|
||||
dat += "<a href='?src=\ref[src];adj_threshold=-10'>--</a> "
|
||||
dat += "<a href='?src=\ref[src];adj_threshold=-5'>-</a> "
|
||||
dat += "[heal_threshold] "
|
||||
dat += "<a href='?src=\ref[src];adj_threshold=5'>+</a> "
|
||||
dat += "<a href='?src=\ref[src];adj_threshold=10'>++</a>"
|
||||
dat += "</TT><br>"
|
||||
data["heal_threshold"] = heal_threshold
|
||||
data["injection_amount"] = injection_amount
|
||||
data["use_beaker"] = use_beaker
|
||||
data["declare_treatment"] = declare_treatment
|
||||
data["vocal"] = vocal
|
||||
return data
|
||||
|
||||
dat += "<TT>Injection Level: "
|
||||
dat += "<a href='?src=\ref[src];adj_inject=-5'>-</a> "
|
||||
dat += "[injection_amount] "
|
||||
dat += "<a href='?src=\ref[src];adj_inject=5'>+</a> "
|
||||
dat += "</TT><br>"
|
||||
|
||||
dat += "Reagent Source: "
|
||||
dat += "<a href='?src=\ref[src];use_beaker=1'>[use_beaker ? "Loaded Beaker (When available)" : "Internal Synthesizer"]</a><br>"
|
||||
|
||||
dat += "Treatment report is [declare_treatment ? "on" : "off"]. <a href='?src=\ref[src];declaretreatment=[1]'>Toggle</a><br>"
|
||||
|
||||
dat += "The speaker switch is [vocal ? "on" : "off"]. <a href='?src=\ref[src];togglevoice=[1]'>Toggle</a><br>"
|
||||
|
||||
user << browse("<HEAD><TITLE>Medibot v1.0 controls</TITLE></HEAD>[dat]", "window=automed")
|
||||
onclose(user, "automed")
|
||||
return
|
||||
/mob/living/bot/medbot/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Medbot", name)
|
||||
ui.open()
|
||||
|
||||
/mob/living/bot/medbot/attackby(var/obj/item/O, var/mob/user)
|
||||
if(istype(O, /obj/item/weapon/reagent_containers/glass))
|
||||
@@ -266,51 +265,53 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/bot/medbot/Topic(href, href_list)
|
||||
/mob/living/bot/medbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return
|
||||
return TRUE
|
||||
|
||||
usr.set_machine(src)
|
||||
add_fingerprint(usr)
|
||||
if ((href_list["power"]) && access_scanner.allowed(usr))
|
||||
if (on)
|
||||
turn_off()
|
||||
else
|
||||
turn_on()
|
||||
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("power")
|
||||
if(!access_scanner.allowed(usr))
|
||||
return FALSE
|
||||
if(on)
|
||||
turn_off()
|
||||
else
|
||||
turn_on()
|
||||
|
||||
else if((href_list["adj_threshold"]) && (!locked || issilicon(usr)))
|
||||
var/adjust_num = text2num(href_list["adj_threshold"])
|
||||
heal_threshold += adjust_num
|
||||
if(heal_threshold <= 0)
|
||||
heal_threshold = 0.1
|
||||
if(heal_threshold > 75)
|
||||
heal_threshold = 75
|
||||
if(locked && !issilicon(usr))
|
||||
return TRUE
|
||||
|
||||
else if((href_list["adj_inject"]) && (!locked || issilicon(usr)))
|
||||
var/adjust_num = text2num(href_list["adj_inject"])
|
||||
injection_amount += adjust_num
|
||||
if(injection_amount < 5)
|
||||
injection_amount = 5
|
||||
if(injection_amount > 15)
|
||||
injection_amount = 15
|
||||
switch(action)
|
||||
if("adj_threshold")
|
||||
heal_threshold = clamp(text2num(params["val"]), MEDBOT_MIN_HEAL, MEDBOT_MAX_HEAL)
|
||||
. = TRUE
|
||||
|
||||
else if((href_list["use_beaker"]) && (!locked || issilicon(usr)))
|
||||
use_beaker = !use_beaker
|
||||
if("adj_inject")
|
||||
injection_amount = clamp(text2num(params["val"]), MEDBOT_MIN_INJECTION, MEDBOT_MAX_INJECTION)
|
||||
. = TRUE
|
||||
|
||||
else if (href_list["eject"] && (!isnull(reagent_glass)))
|
||||
if(!locked)
|
||||
reagent_glass.loc = get_turf(src)
|
||||
reagent_glass = null
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>You cannot eject the beaker because the panel is locked.</span>")
|
||||
if("use_beaker")
|
||||
use_beaker = !use_beaker
|
||||
. = TRUE
|
||||
|
||||
else if ((href_list["togglevoice"]) && (!locked || issilicon(usr)))
|
||||
vocal = !vocal
|
||||
if("eject")
|
||||
if(reagent_glass)
|
||||
reagent_glass.forceMove(get_turf(src))
|
||||
reagent_glass = null
|
||||
. = TRUE
|
||||
|
||||
else if ((href_list["declaretreatment"]) && (!locked || issilicon(usr)))
|
||||
declare_treatment = !declare_treatment
|
||||
if("togglevoice")
|
||||
vocal = !vocal
|
||||
. = TRUE
|
||||
|
||||
if("declaretreatment")
|
||||
declare_treatment = !declare_treatment
|
||||
. = TRUE
|
||||
|
||||
attack_hand(usr)
|
||||
return
|
||||
|
||||
/mob/living/bot/medbot/emag_act(var/remaining_uses, var/mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -88,53 +88,78 @@
|
||||
else
|
||||
set_light(0)
|
||||
|
||||
/mob/living/bot/secbot/attack_hand(var/mob/user)
|
||||
user.set_machine(src)
|
||||
var/list/dat = list()
|
||||
dat += "<TT><B>Automatic Security Unit</B></TT><BR><BR>"
|
||||
dat += "Status: <A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A><BR>"
|
||||
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
|
||||
dat += "Maintenance panel is [open ? "opened" : "closed"]"
|
||||
if(!locked || issilicon(user))
|
||||
dat += "<BR>Check for Weapon Authorization: <A href='?src=\ref[src];operation=idcheck'>[idcheck ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Check Security Records: <A href='?src=\ref[src];operation=ignorerec'>[check_records ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Check Arrest Status: <A href='?src=\ref[src];operation=ignorearr'>[check_arrest ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Operating Mode: <A href='?src=\ref[src];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A><BR>"
|
||||
dat += "Report Arrests: <A href='?src=\ref[src];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A><BR>"
|
||||
if(using_map.bot_patrolling)
|
||||
dat += "Auto Patrol: <A href='?src=\ref[src];operation=patrol'>[will_patrol ? "On" : "Off"]</A>"
|
||||
var/datum/browser/popup = new(user, "autosec", "Securitron controls")
|
||||
popup.set_content(jointext(dat,null))
|
||||
popup.open()
|
||||
/mob/living/bot/secbot/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Secbot", name)
|
||||
ui.open()
|
||||
|
||||
/mob/living/bot/secbot/Topic(href, href_list)
|
||||
/mob/living/bot/secbot/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["on"] = on
|
||||
data["open"] = open
|
||||
data["locked"] = locked
|
||||
|
||||
data["idcheck"] = null
|
||||
data["check_records"] = null
|
||||
data["check_arrest"] = null
|
||||
data["arrest_type"] = null
|
||||
data["declare_arrests"] = null
|
||||
data["will_patrol"] = null
|
||||
|
||||
if(!locked || issilicon(user))
|
||||
data["idcheck"] = idcheck
|
||||
data["check_records"] = check_records
|
||||
data["check_arrest"] = check_arrest
|
||||
data["arrest_type"] = arrest_type
|
||||
data["declare_arrests"] = declare_arrests
|
||||
if(using_map.bot_patrolling)
|
||||
data["will_patrol"] = will_patrol
|
||||
|
||||
return data
|
||||
|
||||
/mob/living/bot/secbot/attack_hand(var/mob/user)
|
||||
tgui_interact(user)
|
||||
|
||||
/mob/living/bot/secbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return
|
||||
|
||||
usr.set_machine(src)
|
||||
add_fingerprint(usr)
|
||||
|
||||
if((href_list["power"]) && (access_scanner.allowed(usr)))
|
||||
if(on)
|
||||
turn_off()
|
||||
else
|
||||
turn_on()
|
||||
return
|
||||
switch(action)
|
||||
if("power")
|
||||
if(!access_scanner.allowed(usr))
|
||||
return FALSE
|
||||
if(on)
|
||||
turn_off()
|
||||
else
|
||||
turn_on()
|
||||
. = TRUE
|
||||
|
||||
switch(href_list["operation"])
|
||||
if(locked && !issilicon(usr))
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("idcheck")
|
||||
idcheck = !idcheck
|
||||
. = TRUE
|
||||
if("ignorerec")
|
||||
check_records = !check_records
|
||||
. = TRUE
|
||||
if("ignorearr")
|
||||
check_arrest = !check_arrest
|
||||
. = TRUE
|
||||
if("switchmode")
|
||||
arrest_type = !arrest_type
|
||||
. = TRUE
|
||||
if("patrol")
|
||||
will_patrol = !will_patrol
|
||||
. = TRUE
|
||||
if("declarearrests")
|
||||
declare_arrests = !declare_arrests
|
||||
attack_hand(usr)
|
||||
. = TRUE
|
||||
|
||||
/mob/living/bot/secbot/emag_act(var/remaining_uses, var/mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -430,7 +430,7 @@
|
||||
to_chat(src, "<span class='notice'>[pick(fruit_gland.empty_message)]</span>")
|
||||
return
|
||||
|
||||
var/datum/seed/S = plant_controller.seeds["[fruit_gland.fruit_type]"]
|
||||
var/datum/seed/S = SSplants.seeds["[fruit_gland.fruit_type]"]
|
||||
S.harvest(usr,0,0,1)
|
||||
|
||||
var/index = rand(0,2)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
return 0
|
||||
|
||||
//This is a terrible hack and I should be ashamed.
|
||||
var/datum/seed/diona = plant_controller.seeds["diona"]
|
||||
var/datum/seed/diona = SSplants.seeds["diona"]
|
||||
if(!diona)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -68,12 +68,12 @@
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
var/genemask = input("Choose a gene to modify.") as null|anything in plant_controller.plant_gene_datums
|
||||
var/genemask = input("Choose a gene to modify.") as null|anything in SSplants.plant_gene_datums
|
||||
|
||||
if(!genemask)
|
||||
return
|
||||
|
||||
gene = plant_controller.plant_gene_datums[genemask]
|
||||
gene = SSplants.plant_gene_datums[genemask]
|
||||
|
||||
to_chat(usr, "<span class='info'>You set the [src]'s targeted genetic area to [genemask].</span>")
|
||||
|
||||
|
||||
@@ -338,6 +338,9 @@
|
||||
item_state = "electronic"
|
||||
slot_flags = SLOT_BELT
|
||||
|
||||
/obj/item/device/destTagger/tgui_state(mob/user)
|
||||
return GLOB.tgui_inventory_state
|
||||
|
||||
/obj/item/device/destTagger/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
|
||||
@@ -29,11 +29,16 @@ other types of metals and chemistry for reagents).
|
||||
var/list/chemicals = list() //List of chemicals.
|
||||
var/build_path = null //The path of the object that gets created.
|
||||
var/time = 10 //How many ticks it requires to build
|
||||
var/category = null //Primarily used for Mech Fabricators, but can be used for anything.
|
||||
var/list/category = list() //Primarily used for Mech Fabricators, but can be used for anything.
|
||||
var/sort_string = "ZZZZZ" //Sorting order
|
||||
/// Optional string that interfaces can use as part of search filters. See- item/borg/upgrade/ai and the Exosuit Fabs.
|
||||
var/search_metadata
|
||||
|
||||
/datum/design/New()
|
||||
..()
|
||||
if(!islist(category))
|
||||
log_runtime(EXCEPTION("Warning: Design [type] defined a non-list category. Please fix this."))
|
||||
category = list(category)
|
||||
item_name = name
|
||||
AssembleDesignInfo()
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
build_type = PROTOLATHE | PROSFAB
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 500)
|
||||
build_path = /obj/item/device/mmi
|
||||
category = "Misc"
|
||||
category = list("Misc")
|
||||
sort_string = "SAAAA"
|
||||
|
||||
/datum/design/item/ai_holder/posibrain
|
||||
@@ -20,7 +20,7 @@
|
||||
build_type = PROTOLATHE | PROSFAB
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "silver" = 1000, "gold" = 500, "phoron" = 500, "diamond" = 100)
|
||||
build_path = /obj/item/device/mmi/digital/posibrain
|
||||
category = "Misc"
|
||||
category = list("Misc")
|
||||
sort_string = "SAAAB"
|
||||
|
||||
/datum/design/item/ai_holder/dronebrain
|
||||
@@ -30,7 +30,7 @@
|
||||
build_type = PROTOLATHE | PROSFAB
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "silver" = 1000, "gold" = 500)
|
||||
build_path = /obj/item/device/mmi/digital/robot
|
||||
category = "Misc"
|
||||
category = list("Misc")
|
||||
sort_string = "SAAAC"
|
||||
|
||||
/datum/design/item/ai_holder/paicard
|
||||
|
||||
@@ -655,7 +655,7 @@ CIRCUITS BELOW
|
||||
sort_string = "OAABA"
|
||||
|
||||
/datum/design/circuit/pointdefense_control
|
||||
name = "deluxe microwave"
|
||||
name = "point defense control"
|
||||
id = "pointdefense_control"
|
||||
req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3, TECH_COMBAT = 2)
|
||||
build_path = /obj/item/weapon/circuitboard/pointdefense_control
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
req_tech = list(TECH_POWER = 1)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 50)
|
||||
build_path = /obj/item/weapon/cell
|
||||
category = "Misc"
|
||||
category = list("Misc")
|
||||
sort_string = "BAAAA"
|
||||
|
||||
/datum/design/item/powercell/high
|
||||
@@ -32,7 +32,7 @@
|
||||
req_tech = list(TECH_POWER = 2)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 60)
|
||||
build_path = /obj/item/weapon/cell/high
|
||||
category = "Misc"
|
||||
category = list("Misc")
|
||||
sort_string = "BAAAB"
|
||||
|
||||
/datum/design/item/powercell/super
|
||||
@@ -41,7 +41,7 @@
|
||||
req_tech = list(TECH_POWER = 3, TECH_MATERIAL = 2)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 70)
|
||||
build_path = /obj/item/weapon/cell/super
|
||||
category = "Misc"
|
||||
category = list("Misc")
|
||||
sort_string = "BAAAC"
|
||||
|
||||
/datum/design/item/powercell/hyper
|
||||
@@ -50,7 +50,7 @@
|
||||
req_tech = list(TECH_POWER = 5, TECH_MATERIAL = 4)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 400, "gold" = 150, "silver" = 150, "glass" = 70)
|
||||
build_path = /obj/item/weapon/cell/hyper
|
||||
category = "Misc"
|
||||
category = list("Misc")
|
||||
sort_string = "BAAAD"
|
||||
|
||||
/datum/design/item/powercell/device
|
||||
@@ -59,7 +59,7 @@
|
||||
id = "device"
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 350, "glass" = 25)
|
||||
build_path = /obj/item/weapon/cell/device
|
||||
category = "Misc"
|
||||
category = list("Misc")
|
||||
sort_string = "BAABA"
|
||||
|
||||
/datum/design/item/powercell/weapon
|
||||
@@ -68,5 +68,5 @@
|
||||
id = "weapon"
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 700, "glass" = 50)
|
||||
build_path = /obj/item/weapon/cell/device/weapon
|
||||
category = "Misc"
|
||||
category = list("Misc")
|
||||
sort_string = "BAABB"
|
||||
@@ -1,10 +1,10 @@
|
||||
/datum/design/item/mechfab
|
||||
build_type = MECHFAB
|
||||
category = "Other"
|
||||
category = list("Other")
|
||||
req_tech = list(TECH_MATERIAL = 1)
|
||||
|
||||
/datum/design/item/mechfab/ripley
|
||||
category = "Ripley"
|
||||
category = list("Ripley")
|
||||
|
||||
/datum/design/item/mechfab/ripley/chassis
|
||||
name = "Ripley Chassis"
|
||||
@@ -54,7 +54,7 @@
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 22500)
|
||||
|
||||
/datum/design/item/mechfab/odysseus
|
||||
category = "Odysseus"
|
||||
category = list("Odysseus")
|
||||
|
||||
/datum/design/item/mechfab/odysseus/chassis
|
||||
name = "Odysseus Chassis"
|
||||
@@ -106,7 +106,7 @@
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 11250)
|
||||
|
||||
/datum/design/item/mechfab/gygax
|
||||
category = "Gygax"
|
||||
category = list("Gygax")
|
||||
|
||||
/datum/design/item/mechfab/gygax/chassis/serenity
|
||||
name = "Serenity Chassis"
|
||||
@@ -171,7 +171,7 @@
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 37500, "diamond" = 7500)
|
||||
|
||||
/datum/design/item/mechfab/durand
|
||||
category = "Durand"
|
||||
category = list("Durand")
|
||||
|
||||
/datum/design/item/mechfab/durand/chassis
|
||||
name = "Durand Chassis"
|
||||
@@ -230,7 +230,7 @@
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 27500, MAT_PLASTEEL = 10000, "uranium" = 7500)
|
||||
|
||||
/datum/design/item/mechfab/janus
|
||||
category = "Janus"
|
||||
category = list("Janus")
|
||||
req_tech = list(TECH_MATERIAL = 7, TECH_BLUESPACE = 5, TECH_MAGNET = 6, TECH_PHORON = 3, TECH_ARCANE = 1, TECH_PRECURSOR = 2)
|
||||
|
||||
/datum/design/item/mechfab/janus/chassis
|
||||
@@ -292,7 +292,7 @@
|
||||
|
||||
/datum/design/item/mecha
|
||||
build_type = MECHFAB
|
||||
category = "Exosuit Equipment"
|
||||
category = list("Exosuit Equipment")
|
||||
time = 10
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 7500)
|
||||
|
||||
@@ -758,7 +758,7 @@
|
||||
build_type = MECHFAB
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 562, "glass" = 562)
|
||||
build_path = /obj/item/device/flash/synthetic
|
||||
category = "Misc"
|
||||
category = list("Misc")
|
||||
|
||||
/*
|
||||
* Non-Mech Vehicles
|
||||
@@ -766,7 +766,7 @@
|
||||
|
||||
/datum/design/item/mechfab/vehicle
|
||||
build_type = MECHFAB
|
||||
category = "Vehicle"
|
||||
category = list("Vehicle")
|
||||
req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 6)
|
||||
|
||||
/datum/design/item/mechfab/vehicle/spacebike_chassis
|
||||
@@ -790,7 +790,7 @@
|
||||
*/
|
||||
|
||||
/datum/design/item/mechfab/rigsuit
|
||||
category = "Rigsuit"
|
||||
category = list("Rigsuit")
|
||||
req_tech = list(TECH_MATERIAL = 6, TECH_ENGINEERING = 5, TECH_PHORON = 3, TECH_MAGNET = 4, TECH_POWER = 6)
|
||||
|
||||
/datum/design/item/mechfab/rigsuit/basic_belt
|
||||
@@ -1042,13 +1042,13 @@
|
||||
// Exosuit Internals
|
||||
|
||||
/datum/design/item/mechfab/exointernal
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
time = 30
|
||||
req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3)
|
||||
|
||||
/datum/design/item/mechfab/exointernal/stan_armor
|
||||
name = "Armor Plate (Standard)"
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
id = "exo_int_armor_standard"
|
||||
req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 10000)
|
||||
@@ -1056,7 +1056,7 @@
|
||||
|
||||
/datum/design/item/mechfab/exointernal/light_armor
|
||||
name = "Armor Plate (Lightweight)"
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
id = "exo_int_armor_lightweight"
|
||||
req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 3)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 3000)
|
||||
@@ -1064,7 +1064,7 @@
|
||||
|
||||
/datum/design/item/mechfab/exointernal/reinf_armor
|
||||
name = "Armor Plate (Reinforced)"
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
id = "exo_int_armor_reinforced"
|
||||
req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 20000, MAT_PLASTEEL = 10000)
|
||||
@@ -1072,7 +1072,7 @@
|
||||
|
||||
/datum/design/item/mechfab/exointernal/mining_armor
|
||||
name = "Armor Plate (Blast)"
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
id = "exo_int_armor_blast"
|
||||
req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 20000, MAT_PLASTEEL = 10000)
|
||||
@@ -1080,7 +1080,7 @@
|
||||
|
||||
/datum/design/item/mechfab/exointernal/gygax_armor
|
||||
name = "Armor Plate (Marshal)"
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
id = "exo_int_armor_gygax"
|
||||
req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_COMBAT = 2)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 40000, MAT_DIAMOND = 8000)
|
||||
@@ -1088,7 +1088,7 @@
|
||||
|
||||
/datum/design/item/mechfab/exointernal/darkgygax_armor
|
||||
name = "Armor Plate (Blackops)"
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
id = "exo_int_armor_dgygax"
|
||||
req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_COMBAT = 4, TECH_ILLEGAL = 2)
|
||||
materials = list(MAT_PLASTEEL = 20000, MAT_DIAMOND = 10000, MAT_GRAPHITE = 20000)
|
||||
@@ -1117,7 +1117,7 @@
|
||||
|
||||
/datum/design/item/mechfab/exointernal/stan_hull
|
||||
name = "Hull (Standard)"
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
id = "exo_int_hull_standard"
|
||||
req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 10000)
|
||||
@@ -1125,7 +1125,7 @@
|
||||
|
||||
/datum/design/item/mechfab/exointernal/durable_hull
|
||||
name = "Hull (Durable)"
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
id = "exo_int_hull_durable"
|
||||
req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 8000, MAT_PLASTEEL = 5000)
|
||||
@@ -1133,7 +1133,7 @@
|
||||
|
||||
/datum/design/item/mechfab/exointernal/light_hull
|
||||
name = "Hull (Lightweight)"
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
id = "exo_int_hull_light"
|
||||
req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 4)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 3000)
|
||||
@@ -1141,7 +1141,7 @@
|
||||
|
||||
/datum/design/item/mechfab/exointernal/stan_gas
|
||||
name = "Life-Support (Standard)"
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
id = "exo_int_lifesup_standard"
|
||||
req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 10000)
|
||||
@@ -1149,7 +1149,7 @@
|
||||
|
||||
/datum/design/item/mechfab/exointernal/reinf_gas
|
||||
name = "Life-Support (Reinforced)"
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
id = "exo_int_lifesup_reinforced"
|
||||
req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 8000, MAT_PLASTEEL = 8000, MAT_GRAPHITE = 1000)
|
||||
@@ -1157,7 +1157,7 @@
|
||||
|
||||
/datum/design/item/mechfab/exointernal/stan_electric
|
||||
name = "Electrical Harness (Standard)"
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
id = "exo_int_electric_standard"
|
||||
req_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 1000)
|
||||
@@ -1165,7 +1165,7 @@
|
||||
|
||||
/datum/design/item/mechfab/exointernal/efficient_electric
|
||||
name = "Electrical Harness (High)"
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
id = "exo_int_electric_efficient"
|
||||
req_tech = list(TECH_POWER = 4, TECH_ENGINEERING = 4, TECH_DATA = 2)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 3000, MAT_SILVER = 3000)
|
||||
@@ -1173,7 +1173,7 @@
|
||||
|
||||
/datum/design/item/mechfab/exointernal/stan_actuator
|
||||
name = "Actuator Lattice (Standard)"
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
id = "exo_int_actuator_standard"
|
||||
req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 10000)
|
||||
@@ -1181,7 +1181,7 @@
|
||||
|
||||
/datum/design/item/mechfab/exointernal/hispeed_actuator
|
||||
name = "Actuator Lattice (Overclocked)"
|
||||
category = "Exosuit Internals"
|
||||
category = list("Exosuit Internals")
|
||||
id = "exo_int_actuator_overclock"
|
||||
req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_POWER = 4)
|
||||
materials = list(MAT_PLASTEEL = 10000, MAT_OSMIUM = 3000, MAT_GOLD = 5000)
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
/datum/design/item/prosfab
|
||||
build_type = PROSFAB
|
||||
category = "Misc"
|
||||
category = list("Misc")
|
||||
req_tech = list(TECH_MATERIAL = 1)
|
||||
|
||||
/datum/design/item/prosfab/pros
|
||||
category = "Prosthetics"
|
||||
category = list("Prosthetics")
|
||||
|
||||
// Make new external organs and make 'em robotish
|
||||
/datum/design/item/prosfab/pros/Fabricate(var/newloc, var/fabricator)
|
||||
if(istype(fabricator, /obj/machinery/pros_fabricator))
|
||||
var/obj/machinery/pros_fabricator/prosfab = fabricator
|
||||
if(istype(fabricator, /obj/machinery/mecha_part_fabricator/pros))
|
||||
var/obj/machinery/mecha_part_fabricator/pros/prosfab = fabricator
|
||||
var/obj/item/organ/O = new build_path(newloc)
|
||||
if(prosfab.manufacturer)
|
||||
var/datum/robolimb/manf = all_robolimbs[prosfab.manufacturer]
|
||||
@@ -37,8 +37,8 @@
|
||||
|
||||
// Deep Magic for the torso since it needs to be a new mob
|
||||
/datum/design/item/prosfab/pros/torso/Fabricate(var/newloc, var/fabricator)
|
||||
if(istype(fabricator, /obj/machinery/pros_fabricator))
|
||||
var/obj/machinery/pros_fabricator/prosfab = fabricator
|
||||
if(istype(fabricator, /obj/machinery/mecha_part_fabricator/pros))
|
||||
var/obj/machinery/mecha_part_fabricator/pros/prosfab = fabricator
|
||||
var/newspecies = "Human"
|
||||
|
||||
var/datum/robolimb/manf = all_robolimbs[prosfab.manufacturer]
|
||||
@@ -175,7 +175,7 @@
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 2813)
|
||||
|
||||
/datum/design/item/prosfab/pros/internal
|
||||
category = "Prosthetics, Internal"
|
||||
category = list("Prosthetics, Internal")
|
||||
|
||||
/datum/design/item/prosfab/pros/internal/cell
|
||||
name = "Prosthetic Powercell"
|
||||
@@ -270,7 +270,7 @@
|
||||
|
||||
//////////////////// Cyborg Parts ////////////////////
|
||||
/datum/design/item/prosfab/cyborg
|
||||
category = "Cyborg Parts"
|
||||
category = list("Cyborg Parts")
|
||||
time = 20
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 3750)
|
||||
|
||||
@@ -326,7 +326,7 @@
|
||||
|
||||
//////////////////// Cyborg Internals ////////////////////
|
||||
/datum/design/item/prosfab/cyborg/component
|
||||
category = "Cyborg Internals"
|
||||
category = list("Cyborg Internals")
|
||||
build_type = PROSFAB
|
||||
time = 12
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 7500)
|
||||
@@ -368,7 +368,7 @@
|
||||
|
||||
//////////////////// Cyborg Modules ////////////////////
|
||||
/datum/design/item/prosfab/robot_upgrade
|
||||
category = "Cyborg Modules"
|
||||
category = list("Cyborg Modules")
|
||||
build_type = PROSFAB
|
||||
time = 12
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 7500)
|
||||
|
||||
@@ -42,7 +42,6 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
var/obj/machinery/r_n_d/protolathe/linked_lathe = null //Linked Protolathe
|
||||
var/obj/machinery/r_n_d/circuit_imprinter/linked_imprinter = null //Linked Circuit Imprinter
|
||||
|
||||
var/screen = 1.0 //Which screen is currently showing.
|
||||
var/id = 0 //ID of the computer (for server restrictions).
|
||||
var/sync = 1 //If sync = 0, it doesn't show up on Server Control Console
|
||||
|
||||
@@ -71,17 +70,10 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
return return_name
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/CallReagentName(var/ID)
|
||||
var/return_name = ID
|
||||
var/datum/reagent/temp_reagent
|
||||
for(var/R in (typesof(/datum/reagent) - /datum/reagent))
|
||||
temp_reagent = null
|
||||
temp_reagent = new R()
|
||||
if(temp_reagent.id == ID)
|
||||
return_name = temp_reagent.name
|
||||
qdel(temp_reagent)
|
||||
temp_reagent = null
|
||||
break
|
||||
return return_name
|
||||
var/datum/reagent/R = SSchemistry.chemical_reagents["[ID]"]
|
||||
if(!R)
|
||||
return ID
|
||||
return R.name
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/SyncRDevices() //Makes sure it is properly sync'ed up with the devices attached to it (if any).
|
||||
for(var/obj/machinery/r_n_d/D in range(3, src))
|
||||
@@ -142,7 +134,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
//The construction/deconstruction of the console code.
|
||||
..()
|
||||
|
||||
src.updateUsrDialog()
|
||||
SStgui.update_uis(src)
|
||||
return
|
||||
|
||||
/obj/machinery/computer/rdconsole/emp_act(var/remaining_charges, var/mob/user)
|
||||
@@ -152,296 +144,6 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
to_chat(user, "<span class='notice'>You you disable the security protocols.</span>")
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/rdconsole/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
usr.set_machine(src)
|
||||
if((screen < 1 || (screen == 1.6 && href_list["menu"] != "1.0")) && (!allowed(usr) && !emagged)) //Stops people from HREF exploiting out of the lock screen, but allow it if they have the access.
|
||||
to_chat(usr, "Unauthorized Access")
|
||||
return
|
||||
|
||||
if(href_list["menu"]) //Switches menu screens. Converts a sent text string into a number. Saves a LOT of code.
|
||||
var/temp_screen = text2num(href_list["menu"])
|
||||
if(temp_screen <= 1.1 || (3 <= temp_screen && 4.9 >= temp_screen) || allowed(usr) || emagged) //Unless you are making something, you need access.
|
||||
screen = temp_screen
|
||||
else
|
||||
to_chat(usr, "Unauthorized Access.")
|
||||
|
||||
else if(href_list["updt_tech"]) //Update the research holder with information from the technology disk.
|
||||
screen = 0.0
|
||||
spawn(5 SECONDS)
|
||||
screen = 1.2
|
||||
files.AddTech2Known(t_disk.stored)
|
||||
updateUsrDialog()
|
||||
griefProtection() //Update CentCom too
|
||||
|
||||
else if(href_list["clear_tech"]) //Erase data on the technology disk.
|
||||
t_disk.stored = null
|
||||
|
||||
else if(href_list["eject_tech"]) //Eject the technology disk.
|
||||
t_disk.loc = loc
|
||||
t_disk = null
|
||||
screen = 1.0
|
||||
|
||||
else if(href_list["copy_tech"]) //Copys some technology data from the research holder to the disk.
|
||||
for(var/datum/tech/T in files.known_tech)
|
||||
if(href_list["copy_tech_ID"] == T.id)
|
||||
t_disk.stored = T
|
||||
break
|
||||
screen = 1.2
|
||||
|
||||
else if(href_list["updt_design"]) //Updates the research holder with design data from the design disk.
|
||||
screen = 0.0
|
||||
spawn(5 SECONDS)
|
||||
screen = 1.4
|
||||
files.AddDesign2Known(d_disk.blueprint)
|
||||
updateUsrDialog()
|
||||
griefProtection() //Update CentCom too
|
||||
|
||||
else if(href_list["clear_design"]) //Erases data on the design disk.
|
||||
d_disk.blueprint = null
|
||||
|
||||
else if(href_list["eject_design"]) //Eject the design disk.
|
||||
d_disk.loc = loc
|
||||
d_disk = null
|
||||
screen = 1.0
|
||||
|
||||
else if(href_list["copy_design"]) //Copy design data from the research holder to the design disk.
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(href_list["copy_design_ID"] == D.id)
|
||||
d_disk.blueprint = D
|
||||
break
|
||||
screen = 1.4
|
||||
|
||||
else if(href_list["eject_item"]) //Eject the item inside the destructive analyzer.
|
||||
if(linked_destroy)
|
||||
if(linked_destroy.busy)
|
||||
to_chat(usr, "<span class='notice'>The destructive analyzer is busy at the moment.</span>")
|
||||
|
||||
else if(linked_destroy.loaded_item)
|
||||
linked_destroy.loaded_item.loc = linked_destroy.loc
|
||||
linked_destroy.loaded_item = null
|
||||
linked_destroy.icon_state = "d_analyzer"
|
||||
screen = 2.1
|
||||
|
||||
else if(href_list["deconstruct"]) //Deconstruct the item in the destructive analyzer and update the research holder.
|
||||
if(linked_destroy)
|
||||
if(linked_destroy.busy)
|
||||
to_chat(usr, "<span class='notice'>The destructive analyzer is busy at the moment.</span>")
|
||||
else
|
||||
if(alert("Proceeding will destroy loaded item. Continue?", "Destructive analyzer confirmation", "Yes", "No") == "No" || !linked_destroy)
|
||||
return
|
||||
linked_destroy.busy = 1
|
||||
screen = 0.1
|
||||
updateUsrDialog()
|
||||
flick("d_analyzer_process", linked_destroy)
|
||||
spawn(2.4 SECONDS)
|
||||
if(linked_destroy)
|
||||
linked_destroy.busy = 0
|
||||
if(!linked_destroy.loaded_item)
|
||||
to_chat(usr, "<span class='notice'>The destructive analyzer appears to be empty.</span>")
|
||||
screen = 1.0
|
||||
return
|
||||
|
||||
for(var/T in linked_destroy.loaded_item.origin_tech)
|
||||
files.UpdateTech(T, linked_destroy.loaded_item.origin_tech[T])
|
||||
if(linked_lathe && linked_destroy.loaded_item.matter) // Also sends salvaged materials to a linked protolathe, if any.
|
||||
for(var/t in linked_destroy.loaded_item.matter)
|
||||
if(t in linked_lathe.materials)
|
||||
linked_lathe.materials[t] += min(linked_lathe.max_material_storage - linked_lathe.TotalMaterials(), linked_destroy.loaded_item.matter[t] * linked_destroy.decon_mod)
|
||||
|
||||
linked_destroy.loaded_item = null
|
||||
for(var/obj/I in linked_destroy.contents)
|
||||
for(var/mob/M in I.contents)
|
||||
M.death()
|
||||
if(istype(I,/obj/item/stack/material))//Only deconsturcts one sheet at a time instead of the entire stack
|
||||
var/obj/item/stack/material/S = I
|
||||
if(S.get_amount() > 1)
|
||||
S.use(1)
|
||||
linked_destroy.loaded_item = S
|
||||
else
|
||||
qdel(S)
|
||||
linked_destroy.icon_state = "d_analyzer"
|
||||
else
|
||||
if(I != linked_destroy.circuit && !(I in linked_destroy.component_parts))
|
||||
qdel(I)
|
||||
linked_destroy.icon_state = "d_analyzer"
|
||||
|
||||
use_power(linked_destroy.active_power_usage)
|
||||
screen = 1.0
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["lock"]) //Lock the console from use by anyone without tox access.
|
||||
if(allowed(usr))
|
||||
screen = text2num(href_list["lock"])
|
||||
else
|
||||
to_chat(usr, "Unauthorized Access.")
|
||||
|
||||
else if(href_list["sync"]) //Sync the research holder with all the R&D consoles in the game that aren't sync protected.
|
||||
screen = 0.0
|
||||
if(!sync)
|
||||
to_chat(usr, "<span class='notice'>You must connect to the network first.</span>")
|
||||
else
|
||||
griefProtection() //Putting this here because I dont trust the sync process
|
||||
spawn(3 SECONDS)
|
||||
if(src)
|
||||
for(var/obj/machinery/r_n_d/server/S in machines)
|
||||
var/server_processed = 0
|
||||
if((id in S.id_with_upload) || istype(S, /obj/machinery/r_n_d/server/centcom))
|
||||
for(var/datum/tech/T in files.known_tech)
|
||||
S.files.AddTech2Known(T)
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
S.files.AddDesign2Known(D)
|
||||
S.files.RefreshResearch()
|
||||
server_processed = 1
|
||||
if((id in S.id_with_download) && !istype(S, /obj/machinery/r_n_d/server/centcom))
|
||||
for(var/datum/tech/T in S.files.known_tech)
|
||||
files.AddTech2Known(T)
|
||||
for(var/datum/design/D in S.files.known_designs)
|
||||
files.AddDesign2Known(D)
|
||||
files.RefreshResearch()
|
||||
server_processed = 1
|
||||
if(!istype(S, /obj/machinery/r_n_d/server/centcom) && server_processed)
|
||||
S.produce_heat()
|
||||
screen = 1.6
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["togglesync"]) //Prevents the console from being synced by other consoles. Can still send data.
|
||||
sync = !sync
|
||||
|
||||
else if(href_list["build"]) //Causes the Protolathe to build something.
|
||||
if(linked_lathe)
|
||||
var/datum/design/being_built = null
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(D.id == href_list["build"])
|
||||
being_built = D
|
||||
break
|
||||
if(being_built)
|
||||
linked_lathe.addToQueue(being_built)
|
||||
|
||||
else if(href_list["buildfive"]) //Causes the Protolathe to build 5 of something.
|
||||
if(linked_lathe)
|
||||
var/datum/design/being_built = null
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(D.id == href_list["buildfive"])
|
||||
being_built = D
|
||||
break
|
||||
if(being_built)
|
||||
for(var/i = 1 to 5)
|
||||
linked_lathe.addToQueue(being_built)
|
||||
|
||||
screen = 3.1
|
||||
|
||||
else if(href_list["protofilter"])
|
||||
var/filterstring = input(usr, "Input a filter string, or blank to not filter:", "Design Filter", protofilter) as null|text
|
||||
if(!Adjacent(usr))
|
||||
return
|
||||
if(isnull(filterstring)) //Clicked Cancel
|
||||
return
|
||||
if(filterstring == "") //Cleared value
|
||||
protofilter = null
|
||||
protofilter = sanitize(filterstring, 25)
|
||||
|
||||
else if(href_list["circuitfilter"])
|
||||
var/filterstring = input(usr, "Input a filter string, or blank to not filter:", "Design Filter", circuitfilter) as null|text
|
||||
if(!Adjacent(usr))
|
||||
return
|
||||
if(isnull(filterstring)) //Clicked Cancel
|
||||
return
|
||||
if(filterstring == "") //Cleared value
|
||||
circuitfilter = null
|
||||
circuitfilter = sanitize(filterstring, 25)
|
||||
|
||||
else if(href_list["imprint"]) //Causes the Circuit Imprinter to build something.
|
||||
if(linked_imprinter)
|
||||
var/datum/design/being_built = null
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(D.id == href_list["imprint"])
|
||||
being_built = D
|
||||
break
|
||||
if(being_built)
|
||||
linked_imprinter.addToQueue(being_built)
|
||||
screen = 4.1
|
||||
|
||||
else if(href_list["disposeI"] && linked_imprinter) //Causes the circuit imprinter to dispose of a single reagent (all of it)
|
||||
linked_imprinter.reagents.del_reagent(href_list["dispose"])
|
||||
|
||||
else if(href_list["disposeallI"] && linked_imprinter) //Causes the circuit imprinter to dispose of all it's reagents.
|
||||
linked_imprinter.reagents.clear_reagents()
|
||||
|
||||
else if(href_list["removeI"] && linked_lathe)
|
||||
linked_imprinter.removeFromQueue(text2num(href_list["removeI"]))
|
||||
|
||||
else if(href_list["disposeP"] && linked_lathe) //Causes the protolathe to dispose of a single reagent (all of it)
|
||||
linked_lathe.reagents.del_reagent(href_list["dispose"])
|
||||
|
||||
else if(href_list["disposeallP"] && linked_lathe) //Causes the protolathe to dispose of all it's reagents.
|
||||
linked_lathe.reagents.clear_reagents()
|
||||
|
||||
else if(href_list["removeP"] && linked_lathe)
|
||||
linked_lathe.removeFromQueue(text2num(href_list["removeP"]))
|
||||
|
||||
else if(href_list["lathe_ejectsheet"] && linked_lathe) //Causes the protolathe to eject a sheet of material
|
||||
linked_lathe.eject(href_list["lathe_ejectsheet"], text2num(href_list["amount"]))
|
||||
|
||||
else if(href_list["imprinter_ejectsheet"] && linked_imprinter) //Causes the protolathe to eject a sheet of material
|
||||
linked_imprinter.eject(href_list["imprinter_ejectsheet"], text2num(href_list["amount"]))
|
||||
|
||||
else if(href_list["find_device"]) //The R&D console looks for devices nearby to link up with.
|
||||
screen = 0.0
|
||||
spawn(10)
|
||||
SyncRDevices()
|
||||
screen = 1.7
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["disconnect"]) //The R&D console disconnects with a specific device.
|
||||
switch(href_list["disconnect"])
|
||||
if("destroy")
|
||||
linked_destroy.linked_console = null
|
||||
linked_destroy = null
|
||||
if("lathe")
|
||||
linked_lathe.linked_console = null
|
||||
linked_lathe = null
|
||||
if("imprinter")
|
||||
linked_imprinter.linked_console = null
|
||||
linked_imprinter = null
|
||||
|
||||
else if(href_list["reset"]) //Reset the R&D console's database.
|
||||
griefProtection()
|
||||
var/choice = alert("R&D Console Database Reset", "Are you sure you want to reset the R&D console's database? Data lost cannot be recovered.", "Continue", "Cancel")
|
||||
if(choice == "Continue")
|
||||
screen = 0.0
|
||||
qdel(files)
|
||||
files = new /datum/research(src)
|
||||
spawn(20)
|
||||
screen = 1.6
|
||||
updateUsrDialog()
|
||||
|
||||
else if (href_list["print"]) //Print research information
|
||||
screen = 0.5
|
||||
spawn(20)
|
||||
var/obj/item/weapon/paper/PR = new/obj/item/weapon/paper
|
||||
PR.name = "list of researched technologies"
|
||||
PR.info = "<center><b>[station_name()] Science Laboratories</b>"
|
||||
PR.info += "<h2>[ (text2num(href_list["print"]) == 2) ? "Detailed" : null] Research Progress Report</h2>"
|
||||
PR.info += "<i>report prepared at [stationtime2text()] station time</i></center><br>"
|
||||
if(text2num(href_list["print"]) == 2)
|
||||
PR.info += GetResearchListInfo()
|
||||
else
|
||||
PR.info += GetResearchLevelsInfo()
|
||||
PR.info_links = PR.info
|
||||
PR.icon_state = "paper_words"
|
||||
PR.loc = src.loc
|
||||
spawn(10)
|
||||
screen = ((text2num(href_list["print"]) == 2) ? 5.0 : 1.1)
|
||||
updateUsrDialog()
|
||||
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/GetResearchLevelsInfo()
|
||||
var/list/dat = list()
|
||||
dat += "<UL>"
|
||||
@@ -469,373 +171,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
var/list/dat = list()
|
||||
files.RefreshResearch()
|
||||
switch(screen) //A quick check to make sure you get the right screen when a device is disconnected.
|
||||
if(2 to 2.9)
|
||||
if(linked_destroy == null)
|
||||
screen = 2.0
|
||||
else if(linked_destroy.loaded_item == null)
|
||||
screen = 2.1
|
||||
else
|
||||
screen = 2.2
|
||||
if(3 to 3.9)
|
||||
if(linked_lathe == null)
|
||||
screen = 3.0
|
||||
if(4 to 4.9)
|
||||
if(linked_imprinter == null)
|
||||
screen = 4.0
|
||||
|
||||
switch(screen)
|
||||
|
||||
//////////////////////R&D CONSOLE SCREENS//////////////////
|
||||
if(0.0)
|
||||
dat += "Updating Database..."
|
||||
|
||||
if(0.1)
|
||||
dat += "Processing and Updating Database..."
|
||||
|
||||
if(0.2)
|
||||
dat += "SYSTEM LOCKED<BR><BR>"
|
||||
dat += "<A href='?src=\ref[src];lock=1.6'>Unlock</A>"
|
||||
|
||||
if(0.3)
|
||||
dat += "Constructing Prototype. Please Wait..."
|
||||
|
||||
if(0.4)
|
||||
dat += "Imprinting Circuit. Please Wait..."
|
||||
|
||||
if(0.5)
|
||||
dat += "Printing Research Information. Please Wait..."
|
||||
|
||||
if(1.0) //Main Menu
|
||||
dat += "Main Menu:<BR><BR>"
|
||||
dat += "Loaded disk: "
|
||||
dat += (t_disk || d_disk) ? (t_disk ? "technology storage disk" : "design storage disk") : "none"
|
||||
dat += "<HR><UL>"
|
||||
dat += "<LI><A href='?src=\ref[src];menu=1.1'>Current Research Levels</A>"
|
||||
dat += "<LI><A href='?src=\ref[src];menu=5.0'>View Researched Technologies</A>"
|
||||
if(t_disk)
|
||||
dat += "<LI><A href='?src=\ref[src];menu=1.2'>Disk Operations</A>"
|
||||
else if(d_disk)
|
||||
dat += "<LI><A href='?src=\ref[src];menu=1.4'>Disk Operations</A>"
|
||||
else
|
||||
dat += "<LI><span class='linkOff'>Disk Operations</span>"
|
||||
if(linked_destroy)
|
||||
dat += "<LI><A href='?src=\ref[src];menu=2.2'>Destructive Analyzer Menu</A>"
|
||||
if(linked_lathe)
|
||||
dat += "<LI><A href='?src=\ref[src];menu=3.1'>Protolathe Construction Menu</A>"
|
||||
if(linked_imprinter)
|
||||
dat += "<LI><A href='?src=\ref[src];menu=4.1'>Circuit Construction Menu</A>"
|
||||
dat += "<LI><A href='?src=\ref[src];menu=1.6'>Settings</A>"
|
||||
dat += "</UL>"
|
||||
|
||||
if(1.1) //Research viewer
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];print=1'>Print This Page</A><HR>"
|
||||
dat += "Current Research Levels:<BR><BR>"
|
||||
dat += GetResearchLevelsInfo()
|
||||
dat += "</UL>"
|
||||
|
||||
if(1.2) //Technology Disk Menu
|
||||
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A><HR>"
|
||||
dat += "Disk Contents: (Technology Data Disk)<BR><BR>"
|
||||
if(t_disk.stored == null)
|
||||
dat += "The disk has no data stored on it.<HR>"
|
||||
dat += "Operations: "
|
||||
dat += "<A href='?src=\ref[src];menu=1.3'>Load Tech to Disk</A> || "
|
||||
else
|
||||
dat += "Name: [t_disk.stored.name]<BR>"
|
||||
dat += "Level: [t_disk.stored.level]<BR>"
|
||||
dat += "Description: [t_disk.stored.desc]<HR>"
|
||||
dat += "Operations: "
|
||||
dat += "<A href='?src=\ref[src];updt_tech=1'>Upload to Database</A> || "
|
||||
dat += "<A href='?src=\ref[src];clear_tech=1'>Clear Disk</A> || "
|
||||
dat += "<A href='?src=\ref[src];eject_tech=1'>Eject Disk</A>"
|
||||
|
||||
if(1.3) //Technology Disk submenu
|
||||
dat += "<BR><A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=1.2'>Return to Disk Operations</A><HR>"
|
||||
dat += "Load Technology to Disk:<BR><BR>"
|
||||
dat += "<UL>"
|
||||
for(var/datum/tech/T in files.known_tech)
|
||||
dat += "<LI>[T.name] "
|
||||
dat += "\[<A href='?src=\ref[src];copy_tech=1;copy_tech_ID=[T.id]'>copy to disk</A>\]"
|
||||
dat += "</UL>"
|
||||
|
||||
if(1.4) //Design Disk menu.
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A><HR>"
|
||||
if(d_disk.blueprint == null)
|
||||
dat += "The disk has no data stored on it.<HR>"
|
||||
dat += "Operations: "
|
||||
dat += "<A href='?src=\ref[src];menu=1.5'>Load Design to Disk</A> || "
|
||||
else
|
||||
dat += "Name: [d_disk.blueprint.name]<BR>"
|
||||
switch(d_disk.blueprint.build_type)
|
||||
if(IMPRINTER) dat += "Lathe Type: Circuit Imprinter<BR>"
|
||||
if(PROTOLATHE) dat += "Lathe Type: Proto-lathe<BR>"
|
||||
dat += "Required Materials:<BR>"
|
||||
for(var/M in d_disk.blueprint.materials)
|
||||
if(copytext(M, 1, 2) == "$") dat += "* [copytext(M, 2)] x [d_disk.blueprint.materials[M]]<BR>"
|
||||
else dat += "* [M] x [d_disk.blueprint.materials[M]]<BR>"
|
||||
dat += "<HR>Operations: "
|
||||
dat += "<A href='?src=\ref[src];updt_design=1'>Upload to Database</A> || "
|
||||
dat += "<A href='?src=\ref[src];clear_design=1'>Clear Disk</A> || "
|
||||
dat += "<A href='?src=\ref[src];eject_design=1'>Eject Disk</A>"
|
||||
|
||||
if(1.5) //Technology disk submenu
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=1.4'>Return to Disk Operations</A><HR>"
|
||||
dat += "Load Design to Disk:<BR><BR>"
|
||||
dat += "<UL>"
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(D.build_path)
|
||||
dat += "<LI>[D.name] "
|
||||
dat += "<A href='?src=\ref[src];copy_design=1;copy_design_ID=[D.id]'>\[copy to disk\]</A>"
|
||||
dat += "</UL>"
|
||||
|
||||
if(1.6) //R&D console settings
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A><HR>"
|
||||
dat += "R&D Console Setting:<HR>"
|
||||
dat += "<UL>"
|
||||
if(sync)
|
||||
dat += "<LI><A href='?src=\ref[src];sync=1'>Sync Database with Network</A><BR>"
|
||||
dat += "<LI><A href='?src=\ref[src];togglesync=1'>Disconnect from Research Network</A><BR>"
|
||||
else
|
||||
dat += "<LI><A href='?src=\ref[src];togglesync=1'>Connect to Research Network</A><BR>"
|
||||
dat += "<LI><A href='?src=\ref[src];menu=1.7'>Device Linkage Menu</A><BR>"
|
||||
dat += "<LI><A href='?src=\ref[src];lock=0.2'>Lock Console</A><BR>"
|
||||
dat += "<LI><A href='?src=\ref[src];reset=1'>Reset R&D Database</A><BR>"
|
||||
dat += "<UL>"
|
||||
|
||||
if(1.7) //R&D device linkage
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=1.6'>Settings Menu</A><HR>"
|
||||
dat += "R&D Console Device Linkage Menu:<BR><BR>"
|
||||
dat += "<A href='?src=\ref[src];find_device=1'>Re-sync with Nearby Devices</A><HR>"
|
||||
dat += "Linked Devices:"
|
||||
dat += "<UL>"
|
||||
if(linked_destroy)
|
||||
dat += "<LI>Destructive Analyzer <A href='?src=\ref[src];disconnect=destroy'>(Disconnect)</A>"
|
||||
else
|
||||
dat += "<LI>(No Destructive Analyzer Linked)"
|
||||
if(linked_lathe)
|
||||
dat += "<LI>Protolathe <A href='?src=\ref[src];disconnect=lathe'>(Disconnect)</A>"
|
||||
else
|
||||
dat += "<LI>(No Protolathe Linked)"
|
||||
if(linked_imprinter)
|
||||
dat += "<LI>Circuit Imprinter <A href='?src=\ref[src];disconnect=imprinter'>(Disconnect)</A>"
|
||||
else
|
||||
dat += "<LI>(No Circuit Imprinter Linked)"
|
||||
dat += "</UL>"
|
||||
|
||||
////////////////////DESTRUCTIVE ANALYZER SCREENS////////////////////////////
|
||||
if(2.0)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A><HR>"
|
||||
dat += "NO DESTRUCTIVE ANALYZER LINKED TO CONSOLE<BR><BR>"
|
||||
|
||||
if(2.1)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A><HR>"
|
||||
dat += "No Item Loaded. Standing-by...<BR><HR>"
|
||||
|
||||
if(2.2)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A><HR>"
|
||||
dat += "Deconstruction Menu<HR>"
|
||||
dat += "Name: [linked_destroy.loaded_item.name]<BR>"
|
||||
dat += "Origin Tech:"
|
||||
dat += "<UL>"
|
||||
for(var/T in linked_destroy.loaded_item.origin_tech)
|
||||
dat += "<LI>[CallTechName(T)] [linked_destroy.loaded_item.origin_tech[T]]"
|
||||
for(var/datum/tech/F in files.known_tech)
|
||||
if(F.name == CallTechName(T))
|
||||
dat += " (Current: [F.level])"
|
||||
break
|
||||
dat += "</UL>"
|
||||
dat += "<HR><A href='?src=\ref[src];deconstruct=1'>Deconstruct Item</A> || "
|
||||
dat += "<A href='?src=\ref[src];eject_item=1'>Eject Item</A> || "
|
||||
|
||||
/////////////////////PROTOLATHE SCREENS/////////////////////////
|
||||
if(3.0)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A><HR>"
|
||||
dat += "NO PROTOLATHE LINKED TO CONSOLE<BR><BR>"
|
||||
|
||||
if(3.1)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=3.4'>View Queue</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=3.2'>Material Storage</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=3.3'>Chemical Storage</A><HR>"
|
||||
dat += "Protolathe Menu:<BR><BR>"
|
||||
dat += "<B>Material Amount:</B> [linked_lathe.TotalMaterials()] cm<sup>3</sup> (MAX: [linked_lathe.max_material_storage])<BR>"
|
||||
dat += "<B>Chemical Volume:</B> [linked_lathe.reagents.total_volume] (MAX: [linked_lathe.reagents.maximum_volume])<HR>"
|
||||
dat += "<UL>"
|
||||
dat += "<B>Filter:</B> <A href='?src=\ref[src];protofilter=1'>[protofilter ? protofilter : "None Set"]</A>"
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(!D.build_path || !(D.build_type & PROTOLATHE))
|
||||
continue
|
||||
if(protofilter && findtext(D.name, protofilter) == 0)
|
||||
continue
|
||||
var/temp_dat
|
||||
for(var/M in D.materials)
|
||||
temp_dat += ", [D.materials[M]*linked_lathe.mat_efficiency] [CallMaterialName(M)]"
|
||||
for(var/T in D.chemicals)
|
||||
temp_dat += ", [D.chemicals[T]*linked_lathe.mat_efficiency] [CallReagentName(T)]"
|
||||
if(temp_dat)
|
||||
temp_dat = " \[[copytext(temp_dat, 3)]\]"
|
||||
if(linked_lathe.canBuild(D))
|
||||
dat += "<LI><B><A href='?src=\ref[src];build=[D.id]'>[D.name]</A></B>(<A href='?src=\ref[src];buildfive=[D.id]'>x5</A>)[temp_dat]"
|
||||
else
|
||||
dat += "<LI><B>[D.name]</B>[temp_dat]"
|
||||
dat += "</UL>"
|
||||
|
||||
if(3.2) //Protolathe Material Storage Sub-menu
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=3.1'>Protolathe Menu</A><HR>"
|
||||
dat += "Material Storage<BR><HR>"
|
||||
dat += "<UL>"
|
||||
for(var/M in linked_lathe.materials)
|
||||
var/amount = linked_lathe.materials[M]
|
||||
var/hidden_mat = FALSE
|
||||
for(var/HM in linked_lathe.hidden_materials)
|
||||
if(M == HM && amount == 0)
|
||||
hidden_mat = TRUE
|
||||
break
|
||||
if(hidden_mat)
|
||||
continue
|
||||
dat += "<LI><B>[capitalize(M)]</B>: [amount] cm<sup>3</sup>"
|
||||
if(amount >= SHEET_MATERIAL_AMOUNT)
|
||||
dat += " || Eject "
|
||||
for (var/C in list(1, 3, 5, 10, 15, 20, 25, 30, 40))
|
||||
if(amount < C * SHEET_MATERIAL_AMOUNT)
|
||||
break
|
||||
dat += "[C > 1 ? ", " : ""]<A href='?src=\ref[src];lathe_ejectsheet=[M];amount=[C]'>[C]</A> "
|
||||
|
||||
dat += " or <A href='?src=\ref[src];lathe_ejectsheet=[M];amount=50'>max</A> sheets"
|
||||
dat += ""
|
||||
dat += "</UL>"
|
||||
|
||||
if(3.3) //Protolathe Chemical Storage Submenu
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=3.1'>Protolathe Menu</A><HR>"
|
||||
dat += "Chemical Storage:<BR><HR>"
|
||||
for(var/datum/reagent/R in linked_lathe.reagents.reagent_list)
|
||||
dat += "Name: [R.name] | Units: [R.volume] "
|
||||
dat += "<A href='?src=\ref[src];disposeP=[R.id]'>(Purge)</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];disposeallP=1'><U>Disposal All Chemicals in Storage</U></A><BR>"
|
||||
|
||||
if(3.4) // Protolathe queue
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=3.1'>Protolathe Menu</A><HR>"
|
||||
dat += "Protolathe Construction Queue:<BR><HR>"
|
||||
if(!linked_lathe.queue.len)
|
||||
dat += "Empty"
|
||||
else
|
||||
var/tmp = 1
|
||||
for(var/datum/design/D in linked_lathe.queue)
|
||||
if(tmp == 1)
|
||||
if(linked_lathe.busy)
|
||||
dat += "<B>1: [D.name]</B><BR>"
|
||||
else
|
||||
dat += "<B>1: [D.name]</B> (Awaiting materials) <A href='?src=\ref[src];removeP=[tmp]'>(Remove)</A><BR>"
|
||||
else
|
||||
dat += "[tmp]: [D.name] <A href='?src=\ref[src];removeP=[tmp]'>(Remove)</A><BR>"
|
||||
++tmp
|
||||
|
||||
///////////////////CIRCUIT IMPRINTER SCREENS////////////////////
|
||||
if(4.0)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A><HR>"
|
||||
dat += "NO CIRCUIT IMPRINTER LINKED TO CONSOLE<BR><BR>"
|
||||
|
||||
if(4.1)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=4.4'>View Queue</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=4.3'>Material Storage</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=4.2'>Chemical Storage</A><HR>"
|
||||
dat += "Circuit Imprinter Menu:<BR><BR>"
|
||||
dat += "Material Amount: [linked_imprinter.TotalMaterials()] cm<sup>3</sup><BR>"
|
||||
dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]<HR>"
|
||||
dat += "<UL>"
|
||||
dat += "<B>Filter:</B> <A href='?src=\ref[src];circuitfilter=1'>[circuitfilter ? circuitfilter : "None Set"]</A>"
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(!D.build_path || !(D.build_type & IMPRINTER))
|
||||
continue
|
||||
if(circuitfilter && findtext(D.name, circuitfilter) == 0)
|
||||
continue
|
||||
var/temp_dat
|
||||
for(var/M in D.materials)
|
||||
temp_dat += ", [D.materials[M]*linked_imprinter.mat_efficiency] [CallMaterialName(M)]"
|
||||
for(var/T in D.chemicals)
|
||||
temp_dat += ", [D.chemicals[T]*linked_imprinter.mat_efficiency] [CallReagentName(T)]"
|
||||
if(temp_dat)
|
||||
temp_dat = " \[[copytext(temp_dat,3)]\]"
|
||||
if(linked_imprinter.canBuild(D))
|
||||
dat += "<LI><B><A href='?src=\ref[src];imprint=[D.id]'>[D.name]</A></B>[temp_dat]"
|
||||
else
|
||||
dat += "<LI><B>[D.name]</B>[temp_dat]"
|
||||
dat += "</UL>"
|
||||
|
||||
if(4.2)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=4.1'>Imprinter Menu</A><HR>"
|
||||
dat += "Chemical Storage<BR><HR>"
|
||||
for(var/datum/reagent/R in linked_imprinter.reagents.reagent_list)
|
||||
dat += "Name: [R.name] | Units: [R.volume] "
|
||||
dat += "<A href='?src=\ref[src];disposeI=[R.id]'>(Purge)</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];disposeallI=1'><U>Disposal All Chemicals in Storage</U></A><BR>"
|
||||
|
||||
if(4.3)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=4.1'>Circuit Imprinter Menu</A><HR>"
|
||||
dat += "Material Storage<BR><HR>"
|
||||
dat += "<UL>"
|
||||
for(var/M in linked_imprinter.materials)
|
||||
var/amount = linked_imprinter.materials[M]
|
||||
var/hidden_mat = FALSE
|
||||
for(var/HM in linked_imprinter.hidden_materials)
|
||||
if(M == HM && amount == 0)
|
||||
hidden_mat = TRUE
|
||||
break
|
||||
if(hidden_mat)
|
||||
continue
|
||||
dat += "<LI><B>[capitalize(M)]</B>: [amount] cm<sup>3</sup>"
|
||||
if(amount >= SHEET_MATERIAL_AMOUNT)
|
||||
dat += " || Eject: "
|
||||
for (var/C in list(1, 3, 5, 10, 15, 20, 25, 30, 40))
|
||||
if(amount < C * SHEET_MATERIAL_AMOUNT)
|
||||
break
|
||||
dat += "[C > 1 ? ", " : ""]<A href='?src=\ref[src];imprinter_ejectsheet=[M];amount=[C]'>[C]</A> "
|
||||
|
||||
dat += " or <A href='?src=\ref[src];imprinter_ejectsheet=[M];amount=50'>max</A> sheets"
|
||||
dat += ""
|
||||
dat += "</UL>"
|
||||
|
||||
if(4.4)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];menu=4.1'>Circuit Imprinter Menu</A><HR>"
|
||||
dat += "Queue<BR><HR>"
|
||||
if(linked_imprinter.queue.len == 0)
|
||||
dat += "Empty"
|
||||
else
|
||||
var/tmp = 1
|
||||
for(var/datum/design/D in linked_imprinter.queue)
|
||||
if(tmp == 1)
|
||||
dat += "<B>1: [D.name]</B><BR>"
|
||||
else
|
||||
dat += "[tmp]: [D.name] <A href='?src=\ref[src];removeI=[tmp]'>(Remove)</A><BR>"
|
||||
++tmp
|
||||
|
||||
///////////////////Research Information Browser////////////////////
|
||||
if(5.0)
|
||||
dat += "<A href='?src=\ref[src];menu=1.0'>Main Menu</A> || "
|
||||
dat += "<A href='?src=\ref[src];print=2'>Print This Page</A><HR>"
|
||||
dat += "List of Researched Technologies and Designs:"
|
||||
dat += GetResearchListInfo()
|
||||
|
||||
dat = jointext(dat, null)
|
||||
var/datum/browser/popup = new(user, "rdconsole", "Research and Development Console", 850, 600)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
tgui_interact(user) // TODO: remove the other UI
|
||||
|
||||
/obj/machinery/computer/rdconsole/robotics
|
||||
name = "Robotics R&D Console"
|
||||
|
||||
@@ -0,0 +1,625 @@
|
||||
/*
|
||||
* This file contains all of the UI code for the RD console.
|
||||
* It's moved off to this file for simplicity and understanding what is UI and what is functionality.
|
||||
*/
|
||||
|
||||
#define ENTRIES_PER_RDPAGE 50
|
||||
|
||||
/obj/machinery/computer/rdconsole
|
||||
var/locked = FALSE
|
||||
var/busy_msg = null
|
||||
|
||||
var/search = ""
|
||||
var/design_page = 0
|
||||
var/builder_page = 0
|
||||
|
||||
/obj/machinery/computer/rdconsole/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "ResearchConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/rdconsole/tgui_status(mob/user)
|
||||
. = ..()
|
||||
if(locked && !allowed(user) && !emagged)
|
||||
. = min(., STATUS_UPDATE)
|
||||
|
||||
/obj/machinery/computer/rdconsole/tgui_static_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
data["tech"] = tgui_GetResearchLevelsInfo()
|
||||
data["designs"] = tgui_GetDesignInfo(design_page)
|
||||
|
||||
data["lathe_designs"] = tgui_GetProtolatheDesigns(linked_lathe, builder_page)
|
||||
data["imprinter_designs"] = tgui_GetImprinterDesigns(linked_imprinter, builder_page)
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/rdconsole/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["locked"] = locked
|
||||
data["busy_msg"] = busy_msg
|
||||
data["search"] = search
|
||||
|
||||
data["info"] = null
|
||||
if(!locked && !busy_msg)
|
||||
data["info"] = list(
|
||||
"sync" = sync,
|
||||
)
|
||||
|
||||
data["info"]["linked_destroy"] = list("present" = FALSE)
|
||||
if(linked_destroy)
|
||||
data["info"]["linked_destroy"] = list(
|
||||
"present" = TRUE,
|
||||
"loaded_item" = linked_destroy.loaded_item,
|
||||
"origin_tech" = tgui_GetOriginTechForItem(linked_destroy.loaded_item),
|
||||
)
|
||||
|
||||
data["info"]["linked_lathe"] = list("present" = FALSE)
|
||||
if(linked_lathe)
|
||||
data["info"]["linked_lathe"] = list(
|
||||
"present" = TRUE,
|
||||
"total_materials" = linked_lathe.TotalMaterials(),
|
||||
"max_materials" = linked_lathe.max_material_storage,
|
||||
"total_volume" = linked_lathe.reagents.total_volume,
|
||||
"max_volume" = linked_lathe.reagents.maximum_volume,
|
||||
"busy" = linked_lathe.busy,
|
||||
)
|
||||
|
||||
var/list/materials = list()
|
||||
for(var/M in linked_lathe.materials)
|
||||
var/amount = linked_lathe.materials[M]
|
||||
var/hidden_mat = FALSE
|
||||
for(var/HM in linked_lathe.hidden_materials)
|
||||
if(M == HM && amount == 0)
|
||||
hidden_mat = TRUE
|
||||
break
|
||||
if(hidden_mat)
|
||||
continue
|
||||
materials.Add(list(list(
|
||||
"name" = M,
|
||||
"amount" = amount,
|
||||
"sheets" = round(amount / SHEET_MATERIAL_AMOUNT),
|
||||
"removable" = amount >= SHEET_MATERIAL_AMOUNT,
|
||||
)))
|
||||
data["info"]["linked_lathe"]["mats"] = materials
|
||||
|
||||
var/list/reagents = list()
|
||||
for(var/datum/reagent/R in linked_lathe.reagents.reagent_list)
|
||||
reagents.Add(list(list(
|
||||
"name" = R.name,
|
||||
"id" = R.id,
|
||||
"volume" = R.volume,
|
||||
)))
|
||||
data["info"]["linked_lathe"]["reagents"] = reagents
|
||||
|
||||
var/list/queue = list()
|
||||
var/i = 1
|
||||
for(var/datum/design/D in linked_lathe.queue)
|
||||
queue.Add(list(list(
|
||||
"name" = D.name,
|
||||
"index" = i, // ugghhhh
|
||||
)))
|
||||
i++
|
||||
data["info"]["linked_lathe"]["queue"] = queue
|
||||
|
||||
data["info"]["linked_imprinter"] = list("present" = FALSE)
|
||||
if(linked_imprinter)
|
||||
data["info"]["linked_imprinter"] = list(
|
||||
"present" = TRUE,
|
||||
"total_materials" = linked_imprinter.TotalMaterials(),
|
||||
"max_materials" = linked_imprinter.max_material_storage,
|
||||
"total_volume" = linked_imprinter.reagents.total_volume,
|
||||
"max_volume" = linked_imprinter.reagents.maximum_volume,
|
||||
"busy" = linked_imprinter.busy,
|
||||
)
|
||||
|
||||
var/list/materials = list()
|
||||
for(var/M in linked_imprinter.materials)
|
||||
var/amount = linked_imprinter.materials[M]
|
||||
var/hidden_mat = FALSE
|
||||
for(var/HM in linked_imprinter.hidden_materials)
|
||||
if(M == HM && amount == 0)
|
||||
hidden_mat = TRUE
|
||||
break
|
||||
if(hidden_mat)
|
||||
continue
|
||||
materials.Add(list(list(
|
||||
"name" = M,
|
||||
"amount" = amount,
|
||||
"sheets" = round(amount / SHEET_MATERIAL_AMOUNT),
|
||||
"removable" = amount >= SHEET_MATERIAL_AMOUNT,
|
||||
)))
|
||||
data["info"]["linked_imprinter"]["mats"] = materials
|
||||
|
||||
var/list/reagents = list()
|
||||
for(var/datum/reagent/R in linked_imprinter.reagents.reagent_list)
|
||||
reagents.Add(list(list(
|
||||
"name" = R.name,
|
||||
"id" = R.id,
|
||||
"volume" = R.volume,
|
||||
)))
|
||||
data["info"]["linked_imprinter"]["reagents"] = reagents
|
||||
|
||||
var/list/queue = list()
|
||||
var/i = 1
|
||||
for(var/datum/design/D in linked_imprinter.queue)
|
||||
queue.Add(list(list(
|
||||
"name" = D.name,
|
||||
"index" = i, // ugghhhh
|
||||
)))
|
||||
i++
|
||||
data["info"]["linked_imprinter"]["queue"] = queue
|
||||
|
||||
data["info"]["t_disk"] = list("present" = FALSE)
|
||||
if(t_disk)
|
||||
data["info"]["t_disk"] = list(
|
||||
"present" = TRUE,
|
||||
"stored" = !!t_disk.stored,
|
||||
)
|
||||
if(t_disk.stored)
|
||||
data["info"]["t_disk"]["name"] = t_disk.stored.name
|
||||
data["info"]["t_disk"]["level"] = t_disk.stored.level
|
||||
data["info"]["t_disk"]["desc"] = t_disk.stored.desc
|
||||
|
||||
data["info"]["d_disk"] = list("present" = FALSE)
|
||||
if(d_disk)
|
||||
data["info"]["d_disk"] = list(
|
||||
"present" = TRUE,
|
||||
"stored" = !!d_disk.blueprint,
|
||||
)
|
||||
if(d_disk.blueprint)
|
||||
data["info"]["d_disk"]["name"] = d_disk.blueprint.name
|
||||
data["info"]["d_disk"]["build_type"] = d_disk.blueprint.build_type
|
||||
data["info"]["d_disk"]["materials"] = d_disk.blueprint.materials
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/tgui_GetResearchLevelsInfo()
|
||||
var/list/data = list()
|
||||
for(var/datum/tech/T in files.known_tech)
|
||||
if(T.level < 1)
|
||||
continue
|
||||
data.Add(list(list(
|
||||
"name" = T.name,
|
||||
"level" = T.level,
|
||||
"desc" = T.desc,
|
||||
"id" = T.id,
|
||||
)))
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/tgui_GetOriginTechForItem(obj/item/I)
|
||||
if(!istype(I))
|
||||
return list()
|
||||
|
||||
var/list/data = list()
|
||||
for(var/T in I.origin_tech)
|
||||
var/list/subdata = list(
|
||||
"name" = CallTechName(T),
|
||||
"level" = I.origin_tech[T],
|
||||
"current" = null,
|
||||
)
|
||||
for(var/datum/tech/F in files.known_tech)
|
||||
if(F.name == CallTechName(T))
|
||||
subdata["current"] = F.level
|
||||
break
|
||||
data.Add(list(subdata))
|
||||
|
||||
return data
|
||||
|
||||
/proc/cmp_designs_rdconsole(list/A, list/B)
|
||||
return sorttext(B["name"], A["name"])
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/tgui_GetProtolatheDesigns(obj/machinery/r_n_d/protolathe/P, page)
|
||||
if(!istype(P))
|
||||
return list()
|
||||
|
||||
var/list/data = list()
|
||||
// For some reason, this is faster than direct access.
|
||||
var/list/known_designs = files.known_designs
|
||||
for(var/datum/design/D in known_designs)
|
||||
if(!D.build_path || !(D.build_type & PROTOLATHE))
|
||||
continue
|
||||
if(search && !findtext(D.name, search))
|
||||
continue
|
||||
|
||||
var/list/mat_list = list()
|
||||
for(var/M in D.materials)
|
||||
mat_list.Add("[D.materials[M] * P.mat_efficiency] [CallMaterialName(M)]")
|
||||
|
||||
var/list/chem_list = list()
|
||||
for(var/T in D.chemicals)
|
||||
chem_list.Add("[D.chemicals[T] * P.mat_efficiency] [CallReagentName(T)]")
|
||||
|
||||
data.Add(list(list(
|
||||
"name" = D.name,
|
||||
"id" = D.id,
|
||||
"mat_list" = mat_list,
|
||||
"chem_list" = chem_list,
|
||||
)))
|
||||
|
||||
data = sortTim(data, /proc/cmp_designs_rdconsole, FALSE)
|
||||
if(LAZYLEN(data) > ENTRIES_PER_RDPAGE)
|
||||
var/first_index = clamp(ENTRIES_PER_RDPAGE * page, 1, LAZYLEN(data))
|
||||
var/last_index = min((ENTRIES_PER_RDPAGE * page) + ENTRIES_PER_RDPAGE, LAZYLEN(data) + 1)
|
||||
|
||||
data = data.Copy(first_index, last_index)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/tgui_GetImprinterDesigns(obj/machinery/r_n_d/circuit_imprinter/P, page)
|
||||
if(!istype(P))
|
||||
return list()
|
||||
|
||||
var/list/data = list()
|
||||
// For some reason, this is faster than direct access.
|
||||
var/list/known_designs = files.known_designs
|
||||
for(var/datum/design/D in known_designs)
|
||||
if(!D.build_path || !(D.build_type & IMPRINTER))
|
||||
continue
|
||||
if(search && !findtext(D.name, search))
|
||||
continue
|
||||
|
||||
var/list/mat_list = list()
|
||||
for(var/M in D.materials)
|
||||
mat_list.Add("[D.materials[M] * P.mat_efficiency] [CallMaterialName(M)]")
|
||||
|
||||
var/list/chem_list = list()
|
||||
for(var/T in D.chemicals)
|
||||
chem_list.Add("[D.chemicals[T] * P.mat_efficiency] [CallReagentName(T)]")
|
||||
|
||||
data.Add(list(list(
|
||||
"name" = D.name,
|
||||
"id" = D.id,
|
||||
"mat_list" = mat_list,
|
||||
"chem_list" = chem_list,
|
||||
)))
|
||||
|
||||
data = sortTim(data, /proc/cmp_designs_rdconsole, FALSE)
|
||||
if(LAZYLEN(data) > ENTRIES_PER_RDPAGE)
|
||||
var/first_index = clamp(ENTRIES_PER_RDPAGE * page, 1, LAZYLEN(data))
|
||||
var/last_index = min((ENTRIES_PER_RDPAGE * page) + ENTRIES_PER_RDPAGE, LAZYLEN(data) + 1)
|
||||
|
||||
data = data.Copy(first_index, last_index)
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/tgui_GetDesignInfo(page)
|
||||
var/list/data = list()
|
||||
// For some reason, this is faster than direct access.
|
||||
var/list/known_designs = files.known_designs
|
||||
for(var/datum/design/D in known_designs)
|
||||
if(search && !findtext(D.name, search))
|
||||
continue
|
||||
if(D.build_path)
|
||||
data.Add(list(list(
|
||||
"name" = D.name,
|
||||
"desc" = D.desc,
|
||||
"id" = D.id,
|
||||
)))
|
||||
|
||||
data = sortTim(data, /proc/cmp_designs_rdconsole, FALSE)
|
||||
if(LAZYLEN(data) > ENTRIES_PER_RDPAGE)
|
||||
var/first_index = clamp(ENTRIES_PER_RDPAGE * page, 1, LAZYLEN(data))
|
||||
var/last_index = clamp((ENTRIES_PER_RDPAGE * page) + ENTRIES_PER_RDPAGE, 1, LAZYLEN(data) + 1)
|
||||
|
||||
data = data.Copy(first_index, last_index)
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/rdconsole/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
usr.set_machine(src)
|
||||
|
||||
switch(action)
|
||||
if("search")
|
||||
search = params["search"]
|
||||
update_tgui_static_data(usr, ui)
|
||||
return TRUE
|
||||
if("design_page")
|
||||
if(params["reset"])
|
||||
design_page = 0
|
||||
else
|
||||
design_page = max(design_page + (1 * params["reverse"]), 0)
|
||||
update_tgui_static_data(usr, ui)
|
||||
return TRUE
|
||||
if("builder_page")
|
||||
if(params["reset"])
|
||||
builder_page = 0
|
||||
else
|
||||
builder_page = max(builder_page + (1 * params["reverse"]), 0)
|
||||
update_tgui_static_data(usr, ui)
|
||||
return TRUE
|
||||
|
||||
if("updt_tech") //Update the research holder with information from the technology disk.
|
||||
busy_msg = "Updating Database..."
|
||||
spawn(5 SECONDS)
|
||||
busy_msg = null
|
||||
files.AddTech2Known(t_disk.stored)
|
||||
files.RefreshResearch()
|
||||
griefProtection() //Update CentCom too
|
||||
update_tgui_static_data(usr, ui)
|
||||
return TRUE
|
||||
|
||||
if("clear_tech") //Erase data on the technology disk.
|
||||
t_disk.stored = null
|
||||
return TRUE
|
||||
|
||||
if("eject_tech") //Eject the technology disk.
|
||||
t_disk.loc = loc
|
||||
t_disk = null
|
||||
return TRUE
|
||||
|
||||
if("copy_tech") //Copys some technology data from the research holder to the disk.
|
||||
for(var/datum/tech/T in files.known_tech)
|
||||
if(params["copy_tech_ID"] == T.id)
|
||||
t_disk.stored = T
|
||||
break
|
||||
return TRUE
|
||||
|
||||
if("updt_design") //Updates the research holder with design data from the design disk.
|
||||
busy_msg = "Updating Database..."
|
||||
spawn(5 SECONDS)
|
||||
busy_msg = null
|
||||
files.AddDesign2Known(d_disk.blueprint)
|
||||
griefProtection() //Update CentCom too
|
||||
update_tgui_static_data(usr, ui)
|
||||
return TRUE
|
||||
|
||||
if("clear_design") //Erases data on the design disk.
|
||||
d_disk.blueprint = null
|
||||
return TRUE
|
||||
|
||||
if("eject_design") //Eject the design disk.
|
||||
d_disk.loc = loc
|
||||
d_disk = null
|
||||
return TRUE
|
||||
|
||||
if("copy_design") //Copy design data from the research holder to the design disk.
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(params["copy_design_ID"] == D.id)
|
||||
d_disk.blueprint = D
|
||||
break
|
||||
return TRUE
|
||||
|
||||
if("eject_item") //Eject the item inside the destructive analyzer.
|
||||
if(linked_destroy)
|
||||
if(linked_destroy.busy)
|
||||
to_chat(usr, "<span class='notice'>The destructive analyzer is busy at the moment.</span>")
|
||||
return FALSE
|
||||
|
||||
if(linked_destroy.loaded_item)
|
||||
linked_destroy.loaded_item.loc = linked_destroy.loc
|
||||
linked_destroy.loaded_item = null
|
||||
linked_destroy.icon_state = "d_analyzer"
|
||||
return TRUE
|
||||
|
||||
if("deconstruct") //Deconstruct the item in the destructive analyzer and update the research holder.
|
||||
if(!linked_destroy)
|
||||
return FALSE
|
||||
|
||||
if(linked_destroy.busy)
|
||||
to_chat(usr, "<span class='notice'>The destructive analyzer is busy at the moment.</span>")
|
||||
return
|
||||
|
||||
if(alert("Proceeding will destroy loaded item. Continue?", "Destructive analyzer confirmation", "Yes", "No") == "No" || !linked_destroy)
|
||||
return
|
||||
linked_destroy.busy = 1
|
||||
busy_msg = "Processing and Updating Database..."
|
||||
flick("d_analyzer_process", linked_destroy)
|
||||
spawn(2.4 SECONDS)
|
||||
if(linked_destroy)
|
||||
linked_destroy.busy = 0
|
||||
busy_msg = null
|
||||
if(!linked_destroy.loaded_item)
|
||||
to_chat(usr, "<span class='notice'>The destructive analyzer appears to be empty.</span>")
|
||||
return
|
||||
|
||||
for(var/T in linked_destroy.loaded_item.origin_tech)
|
||||
files.UpdateTech(T, linked_destroy.loaded_item.origin_tech[T])
|
||||
if(linked_lathe && linked_destroy.loaded_item.matter) // Also sends salvaged materials to a linked protolathe, if any.
|
||||
for(var/t in linked_destroy.loaded_item.matter)
|
||||
if(t in linked_lathe.materials)
|
||||
linked_lathe.materials[t] += min(linked_lathe.max_material_storage - linked_lathe.TotalMaterials(), linked_destroy.loaded_item.matter[t] * linked_destroy.decon_mod)
|
||||
|
||||
|
||||
linked_destroy.loaded_item = null
|
||||
for(var/obj/I in linked_destroy.contents)
|
||||
for(var/mob/M in I.contents)
|
||||
M.death()
|
||||
if(istype(I,/obj/item/stack/material))//Only deconsturcts one sheet at a time instead of the entire stack
|
||||
var/obj/item/stack/material/S = I
|
||||
if(S.get_amount() > 1)
|
||||
S.use(1)
|
||||
linked_destroy.loaded_item = S
|
||||
else
|
||||
qdel(S)
|
||||
linked_destroy.icon_state = "d_analyzer"
|
||||
else
|
||||
if(I != linked_destroy.circuit && !(I in linked_destroy.component_parts))
|
||||
qdel(I)
|
||||
linked_destroy.icon_state = "d_analyzer"
|
||||
|
||||
use_power(linked_destroy.active_power_usage)
|
||||
files.RefreshResearch()
|
||||
update_tgui_static_data(usr, ui)
|
||||
return TRUE
|
||||
|
||||
if("lock") //Lock the console from use by anyone without tox access.
|
||||
if(!allowed(usr))
|
||||
to_chat(usr, "Unauthorized Access.")
|
||||
return
|
||||
locked = !locked
|
||||
return TRUE
|
||||
|
||||
if("sync") //Sync the research holder with all the R&D consoles in the game that aren't sync protected.
|
||||
if(!sync)
|
||||
to_chat(usr, "<span class='notice'>You must connect to the network first.</span>")
|
||||
return
|
||||
|
||||
busy_msg = "Updating Database..."
|
||||
griefProtection() //Putting this here because I dont trust the sync process
|
||||
spawn(3 SECONDS)
|
||||
if(src)
|
||||
for(var/obj/machinery/r_n_d/server/S in machines)
|
||||
var/server_processed = 0
|
||||
if((id in S.id_with_upload) || istype(S, /obj/machinery/r_n_d/server/centcom))
|
||||
for(var/datum/tech/T in files.known_tech)
|
||||
S.files.AddTech2Known(T)
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
S.files.AddDesign2Known(D)
|
||||
S.files.RefreshResearch()
|
||||
server_processed = 1
|
||||
if((id in S.id_with_download) && !istype(S, /obj/machinery/r_n_d/server/centcom))
|
||||
for(var/datum/tech/T in S.files.known_tech)
|
||||
files.AddTech2Known(T)
|
||||
for(var/datum/design/D in S.files.known_designs)
|
||||
files.AddDesign2Known(D)
|
||||
server_processed = 1
|
||||
if(!istype(S, /obj/machinery/r_n_d/server/centcom) && server_processed)
|
||||
S.produce_heat()
|
||||
busy_msg = null
|
||||
files.RefreshResearch()
|
||||
update_tgui_static_data(usr, ui)
|
||||
return TRUE
|
||||
|
||||
if("togglesync") //Prevents the console from being synced by other consoles. Can still send data.
|
||||
sync = !sync
|
||||
return TRUE
|
||||
|
||||
if("build") //Causes the Protolathe to build something.
|
||||
if(linked_lathe)
|
||||
var/datum/design/being_built = null
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(D.id == params["build"])
|
||||
being_built = D
|
||||
break
|
||||
if(being_built)
|
||||
linked_lathe.addToQueue(being_built)
|
||||
return TRUE
|
||||
|
||||
if("buildfive") //Causes the Protolathe to build 5 of something.
|
||||
if(linked_lathe)
|
||||
var/datum/design/being_built = null
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(D.id == params["build"])
|
||||
being_built = D
|
||||
break
|
||||
if(being_built)
|
||||
for(var/i = 1 to 5)
|
||||
linked_lathe.addToQueue(being_built)
|
||||
return TRUE
|
||||
|
||||
if("imprint") //Causes the Circuit Imprinter to build something.
|
||||
if(linked_imprinter)
|
||||
var/datum/design/being_built = null
|
||||
for(var/datum/design/D in files.known_designs)
|
||||
if(D.id == params["imprint"])
|
||||
being_built = D
|
||||
break
|
||||
if(being_built)
|
||||
linked_imprinter.addToQueue(being_built)
|
||||
return TRUE
|
||||
|
||||
if("disposeI") //Causes the circuit imprinter to dispose of a single reagent (all of it)
|
||||
if(!linked_imprinter)
|
||||
return
|
||||
linked_imprinter.reagents.del_reagent(params["dispose"])
|
||||
return TRUE
|
||||
|
||||
if("disposeallI") //Causes the circuit imprinter to dispose of all it's reagents.
|
||||
if(!linked_imprinter)
|
||||
return
|
||||
linked_imprinter.reagents.clear_reagents()
|
||||
return TRUE
|
||||
|
||||
if("removeI")
|
||||
if(!linked_imprinter)
|
||||
return
|
||||
linked_imprinter.removeFromQueue(text2num(params["removeI"]))
|
||||
return TRUE
|
||||
|
||||
if("imprinter_ejectsheet") //Causes the imprinter to eject a sheet of material
|
||||
if(!linked_imprinter)
|
||||
return
|
||||
linked_imprinter.eject(params["imprinter_ejectsheet"], text2num(params["amount"]))
|
||||
return TRUE
|
||||
|
||||
if("disposeP") //Causes the protolathe to dispose of a single reagent (all of it)
|
||||
if(!linked_lathe)
|
||||
return
|
||||
linked_lathe.reagents.del_reagent(params["dispose"])
|
||||
return TRUE
|
||||
|
||||
if("disposeallP") //Causes the protolathe to dispose of all it's reagents.
|
||||
if(!linked_lathe)
|
||||
return
|
||||
linked_lathe.reagents.clear_reagents()
|
||||
return TRUE
|
||||
|
||||
if("removeP")
|
||||
if(!linked_lathe)
|
||||
return
|
||||
linked_lathe.removeFromQueue(text2num(params["removeP"]))
|
||||
return TRUE
|
||||
|
||||
if("lathe_ejectsheet") //Causes the protolathe to eject a sheet of material
|
||||
if(!linked_lathe)
|
||||
return
|
||||
linked_lathe.eject(params["lathe_ejectsheet"], text2num(params["amount"]))
|
||||
return TRUE
|
||||
|
||||
if("find_device") //The R&D console looks for devices nearby to link up with.
|
||||
busy_msg = "Updating Database..."
|
||||
|
||||
spawn(10)
|
||||
busy_msg = null
|
||||
SyncRDevices()
|
||||
update_tgui_static_data(usr, ui)
|
||||
return TRUE
|
||||
|
||||
if("disconnect") //The R&D console disconnects with a specific device.
|
||||
switch(params["disconnect"])
|
||||
if("destroy")
|
||||
linked_destroy.linked_console = null
|
||||
linked_destroy = null
|
||||
if("lathe")
|
||||
linked_lathe.linked_console = null
|
||||
linked_lathe = null
|
||||
if("imprinter")
|
||||
linked_imprinter.linked_console = null
|
||||
linked_imprinter = null
|
||||
update_tgui_static_data(usr, ui)
|
||||
|
||||
if("reset") //Reset the R&D console's database.
|
||||
griefProtection()
|
||||
var/choice = alert("R&D Console Database Reset", "Are you sure you want to reset the R&D console's database? Data lost cannot be recovered.", "Continue", "Cancel")
|
||||
if(choice == "Continue")
|
||||
busy_msg = "Updating Database..."
|
||||
qdel(files)
|
||||
files = new /datum/research(src)
|
||||
spawn(20)
|
||||
busy_msg = null
|
||||
update_tgui_static_data(usr, ui)
|
||||
|
||||
if("print") //Print research information
|
||||
busy_msg = "Printing Research Information. Please Wait..."
|
||||
spawn(20)
|
||||
var/obj/item/weapon/paper/PR = new/obj/item/weapon/paper
|
||||
PR.name = "list of researched technologies"
|
||||
PR.info = "<center><b>[station_name()] Science Laboratories</b>"
|
||||
PR.info += "<h2>[ (text2num(params["print"]) == 2) ? "Detailed" : null] Research Progress Report</h2>"
|
||||
PR.info += "<i>report prepared at [stationtime2text()] station time</i></center><br>"
|
||||
if(text2num(params["print"]) == 2)
|
||||
PR.info += GetResearchListInfo()
|
||||
else
|
||||
PR.info += GetResearchLevelsInfo()
|
||||
PR.info_links = PR.info
|
||||
PR.icon_state = "paper_words"
|
||||
PR.forceMove(loc)
|
||||
busy_msg = null
|
||||
@@ -67,11 +67,10 @@ research holder datum.
|
||||
//Checks to see if design has all the required pre-reqs.
|
||||
//Input: datum/design; Output: 0/1 (false/true)
|
||||
/datum/research/proc/DesignHasReqs(var/datum/design/D)
|
||||
if(D.req_tech.len == 0)
|
||||
return 1
|
||||
if(!LAZYLEN(D.req_tech))
|
||||
return TRUE
|
||||
|
||||
var/list/k_tech = list()
|
||||
|
||||
for(var/datum/tech/known in known_tech)
|
||||
k_tech[known.id] = known.level
|
||||
|
||||
@@ -79,7 +78,7 @@ research holder datum.
|
||||
if(isnull(k_tech[req]) || k_tech[req] < D.req_tech[req])
|
||||
return 0
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//Adds a tech to known_tech list. Checks to make sure there aren't duplicates and updates existing tech's levels if needed.
|
||||
//Input: datum/tech; Output: Null
|
||||
@@ -92,18 +91,7 @@ research holder datum.
|
||||
return
|
||||
|
||||
/datum/research/proc/AddDesign2Known(var/datum/design/D)
|
||||
if(!known_designs.len) // Special case
|
||||
known_designs.Add(D)
|
||||
return
|
||||
for(var/i = 1 to known_designs.len)
|
||||
var/datum/design/A = known_designs[i]
|
||||
if(A.id == D.id) // We are guaranteed to reach this if the ids are the same, because sort_string will also be the same
|
||||
return
|
||||
if(A.sort_string > D.sort_string)
|
||||
known_designs.Insert(i, D)
|
||||
return
|
||||
known_designs.Add(D)
|
||||
return
|
||||
LAZYDISTINCTADD(known_designs, D)
|
||||
|
||||
//Refreshes known_tech and known_designs list
|
||||
//Input/Output: n/a
|
||||
@@ -112,7 +100,7 @@ research holder datum.
|
||||
if(DesignHasReqs(PD))
|
||||
AddDesign2Known(PD)
|
||||
for(var/datum/tech/T in known_tech)
|
||||
T = between(0, T.level, 20)
|
||||
T.level = between(0, T.level, 20)
|
||||
return
|
||||
|
||||
//Refreshes the levels of a given tech.
|
||||
|
||||
+121
-120
@@ -157,143 +157,144 @@
|
||||
var/list/consoles = list()
|
||||
var/badmin = 0
|
||||
|
||||
/obj/machinery/computer/rdservercontrol/Topic(href, href_list)
|
||||
/obj/machinery/computer/rdservercontrol/tgui_status(mob/user)
|
||||
. = ..()
|
||||
if(!allowed(user) && !emagged)
|
||||
. = min(., STATUS_UPDATE)
|
||||
|
||||
/obj/machinery/computer/rdservercontrol/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, "ResearchServerController", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/rdservercontrol/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["badmin"] = badmin
|
||||
|
||||
var/list/server_list = list()
|
||||
data["servers"] = server_list
|
||||
for(var/obj/machinery/r_n_d/server/S in machines)
|
||||
if(istype(S, /obj/machinery/r_n_d/server/centcom) && !badmin)
|
||||
continue
|
||||
var/list/server_data = list(
|
||||
"name" = S.name,
|
||||
"ref" = REF(S),
|
||||
"id" = S.server_id,
|
||||
"id_with_upload" = S.id_with_upload,
|
||||
"id_with_download" = S.id_with_download,
|
||||
"tech" = list(),
|
||||
"designs" = list(),
|
||||
)
|
||||
for(var/datum/tech/T in S.files.known_tech)
|
||||
server_data["tech"].Add(list(list(
|
||||
"name" = T.name,
|
||||
"id" = T.id,
|
||||
)))
|
||||
for(var/datum/design/D in S.files.known_designs)
|
||||
server_data["designs"].Add(list(list(
|
||||
"name" = D.name,
|
||||
"id" = D.id,
|
||||
)))
|
||||
server_list.Add(list(server_data))
|
||||
|
||||
var/list/console_list = list()
|
||||
data["consoles"] = console_list
|
||||
for(var/obj/machinery/computer/rdconsole/C in machines)
|
||||
if(!C.sync)
|
||||
continue
|
||||
console_list.Add(list(list(
|
||||
"name" = C.name,
|
||||
"ref" = REF(C),
|
||||
"loc" = get_area(C),
|
||||
"id" = C.id,
|
||||
)))
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/rdservercontrol/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
usr.set_machine(src)
|
||||
if(!allowed(usr) && !emagged)
|
||||
to_chat(usr, "<span class='warning'>You do not have the required access level</span>")
|
||||
return
|
||||
switch(action)
|
||||
if("toggle_upload", "toggle_download")
|
||||
var/obj/machinery/r_n_d/server/S = locate(params["server"])
|
||||
if(!istype(S))
|
||||
return
|
||||
if(istype(S, /obj/machinery/r_n_d/server/centcom) && !badmin)
|
||||
return
|
||||
var/obj/machinery/computer/rdconsole/C = locate(params["console"])
|
||||
if(!istype(C) || !C.sync)
|
||||
return
|
||||
|
||||
if(href_list["main"])
|
||||
screen = 0
|
||||
switch(action)
|
||||
if("toggle_upload")
|
||||
if(C.id in S.id_with_upload)
|
||||
S.id_with_upload -= C.id
|
||||
else
|
||||
S.id_with_upload += C.id
|
||||
if("toggle_download")
|
||||
if(C.id in S.id_with_download)
|
||||
S.id_with_download -= C.id
|
||||
else
|
||||
S.id_with_download += C.id
|
||||
return TRUE
|
||||
|
||||
else if(href_list["access"] || href_list["data"] || href_list["transfer"])
|
||||
temp_server = null
|
||||
consoles = list()
|
||||
servers = list()
|
||||
for(var/obj/machinery/r_n_d/server/S in machines)
|
||||
if(S.server_id == text2num(href_list["access"]) || S.server_id == text2num(href_list["data"]) || S.server_id == text2num(href_list["transfer"]))
|
||||
temp_server = S
|
||||
break
|
||||
if(href_list["access"])
|
||||
screen = 1
|
||||
for(var/obj/machinery/computer/rdconsole/C in machines)
|
||||
if(C.sync)
|
||||
consoles += C
|
||||
else if(href_list["data"])
|
||||
screen = 2
|
||||
else if(href_list["transfer"])
|
||||
screen = 3
|
||||
for(var/obj/machinery/r_n_d/server/S in machines)
|
||||
if(S == src)
|
||||
continue
|
||||
servers += S
|
||||
if("reset_tech")
|
||||
var/obj/machinery/r_n_d/server/target = locate(params["server"])
|
||||
if(!istype(target))
|
||||
return FALSE
|
||||
var/choice = alert("Technology Data Rest", "Are you sure you want to reset this technology to its default data? Data lost cannot be recovered.", "Continue", "Cancel")
|
||||
if(choice == "Continue")
|
||||
for(var/datum/tech/T in target.files.known_tech)
|
||||
if(T.id == params["tech"])
|
||||
T.level = 1
|
||||
break
|
||||
target.files.RefreshResearch()
|
||||
return TRUE
|
||||
|
||||
else if(href_list["upload_toggle"])
|
||||
var/num = text2num(href_list["upload_toggle"])
|
||||
if(num in temp_server.id_with_upload)
|
||||
temp_server.id_with_upload -= num
|
||||
else
|
||||
temp_server.id_with_upload += num
|
||||
if("reset_design")
|
||||
var/obj/machinery/r_n_d/server/target = locate(params["server"])
|
||||
if(!istype(target))
|
||||
return FALSE
|
||||
var/choice = alert("Design Data Deletion", "Are you sure you want to delete this design? If you still have the prerequisites for the design, it'll reset to its base reliability. Data lost cannot be recovered.", "Continue", "Cancel")
|
||||
if(choice == "Continue")
|
||||
for(var/datum/design/D in target.files.known_designs)
|
||||
if(D.id == params["design"])
|
||||
target.files.known_designs -= D
|
||||
break
|
||||
target.files.RefreshResearch()
|
||||
return TRUE
|
||||
|
||||
else if(href_list["download_toggle"])
|
||||
var/num = text2num(href_list["download_toggle"])
|
||||
if(num in temp_server.id_with_download)
|
||||
temp_server.id_with_download -= num
|
||||
else
|
||||
temp_server.id_with_download += num
|
||||
|
||||
else if(href_list["reset_tech"])
|
||||
var/choice = alert("Technology Data Rest", "Are you sure you want to reset this technology to its default data? Data lost cannot be recovered.", "Continue", "Cancel")
|
||||
if(choice == "Continue")
|
||||
for(var/datum/tech/T in temp_server.files.known_tech)
|
||||
if(T.id == href_list["reset_tech"])
|
||||
T.level = 1
|
||||
break
|
||||
temp_server.files.RefreshResearch()
|
||||
|
||||
else if(href_list["reset_design"])
|
||||
var/choice = alert("Design Data Deletion", "Are you sure you want to delete this design? If you still have the prerequisites for the design, it'll reset to its base reliability. Data lost cannot be recovered.", "Continue", "Cancel")
|
||||
if(choice == "Continue")
|
||||
for(var/datum/design/D in temp_server.files.known_designs)
|
||||
if(D.id == href_list["reset_design"])
|
||||
temp_server.files.known_designs -= D
|
||||
break
|
||||
temp_server.files.RefreshResearch()
|
||||
|
||||
updateUsrDialog()
|
||||
return
|
||||
if("transfer_data")
|
||||
if(!badmin)
|
||||
// no href exploits, you've been r e p o r t e d
|
||||
log_admin("Warning: [key_name(usr)] attempted to transfer R&D data from [params["server"]] to [params["target"]] via href exploit with [src] [COORD(src)]")
|
||||
message_admins("Warning: [ADMIN_FULLMONTY(usr)] attempted to transfer R&D data from [params["server"]] to [params["target"]] via href exploit with [src] [ADMIN_COORDJMP(src)]")
|
||||
return FALSE
|
||||
var/obj/machinery/r_n_d/server/from = locate(params["server"])
|
||||
if(!istype(from))
|
||||
return
|
||||
var/obj/machinery/r_n_d/server/target = locate(params["target"])
|
||||
if(!istype(target))
|
||||
return
|
||||
target.files.known_designs |= from.files.known_designs
|
||||
target.files.known_tech |= from.files.known_tech
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/rdservercontrol/attack_hand(mob/user as mob)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = ""
|
||||
|
||||
switch(screen)
|
||||
if(0) //Main Menu
|
||||
dat += "Connected Servers:<BR><BR>"
|
||||
|
||||
for(var/obj/machinery/r_n_d/server/S in machines)
|
||||
if(istype(S, /obj/machinery/r_n_d/server/centcom) && !badmin)
|
||||
continue
|
||||
dat += "[S.name] || "
|
||||
dat += "<A href='?src=\ref[src];access=[S.server_id]'> Access Rights</A> | "
|
||||
dat += "<A href='?src=\ref[src];data=[S.server_id]'>Data Management</A>"
|
||||
if(badmin) dat += " | <A href='?src=\ref[src];transfer=[S.server_id]'>Server-to-Server Transfer</A>"
|
||||
dat += "<BR>"
|
||||
|
||||
if(1) //Access rights menu
|
||||
dat += "[temp_server.name] Access Rights<BR><BR>"
|
||||
dat += "Consoles with Upload Access<BR>"
|
||||
for(var/obj/machinery/computer/rdconsole/C in consoles)
|
||||
var/turf/console_turf = get_turf(C)
|
||||
dat += "* <A href='?src=\ref[src];upload_toggle=[C.id]'>[console_turf.loc]" //FYI, these are all numeric ids, eventually.
|
||||
if(C.id in temp_server.id_with_upload)
|
||||
dat += " (Remove)</A><BR>"
|
||||
else
|
||||
dat += " (Add)</A><BR>"
|
||||
dat += "Consoles with Download Access<BR>"
|
||||
for(var/obj/machinery/computer/rdconsole/C in consoles)
|
||||
var/turf/console_turf = get_turf(C)
|
||||
dat += "* <A href='?src=\ref[src];download_toggle=[C.id]'>[console_turf.loc]"
|
||||
if(C.id in temp_server.id_with_download)
|
||||
dat += " (Remove)</A><BR>"
|
||||
else
|
||||
dat += " (Add)</A><BR>"
|
||||
dat += "<HR><A href='?src=\ref[src];main=1'>Main Menu</A>"
|
||||
|
||||
if(2) //Data Management menu
|
||||
dat += "[temp_server.name] Data ManagementP<BR><BR>"
|
||||
dat += "Known Technologies<BR>"
|
||||
for(var/datum/tech/T in temp_server.files.known_tech)
|
||||
dat += "* [T.name] "
|
||||
dat += "<A href='?src=\ref[src];reset_tech=[T.id]'>(Reset)</A><BR>" //FYI, these are all strings.
|
||||
dat += "Known Designs<BR>"
|
||||
for(var/datum/design/D in temp_server.files.known_designs)
|
||||
dat += "* [D.name] "
|
||||
dat += "<A href='?src=\ref[src];reset_design=[D.id]'>(Delete)</A><BR>"
|
||||
dat += "<HR><A href='?src=\ref[src];main=1'>Main Menu</A>"
|
||||
|
||||
if(3) //Server Data Transfer
|
||||
dat += "[temp_server.name] Server to Server Transfer<BR><BR>"
|
||||
dat += "Send Data to what server?<BR>"
|
||||
for(var/obj/machinery/r_n_d/server/S in servers)
|
||||
dat += "[S.name] <A href='?src=\ref[src];send_to=[S.server_id]'> (Transfer)</A><BR>"
|
||||
dat += "<HR><A href='?src=\ref[src];main=1'>Main Menu</A>"
|
||||
user << browse("<TITLE>R&D Server Control</TITLE><HR>[dat]", "window=server_control;size=575x400")
|
||||
onclose(user, "server_control")
|
||||
return
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/rdservercontrol/emag_act(var/remaining_charges, var/mob/user)
|
||||
if(!emagged)
|
||||
playsound(src, 'sound/effects/sparks4.ogg', 75, 1)
|
||||
emagged = 1
|
||||
to_chat(user, "<span class='notice'>You you disable the security protocols.</span>")
|
||||
src.updateUsrDialog()
|
||||
SStgui.update_uis(src)
|
||||
return 1
|
||||
|
||||
/obj/machinery/r_n_d/server/robotics
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
return
|
||||
closing = TRUE
|
||||
for(var/datum/tgui/child in children)
|
||||
child.close()
|
||||
child.close(can_be_suspended, logout)
|
||||
children.Cut()
|
||||
// If we don't have window_id, open proc did not have the opportunity
|
||||
// to finish, therefore it's safe to skip this whole block.
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
var/last_process_time = 0
|
||||
|
||||
var/list/construction = list()
|
||||
var/list/tgui_construction = list()
|
||||
var/list/spawning_types = list()
|
||||
var/list/stored_materials = list()
|
||||
|
||||
@@ -67,12 +68,35 @@
|
||||
// /mob/living/simple_mob/mimic/crate, // Vorestation edit //VORESTATION AI TEMPORARY REMOVAL, REPLACE BACK IN LIST WHEN FIXED
|
||||
var/quantity = rand(5, 15)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/button_desc = "a [pick("yellow","purple","green","blue","red","orange","white")], "
|
||||
button_desc += "[pick("round","square","diamond","heart","dog","human")] shaped "
|
||||
button_desc += "[pick("toggle","switch","lever","button","pad","hole")]"
|
||||
var/background = pick("yellow","purple","green","blue","red","orange","white")
|
||||
var/list/icons = list(
|
||||
"round" = "circle",
|
||||
"square" = "square",
|
||||
"diamond" = "gem",
|
||||
"heart" = "heart",
|
||||
"dog" = "dog",
|
||||
"human" = "user",
|
||||
)
|
||||
var/icon = pick(icons)
|
||||
var/list/colors = list(
|
||||
"toggle" = "pink",
|
||||
"switch" = "yellow",
|
||||
"lever" = "red",
|
||||
"button" = "black",
|
||||
"pad" = "white",
|
||||
"hole" = "black",
|
||||
)
|
||||
var/color = pick(colors)
|
||||
var/button_desc = "a [background], [icon] shaped [color]"
|
||||
var/type = pick(viables)
|
||||
viables.Remove(type)
|
||||
construction[button_desc] = type
|
||||
tgui_construction.Add(list(list(
|
||||
"key" = button_desc,
|
||||
"background" = background,
|
||||
"icon" = icons[icon],
|
||||
"foreground" = colors[color],
|
||||
)))
|
||||
|
||||
fail_message = "<font color='blue'>[bicon(src)] a [pick("loud","soft","sinister","eery","triumphant","depressing","cheerful","angry")] \
|
||||
[pick("horn","beep","bing","bleep","blat","honk","hrumph","ding")] sounds and a \
|
||||
@@ -114,15 +138,38 @@
|
||||
last_process_time = world.time
|
||||
|
||||
/obj/machinery/replicator/attack_hand(mob/user as mob)
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/replicator/interact(mob/user)
|
||||
var/dat = "The control panel displays an incomprehensible selection of controls, many with unusual markings or text around them.<br>"
|
||||
dat += "<br>"
|
||||
for(var/index=1, index<=construction.len, index++)
|
||||
dat += "<A href='?src=\ref[src];activate=[index]'>\[[construction[index]]\]</a><br>"
|
||||
/obj/machinery/replicator/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "XenoarchReplicator", name)
|
||||
ui.open()
|
||||
|
||||
user << browse(dat, "window=alien_replicator")
|
||||
/obj/machinery/replicator/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
data["tgui_construction"] = tgui_construction
|
||||
return data
|
||||
|
||||
/obj/machinery/replicator/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("construct")
|
||||
var/key = params["key"]
|
||||
if(key in construction)
|
||||
if(LAZYLEN(stored_materials) > LAZYLEN(spawning_types))
|
||||
if(LAZYLEN(spawning_types))
|
||||
visible_message("<span class='notice'>[bicon(src)] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].</span>")
|
||||
else
|
||||
visible_message("<span class='notice'>[bicon(src)] [src]'s front compartment slides shut.</span>")
|
||||
spawning_types.Add(construction[key])
|
||||
spawn_progress_time = 0
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
icon_state = "borgcharger1(old)"
|
||||
else
|
||||
visible_message(fail_message)
|
||||
|
||||
/obj/machinery/replicator/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
|
||||
if(!W.canremove || !user.canUnEquip(W)) //No armblades, no grabs. No other-thing-I-didn't-think-of.
|
||||
@@ -132,21 +179,3 @@
|
||||
W.loc = src
|
||||
stored_materials.Add(W)
|
||||
src.visible_message("<span class='notice'>\The [user] inserts \the [W] into \the [src].</span>")
|
||||
|
||||
/obj/machinery/replicator/Topic(href, href_list)
|
||||
|
||||
if(href_list["activate"])
|
||||
var/index = text2num(href_list["activate"])
|
||||
if(index > 0 && index <= construction.len)
|
||||
if(stored_materials.len > spawning_types.len)
|
||||
if(spawning_types.len)
|
||||
src.visible_message("<span class='notice'>[bicon(src)] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].</span>")
|
||||
else
|
||||
src.visible_message("<span class='notice'>[bicon(src)] [src]'s front compartment slides shut.</span>")
|
||||
|
||||
spawning_types.Add(construction[construction[index]])
|
||||
spawn_progress_time = 0
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
icon_state = "borgcharger1(old)"
|
||||
else
|
||||
src.visible_message(fail_message)
|
||||
|
||||
@@ -54,35 +54,73 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/anodevice/attack_self(var/mob/user as mob)
|
||||
return src.interact(user)
|
||||
return tgui_interact(user)
|
||||
|
||||
/obj/item/weapon/anodevice/interact(var/mob/user)
|
||||
var/dat = "<b>Anomalous Materials Energy Utiliser</b><br>"
|
||||
/obj/item/weapon/anodevice/tgui_state(mob/user)
|
||||
return GLOB.tgui_inventory_state
|
||||
|
||||
/obj/item/weapon/anodevice/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "XenoarchHandheldPowerUtilizer", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/weapon/anodevice/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["inserted_battery"] = inserted_battery
|
||||
data["anomaly"] = null
|
||||
data["charge"] = null
|
||||
data["capacity"] = null
|
||||
data["timeleft"] = null
|
||||
data["activated"] = null
|
||||
data["duration"] = null
|
||||
data["interval"] = null
|
||||
if(inserted_battery)
|
||||
if(activated)
|
||||
dat += "Device active.<br>"
|
||||
data["anomaly"] = inserted_battery?.battery_effect?.artifact_id
|
||||
data["charge"] = inserted_battery.stored_charge
|
||||
data["capacity"] = inserted_battery.capacity
|
||||
data["timeleft"] = round(max((time_end - last_process) / 10, 0))
|
||||
data["activated"] = activated
|
||||
data["duration"] = duration / 10
|
||||
data["interval"] = interval / 10
|
||||
|
||||
dat += "[inserted_battery] inserted, anomaly ID: [inserted_battery.battery_effect.artifact_id ? inserted_battery.battery_effect.artifact_id : "NA"]<BR>"
|
||||
dat += "<b>Charge:</b> [inserted_battery.stored_charge] / [inserted_battery.capacity]<BR>"
|
||||
dat += "<b>Time left activated:</b> [round(max((time_end - last_process) / 10, 0))]<BR>"
|
||||
if(activated)
|
||||
dat += "<a href='?src=\ref[src];shutdown=1'>Shutdown</a><br>"
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];startup=1'>Start</a><BR>"
|
||||
dat += "<BR>"
|
||||
return data
|
||||
|
||||
dat += "<b>Activate duration (sec):</b> <A href='?src=\ref[src];changetime=-100;duration=1'>--</a> <A href='?src=\ref[src];changetime=-10;duration=1'>-</a> [duration/10] <A href='?src=\ref[src];changetime=10;duration=1'>+</a> <A href='?src=\ref[src];changetime=100;duration=1'>++</a><BR>"
|
||||
dat += "<b>Activate interval (sec):</b> <A href='?src=\ref[src];changetime=-100;interval=1'>--</a> <A href='?src=\ref[src];changetime=-10;interval=1'>-</a> [interval/10] <A href='?src=\ref[src];changetime=10;interval=1'>+</a> <A href='?src=\ref[src];changetime=100;interval=1'>++</a><BR>"
|
||||
dat += "<br>"
|
||||
dat += "<A href='?src=\ref[src];ejectbattery=1'>Eject battery</a><BR>"
|
||||
else
|
||||
dat += "Please insert battery<br>"
|
||||
/obj/item/weapon/anodevice/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
dat += "<hr>"
|
||||
dat += "<a href='?src=\ref[src];refresh=1'>Refresh</a> <a href='?src=\ref[src];close=1'>Close</a>"
|
||||
|
||||
user << browse(dat, "window=anodevice;size=400x500")
|
||||
onclose(user, "anodevice")
|
||||
switch(action)
|
||||
if("changeduration")
|
||||
duration = clamp(text2num(params["duration"]), 0, 300)
|
||||
if(activated)
|
||||
time_end = world.time + duration
|
||||
return TRUE
|
||||
if("changeinterval")
|
||||
interval = clamp(text2num(params["interval"]), 0, 100)
|
||||
return TRUE
|
||||
if("startup")
|
||||
if(inserted_battery && inserted_battery.battery_effect && (inserted_battery.stored_charge > 0))
|
||||
activated = TRUE
|
||||
visible_message("<font color='blue'>[bicon(src)] [src] whirrs.</font>", "[bicon(src)]<font color='blue'>You hear something whirr.</font>")
|
||||
if(!inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate(1)
|
||||
time_end = world.time + duration
|
||||
last_process = world.time
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>[src] is unable to start due to no anomolous power source inserted/remaining.</span>")
|
||||
return TRUE
|
||||
if("shutdown")
|
||||
activated = FALSE
|
||||
return TRUE
|
||||
if("ejectbattery")
|
||||
if(inserted_battery)
|
||||
inserted_battery.forceMove(get_turf(src))
|
||||
inserted_battery = null
|
||||
UpdateSprite()
|
||||
shutdown_emission()
|
||||
return TRUE
|
||||
|
||||
/obj/item/weapon/anodevice/process()
|
||||
if(activated)
|
||||
@@ -150,45 +188,9 @@
|
||||
/obj/item/weapon/anodevice/proc/shutdown_emission()
|
||||
if(activated)
|
||||
activated = 0
|
||||
if(inserted_battery.battery_effect.activated)
|
||||
if(inserted_battery?.battery_effect?.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate(1)
|
||||
|
||||
/obj/item/weapon/anodevice/Topic(href, href_list)
|
||||
|
||||
if(href_list["changetime"])
|
||||
var/timedif = text2num(href_list["changetime"])
|
||||
if(href_list["duration"])
|
||||
duration += timedif
|
||||
//max 30 sec duration
|
||||
duration = min(max(duration, 0), 300)
|
||||
if(activated)
|
||||
time_end += timedif
|
||||
else if(href_list["interval"])
|
||||
interval += timedif
|
||||
//max 10 sec interval
|
||||
interval = min(max(interval, 0), 100)
|
||||
if(href_list["startup"])
|
||||
if(inserted_battery && inserted_battery.battery_effect && (inserted_battery.stored_charge > 0) )
|
||||
activated = 1
|
||||
src.visible_message("<font color='blue'>[bicon(src)] [src] whirrs.</font>", "[bicon(src)]<font color='blue'>You hear something whirr.</font>")
|
||||
if(!inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate(1)
|
||||
time_end = world.time + duration
|
||||
last_process = world.time
|
||||
if(href_list["shutdown"])
|
||||
activated = 0
|
||||
if(href_list["ejectbattery"])
|
||||
shutdown_emission()
|
||||
inserted_battery.loc = get_turf(src)
|
||||
inserted_battery = null
|
||||
UpdateSprite()
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=anodevice")
|
||||
else if(ismob(src.loc))
|
||||
var/mob/M = src.loc
|
||||
src.interact(M)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/anodevice/proc/UpdateSprite()
|
||||
if(!inserted_battery)
|
||||
icon_state = "anodev"
|
||||
@@ -205,8 +207,8 @@
|
||||
if (!istype(M))
|
||||
return
|
||||
|
||||
if(activated && inserted_battery.battery_effect.effect == EFFECT_TOUCH && !isnull(inserted_battery))
|
||||
inserted_battery.battery_effect.DoEffectTouch(M)
|
||||
if(activated && inserted_battery?.battery_effect?.effect == EFFECT_TOUCH && !isnull(inserted_battery))
|
||||
inserted_battery?.battery_effect?.DoEffectTouch(M)
|
||||
inserted_battery.use_power(energy_consumed_on_touch)
|
||||
user.visible_message("<font color='blue'>[user] taps [M] with [src], and it shudders on contact.</font>")
|
||||
else
|
||||
@@ -216,5 +218,5 @@
|
||||
user.lastattacked = M
|
||||
M.lastattacker = user
|
||||
|
||||
if(inserted_battery.battery_effect)
|
||||
add_attack_logs(user,M,"Anobattery tap ([inserted_battery.battery_effect.name])")
|
||||
if(inserted_battery?.battery_effect)
|
||||
add_attack_logs(user,M,"Anobattery tap ([inserted_battery?.battery_effect?.name])")
|
||||
|
||||
@@ -24,35 +24,68 @@
|
||||
if(!owned_scanner)
|
||||
owned_scanner = locate(/obj/machinery/artifact_scanpad) in orange(1, src)
|
||||
|
||||
/obj/machinery/artifact_analyser/attack_hand(var/mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/artifact_analyser/interact(mob/user)
|
||||
/obj/machinery/artifact_analyser/attack_hand(mob/user)
|
||||
add_fingerprint(user)
|
||||
if(stat & (NOPOWER|BROKEN) || get_dist(src, user) > 1)
|
||||
user.unset_machine(src)
|
||||
return
|
||||
tgui_interact(user)
|
||||
|
||||
var/dat = "<B>Anomalous material analyser</B><BR>"
|
||||
dat += "<HR>"
|
||||
/obj/machinery/artifact_analyser/tgui_interact(mob/user, datum/tgui/ui)
|
||||
if(!owned_scanner)
|
||||
reconnect_scanner()
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "XenoarchArtifactAnalyzer", name)
|
||||
ui.open()
|
||||
|
||||
if(!owned_scanner)
|
||||
dat += "<b><font color=red>Unable to locate analysis pad.</font></b><br>"
|
||||
else if(scan_in_progress)
|
||||
dat += "Please wait. Analysis in progress.<br>"
|
||||
dat += "<a href='?src=\ref[src];halt_scan=1'>Halt scanning.</a><br>"
|
||||
else
|
||||
dat += "Scanner is ready.<br>"
|
||||
dat += "<a href='?src=\ref[src];begin_scan=1'>Begin scanning.</a><br>"
|
||||
/obj/machinery/artifact_analyser/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
dat += "<br>"
|
||||
dat += "<hr>"
|
||||
dat += "<a href='?src=\ref[src]'>Refresh</a> <a href='?src=\ref[src];close=1'>Close</a>"
|
||||
user << browse(dat, "window=artanalyser;size=450x500")
|
||||
user.set_machine(src)
|
||||
onclose(user, "artanalyser")
|
||||
data["owned_scanner"] = owned_scanner
|
||||
data["scan_in_progress"] = scan_in_progress
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/artifact_analyser/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
switch(action)
|
||||
if("scan")
|
||||
if(scan_in_progress)
|
||||
scan_in_progress = FALSE
|
||||
atom_say("Scanning halted.")
|
||||
return TRUE
|
||||
if(!owned_scanner)
|
||||
reconnect_scanner()
|
||||
if(owned_scanner)
|
||||
var/artifact_in_use = 0
|
||||
for(var/obj/O in owned_scanner.loc)
|
||||
if(O == owned_scanner)
|
||||
continue
|
||||
if(O.invisibility)
|
||||
continue
|
||||
if(istype(O, /obj/machinery/artifact))
|
||||
var/obj/machinery/artifact/A = O
|
||||
if(A.being_used)
|
||||
artifact_in_use = 1
|
||||
else
|
||||
A.anchored = 1
|
||||
A.being_used = 1
|
||||
|
||||
if(artifact_in_use)
|
||||
atom_say("Cannot scan. Too much interference.")
|
||||
else
|
||||
scanned_object = O
|
||||
scan_in_progress = 1
|
||||
scan_completion_time = world.time + scan_duration
|
||||
atom_say("Scanning begun.")
|
||||
break
|
||||
if(!scanned_object)
|
||||
atom_say("Unable to isolate scan target.")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/artifact_analyser/process()
|
||||
if(scan_in_progress && world.time > scan_completion_time)
|
||||
@@ -69,7 +102,7 @@
|
||||
else
|
||||
results = get_scan_info(scanned_object)
|
||||
|
||||
src.visible_message("<b>[name]</b> states, \"Scanning complete.\"")
|
||||
atom_say("Scanning complete.")
|
||||
var/obj/item/weapon/paper/P = new(src.loc)
|
||||
P.name = "[src] report #[++report_num]"
|
||||
P.info = "<b>[src] analysis report #[report_num]</b><br>"
|
||||
@@ -84,46 +117,6 @@
|
||||
A.being_used = 0
|
||||
scanned_object = null
|
||||
|
||||
/obj/machinery/artifact_analyser/Topic(href, href_list)
|
||||
if(href_list["begin_scan"])
|
||||
if(!owned_scanner)
|
||||
reconnect_scanner()
|
||||
if(owned_scanner)
|
||||
var/artifact_in_use = 0
|
||||
for(var/obj/O in owned_scanner.loc)
|
||||
if(O == owned_scanner)
|
||||
continue
|
||||
if(O.invisibility)
|
||||
continue
|
||||
if(istype(O, /obj/machinery/artifact))
|
||||
var/obj/machinery/artifact/A = O
|
||||
if(A.being_used)
|
||||
artifact_in_use = 1
|
||||
else
|
||||
A.anchored = 1
|
||||
A.being_used = 1
|
||||
|
||||
if(artifact_in_use)
|
||||
src.visible_message("<b>[name]</b> states, \"Cannot scan. Too much interference.\"")
|
||||
else
|
||||
scanned_object = O
|
||||
scan_in_progress = 1
|
||||
scan_completion_time = world.time + scan_duration
|
||||
src.visible_message("<b>[name]</b> states, \"Scanning begun.\"")
|
||||
break
|
||||
if(!scanned_object)
|
||||
src.visible_message("<b>[name]</b> states, \"Unable to isolate scan target.\"")
|
||||
if(href_list["halt_scan"])
|
||||
scan_in_progress = 0
|
||||
src.visible_message("<b>[name]</b> states, \"Scanning halted.\"")
|
||||
|
||||
if(href_list["close"])
|
||||
usr.unset_machine(src)
|
||||
usr << browse(null, "window=artanalyser")
|
||||
|
||||
..()
|
||||
updateDialog()
|
||||
|
||||
//hardcoded responses, oh well
|
||||
/obj/machinery/artifact_analyser/proc/get_scan_info(var/obj/scanned_obj)
|
||||
switch(scanned_obj.type)
|
||||
|
||||
@@ -26,47 +26,194 @@
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
src.inserted_battery = I
|
||||
updateDialog()
|
||||
SStgui.update_uis(src)
|
||||
else
|
||||
to_chat(user, "<font color='red'>There is already a battery in [src].</font>")
|
||||
else
|
||||
return..()
|
||||
|
||||
/obj/machinery/artifact_harvester/attack_hand(var/mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/artifact_harvester/interact(var/mob/user as mob)
|
||||
add_fingerprint(user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<B>Artifact Power Harvester</B><BR>"
|
||||
dat += "<HR><BR>"
|
||||
//
|
||||
if(owned_scanner)
|
||||
if(harvesting)
|
||||
if(harvesting > 0)
|
||||
dat += "Please wait. Harvesting in progress ([round((inserted_battery.stored_charge/inserted_battery.capacity)*100)]%).<br>"
|
||||
else
|
||||
dat += "Please wait. Energy dump in progress ([round((inserted_battery.stored_charge/inserted_battery.capacity)*100)]%).<br>"
|
||||
dat += "<A href='?src=\ref[src];stopharvest=1'>Halt early</A><BR>"
|
||||
else
|
||||
if(inserted_battery)
|
||||
dat += "<b>[inserted_battery.name]</b> inserted, charge level: [inserted_battery.stored_charge]/[inserted_battery.capacity] ([(inserted_battery.stored_charge/inserted_battery.capacity)*100]%)<BR>"
|
||||
dat += "<b>Energy signature ID:</b>[inserted_battery.battery_effect ? (inserted_battery.battery_effect.artifact_id == "" ? "???" : "[inserted_battery.battery_effect.artifact_id]") : "NA"]<BR>"
|
||||
dat += "<A href='?src=\ref[src];ejectbattery=1'>Eject battery</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];drainbattery=1'>Drain battery of all charge</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];harvest=1'>Begin harvesting</a><BR>"
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/artifact_harvester/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "XenoarchArtifactHarvester", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/artifact_harvester/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["info"] = list(
|
||||
"no_scanner" = TRUE,
|
||||
)
|
||||
if(owned_scanner)
|
||||
data["info"] = list(
|
||||
"no_scanner" = FALSE,
|
||||
"harvesting" = harvesting,
|
||||
"inserted_battery" = list(),
|
||||
)
|
||||
if(inserted_battery)
|
||||
data["info"]["inserted_battery"] = list(
|
||||
"name" = inserted_battery.name,
|
||||
"stored_charge" = inserted_battery.stored_charge,
|
||||
"capacity" = inserted_battery.capacity,
|
||||
"artifact_id" = null
|
||||
)
|
||||
if(inserted_battery.battery_effect)
|
||||
data["info"]["inserted_battery"]["artifact_id"] = inserted_battery.battery_effect.artifact_id || "???"
|
||||
else
|
||||
dat += "No battery inserted.<BR>"
|
||||
else
|
||||
dat += "<B><font color=red>Unable to locate analysis pad.</font><BR></b>"
|
||||
//
|
||||
dat += "<HR>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh</A> <A href='?src=\ref[src];close=1'>Close<BR>"
|
||||
user << browse(dat, "window=artharvester;size=450x500")
|
||||
onclose(user, "artharvester")
|
||||
data["info"]["inserted_battery"]["artifact_id"] = "N/A"
|
||||
return data
|
||||
|
||||
/obj/machinery/artifact_harvester/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
switch(action)
|
||||
if("harvest")
|
||||
harvest()
|
||||
return TRUE
|
||||
|
||||
if("stopharvest")
|
||||
if(harvesting)
|
||||
if(harvesting < 0 && inserted_battery.battery_effect && inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate()
|
||||
harvesting = 0
|
||||
cur_artifact.anchored = 0
|
||||
cur_artifact.being_used = 0
|
||||
cur_artifact = null
|
||||
atom_say("Energy harvesting interrupted.")
|
||||
icon_state = "incubator"
|
||||
return TRUE
|
||||
|
||||
if("ejectbattery")
|
||||
if(inserted_battery)
|
||||
inserted_battery.forceMove(loc)
|
||||
inserted_battery = null
|
||||
return TRUE
|
||||
|
||||
if("drainbattery")
|
||||
if(inserted_battery)
|
||||
if(inserted_battery.battery_effect && inserted_battery.stored_charge > 0)
|
||||
if(alert("This action will dump all charge, safety gear is recommended before proceeding","Warning","Continue","Cancel"))
|
||||
if(!inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate(1)
|
||||
last_process = world.time
|
||||
harvesting = -1
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
icon_state = "incubator_on"
|
||||
atom_say("Warning, battery charge dump commencing.")
|
||||
else
|
||||
atom_say("Cannot dump energy. Battery is drained of charge already.")
|
||||
else
|
||||
atom_say("Cannot dump energy. No battery inserted.")
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/machinery/artifact_harvester/proc/harvest()
|
||||
if(!inserted_battery)
|
||||
atom_say("Cannot harvest. No battery inserted.")
|
||||
return
|
||||
if(inserted_battery.stored_charge >= inserted_battery.capacity)
|
||||
atom_say("Cannot harvest. Battery is full.")
|
||||
return
|
||||
|
||||
//locate artifact on analysis pad
|
||||
cur_artifact = null
|
||||
var/articount = 0
|
||||
var/obj/machinery/artifact/analysed
|
||||
for(var/obj/machinery/artifact/A in get_turf(owned_scanner))
|
||||
analysed = A
|
||||
articount++
|
||||
|
||||
if(articount <= 0)
|
||||
atom_say("Cannot harvest. No noteworthy energy signature isolated.")
|
||||
return
|
||||
|
||||
if(analysed && analysed.being_used)
|
||||
atom_say("Cannot harvest. Source already being harvested.")
|
||||
return
|
||||
|
||||
if(articount > 1)
|
||||
atom_say("Cannot harvest. Too many artifacts on the pad.")
|
||||
return
|
||||
|
||||
if(analysed)
|
||||
cur_artifact = analysed
|
||||
|
||||
//if both effects are active, we can't harvest either
|
||||
if(cur_artifact.my_effect && cur_artifact.my_effect.activated && cur_artifact.secondary_effect && cur_artifact.secondary_effect.activated)
|
||||
atom_say("Cannot harvest. Source is emitting conflicting energy signatures.")
|
||||
return
|
||||
if(!cur_artifact.my_effect.activated && !(cur_artifact.secondary_effect && cur_artifact.secondary_effect.activated))
|
||||
atom_say("Cannot harvest. No energy emitting from source.")
|
||||
return
|
||||
|
||||
//see if we can clear out an old effect
|
||||
//delete it when the ids match to account for duplicate ids having different effects
|
||||
if(inserted_battery.battery_effect && inserted_battery.stored_charge <= 0)
|
||||
qdel(inserted_battery.battery_effect)
|
||||
inserted_battery.battery_effect = null
|
||||
|
||||
//
|
||||
var/datum/artifact_effect/source_effect
|
||||
|
||||
//if we already have charge in the battery, we can only recharge it from the source artifact
|
||||
if(inserted_battery.stored_charge > 0)
|
||||
var/battery_matches_primary_id = 0
|
||||
if(inserted_battery.battery_effect && inserted_battery.battery_effect.artifact_id == cur_artifact.my_effect.artifact_id)
|
||||
battery_matches_primary_id = 1
|
||||
if(battery_matches_primary_id && cur_artifact.my_effect.activated)
|
||||
//we're good to recharge the primary effect!
|
||||
source_effect = cur_artifact.my_effect
|
||||
|
||||
var/battery_matches_secondary_id = 0
|
||||
if(inserted_battery.battery_effect && inserted_battery.battery_effect.artifact_id == cur_artifact.secondary_effect.artifact_id)
|
||||
battery_matches_secondary_id = 1
|
||||
if(battery_matches_secondary_id && cur_artifact.secondary_effect.activated)
|
||||
//we're good to recharge the secondary effect!
|
||||
source_effect = cur_artifact.secondary_effect
|
||||
|
||||
if(!source_effect)
|
||||
atom_say("Cannot harvest. Battery is charged with a different energy signature.")
|
||||
else
|
||||
//we're good to charge either
|
||||
if(cur_artifact.my_effect.activated)
|
||||
//charge the primary effect
|
||||
source_effect = cur_artifact.my_effect
|
||||
|
||||
else if(cur_artifact.secondary_effect.activated)
|
||||
//charge the secondary effect
|
||||
source_effect = cur_artifact.secondary_effect
|
||||
|
||||
|
||||
if(source_effect)
|
||||
harvesting = 1
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
cur_artifact.anchored = 1
|
||||
cur_artifact.being_used = 1
|
||||
icon_state = "incubator_on"
|
||||
atom_say("Beginning energy harvesting.")
|
||||
last_process = world.time
|
||||
|
||||
//duplicate the artifact's effect datum
|
||||
if(!inserted_battery.battery_effect)
|
||||
var/effecttype = source_effect.type
|
||||
var/datum/artifact_effect/E = new effecttype(inserted_battery)
|
||||
|
||||
//duplicate it's unique settings
|
||||
for(var/varname in list("chargelevelmax","artifact_id","effect","effectrange","trigger"))
|
||||
E.vars[varname] = source_effect.vars[varname]
|
||||
|
||||
//copy the new datum into the battery
|
||||
inserted_battery.battery_effect = E
|
||||
inserted_battery.stored_charge = 0
|
||||
|
||||
/obj/machinery/artifact_harvester/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
@@ -111,143 +258,3 @@
|
||||
inserted_battery.battery_effect.ToggleActivate()
|
||||
src.visible_message("<b>[name]</b> states, \"Battery dump completed.\"")
|
||||
icon_state = "incubator"
|
||||
|
||||
/obj/machinery/artifact_harvester/Topic(href, href_list)
|
||||
|
||||
if (href_list["harvest"])
|
||||
if(!inserted_battery)
|
||||
src.visible_message("<b>[src]</b> states, \"Cannot harvest. No battery inserted.\"")
|
||||
|
||||
else if(inserted_battery.stored_charge >= inserted_battery.capacity)
|
||||
src.visible_message("<b>[src]</b> states, \"Cannot harvest. battery is full.\"")
|
||||
|
||||
else
|
||||
|
||||
//locate artifact on analysis pad
|
||||
cur_artifact = null
|
||||
var/articount = 0
|
||||
var/obj/machinery/artifact/analysed
|
||||
for(var/obj/machinery/artifact/A in get_turf(owned_scanner))
|
||||
analysed = A
|
||||
articount++
|
||||
|
||||
if(articount <= 0)
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. No noteworthy energy signature isolated.\""
|
||||
src.visible_message(message)
|
||||
|
||||
else if(analysed && analysed.being_used)
|
||||
src.visible_message("<b>[src]</b> states, \"Cannot harvest. Source already being harvested.\"")
|
||||
|
||||
else
|
||||
if(articount > 1)
|
||||
state("Cannot harvest. Too many artifacts on the pad.")
|
||||
else if(analysed)
|
||||
cur_artifact = analysed
|
||||
|
||||
//if both effects are active, we can't harvest either
|
||||
if(cur_artifact.my_effect && cur_artifact.my_effect.activated && cur_artifact.secondary_effect && cur_artifact.secondary_effect.activated)
|
||||
src.visible_message("<b>[src]</b> states, \"Cannot harvest. Source is emitting conflicting energy signatures.\"")
|
||||
else if(!cur_artifact.my_effect.activated && !(cur_artifact.secondary_effect && cur_artifact.secondary_effect.activated))
|
||||
src.visible_message("<b>[src]</b> states, \"Cannot harvest. No energy emitting from source.\"")
|
||||
|
||||
else
|
||||
//see if we can clear out an old effect
|
||||
//delete it when the ids match to account for duplicate ids having different effects
|
||||
if(inserted_battery.battery_effect && inserted_battery.stored_charge <= 0)
|
||||
qdel(inserted_battery.battery_effect)
|
||||
inserted_battery.battery_effect = null
|
||||
|
||||
//
|
||||
var/datum/artifact_effect/source_effect
|
||||
|
||||
//if we already have charge in the battery, we can only recharge it from the source artifact
|
||||
if(inserted_battery.stored_charge > 0)
|
||||
var/battery_matches_primary_id = 0
|
||||
if(inserted_battery.battery_effect && inserted_battery.battery_effect.artifact_id == cur_artifact.my_effect.artifact_id)
|
||||
battery_matches_primary_id = 1
|
||||
if(battery_matches_primary_id && cur_artifact.my_effect.activated)
|
||||
//we're good to recharge the primary effect!
|
||||
source_effect = cur_artifact.my_effect
|
||||
|
||||
var/battery_matches_secondary_id = 0
|
||||
if(inserted_battery.battery_effect && inserted_battery.battery_effect.artifact_id == cur_artifact.secondary_effect.artifact_id)
|
||||
battery_matches_secondary_id = 1
|
||||
if(battery_matches_secondary_id && cur_artifact.secondary_effect.activated)
|
||||
//we're good to recharge the secondary effect!
|
||||
source_effect = cur_artifact.secondary_effect
|
||||
|
||||
if(!source_effect)
|
||||
src.visible_message("<b>[src]</b> states, \"Cannot harvest. Battery is charged with a different energy signature.\"")
|
||||
else
|
||||
//we're good to charge either
|
||||
if(cur_artifact.my_effect.activated)
|
||||
//charge the primary effect
|
||||
source_effect = cur_artifact.my_effect
|
||||
|
||||
else if(cur_artifact.secondary_effect.activated)
|
||||
//charge the secondary effect
|
||||
source_effect = cur_artifact.secondary_effect
|
||||
|
||||
|
||||
if(source_effect)
|
||||
harvesting = 1
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
cur_artifact.anchored = 1
|
||||
cur_artifact.being_used = 1
|
||||
icon_state = "incubator_on"
|
||||
var/message = "<b>[src]</b> states, \"Beginning energy harvesting.\""
|
||||
src.visible_message(message)
|
||||
last_process = world.time
|
||||
|
||||
//duplicate the artifact's effect datum
|
||||
if(!inserted_battery.battery_effect)
|
||||
var/effecttype = source_effect.type
|
||||
var/datum/artifact_effect/E = new effecttype(inserted_battery)
|
||||
|
||||
//duplicate it's unique settings
|
||||
for(var/varname in list("chargelevelmax","artifact_id","effect","effectrange","trigger"))
|
||||
E.vars[varname] = source_effect.vars[varname]
|
||||
|
||||
//copy the new datum into the battery
|
||||
inserted_battery.battery_effect = E
|
||||
inserted_battery.stored_charge = 0
|
||||
|
||||
if (href_list["stopharvest"])
|
||||
if(harvesting)
|
||||
if(harvesting < 0 && inserted_battery.battery_effect && inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate()
|
||||
harvesting = 0
|
||||
cur_artifact.anchored = 0
|
||||
cur_artifact.being_used = 0
|
||||
cur_artifact = null
|
||||
src.visible_message("<b>[name]</b> states, \"Energy harvesting interrupted.\"")
|
||||
icon_state = "incubator"
|
||||
|
||||
if (href_list["ejectbattery"])
|
||||
src.inserted_battery.loc = src.loc
|
||||
src.inserted_battery = null
|
||||
|
||||
if (href_list["drainbattery"])
|
||||
if(inserted_battery)
|
||||
if(inserted_battery.battery_effect && inserted_battery.stored_charge > 0)
|
||||
if(alert("This action will dump all charge, safety gear is recommended before proceeding","Warning","Continue","Cancel"))
|
||||
if(!inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate(1)
|
||||
last_process = world.time
|
||||
harvesting = -1
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
icon_state = "incubator_on"
|
||||
var/message = "<b>[src]</b> states, \"Warning, battery charge dump commencing.\""
|
||||
src.visible_message(message)
|
||||
else
|
||||
var/message = "<b>[src]</b> states, \"Cannot dump energy. Battery is drained of charge already.\""
|
||||
src.visible_message(message)
|
||||
else
|
||||
var/message = "<b>[src]</b> states, \"Cannot dump energy. No battery inserted.\""
|
||||
src.visible_message(message)
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=artharvester")
|
||||
usr.unset_machine(src)
|
||||
|
||||
updateDialog()
|
||||
|
||||
@@ -59,9 +59,6 @@
|
||||
coolant_reagents_purity["coolant"] = 1
|
||||
coolant_reagents_purity["adminordrazine"] = 2
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/attack_hand(var/mob/user as mob)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/attackby(var/obj/I as obj, var/mob/user as mob)
|
||||
if(scanning)
|
||||
to_chat(user, "<span class='warning'>You can't do that while [src] is scanning!</span>")
|
||||
@@ -118,13 +115,19 @@
|
||||
if(total_purity && fresh_coolant)
|
||||
coolant_purity = total_purity / fresh_coolant
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
/obj/machinery/radiocarbon_spectrometer/attack_hand(mob/user)
|
||||
tgui_interact(user)
|
||||
|
||||
if(user.stat)
|
||||
return
|
||||
/obj/machinery/radiocarbon_spectrometer/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "XenoarchSpectrometer", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
// this is the data which will be sent to the ui
|
||||
var/data[0]
|
||||
data["scanned_item"] = (scanned_item ? scanned_item.name : "")
|
||||
data["scanned_item_desc"] = (scanned_item ? (scanned_item.desc ? scanned_item.desc : "No information on record.") : "")
|
||||
data["last_scan_data"] = last_scan_data
|
||||
@@ -136,31 +139,62 @@
|
||||
data["scanner_rpm"] = round(scanner_rpm)
|
||||
data["scanner_temperature"] = round(scanner_temperature)
|
||||
//
|
||||
data["coolant_usage_rate"] = "[coolant_usage_rate]"
|
||||
data["coolant_usage_rate"] = coolant_usage_rate
|
||||
data["coolant_usage_max"] = 10
|
||||
data["unused_coolant_abs"] = round(fresh_coolant)
|
||||
data["unused_coolant_per"] = round(fresh_coolant / reagents.maximum_volume * 100)
|
||||
data["coolant_purity"] = "[coolant_purity * 100]"
|
||||
data["coolant_purity"] = coolant_purity * 100
|
||||
//
|
||||
data["optimal_wavelength"] = round(optimal_wavelength)
|
||||
data["maser_wavelength"] = round(maser_wavelength)
|
||||
data["maser_wavelength_max"] = 10000
|
||||
data["maser_efficiency"] = round(maser_efficiency * 100)
|
||||
//
|
||||
data["radiation"] = round(radiation)
|
||||
data["t_left_radspike"] = round(t_left_radspike)
|
||||
data["rad_shield_on"] = rad_shield
|
||||
|
||||
// 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, "geoscanner.tmpl", "High Res Radiocarbon Spectrometer", 900, 825)
|
||||
// when the ui is first opened this is the data it will use
|
||||
ui.set_initial_data(data)
|
||||
// open the new ui window
|
||||
ui.open()
|
||||
// auto update every Master Controller tick
|
||||
ui.set_auto_update(1)
|
||||
return data
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
switch(action)
|
||||
if("scanItem")
|
||||
if(scanning)
|
||||
stop_scanning()
|
||||
else
|
||||
if(scanned_item)
|
||||
if(scanner_seal_integrity > 0)
|
||||
scanner_progress = 0
|
||||
scanning = 1
|
||||
t_left_radspike = pick(5,10,15)
|
||||
to_chat(usr, "<span class='notice'>Scan initiated.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Could not initiate scan, seal requires replacing.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Insert an item to scan.</span>")
|
||||
return TRUE
|
||||
|
||||
if("maserWavelength")
|
||||
maser_wavelength = clamp(text2num(params["wavelength"]), 1, 10000)
|
||||
return TRUE
|
||||
|
||||
if("coolantRate")
|
||||
coolant_usage_rate = clamp(text2num(params["coolant"]), 0, 10)
|
||||
return TRUE
|
||||
|
||||
if("toggle_rad_shield")
|
||||
rad_shield = !rad_shield
|
||||
return TRUE
|
||||
|
||||
if("ejectItem")
|
||||
if(scanned_item)
|
||||
scanned_item.forceMove(loc)
|
||||
scanned_item = null
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/process()
|
||||
if(scanning)
|
||||
@@ -323,42 +357,3 @@
|
||||
|
||||
scanned_item.loc = src.loc
|
||||
scanned_item = null
|
||||
|
||||
/obj/machinery/radiocarbon_spectrometer/Topic(href, href_list)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return 0 // don't update UIs attached to this object
|
||||
|
||||
if(href_list["scanItem"])
|
||||
if(scanning)
|
||||
stop_scanning()
|
||||
else
|
||||
if(scanned_item)
|
||||
if(scanner_seal_integrity > 0)
|
||||
scanner_progress = 0
|
||||
scanning = 1
|
||||
t_left_radspike = pick(5,10,15)
|
||||
to_chat(usr, "<span class='notice'>Scan initiated.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Could not initiate scan, seal requires replacing.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Insert an item to scan.</span>")
|
||||
|
||||
if(href_list["maserWavelength"])
|
||||
maser_wavelength = max(min(maser_wavelength + 1000 * text2num(href_list["maserWavelength"]), 10000), 1)
|
||||
|
||||
if(href_list["coolantRate"])
|
||||
coolant_usage_rate = max(min(coolant_usage_rate + text2num(href_list["coolantRate"]), 10000), 0)
|
||||
|
||||
if(href_list["toggle_rad_shield"])
|
||||
if(rad_shield)
|
||||
rad_shield = 0
|
||||
else
|
||||
rad_shield = 1
|
||||
|
||||
if(href_list["ejectItem"])
|
||||
if(scanned_item)
|
||||
scanned_item.loc = src.loc
|
||||
scanned_item = null
|
||||
|
||||
add_fingerprint(usr)
|
||||
return 1 // update UIs attached to this object
|
||||
@@ -6,125 +6,90 @@
|
||||
density = 1
|
||||
req_access = list(access_research)
|
||||
var/obj/item/weapon/cell/cell
|
||||
var/obj/item/weapon/card/id/auth_card
|
||||
var/locked = 1
|
||||
var/locked = TRUE
|
||||
var/power_use = 5
|
||||
var/obj/effect/suspension_field/suspension_field
|
||||
|
||||
/obj/machinery/suspension_gen/New()
|
||||
..()
|
||||
src.cell = new /obj/item/weapon/cell/high(src)
|
||||
/obj/machinery/suspension_gen/Initialize()
|
||||
. = ..()
|
||||
cell = new /obj/item/weapon/cell/high(src)
|
||||
|
||||
/obj/machinery/suspension_gen/process()
|
||||
if(suspension_field)
|
||||
cell.charge -= power_use
|
||||
|
||||
var/turf/T = get_turf(suspension_field)
|
||||
for(var/mob/living/M in T)
|
||||
M.Weaken(3)
|
||||
cell.charge -= power_use
|
||||
if(prob(5))
|
||||
to_chat(M, "<span class='warning'>[pick("You feel tingly","You feel like floating","It is hard to speak","You can barely move")].</span>")
|
||||
|
||||
for(var/obj/item/I in T)
|
||||
if(!suspension_field.contents.len)
|
||||
suspension_field.icon_state = "energynet"
|
||||
suspension_field.overlays += "shield2"
|
||||
I.forceMove(suspension_field)
|
||||
|
||||
if(cell.charge <= 0)
|
||||
deactivate()
|
||||
|
||||
/obj/machinery/suspension_gen/interact(var/mob/user)
|
||||
var/dat = "<b>Multi-phase mobile suspension field generator MK II \"Steadfast\"</b><br>"
|
||||
if(cell)
|
||||
var/colour = "red"
|
||||
if(cell.charge / cell.maxcharge > 0.66)
|
||||
colour = "green"
|
||||
else if(cell.charge / cell.maxcharge > 0.33)
|
||||
colour = "orange"
|
||||
dat += "<b>Energy cell</b>: <font color='[colour]'>[100 * cell.charge / cell.maxcharge]%</font><br>"
|
||||
else
|
||||
dat += "<b>Energy cell</b>: None<br>"
|
||||
if(auth_card)
|
||||
dat += "<A href='?src=\ref[src];ejectcard=1'>\[[auth_card]\]<a><br>"
|
||||
if(!locked)
|
||||
dat += "<b><A href='?src=\ref[src];toggle_field=1'>[suspension_field ? "Disable" : "Enable"] field</a></b><br>"
|
||||
else
|
||||
dat += "<br>"
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];insertcard=1'>\[------\]<a><br>"
|
||||
if(!locked)
|
||||
dat += "<b><A href='?src=\ref[src];toggle_field=1'>[suspension_field ? "Disable" : "Enable"] field</a></b><br>"
|
||||
else
|
||||
dat += "Enter your ID to begin.<br>"
|
||||
|
||||
dat += "<hr>"
|
||||
dat += "<hr>"
|
||||
dat += "<font color='blue'><b>Always wear safety gear and consult a field manual before operation.</b></font><br>"
|
||||
if(!locked)
|
||||
dat += "<A href='?src=\ref[src];lock=1'>Lock console</A><br>"
|
||||
else
|
||||
dat += "<br>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh console</A><br>"
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close console</A>"
|
||||
user << browse(dat, "window=suspension;size=500x400")
|
||||
onclose(user, "suspension")
|
||||
|
||||
/obj/machinery/suspension_gen/Topic(href, href_list)
|
||||
..()
|
||||
usr.set_machine(src)
|
||||
|
||||
if(href_list["toggle_field"])
|
||||
if(!suspension_field)
|
||||
if(cell.charge > 0)
|
||||
if(anchored)
|
||||
activate()
|
||||
if(cell.use(power_use))
|
||||
var/turf/T = get_turf(suspension_field)
|
||||
for(var/mob/living/M in T)
|
||||
if(cell.use(power_use))
|
||||
M.Weaken(3)
|
||||
if(prob(5))
|
||||
to_chat(M, "<span class='warning'>[pick("You feel tingly","You feel like floating","It is hard to speak","You can barely move")].</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You are unable to activate [src] until it is properly secured on the ground.</span>")
|
||||
deactivate()
|
||||
|
||||
for(var/obj/item/I in T)
|
||||
if(!suspension_field.contents.len)
|
||||
suspension_field.icon_state = "energynet"
|
||||
suspension_field.overlays += "shield2"
|
||||
I.forceMove(suspension_field)
|
||||
else
|
||||
deactivate()
|
||||
else if(href_list["insertcard"])
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
if (istype(I, /obj/item/weapon/card))
|
||||
usr.drop_item()
|
||||
I.loc = src
|
||||
auth_card = I
|
||||
if(attempt_unlock(I, usr))
|
||||
to_chat(usr, "<span class='info'>You insert [I], the console flashes \'<i>Access granted.</i>\'</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You insert [I], the console flashes \'<i>Access denied.</i>\'</span>")
|
||||
else if(href_list["ejectcard"])
|
||||
if(auth_card)
|
||||
if(ishuman(usr))
|
||||
auth_card.loc = usr.loc
|
||||
if(!usr.get_active_hand())
|
||||
usr.put_in_hands(auth_card)
|
||||
auth_card = null
|
||||
else
|
||||
auth_card.loc = loc
|
||||
auth_card = null
|
||||
else if(href_list["lock"])
|
||||
locked = 1
|
||||
else if(href_list["close"])
|
||||
usr.unset_machine()
|
||||
usr << browse(null, "window=suspension")
|
||||
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/suspension_gen/attack_hand(var/mob/user)
|
||||
if(!panel_open)
|
||||
interact(user)
|
||||
else if(cell)
|
||||
cell.loc = loc
|
||||
cell.add_fingerprint(user)
|
||||
cell.update_icon()
|
||||
if(panel_open)
|
||||
if(cell)
|
||||
to_chat(user, "<span class='notice'>You remove [cell].</span>")
|
||||
cell.forceMove(loc)
|
||||
cell.add_fingerprint(user)
|
||||
cell.update_icon()
|
||||
|
||||
icon_state = "suspension0"
|
||||
cell = null
|
||||
to_chat(user, "<span class='info'>You remove the power cell</span>")
|
||||
icon_state = "suspension0"
|
||||
cell = null
|
||||
return
|
||||
|
||||
/obj/machinery/suspension_gen/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/suspension_gen/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "XenoarchSuspension", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/suspension_gen/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["cell"] = cell
|
||||
data["cellCharge"] = cell?.charge
|
||||
data["cellMaxCharge"] = cell?.maxcharge
|
||||
|
||||
data["locked"] = locked
|
||||
data["suspension_field"] = suspension_field
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/suspension_gen/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("toggle_field")
|
||||
if(locked)
|
||||
return
|
||||
if(!suspension_field)
|
||||
if(cell.charge > 0)
|
||||
if(anchored)
|
||||
activate()
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You are unable to activate [src] until it is properly secured on the ground.</span>")
|
||||
else
|
||||
deactivate()
|
||||
return TRUE
|
||||
|
||||
if("lock")
|
||||
if(allowed(usr))
|
||||
locked = !locked
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/suspension_gen/attackby(obj/item/W, mob/user)
|
||||
if(!locked && !suspension_field && default_deconstruction_screwdriver(user, W))
|
||||
return
|
||||
else if(W.is_wrench())
|
||||
@@ -134,45 +99,36 @@
|
||||
else
|
||||
anchored = 1
|
||||
playsound(src, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='info'>You wrench the stabilising legs [anchored ? "into place" : "up against the body"].</span>")
|
||||
to_chat(user, "<span class='notice'>You wrench the stabilising legs [anchored ? "into place" : "up against the body"].</span>")
|
||||
if(anchored)
|
||||
desc = "It is resting securely on four stubby legs."
|
||||
else
|
||||
desc = "It has stubby legs bolted up against it's body for stabilising."
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You are unable to secure [src] while it is active!</span>")
|
||||
else if (istype(W, /obj/item/weapon/cell))
|
||||
to_chat(user, "<span class='warning'>You are unable to unsecure [src] while it is active!</span>")
|
||||
else if(istype(W, /obj/item/weapon/cell))
|
||||
if(panel_open)
|
||||
if(cell)
|
||||
to_chat(user, "<span class='warning'>There is a power cell already installed.</span>")
|
||||
else
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
return
|
||||
if(user.unEquip(W))
|
||||
W.forceMove(src)
|
||||
cell = W
|
||||
to_chat(user, "<span class='info'>You insert the power cell.</span>")
|
||||
to_chat(user, "<span class='notice'>You insert [cell].</span>")
|
||||
icon_state = "suspension1"
|
||||
else if(istype(W, /obj/item/weapon/card))
|
||||
var/obj/item/weapon/card/I = W
|
||||
if(!auth_card)
|
||||
if(attempt_unlock(I, user))
|
||||
to_chat(user, "<span class='info'>You swipe [I], the console flashes \'<i>Access granted.</i>\'</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You swipe [I], console flashes \'<i>Access denied.</i>\'</span>")
|
||||
else if(istype(W, /obj/item/weapon/card/emag))
|
||||
return W.resolve_attackby(src, user)
|
||||
else
|
||||
if(check_access(W))
|
||||
locked = !locked
|
||||
to_chat(user, "<span class='notice'>You [locked ? "lock" : "unlock"] [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Remove [auth_card] first.</span>")
|
||||
|
||||
/obj/machinery/suspension_gen/proc/attempt_unlock(var/obj/item/weapon/card/C, var/mob/user)
|
||||
if(!panel_open)
|
||||
if(istype(C, /obj/item/weapon/card/emag))
|
||||
C.resolve_attackby(src, user)
|
||||
else if(istype(C, /obj/item/weapon/card/id) && check_access(C))
|
||||
locked = 0
|
||||
if(!locked)
|
||||
return 1
|
||||
to_chat(user, "<span class='warning'>[src] flashes \'<i>Access denied.</i>\'</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/suspension_gen/emag_act(var/remaining_charges, var/mob/user)
|
||||
if(cell.charge > 0 && locked)
|
||||
locked = 0
|
||||
if(locked)
|
||||
locked = FALSE
|
||||
return 1
|
||||
|
||||
//checks for whether the machine can be activated or not should already have occurred by this point
|
||||
@@ -181,11 +137,11 @@
|
||||
var/collected = 0
|
||||
|
||||
for(var/mob/living/M in T)
|
||||
M.weakened += 5
|
||||
M.visible_message("<font color='blue'>[bicon(M)] [M] begins to float in the air!</font>","You feel tingly and light, but it is difficult to move.")
|
||||
M.Weaken(5)
|
||||
M.visible_message("<span class='notice'>[bicon(M)] [M] begins to float in the air!</span>","You feel tingly and light, but it is difficult to move.")
|
||||
|
||||
suspension_field = new(T)
|
||||
src.visible_message("<font color='blue'>[bicon(src)] [src] activates with a low hum.</font>")
|
||||
visible_message("<span class='notice'>[bicon(src)] [src] activates with a low hum.</span>")
|
||||
icon_state = "suspension3"
|
||||
|
||||
for(var/obj/item/I in T)
|
||||
@@ -195,7 +151,7 @@
|
||||
if(collected)
|
||||
suspension_field.icon_state = "energynet"
|
||||
suspension_field.overlays += "shield2"
|
||||
src.visible_message("<font color='blue'>[bicon(suspension_field)] [suspension_field] gently absconds [collected > 1 ? "something" : "several things"].</font>")
|
||||
visible_message("<span class='notice'>[bicon(suspension_field)] [suspension_field] gently absconds [collected > 1 ? "something" : "several things"].</span>")
|
||||
else
|
||||
if(istype(T,/turf/simulated/mineral) || istype(T,/turf/simulated/wall))
|
||||
suspension_field.icon_state = "shieldsparkles"
|
||||
@@ -207,10 +163,10 @@
|
||||
var/turf/T = get_turf(suspension_field)
|
||||
|
||||
for(var/mob/living/M in T)
|
||||
to_chat(M, "<span class='info'>You no longer feel like floating.</span>")
|
||||
to_chat(M, "<span class='notice'>You no longer feel like floating.</span>")
|
||||
M.Weaken(3)
|
||||
|
||||
src.visible_message("<font color='blue'>[bicon(src)] [src] deactivates with a gentle shudder.</font>")
|
||||
visible_message("<span class='notice'>[bicon(src)] [src] deactivates with a gentle shudder.</span>")
|
||||
qdel(suspension_field)
|
||||
suspension_field = null
|
||||
icon_state = "suspension2"
|
||||
@@ -225,9 +181,9 @@
|
||||
set category = "Object"
|
||||
|
||||
if(anchored)
|
||||
to_chat(usr, "<font color='red'>You cannot rotate [src], it has been firmly fixed to the floor.</font>")
|
||||
to_chat(usr, "<span class='warning'>You cannot rotate [src], it has been firmly fixed to the floor.</span>")
|
||||
return
|
||||
src.set_dir(turn(src.dir, 90))
|
||||
set_dir(turn(dir, 90))
|
||||
|
||||
/obj/machinery/suspension_gen/verb/rotate_clockwise()
|
||||
set src in view(1)
|
||||
@@ -235,9 +191,9 @@
|
||||
set category = "Object"
|
||||
|
||||
if(anchored)
|
||||
to_chat(usr, "<font color='red'>You cannot rotate [src], it has been firmly fixed to the floor.</font>")
|
||||
to_chat(usr, "<span class='warning'>You cannot rotate [src], it has been firmly fixed to the floor.</span>")
|
||||
return
|
||||
src.set_dir(turn(src.dir, 270))
|
||||
set_dir(turn(dir, 270))
|
||||
|
||||
/obj/effect/suspension_field
|
||||
name = "energy field"
|
||||
|
||||
@@ -154,66 +154,69 @@
|
||||
to_chat(user, "<span class='notice'>[bicon(src)] [src] pings [pick("madly","wildly","excitedly","crazily")]!</span>")
|
||||
|
||||
/obj/item/device/depth_scanner/attack_self(var/mob/living/user)
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/item/device/depth_scanner/interact(var/mob/user as mob)
|
||||
var/dat = "<b>Coordinates with positive matches</b><br>"
|
||||
/obj/item/device/depth_scanner/tgui_state(mob/user)
|
||||
return GLOB.tgui_deep_inventory_state
|
||||
|
||||
dat += "<A href='?src=\ref[src];clear=0'>== Clear all ==</a><br>"
|
||||
/obj/item/device/depth_scanner/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "XenoarchDepthScanner", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/device/depth_scanner/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
data["current"] = list()
|
||||
if(current)
|
||||
dat += "Time: [current.time]<br>"
|
||||
dat += "Coords: [current.coords]<br>"
|
||||
dat += "Anomaly depth: [current.depth] cm<br>"
|
||||
dat += "Anomaly size: [current.clearance] cm<br>"
|
||||
dat += "Dissonance spread: [current.dissonance_spread]<br>"
|
||||
data["current"] = list(
|
||||
"time" = current.time,
|
||||
"coords" = current.coords,
|
||||
"depth" = current.depth,
|
||||
"clearance" = current.clearance,
|
||||
"dissonance_spread" = current.dissonance_spread,
|
||||
"index" = current.record_index,
|
||||
)
|
||||
data["current"]["material"] = "Unknown"
|
||||
var/index = responsive_carriers.Find(current.material)
|
||||
if(index > 0 && index <= finds_as_strings.len)
|
||||
dat += "Anomaly material: [finds_as_strings[index]]<br>"
|
||||
else
|
||||
dat += "Anomaly material: Unknown<br>"
|
||||
dat += "<A href='?src=\ref[src];clear=[current.record_index]'>clear entry</a><br>"
|
||||
else
|
||||
dat += "Select an entry from the list<br>"
|
||||
dat += "<br><br><br><br>"
|
||||
dat += "<hr>"
|
||||
if(positive_locations.len)
|
||||
for(var/index = 1 to positive_locations.len)
|
||||
var/datum/depth_scan/D = positive_locations[index]
|
||||
dat += "<A href='?src=\ref[src];select=[index]'>[D.time], coords: [D.coords]</a><br>"
|
||||
else
|
||||
dat += "No entries recorded."
|
||||
if(index > 0 && index <= LAZYLEN(finds_as_strings))
|
||||
data["current"]["material"] = finds_as_strings[index]
|
||||
|
||||
dat += "<hr>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh</a><br>"
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close</a><br>"
|
||||
user << browse(dat,"window=depth_scanner;size=300x500")
|
||||
onclose(user, "depth_scanner")
|
||||
var/list/plocs = list()
|
||||
data["positive_locations"] = plocs
|
||||
for(var/i in 1 to LAZYLEN(positive_locations))
|
||||
var/datum/depth_scan/D = positive_locations[i]
|
||||
plocs.Add(list(list(
|
||||
"index" = i,
|
||||
"time" = D.time,
|
||||
"coords" = D.coords,
|
||||
)))
|
||||
|
||||
/obj/item/device/depth_scanner/Topic(href, href_list)
|
||||
..()
|
||||
usr.set_machine(src)
|
||||
return data
|
||||
|
||||
if(href_list["select"])
|
||||
var/index = text2num(href_list["select"])
|
||||
if(index && index <= positive_locations.len)
|
||||
current = positive_locations[index]
|
||||
else if(href_list["clear"])
|
||||
var/index = text2num(href_list["clear"])
|
||||
if(index)
|
||||
if(index <= positive_locations.len)
|
||||
var/datum/depth_scan/D = positive_locations[index]
|
||||
positive_locations.Remove(D)
|
||||
qdel(D)
|
||||
else
|
||||
//GC will hopefully pick them up before too long
|
||||
positive_locations = list()
|
||||
qdel(current)
|
||||
else if(href_list["close"])
|
||||
usr.unset_machine()
|
||||
usr << browse(null, "window=depth_scanner")
|
||||
/obj/item/device/depth_scanner/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
updateSelfDialog()
|
||||
switch(action)
|
||||
if("select")
|
||||
var/index = text2num(params["select"])
|
||||
if(index && index <= LAZYLEN(positive_locations))
|
||||
current = positive_locations[index]
|
||||
return TRUE
|
||||
if("clear")
|
||||
var/index = text2num(params["clear"])
|
||||
if(index)
|
||||
if(index <= LAZYLEN(positive_locations))
|
||||
var/datum/depth_scan/D = positive_locations[index]
|
||||
positive_locations.Remove(D)
|
||||
qdel(D)
|
||||
current = null
|
||||
else
|
||||
QDEL_LIST_NULL(positive_locations)
|
||||
QDEL_NULL(current)
|
||||
return TRUE
|
||||
|
||||
/obj/item/device/beacon_locator
|
||||
name = "locater device"
|
||||
@@ -273,43 +276,46 @@
|
||||
else
|
||||
icon_state = "pinoff"
|
||||
|
||||
/obj/item/device/beacon_locator/attack_self(var/mob/user as mob)
|
||||
return src.interact(user)
|
||||
/obj/item/device/beacon_locator/attack_self(mob/user)
|
||||
return tgui_interact(user)
|
||||
|
||||
/obj/item/device/beacon_locator/interact(var/mob/user as mob)
|
||||
var/dat = "<b>Radio frequency tracker</b><br>"
|
||||
dat += {"
|
||||
<A href='byond://?src=\ref[src];reset_tracking=1'>Reset tracker</A><BR>
|
||||
Frequency:
|
||||
<A href='byond://?src=\ref[src];freq=-10'>-</A>
|
||||
<A href='byond://?src=\ref[src];freq=-2'>-</A>
|
||||
[format_frequency(frequency)]
|
||||
<A href='byond://?src=\ref[src];freq=2'>+</A>
|
||||
<A href='byond://?src=\ref[src];freq=10'>+</A><BR>
|
||||
"}
|
||||
/obj/item/device/beacon_locator/tgui_state(mob/user)
|
||||
return GLOB.tgui_inventory_state
|
||||
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close</a><br>"
|
||||
user << browse(dat,"window=locater;size=300x150")
|
||||
onclose(user, "locater")
|
||||
/obj/item/device/beacon_locator/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "BeaconLocator", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/device/beacon_locator/Topic(href, href_list)
|
||||
..()
|
||||
usr.set_machine(src)
|
||||
/obj/item/device/beacon_locator/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
if(href_list["reset_tracking"])
|
||||
scan_ticks = 1
|
||||
target_radio = null
|
||||
else if(href_list["freq"])
|
||||
var/new_frequency = (frequency + text2num(href_list["freq"]))
|
||||
if (frequency < 1200 || frequency > 1600)
|
||||
new_frequency = sanitize_frequency(new_frequency, 1499)
|
||||
frequency = new_frequency
|
||||
data["scan_ticks"] = scan_ticks
|
||||
data["degrees"] = null
|
||||
if(target_radio)
|
||||
data["degrees"] = round(Get_Angle(get_turf(src), get_turf(target_radio)))
|
||||
|
||||
else if(href_list["close"])
|
||||
usr.unset_machine()
|
||||
usr << browse(null, "window=locater")
|
||||
data["rawfreq"] = frequency
|
||||
data["minFrequency"] = RADIO_LOW_FREQ
|
||||
data["maxFrequency"] = RADIO_HIGH_FREQ
|
||||
|
||||
updateSelfDialog()
|
||||
return data
|
||||
|
||||
/obj/item/device/beacon_locator/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("reset_tracking")
|
||||
scan_ticks = 1
|
||||
target_radio = null
|
||||
return TRUE
|
||||
if("setFrequency")
|
||||
var/new_frequency = (text2num(params["freq"]))
|
||||
new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
|
||||
frequency = new_frequency
|
||||
return TRUE
|
||||
|
||||
/obj/item/device/xenoarch_multi_tool
|
||||
name = "xenoarcheology multitool"
|
||||
@@ -330,7 +336,7 @@
|
||||
depth_scanner = new/obj/item/device/depth_scanner(src)
|
||||
|
||||
/obj/item/device/xenoarch_multi_tool/attack_self(var/mob/living/user)
|
||||
depth_scanner.interact(user)
|
||||
depth_scanner.tgui_interact(user)
|
||||
|
||||
/obj/item/device/xenoarch_multi_tool/verb/swap_settings(var/mob/living/user)
|
||||
set name = "Swap Functionality"
|
||||
|
||||
@@ -4681,7 +4681,7 @@
|
||||
"bMa" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled,/area/assembly/robotics)
|
||||
"bMb" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/simulated/floor/tiled,/area/assembly/robotics)
|
||||
"bMc" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/mecha_part_fabricator,/turf/simulated/floor/tiled,/area/assembly/robotics)
|
||||
"bMd" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/pros_fabricator,/turf/simulated/floor/tiled,/area/assembly/robotics)
|
||||
"bMd" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/machinery/mecha_part_fabricator/pros,/turf/simulated/floor/tiled,/area/assembly/robotics)
|
||||
"bMe" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/floor_decal/industrial/warning{dir = 1},/obj/structure/table/standard,/obj/item/device/robotanalyzer,/obj/item/device/robotanalyzer,/obj/item/device/mmi/digital/robot,/turf/simulated/floor/tiled,/area/assembly/robotics)
|
||||
"bMf" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/simulated/floor/tiled,/area/assembly/robotics)
|
||||
"bMg" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/simulated/floor/tiled,/area/assembly/robotics)
|
||||
|
||||
@@ -1080,7 +1080,7 @@
|
||||
/turf/simulated/floor/tiled/white,
|
||||
/area/ship/aro/centralarea)
|
||||
"cr" = (
|
||||
/obj/machinery/pros_fabricator{
|
||||
/obj/machinery/mecha_part_fabricator/pros{
|
||||
req_access = list()
|
||||
},
|
||||
/turf/simulated/floor/tiled/techmaint,
|
||||
|
||||
@@ -6192,7 +6192,7 @@
|
||||
/turf/simulated/floor/tiled/steel_grid,
|
||||
/area/mothership/rnd)
|
||||
"mm" = (
|
||||
/obj/machinery/pros_fabricator,
|
||||
/obj/machinery/mecha_part_fabricator/pros,
|
||||
/turf/simulated/floor/tiled/steel_grid,
|
||||
/area/mothership/rnd)
|
||||
"mn" = (
|
||||
|
||||
@@ -5242,7 +5242,7 @@
|
||||
"bWP" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/machinery/light_switch{pixel_x = -36},/obj/structure/cable/green,/turf/simulated/floor/tiled/white,/area/assembly/robotics)
|
||||
"bWQ" = (/obj/machinery/mecha_part_fabricator,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/assembly/robotics)
|
||||
"bWR" = (/obj/effect/floor_decal/industrial/outline/yellow,/obj/structure/table/steel_reinforced,/obj/item/device/robotanalyzer,/obj/item/device/robotanalyzer,/obj/item/device/mmi/digital/robot,/turf/simulated/floor/tiled,/area/assembly/robotics)
|
||||
"bWS" = (/obj/machinery/pros_fabricator,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/assembly/robotics)
|
||||
"bWS" = (/obj/machinery/mecha_part_fabricator/pros,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/assembly/robotics)
|
||||
"bWT" = (/obj/machinery/camera/network/research{c_tag = "SCI - Robotics"; dir = 1},/turf/simulated/floor/tiled/white,/area/assembly/robotics)
|
||||
"bWU" = (/obj/effect/floor_decal/industrial/warning{dir = 8},/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor/tiled/techfloor,/area/assembly/robotics)
|
||||
"bWV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled/techfloor,/area/assembly/robotics)
|
||||
|
||||
@@ -1983,7 +1983,7 @@
|
||||
/turf/unsimulated/floor/steel,
|
||||
/area/centcom/control)
|
||||
"dT" = (
|
||||
/obj/machinery/pros_fabricator,
|
||||
/obj/machinery/mecha_part_fabricator/pros,
|
||||
/turf/unsimulated/floor/steel,
|
||||
/area/centcom/control)
|
||||
"dU" = (
|
||||
|
||||
@@ -215,7 +215,7 @@
|
||||
/turf/simulated/floor/tiled/steel_dirty,
|
||||
/area/submap/virgo2/Lab1)
|
||||
"J" = (
|
||||
/obj/machinery/pros_fabricator,
|
||||
/obj/machinery/mecha_part_fabricator/pros,
|
||||
/turf/simulated/floor/tiled/steel_dirty,
|
||||
/area/submap/virgo2/Lab1)
|
||||
"K" = (
|
||||
|
||||
@@ -586,7 +586,7 @@
|
||||
/turf/simulated/floor/tiled/techfloor/virgo2,
|
||||
/area/submap/virgo2/Rockybase)
|
||||
"cb" = (
|
||||
/obj/machinery/pros_fabricator,
|
||||
/obj/machinery/mecha_part_fabricator/pros,
|
||||
/turf/simulated/floor/tiled/techfloor/virgo2,
|
||||
/area/submap/virgo2/Rockybase)
|
||||
"cc" = (
|
||||
|
||||
@@ -215,7 +215,7 @@
|
||||
/turf/simulated/floor/tiled/steel_dirty,
|
||||
/area/submap/Lab1)
|
||||
"K" = (
|
||||
/obj/machinery/pros_fabricator,
|
||||
/obj/machinery/mecha_part_fabricator/pros,
|
||||
/turf/simulated/floor/tiled/steel_dirty,
|
||||
/area/submap/Lab1)
|
||||
"L" = (
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
"cL" = (/mob/living/simple_mob/mechanical/mecha/combat/gygax/dark/advanced{faction = "malf_drone"},/turf/simulated/floor/tiled,/area/submap/Rockybase)
|
||||
"cM" = (/obj/machinery/drone_fabricator{fabricator_tag = "Unknown"},/turf/simulated/floor/tiled,/area/submap/Rockybase)
|
||||
"cN" = (/obj/machinery/mecha_part_fabricator,/turf/simulated/floor/tiled,/area/submap/Rockybase)
|
||||
"cO" = (/obj/machinery/pros_fabricator,/turf/simulated/floor/tiled,/area/submap/Rockybase)
|
||||
"cO" = (/obj/machinery/mecha_part_fabricator/pros,/turf/simulated/floor/tiled,/area/submap/Rockybase)
|
||||
"cP" = (/obj/structure/table/standard,/obj/item/mecha_parts/mecha_equipment/repair_droid,/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive,/turf/simulated/floor/tiled,/area/submap/Rockybase)
|
||||
"cQ" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/tiled,/area/submap/Rockybase)
|
||||
"cR" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/mob/living/simple_mob/mechanical/combat_drone/lesser,/turf/simulated/floor/tiled,/area/submap/Rockybase)
|
||||
|
||||
@@ -17687,15 +17687,15 @@
|
||||
/turf/simulated/floor/plating,
|
||||
/area/maintenance/lower/atmos)
|
||||
"aId" = (
|
||||
/obj/machinery/pros_fabricator{
|
||||
/obj/machinery/mecha_part_fabricator/pros{
|
||||
desc = "A machine used for construction of legit prosthetics. You weren't sure if cardboard was considered an engineering material until now.";
|
||||
dir = 4;
|
||||
emagged = 0;
|
||||
mat_efficiency = 0.9;
|
||||
component_coeff = 0.9;
|
||||
name = "Legitimate Prosthetics Fabricator";
|
||||
req_access = list();
|
||||
res_max_amount = 150000;
|
||||
speed = 0.2
|
||||
time_coeff = 0.2
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/maintenance/lower/atmos)
|
||||
|
||||
@@ -16760,7 +16760,7 @@
|
||||
/turf/simulated/floor/tiled/steel_grid,
|
||||
/area/assembly/robotics)
|
||||
"aCv" = (
|
||||
/obj/machinery/pros_fabricator{
|
||||
/obj/machinery/mecha_part_fabricator/pros{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/reagent_dispensers/acid{
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
<!--
|
||||
Title: Bioballistic Delivery System UI
|
||||
Used In File(s): \code\modules\hydroponics\seed_machines.dm
|
||||
-->
|
||||
|
||||
{{if data.activity}}
|
||||
Scanning...
|
||||
{{else}}
|
||||
<h3>Buffered Genetic Data</h3>
|
||||
{{if data.disk}}
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Source:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.sourceName}}
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Gene decay:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{if data.degradation <= 100}}
|
||||
{{:data.degradation}}%
|
||||
{{else}}
|
||||
<font = '#FF0000'><b>FURTHER AMENDMENTS NONVIABLE</b></font>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Locus:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.locus}}
|
||||
</div>
|
||||
{{:helper.link('Eject Disk', 'circle-arrow-e', {'eject_disk' : 1}, null)}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="notice">No disk loaded.</div>
|
||||
{{/if}}
|
||||
<h3>Loaded Material</h3>
|
||||
{{if data.loaded}}
|
||||
<div class = "item">
|
||||
<div class = "itemLabel">
|
||||
Target:
|
||||
</div>
|
||||
<div class = "itemContent">
|
||||
{{:data.loaded}}
|
||||
</div>
|
||||
{{if data.degradation <= 100}}
|
||||
{{:helper.link('Apply Gene Mods', 'gear', {'apply_gene' : 1}, null)}}
|
||||
{{/if}}
|
||||
{{:helper.link('Eject Target', 'circle-arrow-e', {'eject_packet' : 1}, null)}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="notice">No target seed packet loaded</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
@@ -1,73 +0,0 @@
|
||||
<!--
|
||||
Title: Lysis-isolation Centrifuge UI
|
||||
Used In File(s): \code\modules\hydroponics\seed_machines.dm
|
||||
-->
|
||||
|
||||
{{if data.activity}}
|
||||
Scanning...
|
||||
{{else}}
|
||||
<h3>Buffered Genetic Data</h3>
|
||||
{{if data.hasGenetics}}
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Source:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.sourceName}}
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Gene decay:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.degradation}}%
|
||||
</div>
|
||||
</div>
|
||||
{{if data.disk}}
|
||||
{{for data.geneMasks}}
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
{{:value.mask}}
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link('Extract', 'circle-arrow-s', {'get_gene' : value.tag}, null)}}
|
||||
</div>
|
||||
</div>
|
||||
{{empty}}
|
||||
<div class="notice">Data error. Genetic record corrupt.</div>
|
||||
{{/for}}
|
||||
<br>
|
||||
<div class="item">
|
||||
{{:helper.link('Eject Loaded Disk', 'circle-arrow-e', {'eject_disk' : 1}, null)}}
|
||||
{{:helper.link('Clear Genetic Buffer', 'gear', {'clear_buffer' : 1}, null)}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="notice">No disk inserted.</div>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<div class="notice">No data buffered.</div>
|
||||
{{if data.disk}}
|
||||
<br>
|
||||
<div class="item">
|
||||
{{:helper.link('Eject Loaded Disk', 'circle-arrow-e', {'eject_disk' : 1}, null)}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="notice">No disk inserted.</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
<h3>Loaded Material</h3>
|
||||
{{if data.loaded}}
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Packet loaded:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.loaded}}
|
||||
</div>
|
||||
<div class="item">
|
||||
{{:helper.link('Process Genome', 'gear', {'scan_genome' : 1}, null)}}{{:helper.link('Eject Packet', 'circle-arrow-e', {'eject_packet' : 1}, null)}}
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="notice">No seeds loaded.</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
@@ -1,185 +0,0 @@
|
||||
<!--
|
||||
Title: Radiometric Scanner UI
|
||||
Used In File(s): \code\modules\research\xenoarchaeology\machinery\geosample_scanner.dm
|
||||
-->
|
||||
|
||||
<h3>Machine Status</h3>
|
||||
<div class="item">
|
||||
<div class="itemContent" style="width: 20%;">
|
||||
{{:helper.link(data.scanning ? 'Halt Scan' : 'Begin Scan', 'signal-diag', {'scanItem' : 1}, null)}}
|
||||
</div>
|
||||
<div class="itemContent" style="width: 20%;">
|
||||
{{:helper.link('Eject item', 'eject', {'ejectItem' : 1}, (data.scanned_item && !data.scanning) ? null : 'disabled')}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="statusDisplay">
|
||||
<div class="line">
|
||||
<div class="statusLabel">Item:</div>
|
||||
<div class="statusValue">
|
||||
{{if data.scanned_item}}
|
||||
<span class="good">{{:data.scanned_item}}</span>
|
||||
{{else}}
|
||||
<span class="bad">No item inserted</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="statusLabel">Heuristic analysis:</div>
|
||||
<div class="statusValue">
|
||||
{{if data.scanned_item_desc}}
|
||||
<span class="average">{{:data.scanned_item_desc}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Scanner</h3>
|
||||
<div class="item">
|
||||
<div class="itemLabel" style="width: 21%;">Scan progress:</div>
|
||||
<div class="itemContent" style="width: 35%;">
|
||||
{{:helper.displayBar(data.scan_progress, 0, 100, 'good')}}
|
||||
{{:data.scan_progress}} %
|
||||
</div>
|
||||
<div class="itemContent" style="width: 44%;">
|
||||
{{if data.scan_progress >= 100}}
|
||||
<span class="notice" style="width: 100%;">Scan completed successfully.</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel" style="width: 21%;">Vacuum seal integrity:</div>
|
||||
<div class="itemContent" style="width: 35%;">
|
||||
{{:helper.displayBar(data.scanner_seal_integrity, 0, 100, ((data.scanner_seal_integrity < 66) ? ((data.scanner_seal_integrity < 33) ? 'bad' : 'average') : 'good'))}}
|
||||
{{:data.scanner_seal_integrity}} %
|
||||
</div>
|
||||
<div class="itemContent" style="width: 44%;">
|
||||
{{if data.scanner_seal_integrity < 25}}
|
||||
<span class="notice">Warning! Vacuum seal breach will result in scan failure!</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>MASER</h3>
|
||||
<div class="item">
|
||||
<div class="itemLabel" style="width: 21%;">MASER Efficiency:</div>
|
||||
<div class="itemContent" style="width: 35%;">
|
||||
{{:helper.displayBar(data.maser_efficiency, 1, 100, ((data.maser_efficiency < 66) ? ((data.maser_efficiency) < 33 ? 'bad' : 'average') : 'good'))}}
|
||||
{{:data.maser_efficiency}} %
|
||||
</div>
|
||||
<div class="itemContent" style="width: 44%;">
|
||||
{{if data.maser_efficiency < 50}}
|
||||
<span class="notice">Match wavelengths to progress the scan.</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel" style="width: 21%;">Optimal Wavelength:</div>
|
||||
<div class="itemContent" style="width: 35%;">
|
||||
{{:helper.displayBar(data.optimal_wavelength, 1, 10000, 'good')}}
|
||||
{{:data.optimal_wavelength}} MHz
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel" style="width: 21%;">Current Wavelength:</div>
|
||||
<div class="itemContent" style="width: 35%;">
|
||||
{{:helper.displayBar(data.maser_wavelength, 1, 10000, 'good')}}
|
||||
{{:data.maser_wavelength}} MHz
|
||||
</div>
|
||||
<div class="itemContent" style="text-align:left; width: 22%;">
|
||||
{{:helper.link('-2 GHz', null, {'maserWavelength' : -2}, null)}}
|
||||
{{:helper.link('-1 GHz', null, {'maserWavelength' : -1}, null)}}
|
||||
{{:helper.link('-0.5 GHz', null, {'maserWavelength' : -0.5}, null)}}
|
||||
</div>
|
||||
<div class="itemContent" style="text-align:right; width: 22%;">
|
||||
{{:helper.link('+0.5 GHz', null, {'maserWavelength' : 0.5}, null)}}
|
||||
{{:helper.link('+1 GHz', null, {'maserWavelength' : 1}, null)}}
|
||||
{{:helper.link('+2 GHz', null, {'maserWavelength' : 2}, null)}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Environment / Internal</h3>
|
||||
<div class="item">
|
||||
<div class="itemLabel" style="width: 21%;">Centrifuge speed:</div>
|
||||
<div class="itemContent" style="width: 35%;">
|
||||
{{:helper.displayBar(data.scanner_rpm, 0, 1000, 'good')}}
|
||||
{{:data.scanner_rpm}} RPM
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel" style="width: 21%;">Internal temperature:</div>
|
||||
<div class="itemContent" style="width: 35%;">
|
||||
{{:helper.displayBar(data.scanner_temperature, 0, 1273, (data.scanner_temperature > 250 ? (data.scanner_temperature > 1000 ? 'bad' : 'average') : 'good'))}}
|
||||
{{:data.scanner_temperature}} K
|
||||
</div>
|
||||
<div class="itemContent" style="width: 44%;">
|
||||
{{if data.scanner_temperature > 1000}}
|
||||
<span class="notice" style="width: 100%;">Warning! Exceeding 1200K will result in scan failure!</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Radiation</h3>
|
||||
<div class="item">
|
||||
<div class="itemLabel" style="width: 21%;">Ambient radiation:</div>
|
||||
<div class="itemContent" style="width: 35%;">
|
||||
{{:helper.displayBar(data.radiation, 0, 100, ((data.radiation > 15) ? ((data.radiation > 65) ? 'bad' : 'average') : 'good'))}}
|
||||
{{:data.radiation}} mSv
|
||||
</div>
|
||||
<div class="itemContent" style="width: 44%;">
|
||||
{{:helper.link(data.rad_shield_on ? 'Disable Radiation Shielding' : 'Enable Radiation Shielding', 'radiation', {'toggle_rad_shield' : 1}, null)}}
|
||||
{{if data.rad_shield_on}}
|
||||
<span class="notice" style="width: 100%;">Shield blocking scanner.</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Cooling</h3>
|
||||
<div class="item">
|
||||
<div class="itemLabel" style="width: 21%;">Coolant remaining:</div>
|
||||
<div class="itemContent" style="width: 35%;">
|
||||
{{:helper.displayBar(data.unused_coolant_per, 0, 100, ((data.unused_coolant_per < 66) ? ((data.unused_coolant_per < 33) ? 'bad' : 'average') : 'good'))}}
|
||||
{{:data.unused_coolant_abs}} u
|
||||
</div>
|
||||
<div class="itemContent" style="width: 44%;">
|
||||
{{if data.unused_coolant_per < 20}}
|
||||
<span class="notice" style="width: 100%;">Warning! Coolant stocks low!</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel" style="width: 21%;">Coolant flow rate:</div>
|
||||
<div class="itemContent" style="width: 35%;">
|
||||
{{:helper.displayBar(data.coolant_usage_rate, 0, 10, 'good')}}
|
||||
{{:data.coolant_usage_rate}} u/s
|
||||
</div>
|
||||
<div class="itemContent" style="text-align:left; width: 22%;">
|
||||
{{:helper.link('Min u/s', null, {'coolantRate' : -10}, null)}}
|
||||
{{:helper.link('-3 u/s', null, {'coolantRate' : -3}, null)}}
|
||||
{{:helper.link('-1 u/s', null, {'coolantRate' : -1}, null)}}
|
||||
</div>
|
||||
<div class="itemContent" style="text-align:right; width: 22%;">
|
||||
{{:helper.link('+1 u/s', null, {'coolantRate' : 1}, null)}}
|
||||
{{:helper.link('+3 u/s', null, {'coolantRate' : 3}, null)}}
|
||||
{{:helper.link('Max u/s', null, {'coolantRate' : 10}, null)}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel" style="width: 21%;">Coolant purity:</div>
|
||||
<div class="itemContent" style="width: 35%;">
|
||||
{{:helper.displayBar(data.coolant_purity, 0, 100, ((data.coolant_purity < 66) ? ((data.coolant_purity < 33) ? 'bad' : 'average') : 'good'))}}
|
||||
{{:data.coolant_purity}} %
|
||||
</div>
|
||||
<div class="itemContent" style="width: 44%;">
|
||||
{{if data.coolant_purity < 0.5}}
|
||||
<span class="notice" style="width: 100%;">Warning! Check coolant for contaminants!</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Latest Results</h3>
|
||||
<div class="statusDisplay">
|
||||
<div class="line">
|
||||
<span class="highlight">{{:data.last_scan_data}}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,91 +0,0 @@
|
||||
<div style="float: left; width: 60%;">
|
||||
<div class="item">
|
||||
{{:helper.link("Sync", null, {'sync' : 1})}}
|
||||
{{:data.sync}}
|
||||
</div>
|
||||
<hr style="width: 90%;">
|
||||
{{if data.species_types}}
|
||||
<div class="item">
|
||||
{{for data.species_types}}
|
||||
{{:helper.link(value, null, {'species' : value}, value == data.species ? 'selected' : null)}}
|
||||
{{/for}}
|
||||
</div>
|
||||
<hr style="width: 90%;">
|
||||
{{/if}}
|
||||
{{if data.manufacturers}}
|
||||
<div class="item">
|
||||
{{for data.manufacturers}}
|
||||
{{:helper.link(value.company, null, {'manufacturer' : value.id}, value.id == data.manufacturer ? 'selected' : null)}}
|
||||
{{/for}}
|
||||
</div>
|
||||
<hr style="width: 90%;">
|
||||
{{/if}}
|
||||
<div class="item">
|
||||
{{for data.categories}}
|
||||
{{:helper.link(value, null, {'category' : value}, value == data.category ? 'selected' : null)}}
|
||||
{{empty}}
|
||||
There are no known designs
|
||||
{{/for}}
|
||||
</div>
|
||||
<hr style="width: 90%;">
|
||||
{{for data.buildable}}
|
||||
{{if value.category == data.category}}
|
||||
<div class="item">
|
||||
<div class="itemLabelWide">
|
||||
{{:helper.link(value.name, null, {'build' : value.id})}}
|
||||
</div>
|
||||
<div class="itemContentMedium">
|
||||
{{:value.resourses}}, {{:value.time}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/for}}
|
||||
</div>
|
||||
<div style="float: right; width: 40%">
|
||||
<div class="item">
|
||||
<b>Queue contains:</b>
|
||||
</div>
|
||||
{{if data.current}}
|
||||
<div class="item">
|
||||
<div class="itemLabelWide">
|
||||
<b>Now: {{:data.current}}</b> ({{:data.builtperc}}% ready)
|
||||
</div>
|
||||
<div class="itemContentMedium">
|
||||
{{:helper.link('Cancel', null, {'remove' : 1})}}
|
||||
</div>
|
||||
</div>
|
||||
{{for data.queue}}
|
||||
<div class="item">
|
||||
<div class="itemLabelWide">
|
||||
{{:index + 2}}: {{:value}}
|
||||
</div>
|
||||
<div class="itemContentMedium">
|
||||
{{:helper.link('Remove', null, {'remove' : index + 2})}}
|
||||
</div>
|
||||
{{empty}}
|
||||
<div class="item">
|
||||
The queue is empty
|
||||
</div>
|
||||
{{/for}}
|
||||
{{else}}
|
||||
<div class="item">
|
||||
Nothing
|
||||
</div>
|
||||
{{/if}}
|
||||
<b>Materials:</b>
|
||||
{{for data.materials}}
|
||||
<div class="item">
|
||||
<div class="itemLabelWide">
|
||||
{{:value.mat}}: {{:value.amt}}/{{:data.maxres}}
|
||||
</div>
|
||||
<div class="itemContentMedium">
|
||||
{{:helper.link('x1', null, {'eject' : value.mat, 'amount' : 1}, value.amt > 2000 ? null : 'disabled')}}
|
||||
{{:helper.link('x5', null, {'eject' : value.mat, 'amount' : 5}, value.amt > 10000 ? null : 'disabled')}}
|
||||
{{:helper.link('x10', null, {'eject' : value.mat, 'amount' : 10}, value.amt > 20000 ? null : 'disabled')}}
|
||||
{{:helper.link('Stack', null, {'eject' : value.mat, 'amount' : 0})}}
|
||||
{{:helper.link('All', null, {'eject' : value.mat, 'amount' : -1})}}
|
||||
</div>
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user